File:  [local] / rpl / lapack / lapack / dgegv.f
Revision 1.14: download - view: text, annotated - select for diffs - revision graph
Sat Jun 17 10:53:47 2017 UTC (6 years, 11 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Mise à jour de lapack.

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

CVSweb interface <joel.bertrand@systella.fr>