Annotation of rpl/lapack/lapack/zggesx.f, revision 1.8
1.8 ! bertrand 1: *> \brief <b> ZGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b>
! 2: *
! 3: * =========== DOCUMENTATION ===========
! 4: *
! 5: * Online html documentation available at
! 6: * http://www.netlib.org/lapack/explore-html/
! 7: *
! 8: *> \htmlonly
! 9: *> Download ZGGESX + dependencies
! 10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zggesx.f">
! 11: *> [TGZ]</a>
! 12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zggesx.f">
! 13: *> [ZIP]</a>
! 14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zggesx.f">
! 15: *> [TXT]</a>
! 16: *> \endhtmlonly
! 17: *
! 18: * Definition:
! 19: * ===========
! 20: *
! 21: * SUBROUTINE ZGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
! 22: * B, LDB, SDIM, ALPHA, BETA, VSL, LDVSL, VSR,
! 23: * LDVSR, RCONDE, RCONDV, WORK, LWORK, RWORK,
! 24: * IWORK, LIWORK, BWORK, INFO )
! 25: *
! 26: * .. Scalar Arguments ..
! 27: * CHARACTER JOBVSL, JOBVSR, SENSE, SORT
! 28: * INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
! 29: * $ SDIM
! 30: * ..
! 31: * .. Array Arguments ..
! 32: * LOGICAL BWORK( * )
! 33: * INTEGER IWORK( * )
! 34: * DOUBLE PRECISION RCONDE( 2 ), RCONDV( 2 ), RWORK( * )
! 35: * COMPLEX*16 A( LDA, * ), ALPHA( * ), B( LDB, * ),
! 36: * $ BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ),
! 37: * $ WORK( * )
! 38: * ..
! 39: * .. Function Arguments ..
! 40: * LOGICAL SELCTG
! 41: * EXTERNAL SELCTG
! 42: * ..
! 43: *
! 44: *
! 45: *> \par Purpose:
! 46: * =============
! 47: *>
! 48: *> \verbatim
! 49: *>
! 50: *> ZGGESX computes for a pair of N-by-N complex nonsymmetric matrices
! 51: *> (A,B), the generalized eigenvalues, the complex Schur form (S,T),
! 52: *> and, optionally, the left and/or right matrices of Schur vectors (VSL
! 53: *> and VSR). This gives the generalized Schur factorization
! 54: *>
! 55: *> (A,B) = ( (VSL) S (VSR)**H, (VSL) T (VSR)**H )
! 56: *>
! 57: *> where (VSR)**H is the conjugate-transpose of VSR.
! 58: *>
! 59: *> Optionally, it also orders the eigenvalues so that a selected cluster
! 60: *> of eigenvalues appears in the leading diagonal blocks of the upper
! 61: *> triangular matrix S and the upper triangular matrix T; computes
! 62: *> a reciprocal condition number for the average of the selected
! 63: *> eigenvalues (RCONDE); and computes a reciprocal condition number for
! 64: *> the right and left deflating subspaces corresponding to the selected
! 65: *> eigenvalues (RCONDV). The leading columns of VSL and VSR then form
! 66: *> an orthonormal basis for the corresponding left and right eigenspaces
! 67: *> (deflating subspaces).
! 68: *>
! 69: *> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w
! 70: *> or a ratio alpha/beta = w, such that A - w*B is singular. It is
! 71: *> usually represented as the pair (alpha,beta), as there is a
! 72: *> reasonable interpretation for beta=0 or for both being zero.
! 73: *>
! 74: *> A pair of matrices (S,T) is in generalized complex Schur form if T is
! 75: *> upper triangular with non-negative diagonal and S is upper
! 76: *> triangular.
! 77: *> \endverbatim
! 78: *
! 79: * Arguments:
! 80: * ==========
! 81: *
! 82: *> \param[in] JOBVSL
! 83: *> \verbatim
! 84: *> JOBVSL is CHARACTER*1
! 85: *> = 'N': do not compute the left Schur vectors;
! 86: *> = 'V': compute the left Schur vectors.
! 87: *> \endverbatim
! 88: *>
! 89: *> \param[in] JOBVSR
! 90: *> \verbatim
! 91: *> JOBVSR is CHARACTER*1
! 92: *> = 'N': do not compute the right Schur vectors;
! 93: *> = 'V': compute the right Schur vectors.
! 94: *> \endverbatim
! 95: *>
! 96: *> \param[in] SORT
! 97: *> \verbatim
! 98: *> SORT is CHARACTER*1
! 99: *> Specifies whether or not to order the eigenvalues on the
! 100: *> diagonal of the generalized Schur form.
! 101: *> = 'N': Eigenvalues are not ordered;
! 102: *> = 'S': Eigenvalues are ordered (see SELCTG).
! 103: *> \endverbatim
! 104: *>
! 105: *> \param[in] SELCTG
! 106: *> \verbatim
! 107: *> SELCTG is procedure) LOGICAL FUNCTION of two COMPLEX*16 arguments
! 108: *> SELCTG must be declared EXTERNAL in the calling subroutine.
! 109: *> If SORT = 'N', SELCTG is not referenced.
! 110: *> If SORT = 'S', SELCTG is used to select eigenvalues to sort
! 111: *> to the top left of the Schur form.
! 112: *> Note that a selected complex eigenvalue may no longer satisfy
! 113: *> SELCTG(ALPHA(j),BETA(j)) = .TRUE. after ordering, since
! 114: *> ordering may change the value of complex eigenvalues
! 115: *> (especially if the eigenvalue is ill-conditioned), in this
! 116: *> case INFO is set to N+3 see INFO below).
! 117: *> \endverbatim
! 118: *>
! 119: *> \param[in] SENSE
! 120: *> \verbatim
! 121: *> SENSE is CHARACTER*1
! 122: *> Determines which reciprocal condition numbers are computed.
! 123: *> = 'N' : None are computed;
! 124: *> = 'E' : Computed for average of selected eigenvalues only;
! 125: *> = 'V' : Computed for selected deflating subspaces only;
! 126: *> = 'B' : Computed for both.
! 127: *> If SENSE = 'E', 'V', or 'B', SORT must equal 'S'.
! 128: *> \endverbatim
! 129: *>
! 130: *> \param[in] N
! 131: *> \verbatim
! 132: *> N is INTEGER
! 133: *> The order of the matrices A, B, VSL, and VSR. N >= 0.
! 134: *> \endverbatim
! 135: *>
! 136: *> \param[in,out] A
! 137: *> \verbatim
! 138: *> A is COMPLEX*16 array, dimension (LDA, N)
! 139: *> On entry, the first of the pair of matrices.
! 140: *> On exit, A has been overwritten by its generalized Schur
! 141: *> form S.
! 142: *> \endverbatim
! 143: *>
! 144: *> \param[in] LDA
! 145: *> \verbatim
! 146: *> LDA is INTEGER
! 147: *> The leading dimension of A. LDA >= max(1,N).
! 148: *> \endverbatim
! 149: *>
! 150: *> \param[in,out] B
! 151: *> \verbatim
! 152: *> B is COMPLEX*16 array, dimension (LDB, N)
! 153: *> On entry, the second of the pair of matrices.
! 154: *> On exit, B has been overwritten by its generalized Schur
! 155: *> form T.
! 156: *> \endverbatim
! 157: *>
! 158: *> \param[in] LDB
! 159: *> \verbatim
! 160: *> LDB is INTEGER
! 161: *> The leading dimension of B. LDB >= max(1,N).
! 162: *> \endverbatim
! 163: *>
! 164: *> \param[out] SDIM
! 165: *> \verbatim
! 166: *> SDIM is INTEGER
! 167: *> If SORT = 'N', SDIM = 0.
! 168: *> If SORT = 'S', SDIM = number of eigenvalues (after sorting)
! 169: *> for which SELCTG is true.
! 170: *> \endverbatim
! 171: *>
! 172: *> \param[out] ALPHA
! 173: *> \verbatim
! 174: *> ALPHA is COMPLEX*16 array, dimension (N)
! 175: *> \endverbatim
! 176: *>
! 177: *> \param[out] BETA
! 178: *> \verbatim
! 179: *> BETA is COMPLEX*16 array, dimension (N)
! 180: *> On exit, ALPHA(j)/BETA(j), j=1,...,N, will be the
! 181: *> generalized eigenvalues. ALPHA(j) and BETA(j),j=1,...,N are
! 182: *> the diagonals of the complex Schur form (S,T). BETA(j) will
! 183: *> be non-negative real.
! 184: *>
! 185: *> Note: the quotients ALPHA(j)/BETA(j) may easily over- or
! 186: *> underflow, and BETA(j) may even be zero. Thus, the user
! 187: *> should avoid naively computing the ratio alpha/beta.
! 188: *> However, ALPHA will be always less than and usually
! 189: *> comparable with norm(A) in magnitude, and BETA always less
! 190: *> than and usually comparable with norm(B).
! 191: *> \endverbatim
! 192: *>
! 193: *> \param[out] VSL
! 194: *> \verbatim
! 195: *> VSL is COMPLEX*16 array, dimension (LDVSL,N)
! 196: *> If JOBVSL = 'V', VSL will contain the left Schur vectors.
! 197: *> Not referenced if JOBVSL = 'N'.
! 198: *> \endverbatim
! 199: *>
! 200: *> \param[in] LDVSL
! 201: *> \verbatim
! 202: *> LDVSL is INTEGER
! 203: *> The leading dimension of the matrix VSL. LDVSL >=1, and
! 204: *> if JOBVSL = 'V', LDVSL >= N.
! 205: *> \endverbatim
! 206: *>
! 207: *> \param[out] VSR
! 208: *> \verbatim
! 209: *> VSR is COMPLEX*16 array, dimension (LDVSR,N)
! 210: *> If JOBVSR = 'V', VSR will contain the right Schur vectors.
! 211: *> Not referenced if JOBVSR = 'N'.
! 212: *> \endverbatim
! 213: *>
! 214: *> \param[in] LDVSR
! 215: *> \verbatim
! 216: *> LDVSR is INTEGER
! 217: *> The leading dimension of the matrix VSR. LDVSR >= 1, and
! 218: *> if JOBVSR = 'V', LDVSR >= N.
! 219: *> \endverbatim
! 220: *>
! 221: *> \param[out] RCONDE
! 222: *> \verbatim
! 223: *> RCONDE is DOUBLE PRECISION array, dimension ( 2 )
! 224: *> If SENSE = 'E' or 'B', RCONDE(1) and RCONDE(2) contain the
! 225: *> reciprocal condition numbers for the average of the selected
! 226: *> eigenvalues.
! 227: *> Not referenced if SENSE = 'N' or 'V'.
! 228: *> \endverbatim
! 229: *>
! 230: *> \param[out] RCONDV
! 231: *> \verbatim
! 232: *> RCONDV is DOUBLE PRECISION array, dimension ( 2 )
! 233: *> If SENSE = 'V' or 'B', RCONDV(1) and RCONDV(2) contain the
! 234: *> reciprocal condition number for the selected deflating
! 235: *> subspaces.
! 236: *> Not referenced if SENSE = 'N' or 'E'.
! 237: *> \endverbatim
! 238: *>
! 239: *> \param[out] WORK
! 240: *> \verbatim
! 241: *> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
! 242: *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
! 243: *> \endverbatim
! 244: *>
! 245: *> \param[in] LWORK
! 246: *> \verbatim
! 247: *> LWORK is INTEGER
! 248: *> The dimension of the array WORK.
! 249: *> If N = 0, LWORK >= 1, else if SENSE = 'E', 'V', or 'B',
! 250: *> LWORK >= MAX(1,2*N,2*SDIM*(N-SDIM)), else
! 251: *> LWORK >= MAX(1,2*N). Note that 2*SDIM*(N-SDIM) <= N*N/2.
! 252: *> Note also that an error is only returned if
! 253: *> LWORK < MAX(1,2*N), but if SENSE = 'E' or 'V' or 'B' this may
! 254: *> not be large enough.
! 255: *>
! 256: *> If LWORK = -1, then a workspace query is assumed; the routine
! 257: *> only calculates the bound on the optimal size of the WORK
! 258: *> array and the minimum size of the IWORK array, returns these
! 259: *> values as the first entries of the WORK and IWORK arrays, and
! 260: *> no error message related to LWORK or LIWORK is issued by
! 261: *> XERBLA.
! 262: *> \endverbatim
! 263: *>
! 264: *> \param[out] RWORK
! 265: *> \verbatim
! 266: *> RWORK is DOUBLE PRECISION array, dimension ( 8*N )
! 267: *> Real workspace.
! 268: *> \endverbatim
! 269: *>
! 270: *> \param[out] IWORK
! 271: *> \verbatim
! 272: *> IWORK is INTEGER array, dimension (MAX(1,LIWORK))
! 273: *> On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.
! 274: *> \endverbatim
! 275: *>
! 276: *> \param[in] LIWORK
! 277: *> \verbatim
! 278: *> LIWORK is INTEGER
! 279: *> The dimension of the array IWORK.
! 280: *> If SENSE = 'N' or N = 0, LIWORK >= 1, otherwise
! 281: *> LIWORK >= N+2.
! 282: *>
! 283: *> If LIWORK = -1, then a workspace query is assumed; the
! 284: *> routine only calculates the bound on the optimal size of the
! 285: *> WORK array and the minimum size of the IWORK array, returns
! 286: *> these values as the first entries of the WORK and IWORK
! 287: *> arrays, and no error message related to LWORK or LIWORK is
! 288: *> issued by XERBLA.
! 289: *> \endverbatim
! 290: *>
! 291: *> \param[out] BWORK
! 292: *> \verbatim
! 293: *> BWORK is LOGICAL array, dimension (N)
! 294: *> Not referenced if SORT = 'N'.
! 295: *> \endverbatim
! 296: *>
! 297: *> \param[out] INFO
! 298: *> \verbatim
! 299: *> INFO is INTEGER
! 300: *> = 0: successful exit
! 301: *> < 0: if INFO = -i, the i-th argument had an illegal value.
! 302: *> = 1,...,N:
! 303: *> The QZ iteration failed. (A,B) are not in Schur
! 304: *> form, but ALPHA(j) and BETA(j) should be correct for
! 305: *> j=INFO+1,...,N.
! 306: *> > N: =N+1: other than QZ iteration failed in ZHGEQZ
! 307: *> =N+2: after reordering, roundoff changed values of
! 308: *> some complex eigenvalues so that leading
! 309: *> eigenvalues in the Generalized Schur form no
! 310: *> longer satisfy SELCTG=.TRUE. This could also
! 311: *> be caused due to scaling.
! 312: *> =N+3: reordering failed in ZTGSEN.
! 313: *> \endverbatim
! 314: *
! 315: * Authors:
! 316: * ========
! 317: *
! 318: *> \author Univ. of Tennessee
! 319: *> \author Univ. of California Berkeley
! 320: *> \author Univ. of Colorado Denver
! 321: *> \author NAG Ltd.
! 322: *
! 323: *> \date November 2011
! 324: *
! 325: *> \ingroup complex16GEeigen
! 326: *
! 327: * =====================================================================
1.1 bertrand 328: SUBROUTINE ZGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
329: $ B, LDB, SDIM, ALPHA, BETA, VSL, LDVSL, VSR,
330: $ LDVSR, RCONDE, RCONDV, WORK, LWORK, RWORK,
331: $ IWORK, LIWORK, BWORK, INFO )
332: *
1.8 ! bertrand 333: * -- LAPACK driver routine (version 3.4.0) --
1.1 bertrand 334: * -- LAPACK is a software package provided by Univ. of Tennessee, --
335: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
1.8 ! bertrand 336: * November 2011
1.1 bertrand 337: *
338: * .. Scalar Arguments ..
339: CHARACTER JOBVSL, JOBVSR, SENSE, SORT
340: INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
341: $ SDIM
342: * ..
343: * .. Array Arguments ..
344: LOGICAL BWORK( * )
345: INTEGER IWORK( * )
346: DOUBLE PRECISION RCONDE( 2 ), RCONDV( 2 ), RWORK( * )
347: COMPLEX*16 A( LDA, * ), ALPHA( * ), B( LDB, * ),
348: $ BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ),
349: $ WORK( * )
350: * ..
351: * .. Function Arguments ..
352: LOGICAL SELCTG
353: EXTERNAL SELCTG
354: * ..
355: *
356: * =====================================================================
357: *
358: * .. Parameters ..
359: DOUBLE PRECISION ZERO, ONE
360: PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
361: COMPLEX*16 CZERO, CONE
362: PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
363: $ CONE = ( 1.0D+0, 0.0D+0 ) )
364: * ..
365: * .. Local Scalars ..
366: LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
367: $ LQUERY, WANTSB, WANTSE, WANTSN, WANTST, WANTSV
368: INTEGER I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,
369: $ ILEFT, ILO, IRIGHT, IROWS, IRWRK, ITAU, IWRK,
370: $ LIWMIN, LWRK, MAXWRK, MINWRK
371: DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
372: $ PR, SMLNUM
373: * ..
374: * .. Local Arrays ..
375: DOUBLE PRECISION DIF( 2 )
376: * ..
377: * .. External Subroutines ..
378: EXTERNAL DLABAD, XERBLA, ZGEQRF, ZGGBAK, ZGGBAL, ZGGHRD,
379: $ ZHGEQZ, ZLACPY, ZLASCL, ZLASET, ZTGSEN, ZUNGQR,
380: $ ZUNMQR
381: * ..
382: * .. External Functions ..
383: LOGICAL LSAME
384: INTEGER ILAENV
385: DOUBLE PRECISION DLAMCH, ZLANGE
386: EXTERNAL LSAME, ILAENV, DLAMCH, ZLANGE
387: * ..
388: * .. Intrinsic Functions ..
389: INTRINSIC MAX, SQRT
390: * ..
391: * .. Executable Statements ..
392: *
393: * Decode the input arguments
394: *
395: IF( LSAME( JOBVSL, 'N' ) ) THEN
396: IJOBVL = 1
397: ILVSL = .FALSE.
398: ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
399: IJOBVL = 2
400: ILVSL = .TRUE.
401: ELSE
402: IJOBVL = -1
403: ILVSL = .FALSE.
404: END IF
405: *
406: IF( LSAME( JOBVSR, 'N' ) ) THEN
407: IJOBVR = 1
408: ILVSR = .FALSE.
409: ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
410: IJOBVR = 2
411: ILVSR = .TRUE.
412: ELSE
413: IJOBVR = -1
414: ILVSR = .FALSE.
415: END IF
416: *
417: WANTST = LSAME( SORT, 'S' )
418: WANTSN = LSAME( SENSE, 'N' )
419: WANTSE = LSAME( SENSE, 'E' )
420: WANTSV = LSAME( SENSE, 'V' )
421: WANTSB = LSAME( SENSE, 'B' )
422: LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
423: IF( WANTSN ) THEN
424: IJOB = 0
425: ELSE IF( WANTSE ) THEN
426: IJOB = 1
427: ELSE IF( WANTSV ) THEN
428: IJOB = 2
429: ELSE IF( WANTSB ) THEN
430: IJOB = 4
431: END IF
432: *
433: * Test the input arguments
434: *
435: INFO = 0
436: IF( IJOBVL.LE.0 ) THEN
437: INFO = -1
438: ELSE IF( IJOBVR.LE.0 ) THEN
439: INFO = -2
440: ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
441: INFO = -3
442: ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
443: $ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
444: INFO = -5
445: ELSE IF( N.LT.0 ) THEN
446: INFO = -6
447: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
448: INFO = -8
449: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
450: INFO = -10
451: ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
452: INFO = -15
453: ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
454: INFO = -17
455: END IF
456: *
457: * Compute workspace
458: * (Note: Comments in the code beginning "Workspace:" describe the
459: * minimal amount of workspace needed at that point in the code,
460: * as well as the preferred amount for good performance.
461: * NB refers to the optimal block size for the immediately
462: * following subroutine, as returned by ILAENV.)
463: *
464: IF( INFO.EQ.0 ) THEN
465: IF( N.GT.0) THEN
466: MINWRK = 2*N
467: MAXWRK = N*(1 + ILAENV( 1, 'ZGEQRF', ' ', N, 1, N, 0 ) )
468: MAXWRK = MAX( MAXWRK, N*( 1 +
469: $ ILAENV( 1, 'ZUNMQR', ' ', N, 1, N, -1 ) ) )
470: IF( ILVSL ) THEN
471: MAXWRK = MAX( MAXWRK, N*( 1 +
472: $ ILAENV( 1, 'ZUNGQR', ' ', N, 1, N, -1 ) ) )
473: END IF
474: LWRK = MAXWRK
475: IF( IJOB.GE.1 )
476: $ LWRK = MAX( LWRK, N*N/2 )
477: ELSE
478: MINWRK = 1
479: MAXWRK = 1
480: LWRK = 1
481: END IF
482: WORK( 1 ) = LWRK
483: IF( WANTSN .OR. N.EQ.0 ) THEN
484: LIWMIN = 1
485: ELSE
486: LIWMIN = N + 2
487: END IF
488: IWORK( 1 ) = LIWMIN
489: *
490: IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
491: INFO = -21
492: ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY) THEN
493: INFO = -24
494: END IF
495: END IF
496: *
497: IF( INFO.NE.0 ) THEN
498: CALL XERBLA( 'ZGGESX', -INFO )
499: RETURN
500: ELSE IF (LQUERY) THEN
501: RETURN
502: END IF
503: *
504: * Quick return if possible
505: *
506: IF( N.EQ.0 ) THEN
507: SDIM = 0
508: RETURN
509: END IF
510: *
511: * Get machine constants
512: *
513: EPS = DLAMCH( 'P' )
514: SMLNUM = DLAMCH( 'S' )
515: BIGNUM = ONE / SMLNUM
516: CALL DLABAD( SMLNUM, BIGNUM )
517: SMLNUM = SQRT( SMLNUM ) / EPS
518: BIGNUM = ONE / SMLNUM
519: *
520: * Scale A if max element outside range [SMLNUM,BIGNUM]
521: *
522: ANRM = ZLANGE( 'M', N, N, A, LDA, RWORK )
523: ILASCL = .FALSE.
524: IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
525: ANRMTO = SMLNUM
526: ILASCL = .TRUE.
527: ELSE IF( ANRM.GT.BIGNUM ) THEN
528: ANRMTO = BIGNUM
529: ILASCL = .TRUE.
530: END IF
531: IF( ILASCL )
532: $ CALL ZLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
533: *
534: * Scale B if max element outside range [SMLNUM,BIGNUM]
535: *
536: BNRM = ZLANGE( 'M', N, N, B, LDB, RWORK )
537: ILBSCL = .FALSE.
538: IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
539: BNRMTO = SMLNUM
540: ILBSCL = .TRUE.
541: ELSE IF( BNRM.GT.BIGNUM ) THEN
542: BNRMTO = BIGNUM
543: ILBSCL = .TRUE.
544: END IF
545: IF( ILBSCL )
546: $ CALL ZLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
547: *
548: * Permute the matrix to make it more nearly triangular
549: * (Real Workspace: need 6*N)
550: *
551: ILEFT = 1
552: IRIGHT = N + 1
553: IRWRK = IRIGHT + N
554: CALL ZGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
555: $ RWORK( IRIGHT ), RWORK( IRWRK ), IERR )
556: *
557: * Reduce B to triangular form (QR decomposition of B)
558: * (Complex Workspace: need N, prefer N*NB)
559: *
560: IROWS = IHI + 1 - ILO
561: ICOLS = N + 1 - ILO
562: ITAU = 1
563: IWRK = ITAU + IROWS
564: CALL ZGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
565: $ WORK( IWRK ), LWORK+1-IWRK, IERR )
566: *
567: * Apply the unitary transformation to matrix A
568: * (Complex Workspace: need N, prefer N*NB)
569: *
570: CALL ZUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
571: $ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
572: $ LWORK+1-IWRK, IERR )
573: *
574: * Initialize VSL
575: * (Complex Workspace: need N, prefer N*NB)
576: *
577: IF( ILVSL ) THEN
578: CALL ZLASET( 'Full', N, N, CZERO, CONE, VSL, LDVSL )
579: IF( IROWS.GT.1 ) THEN
580: CALL ZLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
581: $ VSL( ILO+1, ILO ), LDVSL )
582: END IF
583: CALL ZUNGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
584: $ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
585: END IF
586: *
587: * Initialize VSR
588: *
589: IF( ILVSR )
590: $ CALL ZLASET( 'Full', N, N, CZERO, CONE, VSR, LDVSR )
591: *
592: * Reduce to generalized Hessenberg form
593: * (Workspace: none needed)
594: *
595: CALL ZGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
596: $ LDVSL, VSR, LDVSR, IERR )
597: *
598: SDIM = 0
599: *
600: * Perform QZ algorithm, computing Schur vectors if desired
601: * (Complex Workspace: need N)
602: * (Real Workspace: need N)
603: *
604: IWRK = ITAU
605: CALL ZHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
606: $ ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK( IWRK ),
607: $ LWORK+1-IWRK, RWORK( IRWRK ), IERR )
608: IF( IERR.NE.0 ) THEN
609: IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
610: INFO = IERR
611: ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
612: INFO = IERR - N
613: ELSE
614: INFO = N + 1
615: END IF
616: GO TO 40
617: END IF
618: *
619: * Sort eigenvalues ALPHA/BETA and compute the reciprocal of
620: * condition number(s)
621: *
622: IF( WANTST ) THEN
623: *
624: * Undo scaling on eigenvalues before SELCTGing
625: *
626: IF( ILASCL )
627: $ CALL ZLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
628: IF( ILBSCL )
629: $ CALL ZLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
630: *
631: * Select eigenvalues
632: *
633: DO 10 I = 1, N
634: BWORK( I ) = SELCTG( ALPHA( I ), BETA( I ) )
635: 10 CONTINUE
636: *
637: * Reorder eigenvalues, transform Generalized Schur vectors, and
638: * compute reciprocal condition numbers
639: * (Complex Workspace: If IJOB >= 1, need MAX(1, 2*SDIM*(N-SDIM))
640: * otherwise, need 1 )
641: *
642: CALL ZTGSEN( IJOB, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
643: $ ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, SDIM, PL, PR,
644: $ DIF, WORK( IWRK ), LWORK-IWRK+1, IWORK, LIWORK,
645: $ IERR )
646: *
647: IF( IJOB.GE.1 )
648: $ MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )
649: IF( IERR.EQ.-21 ) THEN
650: *
651: * not enough complex workspace
652: *
653: INFO = -21
654: ELSE
655: IF( IJOB.EQ.1 .OR. IJOB.EQ.4 ) THEN
656: RCONDE( 1 ) = PL
657: RCONDE( 2 ) = PR
658: END IF
659: IF( IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
660: RCONDV( 1 ) = DIF( 1 )
661: RCONDV( 2 ) = DIF( 2 )
662: END IF
663: IF( IERR.EQ.1 )
664: $ INFO = N + 3
665: END IF
666: *
667: END IF
668: *
669: * Apply permutation to VSL and VSR
670: * (Workspace: none needed)
671: *
672: IF( ILVSL )
673: $ CALL ZGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
674: $ RWORK( IRIGHT ), N, VSL, LDVSL, IERR )
675: *
676: IF( ILVSR )
677: $ CALL ZGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
678: $ RWORK( IRIGHT ), N, VSR, LDVSR, IERR )
679: *
680: * Undo scaling
681: *
682: IF( ILASCL ) THEN
683: CALL ZLASCL( 'U', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )
684: CALL ZLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
685: END IF
686: *
687: IF( ILBSCL ) THEN
688: CALL ZLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )
689: CALL ZLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
690: END IF
691: *
692: IF( WANTST ) THEN
693: *
694: * Check if reordering is correct
695: *
696: LASTSL = .TRUE.
697: SDIM = 0
698: DO 30 I = 1, N
699: CURSL = SELCTG( ALPHA( I ), BETA( I ) )
700: IF( CURSL )
701: $ SDIM = SDIM + 1
702: IF( CURSL .AND. .NOT.LASTSL )
703: $ INFO = N + 2
704: LASTSL = CURSL
705: 30 CONTINUE
706: *
707: END IF
708: *
709: 40 CONTINUE
710: *
711: WORK( 1 ) = MAXWRK
712: IWORK( 1 ) = LIWMIN
713: *
714: RETURN
715: *
716: * End of ZGGESX
717: *
718: END
CVSweb interface <joel.bertrand@systella.fr>