Annotation of rpl/lapack/lapack/dtgsna.f, revision 1.1

1.1     ! bertrand    1:       SUBROUTINE DTGSNA( JOB, HOWMNY, SELECT, N, A, LDA, B, LDB, VL,
        !             2:      $                   LDVL, VR, LDVR, S, DIF, MM, M, WORK, LWORK,
        !             3:      $                   IWORK, INFO )
        !             4: *
        !             5: *  -- LAPACK routine (version 3.2) --
        !             6: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
        !             7: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
        !             8: *     November 2006
        !             9: *
        !            10: *     .. Scalar Arguments ..
        !            11:       CHARACTER          HOWMNY, JOB
        !            12:       INTEGER            INFO, LDA, LDB, LDVL, LDVR, LWORK, M, MM, N
        !            13: *     ..
        !            14: *     .. Array Arguments ..
        !            15:       LOGICAL            SELECT( * )
        !            16:       INTEGER            IWORK( * )
        !            17:       DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), DIF( * ), S( * ),
        !            18:      $                   VL( LDVL, * ), VR( LDVR, * ), WORK( * )
        !            19: *     ..
        !            20: *
        !            21: *  Purpose
        !            22: *  =======
        !            23: *
        !            24: *  DTGSNA estimates reciprocal condition numbers for specified
        !            25: *  eigenvalues and/or eigenvectors of a matrix pair (A, B) in
        !            26: *  generalized real Schur canonical form (or of any matrix pair
        !            27: *  (Q*A*Z', Q*B*Z') with orthogonal matrices Q and Z, where
        !            28: *  Z' denotes the transpose of Z.
        !            29: *
        !            30: *  (A, B) must be in generalized real Schur form (as returned by DGGES),
        !            31: *  i.e. A is block upper triangular with 1-by-1 and 2-by-2 diagonal
        !            32: *  blocks. B is upper triangular.
        !            33: *
        !            34: *
        !            35: *  Arguments
        !            36: *  =========
        !            37: *
        !            38: *  JOB     (input) CHARACTER*1
        !            39: *          Specifies whether condition numbers are required for
        !            40: *          eigenvalues (S) or eigenvectors (DIF):
        !            41: *          = 'E': for eigenvalues only (S);
        !            42: *          = 'V': for eigenvectors only (DIF);
        !            43: *          = 'B': for both eigenvalues and eigenvectors (S and DIF).
        !            44: *
        !            45: *  HOWMNY  (input) CHARACTER*1
        !            46: *          = 'A': compute condition numbers for all eigenpairs;
        !            47: *          = 'S': compute condition numbers for selected eigenpairs
        !            48: *                 specified by the array SELECT.
        !            49: *
        !            50: *  SELECT  (input) LOGICAL array, dimension (N)
        !            51: *          If HOWMNY = 'S', SELECT specifies the eigenpairs for which
        !            52: *          condition numbers are required. To select condition numbers
        !            53: *          for the eigenpair corresponding to a real eigenvalue w(j),
        !            54: *          SELECT(j) must be set to .TRUE.. To select condition numbers
        !            55: *          corresponding to a complex conjugate pair of eigenvalues w(j)
        !            56: *          and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be
        !            57: *          set to .TRUE..
        !            58: *          If HOWMNY = 'A', SELECT is not referenced.
        !            59: *
        !            60: *  N       (input) INTEGER
        !            61: *          The order of the square matrix pair (A, B). N >= 0.
        !            62: *
        !            63: *  A       (input) DOUBLE PRECISION array, dimension (LDA,N)
        !            64: *          The upper quasi-triangular matrix A in the pair (A,B).
        !            65: *
        !            66: *  LDA     (input) INTEGER
        !            67: *          The leading dimension of the array A. LDA >= max(1,N).
        !            68: *
        !            69: *  B       (input) DOUBLE PRECISION array, dimension (LDB,N)
        !            70: *          The upper triangular matrix B in the pair (A,B).
        !            71: *
        !            72: *  LDB     (input) INTEGER
        !            73: *          The leading dimension of the array B. LDB >= max(1,N).
        !            74: *
        !            75: *  VL      (input) DOUBLE PRECISION array, dimension (LDVL,M)
        !            76: *          If JOB = 'E' or 'B', VL must contain left eigenvectors of
        !            77: *          (A, B), corresponding to the eigenpairs specified by HOWMNY
        !            78: *          and SELECT. The eigenvectors must be stored in consecutive
        !            79: *          columns of VL, as returned by DTGEVC.
        !            80: *          If JOB = 'V', VL is not referenced.
        !            81: *
        !            82: *  LDVL    (input) INTEGER
        !            83: *          The leading dimension of the array VL. LDVL >= 1.
        !            84: *          If JOB = 'E' or 'B', LDVL >= N.
        !            85: *
        !            86: *  VR      (input) DOUBLE PRECISION array, dimension (LDVR,M)
        !            87: *          If JOB = 'E' or 'B', VR must contain right eigenvectors of
        !            88: *          (A, B), corresponding to the eigenpairs specified by HOWMNY
        !            89: *          and SELECT. The eigenvectors must be stored in consecutive
        !            90: *          columns ov VR, as returned by DTGEVC.
        !            91: *          If JOB = 'V', VR is not referenced.
        !            92: *
        !            93: *  LDVR    (input) INTEGER
        !            94: *          The leading dimension of the array VR. LDVR >= 1.
        !            95: *          If JOB = 'E' or 'B', LDVR >= N.
        !            96: *
        !            97: *  S       (output) DOUBLE PRECISION array, dimension (MM)
        !            98: *          If JOB = 'E' or 'B', the reciprocal condition numbers of the
        !            99: *          selected eigenvalues, stored in consecutive elements of the
        !           100: *          array. For a complex conjugate pair of eigenvalues two
        !           101: *          consecutive elements of S are set to the same value. Thus
        !           102: *          S(j), DIF(j), and the j-th columns of VL and VR all
        !           103: *          correspond to the same eigenpair (but not in general the
        !           104: *          j-th eigenpair, unless all eigenpairs are selected).
        !           105: *          If JOB = 'V', S is not referenced.
        !           106: *
        !           107: *  DIF     (output) DOUBLE PRECISION array, dimension (MM)
        !           108: *          If JOB = 'V' or 'B', the estimated reciprocal condition
        !           109: *          numbers of the selected eigenvectors, stored in consecutive
        !           110: *          elements of the array. For a complex eigenvector two
        !           111: *          consecutive elements of DIF are set to the same value. If
        !           112: *          the eigenvalues cannot be reordered to compute DIF(j), DIF(j)
        !           113: *          is set to 0; this can only occur when the true value would be
        !           114: *          very small anyway.
        !           115: *          If JOB = 'E', DIF is not referenced.
        !           116: *
        !           117: *  MM      (input) INTEGER
        !           118: *          The number of elements in the arrays S and DIF. MM >= M.
        !           119: *
        !           120: *  M       (output) INTEGER
        !           121: *          The number of elements of the arrays S and DIF used to store
        !           122: *          the specified condition numbers; for each selected real
        !           123: *          eigenvalue one element is used, and for each selected complex
        !           124: *          conjugate pair of eigenvalues, two elements are used.
        !           125: *          If HOWMNY = 'A', M is set to N.
        !           126: *
        !           127: *  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
        !           128: *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
        !           129: *
        !           130: *  LWORK   (input) INTEGER
        !           131: *          The dimension of the array WORK. LWORK >= max(1,N).
        !           132: *          If JOB = 'V' or 'B' LWORK >= 2*N*(N+2)+16.
        !           133: *
        !           134: *          If LWORK = -1, then a workspace query is assumed; the routine
        !           135: *          only calculates the optimal size of the WORK array, returns
        !           136: *          this value as the first entry of the WORK array, and no error
        !           137: *          message related to LWORK is issued by XERBLA.
        !           138: *
        !           139: *  IWORK   (workspace) INTEGER array, dimension (N + 6)
        !           140: *          If JOB = 'E', IWORK is not referenced.
        !           141: *
        !           142: *  INFO    (output) INTEGER
        !           143: *          =0: Successful exit
        !           144: *          <0: If INFO = -i, the i-th argument had an illegal value
        !           145: *
        !           146: *
        !           147: *  Further Details
        !           148: *  ===============
        !           149: *
        !           150: *  The reciprocal of the condition number of a generalized eigenvalue
        !           151: *  w = (a, b) is defined as
        !           152: *
        !           153: *       S(w) = (|u'Av|**2 + |u'Bv|**2)**(1/2) / (norm(u)*norm(v))
        !           154: *
        !           155: *  where u and v are the left and right eigenvectors of (A, B)
        !           156: *  corresponding to w; |z| denotes the absolute value of the complex
        !           157: *  number, and norm(u) denotes the 2-norm of the vector u.
        !           158: *  The pair (a, b) corresponds to an eigenvalue w = a/b (= u'Av/u'Bv)
        !           159: *  of the matrix pair (A, B). If both a and b equal zero, then (A B) is
        !           160: *  singular and S(I) = -1 is returned.
        !           161: *
        !           162: *  An approximate error bound on the chordal distance between the i-th
        !           163: *  computed generalized eigenvalue w and the corresponding exact
        !           164: *  eigenvalue lambda is
        !           165: *
        !           166: *       chord(w, lambda) <= EPS * norm(A, B) / S(I)
        !           167: *
        !           168: *  where EPS is the machine precision.
        !           169: *
        !           170: *  The reciprocal of the condition number DIF(i) of right eigenvector u
        !           171: *  and left eigenvector v corresponding to the generalized eigenvalue w
        !           172: *  is defined as follows:
        !           173: *
        !           174: *  a) If the i-th eigenvalue w = (a,b) is real
        !           175: *
        !           176: *     Suppose U and V are orthogonal transformations such that
        !           177: *
        !           178: *                U'*(A, B)*V  = (S, T) = ( a   *  ) ( b  *  )  1
        !           179: *                                        ( 0  S22 ),( 0 T22 )  n-1
        !           180: *                                          1  n-1     1 n-1
        !           181: *
        !           182: *     Then the reciprocal condition number DIF(i) is
        !           183: *
        !           184: *                Difl((a, b), (S22, T22)) = sigma-min( Zl ),
        !           185: *
        !           186: *     where sigma-min(Zl) denotes the smallest singular value of the
        !           187: *     2(n-1)-by-2(n-1) matrix
        !           188: *
        !           189: *         Zl = [ kron(a, In-1)  -kron(1, S22) ]
        !           190: *              [ kron(b, In-1)  -kron(1, T22) ] .
        !           191: *
        !           192: *     Here In-1 is the identity matrix of size n-1. kron(X, Y) is the
        !           193: *     Kronecker product between the matrices X and Y.
        !           194: *
        !           195: *     Note that if the default method for computing DIF(i) is wanted
        !           196: *     (see DLATDF), then the parameter DIFDRI (see below) should be
        !           197: *     changed from 3 to 4 (routine DLATDF(IJOB = 2 will be used)).
        !           198: *     See DTGSYL for more details.
        !           199: *
        !           200: *  b) If the i-th and (i+1)-th eigenvalues are complex conjugate pair,
        !           201: *
        !           202: *     Suppose U and V are orthogonal transformations such that
        !           203: *
        !           204: *                U'*(A, B)*V = (S, T) = ( S11  *   ) ( T11  *  )  2
        !           205: *                                       ( 0    S22 ),( 0    T22) n-2
        !           206: *                                         2    n-2     2    n-2
        !           207: *
        !           208: *     and (S11, T11) corresponds to the complex conjugate eigenvalue
        !           209: *     pair (w, conjg(w)). There exist unitary matrices U1 and V1 such
        !           210: *     that
        !           211: *
        !           212: *         U1'*S11*V1 = ( s11 s12 )   and U1'*T11*V1 = ( t11 t12 )
        !           213: *                      (  0  s22 )                    (  0  t22 )
        !           214: *
        !           215: *     where the generalized eigenvalues w = s11/t11 and
        !           216: *     conjg(w) = s22/t22.
        !           217: *
        !           218: *     Then the reciprocal condition number DIF(i) is bounded by
        !           219: *
        !           220: *         min( d1, max( 1, |real(s11)/real(s22)| )*d2 )
        !           221: *
        !           222: *     where, d1 = Difl((s11, t11), (s22, t22)) = sigma-min(Z1), where
        !           223: *     Z1 is the complex 2-by-2 matrix
        !           224: *
        !           225: *              Z1 =  [ s11  -s22 ]
        !           226: *                    [ t11  -t22 ],
        !           227: *
        !           228: *     This is done by computing (using real arithmetic) the
        !           229: *     roots of the characteristical polynomial det(Z1' * Z1 - lambda I),
        !           230: *     where Z1' denotes the conjugate transpose of Z1 and det(X) denotes
        !           231: *     the determinant of X.
        !           232: *
        !           233: *     and d2 is an upper bound on Difl((S11, T11), (S22, T22)), i.e. an
        !           234: *     upper bound on sigma-min(Z2), where Z2 is (2n-2)-by-(2n-2)
        !           235: *
        !           236: *              Z2 = [ kron(S11', In-2)  -kron(I2, S22) ]
        !           237: *                   [ kron(T11', In-2)  -kron(I2, T22) ]
        !           238: *
        !           239: *     Note that if the default method for computing DIF is wanted (see
        !           240: *     DLATDF), then the parameter DIFDRI (see below) should be changed
        !           241: *     from 3 to 4 (routine DLATDF(IJOB = 2 will be used)). See DTGSYL
        !           242: *     for more details.
        !           243: *
        !           244: *  For each eigenvalue/vector specified by SELECT, DIF stores a
        !           245: *  Frobenius norm-based estimate of Difl.
        !           246: *
        !           247: *  An approximate error bound for the i-th computed eigenvector VL(i) or
        !           248: *  VR(i) is given by
        !           249: *
        !           250: *             EPS * norm(A, B) / DIF(i).
        !           251: *
        !           252: *  See ref. [2-3] for more details and further references.
        !           253: *
        !           254: *  Based on contributions by
        !           255: *     Bo Kagstrom and Peter Poromaa, Department of Computing Science,
        !           256: *     Umea University, S-901 87 Umea, Sweden.
        !           257: *
        !           258: *  References
        !           259: *  ==========
        !           260: *
        !           261: *  [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the
        !           262: *      Generalized Real Schur Form of a Regular Matrix Pair (A, B), in
        !           263: *      M.S. Moonen et al (eds), Linear Algebra for Large Scale and
        !           264: *      Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.
        !           265: *
        !           266: *  [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified
        !           267: *      Eigenvalues of a Regular Matrix Pair (A, B) and Condition
        !           268: *      Estimation: Theory, Algorithms and Software,
        !           269: *      Report UMINF - 94.04, Department of Computing Science, Umea
        !           270: *      University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working
        !           271: *      Note 87. To appear in Numerical Algorithms, 1996.
        !           272: *
        !           273: *  [3] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software
        !           274: *      for Solving the Generalized Sylvester Equation and Estimating the
        !           275: *      Separation between Regular Matrix Pairs, Report UMINF - 93.23,
        !           276: *      Department of Computing Science, Umea University, S-901 87 Umea,
        !           277: *      Sweden, December 1993, Revised April 1994, Also as LAPACK Working
        !           278: *      Note 75.  To appear in ACM Trans. on Math. Software, Vol 22,
        !           279: *      No 1, 1996.
        !           280: *
        !           281: *  =====================================================================
        !           282: *
        !           283: *     .. Parameters ..
        !           284:       INTEGER            DIFDRI
        !           285:       PARAMETER          ( DIFDRI = 3 )
        !           286:       DOUBLE PRECISION   ZERO, ONE, TWO, FOUR
        !           287:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
        !           288:      $                   FOUR = 4.0D+0 )
        !           289: *     ..
        !           290: *     .. Local Scalars ..
        !           291:       LOGICAL            LQUERY, PAIR, SOMCON, WANTBH, WANTDF, WANTS
        !           292:       INTEGER            I, IERR, IFST, ILST, IZ, K, KS, LWMIN, N1, N2
        !           293:       DOUBLE PRECISION   ALPHAI, ALPHAR, ALPRQT, BETA, C1, C2, COND,
        !           294:      $                   EPS, LNRM, RNRM, ROOT1, ROOT2, SCALE, SMLNUM,
        !           295:      $                   TMPII, TMPIR, TMPRI, TMPRR, UHAV, UHAVI, UHBV,
        !           296:      $                   UHBVI
        !           297: *     ..
        !           298: *     .. Local Arrays ..
        !           299:       DOUBLE PRECISION   DUMMY( 1 ), DUMMY1( 1 )
        !           300: *     ..
        !           301: *     .. External Functions ..
        !           302:       LOGICAL            LSAME
        !           303:       DOUBLE PRECISION   DDOT, DLAMCH, DLAPY2, DNRM2
        !           304:       EXTERNAL           LSAME, DDOT, DLAMCH, DLAPY2, DNRM2
        !           305: *     ..
        !           306: *     .. External Subroutines ..
        !           307:       EXTERNAL           DGEMV, DLACPY, DLAG2, DTGEXC, DTGSYL, XERBLA
        !           308: *     ..
        !           309: *     .. Intrinsic Functions ..
        !           310:       INTRINSIC          MAX, MIN, SQRT
        !           311: *     ..
        !           312: *     .. Executable Statements ..
        !           313: *
        !           314: *     Decode and test the input parameters
        !           315: *
        !           316:       WANTBH = LSAME( JOB, 'B' )
        !           317:       WANTS = LSAME( JOB, 'E' ) .OR. WANTBH
        !           318:       WANTDF = LSAME( JOB, 'V' ) .OR. WANTBH
        !           319: *
        !           320:       SOMCON = LSAME( HOWMNY, 'S' )
        !           321: *
        !           322:       INFO = 0
        !           323:       LQUERY = ( LWORK.EQ.-1 )
        !           324: *
        !           325:       IF( .NOT.WANTS .AND. .NOT.WANTDF ) THEN
        !           326:          INFO = -1
        !           327:       ELSE IF( .NOT.LSAME( HOWMNY, 'A' ) .AND. .NOT.SOMCON ) THEN
        !           328:          INFO = -2
        !           329:       ELSE IF( N.LT.0 ) THEN
        !           330:          INFO = -4
        !           331:       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
        !           332:          INFO = -6
        !           333:       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
        !           334:          INFO = -8
        !           335:       ELSE IF( WANTS .AND. LDVL.LT.N ) THEN
        !           336:          INFO = -10
        !           337:       ELSE IF( WANTS .AND. LDVR.LT.N ) THEN
        !           338:          INFO = -12
        !           339:       ELSE
        !           340: *
        !           341: *        Set M to the number of eigenpairs for which condition numbers
        !           342: *        are required, and test MM.
        !           343: *
        !           344:          IF( SOMCON ) THEN
        !           345:             M = 0
        !           346:             PAIR = .FALSE.
        !           347:             DO 10 K = 1, N
        !           348:                IF( PAIR ) THEN
        !           349:                   PAIR = .FALSE.
        !           350:                ELSE
        !           351:                   IF( K.LT.N ) THEN
        !           352:                      IF( A( K+1, K ).EQ.ZERO ) THEN
        !           353:                         IF( SELECT( K ) )
        !           354:      $                     M = M + 1
        !           355:                      ELSE
        !           356:                         PAIR = .TRUE.
        !           357:                         IF( SELECT( K ) .OR. SELECT( K+1 ) )
        !           358:      $                     M = M + 2
        !           359:                      END IF
        !           360:                   ELSE
        !           361:                      IF( SELECT( N ) )
        !           362:      $                  M = M + 1
        !           363:                   END IF
        !           364:                END IF
        !           365:    10       CONTINUE
        !           366:          ELSE
        !           367:             M = N
        !           368:          END IF
        !           369: *
        !           370:          IF( N.EQ.0 ) THEN
        !           371:             LWMIN = 1
        !           372:          ELSE IF( LSAME( JOB, 'V' ) .OR. LSAME( JOB, 'B' ) ) THEN
        !           373:             LWMIN = 2*N*( N + 2 ) + 16
        !           374:          ELSE
        !           375:             LWMIN = N
        !           376:          END IF
        !           377:          WORK( 1 ) = LWMIN
        !           378: *
        !           379:          IF( MM.LT.M ) THEN
        !           380:             INFO = -15
        !           381:          ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THEN
        !           382:             INFO = -18
        !           383:          END IF
        !           384:       END IF
        !           385: *
        !           386:       IF( INFO.NE.0 ) THEN
        !           387:          CALL XERBLA( 'DTGSNA', -INFO )
        !           388:          RETURN
        !           389:       ELSE IF( LQUERY ) THEN
        !           390:          RETURN
        !           391:       END IF
        !           392: *
        !           393: *     Quick return if possible
        !           394: *
        !           395:       IF( N.EQ.0 )
        !           396:      $   RETURN
        !           397: *
        !           398: *     Get machine constants
        !           399: *
        !           400:       EPS = DLAMCH( 'P' )
        !           401:       SMLNUM = DLAMCH( 'S' ) / EPS
        !           402:       KS = 0
        !           403:       PAIR = .FALSE.
        !           404: *
        !           405:       DO 20 K = 1, N
        !           406: *
        !           407: *        Determine whether A(k,k) begins a 1-by-1 or 2-by-2 block.
        !           408: *
        !           409:          IF( PAIR ) THEN
        !           410:             PAIR = .FALSE.
        !           411:             GO TO 20
        !           412:          ELSE
        !           413:             IF( K.LT.N )
        !           414:      $         PAIR = A( K+1, K ).NE.ZERO
        !           415:          END IF
        !           416: *
        !           417: *        Determine whether condition numbers are required for the k-th
        !           418: *        eigenpair.
        !           419: *
        !           420:          IF( SOMCON ) THEN
        !           421:             IF( PAIR ) THEN
        !           422:                IF( .NOT.SELECT( K ) .AND. .NOT.SELECT( K+1 ) )
        !           423:      $            GO TO 20
        !           424:             ELSE
        !           425:                IF( .NOT.SELECT( K ) )
        !           426:      $            GO TO 20
        !           427:             END IF
        !           428:          END IF
        !           429: *
        !           430:          KS = KS + 1
        !           431: *
        !           432:          IF( WANTS ) THEN
        !           433: *
        !           434: *           Compute the reciprocal condition number of the k-th
        !           435: *           eigenvalue.
        !           436: *
        !           437:             IF( PAIR ) THEN
        !           438: *
        !           439: *              Complex eigenvalue pair.
        !           440: *
        !           441:                RNRM = DLAPY2( DNRM2( N, VR( 1, KS ), 1 ),
        !           442:      $                DNRM2( N, VR( 1, KS+1 ), 1 ) )
        !           443:                LNRM = DLAPY2( DNRM2( N, VL( 1, KS ), 1 ),
        !           444:      $                DNRM2( N, VL( 1, KS+1 ), 1 ) )
        !           445:                CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS ), 1, ZERO,
        !           446:      $                     WORK, 1 )
        !           447:                TMPRR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
        !           448:                TMPRI = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )
        !           449:                CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS+1 ), 1,
        !           450:      $                     ZERO, WORK, 1 )
        !           451:                TMPII = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )
        !           452:                TMPIR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
        !           453:                UHAV = TMPRR + TMPII
        !           454:                UHAVI = TMPIR - TMPRI
        !           455:                CALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS ), 1, ZERO,
        !           456:      $                     WORK, 1 )
        !           457:                TMPRR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
        !           458:                TMPRI = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )
        !           459:                CALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS+1 ), 1,
        !           460:      $                     ZERO, WORK, 1 )
        !           461:                TMPII = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )
        !           462:                TMPIR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
        !           463:                UHBV = TMPRR + TMPII
        !           464:                UHBVI = TMPIR - TMPRI
        !           465:                UHAV = DLAPY2( UHAV, UHAVI )
        !           466:                UHBV = DLAPY2( UHBV, UHBVI )
        !           467:                COND = DLAPY2( UHAV, UHBV )
        !           468:                S( KS ) = COND / ( RNRM*LNRM )
        !           469:                S( KS+1 ) = S( KS )
        !           470: *
        !           471:             ELSE
        !           472: *
        !           473: *              Real eigenvalue.
        !           474: *
        !           475:                RNRM = DNRM2( N, VR( 1, KS ), 1 )
        !           476:                LNRM = DNRM2( N, VL( 1, KS ), 1 )
        !           477:                CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS ), 1, ZERO,
        !           478:      $                     WORK, 1 )
        !           479:                UHAV = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
        !           480:                CALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS ), 1, ZERO,
        !           481:      $                     WORK, 1 )
        !           482:                UHBV = DDOT( N, WORK, 1, VL( 1, KS ), 1 )
        !           483:                COND = DLAPY2( UHAV, UHBV )
        !           484:                IF( COND.EQ.ZERO ) THEN
        !           485:                   S( KS ) = -ONE
        !           486:                ELSE
        !           487:                   S( KS ) = COND / ( RNRM*LNRM )
        !           488:                END IF
        !           489:             END IF
        !           490:          END IF
        !           491: *
        !           492:          IF( WANTDF ) THEN
        !           493:             IF( N.EQ.1 ) THEN
        !           494:                DIF( KS ) = DLAPY2( A( 1, 1 ), B( 1, 1 ) )
        !           495:                GO TO 20
        !           496:             END IF
        !           497: *
        !           498: *           Estimate the reciprocal condition number of the k-th
        !           499: *           eigenvectors.
        !           500:             IF( PAIR ) THEN
        !           501: *
        !           502: *              Copy the  2-by 2 pencil beginning at (A(k,k), B(k, k)).
        !           503: *              Compute the eigenvalue(s) at position K.
        !           504: *
        !           505:                WORK( 1 ) = A( K, K )
        !           506:                WORK( 2 ) = A( K+1, K )
        !           507:                WORK( 3 ) = A( K, K+1 )
        !           508:                WORK( 4 ) = A( K+1, K+1 )
        !           509:                WORK( 5 ) = B( K, K )
        !           510:                WORK( 6 ) = B( K+1, K )
        !           511:                WORK( 7 ) = B( K, K+1 )
        !           512:                WORK( 8 ) = B( K+1, K+1 )
        !           513:                CALL DLAG2( WORK, 2, WORK( 5 ), 2, SMLNUM*EPS, BETA,
        !           514:      $                     DUMMY1( 1 ), ALPHAR, DUMMY( 1 ), ALPHAI )
        !           515:                ALPRQT = ONE
        !           516:                C1 = TWO*( ALPHAR*ALPHAR+ALPHAI*ALPHAI+BETA*BETA )
        !           517:                C2 = FOUR*BETA*BETA*ALPHAI*ALPHAI
        !           518:                ROOT1 = C1 + SQRT( C1*C1-4.0D0*C2 )
        !           519:                ROOT2 = C2 / ROOT1
        !           520:                ROOT1 = ROOT1 / TWO
        !           521:                COND = MIN( SQRT( ROOT1 ), SQRT( ROOT2 ) )
        !           522:             END IF
        !           523: *
        !           524: *           Copy the matrix (A, B) to the array WORK and swap the
        !           525: *           diagonal block beginning at A(k,k) to the (1,1) position.
        !           526: *
        !           527:             CALL DLACPY( 'Full', N, N, A, LDA, WORK, N )
        !           528:             CALL DLACPY( 'Full', N, N, B, LDB, WORK( N*N+1 ), N )
        !           529:             IFST = K
        !           530:             ILST = 1
        !           531: *
        !           532:             CALL DTGEXC( .FALSE., .FALSE., N, WORK, N, WORK( N*N+1 ), N,
        !           533:      $                   DUMMY, 1, DUMMY1, 1, IFST, ILST,
        !           534:      $                   WORK( N*N*2+1 ), LWORK-2*N*N, IERR )
        !           535: *
        !           536:             IF( IERR.GT.0 ) THEN
        !           537: *
        !           538: *              Ill-conditioned problem - swap rejected.
        !           539: *
        !           540:                DIF( KS ) = ZERO
        !           541:             ELSE
        !           542: *
        !           543: *              Reordering successful, solve generalized Sylvester
        !           544: *              equation for R and L,
        !           545: *                         A22 * R - L * A11 = A12
        !           546: *                         B22 * R - L * B11 = B12,
        !           547: *              and compute estimate of Difl((A11,B11), (A22, B22)).
        !           548: *
        !           549:                N1 = 1
        !           550:                IF( WORK( 2 ).NE.ZERO )
        !           551:      $            N1 = 2
        !           552:                N2 = N - N1
        !           553:                IF( N2.EQ.0 ) THEN
        !           554:                   DIF( KS ) = COND
        !           555:                ELSE
        !           556:                   I = N*N + 1
        !           557:                   IZ = 2*N*N + 1
        !           558:                   CALL DTGSYL( 'N', DIFDRI, N2, N1, WORK( N*N1+N1+1 ),
        !           559:      $                         N, WORK, N, WORK( N1+1 ), N,
        !           560:      $                         WORK( N*N1+N1+I ), N, WORK( I ), N,
        !           561:      $                         WORK( N1+I ), N, SCALE, DIF( KS ),
        !           562:      $                         WORK( IZ+1 ), LWORK-2*N*N, IWORK, IERR )
        !           563: *
        !           564:                   IF( PAIR )
        !           565:      $               DIF( KS ) = MIN( MAX( ONE, ALPRQT )*DIF( KS ),
        !           566:      $                           COND )
        !           567:                END IF
        !           568:             END IF
        !           569:             IF( PAIR )
        !           570:      $         DIF( KS+1 ) = DIF( KS )
        !           571:          END IF
        !           572:          IF( PAIR )
        !           573:      $      KS = KS + 1
        !           574: *
        !           575:    20 CONTINUE
        !           576:       WORK( 1 ) = LWMIN
        !           577:       RETURN
        !           578: *
        !           579: *     End of DTGSNA
        !           580: *
        !           581:       END

CVSweb interface <joel.bertrand@systella.fr>