Annotation of rpl/lapack/lapack/ztgevc.f, revision 1.1
1.1 ! bertrand 1: SUBROUTINE ZTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
! 2: $ LDVL, VR, LDVR, MM, M, WORK, RWORK, INFO )
! 3: *
! 4: * -- LAPACK routine (version 3.2) --
! 5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
! 6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
! 7: * November 2006
! 8: *
! 9: * .. Scalar Arguments ..
! 10: CHARACTER HOWMNY, SIDE
! 11: INTEGER INFO, LDP, LDS, LDVL, LDVR, M, MM, N
! 12: * ..
! 13: * .. Array Arguments ..
! 14: LOGICAL SELECT( * )
! 15: DOUBLE PRECISION RWORK( * )
! 16: COMPLEX*16 P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
! 17: $ VR( LDVR, * ), WORK( * )
! 18: * ..
! 19: *
! 20: *
! 21: * Purpose
! 22: * =======
! 23: *
! 24: * ZTGEVC computes some or all of the right and/or left eigenvectors of
! 25: * a pair of complex matrices (S,P), where S and P are upper triangular.
! 26: * Matrix pairs of this type are produced by the generalized Schur
! 27: * factorization of a complex matrix pair (A,B):
! 28: *
! 29: * A = Q*S*Z**H, B = Q*P*Z**H
! 30: *
! 31: * as computed by ZGGHRD + ZHGEQZ.
! 32: *
! 33: * The right eigenvector x and the left eigenvector y of (S,P)
! 34: * corresponding to an eigenvalue w are defined by:
! 35: *
! 36: * S*x = w*P*x, (y**H)*S = w*(y**H)*P,
! 37: *
! 38: * where y**H denotes the conjugate tranpose of y.
! 39: * The eigenvalues are not input to this routine, but are computed
! 40: * directly from the diagonal elements of S and P.
! 41: *
! 42: * This routine returns the matrices X and/or Y of right and left
! 43: * eigenvectors of (S,P), or the products Z*X and/or Q*Y,
! 44: * where Z and Q are input matrices.
! 45: * If Q and Z are the unitary factors from the generalized Schur
! 46: * factorization of a matrix pair (A,B), then Z*X and Q*Y
! 47: * are the matrices of right and left eigenvectors of (A,B).
! 48: *
! 49: * Arguments
! 50: * =========
! 51: *
! 52: * SIDE (input) CHARACTER*1
! 53: * = 'R': compute right eigenvectors only;
! 54: * = 'L': compute left eigenvectors only;
! 55: * = 'B': compute both right and left eigenvectors.
! 56: *
! 57: * HOWMNY (input) CHARACTER*1
! 58: * = 'A': compute all right and/or left eigenvectors;
! 59: * = 'B': compute all right and/or left eigenvectors,
! 60: * backtransformed by the matrices in VR and/or VL;
! 61: * = 'S': compute selected right and/or left eigenvectors,
! 62: * specified by the logical array SELECT.
! 63: *
! 64: * SELECT (input) LOGICAL array, dimension (N)
! 65: * If HOWMNY='S', SELECT specifies the eigenvectors to be
! 66: * computed. The eigenvector corresponding to the j-th
! 67: * eigenvalue is computed if SELECT(j) = .TRUE..
! 68: * Not referenced if HOWMNY = 'A' or 'B'.
! 69: *
! 70: * N (input) INTEGER
! 71: * The order of the matrices S and P. N >= 0.
! 72: *
! 73: * S (input) COMPLEX*16 array, dimension (LDS,N)
! 74: * The upper triangular matrix S from a generalized Schur
! 75: * factorization, as computed by ZHGEQZ.
! 76: *
! 77: * LDS (input) INTEGER
! 78: * The leading dimension of array S. LDS >= max(1,N).
! 79: *
! 80: * P (input) COMPLEX*16 array, dimension (LDP,N)
! 81: * The upper triangular matrix P from a generalized Schur
! 82: * factorization, as computed by ZHGEQZ. P must have real
! 83: * diagonal elements.
! 84: *
! 85: * LDP (input) INTEGER
! 86: * The leading dimension of array P. LDP >= max(1,N).
! 87: *
! 88: * VL (input/output) COMPLEX*16 array, dimension (LDVL,MM)
! 89: * On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
! 90: * contain an N-by-N matrix Q (usually the unitary matrix Q
! 91: * of left Schur vectors returned by ZHGEQZ).
! 92: * On exit, if SIDE = 'L' or 'B', VL contains:
! 93: * if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
! 94: * if HOWMNY = 'B', the matrix Q*Y;
! 95: * if HOWMNY = 'S', the left eigenvectors of (S,P) specified by
! 96: * SELECT, stored consecutively in the columns of
! 97: * VL, in the same order as their eigenvalues.
! 98: * Not referenced if SIDE = 'R'.
! 99: *
! 100: * LDVL (input) INTEGER
! 101: * The leading dimension of array VL. LDVL >= 1, and if
! 102: * SIDE = 'L' or 'l' or 'B' or 'b', LDVL >= N.
! 103: *
! 104: * VR (input/output) COMPLEX*16 array, dimension (LDVR,MM)
! 105: * On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
! 106: * contain an N-by-N matrix Q (usually the unitary matrix Z
! 107: * of right Schur vectors returned by ZHGEQZ).
! 108: * On exit, if SIDE = 'R' or 'B', VR contains:
! 109: * if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
! 110: * if HOWMNY = 'B', the matrix Z*X;
! 111: * if HOWMNY = 'S', the right eigenvectors of (S,P) specified by
! 112: * SELECT, stored consecutively in the columns of
! 113: * VR, in the same order as their eigenvalues.
! 114: * Not referenced if SIDE = 'L'.
! 115: *
! 116: * LDVR (input) INTEGER
! 117: * The leading dimension of the array VR. LDVR >= 1, and if
! 118: * SIDE = 'R' or 'B', LDVR >= N.
! 119: *
! 120: * MM (input) INTEGER
! 121: * The number of columns in the arrays VL and/or VR. MM >= M.
! 122: *
! 123: * M (output) INTEGER
! 124: * The number of columns in the arrays VL and/or VR actually
! 125: * used to store the eigenvectors. If HOWMNY = 'A' or 'B', M
! 126: * is set to N. Each selected eigenvector occupies one column.
! 127: *
! 128: * WORK (workspace) COMPLEX*16 array, dimension (2*N)
! 129: *
! 130: * RWORK (workspace) DOUBLE PRECISION array, dimension (2*N)
! 131: *
! 132: * INFO (output) INTEGER
! 133: * = 0: successful exit.
! 134: * < 0: if INFO = -i, the i-th argument had an illegal value.
! 135: *
! 136: * =====================================================================
! 137: *
! 138: * .. Parameters ..
! 139: DOUBLE PRECISION ZERO, ONE
! 140: PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
! 141: COMPLEX*16 CZERO, CONE
! 142: PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
! 143: $ CONE = ( 1.0D+0, 0.0D+0 ) )
! 144: * ..
! 145: * .. Local Scalars ..
! 146: LOGICAL COMPL, COMPR, ILALL, ILBACK, ILBBAD, ILCOMP,
! 147: $ LSA, LSB
! 148: INTEGER I, IBEG, IEIG, IEND, IHWMNY, IM, ISIDE, ISRC,
! 149: $ J, JE, JR
! 150: DOUBLE PRECISION ACOEFA, ACOEFF, ANORM, ASCALE, BCOEFA, BIG,
! 151: $ BIGNUM, BNORM, BSCALE, DMIN, SAFMIN, SBETA,
! 152: $ SCALE, SMALL, TEMP, ULP, XMAX
! 153: COMPLEX*16 BCOEFF, CA, CB, D, SALPHA, SUM, SUMA, SUMB, X
! 154: * ..
! 155: * .. External Functions ..
! 156: LOGICAL LSAME
! 157: DOUBLE PRECISION DLAMCH
! 158: COMPLEX*16 ZLADIV
! 159: EXTERNAL LSAME, DLAMCH, ZLADIV
! 160: * ..
! 161: * .. External Subroutines ..
! 162: EXTERNAL DLABAD, XERBLA, ZGEMV
! 163: * ..
! 164: * .. Intrinsic Functions ..
! 165: INTRINSIC ABS, DBLE, DCMPLX, DCONJG, DIMAG, MAX, MIN
! 166: * ..
! 167: * .. Statement Functions ..
! 168: DOUBLE PRECISION ABS1
! 169: * ..
! 170: * .. Statement Function definitions ..
! 171: ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
! 172: * ..
! 173: * .. Executable Statements ..
! 174: *
! 175: * Decode and Test the input parameters
! 176: *
! 177: IF( LSAME( HOWMNY, 'A' ) ) THEN
! 178: IHWMNY = 1
! 179: ILALL = .TRUE.
! 180: ILBACK = .FALSE.
! 181: ELSE IF( LSAME( HOWMNY, 'S' ) ) THEN
! 182: IHWMNY = 2
! 183: ILALL = .FALSE.
! 184: ILBACK = .FALSE.
! 185: ELSE IF( LSAME( HOWMNY, 'B' ) ) THEN
! 186: IHWMNY = 3
! 187: ILALL = .TRUE.
! 188: ILBACK = .TRUE.
! 189: ELSE
! 190: IHWMNY = -1
! 191: END IF
! 192: *
! 193: IF( LSAME( SIDE, 'R' ) ) THEN
! 194: ISIDE = 1
! 195: COMPL = .FALSE.
! 196: COMPR = .TRUE.
! 197: ELSE IF( LSAME( SIDE, 'L' ) ) THEN
! 198: ISIDE = 2
! 199: COMPL = .TRUE.
! 200: COMPR = .FALSE.
! 201: ELSE IF( LSAME( SIDE, 'B' ) ) THEN
! 202: ISIDE = 3
! 203: COMPL = .TRUE.
! 204: COMPR = .TRUE.
! 205: ELSE
! 206: ISIDE = -1
! 207: END IF
! 208: *
! 209: INFO = 0
! 210: IF( ISIDE.LT.0 ) THEN
! 211: INFO = -1
! 212: ELSE IF( IHWMNY.LT.0 ) THEN
! 213: INFO = -2
! 214: ELSE IF( N.LT.0 ) THEN
! 215: INFO = -4
! 216: ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
! 217: INFO = -6
! 218: ELSE IF( LDP.LT.MAX( 1, N ) ) THEN
! 219: INFO = -8
! 220: END IF
! 221: IF( INFO.NE.0 ) THEN
! 222: CALL XERBLA( 'ZTGEVC', -INFO )
! 223: RETURN
! 224: END IF
! 225: *
! 226: * Count the number of eigenvectors
! 227: *
! 228: IF( .NOT.ILALL ) THEN
! 229: IM = 0
! 230: DO 10 J = 1, N
! 231: IF( SELECT( J ) )
! 232: $ IM = IM + 1
! 233: 10 CONTINUE
! 234: ELSE
! 235: IM = N
! 236: END IF
! 237: *
! 238: * Check diagonal of B
! 239: *
! 240: ILBBAD = .FALSE.
! 241: DO 20 J = 1, N
! 242: IF( DIMAG( P( J, J ) ).NE.ZERO )
! 243: $ ILBBAD = .TRUE.
! 244: 20 CONTINUE
! 245: *
! 246: IF( ILBBAD ) THEN
! 247: INFO = -7
! 248: ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THEN
! 249: INFO = -10
! 250: ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THEN
! 251: INFO = -12
! 252: ELSE IF( MM.LT.IM ) THEN
! 253: INFO = -13
! 254: END IF
! 255: IF( INFO.NE.0 ) THEN
! 256: CALL XERBLA( 'ZTGEVC', -INFO )
! 257: RETURN
! 258: END IF
! 259: *
! 260: * Quick return if possible
! 261: *
! 262: M = IM
! 263: IF( N.EQ.0 )
! 264: $ RETURN
! 265: *
! 266: * Machine Constants
! 267: *
! 268: SAFMIN = DLAMCH( 'Safe minimum' )
! 269: BIG = ONE / SAFMIN
! 270: CALL DLABAD( SAFMIN, BIG )
! 271: ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
! 272: SMALL = SAFMIN*N / ULP
! 273: BIG = ONE / SMALL
! 274: BIGNUM = ONE / ( SAFMIN*N )
! 275: *
! 276: * Compute the 1-norm of each column of the strictly upper triangular
! 277: * part of A and B to check for possible overflow in the triangular
! 278: * solver.
! 279: *
! 280: ANORM = ABS1( S( 1, 1 ) )
! 281: BNORM = ABS1( P( 1, 1 ) )
! 282: RWORK( 1 ) = ZERO
! 283: RWORK( N+1 ) = ZERO
! 284: DO 40 J = 2, N
! 285: RWORK( J ) = ZERO
! 286: RWORK( N+J ) = ZERO
! 287: DO 30 I = 1, J - 1
! 288: RWORK( J ) = RWORK( J ) + ABS1( S( I, J ) )
! 289: RWORK( N+J ) = RWORK( N+J ) + ABS1( P( I, J ) )
! 290: 30 CONTINUE
! 291: ANORM = MAX( ANORM, RWORK( J )+ABS1( S( J, J ) ) )
! 292: BNORM = MAX( BNORM, RWORK( N+J )+ABS1( P( J, J ) ) )
! 293: 40 CONTINUE
! 294: *
! 295: ASCALE = ONE / MAX( ANORM, SAFMIN )
! 296: BSCALE = ONE / MAX( BNORM, SAFMIN )
! 297: *
! 298: * Left eigenvectors
! 299: *
! 300: IF( COMPL ) THEN
! 301: IEIG = 0
! 302: *
! 303: * Main loop over eigenvalues
! 304: *
! 305: DO 140 JE = 1, N
! 306: IF( ILALL ) THEN
! 307: ILCOMP = .TRUE.
! 308: ELSE
! 309: ILCOMP = SELECT( JE )
! 310: END IF
! 311: IF( ILCOMP ) THEN
! 312: IEIG = IEIG + 1
! 313: *
! 314: IF( ABS1( S( JE, JE ) ).LE.SAFMIN .AND.
! 315: $ ABS( DBLE( P( JE, JE ) ) ).LE.SAFMIN ) THEN
! 316: *
! 317: * Singular matrix pencil -- return unit eigenvector
! 318: *
! 319: DO 50 JR = 1, N
! 320: VL( JR, IEIG ) = CZERO
! 321: 50 CONTINUE
! 322: VL( IEIG, IEIG ) = CONE
! 323: GO TO 140
! 324: END IF
! 325: *
! 326: * Non-singular eigenvalue:
! 327: * Compute coefficients a and b in
! 328: * H
! 329: * y ( a A - b B ) = 0
! 330: *
! 331: TEMP = ONE / MAX( ABS1( S( JE, JE ) )*ASCALE,
! 332: $ ABS( DBLE( P( JE, JE ) ) )*BSCALE, SAFMIN )
! 333: SALPHA = ( TEMP*S( JE, JE ) )*ASCALE
! 334: SBETA = ( TEMP*DBLE( P( JE, JE ) ) )*BSCALE
! 335: ACOEFF = SBETA*ASCALE
! 336: BCOEFF = SALPHA*BSCALE
! 337: *
! 338: * Scale to avoid underflow
! 339: *
! 340: LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEFF ).LT.SMALL
! 341: LSB = ABS1( SALPHA ).GE.SAFMIN .AND. ABS1( BCOEFF ).LT.
! 342: $ SMALL
! 343: *
! 344: SCALE = ONE
! 345: IF( LSA )
! 346: $ SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
! 347: IF( LSB )
! 348: $ SCALE = MAX( SCALE, ( SMALL / ABS1( SALPHA ) )*
! 349: $ MIN( BNORM, BIG ) )
! 350: IF( LSA .OR. LSB ) THEN
! 351: SCALE = MIN( SCALE, ONE /
! 352: $ ( SAFMIN*MAX( ONE, ABS( ACOEFF ),
! 353: $ ABS1( BCOEFF ) ) ) )
! 354: IF( LSA ) THEN
! 355: ACOEFF = ASCALE*( SCALE*SBETA )
! 356: ELSE
! 357: ACOEFF = SCALE*ACOEFF
! 358: END IF
! 359: IF( LSB ) THEN
! 360: BCOEFF = BSCALE*( SCALE*SALPHA )
! 361: ELSE
! 362: BCOEFF = SCALE*BCOEFF
! 363: END IF
! 364: END IF
! 365: *
! 366: ACOEFA = ABS( ACOEFF )
! 367: BCOEFA = ABS1( BCOEFF )
! 368: XMAX = ONE
! 369: DO 60 JR = 1, N
! 370: WORK( JR ) = CZERO
! 371: 60 CONTINUE
! 372: WORK( JE ) = CONE
! 373: DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
! 374: *
! 375: * H
! 376: * Triangular solve of (a A - b B) y = 0
! 377: *
! 378: * H
! 379: * (rowwise in (a A - b B) , or columnwise in a A - b B)
! 380: *
! 381: DO 100 J = JE + 1, N
! 382: *
! 383: * Compute
! 384: * j-1
! 385: * SUM = sum conjg( a*S(k,j) - b*P(k,j) )*x(k)
! 386: * k=je
! 387: * (Scale if necessary)
! 388: *
! 389: TEMP = ONE / XMAX
! 390: IF( ACOEFA*RWORK( J )+BCOEFA*RWORK( N+J ).GT.BIGNUM*
! 391: $ TEMP ) THEN
! 392: DO 70 JR = JE, J - 1
! 393: WORK( JR ) = TEMP*WORK( JR )
! 394: 70 CONTINUE
! 395: XMAX = ONE
! 396: END IF
! 397: SUMA = CZERO
! 398: SUMB = CZERO
! 399: *
! 400: DO 80 JR = JE, J - 1
! 401: SUMA = SUMA + DCONJG( S( JR, J ) )*WORK( JR )
! 402: SUMB = SUMB + DCONJG( P( JR, J ) )*WORK( JR )
! 403: 80 CONTINUE
! 404: SUM = ACOEFF*SUMA - DCONJG( BCOEFF )*SUMB
! 405: *
! 406: * Form x(j) = - SUM / conjg( a*S(j,j) - b*P(j,j) )
! 407: *
! 408: * with scaling and perturbation of the denominator
! 409: *
! 410: D = DCONJG( ACOEFF*S( J, J )-BCOEFF*P( J, J ) )
! 411: IF( ABS1( D ).LE.DMIN )
! 412: $ D = DCMPLX( DMIN )
! 413: *
! 414: IF( ABS1( D ).LT.ONE ) THEN
! 415: IF( ABS1( SUM ).GE.BIGNUM*ABS1( D ) ) THEN
! 416: TEMP = ONE / ABS1( SUM )
! 417: DO 90 JR = JE, J - 1
! 418: WORK( JR ) = TEMP*WORK( JR )
! 419: 90 CONTINUE
! 420: XMAX = TEMP*XMAX
! 421: SUM = TEMP*SUM
! 422: END IF
! 423: END IF
! 424: WORK( J ) = ZLADIV( -SUM, D )
! 425: XMAX = MAX( XMAX, ABS1( WORK( J ) ) )
! 426: 100 CONTINUE
! 427: *
! 428: * Back transform eigenvector if HOWMNY='B'.
! 429: *
! 430: IF( ILBACK ) THEN
! 431: CALL ZGEMV( 'N', N, N+1-JE, CONE, VL( 1, JE ), LDVL,
! 432: $ WORK( JE ), 1, CZERO, WORK( N+1 ), 1 )
! 433: ISRC = 2
! 434: IBEG = 1
! 435: ELSE
! 436: ISRC = 1
! 437: IBEG = JE
! 438: END IF
! 439: *
! 440: * Copy and scale eigenvector into column of VL
! 441: *
! 442: XMAX = ZERO
! 443: DO 110 JR = IBEG, N
! 444: XMAX = MAX( XMAX, ABS1( WORK( ( ISRC-1 )*N+JR ) ) )
! 445: 110 CONTINUE
! 446: *
! 447: IF( XMAX.GT.SAFMIN ) THEN
! 448: TEMP = ONE / XMAX
! 449: DO 120 JR = IBEG, N
! 450: VL( JR, IEIG ) = TEMP*WORK( ( ISRC-1 )*N+JR )
! 451: 120 CONTINUE
! 452: ELSE
! 453: IBEG = N + 1
! 454: END IF
! 455: *
! 456: DO 130 JR = 1, IBEG - 1
! 457: VL( JR, IEIG ) = CZERO
! 458: 130 CONTINUE
! 459: *
! 460: END IF
! 461: 140 CONTINUE
! 462: END IF
! 463: *
! 464: * Right eigenvectors
! 465: *
! 466: IF( COMPR ) THEN
! 467: IEIG = IM + 1
! 468: *
! 469: * Main loop over eigenvalues
! 470: *
! 471: DO 250 JE = N, 1, -1
! 472: IF( ILALL ) THEN
! 473: ILCOMP = .TRUE.
! 474: ELSE
! 475: ILCOMP = SELECT( JE )
! 476: END IF
! 477: IF( ILCOMP ) THEN
! 478: IEIG = IEIG - 1
! 479: *
! 480: IF( ABS1( S( JE, JE ) ).LE.SAFMIN .AND.
! 481: $ ABS( DBLE( P( JE, JE ) ) ).LE.SAFMIN ) THEN
! 482: *
! 483: * Singular matrix pencil -- return unit eigenvector
! 484: *
! 485: DO 150 JR = 1, N
! 486: VR( JR, IEIG ) = CZERO
! 487: 150 CONTINUE
! 488: VR( IEIG, IEIG ) = CONE
! 489: GO TO 250
! 490: END IF
! 491: *
! 492: * Non-singular eigenvalue:
! 493: * Compute coefficients a and b in
! 494: *
! 495: * ( a A - b B ) x = 0
! 496: *
! 497: TEMP = ONE / MAX( ABS1( S( JE, JE ) )*ASCALE,
! 498: $ ABS( DBLE( P( JE, JE ) ) )*BSCALE, SAFMIN )
! 499: SALPHA = ( TEMP*S( JE, JE ) )*ASCALE
! 500: SBETA = ( TEMP*DBLE( P( JE, JE ) ) )*BSCALE
! 501: ACOEFF = SBETA*ASCALE
! 502: BCOEFF = SALPHA*BSCALE
! 503: *
! 504: * Scale to avoid underflow
! 505: *
! 506: LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEFF ).LT.SMALL
! 507: LSB = ABS1( SALPHA ).GE.SAFMIN .AND. ABS1( BCOEFF ).LT.
! 508: $ SMALL
! 509: *
! 510: SCALE = ONE
! 511: IF( LSA )
! 512: $ SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
! 513: IF( LSB )
! 514: $ SCALE = MAX( SCALE, ( SMALL / ABS1( SALPHA ) )*
! 515: $ MIN( BNORM, BIG ) )
! 516: IF( LSA .OR. LSB ) THEN
! 517: SCALE = MIN( SCALE, ONE /
! 518: $ ( SAFMIN*MAX( ONE, ABS( ACOEFF ),
! 519: $ ABS1( BCOEFF ) ) ) )
! 520: IF( LSA ) THEN
! 521: ACOEFF = ASCALE*( SCALE*SBETA )
! 522: ELSE
! 523: ACOEFF = SCALE*ACOEFF
! 524: END IF
! 525: IF( LSB ) THEN
! 526: BCOEFF = BSCALE*( SCALE*SALPHA )
! 527: ELSE
! 528: BCOEFF = SCALE*BCOEFF
! 529: END IF
! 530: END IF
! 531: *
! 532: ACOEFA = ABS( ACOEFF )
! 533: BCOEFA = ABS1( BCOEFF )
! 534: XMAX = ONE
! 535: DO 160 JR = 1, N
! 536: WORK( JR ) = CZERO
! 537: 160 CONTINUE
! 538: WORK( JE ) = CONE
! 539: DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
! 540: *
! 541: * Triangular solve of (a A - b B) x = 0 (columnwise)
! 542: *
! 543: * WORK(1:j-1) contains sums w,
! 544: * WORK(j+1:JE) contains x
! 545: *
! 546: DO 170 JR = 1, JE - 1
! 547: WORK( JR ) = ACOEFF*S( JR, JE ) - BCOEFF*P( JR, JE )
! 548: 170 CONTINUE
! 549: WORK( JE ) = CONE
! 550: *
! 551: DO 210 J = JE - 1, 1, -1
! 552: *
! 553: * Form x(j) := - w(j) / d
! 554: * with scaling and perturbation of the denominator
! 555: *
! 556: D = ACOEFF*S( J, J ) - BCOEFF*P( J, J )
! 557: IF( ABS1( D ).LE.DMIN )
! 558: $ D = DCMPLX( DMIN )
! 559: *
! 560: IF( ABS1( D ).LT.ONE ) THEN
! 561: IF( ABS1( WORK( J ) ).GE.BIGNUM*ABS1( D ) ) THEN
! 562: TEMP = ONE / ABS1( WORK( J ) )
! 563: DO 180 JR = 1, JE
! 564: WORK( JR ) = TEMP*WORK( JR )
! 565: 180 CONTINUE
! 566: END IF
! 567: END IF
! 568: *
! 569: WORK( J ) = ZLADIV( -WORK( J ), D )
! 570: *
! 571: IF( J.GT.1 ) THEN
! 572: *
! 573: * w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling
! 574: *
! 575: IF( ABS1( WORK( J ) ).GT.ONE ) THEN
! 576: TEMP = ONE / ABS1( WORK( J ) )
! 577: IF( ACOEFA*RWORK( J )+BCOEFA*RWORK( N+J ).GE.
! 578: $ BIGNUM*TEMP ) THEN
! 579: DO 190 JR = 1, JE
! 580: WORK( JR ) = TEMP*WORK( JR )
! 581: 190 CONTINUE
! 582: END IF
! 583: END IF
! 584: *
! 585: CA = ACOEFF*WORK( J )
! 586: CB = BCOEFF*WORK( J )
! 587: DO 200 JR = 1, J - 1
! 588: WORK( JR ) = WORK( JR ) + CA*S( JR, J ) -
! 589: $ CB*P( JR, J )
! 590: 200 CONTINUE
! 591: END IF
! 592: 210 CONTINUE
! 593: *
! 594: * Back transform eigenvector if HOWMNY='B'.
! 595: *
! 596: IF( ILBACK ) THEN
! 597: CALL ZGEMV( 'N', N, JE, CONE, VR, LDVR, WORK, 1,
! 598: $ CZERO, WORK( N+1 ), 1 )
! 599: ISRC = 2
! 600: IEND = N
! 601: ELSE
! 602: ISRC = 1
! 603: IEND = JE
! 604: END IF
! 605: *
! 606: * Copy and scale eigenvector into column of VR
! 607: *
! 608: XMAX = ZERO
! 609: DO 220 JR = 1, IEND
! 610: XMAX = MAX( XMAX, ABS1( WORK( ( ISRC-1 )*N+JR ) ) )
! 611: 220 CONTINUE
! 612: *
! 613: IF( XMAX.GT.SAFMIN ) THEN
! 614: TEMP = ONE / XMAX
! 615: DO 230 JR = 1, IEND
! 616: VR( JR, IEIG ) = TEMP*WORK( ( ISRC-1 )*N+JR )
! 617: 230 CONTINUE
! 618: ELSE
! 619: IEND = 0
! 620: END IF
! 621: *
! 622: DO 240 JR = IEND + 1, N
! 623: VR( JR, IEIG ) = CZERO
! 624: 240 CONTINUE
! 625: *
! 626: END IF
! 627: 250 CONTINUE
! 628: END IF
! 629: *
! 630: RETURN
! 631: *
! 632: * End of ZTGEVC
! 633: *
! 634: END
CVSweb interface <joel.bertrand@systella.fr>