LAPACK 3.3.1
Linear Algebra PACKage
|
00001 SUBROUTINE ZGGSVP( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB, 00002 $ TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ, 00003 $ IWORK, RWORK, TAU, WORK, INFO ) 00004 * 00005 * -- LAPACK routine (version 3.3.1) -- 00006 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00007 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00008 * -- April 2011 -- 00009 * 00010 * .. Scalar Arguments .. 00011 CHARACTER JOBQ, JOBU, JOBV 00012 INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P 00013 DOUBLE PRECISION TOLA, TOLB 00014 * .. 00015 * .. Array Arguments .. 00016 INTEGER IWORK( * ) 00017 DOUBLE PRECISION RWORK( * ) 00018 COMPLEX*16 A( LDA, * ), B( LDB, * ), Q( LDQ, * ), 00019 $ TAU( * ), U( LDU, * ), V( LDV, * ), WORK( * ) 00020 * .. 00021 * 00022 * Purpose 00023 * ======= 00024 * 00025 * ZGGSVP computes unitary matrices U, V and Q such that 00026 * 00027 * N-K-L K L 00028 * U**H*A*Q = K ( 0 A12 A13 ) if M-K-L >= 0; 00029 * L ( 0 0 A23 ) 00030 * M-K-L ( 0 0 0 ) 00031 * 00032 * N-K-L K L 00033 * = K ( 0 A12 A13 ) if M-K-L < 0; 00034 * M-K ( 0 0 A23 ) 00035 * 00036 * N-K-L K L 00037 * V**H*B*Q = L ( 0 0 B13 ) 00038 * P-L ( 0 0 0 ) 00039 * 00040 * where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular 00041 * upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0, 00042 * otherwise A23 is (M-K)-by-L upper trapezoidal. K+L = the effective 00043 * numerical rank of the (M+P)-by-N matrix (A**H,B**H)**H. 00044 * 00045 * This decomposition is the preprocessing step for computing the 00046 * Generalized Singular Value Decomposition (GSVD), see subroutine 00047 * ZGGSVD. 00048 * 00049 * Arguments 00050 * ========= 00051 * 00052 * JOBU (input) CHARACTER*1 00053 * = 'U': Unitary matrix U is computed; 00054 * = 'N': U is not computed. 00055 * 00056 * JOBV (input) CHARACTER*1 00057 * = 'V': Unitary matrix V is computed; 00058 * = 'N': V is not computed. 00059 * 00060 * JOBQ (input) CHARACTER*1 00061 * = 'Q': Unitary matrix Q is computed; 00062 * = 'N': Q is not computed. 00063 * 00064 * M (input) INTEGER 00065 * The number of rows of the matrix A. M >= 0. 00066 * 00067 * P (input) INTEGER 00068 * The number of rows of the matrix B. P >= 0. 00069 * 00070 * N (input) INTEGER 00071 * The number of columns of the matrices A and B. N >= 0. 00072 * 00073 * A (input/output) COMPLEX*16 array, dimension (LDA,N) 00074 * On entry, the M-by-N matrix A. 00075 * On exit, A contains the triangular (or trapezoidal) matrix 00076 * described in the Purpose section. 00077 * 00078 * LDA (input) INTEGER 00079 * The leading dimension of the array A. LDA >= max(1,M). 00080 * 00081 * B (input/output) COMPLEX*16 array, dimension (LDB,N) 00082 * On entry, the P-by-N matrix B. 00083 * On exit, B contains the triangular matrix described in 00084 * the Purpose section. 00085 * 00086 * LDB (input) INTEGER 00087 * The leading dimension of the array B. LDB >= max(1,P). 00088 * 00089 * TOLA (input) DOUBLE PRECISION 00090 * TOLB (input) DOUBLE PRECISION 00091 * TOLA and TOLB are the thresholds to determine the effective 00092 * numerical rank of matrix B and a subblock of A. Generally, 00093 * they are set to 00094 * TOLA = MAX(M,N)*norm(A)*MAZHEPS, 00095 * TOLB = MAX(P,N)*norm(B)*MAZHEPS. 00096 * The size of TOLA and TOLB may affect the size of backward 00097 * errors of the decomposition. 00098 * 00099 * K (output) INTEGER 00100 * L (output) INTEGER 00101 * On exit, K and L specify the dimension of the subblocks 00102 * described in Purpose section. 00103 * K + L = effective numerical rank of (A**H,B**H)**H. 00104 * 00105 * U (output) COMPLEX*16 array, dimension (LDU,M) 00106 * If JOBU = 'U', U contains the unitary matrix U. 00107 * If JOBU = 'N', U is not referenced. 00108 * 00109 * LDU (input) INTEGER 00110 * The leading dimension of the array U. LDU >= max(1,M) if 00111 * JOBU = 'U'; LDU >= 1 otherwise. 00112 * 00113 * V (output) COMPLEX*16 array, dimension (LDV,P) 00114 * If JOBV = 'V', V contains the unitary matrix V. 00115 * If JOBV = 'N', V is not referenced. 00116 * 00117 * LDV (input) INTEGER 00118 * The leading dimension of the array V. LDV >= max(1,P) if 00119 * JOBV = 'V'; LDV >= 1 otherwise. 00120 * 00121 * Q (output) COMPLEX*16 array, dimension (LDQ,N) 00122 * If JOBQ = 'Q', Q contains the unitary matrix Q. 00123 * If JOBQ = 'N', Q is not referenced. 00124 * 00125 * LDQ (input) INTEGER 00126 * The leading dimension of the array Q. LDQ >= max(1,N) if 00127 * JOBQ = 'Q'; LDQ >= 1 otherwise. 00128 * 00129 * IWORK (workspace) INTEGER array, dimension (N) 00130 * 00131 * RWORK (workspace) DOUBLE PRECISION array, dimension (2*N) 00132 * 00133 * TAU (workspace) COMPLEX*16 array, dimension (N) 00134 * 00135 * WORK (workspace) COMPLEX*16 array, dimension (max(3*N,M,P)) 00136 * 00137 * INFO (output) INTEGER 00138 * = 0: successful exit 00139 * < 0: if INFO = -i, the i-th argument had an illegal value. 00140 * 00141 * Further Details 00142 * =============== 00143 * 00144 * The subroutine uses LAPACK subroutine ZGEQPF for the QR factorization 00145 * with column pivoting to detect the effective numerical rank of the 00146 * a matrix. It may be replaced by a better rank determination strategy. 00147 * 00148 * ===================================================================== 00149 * 00150 * .. Parameters .. 00151 COMPLEX*16 CZERO, CONE 00152 PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ), 00153 $ CONE = ( 1.0D+0, 0.0D+0 ) ) 00154 * .. 00155 * .. Local Scalars .. 00156 LOGICAL FORWRD, WANTQ, WANTU, WANTV 00157 INTEGER I, J 00158 COMPLEX*16 T 00159 * .. 00160 * .. External Functions .. 00161 LOGICAL LSAME 00162 EXTERNAL LSAME 00163 * .. 00164 * .. External Subroutines .. 00165 EXTERNAL XERBLA, ZGEQPF, ZGEQR2, ZGERQ2, ZLACPY, ZLAPMT, 00166 $ ZLASET, ZUNG2R, ZUNM2R, ZUNMR2 00167 * .. 00168 * .. Intrinsic Functions .. 00169 INTRINSIC ABS, DBLE, DIMAG, MAX, MIN 00170 * .. 00171 * .. Statement Functions .. 00172 DOUBLE PRECISION CABS1 00173 * .. 00174 * .. Statement Function definitions .. 00175 CABS1( T ) = ABS( DBLE( T ) ) + ABS( DIMAG( T ) ) 00176 * .. 00177 * .. Executable Statements .. 00178 * 00179 * Test the input parameters 00180 * 00181 WANTU = LSAME( JOBU, 'U' ) 00182 WANTV = LSAME( JOBV, 'V' ) 00183 WANTQ = LSAME( JOBQ, 'Q' ) 00184 FORWRD = .TRUE. 00185 * 00186 INFO = 0 00187 IF( .NOT.( WANTU .OR. LSAME( JOBU, 'N' ) ) ) THEN 00188 INFO = -1 00189 ELSE IF( .NOT.( WANTV .OR. LSAME( JOBV, 'N' ) ) ) THEN 00190 INFO = -2 00191 ELSE IF( .NOT.( WANTQ .OR. LSAME( JOBQ, 'N' ) ) ) THEN 00192 INFO = -3 00193 ELSE IF( M.LT.0 ) THEN 00194 INFO = -4 00195 ELSE IF( P.LT.0 ) THEN 00196 INFO = -5 00197 ELSE IF( N.LT.0 ) THEN 00198 INFO = -6 00199 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN 00200 INFO = -8 00201 ELSE IF( LDB.LT.MAX( 1, P ) ) THEN 00202 INFO = -10 00203 ELSE IF( LDU.LT.1 .OR. ( WANTU .AND. LDU.LT.M ) ) THEN 00204 INFO = -16 00205 ELSE IF( LDV.LT.1 .OR. ( WANTV .AND. LDV.LT.P ) ) THEN 00206 INFO = -18 00207 ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THEN 00208 INFO = -20 00209 END IF 00210 IF( INFO.NE.0 ) THEN 00211 CALL XERBLA( 'ZGGSVP', -INFO ) 00212 RETURN 00213 END IF 00214 * 00215 * QR with column pivoting of B: B*P = V*( S11 S12 ) 00216 * ( 0 0 ) 00217 * 00218 DO 10 I = 1, N 00219 IWORK( I ) = 0 00220 10 CONTINUE 00221 CALL ZGEQPF( P, N, B, LDB, IWORK, TAU, WORK, RWORK, INFO ) 00222 * 00223 * Update A := A*P 00224 * 00225 CALL ZLAPMT( FORWRD, M, N, A, LDA, IWORK ) 00226 * 00227 * Determine the effective rank of matrix B. 00228 * 00229 L = 0 00230 DO 20 I = 1, MIN( P, N ) 00231 IF( CABS1( B( I, I ) ).GT.TOLB ) 00232 $ L = L + 1 00233 20 CONTINUE 00234 * 00235 IF( WANTV ) THEN 00236 * 00237 * Copy the details of V, and form V. 00238 * 00239 CALL ZLASET( 'Full', P, P, CZERO, CZERO, V, LDV ) 00240 IF( P.GT.1 ) 00241 $ CALL ZLACPY( 'Lower', P-1, N, B( 2, 1 ), LDB, V( 2, 1 ), 00242 $ LDV ) 00243 CALL ZUNG2R( P, P, MIN( P, N ), V, LDV, TAU, WORK, INFO ) 00244 END IF 00245 * 00246 * Clean up B 00247 * 00248 DO 40 J = 1, L - 1 00249 DO 30 I = J + 1, L 00250 B( I, J ) = CZERO 00251 30 CONTINUE 00252 40 CONTINUE 00253 IF( P.GT.L ) 00254 $ CALL ZLASET( 'Full', P-L, N, CZERO, CZERO, B( L+1, 1 ), LDB ) 00255 * 00256 IF( WANTQ ) THEN 00257 * 00258 * Set Q = I and Update Q := Q*P 00259 * 00260 CALL ZLASET( 'Full', N, N, CZERO, CONE, Q, LDQ ) 00261 CALL ZLAPMT( FORWRD, N, N, Q, LDQ, IWORK ) 00262 END IF 00263 * 00264 IF( P.GE.L .AND. N.NE.L ) THEN 00265 * 00266 * RQ factorization of ( S11 S12 ) = ( 0 S12 )*Z 00267 * 00268 CALL ZGERQ2( L, N, B, LDB, TAU, WORK, INFO ) 00269 * 00270 * Update A := A*Z**H 00271 * 00272 CALL ZUNMR2( 'Right', 'Conjugate transpose', M, N, L, B, LDB, 00273 $ TAU, A, LDA, WORK, INFO ) 00274 IF( WANTQ ) THEN 00275 * 00276 * Update Q := Q*Z**H 00277 * 00278 CALL ZUNMR2( 'Right', 'Conjugate transpose', N, N, L, B, 00279 $ LDB, TAU, Q, LDQ, WORK, INFO ) 00280 END IF 00281 * 00282 * Clean up B 00283 * 00284 CALL ZLASET( 'Full', L, N-L, CZERO, CZERO, B, LDB ) 00285 DO 60 J = N - L + 1, N 00286 DO 50 I = J - N + L + 1, L 00287 B( I, J ) = CZERO 00288 50 CONTINUE 00289 60 CONTINUE 00290 * 00291 END IF 00292 * 00293 * Let N-L L 00294 * A = ( A11 A12 ) M, 00295 * 00296 * then the following does the complete QR decomposition of A11: 00297 * 00298 * A11 = U*( 0 T12 )*P1**H 00299 * ( 0 0 ) 00300 * 00301 DO 70 I = 1, N - L 00302 IWORK( I ) = 0 00303 70 CONTINUE 00304 CALL ZGEQPF( M, N-L, A, LDA, IWORK, TAU, WORK, RWORK, INFO ) 00305 * 00306 * Determine the effective rank of A11 00307 * 00308 K = 0 00309 DO 80 I = 1, MIN( M, N-L ) 00310 IF( CABS1( A( I, I ) ).GT.TOLA ) 00311 $ K = K + 1 00312 80 CONTINUE 00313 * 00314 * Update A12 := U**H*A12, where A12 = A( 1:M, N-L+1:N ) 00315 * 00316 CALL ZUNM2R( 'Left', 'Conjugate transpose', M, L, MIN( M, N-L ), 00317 $ A, LDA, TAU, A( 1, N-L+1 ), LDA, WORK, INFO ) 00318 * 00319 IF( WANTU ) THEN 00320 * 00321 * Copy the details of U, and form U 00322 * 00323 CALL ZLASET( 'Full', M, M, CZERO, CZERO, U, LDU ) 00324 IF( M.GT.1 ) 00325 $ CALL ZLACPY( 'Lower', M-1, N-L, A( 2, 1 ), LDA, U( 2, 1 ), 00326 $ LDU ) 00327 CALL ZUNG2R( M, M, MIN( M, N-L ), U, LDU, TAU, WORK, INFO ) 00328 END IF 00329 * 00330 IF( WANTQ ) THEN 00331 * 00332 * Update Q( 1:N, 1:N-L ) = Q( 1:N, 1:N-L )*P1 00333 * 00334 CALL ZLAPMT( FORWRD, N, N-L, Q, LDQ, IWORK ) 00335 END IF 00336 * 00337 * Clean up A: set the strictly lower triangular part of 00338 * A(1:K, 1:K) = 0, and A( K+1:M, 1:N-L ) = 0. 00339 * 00340 DO 100 J = 1, K - 1 00341 DO 90 I = J + 1, K 00342 A( I, J ) = CZERO 00343 90 CONTINUE 00344 100 CONTINUE 00345 IF( M.GT.K ) 00346 $ CALL ZLASET( 'Full', M-K, N-L, CZERO, CZERO, A( K+1, 1 ), LDA ) 00347 * 00348 IF( N-L.GT.K ) THEN 00349 * 00350 * RQ factorization of ( T11 T12 ) = ( 0 T12 )*Z1 00351 * 00352 CALL ZGERQ2( K, N-L, A, LDA, TAU, WORK, INFO ) 00353 * 00354 IF( WANTQ ) THEN 00355 * 00356 * Update Q( 1:N,1:N-L ) = Q( 1:N,1:N-L )*Z1**H 00357 * 00358 CALL ZUNMR2( 'Right', 'Conjugate transpose', N, N-L, K, A, 00359 $ LDA, TAU, Q, LDQ, WORK, INFO ) 00360 END IF 00361 * 00362 * Clean up A 00363 * 00364 CALL ZLASET( 'Full', K, N-L-K, CZERO, CZERO, A, LDA ) 00365 DO 120 J = N - L - K + 1, N - L 00366 DO 110 I = J - N + L + K + 1, K 00367 A( I, J ) = CZERO 00368 110 CONTINUE 00369 120 CONTINUE 00370 * 00371 END IF 00372 * 00373 IF( M.GT.K ) THEN 00374 * 00375 * QR factorization of A( K+1:M,N-L+1:N ) 00376 * 00377 CALL ZGEQR2( M-K, L, A( K+1, N-L+1 ), LDA, TAU, WORK, INFO ) 00378 * 00379 IF( WANTU ) THEN 00380 * 00381 * Update U(:,K+1:M) := U(:,K+1:M)*U1 00382 * 00383 CALL ZUNM2R( 'Right', 'No transpose', M, M-K, MIN( M-K, L ), 00384 $ A( K+1, N-L+1 ), LDA, TAU, U( 1, K+1 ), LDU, 00385 $ WORK, INFO ) 00386 END IF 00387 * 00388 * Clean up 00389 * 00390 DO 140 J = N - L + 1, N 00391 DO 130 I = J - N + K + L + 1, M 00392 A( I, J ) = CZERO 00393 130 CONTINUE 00394 140 CONTINUE 00395 * 00396 END IF 00397 * 00398 RETURN 00399 * 00400 * End of ZGGSVP 00401 * 00402 END