LAPACK 3.3.1
Linear Algebra PACKage
|
00001 SUBROUTINE CGGES( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B, LDB, 00002 $ SDIM, ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK, 00003 $ LWORK, RWORK, BWORK, INFO ) 00004 * 00005 * -- LAPACK driver routine (version 3.2) -- 00006 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00007 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00008 * November 2006 00009 * 00010 * .. Scalar Arguments .. 00011 CHARACTER JOBVSL, JOBVSR, SORT 00012 INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM 00013 * .. 00014 * .. Array Arguments .. 00015 LOGICAL BWORK( * ) 00016 REAL RWORK( * ) 00017 COMPLEX A( LDA, * ), ALPHA( * ), B( LDB, * ), 00018 $ BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ), 00019 $ WORK( * ) 00020 * .. 00021 * .. Function Arguments .. 00022 LOGICAL SELCTG 00023 EXTERNAL SELCTG 00024 * .. 00025 * 00026 * Purpose 00027 * ======= 00028 * 00029 * CGGES computes for a pair of N-by-N complex nonsymmetric matrices 00030 * (A,B), the generalized eigenvalues, the generalized complex Schur 00031 * form (S, T), and optionally left and/or right Schur vectors (VSL 00032 * and VSR). This gives the generalized Schur factorization 00033 * 00034 * (A,B) = ( (VSL)*S*(VSR)**H, (VSL)*T*(VSR)**H ) 00035 * 00036 * where (VSR)**H is the conjugate-transpose of VSR. 00037 * 00038 * Optionally, it also orders the eigenvalues so that a selected cluster 00039 * of eigenvalues appears in the leading diagonal blocks of the upper 00040 * triangular matrix S and the upper triangular matrix T. The leading 00041 * columns of VSL and VSR then form an unitary basis for the 00042 * corresponding left and right eigenspaces (deflating subspaces). 00043 * 00044 * (If only the generalized eigenvalues are needed, use the driver 00045 * CGGEV instead, which is faster.) 00046 * 00047 * A generalized eigenvalue for a pair of matrices (A,B) is a scalar w 00048 * or a ratio alpha/beta = w, such that A - w*B is singular. It is 00049 * usually represented as the pair (alpha,beta), as there is a 00050 * reasonable interpretation for beta=0, and even for both being zero. 00051 * 00052 * A pair of matrices (S,T) is in generalized complex Schur form if S 00053 * and T are upper triangular and, in addition, the diagonal elements 00054 * of T are non-negative real numbers. 00055 * 00056 * Arguments 00057 * ========= 00058 * 00059 * JOBVSL (input) CHARACTER*1 00060 * = 'N': do not compute the left Schur vectors; 00061 * = 'V': compute the left Schur vectors. 00062 * 00063 * JOBVSR (input) CHARACTER*1 00064 * = 'N': do not compute the right Schur vectors; 00065 * = 'V': compute the right Schur vectors. 00066 * 00067 * SORT (input) CHARACTER*1 00068 * Specifies whether or not to order the eigenvalues on the 00069 * diagonal of the generalized Schur form. 00070 * = 'N': Eigenvalues are not ordered; 00071 * = 'S': Eigenvalues are ordered (see SELCTG). 00072 * 00073 * SELCTG (external procedure) LOGICAL FUNCTION of two COMPLEX arguments 00074 * SELCTG must be declared EXTERNAL in the calling subroutine. 00075 * If SORT = 'N', SELCTG is not referenced. 00076 * If SORT = 'S', SELCTG is used to select eigenvalues to sort 00077 * to the top left of the Schur form. 00078 * An eigenvalue ALPHA(j)/BETA(j) is selected if 00079 * SELCTG(ALPHA(j),BETA(j)) is true. 00080 * 00081 * Note that a selected complex eigenvalue may no longer satisfy 00082 * SELCTG(ALPHA(j),BETA(j)) = .TRUE. after ordering, since 00083 * ordering may change the value of complex eigenvalues 00084 * (especially if the eigenvalue is ill-conditioned), in this 00085 * case INFO is set to N+2 (See INFO below). 00086 * 00087 * N (input) INTEGER 00088 * The order of the matrices A, B, VSL, and VSR. N >= 0. 00089 * 00090 * A (input/output) COMPLEX array, dimension (LDA, N) 00091 * On entry, the first of the pair of matrices. 00092 * On exit, A has been overwritten by its generalized Schur 00093 * form S. 00094 * 00095 * LDA (input) INTEGER 00096 * The leading dimension of A. LDA >= max(1,N). 00097 * 00098 * B (input/output) COMPLEX array, dimension (LDB, N) 00099 * On entry, the second of the pair of matrices. 00100 * On exit, B has been overwritten by its generalized Schur 00101 * form T. 00102 * 00103 * LDB (input) INTEGER 00104 * The leading dimension of B. LDB >= max(1,N). 00105 * 00106 * SDIM (output) INTEGER 00107 * If SORT = 'N', SDIM = 0. 00108 * If SORT = 'S', SDIM = number of eigenvalues (after sorting) 00109 * for which SELCTG is true. 00110 * 00111 * ALPHA (output) COMPLEX array, dimension (N) 00112 * BETA (output) COMPLEX array, dimension (N) 00113 * On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the 00114 * generalized eigenvalues. ALPHA(j), j=1,...,N and BETA(j), 00115 * j=1,...,N are the diagonals of the complex Schur form (A,B) 00116 * output by CGGES. The BETA(j) will be non-negative real. 00117 * 00118 * Note: the quotients ALPHA(j)/BETA(j) may easily over- or 00119 * underflow, and BETA(j) may even be zero. Thus, the user 00120 * should avoid naively computing the ratio alpha/beta. 00121 * However, ALPHA will be always less than and usually 00122 * comparable with norm(A) in magnitude, and BETA always less 00123 * than and usually comparable with norm(B). 00124 * 00125 * VSL (output) COMPLEX array, dimension (LDVSL,N) 00126 * If JOBVSL = 'V', VSL will contain the left Schur vectors. 00127 * Not referenced if JOBVSL = 'N'. 00128 * 00129 * LDVSL (input) INTEGER 00130 * The leading dimension of the matrix VSL. LDVSL >= 1, and 00131 * if JOBVSL = 'V', LDVSL >= N. 00132 * 00133 * VSR (output) COMPLEX array, dimension (LDVSR,N) 00134 * If JOBVSR = 'V', VSR will contain the right Schur vectors. 00135 * Not referenced if JOBVSR = 'N'. 00136 * 00137 * LDVSR (input) INTEGER 00138 * The leading dimension of the matrix VSR. LDVSR >= 1, and 00139 * if JOBVSR = 'V', LDVSR >= N. 00140 * 00141 * WORK (workspace/output) COMPLEX array, dimension (MAX(1,LWORK)) 00142 * On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 00143 * 00144 * LWORK (input) INTEGER 00145 * The dimension of the array WORK. LWORK >= max(1,2*N). 00146 * For good performance, LWORK must generally be larger. 00147 * 00148 * If LWORK = -1, then a workspace query is assumed; the routine 00149 * only calculates the optimal size of the WORK array, returns 00150 * this value as the first entry of the WORK array, and no error 00151 * message related to LWORK is issued by XERBLA. 00152 * 00153 * RWORK (workspace) REAL array, dimension (8*N) 00154 * 00155 * BWORK (workspace) LOGICAL array, dimension (N) 00156 * Not referenced if SORT = 'N'. 00157 * 00158 * INFO (output) INTEGER 00159 * = 0: successful exit 00160 * < 0: if INFO = -i, the i-th argument had an illegal value. 00161 * =1,...,N: 00162 * The QZ iteration failed. (A,B) are not in Schur 00163 * form, but ALPHA(j) and BETA(j) should be correct for 00164 * j=INFO+1,...,N. 00165 * > N: =N+1: other than QZ iteration failed in CHGEQZ 00166 * =N+2: after reordering, roundoff changed values of 00167 * some complex eigenvalues so that leading 00168 * eigenvalues in the Generalized Schur form no 00169 * longer satisfy SELCTG=.TRUE. This could also 00170 * be caused due to scaling. 00171 * =N+3: reordering falied in CTGSEN. 00172 * 00173 * ===================================================================== 00174 * 00175 * .. Parameters .. 00176 REAL ZERO, ONE 00177 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 ) 00178 COMPLEX CZERO, CONE 00179 PARAMETER ( CZERO = ( 0.0E0, 0.0E0 ), 00180 $ CONE = ( 1.0E0, 0.0E0 ) ) 00181 * .. 00182 * .. Local Scalars .. 00183 LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL, 00184 $ LQUERY, WANTST 00185 INTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, 00186 $ ILO, IRIGHT, IROWS, IRWRK, ITAU, IWRK, LWKMIN, 00187 $ LWKOPT 00188 REAL ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL, 00189 $ PVSR, SMLNUM 00190 * .. 00191 * .. Local Arrays .. 00192 INTEGER IDUM( 1 ) 00193 REAL DIF( 2 ) 00194 * .. 00195 * .. External Subroutines .. 00196 EXTERNAL CGEQRF, CGGBAK, CGGBAL, CGGHRD, CHGEQZ, CLACPY, 00197 $ CLASCL, CLASET, CTGSEN, CUNGQR, CUNMQR, SLABAD, 00198 $ XERBLA 00199 * .. 00200 * .. External Functions .. 00201 LOGICAL LSAME 00202 INTEGER ILAENV 00203 REAL CLANGE, SLAMCH 00204 EXTERNAL LSAME, ILAENV, CLANGE, SLAMCH 00205 * .. 00206 * .. Intrinsic Functions .. 00207 INTRINSIC MAX, SQRT 00208 * .. 00209 * .. Executable Statements .. 00210 * 00211 * Decode the input arguments 00212 * 00213 IF( LSAME( JOBVSL, 'N' ) ) THEN 00214 IJOBVL = 1 00215 ILVSL = .FALSE. 00216 ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN 00217 IJOBVL = 2 00218 ILVSL = .TRUE. 00219 ELSE 00220 IJOBVL = -1 00221 ILVSL = .FALSE. 00222 END IF 00223 * 00224 IF( LSAME( JOBVSR, 'N' ) ) THEN 00225 IJOBVR = 1 00226 ILVSR = .FALSE. 00227 ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN 00228 IJOBVR = 2 00229 ILVSR = .TRUE. 00230 ELSE 00231 IJOBVR = -1 00232 ILVSR = .FALSE. 00233 END IF 00234 * 00235 WANTST = LSAME( SORT, 'S' ) 00236 * 00237 * Test the input arguments 00238 * 00239 INFO = 0 00240 LQUERY = ( LWORK.EQ.-1 ) 00241 IF( IJOBVL.LE.0 ) THEN 00242 INFO = -1 00243 ELSE IF( IJOBVR.LE.0 ) THEN 00244 INFO = -2 00245 ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN 00246 INFO = -3 00247 ELSE IF( N.LT.0 ) THEN 00248 INFO = -5 00249 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN 00250 INFO = -7 00251 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN 00252 INFO = -9 00253 ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN 00254 INFO = -14 00255 ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN 00256 INFO = -16 00257 END IF 00258 * 00259 * Compute workspace 00260 * (Note: Comments in the code beginning "Workspace:" describe the 00261 * minimal amount of workspace needed at that point in the code, 00262 * as well as the preferred amount for good performance. 00263 * NB refers to the optimal block size for the immediately 00264 * following subroutine, as returned by ILAENV.) 00265 * 00266 IF( INFO.EQ.0 ) THEN 00267 LWKMIN = MAX( 1, 2*N ) 00268 LWKOPT = MAX( 1, N + N*ILAENV( 1, 'CGEQRF', ' ', N, 1, N, 0 ) ) 00269 LWKOPT = MAX( LWKOPT, N + 00270 $ N*ILAENV( 1, 'CUNMQR', ' ', N, 1, N, -1 ) ) 00271 IF( ILVSL ) THEN 00272 LWKOPT = MAX( LWKOPT, N + 00273 $ N*ILAENV( 1, 'CUNGQR', ' ', N, 1, N, -1 ) ) 00274 END IF 00275 WORK( 1 ) = LWKOPT 00276 * 00277 IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) 00278 $ INFO = -18 00279 END IF 00280 * 00281 IF( INFO.NE.0 ) THEN 00282 CALL XERBLA( 'CGGES ', -INFO ) 00283 RETURN 00284 ELSE IF( LQUERY ) THEN 00285 RETURN 00286 END IF 00287 * 00288 * Quick return if possible 00289 * 00290 IF( N.EQ.0 ) THEN 00291 SDIM = 0 00292 RETURN 00293 END IF 00294 * 00295 * Get machine constants 00296 * 00297 EPS = SLAMCH( 'P' ) 00298 SMLNUM = SLAMCH( 'S' ) 00299 BIGNUM = ONE / SMLNUM 00300 CALL SLABAD( SMLNUM, BIGNUM ) 00301 SMLNUM = SQRT( SMLNUM ) / EPS 00302 BIGNUM = ONE / SMLNUM 00303 * 00304 * Scale A if max element outside range [SMLNUM,BIGNUM] 00305 * 00306 ANRM = CLANGE( 'M', N, N, A, LDA, RWORK ) 00307 ILASCL = .FALSE. 00308 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN 00309 ANRMTO = SMLNUM 00310 ILASCL = .TRUE. 00311 ELSE IF( ANRM.GT.BIGNUM ) THEN 00312 ANRMTO = BIGNUM 00313 ILASCL = .TRUE. 00314 END IF 00315 * 00316 IF( ILASCL ) 00317 $ CALL CLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR ) 00318 * 00319 * Scale B if max element outside range [SMLNUM,BIGNUM] 00320 * 00321 BNRM = CLANGE( 'M', N, N, B, LDB, RWORK ) 00322 ILBSCL = .FALSE. 00323 IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN 00324 BNRMTO = SMLNUM 00325 ILBSCL = .TRUE. 00326 ELSE IF( BNRM.GT.BIGNUM ) THEN 00327 BNRMTO = BIGNUM 00328 ILBSCL = .TRUE. 00329 END IF 00330 * 00331 IF( ILBSCL ) 00332 $ CALL CLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR ) 00333 * 00334 * Permute the matrix to make it more nearly triangular 00335 * (Real Workspace: need 6*N) 00336 * 00337 ILEFT = 1 00338 IRIGHT = N + 1 00339 IRWRK = IRIGHT + N 00340 CALL CGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ), 00341 $ RWORK( IRIGHT ), RWORK( IRWRK ), IERR ) 00342 * 00343 * Reduce B to triangular form (QR decomposition of B) 00344 * (Complex Workspace: need N, prefer N*NB) 00345 * 00346 IROWS = IHI + 1 - ILO 00347 ICOLS = N + 1 - ILO 00348 ITAU = 1 00349 IWRK = ITAU + IROWS 00350 CALL CGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ), 00351 $ WORK( IWRK ), LWORK+1-IWRK, IERR ) 00352 * 00353 * Apply the orthogonal transformation to matrix A 00354 * (Complex Workspace: need N, prefer N*NB) 00355 * 00356 CALL CUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB, 00357 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ), 00358 $ LWORK+1-IWRK, IERR ) 00359 * 00360 * Initialize VSL 00361 * (Complex Workspace: need N, prefer N*NB) 00362 * 00363 IF( ILVSL ) THEN 00364 CALL CLASET( 'Full', N, N, CZERO, CONE, VSL, LDVSL ) 00365 IF( IROWS.GT.1 ) THEN 00366 CALL CLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB, 00367 $ VSL( ILO+1, ILO ), LDVSL ) 00368 END IF 00369 CALL CUNGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL, 00370 $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR ) 00371 END IF 00372 * 00373 * Initialize VSR 00374 * 00375 IF( ILVSR ) 00376 $ CALL CLASET( 'Full', N, N, CZERO, CONE, VSR, LDVSR ) 00377 * 00378 * Reduce to generalized Hessenberg form 00379 * (Workspace: none needed) 00380 * 00381 CALL CGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL, 00382 $ LDVSL, VSR, LDVSR, IERR ) 00383 * 00384 SDIM = 0 00385 * 00386 * Perform QZ algorithm, computing Schur vectors if desired 00387 * (Complex Workspace: need N) 00388 * (Real Workspace: need N) 00389 * 00390 IWRK = ITAU 00391 CALL CHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, 00392 $ ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK( IWRK ), 00393 $ LWORK+1-IWRK, RWORK( IRWRK ), IERR ) 00394 IF( IERR.NE.0 ) THEN 00395 IF( IERR.GT.0 .AND. IERR.LE.N ) THEN 00396 INFO = IERR 00397 ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN 00398 INFO = IERR - N 00399 ELSE 00400 INFO = N + 1 00401 END IF 00402 GO TO 30 00403 END IF 00404 * 00405 * Sort eigenvalues ALPHA/BETA if desired 00406 * (Workspace: none needed) 00407 * 00408 IF( WANTST ) THEN 00409 * 00410 * Undo scaling on eigenvalues before selecting 00411 * 00412 IF( ILASCL ) 00413 $ CALL CLASCL( 'G', 0, 0, ANRM, ANRMTO, N, 1, ALPHA, N, IERR ) 00414 IF( ILBSCL ) 00415 $ CALL CLASCL( 'G', 0, 0, BNRM, BNRMTO, N, 1, BETA, N, IERR ) 00416 * 00417 * Select eigenvalues 00418 * 00419 DO 10 I = 1, N 00420 BWORK( I ) = SELCTG( ALPHA( I ), BETA( I ) ) 00421 10 CONTINUE 00422 * 00423 CALL CTGSEN( 0, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB, ALPHA, 00424 $ BETA, VSL, LDVSL, VSR, LDVSR, SDIM, PVSL, PVSR, 00425 $ DIF, WORK( IWRK ), LWORK-IWRK+1, IDUM, 1, IERR ) 00426 IF( IERR.EQ.1 ) 00427 $ INFO = N + 3 00428 * 00429 END IF 00430 * 00431 * Apply back-permutation to VSL and VSR 00432 * (Workspace: none needed) 00433 * 00434 IF( ILVSL ) 00435 $ CALL CGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ), 00436 $ RWORK( IRIGHT ), N, VSL, LDVSL, IERR ) 00437 IF( ILVSR ) 00438 $ CALL CGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ), 00439 $ RWORK( IRIGHT ), N, VSR, LDVSR, IERR ) 00440 * 00441 * Undo scaling 00442 * 00443 IF( ILASCL ) THEN 00444 CALL CLASCL( 'U', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR ) 00445 CALL CLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR ) 00446 END IF 00447 * 00448 IF( ILBSCL ) THEN 00449 CALL CLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR ) 00450 CALL CLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR ) 00451 END IF 00452 * 00453 IF( WANTST ) THEN 00454 * 00455 * Check if reordering is correct 00456 * 00457 LASTSL = .TRUE. 00458 SDIM = 0 00459 DO 20 I = 1, N 00460 CURSL = SELCTG( ALPHA( I ), BETA( I ) ) 00461 IF( CURSL ) 00462 $ SDIM = SDIM + 1 00463 IF( CURSL .AND. .NOT.LASTSL ) 00464 $ INFO = N + 2 00465 LASTSL = CURSL 00466 20 CONTINUE 00467 * 00468 END IF 00469 * 00470 30 CONTINUE 00471 * 00472 WORK( 1 ) = LWKOPT 00473 * 00474 RETURN 00475 * 00476 * End of CGGES 00477 * 00478 END