File:  [local] / rpl / lapack / lapack / dtgevc.f
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Fri Aug 6 15:32:36 2010 UTC (13 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Cohérence

    1:       SUBROUTINE DTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
    2:      $                   LDVL, VR, LDVR, MM, M, WORK, INFO )
    3: *
    4: *  -- LAPACK routine (version 3.2) --
    5: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
    6: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
    7: *     November 2006
    8: *
    9: *     .. Scalar Arguments ..
   10:       CHARACTER          HOWMNY, SIDE
   11:       INTEGER            INFO, LDP, LDS, LDVL, LDVR, M, MM, N
   12: *     ..
   13: *     .. Array Arguments ..
   14:       LOGICAL            SELECT( * )
   15:       DOUBLE PRECISION   P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
   16:      $                   VR( LDVR, * ), WORK( * )
   17: *     ..
   18: *
   19: *
   20: *  Purpose
   21: *  =======
   22: *
   23: *  DTGEVC computes some or all of the right and/or left eigenvectors of
   24: *  a pair of real matrices (S,P), where S is a quasi-triangular matrix
   25: *  and P is upper triangular.  Matrix pairs of this type are produced by
   26: *  the generalized Schur factorization of a matrix pair (A,B):
   27: *
   28: *     A = Q*S*Z**T,  B = Q*P*Z**T
   29: *
   30: *  as computed by DGGHRD + DHGEQZ.
   31: *
   32: *  The right eigenvector x and the left eigenvector y of (S,P)
   33: *  corresponding to an eigenvalue w are defined by:
   34: *  
   35: *     S*x = w*P*x,  (y**H)*S = w*(y**H)*P,
   36: *  
   37: *  where y**H denotes the conjugate tranpose of y.
   38: *  The eigenvalues are not input to this routine, but are computed
   39: *  directly from the diagonal blocks of S and P.
   40: *  
   41: *  This routine returns the matrices X and/or Y of right and left
   42: *  eigenvectors of (S,P), or the products Z*X and/or Q*Y,
   43: *  where Z and Q are input matrices.
   44: *  If Q and Z are the orthogonal factors from the generalized Schur
   45: *  factorization of a matrix pair (A,B), then Z*X and Q*Y
   46: *  are the matrices of right and left eigenvectors of (A,B).
   47:    48: *  Arguments
   49: *  =========
   50: *
   51: *  SIDE    (input) CHARACTER*1
   52: *          = 'R': compute right eigenvectors only;
   53: *          = 'L': compute left eigenvectors only;
   54: *          = 'B': compute both right and left eigenvectors.
   55: *
   56: *  HOWMNY  (input) CHARACTER*1
   57: *          = 'A': compute all right and/or left eigenvectors;
   58: *          = 'B': compute all right and/or left eigenvectors,
   59: *                 backtransformed by the matrices in VR and/or VL;
   60: *          = 'S': compute selected right and/or left eigenvectors,
   61: *                 specified by the logical array SELECT.
   62: *
   63: *  SELECT  (input) LOGICAL array, dimension (N)
   64: *          If HOWMNY='S', SELECT specifies the eigenvectors to be
   65: *          computed.  If w(j) is a real eigenvalue, the corresponding
   66: *          real eigenvector is computed if SELECT(j) is .TRUE..
   67: *          If w(j) and w(j+1) are the real and imaginary parts of a
   68: *          complex eigenvalue, the corresponding complex eigenvector
   69: *          is computed if either SELECT(j) or SELECT(j+1) is .TRUE.,
   70: *          and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is
   71: *          set to .FALSE..
   72: *          Not referenced if HOWMNY = 'A' or 'B'.
   73: *
   74: *  N       (input) INTEGER
   75: *          The order of the matrices S and P.  N >= 0.
   76: *
   77: *  S       (input) DOUBLE PRECISION array, dimension (LDS,N)
   78: *          The upper quasi-triangular matrix S from a generalized Schur
   79: *          factorization, as computed by DHGEQZ.
   80: *
   81: *  LDS     (input) INTEGER
   82: *          The leading dimension of array S.  LDS >= max(1,N).
   83: *
   84: *  P       (input) DOUBLE PRECISION array, dimension (LDP,N)
   85: *          The upper triangular matrix P from a generalized Schur
   86: *          factorization, as computed by DHGEQZ.
   87: *          2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks
   88: *          of S must be in positive diagonal form.
   89: *
   90: *  LDP     (input) INTEGER
   91: *          The leading dimension of array P.  LDP >= max(1,N).
   92: *
   93: *  VL      (input/output) DOUBLE PRECISION array, dimension (LDVL,MM)
   94: *          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
   95: *          contain an N-by-N matrix Q (usually the orthogonal matrix Q
   96: *          of left Schur vectors returned by DHGEQZ).
   97: *          On exit, if SIDE = 'L' or 'B', VL contains:
   98: *          if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
   99: *          if HOWMNY = 'B', the matrix Q*Y;
  100: *          if HOWMNY = 'S', the left eigenvectors of (S,P) specified by
  101: *                      SELECT, stored consecutively in the columns of
  102: *                      VL, in the same order as their eigenvalues.
  103: *
  104: *          A complex eigenvector corresponding to a complex eigenvalue
  105: *          is stored in two consecutive columns, the first holding the
  106: *          real part, and the second the imaginary part.
  107: *
  108: *          Not referenced if SIDE = 'R'.
  109: *
  110: *  LDVL    (input) INTEGER
  111: *          The leading dimension of array VL.  LDVL >= 1, and if
  112: *          SIDE = 'L' or 'B', LDVL >= N.
  113: *
  114: *  VR      (input/output) DOUBLE PRECISION array, dimension (LDVR,MM)
  115: *          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
  116: *          contain an N-by-N matrix Z (usually the orthogonal matrix Z
  117: *          of right Schur vectors returned by DHGEQZ).
  118: *
  119: *          On exit, if SIDE = 'R' or 'B', VR contains:
  120: *          if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
  121: *          if HOWMNY = 'B' or 'b', the matrix Z*X;
  122: *          if HOWMNY = 'S' or 's', the right eigenvectors of (S,P)
  123: *                      specified by SELECT, stored consecutively in the
  124: *                      columns of VR, in the same order as their
  125: *                      eigenvalues.
  126: *
  127: *          A complex eigenvector corresponding to a complex eigenvalue
  128: *          is stored in two consecutive columns, the first holding the
  129: *          real part and the second the imaginary part.
  130: *          
  131: *          Not referenced if SIDE = 'L'.
  132: *
  133: *  LDVR    (input) INTEGER
  134: *          The leading dimension of the array VR.  LDVR >= 1, and if
  135: *          SIDE = 'R' or 'B', LDVR >= N.
  136: *
  137: *  MM      (input) INTEGER
  138: *          The number of columns in the arrays VL and/or VR. MM >= M.
  139: *
  140: *  M       (output) INTEGER
  141: *          The number of columns in the arrays VL and/or VR actually
  142: *          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M
  143: *          is set to N.  Each selected real eigenvector occupies one
  144: *          column and each selected complex eigenvector occupies two
  145: *          columns.
  146: *
  147: *  WORK    (workspace) DOUBLE PRECISION array, dimension (6*N)
  148: *
  149: *  INFO    (output) INTEGER
  150: *          = 0:  successful exit.
  151: *          < 0:  if INFO = -i, the i-th argument had an illegal value.
  152: *          > 0:  the 2-by-2 block (INFO:INFO+1) does not have a complex
  153: *                eigenvalue.
  154: *
  155: *  Further Details
  156: *  ===============
  157: *
  158: *  Allocation of workspace:
  159: *  ---------- -- ---------
  160: *
  161: *     WORK( j ) = 1-norm of j-th column of A, above the diagonal
  162: *     WORK( N+j ) = 1-norm of j-th column of B, above the diagonal
  163: *     WORK( 2*N+1:3*N ) = real part of eigenvector
  164: *     WORK( 3*N+1:4*N ) = imaginary part of eigenvector
  165: *     WORK( 4*N+1:5*N ) = real part of back-transformed eigenvector
  166: *     WORK( 5*N+1:6*N ) = imaginary part of back-transformed eigenvector
  167: *
  168: *  Rowwise vs. columnwise solution methods:
  169: *  ------- --  ---------- -------- -------
  170: *
  171: *  Finding a generalized eigenvector consists basically of solving the
  172: *  singular triangular system
  173: *
  174: *   (A - w B) x = 0     (for right) or:   (A - w B)**H y = 0  (for left)
  175: *
  176: *  Consider finding the i-th right eigenvector (assume all eigenvalues
  177: *  are real). The equation to be solved is:
  178: *       n                   i
  179: *  0 = sum  C(j,k) v(k)  = sum  C(j,k) v(k)     for j = i,. . .,1
  180: *      k=j                 k=j
  181: *
  182: *  where  C = (A - w B)  (The components v(i+1:n) are 0.)
  183: *
  184: *  The "rowwise" method is:
  185: *
  186: *  (1)  v(i) := 1
  187: *  for j = i-1,. . .,1:
  188: *                          i
  189: *      (2) compute  s = - sum C(j,k) v(k)   and
  190: *                        k=j+1
  191: *
  192: *      (3) v(j) := s / C(j,j)
  193: *
  194: *  Step 2 is sometimes called the "dot product" step, since it is an
  195: *  inner product between the j-th row and the portion of the eigenvector
  196: *  that has been computed so far.
  197: *
  198: *  The "columnwise" method consists basically in doing the sums
  199: *  for all the rows in parallel.  As each v(j) is computed, the
  200: *  contribution of v(j) times the j-th column of C is added to the
  201: *  partial sums.  Since FORTRAN arrays are stored columnwise, this has
  202: *  the advantage that at each step, the elements of C that are accessed
  203: *  are adjacent to one another, whereas with the rowwise method, the
  204: *  elements accessed at a step are spaced LDS (and LDP) words apart.
  205: *
  206: *  When finding left eigenvectors, the matrix in question is the
  207: *  transpose of the one in storage, so the rowwise method then
  208: *  actually accesses columns of A and B at each step, and so is the
  209: *  preferred method.
  210: *
  211: *  =====================================================================
  212: *
  213: *     .. Parameters ..
  214:       DOUBLE PRECISION   ZERO, ONE, SAFETY
  215:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0,
  216:      $                   SAFETY = 1.0D+2 )
  217: *     ..
  218: *     .. Local Scalars ..
  219:       LOGICAL            COMPL, COMPR, IL2BY2, ILABAD, ILALL, ILBACK,
  220:      $                   ILBBAD, ILCOMP, ILCPLX, LSA, LSB
  221:       INTEGER            I, IBEG, IEIG, IEND, IHWMNY, IINFO, IM, ISIDE,
  222:      $                   J, JA, JC, JE, JR, JW, NA, NW
  223:       DOUBLE PRECISION   ACOEF, ACOEFA, ANORM, ASCALE, BCOEFA, BCOEFI,
  224:      $                   BCOEFR, BIG, BIGNUM, BNORM, BSCALE, CIM2A,
  225:      $                   CIM2B, CIMAGA, CIMAGB, CRE2A, CRE2B, CREALA,
  226:      $                   CREALB, DMIN, SAFMIN, SALFAR, SBETA, SCALE,
  227:      $                   SMALL, TEMP, TEMP2, TEMP2I, TEMP2R, ULP, XMAX,
  228:      $                   XSCALE
  229: *     ..
  230: *     .. Local Arrays ..
  231:       DOUBLE PRECISION   BDIAG( 2 ), SUM( 2, 2 ), SUMS( 2, 2 ),
  232:      $                   SUMP( 2, 2 )
  233: *     ..
  234: *     .. External Functions ..
  235:       LOGICAL            LSAME
  236:       DOUBLE PRECISION   DLAMCH
  237:       EXTERNAL           LSAME, DLAMCH
  238: *     ..
  239: *     .. External Subroutines ..
  240:       EXTERNAL           DGEMV, DLABAD, DLACPY, DLAG2, DLALN2, XERBLA
  241: *     ..
  242: *     .. Intrinsic Functions ..
  243:       INTRINSIC          ABS, MAX, MIN
  244: *     ..
  245: *     .. Executable Statements ..
  246: *
  247: *     Decode and Test the input parameters
  248: *
  249:       IF( LSAME( HOWMNY, 'A' ) ) THEN
  250:          IHWMNY = 1
  251:          ILALL = .TRUE.
  252:          ILBACK = .FALSE.
  253:       ELSE IF( LSAME( HOWMNY, 'S' ) ) THEN
  254:          IHWMNY = 2
  255:          ILALL = .FALSE.
  256:          ILBACK = .FALSE.
  257:       ELSE IF( LSAME( HOWMNY, 'B' ) ) THEN
  258:          IHWMNY = 3
  259:          ILALL = .TRUE.
  260:          ILBACK = .TRUE.
  261:       ELSE
  262:          IHWMNY = -1
  263:          ILALL = .TRUE.
  264:       END IF
  265: *
  266:       IF( LSAME( SIDE, 'R' ) ) THEN
  267:          ISIDE = 1
  268:          COMPL = .FALSE.
  269:          COMPR = .TRUE.
  270:       ELSE IF( LSAME( SIDE, 'L' ) ) THEN
  271:          ISIDE = 2
  272:          COMPL = .TRUE.
  273:          COMPR = .FALSE.
  274:       ELSE IF( LSAME( SIDE, 'B' ) ) THEN
  275:          ISIDE = 3
  276:          COMPL = .TRUE.
  277:          COMPR = .TRUE.
  278:       ELSE
  279:          ISIDE = -1
  280:       END IF
  281: *
  282:       INFO = 0
  283:       IF( ISIDE.LT.0 ) THEN
  284:          INFO = -1
  285:       ELSE IF( IHWMNY.LT.0 ) THEN
  286:          INFO = -2
  287:       ELSE IF( N.LT.0 ) THEN
  288:          INFO = -4
  289:       ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
  290:          INFO = -6
  291:       ELSE IF( LDP.LT.MAX( 1, N ) ) THEN
  292:          INFO = -8
  293:       END IF
  294:       IF( INFO.NE.0 ) THEN
  295:          CALL XERBLA( 'DTGEVC', -INFO )
  296:          RETURN
  297:       END IF
  298: *
  299: *     Count the number of eigenvectors to be computed
  300: *
  301:       IF( .NOT.ILALL ) THEN
  302:          IM = 0
  303:          ILCPLX = .FALSE.
  304:          DO 10 J = 1, N
  305:             IF( ILCPLX ) THEN
  306:                ILCPLX = .FALSE.
  307:                GO TO 10
  308:             END IF
  309:             IF( J.LT.N ) THEN
  310:                IF( S( J+1, J ).NE.ZERO )
  311:      $            ILCPLX = .TRUE.
  312:             END IF
  313:             IF( ILCPLX ) THEN
  314:                IF( SELECT( J ) .OR. SELECT( J+1 ) )
  315:      $            IM = IM + 2
  316:             ELSE
  317:                IF( SELECT( J ) )
  318:      $            IM = IM + 1
  319:             END IF
  320:    10    CONTINUE
  321:       ELSE
  322:          IM = N
  323:       END IF
  324: *
  325: *     Check 2-by-2 diagonal blocks of A, B
  326: *
  327:       ILABAD = .FALSE.
  328:       ILBBAD = .FALSE.
  329:       DO 20 J = 1, N - 1
  330:          IF( S( J+1, J ).NE.ZERO ) THEN
  331:             IF( P( J, J ).EQ.ZERO .OR. P( J+1, J+1 ).EQ.ZERO .OR.
  332:      $          P( J, J+1 ).NE.ZERO )ILBBAD = .TRUE.
  333:             IF( J.LT.N-1 ) THEN
  334:                IF( S( J+2, J+1 ).NE.ZERO )
  335:      $            ILABAD = .TRUE.
  336:             END IF
  337:          END IF
  338:    20 CONTINUE
  339: *
  340:       IF( ILABAD ) THEN
  341:          INFO = -5
  342:       ELSE IF( ILBBAD ) THEN
  343:          INFO = -7
  344:       ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THEN
  345:          INFO = -10
  346:       ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THEN
  347:          INFO = -12
  348:       ELSE IF( MM.LT.IM ) THEN
  349:          INFO = -13
  350:       END IF
  351:       IF( INFO.NE.0 ) THEN
  352:          CALL XERBLA( 'DTGEVC', -INFO )
  353:          RETURN
  354:       END IF
  355: *
  356: *     Quick return if possible
  357: *
  358:       M = IM
  359:       IF( N.EQ.0 )
  360:      $   RETURN
  361: *
  362: *     Machine Constants
  363: *
  364:       SAFMIN = DLAMCH( 'Safe minimum' )
  365:       BIG = ONE / SAFMIN
  366:       CALL DLABAD( SAFMIN, BIG )
  367:       ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
  368:       SMALL = SAFMIN*N / ULP
  369:       BIG = ONE / SMALL
  370:       BIGNUM = ONE / ( SAFMIN*N )
  371: *
  372: *     Compute the 1-norm of each column of the strictly upper triangular
  373: *     part (i.e., excluding all elements belonging to the diagonal
  374: *     blocks) of A and B to check for possible overflow in the
  375: *     triangular solver.
  376: *
  377:       ANORM = ABS( S( 1, 1 ) )
  378:       IF( N.GT.1 )
  379:      $   ANORM = ANORM + ABS( S( 2, 1 ) )
  380:       BNORM = ABS( P( 1, 1 ) )
  381:       WORK( 1 ) = ZERO
  382:       WORK( N+1 ) = ZERO
  383: *
  384:       DO 50 J = 2, N
  385:          TEMP = ZERO
  386:          TEMP2 = ZERO
  387:          IF( S( J, J-1 ).EQ.ZERO ) THEN
  388:             IEND = J - 1
  389:          ELSE
  390:             IEND = J - 2
  391:          END IF
  392:          DO 30 I = 1, IEND
  393:             TEMP = TEMP + ABS( S( I, J ) )
  394:             TEMP2 = TEMP2 + ABS( P( I, J ) )
  395:    30    CONTINUE
  396:          WORK( J ) = TEMP
  397:          WORK( N+J ) = TEMP2
  398:          DO 40 I = IEND + 1, MIN( J+1, N )
  399:             TEMP = TEMP + ABS( S( I, J ) )
  400:             TEMP2 = TEMP2 + ABS( P( I, J ) )
  401:    40    CONTINUE
  402:          ANORM = MAX( ANORM, TEMP )
  403:          BNORM = MAX( BNORM, TEMP2 )
  404:    50 CONTINUE
  405: *
  406:       ASCALE = ONE / MAX( ANORM, SAFMIN )
  407:       BSCALE = ONE / MAX( BNORM, SAFMIN )
  408: *
  409: *     Left eigenvectors
  410: *
  411:       IF( COMPL ) THEN
  412:          IEIG = 0
  413: *
  414: *        Main loop over eigenvalues
  415: *
  416:          ILCPLX = .FALSE.
  417:          DO 220 JE = 1, N
  418: *
  419: *           Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
  420: *           (b) this would be the second of a complex pair.
  421: *           Check for complex eigenvalue, so as to be sure of which
  422: *           entry(-ies) of SELECT to look at.
  423: *
  424:             IF( ILCPLX ) THEN
  425:                ILCPLX = .FALSE.
  426:                GO TO 220
  427:             END IF
  428:             NW = 1
  429:             IF( JE.LT.N ) THEN
  430:                IF( S( JE+1, JE ).NE.ZERO ) THEN
  431:                   ILCPLX = .TRUE.
  432:                   NW = 2
  433:                END IF
  434:             END IF
  435:             IF( ILALL ) THEN
  436:                ILCOMP = .TRUE.
  437:             ELSE IF( ILCPLX ) THEN
  438:                ILCOMP = SELECT( JE ) .OR. SELECT( JE+1 )
  439:             ELSE
  440:                ILCOMP = SELECT( JE )
  441:             END IF
  442:             IF( .NOT.ILCOMP )
  443:      $         GO TO 220
  444: *
  445: *           Decide if (a) singular pencil, (b) real eigenvalue, or
  446: *           (c) complex eigenvalue.
  447: *
  448:             IF( .NOT.ILCPLX ) THEN
  449:                IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
  450:      $             ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
  451: *
  452: *                 Singular matrix pencil -- return unit eigenvector
  453: *
  454:                   IEIG = IEIG + 1
  455:                   DO 60 JR = 1, N
  456:                      VL( JR, IEIG ) = ZERO
  457:    60             CONTINUE
  458:                   VL( IEIG, IEIG ) = ONE
  459:                   GO TO 220
  460:                END IF
  461:             END IF
  462: *
  463: *           Clear vector
  464: *
  465:             DO 70 JR = 1, NW*N
  466:                WORK( 2*N+JR ) = ZERO
  467:    70       CONTINUE
  468: *                                                 T
  469: *           Compute coefficients in  ( a A - b B )  y = 0
  470: *              a  is  ACOEF
  471: *              b  is  BCOEFR + i*BCOEFI
  472: *
  473:             IF( .NOT.ILCPLX ) THEN
  474: *
  475: *              Real eigenvalue
  476: *
  477:                TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
  478:      $                ABS( P( JE, JE ) )*BSCALE, SAFMIN )
  479:                SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
  480:                SBETA = ( TEMP*P( JE, JE ) )*BSCALE
  481:                ACOEF = SBETA*ASCALE
  482:                BCOEFR = SALFAR*BSCALE
  483:                BCOEFI = ZERO
  484: *
  485: *              Scale to avoid underflow
  486: *
  487:                SCALE = ONE
  488:                LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
  489:                LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
  490:      $               SMALL
  491:                IF( LSA )
  492:      $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
  493:                IF( LSB )
  494:      $            SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
  495:      $                    MIN( BNORM, BIG ) )
  496:                IF( LSA .OR. LSB ) THEN
  497:                   SCALE = MIN( SCALE, ONE /
  498:      $                    ( SAFMIN*MAX( ONE, ABS( ACOEF ),
  499:      $                    ABS( BCOEFR ) ) ) )
  500:                   IF( LSA ) THEN
  501:                      ACOEF = ASCALE*( SCALE*SBETA )
  502:                   ELSE
  503:                      ACOEF = SCALE*ACOEF
  504:                   END IF
  505:                   IF( LSB ) THEN
  506:                      BCOEFR = BSCALE*( SCALE*SALFAR )
  507:                   ELSE
  508:                      BCOEFR = SCALE*BCOEFR
  509:                   END IF
  510:                END IF
  511:                ACOEFA = ABS( ACOEF )
  512:                BCOEFA = ABS( BCOEFR )
  513: *
  514: *              First component is 1
  515: *
  516:                WORK( 2*N+JE ) = ONE
  517:                XMAX = ONE
  518:             ELSE
  519: *
  520: *              Complex eigenvalue
  521: *
  522:                CALL DLAG2( S( JE, JE ), LDS, P( JE, JE ), LDP,
  523:      $                     SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
  524:      $                     BCOEFI )
  525:                BCOEFI = -BCOEFI
  526:                IF( BCOEFI.EQ.ZERO ) THEN
  527:                   INFO = JE
  528:                   RETURN
  529:                END IF
  530: *
  531: *              Scale to avoid over/underflow
  532: *
  533:                ACOEFA = ABS( ACOEF )
  534:                BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
  535:                SCALE = ONE
  536:                IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
  537:      $            SCALE = ( SAFMIN / ULP ) / ACOEFA
  538:                IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
  539:      $            SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
  540:                IF( SAFMIN*ACOEFA.GT.ASCALE )
  541:      $            SCALE = ASCALE / ( SAFMIN*ACOEFA )
  542:                IF( SAFMIN*BCOEFA.GT.BSCALE )
  543:      $            SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
  544:                IF( SCALE.NE.ONE ) THEN
  545:                   ACOEF = SCALE*ACOEF
  546:                   ACOEFA = ABS( ACOEF )
  547:                   BCOEFR = SCALE*BCOEFR
  548:                   BCOEFI = SCALE*BCOEFI
  549:                   BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
  550:                END IF
  551: *
  552: *              Compute first two components of eigenvector
  553: *
  554:                TEMP = ACOEF*S( JE+1, JE )
  555:                TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
  556:                TEMP2I = -BCOEFI*P( JE, JE )
  557:                IF( ABS( TEMP ).GT.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
  558:                   WORK( 2*N+JE ) = ONE
  559:                   WORK( 3*N+JE ) = ZERO
  560:                   WORK( 2*N+JE+1 ) = -TEMP2R / TEMP
  561:                   WORK( 3*N+JE+1 ) = -TEMP2I / TEMP
  562:                ELSE
  563:                   WORK( 2*N+JE+1 ) = ONE
  564:                   WORK( 3*N+JE+1 ) = ZERO
  565:                   TEMP = ACOEF*S( JE, JE+1 )
  566:                   WORK( 2*N+JE ) = ( BCOEFR*P( JE+1, JE+1 )-ACOEF*
  567:      $                             S( JE+1, JE+1 ) ) / TEMP
  568:                   WORK( 3*N+JE ) = BCOEFI*P( JE+1, JE+1 ) / TEMP
  569:                END IF
  570:                XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
  571:      $                ABS( WORK( 2*N+JE+1 ) )+ABS( WORK( 3*N+JE+1 ) ) )
  572:             END IF
  573: *
  574:             DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
  575: *
  576: *                                           T
  577: *           Triangular solve of  (a A - b B)  y = 0
  578: *
  579: *                                   T
  580: *           (rowwise in  (a A - b B) , or columnwise in (a A - b B) )
  581: *
  582:             IL2BY2 = .FALSE.
  583: *
  584:             DO 160 J = JE + NW, N
  585:                IF( IL2BY2 ) THEN
  586:                   IL2BY2 = .FALSE.
  587:                   GO TO 160
  588:                END IF
  589: *
  590:                NA = 1
  591:                BDIAG( 1 ) = P( J, J )
  592:                IF( J.LT.N ) THEN
  593:                   IF( S( J+1, J ).NE.ZERO ) THEN
  594:                      IL2BY2 = .TRUE.
  595:                      BDIAG( 2 ) = P( J+1, J+1 )
  596:                      NA = 2
  597:                   END IF
  598:                END IF
  599: *
  600: *              Check whether scaling is necessary for dot products
  601: *
  602:                XSCALE = ONE / MAX( ONE, XMAX )
  603:                TEMP = MAX( WORK( J ), WORK( N+J ),
  604:      $                ACOEFA*WORK( J )+BCOEFA*WORK( N+J ) )
  605:                IF( IL2BY2 )
  606:      $            TEMP = MAX( TEMP, WORK( J+1 ), WORK( N+J+1 ),
  607:      $                   ACOEFA*WORK( J+1 )+BCOEFA*WORK( N+J+1 ) )
  608:                IF( TEMP.GT.BIGNUM*XSCALE ) THEN
  609:                   DO 90 JW = 0, NW - 1
  610:                      DO 80 JR = JE, J - 1
  611:                         WORK( ( JW+2 )*N+JR ) = XSCALE*
  612:      $                     WORK( ( JW+2 )*N+JR )
  613:    80                CONTINUE
  614:    90             CONTINUE
  615:                   XMAX = XMAX*XSCALE
  616:                END IF
  617: *
  618: *              Compute dot products
  619: *
  620: *                    j-1
  621: *              SUM = sum  conjg( a*S(k,j) - b*P(k,j) )*x(k)
  622: *                    k=je
  623: *
  624: *              To reduce the op count, this is done as
  625: *
  626: *              _        j-1                  _        j-1
  627: *              a*conjg( sum  S(k,j)*x(k) ) - b*conjg( sum  P(k,j)*x(k) )
  628: *                       k=je                          k=je
  629: *
  630: *              which may cause underflow problems if A or B are close
  631: *              to underflow.  (E.g., less than SMALL.)
  632: *
  633: *
  634: *              A series of compiler directives to defeat vectorization
  635: *              for the next loop
  636: *
  637: *$PL$ CMCHAR=' '
  638: CDIR$          NEXTSCALAR
  639: C$DIR          SCALAR
  640: CDIR$          NEXT SCALAR
  641: CVD$L          NOVECTOR
  642: CDEC$          NOVECTOR
  643: CVD$           NOVECTOR
  644: *VDIR          NOVECTOR
  645: *VOCL          LOOP,SCALAR
  646: CIBM           PREFER SCALAR
  647: *$PL$ CMCHAR='*'
  648: *
  649:                DO 120 JW = 1, NW
  650: *
  651: *$PL$ CMCHAR=' '
  652: CDIR$             NEXTSCALAR
  653: C$DIR             SCALAR
  654: CDIR$             NEXT SCALAR
  655: CVD$L             NOVECTOR
  656: CDEC$             NOVECTOR
  657: CVD$              NOVECTOR
  658: *VDIR             NOVECTOR
  659: *VOCL             LOOP,SCALAR
  660: CIBM              PREFER SCALAR
  661: *$PL$ CMCHAR='*'
  662: *
  663:                   DO 110 JA = 1, NA
  664:                      SUMS( JA, JW ) = ZERO
  665:                      SUMP( JA, JW ) = ZERO
  666: *
  667:                      DO 100 JR = JE, J - 1
  668:                         SUMS( JA, JW ) = SUMS( JA, JW ) +
  669:      $                                   S( JR, J+JA-1 )*
  670:      $                                   WORK( ( JW+1 )*N+JR )
  671:                         SUMP( JA, JW ) = SUMP( JA, JW ) +
  672:      $                                   P( JR, J+JA-1 )*
  673:      $                                   WORK( ( JW+1 )*N+JR )
  674:   100                CONTINUE
  675:   110             CONTINUE
  676:   120          CONTINUE
  677: *
  678: *$PL$ CMCHAR=' '
  679: CDIR$          NEXTSCALAR
  680: C$DIR          SCALAR
  681: CDIR$          NEXT SCALAR
  682: CVD$L          NOVECTOR
  683: CDEC$          NOVECTOR
  684: CVD$           NOVECTOR
  685: *VDIR          NOVECTOR
  686: *VOCL          LOOP,SCALAR
  687: CIBM           PREFER SCALAR
  688: *$PL$ CMCHAR='*'
  689: *
  690:                DO 130 JA = 1, NA
  691:                   IF( ILCPLX ) THEN
  692:                      SUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +
  693:      $                              BCOEFR*SUMP( JA, 1 ) -
  694:      $                              BCOEFI*SUMP( JA, 2 )
  695:                      SUM( JA, 2 ) = -ACOEF*SUMS( JA, 2 ) +
  696:      $                              BCOEFR*SUMP( JA, 2 ) +
  697:      $                              BCOEFI*SUMP( JA, 1 )
  698:                   ELSE
  699:                      SUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +
  700:      $                              BCOEFR*SUMP( JA, 1 )
  701:                   END IF
  702:   130          CONTINUE
  703: *
  704: *                                  T
  705: *              Solve  ( a A - b B )  y = SUM(,)
  706: *              with scaling and perturbation of the denominator
  707: *
  708:                CALL DLALN2( .TRUE., NA, NW, DMIN, ACOEF, S( J, J ), LDS,
  709:      $                      BDIAG( 1 ), BDIAG( 2 ), SUM, 2, BCOEFR,
  710:      $                      BCOEFI, WORK( 2*N+J ), N, SCALE, TEMP,
  711:      $                      IINFO )
  712:                IF( SCALE.LT.ONE ) THEN
  713:                   DO 150 JW = 0, NW - 1
  714:                      DO 140 JR = JE, J - 1
  715:                         WORK( ( JW+2 )*N+JR ) = SCALE*
  716:      $                     WORK( ( JW+2 )*N+JR )
  717:   140                CONTINUE
  718:   150             CONTINUE
  719:                   XMAX = SCALE*XMAX
  720:                END IF
  721:                XMAX = MAX( XMAX, TEMP )
  722:   160       CONTINUE
  723: *
  724: *           Copy eigenvector to VL, back transforming if
  725: *           HOWMNY='B'.
  726: *
  727:             IEIG = IEIG + 1
  728:             IF( ILBACK ) THEN
  729:                DO 170 JW = 0, NW - 1
  730:                   CALL DGEMV( 'N', N, N+1-JE, ONE, VL( 1, JE ), LDVL,
  731:      $                        WORK( ( JW+2 )*N+JE ), 1, ZERO,
  732:      $                        WORK( ( JW+4 )*N+1 ), 1 )
  733:   170          CONTINUE
  734:                CALL DLACPY( ' ', N, NW, WORK( 4*N+1 ), N, VL( 1, JE ),
  735:      $                      LDVL )
  736:                IBEG = 1
  737:             ELSE
  738:                CALL DLACPY( ' ', N, NW, WORK( 2*N+1 ), N, VL( 1, IEIG ),
  739:      $                      LDVL )
  740:                IBEG = JE
  741:             END IF
  742: *
  743: *           Scale eigenvector
  744: *
  745:             XMAX = ZERO
  746:             IF( ILCPLX ) THEN
  747:                DO 180 J = IBEG, N
  748:                   XMAX = MAX( XMAX, ABS( VL( J, IEIG ) )+
  749:      $                   ABS( VL( J, IEIG+1 ) ) )
  750:   180          CONTINUE
  751:             ELSE
  752:                DO 190 J = IBEG, N
  753:                   XMAX = MAX( XMAX, ABS( VL( J, IEIG ) ) )
  754:   190          CONTINUE
  755:             END IF
  756: *
  757:             IF( XMAX.GT.SAFMIN ) THEN
  758:                XSCALE = ONE / XMAX
  759: *
  760:                DO 210 JW = 0, NW - 1
  761:                   DO 200 JR = IBEG, N
  762:                      VL( JR, IEIG+JW ) = XSCALE*VL( JR, IEIG+JW )
  763:   200             CONTINUE
  764:   210          CONTINUE
  765:             END IF
  766:             IEIG = IEIG + NW - 1
  767: *
  768:   220    CONTINUE
  769:       END IF
  770: *
  771: *     Right eigenvectors
  772: *
  773:       IF( COMPR ) THEN
  774:          IEIG = IM + 1
  775: *
  776: *        Main loop over eigenvalues
  777: *
  778:          ILCPLX = .FALSE.
  779:          DO 500 JE = N, 1, -1
  780: *
  781: *           Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
  782: *           (b) this would be the second of a complex pair.
  783: *           Check for complex eigenvalue, so as to be sure of which
  784: *           entry(-ies) of SELECT to look at -- if complex, SELECT(JE)
  785: *           or SELECT(JE-1).
  786: *           If this is a complex pair, the 2-by-2 diagonal block
  787: *           corresponding to the eigenvalue is in rows/columns JE-1:JE
  788: *
  789:             IF( ILCPLX ) THEN
  790:                ILCPLX = .FALSE.
  791:                GO TO 500
  792:             END IF
  793:             NW = 1
  794:             IF( JE.GT.1 ) THEN
  795:                IF( S( JE, JE-1 ).NE.ZERO ) THEN
  796:                   ILCPLX = .TRUE.
  797:                   NW = 2
  798:                END IF
  799:             END IF
  800:             IF( ILALL ) THEN
  801:                ILCOMP = .TRUE.
  802:             ELSE IF( ILCPLX ) THEN
  803:                ILCOMP = SELECT( JE ) .OR. SELECT( JE-1 )
  804:             ELSE
  805:                ILCOMP = SELECT( JE )
  806:             END IF
  807:             IF( .NOT.ILCOMP )
  808:      $         GO TO 500
  809: *
  810: *           Decide if (a) singular pencil, (b) real eigenvalue, or
  811: *           (c) complex eigenvalue.
  812: *
  813:             IF( .NOT.ILCPLX ) THEN
  814:                IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
  815:      $             ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
  816: *
  817: *                 Singular matrix pencil -- unit eigenvector
  818: *
  819:                   IEIG = IEIG - 1
  820:                   DO 230 JR = 1, N
  821:                      VR( JR, IEIG ) = ZERO
  822:   230             CONTINUE
  823:                   VR( IEIG, IEIG ) = ONE
  824:                   GO TO 500
  825:                END IF
  826:             END IF
  827: *
  828: *           Clear vector
  829: *
  830:             DO 250 JW = 0, NW - 1
  831:                DO 240 JR = 1, N
  832:                   WORK( ( JW+2 )*N+JR ) = ZERO
  833:   240          CONTINUE
  834:   250       CONTINUE
  835: *
  836: *           Compute coefficients in  ( a A - b B ) x = 0
  837: *              a  is  ACOEF
  838: *              b  is  BCOEFR + i*BCOEFI
  839: *
  840:             IF( .NOT.ILCPLX ) THEN
  841: *
  842: *              Real eigenvalue
  843: *
  844:                TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
  845:      $                ABS( P( JE, JE ) )*BSCALE, SAFMIN )
  846:                SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
  847:                SBETA = ( TEMP*P( JE, JE ) )*BSCALE
  848:                ACOEF = SBETA*ASCALE
  849:                BCOEFR = SALFAR*BSCALE
  850:                BCOEFI = ZERO
  851: *
  852: *              Scale to avoid underflow
  853: *
  854:                SCALE = ONE
  855:                LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
  856:                LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
  857:      $               SMALL
  858:                IF( LSA )
  859:      $            SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
  860:                IF( LSB )
  861:      $            SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
  862:      $                    MIN( BNORM, BIG ) )
  863:                IF( LSA .OR. LSB ) THEN
  864:                   SCALE = MIN( SCALE, ONE /
  865:      $                    ( SAFMIN*MAX( ONE, ABS( ACOEF ),
  866:      $                    ABS( BCOEFR ) ) ) )
  867:                   IF( LSA ) THEN
  868:                      ACOEF = ASCALE*( SCALE*SBETA )
  869:                   ELSE
  870:                      ACOEF = SCALE*ACOEF
  871:                   END IF
  872:                   IF( LSB ) THEN
  873:                      BCOEFR = BSCALE*( SCALE*SALFAR )
  874:                   ELSE
  875:                      BCOEFR = SCALE*BCOEFR
  876:                   END IF
  877:                END IF
  878:                ACOEFA = ABS( ACOEF )
  879:                BCOEFA = ABS( BCOEFR )
  880: *
  881: *              First component is 1
  882: *
  883:                WORK( 2*N+JE ) = ONE
  884:                XMAX = ONE
  885: *
  886: *              Compute contribution from column JE of A and B to sum
  887: *              (See "Further Details", above.)
  888: *
  889:                DO 260 JR = 1, JE - 1
  890:                   WORK( 2*N+JR ) = BCOEFR*P( JR, JE ) -
  891:      $                             ACOEF*S( JR, JE )
  892:   260          CONTINUE
  893:             ELSE
  894: *
  895: *              Complex eigenvalue
  896: *
  897:                CALL DLAG2( S( JE-1, JE-1 ), LDS, P( JE-1, JE-1 ), LDP,
  898:      $                     SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
  899:      $                     BCOEFI )
  900:                IF( BCOEFI.EQ.ZERO ) THEN
  901:                   INFO = JE - 1
  902:                   RETURN
  903:                END IF
  904: *
  905: *              Scale to avoid over/underflow
  906: *
  907:                ACOEFA = ABS( ACOEF )
  908:                BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
  909:                SCALE = ONE
  910:                IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
  911:      $            SCALE = ( SAFMIN / ULP ) / ACOEFA
  912:                IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
  913:      $            SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
  914:                IF( SAFMIN*ACOEFA.GT.ASCALE )
  915:      $            SCALE = ASCALE / ( SAFMIN*ACOEFA )
  916:                IF( SAFMIN*BCOEFA.GT.BSCALE )
  917:      $            SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
  918:                IF( SCALE.NE.ONE ) THEN
  919:                   ACOEF = SCALE*ACOEF
  920:                   ACOEFA = ABS( ACOEF )
  921:                   BCOEFR = SCALE*BCOEFR
  922:                   BCOEFI = SCALE*BCOEFI
  923:                   BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
  924:                END IF
  925: *
  926: *              Compute first two components of eigenvector
  927: *              and contribution to sums
  928: *
  929:                TEMP = ACOEF*S( JE, JE-1 )
  930:                TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
  931:                TEMP2I = -BCOEFI*P( JE, JE )
  932:                IF( ABS( TEMP ).GE.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
  933:                   WORK( 2*N+JE ) = ONE
  934:                   WORK( 3*N+JE ) = ZERO
  935:                   WORK( 2*N+JE-1 ) = -TEMP2R / TEMP
  936:                   WORK( 3*N+JE-1 ) = -TEMP2I / TEMP
  937:                ELSE
  938:                   WORK( 2*N+JE-1 ) = ONE
  939:                   WORK( 3*N+JE-1 ) = ZERO
  940:                   TEMP = ACOEF*S( JE-1, JE )
  941:                   WORK( 2*N+JE ) = ( BCOEFR*P( JE-1, JE-1 )-ACOEF*
  942:      $                             S( JE-1, JE-1 ) ) / TEMP
  943:                   WORK( 3*N+JE ) = BCOEFI*P( JE-1, JE-1 ) / TEMP
  944:                END IF
  945: *
  946:                XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
  947:      $                ABS( WORK( 2*N+JE-1 ) )+ABS( WORK( 3*N+JE-1 ) ) )
  948: *
  949: *              Compute contribution from columns JE and JE-1
  950: *              of A and B to the sums.
  951: *
  952:                CREALA = ACOEF*WORK( 2*N+JE-1 )
  953:                CIMAGA = ACOEF*WORK( 3*N+JE-1 )
  954:                CREALB = BCOEFR*WORK( 2*N+JE-1 ) -
  955:      $                  BCOEFI*WORK( 3*N+JE-1 )
  956:                CIMAGB = BCOEFI*WORK( 2*N+JE-1 ) +
  957:      $                  BCOEFR*WORK( 3*N+JE-1 )
  958:                CRE2A = ACOEF*WORK( 2*N+JE )
  959:                CIM2A = ACOEF*WORK( 3*N+JE )
  960:                CRE2B = BCOEFR*WORK( 2*N+JE ) - BCOEFI*WORK( 3*N+JE )
  961:                CIM2B = BCOEFI*WORK( 2*N+JE ) + BCOEFR*WORK( 3*N+JE )
  962:                DO 270 JR = 1, JE - 2
  963:                   WORK( 2*N+JR ) = -CREALA*S( JR, JE-1 ) +
  964:      $                             CREALB*P( JR, JE-1 ) -
  965:      $                             CRE2A*S( JR, JE ) + CRE2B*P( JR, JE )
  966:                   WORK( 3*N+JR ) = -CIMAGA*S( JR, JE-1 ) +
  967:      $                             CIMAGB*P( JR, JE-1 ) -
  968:      $                             CIM2A*S( JR, JE ) + CIM2B*P( JR, JE )
  969:   270          CONTINUE
  970:             END IF
  971: *
  972:             DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
  973: *
  974: *           Columnwise triangular solve of  (a A - b B)  x = 0
  975: *
  976:             IL2BY2 = .FALSE.
  977:             DO 370 J = JE - NW, 1, -1
  978: *
  979: *              If a 2-by-2 block, is in position j-1:j, wait until
  980: *              next iteration to process it (when it will be j:j+1)
  981: *
  982:                IF( .NOT.IL2BY2 .AND. J.GT.1 ) THEN
  983:                   IF( S( J, J-1 ).NE.ZERO ) THEN
  984:                      IL2BY2 = .TRUE.
  985:                      GO TO 370
  986:                   END IF
  987:                END IF
  988:                BDIAG( 1 ) = P( J, J )
  989:                IF( IL2BY2 ) THEN
  990:                   NA = 2
  991:                   BDIAG( 2 ) = P( J+1, J+1 )
  992:                ELSE
  993:                   NA = 1
  994:                END IF
  995: *
  996: *              Compute x(j) (and x(j+1), if 2-by-2 block)
  997: *
  998:                CALL DLALN2( .FALSE., NA, NW, DMIN, ACOEF, S( J, J ),
  999:      $                      LDS, BDIAG( 1 ), BDIAG( 2 ), WORK( 2*N+J ),
 1000:      $                      N, BCOEFR, BCOEFI, SUM, 2, SCALE, TEMP,
 1001:      $                      IINFO )
 1002:                IF( SCALE.LT.ONE ) THEN
 1003: *
 1004:                   DO 290 JW = 0, NW - 1
 1005:                      DO 280 JR = 1, JE
 1006:                         WORK( ( JW+2 )*N+JR ) = SCALE*
 1007:      $                     WORK( ( JW+2 )*N+JR )
 1008:   280                CONTINUE
 1009:   290             CONTINUE
 1010:                END IF
 1011:                XMAX = MAX( SCALE*XMAX, TEMP )
 1012: *
 1013:                DO 310 JW = 1, NW
 1014:                   DO 300 JA = 1, NA
 1015:                      WORK( ( JW+1 )*N+J+JA-1 ) = SUM( JA, JW )
 1016:   300             CONTINUE
 1017:   310          CONTINUE
 1018: *
 1019: *              w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling
 1020: *
 1021:                IF( J.GT.1 ) THEN
 1022: *
 1023: *                 Check whether scaling is necessary for sum.
 1024: *
 1025:                   XSCALE = ONE / MAX( ONE, XMAX )
 1026:                   TEMP = ACOEFA*WORK( J ) + BCOEFA*WORK( N+J )
 1027:                   IF( IL2BY2 )
 1028:      $               TEMP = MAX( TEMP, ACOEFA*WORK( J+1 )+BCOEFA*
 1029:      $                      WORK( N+J+1 ) )
 1030:                   TEMP = MAX( TEMP, ACOEFA, BCOEFA )
 1031:                   IF( TEMP.GT.BIGNUM*XSCALE ) THEN
 1032: *
 1033:                      DO 330 JW = 0, NW - 1
 1034:                         DO 320 JR = 1, JE
 1035:                            WORK( ( JW+2 )*N+JR ) = XSCALE*
 1036:      $                        WORK( ( JW+2 )*N+JR )
 1037:   320                   CONTINUE
 1038:   330                CONTINUE
 1039:                      XMAX = XMAX*XSCALE
 1040:                   END IF
 1041: *
 1042: *                 Compute the contributions of the off-diagonals of
 1043: *                 column j (and j+1, if 2-by-2 block) of A and B to the
 1044: *                 sums.
 1045: *
 1046: *
 1047:                   DO 360 JA = 1, NA
 1048:                      IF( ILCPLX ) THEN
 1049:                         CREALA = ACOEF*WORK( 2*N+J+JA-1 )
 1050:                         CIMAGA = ACOEF*WORK( 3*N+J+JA-1 )
 1051:                         CREALB = BCOEFR*WORK( 2*N+J+JA-1 ) -
 1052:      $                           BCOEFI*WORK( 3*N+J+JA-1 )
 1053:                         CIMAGB = BCOEFI*WORK( 2*N+J+JA-1 ) +
 1054:      $                           BCOEFR*WORK( 3*N+J+JA-1 )
 1055:                         DO 340 JR = 1, J - 1
 1056:                            WORK( 2*N+JR ) = WORK( 2*N+JR ) -
 1057:      $                                      CREALA*S( JR, J+JA-1 ) +
 1058:      $                                      CREALB*P( JR, J+JA-1 )
 1059:                            WORK( 3*N+JR ) = WORK( 3*N+JR ) -
 1060:      $                                      CIMAGA*S( JR, J+JA-1 ) +
 1061:      $                                      CIMAGB*P( JR, J+JA-1 )
 1062:   340                   CONTINUE
 1063:                      ELSE
 1064:                         CREALA = ACOEF*WORK( 2*N+J+JA-1 )
 1065:                         CREALB = BCOEFR*WORK( 2*N+J+JA-1 )
 1066:                         DO 350 JR = 1, J - 1
 1067:                            WORK( 2*N+JR ) = WORK( 2*N+JR ) -
 1068:      $                                      CREALA*S( JR, J+JA-1 ) +
 1069:      $                                      CREALB*P( JR, J+JA-1 )
 1070:   350                   CONTINUE
 1071:                      END IF
 1072:   360             CONTINUE
 1073:                END IF
 1074: *
 1075:                IL2BY2 = .FALSE.
 1076:   370       CONTINUE
 1077: *
 1078: *           Copy eigenvector to VR, back transforming if
 1079: *           HOWMNY='B'.
 1080: *
 1081:             IEIG = IEIG - NW
 1082:             IF( ILBACK ) THEN
 1083: *
 1084:                DO 410 JW = 0, NW - 1
 1085:                   DO 380 JR = 1, N
 1086:                      WORK( ( JW+4 )*N+JR ) = WORK( ( JW+2 )*N+1 )*
 1087:      $                                       VR( JR, 1 )
 1088:   380             CONTINUE
 1089: *
 1090: *                 A series of compiler directives to defeat
 1091: *                 vectorization for the next loop
 1092: *
 1093: *
 1094:                   DO 400 JC = 2, JE
 1095:                      DO 390 JR = 1, N
 1096:                         WORK( ( JW+4 )*N+JR ) = WORK( ( JW+4 )*N+JR ) +
 1097:      $                     WORK( ( JW+2 )*N+JC )*VR( JR, JC )
 1098:   390                CONTINUE
 1099:   400             CONTINUE
 1100:   410          CONTINUE
 1101: *
 1102:                DO 430 JW = 0, NW - 1
 1103:                   DO 420 JR = 1, N
 1104:                      VR( JR, IEIG+JW ) = WORK( ( JW+4 )*N+JR )
 1105:   420             CONTINUE
 1106:   430          CONTINUE
 1107: *
 1108:                IEND = N
 1109:             ELSE
 1110:                DO 450 JW = 0, NW - 1
 1111:                   DO 440 JR = 1, N
 1112:                      VR( JR, IEIG+JW ) = WORK( ( JW+2 )*N+JR )
 1113:   440             CONTINUE
 1114:   450          CONTINUE
 1115: *
 1116:                IEND = JE
 1117:             END IF
 1118: *
 1119: *           Scale eigenvector
 1120: *
 1121:             XMAX = ZERO
 1122:             IF( ILCPLX ) THEN
 1123:                DO 460 J = 1, IEND
 1124:                   XMAX = MAX( XMAX, ABS( VR( J, IEIG ) )+
 1125:      $                   ABS( VR( J, IEIG+1 ) ) )
 1126:   460          CONTINUE
 1127:             ELSE
 1128:                DO 470 J = 1, IEND
 1129:                   XMAX = MAX( XMAX, ABS( VR( J, IEIG ) ) )
 1130:   470          CONTINUE
 1131:             END IF
 1132: *
 1133:             IF( XMAX.GT.SAFMIN ) THEN
 1134:                XSCALE = ONE / XMAX
 1135:                DO 490 JW = 0, NW - 1
 1136:                   DO 480 JR = 1, IEND
 1137:                      VR( JR, IEIG+JW ) = XSCALE*VR( JR, IEIG+JW )
 1138:   480             CONTINUE
 1139:   490          CONTINUE
 1140:             END IF
 1141:   500    CONTINUE
 1142:       END IF
 1143: *
 1144:       RETURN
 1145: *
 1146: *     End of DTGEVC
 1147: *
 1148:       END

CVSweb interface <joel.bertrand@systella.fr>