1*> \brief \b ZQRT05 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8* Definition: 9* =========== 10* 11* SUBROUTINE ZQRT05(M,N,L,NB,RESULT) 12* 13* .. Scalar Arguments .. 14* INTEGER LWORK, M, N, L, NB, LDT 15* .. Return values .. 16* DOUBLE PRECISION RESULT(6) 17* 18* 19*> \par Purpose: 20* ============= 21*> 22*> \verbatim 23*> 24*> ZQRT05 tests ZTPQRT and ZTPMQRT. 25*> \endverbatim 26* 27* Arguments: 28* ========== 29* 30*> \param[in] M 31*> \verbatim 32*> M is INTEGER 33*> Number of rows in lower part of the test matrix. 34*> \endverbatim 35*> 36*> \param[in] N 37*> \verbatim 38*> N is INTEGER 39*> Number of columns in test matrix. 40*> \endverbatim 41*> 42*> \param[in] L 43*> \verbatim 44*> L is INTEGER 45*> The number of rows of the upper trapezoidal part the 46*> lower test matrix. 0 <= L <= M. 47*> \endverbatim 48*> 49*> \param[in] NB 50*> \verbatim 51*> NB is INTEGER 52*> Block size of test matrix. NB <= N. 53*> \endverbatim 54*> 55*> \param[out] RESULT 56*> \verbatim 57*> RESULT is DOUBLE PRECISION array, dimension (6) 58*> Results of each of the six tests below. 59*> 60*> RESULT(1) = | A - Q R | 61*> RESULT(2) = | I - Q^H Q | 62*> RESULT(3) = | Q C - Q C | 63*> RESULT(4) = | Q^H C - Q^H C | 64*> RESULT(5) = | C Q - C Q | 65*> RESULT(6) = | C Q^H - C Q^H | 66*> \endverbatim 67* 68* Authors: 69* ======== 70* 71*> \author Univ. of Tennessee 72*> \author Univ. of California Berkeley 73*> \author Univ. of Colorado Denver 74*> \author NAG Ltd. 75* 76*> \ingroup complex16_lin 77* 78* ===================================================================== 79 SUBROUTINE ZQRT05(M,N,L,NB,RESULT) 80 IMPLICIT NONE 81* 82* -- LAPACK test routine -- 83* -- LAPACK is a software package provided by Univ. of Tennessee, -- 84* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 85* 86* .. Scalar Arguments .. 87 INTEGER LWORK, M, N, L, NB, LDT 88* .. Return values .. 89 DOUBLE PRECISION RESULT(6) 90* 91* ===================================================================== 92* 93* .. 94* .. Local allocatable arrays 95 COMPLEX*16, ALLOCATABLE :: AF(:,:), Q(:,:), 96 $ R(:,:), WORK( : ), T(:,:), 97 $ CF(:,:), DF(:,:), A(:,:), C(:,:), D(:,:) 98 DOUBLE PRECISION, ALLOCATABLE :: RWORK(:) 99* 100* .. Parameters .. 101 DOUBLE PRECISION ZERO 102 COMPLEX*16 ONE, CZERO 103 PARAMETER( ZERO = 0.0, ONE = (1.0,0.0), CZERO=(0.0,0.0) ) 104* .. 105* .. Local Scalars .. 106 INTEGER INFO, J, K, M2, NP1 107 DOUBLE PRECISION ANORM, EPS, RESID, CNORM, DNORM 108* .. 109* .. Local Arrays .. 110 INTEGER ISEED( 4 ) 111* .. 112* .. External Functions .. 113 DOUBLE PRECISION DLAMCH 114 DOUBLE PRECISION ZLANGE, ZLANSY 115 LOGICAL LSAME 116 EXTERNAL DLAMCH, ZLANGE, ZLANSY, LSAME 117* .. 118* .. Data statements .. 119 DATA ISEED / 1988, 1989, 1990, 1991 / 120* 121 EPS = DLAMCH( 'Epsilon' ) 122 K = N 123 M2 = M+N 124 IF( M.GT.0 ) THEN 125 NP1 = N+1 126 ELSE 127 NP1 = 1 128 END IF 129 LWORK = M2*M2*NB 130* 131* Dynamically allocate all arrays 132* 133 ALLOCATE(A(M2,N),AF(M2,N),Q(M2,M2),R(M2,M2),RWORK(M2), 134 $ WORK(LWORK),T(NB,N),C(M2,N),CF(M2,N), 135 $ D(N,M2),DF(N,M2) ) 136* 137* Put random stuff into A 138* 139 LDT=NB 140 CALL ZLASET( 'Full', M2, N, CZERO, CZERO, A, M2 ) 141 CALL ZLASET( 'Full', NB, N, CZERO, CZERO, T, NB ) 142 DO J=1,N 143 CALL ZLARNV( 2, ISEED, J, A( 1, J ) ) 144 END DO 145 IF( M.GT.0 ) THEN 146 DO J=1,N 147 CALL ZLARNV( 2, ISEED, M-L, A( MIN(N+M,N+1), J ) ) 148 END DO 149 END IF 150 IF( L.GT.0 ) THEN 151 DO J=1,N 152 CALL ZLARNV( 2, ISEED, MIN(J,L), A( MIN(N+M,N+M-L+1), J ) ) 153 END DO 154 END IF 155* 156* Copy the matrix A to the array AF. 157* 158 CALL ZLACPY( 'Full', M2, N, A, M2, AF, M2 ) 159* 160* Factor the matrix A in the array AF. 161* 162 CALL ZTPQRT( M,N,L,NB,AF,M2,AF(NP1,1),M2,T,LDT,WORK,INFO) 163* 164* Generate the (M+N)-by-(M+N) matrix Q by applying H to I 165* 166 CALL ZLASET( 'Full', M2, M2, CZERO, ONE, Q, M2 ) 167 CALL ZGEMQRT( 'R', 'N', M2, M2, K, NB, AF, M2, T, LDT, Q, M2, 168 $ WORK, INFO ) 169* 170* Copy R 171* 172 CALL ZLASET( 'Full', M2, N, CZERO, CZERO, R, M2 ) 173 CALL ZLACPY( 'Upper', M2, N, AF, M2, R, M2 ) 174* 175* Compute |R - Q'*A| / |A| and store in RESULT(1) 176* 177 CALL ZGEMM( 'C', 'N', M2, N, M2, -ONE, Q, M2, A, M2, ONE, R, M2 ) 178 ANORM = ZLANGE( '1', M2, N, A, M2, RWORK ) 179 RESID = ZLANGE( '1', M2, N, R, M2, RWORK ) 180 IF( ANORM.GT.ZERO ) THEN 181 RESULT( 1 ) = RESID / (EPS*ANORM*MAX(1,M2)) 182 ELSE 183 RESULT( 1 ) = ZERO 184 END IF 185* 186* Compute |I - Q'*Q| and store in RESULT(2) 187* 188 CALL ZLASET( 'Full', M2, M2, CZERO, ONE, R, M2 ) 189 CALL ZHERK( 'U', 'C', M2, M2, DREAL(-ONE), Q, M2, DREAL(ONE), 190 $ R, M2 ) 191 RESID = ZLANSY( '1', 'Upper', M2, R, M2, RWORK ) 192 RESULT( 2 ) = RESID / (EPS*MAX(1,M2)) 193* 194* Generate random m-by-n matrix C and a copy CF 195* 196 DO J=1,N 197 CALL ZLARNV( 2, ISEED, M2, C( 1, J ) ) 198 END DO 199 CNORM = ZLANGE( '1', M2, N, C, M2, RWORK) 200 CALL ZLACPY( 'Full', M2, N, C, M2, CF, M2 ) 201* 202* Apply Q to C as Q*C 203* 204 CALL ZTPMQRT( 'L','N', M,N,K,L,NB,AF(NP1,1),M2,T,LDT,CF,M2, 205 $ CF(NP1,1),M2,WORK,INFO) 206* 207* Compute |Q*C - Q*C| / |C| 208* 209 CALL ZGEMM( 'N', 'N', M2, N, M2, -ONE, Q, M2, C, M2, ONE, CF, M2 ) 210 RESID = ZLANGE( '1', M2, N, CF, M2, RWORK ) 211 IF( CNORM.GT.ZERO ) THEN 212 RESULT( 3 ) = RESID / (EPS*MAX(1,M2)*CNORM) 213 ELSE 214 RESULT( 3 ) = ZERO 215 END IF 216* 217* Copy C into CF again 218* 219 CALL ZLACPY( 'Full', M2, N, C, M2, CF, M2 ) 220* 221* Apply Q to C as QT*C 222* 223 CALL ZTPMQRT( 'L','C',M,N,K,L,NB,AF(NP1,1),M2,T,LDT,CF,M2, 224 $ CF(NP1,1),M2,WORK,INFO) 225* 226* Compute |QT*C - QT*C| / |C| 227* 228 CALL ZGEMM('C','N',M2,N,M2,-ONE,Q,M2,C,M2,ONE,CF,M2) 229 RESID = ZLANGE( '1', M2, N, CF, M2, RWORK ) 230 IF( CNORM.GT.ZERO ) THEN 231 RESULT( 4 ) = RESID / (EPS*MAX(1,M2)*CNORM) 232 ELSE 233 RESULT( 4 ) = ZERO 234 END IF 235* 236* Generate random n-by-m matrix D and a copy DF 237* 238 DO J=1,M2 239 CALL ZLARNV( 2, ISEED, N, D( 1, J ) ) 240 END DO 241 DNORM = ZLANGE( '1', N, M2, D, N, RWORK) 242 CALL ZLACPY( 'Full', N, M2, D, N, DF, N ) 243* 244* Apply Q to D as D*Q 245* 246 CALL ZTPMQRT('R','N',N,M,N,L,NB,AF(NP1,1),M2,T,LDT,DF,N, 247 $ DF(1,NP1),N,WORK,INFO) 248* 249* Compute |D*Q - D*Q| / |D| 250* 251 CALL ZGEMM('N','N',N,M2,M2,-ONE,D,N,Q,M2,ONE,DF,N) 252 RESID = ZLANGE('1',N, M2,DF,N,RWORK ) 253 IF( CNORM.GT.ZERO ) THEN 254 RESULT( 5 ) = RESID / (EPS*MAX(1,M2)*DNORM) 255 ELSE 256 RESULT( 5 ) = ZERO 257 END IF 258* 259* Copy D into DF again 260* 261 CALL ZLACPY('Full',N,M2,D,N,DF,N ) 262* 263* Apply Q to D as D*QT 264* 265 CALL ZTPMQRT('R','C',N,M,N,L,NB,AF(NP1,1),M2,T,LDT,DF,N, 266 $ DF(1,NP1),N,WORK,INFO) 267 268* 269* Compute |D*QT - D*QT| / |D| 270* 271 CALL ZGEMM( 'N', 'C', N, M2, M2, -ONE, D, N, Q, M2, ONE, DF, N ) 272 RESID = ZLANGE( '1', N, M2, DF, N, RWORK ) 273 IF( CNORM.GT.ZERO ) THEN 274 RESULT( 6 ) = RESID / (EPS*MAX(1,M2)*DNORM) 275 ELSE 276 RESULT( 6 ) = ZERO 277 END IF 278* 279* Deallocate all arrays 280* 281 DEALLOCATE ( A, AF, Q, R, RWORK, WORK, T, C, D, CF, DF) 282 RETURN 283 END 284 285