File:  [local] / rpl / lapack / lapack / zgegv.f
Revision 1.17: download - view: text, annotated - select for diffs - revision graph
Mon Aug 7 08:39:16 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> ZGEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors 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 ZGEGV + dependencies
   10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgegv.f">
   11: *> [TGZ]</a>
   12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgegv.f">
   13: *> [ZIP]</a>
   14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgegv.f">
   15: *> [TXT]</a>
   16: *> \endhtmlonly
   17: *
   18: *  Definition:
   19: *  ===========
   20: *
   21: *       SUBROUTINE ZGEGV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
   22: *                         VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
   23: *
   24: *       .. Scalar Arguments ..
   25: *       CHARACTER          JOBVL, JOBVR
   26: *       INTEGER            INFO, LDA, LDB, LDVL, LDVR, LWORK, N
   27: *       ..
   28: *       .. Array Arguments ..
   29: *       DOUBLE PRECISION   RWORK( * )
   30: *       COMPLEX*16         A( LDA, * ), ALPHA( * ), B( LDB, * ),
   31: *      $                   BETA( * ), VL( LDVL, * ), VR( LDVR, * ),
   32: *      $                   WORK( * )
   33: *       ..
   34: *
   35: *
   36: *> \par Purpose:
   37: *  =============
   38: *>
   39: *> \verbatim
   40: *>
   41: *> This routine is deprecated and has been replaced by routine ZGGEV.
   42: *>
   43: *> ZGEGV computes the eigenvalues and, optionally, the left and/or right
   44: *> eigenvectors of a complex matrix pair (A,B).
   45: *> Given two square matrices A and B,
   46: *> the generalized nonsymmetric eigenvalue problem (GNEP) is to find the
   47: *> eigenvalues lambda and corresponding (non-zero) eigenvectors x such
   48: *> that
   49: *>    A*x = lambda*B*x.
   50: *>
   51: *> An alternate form is to find the eigenvalues mu and corresponding
   52: *> eigenvectors y such that
   53: *>    mu*A*y = B*y.
   54: *>
   55: *> These two forms are equivalent with mu = 1/lambda and x = y if
   56: *> neither lambda nor mu is zero.  In order to deal with the case that
   57: *> lambda or mu is zero or small, two values alpha and beta are returned
   58: *> for each eigenvalue, such that lambda = alpha/beta and
   59: *> mu = beta/alpha.
   60: *>
   61: *> The vectors x and y in the above equations are right eigenvectors of
   62: *> the matrix pair (A,B).  Vectors u and v satisfying
   63: *>    u**H*A = lambda*u**H*B  or  mu*v**H*A = v**H*B
   64: *> are left eigenvectors of (A,B).
   65: *>
   66: *> Note: this routine performs "full balancing" on A and B
   67: *> \endverbatim
   68: *
   69: *  Arguments:
   70: *  ==========
   71: *
   72: *> \param[in] JOBVL
   73: *> \verbatim
   74: *>          JOBVL is CHARACTER*1
   75: *>          = 'N':  do not compute the left generalized eigenvectors;
   76: *>          = 'V':  compute the left generalized eigenvectors (returned
   77: *>                  in VL).
   78: *> \endverbatim
   79: *>
   80: *> \param[in] JOBVR
   81: *> \verbatim
   82: *>          JOBVR is CHARACTER*1
   83: *>          = 'N':  do not compute the right generalized eigenvectors;
   84: *>          = 'V':  compute the right generalized eigenvectors (returned
   85: *>                  in VR).
   86: *> \endverbatim
   87: *>
   88: *> \param[in] N
   89: *> \verbatim
   90: *>          N is INTEGER
   91: *>          The order of the matrices A, B, VL, and VR.  N >= 0.
   92: *> \endverbatim
   93: *>
   94: *> \param[in,out] A
   95: *> \verbatim
   96: *>          A is COMPLEX*16 array, dimension (LDA, N)
   97: *>          On entry, the matrix A.
   98: *>          If JOBVL = 'V' or JOBVR = 'V', then on exit A
   99: *>          contains the Schur form of A from the generalized Schur
  100: *>          factorization of the pair (A,B) after balancing.  If no
  101: *>          eigenvectors were computed, then only the diagonal elements
  102: *>          of the Schur form will be correct.  See ZGGHRD and ZHGEQZ
  103: *>          for details.
  104: *> \endverbatim
  105: *>
  106: *> \param[in] LDA
  107: *> \verbatim
  108: *>          LDA is INTEGER
  109: *>          The leading dimension of A.  LDA >= max(1,N).
  110: *> \endverbatim
  111: *>
  112: *> \param[in,out] B
  113: *> \verbatim
  114: *>          B is COMPLEX*16 array, dimension (LDB, N)
  115: *>          On entry, the matrix B.
  116: *>          If JOBVL = 'V' or JOBVR = 'V', then on exit B contains the
  117: *>          upper triangular matrix obtained from B in the generalized
  118: *>          Schur factorization of the pair (A,B) after balancing.
  119: *>          If no eigenvectors were computed, then only the diagonal
  120: *>          elements of B will be correct.  See ZGGHRD and ZHGEQZ for
  121: *>          details.
  122: *> \endverbatim
  123: *>
  124: *> \param[in] LDB
  125: *> \verbatim
  126: *>          LDB is INTEGER
  127: *>          The leading dimension of B.  LDB >= max(1,N).
  128: *> \endverbatim
  129: *>
  130: *> \param[out] ALPHA
  131: *> \verbatim
  132: *>          ALPHA is COMPLEX*16 array, dimension (N)
  133: *>          The complex scalars alpha that define the eigenvalues of
  134: *>          GNEP.
  135: *> \endverbatim
  136: *>
  137: *> \param[out] BETA
  138: *> \verbatim
  139: *>          BETA is COMPLEX*16 array, dimension (N)
  140: *>          The complex scalars beta that define the eigenvalues of GNEP.
  141: *>
  142: *>          Together, the quantities alpha = ALPHA(j) and beta = BETA(j)
  143: *>          represent the j-th eigenvalue of the matrix pair (A,B), in
  144: *>          one of the forms lambda = alpha/beta or mu = beta/alpha.
  145: *>          Since either lambda or mu may overflow, they should not,
  146: *>          in general, be computed.
  147: *> \endverbatim
  148: *>
  149: *> \param[out] VL
  150: *> \verbatim
  151: *>          VL is COMPLEX*16 array, dimension (LDVL,N)
  152: *>          If JOBVL = 'V', the left eigenvectors u(j) are stored
  153: *>          in the columns of VL, in the same order as their eigenvalues.
  154: *>          Each eigenvector is scaled so that its largest component has
  155: *>          abs(real part) + abs(imag. part) = 1, except for eigenvectors
  156: *>          corresponding to an eigenvalue with alpha = beta = 0, which
  157: *>          are set to zero.
  158: *>          Not referenced if JOBVL = 'N'.
  159: *> \endverbatim
  160: *>
  161: *> \param[in] LDVL
  162: *> \verbatim
  163: *>          LDVL is INTEGER
  164: *>          The leading dimension of the matrix VL. LDVL >= 1, and
  165: *>          if JOBVL = 'V', LDVL >= N.
  166: *> \endverbatim
  167: *>
  168: *> \param[out] VR
  169: *> \verbatim
  170: *>          VR is COMPLEX*16 array, dimension (LDVR,N)
  171: *>          If JOBVR = 'V', the right eigenvectors x(j) are stored
  172: *>          in the columns of VR, in the same order as their eigenvalues.
  173: *>          Each eigenvector is scaled so that its largest component has
  174: *>          abs(real part) + abs(imag. part) = 1, except for eigenvectors
  175: *>          corresponding to an eigenvalue with alpha = beta = 0, which
  176: *>          are set to zero.
  177: *>          Not referenced if JOBVR = 'N'.
  178: *> \endverbatim
  179: *>
  180: *> \param[in] LDVR
  181: *> \verbatim
  182: *>          LDVR is INTEGER
  183: *>          The leading dimension of the matrix VR. LDVR >= 1, and
  184: *>          if JOBVR = 'V', LDVR >= N.
  185: *> \endverbatim
  186: *>
  187: *> \param[out] WORK
  188: *> \verbatim
  189: *>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
  190: *>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  191: *> \endverbatim
  192: *>
  193: *> \param[in] LWORK
  194: *> \verbatim
  195: *>          LWORK is INTEGER
  196: *>          The dimension of the array WORK.  LWORK >= max(1,2*N).
  197: *>          For good performance, LWORK must generally be larger.
  198: *>          To compute the optimal value of LWORK, call ILAENV to get
  199: *>          blocksizes (for ZGEQRF, ZUNMQR, and ZUNGQR.)  Then compute:
  200: *>          NB  -- MAX of the blocksizes for ZGEQRF, ZUNMQR, and ZUNGQR;
  201: *>          The optimal LWORK is  MAX( 2*N, N*(NB+1) ).
  202: *>
  203: *>          If LWORK = -1, then a workspace query is assumed; the routine
  204: *>          only calculates the optimal size of the WORK array, returns
  205: *>          this value as the first entry of the WORK array, and no error
  206: *>          message related to LWORK is issued by XERBLA.
  207: *> \endverbatim
  208: *>
  209: *> \param[out] RWORK
  210: *> \verbatim
  211: *>          RWORK is DOUBLE PRECISION array, dimension (8*N)
  212: *> \endverbatim
  213: *>
  214: *> \param[out] INFO
  215: *> \verbatim
  216: *>          INFO is INTEGER
  217: *>          = 0:  successful exit
  218: *>          < 0:  if INFO = -i, the i-th argument had an illegal value.
  219: *>          =1,...,N:
  220: *>                The QZ iteration failed.  No eigenvectors have been
  221: *>                calculated, but ALPHA(j) and BETA(j) should be
  222: *>                correct for j=INFO+1,...,N.
  223: *>          > N:  errors that usually indicate LAPACK problems:
  224: *>                =N+1: error return from ZGGBAL
  225: *>                =N+2: error return from ZGEQRF
  226: *>                =N+3: error return from ZUNMQR
  227: *>                =N+4: error return from ZUNGQR
  228: *>                =N+5: error return from ZGGHRD
  229: *>                =N+6: error return from ZHGEQZ (other than failed
  230: *>                                               iteration)
  231: *>                =N+7: error return from ZTGEVC
  232: *>                =N+8: error return from ZGGBAK (computing VL)
  233: *>                =N+9: error return from ZGGBAK (computing VR)
  234: *>                =N+10: error return from ZLASCL (various calls)
  235: *> \endverbatim
  236: *
  237: *  Authors:
  238: *  ========
  239: *
  240: *> \author Univ. of Tennessee
  241: *> \author Univ. of California Berkeley
  242: *> \author Univ. of Colorado Denver
  243: *> \author NAG Ltd.
  244: *
  245: *> \ingroup complex16GEeigen
  246: *
  247: *> \par Further Details:
  248: *  =====================
  249: *>
  250: *> \verbatim
  251: *>
  252: *>  Balancing
  253: *>  ---------
  254: *>
  255: *>  This driver calls ZGGBAL to both permute and scale rows and columns
  256: *>  of A and B.  The permutations PL and PR are chosen so that PL*A*PR
  257: *>  and PL*B*R will be upper triangular except for the diagonal blocks
  258: *>  A(i:j,i:j) and B(i:j,i:j), with i and j as close together as
  259: *>  possible.  The diagonal scaling matrices DL and DR are chosen so
  260: *>  that the pair  DL*PL*A*PR*DR, DL*PL*B*PR*DR have elements close to
  261: *>  one (except for the elements that start out zero.)
  262: *>
  263: *>  After the eigenvalues and eigenvectors of the balanced matrices
  264: *>  have been computed, ZGGBAK transforms the eigenvectors back to what
  265: *>  they would have been (in perfect arithmetic) if they had not been
  266: *>  balanced.
  267: *>
  268: *>  Contents of A and B on Exit
  269: *>  -------- -- - --- - -- ----
  270: *>
  271: *>  If any eigenvectors are computed (either JOBVL='V' or JOBVR='V' or
  272: *>  both), then on exit the arrays A and B will contain the complex Schur
  273: *>  form[*] of the "balanced" versions of A and B.  If no eigenvectors
  274: *>  are computed, then only the diagonal blocks will be correct.
  275: *>
  276: *>  [*] In other words, upper triangular form.
  277: *> \endverbatim
  278: *>
  279: *  =====================================================================
  280:       SUBROUTINE ZGEGV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHA, BETA,
  281:      $                  VL, LDVL, VR, LDVR, WORK, LWORK, RWORK, INFO )
  282: *
  283: *  -- LAPACK driver routine --
  284: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  285: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  286: *
  287: *     .. Scalar Arguments ..
  288:       CHARACTER          JOBVL, JOBVR
  289:       INTEGER            INFO, LDA, LDB, LDVL, LDVR, LWORK, N
  290: *     ..
  291: *     .. Array Arguments ..
  292:       DOUBLE PRECISION   RWORK( * )
  293:       COMPLEX*16         A( LDA, * ), ALPHA( * ), B( LDB, * ),
  294:      $                   BETA( * ), VL( LDVL, * ), VR( LDVR, * ),
  295:      $                   WORK( * )
  296: *     ..
  297: *
  298: *  =====================================================================
  299: *
  300: *     .. Parameters ..
  301:       DOUBLE PRECISION   ZERO, ONE
  302:       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
  303:       COMPLEX*16         CZERO, CONE
  304:       PARAMETER          ( CZERO = ( 0.0D0, 0.0D0 ),
  305:      $                   CONE = ( 1.0D0, 0.0D0 ) )
  306: *     ..
  307: *     .. Local Scalars ..
  308:       LOGICAL            ILIMIT, ILV, ILVL, ILVR, LQUERY
  309:       CHARACTER          CHTEMP
  310:       INTEGER            ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,
  311:      $                   IN, IRIGHT, IROWS, IRWORK, ITAU, IWORK, JC, JR,
  312:      $                   LOPT, LWKMIN, LWKOPT, NB, NB1, NB2, NB3
  313:       DOUBLE PRECISION   ABSAI, ABSAR, ABSB, ANRM, ANRM1, ANRM2, BNRM,
  314:      $                   BNRM1, BNRM2, EPS, SAFMAX, SAFMIN, SALFAI,
  315:      $                   SALFAR, SBETA, SCALE, TEMP
  316:       COMPLEX*16         X
  317: *     ..
  318: *     .. Local Arrays ..
  319:       LOGICAL            LDUMMA( 1 )
  320: *     ..
  321: *     .. External Subroutines ..
  322:       EXTERNAL           XERBLA, ZGEQRF, ZGGBAK, ZGGBAL, ZGGHRD, ZHGEQZ,
  323:      $                   ZLACPY, ZLASCL, ZLASET, ZTGEVC, ZUNGQR, ZUNMQR
  324: *     ..
  325: *     .. External Functions ..
  326:       LOGICAL            LSAME
  327:       INTEGER            ILAENV
  328:       DOUBLE PRECISION   DLAMCH, ZLANGE
  329:       EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
  330: *     ..
  331: *     .. Intrinsic Functions ..
  332:       INTRINSIC          ABS, DBLE, DCMPLX, DIMAG, INT, MAX
  333: *     ..
  334: *     .. Statement Functions ..
  335:       DOUBLE PRECISION   ABS1
  336: *     ..
  337: *     .. Statement Function definitions ..
  338:       ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
  339: *     ..
  340: *     .. Executable Statements ..
  341: *
  342: *     Decode the input arguments
  343: *
  344:       IF( LSAME( JOBVL, 'N' ) ) THEN
  345:          IJOBVL = 1
  346:          ILVL = .FALSE.
  347:       ELSE IF( LSAME( JOBVL, 'V' ) ) THEN
  348:          IJOBVL = 2
  349:          ILVL = .TRUE.
  350:       ELSE
  351:          IJOBVL = -1
  352:          ILVL = .FALSE.
  353:       END IF
  354: *
  355:       IF( LSAME( JOBVR, 'N' ) ) THEN
  356:          IJOBVR = 1
  357:          ILVR = .FALSE.
  358:       ELSE IF( LSAME( JOBVR, 'V' ) ) THEN
  359:          IJOBVR = 2
  360:          ILVR = .TRUE.
  361:       ELSE
  362:          IJOBVR = -1
  363:          ILVR = .FALSE.
  364:       END IF
  365:       ILV = ILVL .OR. ILVR
  366: *
  367: *     Test the input arguments
  368: *
  369:       LWKMIN = MAX( 2*N, 1 )
  370:       LWKOPT = LWKMIN
  371:       WORK( 1 ) = LWKOPT
  372:       LQUERY = ( LWORK.EQ.-1 )
  373:       INFO = 0
  374:       IF( IJOBVL.LE.0 ) THEN
  375:          INFO = -1
  376:       ELSE IF( IJOBVR.LE.0 ) THEN
  377:          INFO = -2
  378:       ELSE IF( N.LT.0 ) THEN
  379:          INFO = -3
  380:       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
  381:          INFO = -5
  382:       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  383:          INFO = -7
  384:       ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THEN
  385:          INFO = -11
  386:       ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THEN
  387:          INFO = -13
  388:       ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THEN
  389:          INFO = -15
  390:       END IF
  391: *
  392:       IF( INFO.EQ.0 ) THEN
  393:          NB1 = ILAENV( 1, 'ZGEQRF', ' ', N, N, -1, -1 )
  394:          NB2 = ILAENV( 1, 'ZUNMQR', ' ', N, N, N, -1 )
  395:          NB3 = ILAENV( 1, 'ZUNGQR', ' ', N, N, N, -1 )
  396:          NB = MAX( NB1, NB2, NB3 )
  397:          LOPT = MAX( 2*N, N*( NB+1 ) )
  398:          WORK( 1 ) = LOPT
  399:       END IF
  400: *
  401:       IF( INFO.NE.0 ) THEN
  402:          CALL XERBLA( 'ZGEGV ', -INFO )
  403:          RETURN
  404:       ELSE IF( LQUERY ) THEN
  405:          RETURN
  406:       END IF
  407: *
  408: *     Quick return if possible
  409: *
  410:       IF( N.EQ.0 )
  411:      $   RETURN
  412: *
  413: *     Get machine constants
  414: *
  415:       EPS = DLAMCH( 'E' )*DLAMCH( 'B' )
  416:       SAFMIN = DLAMCH( 'S' )
  417:       SAFMIN = SAFMIN + SAFMIN
  418:       SAFMAX = ONE / SAFMIN
  419: *
  420: *     Scale A
  421: *
  422:       ANRM = ZLANGE( 'M', N, N, A, LDA, RWORK )
  423:       ANRM1 = ANRM
  424:       ANRM2 = ONE
  425:       IF( ANRM.LT.ONE ) THEN
  426:          IF( SAFMAX*ANRM.LT.ONE ) THEN
  427:             ANRM1 = SAFMIN
  428:             ANRM2 = SAFMAX*ANRM
  429:          END IF
  430:       END IF
  431: *
  432:       IF( ANRM.GT.ZERO ) THEN
  433:          CALL ZLASCL( 'G', -1, -1, ANRM, ONE, N, N, A, LDA, IINFO )
  434:          IF( IINFO.NE.0 ) THEN
  435:             INFO = N + 10
  436:             RETURN
  437:          END IF
  438:       END IF
  439: *
  440: *     Scale B
  441: *
  442:       BNRM = ZLANGE( 'M', N, N, B, LDB, RWORK )
  443:       BNRM1 = BNRM
  444:       BNRM2 = ONE
  445:       IF( BNRM.LT.ONE ) THEN
  446:          IF( SAFMAX*BNRM.LT.ONE ) THEN
  447:             BNRM1 = SAFMIN
  448:             BNRM2 = SAFMAX*BNRM
  449:          END IF
  450:       END IF
  451: *
  452:       IF( BNRM.GT.ZERO ) THEN
  453:          CALL ZLASCL( 'G', -1, -1, BNRM, ONE, N, N, B, LDB, IINFO )
  454:          IF( IINFO.NE.0 ) THEN
  455:             INFO = N + 10
  456:             RETURN
  457:          END IF
  458:       END IF
  459: *
  460: *     Permute the matrix to make it more nearly triangular
  461: *     Also "balance" the matrix.
  462: *
  463:       ILEFT = 1
  464:       IRIGHT = N + 1
  465:       IRWORK = IRIGHT + N
  466:       CALL ZGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, RWORK( ILEFT ),
  467:      $             RWORK( IRIGHT ), RWORK( IRWORK ), IINFO )
  468:       IF( IINFO.NE.0 ) THEN
  469:          INFO = N + 1
  470:          GO TO 80
  471:       END IF
  472: *
  473: *     Reduce B to triangular form, and initialize VL and/or VR
  474: *
  475:       IROWS = IHI + 1 - ILO
  476:       IF( ILV ) THEN
  477:          ICOLS = N + 1 - ILO
  478:       ELSE
  479:          ICOLS = IROWS
  480:       END IF
  481:       ITAU = 1
  482:       IWORK = ITAU + IROWS
  483:       CALL ZGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),
  484:      $             WORK( IWORK ), LWORK+1-IWORK, IINFO )
  485:       IF( IINFO.GE.0 )
  486:      $   LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  487:       IF( IINFO.NE.0 ) THEN
  488:          INFO = N + 2
  489:          GO TO 80
  490:       END IF
  491: *
  492:       CALL ZUNMQR( 'L', 'C', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,
  493:      $             WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),
  494:      $             LWORK+1-IWORK, IINFO )
  495:       IF( IINFO.GE.0 )
  496:      $   LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  497:       IF( IINFO.NE.0 ) THEN
  498:          INFO = N + 3
  499:          GO TO 80
  500:       END IF
  501: *
  502:       IF( ILVL ) THEN
  503:          CALL ZLASET( 'Full', N, N, CZERO, CONE, VL, LDVL )
  504:          CALL ZLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,
  505:      $                VL( ILO+1, ILO ), LDVL )
  506:          CALL ZUNGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,
  507:      $                WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,
  508:      $                IINFO )
  509:          IF( IINFO.GE.0 )
  510:      $      LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  511:          IF( IINFO.NE.0 ) THEN
  512:             INFO = N + 4
  513:             GO TO 80
  514:          END IF
  515:       END IF
  516: *
  517:       IF( ILVR )
  518:      $   CALL ZLASET( 'Full', N, N, CZERO, CONE, VR, LDVR )
  519: *
  520: *     Reduce to generalized Hessenberg form
  521: *
  522:       IF( ILV ) THEN
  523: *
  524: *        Eigenvectors requested -- work on whole matrix.
  525: *
  526:          CALL ZGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,
  527:      $                LDVL, VR, LDVR, IINFO )
  528:       ELSE
  529:          CALL ZGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,
  530:      $                B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IINFO )
  531:       END IF
  532:       IF( IINFO.NE.0 ) THEN
  533:          INFO = N + 5
  534:          GO TO 80
  535:       END IF
  536: *
  537: *     Perform QZ algorithm
  538: *
  539:       IWORK = ITAU
  540:       IF( ILV ) THEN
  541:          CHTEMP = 'S'
  542:       ELSE
  543:          CHTEMP = 'E'
  544:       END IF
  545:       CALL ZHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,
  546:      $             ALPHA, BETA, VL, LDVL, VR, LDVR, WORK( IWORK ),
  547:      $             LWORK+1-IWORK, RWORK( IRWORK ), IINFO )
  548:       IF( IINFO.GE.0 )
  549:      $   LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )
  550:       IF( IINFO.NE.0 ) THEN
  551:          IF( IINFO.GT.0 .AND. IINFO.LE.N ) THEN
  552:             INFO = IINFO
  553:          ELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THEN
  554:             INFO = IINFO - N
  555:          ELSE
  556:             INFO = N + 6
  557:          END IF
  558:          GO TO 80
  559:       END IF
  560: *
  561:       IF( ILV ) THEN
  562: *
  563: *        Compute Eigenvectors
  564: *
  565:          IF( ILVL ) THEN
  566:             IF( ILVR ) THEN
  567:                CHTEMP = 'B'
  568:             ELSE
  569:                CHTEMP = 'L'
  570:             END IF
  571:          ELSE
  572:             CHTEMP = 'R'
  573:          END IF
  574: *
  575:          CALL ZTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,
  576:      $                VR, LDVR, N, IN, WORK( IWORK ), RWORK( IRWORK ),
  577:      $                IINFO )
  578:          IF( IINFO.NE.0 ) THEN
  579:             INFO = N + 7
  580:             GO TO 80
  581:          END IF
  582: *
  583: *        Undo balancing on VL and VR, rescale
  584: *
  585:          IF( ILVL ) THEN
  586:             CALL ZGGBAK( 'P', 'L', N, ILO, IHI, RWORK( ILEFT ),
  587:      $                   RWORK( IRIGHT ), N, VL, LDVL, IINFO )
  588:             IF( IINFO.NE.0 ) THEN
  589:                INFO = N + 8
  590:                GO TO 80
  591:             END IF
  592:             DO 30 JC = 1, N
  593:                TEMP = ZERO
  594:                DO 10 JR = 1, N
  595:                   TEMP = MAX( TEMP, ABS1( VL( JR, JC ) ) )
  596:    10          CONTINUE
  597:                IF( TEMP.LT.SAFMIN )
  598:      $            GO TO 30
  599:                TEMP = ONE / TEMP
  600:                DO 20 JR = 1, N
  601:                   VL( JR, JC ) = VL( JR, JC )*TEMP
  602:    20          CONTINUE
  603:    30       CONTINUE
  604:          END IF
  605:          IF( ILVR ) THEN
  606:             CALL ZGGBAK( 'P', 'R', N, ILO, IHI, RWORK( ILEFT ),
  607:      $                   RWORK( IRIGHT ), N, VR, LDVR, IINFO )
  608:             IF( IINFO.NE.0 ) THEN
  609:                INFO = N + 9
  610:                GO TO 80
  611:             END IF
  612:             DO 60 JC = 1, N
  613:                TEMP = ZERO
  614:                DO 40 JR = 1, N
  615:                   TEMP = MAX( TEMP, ABS1( VR( JR, JC ) ) )
  616:    40          CONTINUE
  617:                IF( TEMP.LT.SAFMIN )
  618:      $            GO TO 60
  619:                TEMP = ONE / TEMP
  620:                DO 50 JR = 1, N
  621:                   VR( JR, JC ) = VR( JR, JC )*TEMP
  622:    50          CONTINUE
  623:    60       CONTINUE
  624:          END IF
  625: *
  626: *        End of eigenvector calculation
  627: *
  628:       END IF
  629: *
  630: *     Undo scaling in alpha, beta
  631: *
  632: *     Note: this does not give the alpha and beta for the unscaled
  633: *     problem.
  634: *
  635: *     Un-scaling is limited to avoid underflow in alpha and beta
  636: *     if they are significant.
  637: *
  638:       DO 70 JC = 1, N
  639:          ABSAR = ABS( DBLE( ALPHA( JC ) ) )
  640:          ABSAI = ABS( DIMAG( ALPHA( JC ) ) )
  641:          ABSB = ABS( DBLE( BETA( JC ) ) )
  642:          SALFAR = ANRM*DBLE( ALPHA( JC ) )
  643:          SALFAI = ANRM*DIMAG( ALPHA( JC ) )
  644:          SBETA = BNRM*DBLE( BETA( JC ) )
  645:          ILIMIT = .FALSE.
  646:          SCALE = ONE
  647: *
  648: *        Check for significant underflow in imaginary part of ALPHA
  649: *
  650:          IF( ABS( SALFAI ).LT.SAFMIN .AND. ABSAI.GE.
  651:      $       MAX( SAFMIN, EPS*ABSAR, EPS*ABSB ) ) THEN
  652:             ILIMIT = .TRUE.
  653:             SCALE = ( SAFMIN / ANRM1 ) / MAX( SAFMIN, ANRM2*ABSAI )
  654:          END IF
  655: *
  656: *        Check for significant underflow in real part of ALPHA
  657: *
  658:          IF( ABS( SALFAR ).LT.SAFMIN .AND. ABSAR.GE.
  659:      $       MAX( SAFMIN, EPS*ABSAI, EPS*ABSB ) ) THEN
  660:             ILIMIT = .TRUE.
  661:             SCALE = MAX( SCALE, ( SAFMIN / ANRM1 ) /
  662:      $              MAX( SAFMIN, ANRM2*ABSAR ) )
  663:          END IF
  664: *
  665: *        Check for significant underflow in BETA
  666: *
  667:          IF( ABS( SBETA ).LT.SAFMIN .AND. ABSB.GE.
  668:      $       MAX( SAFMIN, EPS*ABSAR, EPS*ABSAI ) ) THEN
  669:             ILIMIT = .TRUE.
  670:             SCALE = MAX( SCALE, ( SAFMIN / BNRM1 ) /
  671:      $              MAX( SAFMIN, BNRM2*ABSB ) )
  672:          END IF
  673: *
  674: *        Check for possible overflow when limiting scaling
  675: *
  676:          IF( ILIMIT ) THEN
  677:             TEMP = ( SCALE*SAFMIN )*MAX( ABS( SALFAR ), ABS( SALFAI ),
  678:      $             ABS( SBETA ) )
  679:             IF( TEMP.GT.ONE )
  680:      $         SCALE = SCALE / TEMP
  681:             IF( SCALE.LT.ONE )
  682:      $         ILIMIT = .FALSE.
  683:          END IF
  684: *
  685: *        Recompute un-scaled ALPHA, BETA if necessary.
  686: *
  687:          IF( ILIMIT ) THEN
  688:             SALFAR = ( SCALE*DBLE( ALPHA( JC ) ) )*ANRM
  689:             SALFAI = ( SCALE*DIMAG( ALPHA( JC ) ) )*ANRM
  690:             SBETA = ( SCALE*BETA( JC ) )*BNRM
  691:          END IF
  692:          ALPHA( JC ) = DCMPLX( SALFAR, SALFAI )
  693:          BETA( JC ) = SBETA
  694:    70 CONTINUE
  695: *
  696:    80 CONTINUE
  697:       WORK( 1 ) = LWKOPT
  698: *
  699:       RETURN
  700: *
  701: *     End of ZGEGV
  702: *
  703:       END

CVSweb interface <joel.bertrand@systella.fr>