LAPACK 3.3.0
|
00001 SUBROUTINE DGGEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B, LDB, 00002 $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO, 00003 $ IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE, 00004 $ RCONDV, WORK, LWORK, IWORK, BWORK, INFO ) 00005 * 00006 * -- LAPACK driver routine (version 3.2) -- 00007 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00008 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00009 * November 2006 00010 * 00011 * .. Scalar Arguments .. 00012 CHARACTER BALANC, JOBVL, JOBVR, SENSE 00013 INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N 00014 DOUBLE PRECISION ABNRM, BBNRM 00015 * .. 00016 * .. Array Arguments .. 00017 LOGICAL BWORK( * ) 00018 INTEGER IWORK( * ) 00019 DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ), 00020 $ B( LDB, * ), BETA( * ), LSCALE( * ), 00021 $ RCONDE( * ), RCONDV( * ), RSCALE( * ), 00022 $ VL( LDVL, * ), VR( LDVR, * ), WORK( * ) 00023 * .. 00024 * 00025 * Purpose 00026 * ======= 00027 * 00028 * DGGEVX computes for a pair of N-by-N real nonsymmetric matrices (A,B) 00029 * the generalized eigenvalues, and optionally, the left and/or right 00030 * generalized eigenvectors. 00031 * 00032 * Optionally also, it computes a balancing transformation to improve 00033 * the conditioning of the eigenvalues and eigenvectors (ILO, IHI, 00034 * LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for 00035 * the eigenvalues (RCONDE), and reciprocal condition numbers for the 00036 * right eigenvectors (RCONDV). 00037 * 00038 * A generalized eigenvalue for a pair of matrices (A,B) is a scalar 00039 * lambda or a ratio alpha/beta = lambda, such that A - lambda*B is 00040 * singular. It is usually represented as the pair (alpha,beta), as 00041 * there is a reasonable interpretation for beta=0, and even for both 00042 * being zero. 00043 * 00044 * The right eigenvector v(j) corresponding to the eigenvalue lambda(j) 00045 * of (A,B) satisfies 00046 * 00047 * A * v(j) = lambda(j) * B * v(j) . 00048 * 00049 * The left eigenvector u(j) corresponding to the eigenvalue lambda(j) 00050 * of (A,B) satisfies 00051 * 00052 * u(j)**H * A = lambda(j) * u(j)**H * B. 00053 * 00054 * where u(j)**H is the conjugate-transpose of u(j). 00055 * 00056 * 00057 * Arguments 00058 * ========= 00059 * 00060 * BALANC (input) CHARACTER*1 00061 * Specifies the balance option to be performed. 00062 * = 'N': do not diagonally scale or permute; 00063 * = 'P': permute only; 00064 * = 'S': scale only; 00065 * = 'B': both permute and scale. 00066 * Computed reciprocal condition numbers will be for the 00067 * matrices after permuting and/or balancing. Permuting does 00068 * not change condition numbers (in exact arithmetic), but 00069 * balancing does. 00070 * 00071 * JOBVL (input) CHARACTER*1 00072 * = 'N': do not compute the left generalized eigenvectors; 00073 * = 'V': compute the left generalized eigenvectors. 00074 * 00075 * JOBVR (input) CHARACTER*1 00076 * = 'N': do not compute the right generalized eigenvectors; 00077 * = 'V': compute the right generalized eigenvectors. 00078 * 00079 * SENSE (input) CHARACTER*1 00080 * Determines which reciprocal condition numbers are computed. 00081 * = 'N': none are computed; 00082 * = 'E': computed for eigenvalues only; 00083 * = 'V': computed for eigenvectors only; 00084 * = 'B': computed for eigenvalues and eigenvectors. 00085 * 00086 * N (input) INTEGER 00087 * The order of the matrices A, B, VL, and VR. N >= 0. 00088 * 00089 * A (input/output) DOUBLE PRECISION array, dimension (LDA, N) 00090 * On entry, the matrix A in the pair (A,B). 00091 * On exit, A has been overwritten. If JOBVL='V' or JOBVR='V' 00092 * or both, then A contains the first part of the real Schur 00093 * form of the "balanced" versions of the input A and B. 00094 * 00095 * LDA (input) INTEGER 00096 * The leading dimension of A. LDA >= max(1,N). 00097 * 00098 * B (input/output) DOUBLE PRECISION array, dimension (LDB, N) 00099 * On entry, the matrix B in the pair (A,B). 00100 * On exit, B has been overwritten. If JOBVL='V' or JOBVR='V' 00101 * or both, then B contains the second part of the real Schur 00102 * form of the "balanced" versions of the input A and B. 00103 * 00104 * LDB (input) INTEGER 00105 * The leading dimension of B. LDB >= max(1,N). 00106 * 00107 * ALPHAR (output) DOUBLE PRECISION array, dimension (N) 00108 * ALPHAI (output) DOUBLE PRECISION array, dimension (N) 00109 * BETA (output) DOUBLE PRECISION array, dimension (N) 00110 * On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will 00111 * be the generalized eigenvalues. If ALPHAI(j) is zero, then 00112 * the j-th eigenvalue is real; if positive, then the j-th and 00113 * (j+1)-st eigenvalues are a complex conjugate pair, with 00114 * ALPHAI(j+1) negative. 00115 * 00116 * Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j) 00117 * may easily over- or underflow, and BETA(j) may even be zero. 00118 * Thus, the user should avoid naively computing the ratio 00119 * ALPHA/BETA. However, ALPHAR and ALPHAI will be always less 00120 * than and usually comparable with norm(A) in magnitude, and 00121 * BETA always less than and usually comparable with norm(B). 00122 * 00123 * VL (output) DOUBLE PRECISION array, dimension (LDVL,N) 00124 * If JOBVL = 'V', the left eigenvectors u(j) are stored one 00125 * after another in the columns of VL, in the same order as 00126 * their eigenvalues. If the j-th eigenvalue is real, then 00127 * u(j) = VL(:,j), the j-th column of VL. If the j-th and 00128 * (j+1)-th eigenvalues form a complex conjugate pair, then 00129 * u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1). 00130 * Each eigenvector will be scaled so the largest component have 00131 * abs(real part) + abs(imag. part) = 1. 00132 * Not referenced if JOBVL = 'N'. 00133 * 00134 * LDVL (input) INTEGER 00135 * The leading dimension of the matrix VL. LDVL >= 1, and 00136 * if JOBVL = 'V', LDVL >= N. 00137 * 00138 * VR (output) DOUBLE PRECISION array, dimension (LDVR,N) 00139 * If JOBVR = 'V', the right eigenvectors v(j) are stored one 00140 * after another in the columns of VR, in the same order as 00141 * their eigenvalues. If the j-th eigenvalue is real, then 00142 * v(j) = VR(:,j), the j-th column of VR. If the j-th and 00143 * (j+1)-th eigenvalues form a complex conjugate pair, then 00144 * v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1). 00145 * Each eigenvector will be scaled so the largest component have 00146 * abs(real part) + abs(imag. part) = 1. 00147 * Not referenced if JOBVR = 'N'. 00148 * 00149 * LDVR (input) INTEGER 00150 * The leading dimension of the matrix VR. LDVR >= 1, and 00151 * if JOBVR = 'V', LDVR >= N. 00152 * 00153 * ILO (output) INTEGER 00154 * IHI (output) INTEGER 00155 * ILO and IHI are integer values such that on exit 00156 * A(i,j) = 0 and B(i,j) = 0 if i > j and 00157 * j = 1,...,ILO-1 or i = IHI+1,...,N. 00158 * If BALANC = 'N' or 'S', ILO = 1 and IHI = N. 00159 * 00160 * LSCALE (output) DOUBLE PRECISION array, dimension (N) 00161 * Details of the permutations and scaling factors applied 00162 * to the left side of A and B. If PL(j) is the index of the 00163 * row interchanged with row j, and DL(j) is the scaling 00164 * factor applied to row j, then 00165 * LSCALE(j) = PL(j) for j = 1,...,ILO-1 00166 * = DL(j) for j = ILO,...,IHI 00167 * = PL(j) for j = IHI+1,...,N. 00168 * The order in which the interchanges are made is N to IHI+1, 00169 * then 1 to ILO-1. 00170 * 00171 * RSCALE (output) DOUBLE PRECISION array, dimension (N) 00172 * Details of the permutations and scaling factors applied 00173 * to the right side of A and B. If PR(j) is the index of the 00174 * column interchanged with column j, and DR(j) is the scaling 00175 * factor applied to column j, then 00176 * RSCALE(j) = PR(j) for j = 1,...,ILO-1 00177 * = DR(j) for j = ILO,...,IHI 00178 * = PR(j) for j = IHI+1,...,N 00179 * The order in which the interchanges are made is N to IHI+1, 00180 * then 1 to ILO-1. 00181 * 00182 * ABNRM (output) DOUBLE PRECISION 00183 * The one-norm of the balanced matrix A. 00184 * 00185 * BBNRM (output) DOUBLE PRECISION 00186 * The one-norm of the balanced matrix B. 00187 * 00188 * RCONDE (output) DOUBLE PRECISION array, dimension (N) 00189 * If SENSE = 'E' or 'B', the reciprocal condition numbers of 00190 * the eigenvalues, stored in consecutive elements of the array. 00191 * For a complex conjugate pair of eigenvalues two consecutive 00192 * elements of RCONDE are set to the same value. Thus RCONDE(j), 00193 * RCONDV(j), and the j-th columns of VL and VR all correspond 00194 * to the j-th eigenpair. 00195 * If SENSE = 'N or 'V', RCONDE is not referenced. 00196 * 00197 * RCONDV (output) DOUBLE PRECISION array, dimension (N) 00198 * If SENSE = 'V' or 'B', the estimated reciprocal condition 00199 * numbers of the eigenvectors, stored in consecutive elements 00200 * of the array. For a complex eigenvector two consecutive 00201 * elements of RCONDV are set to the same value. If the 00202 * eigenvalues cannot be reordered to compute RCONDV(j), 00203 * RCONDV(j) is set to 0; this can only occur when the true 00204 * value would be very small anyway. 00205 * If SENSE = 'N' or 'E', RCONDV is not referenced. 00206 * 00207 * WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) 00208 * On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 00209 * 00210 * LWORK (input) INTEGER 00211 * The dimension of the array WORK. LWORK >= max(1,2*N). 00212 * If BALANC = 'S' or 'B', or JOBVL = 'V', or JOBVR = 'V', 00213 * LWORK >= max(1,6*N). 00214 * If SENSE = 'E' or 'B', LWORK >= max(1,10*N). 00215 * If SENSE = 'V' or 'B', LWORK >= 2*N*N+8*N+16. 00216 * 00217 * If LWORK = -1, then a workspace query is assumed; the routine 00218 * only calculates the optimal size of the WORK array, returns 00219 * this value as the first entry of the WORK array, and no error 00220 * message related to LWORK is issued by XERBLA. 00221 * 00222 * IWORK (workspace) INTEGER array, dimension (N+6) 00223 * If SENSE = 'E', IWORK is not referenced. 00224 * 00225 * BWORK (workspace) LOGICAL array, dimension (N) 00226 * If SENSE = 'N', BWORK is not referenced. 00227 * 00228 * INFO (output) INTEGER 00229 * = 0: successful exit 00230 * < 0: if INFO = -i, the i-th argument had an illegal value. 00231 * = 1,...,N: 00232 * The QZ iteration failed. No eigenvectors have been 00233 * calculated, but ALPHAR(j), ALPHAI(j), and BETA(j) 00234 * should be correct for j=INFO+1,...,N. 00235 * > N: =N+1: other than QZ iteration failed in DHGEQZ. 00236 * =N+2: error return from DTGEVC. 00237 * 00238 * Further Details 00239 * =============== 00240 * 00241 * Balancing a matrix pair (A,B) includes, first, permuting rows and 00242 * columns to isolate eigenvalues, second, applying diagonal similarity 00243 * transformation to the rows and columns to make the rows and columns 00244 * as close in norm as possible. The computed reciprocal condition 00245 * numbers correspond to the balanced matrix. Permuting rows and columns 00246 * will not change the condition numbers (in exact arithmetic) but 00247 * diagonal scaling will. For further explanation of balancing, see 00248 * section 4.11.1.2 of LAPACK Users' Guide. 00249 * 00250 * An approximate error bound on the chordal distance between the i-th 00251 * computed generalized eigenvalue w and the corresponding exact 00252 * eigenvalue lambda is 00253 * 00254 * chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I) 00255 * 00256 * An approximate error bound for the angle between the i-th computed 00257 * eigenvector VL(i) or VR(i) is given by 00258 * 00259 * EPS * norm(ABNRM, BBNRM) / DIF(i). 00260 * 00261 * For further explanation of the reciprocal condition numbers RCONDE 00262 * and RCONDV, see section 4.11 of LAPACK User's Guide. 00263 * 00264 * ===================================================================== 00265 * 00266 * .. Parameters .. 00267 DOUBLE PRECISION ZERO, ONE 00268 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) 00269 * .. 00270 * .. Local Scalars .. 00271 LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL, 00272 $ PAIR, WANTSB, WANTSE, WANTSN, WANTSV 00273 CHARACTER CHTEMP 00274 INTEGER I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS, 00275 $ ITAU, IWRK, IWRK1, J, JC, JR, M, MAXWRK, 00276 $ MINWRK, MM 00277 DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, 00278 $ SMLNUM, TEMP 00279 * .. 00280 * .. Local Arrays .. 00281 LOGICAL LDUMMA( 1 ) 00282 * .. 00283 * .. External Subroutines .. 00284 EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD, 00285 $ DLACPY, DLASCL, DLASET, DORGQR, DORMQR, DTGEVC, 00286 $ DTGSNA, XERBLA 00287 * .. 00288 * .. External Functions .. 00289 LOGICAL LSAME 00290 INTEGER ILAENV 00291 DOUBLE PRECISION DLAMCH, DLANGE 00292 EXTERNAL LSAME, ILAENV, DLAMCH, DLANGE 00293 * .. 00294 * .. Intrinsic Functions .. 00295 INTRINSIC ABS, MAX, SQRT 00296 * .. 00297 * .. Executable Statements .. 00298 * 00299 * Decode the input arguments 00300 * 00301 IF( LSAME( JOBVL, 'N' ) ) THEN 00302 IJOBVL = 1 00303 ILVL = .FALSE. 00304 ELSE IF( LSAME( JOBVL, 'V' ) ) THEN 00305 IJOBVL = 2 00306 ILVL = .TRUE. 00307 ELSE 00308 IJOBVL = -1 00309 ILVL = .FALSE. 00310 END IF 00311 * 00312 IF( LSAME( JOBVR, 'N' ) ) THEN 00313 IJOBVR = 1 00314 ILVR = .FALSE. 00315 ELSE IF( LSAME( JOBVR, 'V' ) ) THEN 00316 IJOBVR = 2 00317 ILVR = .TRUE. 00318 ELSE 00319 IJOBVR = -1 00320 ILVR = .FALSE. 00321 END IF 00322 ILV = ILVL .OR. ILVR 00323 * 00324 NOSCL = LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 'P' ) 00325 WANTSN = LSAME( SENSE, 'N' ) 00326 WANTSE = LSAME( SENSE, 'E' ) 00327 WANTSV = LSAME( SENSE, 'V' ) 00328 WANTSB = LSAME( SENSE, 'B' ) 00329 * 00330 * Test the input arguments 00331 * 00332 INFO = 0 00333 LQUERY = ( LWORK.EQ.-1 ) 00334 IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 00335 $ 'S' ) .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) ) 00336 $ THEN 00337 INFO = -1 00338 ELSE IF( IJOBVL.LE.0 ) THEN 00339 INFO = -2 00340 ELSE IF( IJOBVR.LE.0 ) THEN 00341 INFO = -3 00342 ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSB .OR. WANTSV ) ) 00343 $ THEN 00344 INFO = -4 00345 ELSE IF( N.LT.0 ) THEN 00346 INFO = -5 00347 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN 00348 INFO = -7 00349 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN 00350 INFO = -9 00351 ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN 00352 INFO = -14 00353 ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN 00354 INFO = -16 00355 END IF 00356 * 00357 * Compute workspace 00358 * (Note: Comments in the code beginning "Workspace:" describe the 00359 * minimal amount of workspace needed at that point in the code, 00360 * as well as the preferred amount for good performance. 00361 * NB refers to the optimal block size for the immediately 00362 * following subroutine, as returned by ILAENV. The workspace is 00363 * computed assuming ILO = 1 and IHI = N, the worst case.) 00364 * 00365 IF( INFO.EQ.0 ) THEN 00366 IF( N.EQ.0 ) THEN 00367 MINWRK = 1 00368 MAXWRK = 1 00369 ELSE 00370 IF( NOSCL .AND. .NOT.ILV ) THEN 00371 MINWRK = 2*N 00372 ELSE 00373 MINWRK = 6*N 00374 END IF 00375 IF( WANTSE .OR. WANTSB ) THEN 00376 MINWRK = 10*N 00377 END IF 00378 IF( WANTSV .OR. WANTSB ) THEN 00379 MINWRK = MAX( MINWRK, 2*N*( N + 4 ) + 16 ) 00380 END IF 00381 MAXWRK = MINWRK 00382 MAXWRK = MAX( MAXWRK, 00383 $ N + N*ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 ) ) 00384 MAXWRK = MAX( MAXWRK, 00385 $ N + N*ILAENV( 1, 'DORMQR', ' ', N, 1, N, 0 ) ) 00386 IF( ILVL ) THEN 00387 MAXWRK = MAX( MAXWRK, N + 00388 $ N*ILAENV( 1, 'DORGQR', ' ', N, 1, N, 0 ) ) 00389 END IF 00390 END IF 00391 WORK( 1 ) = MAXWRK 00392 * 00393 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN 00394 INFO = -26 00395 END IF 00396 END IF 00397 * 00398 IF( INFO.NE.0 ) THEN 00399 CALL XERBLA( 'DGGEVX', -INFO ) 00400 RETURN 00401 ELSE IF( LQUERY ) THEN 00402 RETURN 00403 END IF 00404 * 00405 * Quick return if possible 00406 * 00407 IF( N.EQ.0 ) 00408 $ RETURN 00409 * 00410 * 00411 * Get machine constants 00412 * 00413 EPS = DLAMCH( 'P' ) 00414 SMLNUM = DLAMCH( 'S' ) 00415 BIGNUM = ONE / SMLNUM 00416 CALL DLABAD( SMLNUM, BIGNUM ) 00417 SMLNUM = SQRT( SMLNUM ) / EPS 00418 BIGNUM = ONE / SMLNUM 00419 * 00420 * Scale A if max element outside range [SMLNUM,BIGNUM] 00421 * 00422 ANRM = DLANGE( 'M', N, N, A, LDA, WORK ) 00423 ILASCL = .FALSE. 00424 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN 00425 ANRMTO = SMLNUM 00426 ILASCL = .TRUE. 00427 ELSE IF( ANRM.GT.BIGNUM ) THEN 00428 ANRMTO = BIGNUM 00429 ILASCL = .TRUE. 00430 END IF 00431 IF( ILASCL ) 00432 $ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR ) 00433 * 00434 * Scale B if max element outside range [SMLNUM,BIGNUM] 00435 * 00436 BNRM = DLANGE( 'M', N, N, B, LDB, WORK ) 00437 ILBSCL = .FALSE. 00438 IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN 00439 BNRMTO = SMLNUM 00440 ILBSCL = .TRUE. 00441 ELSE IF( BNRM.GT.BIGNUM ) THEN 00442 BNRMTO = BIGNUM 00443 ILBSCL = .TRUE. 00444 END IF 00445 IF( ILBSCL ) 00446 $ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR ) 00447 * 00448 * Permute and/or balance the matrix pair (A,B) 00449 * (Workspace: need 6*N if BALANC = 'S' or 'B', 1 otherwise) 00450 * 00451 CALL DGGBAL( BALANC, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE, 00452 $ WORK, IERR ) 00453 * 00454 * Compute ABNRM and BBNRM 00455 * 00456 ABNRM = DLANGE( '1', N, N, A, LDA, WORK( 1 ) ) 00457 IF( ILASCL ) THEN 00458 WORK( 1 ) = ABNRM 00459 CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, 1, 1, WORK( 1 ), 1, 00460 $ IERR ) 00461 ABNRM = WORK( 1 ) 00462 END IF 00463 * 00464 BBNRM = DLANGE( '1', N, N, B, LDB, WORK( 1 ) ) 00465 IF( ILBSCL ) THEN 00466 WORK( 1 ) = BBNRM 00467 CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, 1, 1, WORK( 1 ), 1, 00468 $ IERR ) 00469 BBNRM = WORK( 1 ) 00470 END IF 00471 * 00472 * Reduce B to triangular form (QR decomposition of B) 00473 * (Workspace: need N, prefer N*NB ) 00474 * 00475 IROWS = IHI + 1 - ILO 00476 IF( ILV .OR. .NOT.WANTSN ) THEN 00477 ICOLS = N + 1 - ILO 00478 ELSE 00479 ICOLS = IROWS 00480 END IF 00481 ITAU = 1 00482 IWRK = ITAU + IROWS 00483 CALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ), 00484 $ WORK( IWRK ), LWORK+1-IWRK, IERR ) 00485 * 00486 * Apply the orthogonal transformation to A 00487 * (Workspace: need N, prefer N*NB) 00488 * 00489 CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB, 00490 $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ), 00491 $ LWORK+1-IWRK, IERR ) 00492 * 00493 * Initialize VL and/or VR 00494 * (Workspace: need N, prefer N*NB) 00495 * 00496 IF( ILVL ) THEN 00497 CALL DLASET( 'Full', N, N, ZERO, ONE, VL, LDVL ) 00498 IF( IROWS.GT.1 ) THEN 00499 CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB, 00500 $ VL( ILO+1, ILO ), LDVL ) 00501 END IF 00502 CALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL, 00503 $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR ) 00504 END IF 00505 * 00506 IF( ILVR ) 00507 $ CALL DLASET( 'Full', N, N, ZERO, ONE, VR, LDVR ) 00508 * 00509 * Reduce to generalized Hessenberg form 00510 * (Workspace: none needed) 00511 * 00512 IF( ILV .OR. .NOT.WANTSN ) THEN 00513 * 00514 * Eigenvectors requested -- work on whole matrix. 00515 * 00516 CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL, 00517 $ LDVL, VR, LDVR, IERR ) 00518 ELSE 00519 CALL DGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA, 00520 $ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR ) 00521 END IF 00522 * 00523 * Perform QZ algorithm (Compute eigenvalues, and optionally, the 00524 * Schur forms and Schur vectors) 00525 * (Workspace: need N) 00526 * 00527 IF( ILV .OR. .NOT.WANTSN ) THEN 00528 CHTEMP = 'S' 00529 ELSE 00530 CHTEMP = 'E' 00531 END IF 00532 * 00533 CALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, 00534 $ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK, 00535 $ LWORK, IERR ) 00536 IF( IERR.NE.0 ) THEN 00537 IF( IERR.GT.0 .AND. IERR.LE.N ) THEN 00538 INFO = IERR 00539 ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN 00540 INFO = IERR - N 00541 ELSE 00542 INFO = N + 1 00543 END IF 00544 GO TO 130 00545 END IF 00546 * 00547 * Compute Eigenvectors and estimate condition numbers if desired 00548 * (Workspace: DTGEVC: need 6*N 00549 * DTGSNA: need 2*N*(N+2)+16 if SENSE = 'V' or 'B', 00550 * need N otherwise ) 00551 * 00552 IF( ILV .OR. .NOT.WANTSN ) THEN 00553 IF( ILV ) THEN 00554 IF( ILVL ) THEN 00555 IF( ILVR ) THEN 00556 CHTEMP = 'B' 00557 ELSE 00558 CHTEMP = 'L' 00559 END IF 00560 ELSE 00561 CHTEMP = 'R' 00562 END IF 00563 * 00564 CALL DTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, 00565 $ LDVL, VR, LDVR, N, IN, WORK, IERR ) 00566 IF( IERR.NE.0 ) THEN 00567 INFO = N + 2 00568 GO TO 130 00569 END IF 00570 END IF 00571 * 00572 IF( .NOT.WANTSN ) THEN 00573 * 00574 * compute eigenvectors (DTGEVC) and estimate condition 00575 * numbers (DTGSNA). Note that the definition of the condition 00576 * number is not invariant under transformation (u,v) to 00577 * (Q*u, Z*v), where (u,v) are eigenvectors of the generalized 00578 * Schur form (S,T), Q and Z are orthogonal matrices. In order 00579 * to avoid using extra 2*N*N workspace, we have to recalculate 00580 * eigenvectors and estimate one condition numbers at a time. 00581 * 00582 PAIR = .FALSE. 00583 DO 20 I = 1, N 00584 * 00585 IF( PAIR ) THEN 00586 PAIR = .FALSE. 00587 GO TO 20 00588 END IF 00589 MM = 1 00590 IF( I.LT.N ) THEN 00591 IF( A( I+1, I ).NE.ZERO ) THEN 00592 PAIR = .TRUE. 00593 MM = 2 00594 END IF 00595 END IF 00596 * 00597 DO 10 J = 1, N 00598 BWORK( J ) = .FALSE. 00599 10 CONTINUE 00600 IF( MM.EQ.1 ) THEN 00601 BWORK( I ) = .TRUE. 00602 ELSE IF( MM.EQ.2 ) THEN 00603 BWORK( I ) = .TRUE. 00604 BWORK( I+1 ) = .TRUE. 00605 END IF 00606 * 00607 IWRK = MM*N + 1 00608 IWRK1 = IWRK + MM*N 00609 * 00610 * Compute a pair of left and right eigenvectors. 00611 * (compute workspace: need up to 4*N + 6*N) 00612 * 00613 IF( WANTSE .OR. WANTSB ) THEN 00614 CALL DTGEVC( 'B', 'S', BWORK, N, A, LDA, B, LDB, 00615 $ WORK( 1 ), N, WORK( IWRK ), N, MM, M, 00616 $ WORK( IWRK1 ), IERR ) 00617 IF( IERR.NE.0 ) THEN 00618 INFO = N + 2 00619 GO TO 130 00620 END IF 00621 END IF 00622 * 00623 CALL DTGSNA( SENSE, 'S', BWORK, N, A, LDA, B, LDB, 00624 $ WORK( 1 ), N, WORK( IWRK ), N, RCONDE( I ), 00625 $ RCONDV( I ), MM, M, WORK( IWRK1 ), 00626 $ LWORK-IWRK1+1, IWORK, IERR ) 00627 * 00628 20 CONTINUE 00629 END IF 00630 END IF 00631 * 00632 * Undo balancing on VL and VR and normalization 00633 * (Workspace: none needed) 00634 * 00635 IF( ILVL ) THEN 00636 CALL DGGBAK( BALANC, 'L', N, ILO, IHI, LSCALE, RSCALE, N, VL, 00637 $ LDVL, IERR ) 00638 * 00639 DO 70 JC = 1, N 00640 IF( ALPHAI( JC ).LT.ZERO ) 00641 $ GO TO 70 00642 TEMP = ZERO 00643 IF( ALPHAI( JC ).EQ.ZERO ) THEN 00644 DO 30 JR = 1, N 00645 TEMP = MAX( TEMP, ABS( VL( JR, JC ) ) ) 00646 30 CONTINUE 00647 ELSE 00648 DO 40 JR = 1, N 00649 TEMP = MAX( TEMP, ABS( VL( JR, JC ) )+ 00650 $ ABS( VL( JR, JC+1 ) ) ) 00651 40 CONTINUE 00652 END IF 00653 IF( TEMP.LT.SMLNUM ) 00654 $ GO TO 70 00655 TEMP = ONE / TEMP 00656 IF( ALPHAI( JC ).EQ.ZERO ) THEN 00657 DO 50 JR = 1, N 00658 VL( JR, JC ) = VL( JR, JC )*TEMP 00659 50 CONTINUE 00660 ELSE 00661 DO 60 JR = 1, N 00662 VL( JR, JC ) = VL( JR, JC )*TEMP 00663 VL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP 00664 60 CONTINUE 00665 END IF 00666 70 CONTINUE 00667 END IF 00668 IF( ILVR ) THEN 00669 CALL DGGBAK( BALANC, 'R', N, ILO, IHI, LSCALE, RSCALE, N, VR, 00670 $ LDVR, IERR ) 00671 DO 120 JC = 1, N 00672 IF( ALPHAI( JC ).LT.ZERO ) 00673 $ GO TO 120 00674 TEMP = ZERO 00675 IF( ALPHAI( JC ).EQ.ZERO ) THEN 00676 DO 80 JR = 1, N 00677 TEMP = MAX( TEMP, ABS( VR( JR, JC ) ) ) 00678 80 CONTINUE 00679 ELSE 00680 DO 90 JR = 1, N 00681 TEMP = MAX( TEMP, ABS( VR( JR, JC ) )+ 00682 $ ABS( VR( JR, JC+1 ) ) ) 00683 90 CONTINUE 00684 END IF 00685 IF( TEMP.LT.SMLNUM ) 00686 $ GO TO 120 00687 TEMP = ONE / TEMP 00688 IF( ALPHAI( JC ).EQ.ZERO ) THEN 00689 DO 100 JR = 1, N 00690 VR( JR, JC ) = VR( JR, JC )*TEMP 00691 100 CONTINUE 00692 ELSE 00693 DO 110 JR = 1, N 00694 VR( JR, JC ) = VR( JR, JC )*TEMP 00695 VR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP 00696 110 CONTINUE 00697 END IF 00698 120 CONTINUE 00699 END IF 00700 * 00701 * Undo scaling if necessary 00702 * 00703 IF( ILASCL ) THEN 00704 CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR ) 00705 CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR ) 00706 END IF 00707 * 00708 IF( ILBSCL ) THEN 00709 CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR ) 00710 END IF 00711 * 00712 130 CONTINUE 00713 WORK( 1 ) = MAXWRK 00714 * 00715 RETURN 00716 * 00717 * End of DGGEVX 00718 * 00719 END