File:  [local] / rpl / lapack / lapack / zggesx.f
Revision 1.19: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:39:20 2023 UTC (8 months, 3 weeks ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_35, rpl-4_1_34, HEAD
Première mise à jour de lapack et blas.

    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 a 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: *> \ingroup complex16GEeigen
  324: *
  325: *  =====================================================================
  326:       SUBROUTINE ZGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,
  327:      $                   B, LDB, SDIM, ALPHA, BETA, VSL, LDVSL, VSR,
  328:      $                   LDVSR, RCONDE, RCONDV, WORK, LWORK, RWORK,
  329:      $                   IWORK, LIWORK, BWORK, INFO )
  330: *
  331: *  -- LAPACK driver routine --
  332: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  333: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  334: *
  335: *     .. Scalar Arguments ..
  336:       CHARACTER          JOBVSL, JOBVSR, SENSE, SORT
  337:       INTEGER            INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,
  338:      $                   SDIM
  339: *     ..
  340: *     .. Array Arguments ..
  341:       LOGICAL            BWORK( * )
  342:       INTEGER            IWORK( * )
  343:       DOUBLE PRECISION   RCONDE( 2 ), RCONDV( 2 ), RWORK( * )
  344:       COMPLEX*16         A( LDA, * ), ALPHA( * ), B( LDB, * ),
  345:      $                   BETA( * ), VSL( LDVSL, * ), VSR( LDVSR, * ),
  346:      $                   WORK( * )
  347: *     ..
  348: *     .. Function Arguments ..
  349:       LOGICAL            SELCTG
  350:       EXTERNAL           SELCTG
  351: *     ..
  352: *
  353: *  =====================================================================
  354: *
  355: *     .. Parameters ..
  356:       DOUBLE PRECISION   ZERO, ONE
  357:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
  358:       COMPLEX*16         CZERO, CONE
  359:       PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
  360:      $                   CONE = ( 1.0D+0, 0.0D+0 ) )
  361: *     ..
  362: *     .. Local Scalars ..
  363:       LOGICAL            CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,
  364:      $                   LQUERY, WANTSB, WANTSE, WANTSN, WANTST, WANTSV
  365:       INTEGER            I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,
  366:      $                   ILEFT, ILO, IRIGHT, IROWS, IRWRK, ITAU, IWRK,
  367:      $                   LIWMIN, LWRK, MAXWRK, MINWRK
  368:       DOUBLE PRECISION   ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,
  369:      $                   PR, SMLNUM
  370: *     ..
  371: *     .. Local Arrays ..
  372:       DOUBLE PRECISION   DIF( 2 )
  373: *     ..
  374: *     .. External Subroutines ..
  375:       EXTERNAL           DLABAD, XERBLA, ZGEQRF, ZGGBAK, ZGGBAL, ZGGHRD,
  376:      $                   ZHGEQZ, ZLACPY, ZLASCL, ZLASET, ZTGSEN, ZUNGQR,
  377:      $                   ZUNMQR
  378: *     ..
  379: *     .. External Functions ..
  380:       LOGICAL            LSAME
  381:       INTEGER            ILAENV
  382:       DOUBLE PRECISION   DLAMCH, ZLANGE
  383:       EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
  384: *     ..
  385: *     .. Intrinsic Functions ..
  386:       INTRINSIC          MAX, SQRT
  387: *     ..
  388: *     .. Executable Statements ..
  389: *
  390: *     Decode the input arguments
  391: *
  392:       IF( LSAME( JOBVSL, 'N' ) ) THEN
  393:          IJOBVL = 1
  394:          ILVSL = .FALSE.
  395:       ELSE IF( LSAME( JOBVSL, 'V' ) ) THEN
  396:          IJOBVL = 2
  397:          ILVSL = .TRUE.
  398:       ELSE
  399:          IJOBVL = -1
  400:          ILVSL = .FALSE.
  401:       END IF
  402: *
  403:       IF( LSAME( JOBVSR, 'N' ) ) THEN
  404:          IJOBVR = 1
  405:          ILVSR = .FALSE.
  406:       ELSE IF( LSAME( JOBVSR, 'V' ) ) THEN
  407:          IJOBVR = 2
  408:          ILVSR = .TRUE.
  409:       ELSE
  410:          IJOBVR = -1
  411:          ILVSR = .FALSE.
  412:       END IF
  413: *
  414:       WANTST = LSAME( SORT, 'S' )
  415:       WANTSN = LSAME( SENSE, 'N' )
  416:       WANTSE = LSAME( SENSE, 'E' )
  417:       WANTSV = LSAME( SENSE, 'V' )
  418:       WANTSB = LSAME( SENSE, 'B' )
  419:       LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )
  420:       IF( WANTSN ) THEN
  421:          IJOB = 0
  422:       ELSE IF( WANTSE ) THEN
  423:          IJOB = 1
  424:       ELSE IF( WANTSV ) THEN
  425:          IJOB = 2
  426:       ELSE IF( WANTSB ) THEN
  427:          IJOB = 4
  428:       END IF
  429: *
  430: *     Test the input arguments
  431: *
  432:       INFO = 0
  433:       IF( IJOBVL.LE.0 ) THEN
  434:          INFO = -1
  435:       ELSE IF( IJOBVR.LE.0 ) THEN
  436:          INFO = -2
  437:       ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
  438:          INFO = -3
  439:       ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.
  440:      $         ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THEN
  441:          INFO = -5
  442:       ELSE IF( N.LT.0 ) THEN
  443:          INFO = -6
  444:       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  445:          INFO = -8
  446:       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  447:          INFO = -10
  448:       ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THEN
  449:          INFO = -15
  450:       ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THEN
  451:          INFO = -17
  452:       END IF
  453: *
  454: *     Compute workspace
  455: *      (Note: Comments in the code beginning "Workspace:" describe the
  456: *       minimal amount of workspace needed at that point in the code,
  457: *       as well as the preferred amount for good performance.
  458: *       NB refers to the optimal block size for the immediately
  459: *       following subroutine, as returned by ILAENV.)
  460: *
  461:       IF( INFO.EQ.0 ) THEN
  462:          IF( N.GT.0) THEN
  463:             MINWRK = 2*N
  464:             MAXWRK = N*(1 + ILAENV( 1, 'ZGEQRF', ' ', N, 1, N, 0 ) )
  465:             MAXWRK = MAX( MAXWRK, N*( 1 +
  466:      $                    ILAENV( 1, 'ZUNMQR', ' ', N, 1, N, -1 ) ) )
  467:             IF( ILVSL ) THEN
  468:                MAXWRK = MAX( MAXWRK, N*( 1 +
  469:      $                       ILAENV( 1, 'ZUNGQR', ' ', N, 1, N, -1 ) ) )
  470:             END IF
  471:             LWRK = MAXWRK
  472:             IF( IJOB.GE.1 )
  473:      $         LWRK = MAX( LWRK, N*N/2 )
  474:          ELSE
  475:             MINWRK = 1
  476:             MAXWRK = 1
  477:             LWRK   = 1
  478:          END IF
  479:          WORK( 1 ) = LWRK
  480:          IF( WANTSN .OR. N.EQ.0 ) THEN
  481:             LIWMIN = 1
  482:          ELSE
  483:             LIWMIN = N + 2
  484:          END IF
  485:          IWORK( 1 ) = LIWMIN
  486: *
  487:          IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
  488:             INFO = -21
  489:          ELSE IF( LIWORK.LT.LIWMIN  .AND. .NOT.LQUERY) THEN
  490:             INFO = -24
  491:          END IF
  492:       END IF
  493: *
  494:       IF( INFO.NE.0 ) THEN
  495:          CALL XERBLA( 'ZGGESX', -INFO )
  496:          RETURN
  497:       ELSE IF (LQUERY) THEN
  498:          RETURN
  499:       END IF
  500: *
  501: *     Quick return if possible
  502: *
  503:       IF( N.EQ.0 ) THEN
  504:          SDIM = 0
  505:          RETURN
  506:       END IF
  507: *
  508: *     Get machine constants
  509: *
  510:       EPS = DLAMCH( 'P' )
  511:       SMLNUM = DLAMCH( 'S' )
  512:       BIGNUM = ONE / SMLNUM
  513:       CALL DLABAD( SMLNUM, BIGNUM )
  514:       SMLNUM = SQRT( SMLNUM ) / EPS
  515:       BIGNUM = ONE / SMLNUM
  516: *
  517: *     Scale A if max element outside range [SMLNUM,BIGNUM]
  518: *
  519:       ANRM = ZLANGE( 'M', N, N, A, LDA, RWORK )
  520:       ILASCL = .FALSE.
  521:       IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
  522:          ANRMTO = SMLNUM
  523:          ILASCL = .TRUE.
  524:       ELSE IF( ANRM.GT.BIGNUM ) THEN
  525:          ANRMTO = BIGNUM
  526:          ILASCL = .TRUE.
  527:       END IF
  528:       IF( ILASCL )
  529:      $   CALL ZLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )
  530: *
  531: *     Scale B if max element outside range [SMLNUM,BIGNUM]
  532: *
  533:       BNRM = ZLANGE( 'M', N, N, B, LDB, RWORK )
  534:       ILBSCL = .FALSE.
  535:       IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
  536:          BNRMTO = SMLNUM
  537:          ILBSCL = .TRUE.
  538:       ELSE IF( BNRM.GT.BIGNUM ) THEN
  539:          BNRMTO = BIGNUM
  540:          ILBSCL = .TRUE.
  541:       END IF
  542:       IF( ILBSCL )
  543:      $   CALL ZLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )
  544: *
  545: *     Permute the matrix to make it more nearly triangular
  546: *     (Real Workspace: need 6*N)
  547: *
  548:       ILEFT = 1
  549:       IRIGHT = N + 1
  550:       IRWRK = IRIGHT + N
  551:       CALL ZGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
  552:      $             RWORK( IRIGHT ), RWORK( IRWRK ), IERR )
  553: *
  554: *     Reduce B to triangular form (QR decomposition of B)
  555: *     (Complex Workspace: need N, prefer N*NB)
  556: *
  557:       IROWS = IHI + 1 - ILO
  558:       ICOLS = N + 1 - ILO
  559:       ITAU = 1
  560:       IWRK = ITAU + IROWS
  561:       CALL ZGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
  562:      $             WORK( IWRK ), LWORK+1-IWRK, IERR )
  563: *
  564: *     Apply the unitary transformation to matrix A
  565: *     (Complex Workspace: need N, prefer N*NB)
  566: *
  567:       CALL ZUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
  568:      $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),
  569:      $             LWORK+1-IWRK, IERR )
  570: *
  571: *     Initialize VSL
  572: *     (Complex Workspace: need N, prefer N*NB)
  573: *
  574:       IF( ILVSL ) THEN
  575:          CALL ZLASET( 'Full', N, N, CZERO, CONE, VSL, LDVSL )
  576:          IF( IROWS.GT.1 ) THEN
  577:             CALL ZLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
  578:      $                   VSL( ILO+1, ILO ), LDVSL )
  579:          END IF
  580:          CALL ZUNGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,
  581:      $                WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )
  582:       END IF
  583: *
  584: *     Initialize VSR
  585: *
  586:       IF( ILVSR )
  587:      $   CALL ZLASET( 'Full', N, N, CZERO, CONE, VSR, LDVSR )
  588: *
  589: *     Reduce to generalized Hessenberg form
  590: *     (Workspace: none needed)
  591: *
  592:       CALL ZGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,
  593:      $             LDVSL, VSR, LDVSR, IERR )
  594: *
  595:       SDIM = 0
  596: *
  597: *     Perform QZ algorithm, computing Schur vectors if desired
  598: *     (Complex Workspace: need N)
  599: *     (Real Workspace:    need N)
  600: *
  601:       IWRK = ITAU
  602:       CALL ZHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,
  603:      $             ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, WORK( IWRK ),
  604:      $             LWORK+1-IWRK, RWORK( IRWRK ), IERR )
  605:       IF( IERR.NE.0 ) THEN
  606:          IF( IERR.GT.0 .AND. IERR.LE.N ) THEN
  607:             INFO = IERR
  608:          ELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THEN
  609:             INFO = IERR - N
  610:          ELSE
  611:             INFO = N + 1
  612:          END IF
  613:          GO TO 40
  614:       END IF
  615: *
  616: *     Sort eigenvalues ALPHA/BETA and compute the reciprocal of
  617: *     condition number(s)
  618: *
  619:       IF( WANTST ) THEN
  620: *
  621: *        Undo scaling on eigenvalues before SELCTGing
  622: *
  623:          IF( ILASCL )
  624:      $      CALL ZLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
  625:          IF( ILBSCL )
  626:      $      CALL ZLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
  627: *
  628: *        Select eigenvalues
  629: *
  630:          DO 10 I = 1, N
  631:             BWORK( I ) = SELCTG( ALPHA( I ), BETA( I ) )
  632:    10    CONTINUE
  633: *
  634: *        Reorder eigenvalues, transform Generalized Schur vectors, and
  635: *        compute reciprocal condition numbers
  636: *        (Complex Workspace: If IJOB >= 1, need MAX(1, 2*SDIM*(N-SDIM))
  637: *                            otherwise, need 1 )
  638: *
  639:          CALL ZTGSEN( IJOB, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,
  640:      $                ALPHA, BETA, VSL, LDVSL, VSR, LDVSR, SDIM, PL, PR,
  641:      $                DIF, WORK( IWRK ), LWORK-IWRK+1, IWORK, LIWORK,
  642:      $                IERR )
  643: *
  644:          IF( IJOB.GE.1 )
  645:      $      MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )
  646:          IF( IERR.EQ.-21 ) THEN
  647: *
  648: *            not enough complex workspace
  649: *
  650:             INFO = -21
  651:          ELSE
  652:             IF( IJOB.EQ.1 .OR. IJOB.EQ.4 ) THEN
  653:                RCONDE( 1 ) = PL
  654:                RCONDE( 2 ) = PR
  655:             END IF
  656:             IF( IJOB.EQ.2 .OR. IJOB.EQ.4 ) THEN
  657:                RCONDV( 1 ) = DIF( 1 )
  658:                RCONDV( 2 ) = DIF( 2 )
  659:             END IF
  660:             IF( IERR.EQ.1 )
  661:      $         INFO = N + 3
  662:          END IF
  663: *
  664:       END IF
  665: *
  666: *     Apply permutation to VSL and VSR
  667: *     (Workspace: none needed)
  668: *
  669:       IF( ILVSL )
  670:      $   CALL ZGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
  671:      $                RWORK( IRIGHT ), N, VSL, LDVSL, IERR )
  672: *
  673:       IF( ILVSR )
  674:      $   CALL ZGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
  675:      $                RWORK( IRIGHT ), N, VSR, LDVSR, IERR )
  676: *
  677: *     Undo scaling
  678: *
  679:       IF( ILASCL ) THEN
  680:          CALL ZLASCL( 'U', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )
  681:          CALL ZLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHA, N, IERR )
  682:       END IF
  683: *
  684:       IF( ILBSCL ) THEN
  685:          CALL ZLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )
  686:          CALL ZLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )
  687:       END IF
  688: *
  689:       IF( WANTST ) THEN
  690: *
  691: *        Check if reordering is correct
  692: *
  693:          LASTSL = .TRUE.
  694:          SDIM = 0
  695:          DO 30 I = 1, N
  696:             CURSL = SELCTG( ALPHA( I ), BETA( I ) )
  697:             IF( CURSL )
  698:      $         SDIM = SDIM + 1
  699:             IF( CURSL .AND. .NOT.LASTSL )
  700:      $         INFO = N + 2
  701:             LASTSL = CURSL
  702:    30    CONTINUE
  703: *
  704:       END IF
  705: *
  706:    40 CONTINUE
  707: *
  708:       WORK( 1 ) = MAXWRK
  709:       IWORK( 1 ) = LIWMIN
  710: *
  711:       RETURN
  712: *
  713: *     End of ZGGESX
  714: *
  715:       END

CVSweb interface <joel.bertrand@systella.fr>