LAPACK 3.3.0
|
00001 SUBROUTINE DCSDTS( M, P, Q, X, XF, LDX, U1, LDU1, U2, LDU2, V1T, 00002 $ LDV1T, V2T, LDV2T, THETA, IWORK, WORK, LWORK, 00003 $ RWORK, RESULT ) 00004 IMPLICIT NONE 00005 * 00006 * Originally xGSVTS 00007 * -- LAPACK test routine (version 3.1) -- 00008 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. 00009 * November 2006 00010 * 00011 * Adapted to DCSDTS 00012 * July 2010 00013 * 00014 * .. Scalar Arguments .. 00015 INTEGER LDX, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q 00016 * .. 00017 * .. Array Arguments .. 00018 INTEGER IWORK( * ) 00019 DOUBLE PRECISION RESULT( 9 ), RWORK( * ), THETA( * ) 00020 DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ), 00021 $ V2T( LDV2T, * ), WORK( LWORK ), X( LDX, * ), 00022 $ XF( LDX, * ) 00023 * .. 00024 * 00025 * Purpose 00026 * ======= 00027 * 00028 * DCSDTS tests DORCSD, which, given an M-by-M partitioned orthogonal 00029 * matrix X, 00030 * Q M-Q 00031 * X = [ X11 X12 ] P , 00032 * [ X21 X22 ] M-P 00033 * 00034 * computes the CSD 00035 * 00036 * [ U1 ]**T * [ X11 X12 ] * [ V1 ] 00037 * [ U2 ] [ X21 X22 ] [ V2 ] 00038 * 00039 * [ I 0 0 | 0 0 0 ] 00040 * [ 0 C 0 | 0 -S 0 ] 00041 * [ 0 0 0 | 0 0 -I ] 00042 * = [---------------------] = [ D11 D12 ] . 00043 * [ 0 0 0 | I 0 0 ] [ D21 D22 ] 00044 * [ 0 S 0 | 0 C 0 ] 00045 * [ 0 0 I | 0 0 0 ] 00046 * 00047 * Arguments 00048 * ========= 00049 * 00050 * M (input) INTEGER 00051 * The number of rows of the matrix X. M >= 0. 00052 * 00053 * P (input) INTEGER 00054 * The number of rows of the matrix X11. P >= 0. 00055 * 00056 * Q (input) INTEGER 00057 * The number of columns of the matrix X11. Q >= 0. 00058 * 00059 * X (input) DOUBLE PRECISION array, dimension (LDX,M) 00060 * The M-by-M matrix X. 00061 * 00062 * XF (output) DOUBLE PRECISION array, dimension (LDX,M) 00063 * Details of the CSD of X, as returned by DORCSD; 00064 * see DORCSD for further details. 00065 * 00066 * LDX (input) INTEGER 00067 * The leading dimension of the arrays X and XF. 00068 * LDX >= max( 1,M ). 00069 * 00070 * U1 (output) DOUBLE PRECISION array, dimension(LDU1,P) 00071 * The P-by-P orthogonal matrix U1. 00072 * 00073 * LDU1 (input) INTEGER 00074 * The leading dimension of the array U1. LDU >= max(1,P). 00075 * 00076 * U2 (output) DOUBLE PRECISION array, dimension(LDU2,M-P) 00077 * The (M-P)-by-(M-P) orthogonal matrix U2. 00078 * 00079 * LDU2 (input) INTEGER 00080 * The leading dimension of the array U2. LDU >= max(1,M-P). 00081 * 00082 * V1T (output) DOUBLE PRECISION array, dimension(LDV1T,Q) 00083 * The Q-by-Q orthogonal matrix V1T. 00084 * 00085 * LDV1T (input) INTEGER 00086 * The leading dimension of the array V1T. LDV1T >= 00087 * max(1,Q). 00088 * 00089 * V2T (output) DOUBLE PRECISION array, dimension(LDV2T,M-Q) 00090 * The (M-Q)-by-(M-Q) orthogonal matrix V2T. 00091 * 00092 * LDV2T (input) INTEGER 00093 * The leading dimension of the array V2T. LDV2T >= 00094 * max(1,M-Q). 00095 * 00096 * THETA (output) DOUBLE PRECISION array, dimension MIN(P,M-P,Q,M-Q) 00097 * The CS values of X; the essentially diagonal matrices C and 00098 * S are constructed from THETA; see subroutine DORCSD for 00099 * details. 00100 * 00101 * IWORK (workspace) INTEGER array, dimension (M) 00102 * 00103 * WORK (workspace) DOUBLE PRECISION array, dimension (LWORK) 00104 * 00105 * LWORK (input) INTEGER 00106 * The dimension of the array WORK 00107 * 00108 * RWORK (workspace) DOUBLE PRECISION array 00109 * 00110 * RESULT (output) DOUBLE PRECISION array, dimension (9) 00111 * The test ratios: 00112 * RESULT(1) = norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) 00113 * RESULT(2) = norm( U1'*X12*V2 - D12 ) / ( MAX(1,P,M-Q)*EPS2 ) 00114 * RESULT(3) = norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 ) 00115 * RESULT(4) = norm( U2'*X22*V2 - D22 ) / ( MAX(1,M-P,M-Q)*EPS2 ) 00116 * RESULT(5) = norm( I - U1'*U1 ) / ( MAX(1,P)*ULP ) 00117 * RESULT(6) = norm( I - U2'*U2 ) / ( MAX(1,M-P)*ULP ) 00118 * RESULT(7) = norm( I - V1T'*V1T ) / ( MAX(1,Q)*ULP ) 00119 * RESULT(8) = norm( I - V2T'*V2T ) / ( MAX(1,M-Q)*ULP ) 00120 * RESULT(9) = 0 if THETA is in increasing order and 00121 * all angles are in [0,pi/2]; 00122 * = ULPINV otherwise. 00123 * ( EPS2 = MAX( norm( I - X'*X ) / M, ULP ). ) 00124 * 00125 * ===================================================================== 00126 * 00127 * .. Parameters .. 00128 DOUBLE PRECISION PIOVER2, REALONE, REALZERO 00129 PARAMETER ( PIOVER2 = 1.57079632679489662D0, 00130 $ REALONE = 1.0D0, REALZERO = 0.0D0 ) 00131 DOUBLE PRECISION ZERO, ONE 00132 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) 00133 * .. 00134 * .. Local Scalars .. 00135 INTEGER I, INFO, R 00136 DOUBLE PRECISION EPS2, RESID, ULP, ULPINV 00137 * .. 00138 * .. External Functions .. 00139 DOUBLE PRECISION DLAMCH, DLANGE, DLANSY 00140 EXTERNAL DLAMCH, DLANGE, DLANSY 00141 * .. 00142 * .. External Subroutines .. 00143 EXTERNAL DGEMM, DLACPY, DLASET, DORCSD, DSYRK 00144 * .. 00145 * .. Intrinsic Functions .. 00146 INTRINSIC DBLE, MAX, MIN 00147 * .. 00148 * .. Executable Statements .. 00149 * 00150 ULP = DLAMCH( 'Precision' ) 00151 ULPINV = REALONE / ULP 00152 CALL DLASET( 'Full', M, M, ZERO, ONE, WORK, LDX ) 00153 CALL DSYRK( 'Upper', 'Conjugate transpose', M, M, -ONE, X, LDX, 00154 $ ONE, WORK, LDX ) 00155 EPS2 = MAX( ULP, 00156 $ DLANGE( '1', M, M, WORK, LDX, RWORK ) / DBLE( M ) ) 00157 R = MIN( P, M-P, Q, M-Q ) 00158 * 00159 * Copy the matrix X to the array XF. 00160 * 00161 CALL DLACPY( 'Full', M, M, X, LDX, XF, LDX ) 00162 * 00163 * Compute the CSD 00164 * 00165 CALL DORCSD( 'Y', 'Y', 'Y', 'Y', 'N', 'D', M, P, Q, XF(1,1), LDX, 00166 $ XF(1,Q+1), LDX, XF(P+1,1), LDX, XF(P+1,Q+1), LDX, 00167 $ THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T, 00168 $ WORK, LWORK, IWORK, INFO ) 00169 * 00170 * Compute X := diag(U1,U2)'*X*diag(V1,V2) - [D11 D12; D21 D22] 00171 * 00172 CALL DGEMM( 'No transpose', 'Conjugate transpose', P, Q, Q, ONE, 00173 $ X, LDX, V1T, LDV1T, ZERO, WORK, LDX ) 00174 * 00175 CALL DGEMM( 'Conjugate transpose', 'No transpose', P, Q, P, ONE, 00176 $ U1, LDU1, WORK, LDX, ZERO, X, LDX ) 00177 * 00178 DO I = 1, MIN(P,Q)-R 00179 X(I,I) = X(I,I) - ONE 00180 END DO 00181 DO I = 1, R 00182 X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) = 00183 $ X(MIN(P,Q)-R+I,MIN(P,Q)-R+I) - COS(THETA(I)) 00184 END DO 00185 * 00186 CALL DGEMM( 'No transpose', 'Conjugate transpose', P, M-Q, M-Q, 00187 $ ONE, X(1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX ) 00188 * 00189 CALL DGEMM( 'Conjugate transpose', 'No transpose', P, M-Q, P, 00190 $ ONE, U1, LDU1, WORK, LDX, ZERO, X(1,Q+1), LDX ) 00191 * 00192 DO I = 1, MIN(P,M-Q)-R 00193 X(P-I+1,M-I+1) = X(P-I+1,M-I+1) + ONE 00194 END DO 00195 DO I = 1, R 00196 X(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) = 00197 $ X(P-(MIN(P,M-Q)-R)+1-I,M-(MIN(P,M-Q)-R)+1-I) + 00198 $ SIN(THETA(R-I+1)) 00199 END DO 00200 * 00201 CALL DGEMM( 'No transpose', 'Conjugate transpose', M-P, Q, Q, ONE, 00202 $ X(P+1,1), LDX, V1T, LDV1T, ZERO, WORK, LDX ) 00203 * 00204 CALL DGEMM( 'Conjugate transpose', 'No transpose', M-P, Q, M-P, 00205 $ ONE, U2, LDU2, WORK, LDX, ZERO, X(P+1,1), LDX ) 00206 * 00207 DO I = 1, MIN(M-P,Q)-R 00208 X(M-I+1,Q-I+1) = X(M-I+1,Q-I+1) - ONE 00209 END DO 00210 DO I = 1, R 00211 X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) = 00212 $ X(M-(MIN(M-P,Q)-R)+1-I,Q-(MIN(M-P,Q)-R)+1-I) - 00213 $ SIN(THETA(R-I+1)) 00214 END DO 00215 * 00216 CALL DGEMM( 'No transpose', 'Conjugate transpose', M-P, M-Q, M-Q, 00217 $ ONE, X(P+1,Q+1), LDX, V2T, LDV2T, ZERO, WORK, LDX ) 00218 * 00219 CALL DGEMM( 'Conjugate transpose', 'No transpose', M-P, M-Q, M-P, 00220 $ ONE, U2, LDU2, WORK, LDX, ZERO, X(P+1,Q+1), LDX ) 00221 * 00222 DO I = 1, MIN(M-P,M-Q)-R 00223 X(P+I,Q+I) = X(P+I,Q+I) - ONE 00224 END DO 00225 DO I = 1, R 00226 X(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) = 00227 $ X(P+(MIN(M-P,M-Q)-R)+I,Q+(MIN(M-P,M-Q)-R)+I) - 00228 $ COS(THETA(I)) 00229 END DO 00230 * 00231 * Compute norm( U1'*X11*V1 - D11 ) / ( MAX(1,P,Q)*EPS2 ) . 00232 * 00233 RESID = DLANGE( '1', P, Q, X, LDX, RWORK ) 00234 RESULT( 1 ) = ( RESID / DBLE(MAX(1,P,Q)) ) / EPS2 00235 * 00236 * Compute norm( U1'*X12*V2 - D12 ) / ( MAX(1,P,M-Q)*EPS2 ) . 00237 * 00238 RESID = DLANGE( '1', P, M-Q, X(1,Q+1), LDX, RWORK ) 00239 RESULT( 2 ) = ( RESID / DBLE(MAX(1,P,M-Q)) ) / EPS2 00240 * 00241 * Compute norm( U2'*X21*V1 - D21 ) / ( MAX(1,M-P,Q)*EPS2 ) . 00242 * 00243 RESID = DLANGE( '1', M-P, Q, X(P+1,1), LDX, RWORK ) 00244 RESULT( 3 ) = ( RESID / DBLE(MAX(1,M-P,Q)) ) / EPS2 00245 * 00246 * Compute norm( U2'*X22*V2 - D22 ) / ( MAX(1,M-P,M-Q)*EPS2 ) . 00247 * 00248 RESID = DLANGE( '1', M-P, M-Q, X(P+1,Q+1), LDX, RWORK ) 00249 RESULT( 4 ) = ( RESID / DBLE(MAX(1,M-P,M-Q)) ) / EPS2 00250 * 00251 * Compute I - U1'*U1 00252 * 00253 CALL DLASET( 'Full', P, P, ZERO, ONE, WORK, LDU1 ) 00254 CALL DSYRK( 'Upper', 'Conjugate transpose', P, P, -ONE, U1, LDU1, 00255 $ ONE, WORK, LDU1 ) 00256 * 00257 * Compute norm( I - U'*U ) / ( MAX(1,P) * ULP ) . 00258 * 00259 RESID = DLANSY( '1', 'Upper', P, WORK, LDU1, RWORK ) 00260 RESULT( 5 ) = ( RESID / DBLE(MAX(1,P)) ) / ULP 00261 * 00262 * Compute I - U2'*U2 00263 * 00264 CALL DLASET( 'Full', M-P, M-P, ZERO, ONE, WORK, LDU2 ) 00265 CALL DSYRK( 'Upper', 'Conjugate transpose', M-P, M-P, -ONE, U2, 00266 $ LDU2, ONE, WORK, LDU2 ) 00267 * 00268 * Compute norm( I - U2'*U2 ) / ( MAX(1,M-P) * ULP ) . 00269 * 00270 RESID = DLANSY( '1', 'Upper', M-P, WORK, LDU2, RWORK ) 00271 RESULT( 6 ) = ( RESID / DBLE(MAX(1,M-P)) ) / ULP 00272 * 00273 * Compute I - V1T*V1T' 00274 * 00275 CALL DLASET( 'Full', Q, Q, ZERO, ONE, WORK, LDV1T ) 00276 CALL DSYRK( 'Upper', 'No transpose', Q, Q, -ONE, V1T, LDV1T, ONE, 00277 $ WORK, LDV1T ) 00278 * 00279 * Compute norm( I - V1T*V1T' ) / ( MAX(1,Q) * ULP ) . 00280 * 00281 RESID = DLANSY( '1', 'Upper', Q, WORK, LDV1T, RWORK ) 00282 RESULT( 7 ) = ( RESID / DBLE(MAX(1,Q)) ) / ULP 00283 * 00284 * Compute I - V2T*V2T' 00285 * 00286 CALL DLASET( 'Full', M-Q, M-Q, ZERO, ONE, WORK, LDV2T ) 00287 CALL DSYRK( 'Upper', 'No transpose', M-Q, M-Q, -ONE, V2T, LDV2T, 00288 $ ONE, WORK, LDV2T ) 00289 * 00290 * Compute norm( I - V2T*V2T' ) / ( MAX(1,M-Q) * ULP ) . 00291 * 00292 RESID = DLANSY( '1', 'Upper', M-Q, WORK, LDV2T, RWORK ) 00293 RESULT( 8 ) = ( RESID / DBLE(MAX(1,M-Q)) ) / ULP 00294 * 00295 * Check sorting 00296 * 00297 RESULT(9) = REALZERO 00298 DO I = 1, R 00299 IF( THETA(I).LT.REALZERO .OR. THETA(I).GT.PIOVER2 ) THEN 00300 RESULT(9) = ULPINV 00301 END IF 00302 IF( I.GT.1) THEN 00303 IF ( THETA(I).LT.THETA(I-1) ) THEN 00304 RESULT(9) = ULPINV 00305 END IF 00306 END IF 00307 END DO 00308 * 00309 RETURN 00310 * 00311 * End of DCSDTS 00312 * 00313 END 00314