1       SUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
  2      $                   LDVR, MM, M, WORK, INFO )
  3 *
  4 *  -- LAPACK routine (version 3.3.1) --
  5 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
  6 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
  7 *  -- April 2011                                                      --
  8 *
  9 *     .. Scalar Arguments ..
 10       CHARACTER          HOWMNY, SIDE
 11       INTEGER            INFO, LDT, LDVL, LDVR, M, MM, N
 12 *     ..
 13 *     .. Array Arguments ..
 14       LOGICAL            SELECT* )
 15       DOUBLE PRECISION   T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
 16      $                   WORK( * )
 17 *     ..
 18 *
 19 *  Purpose
 20 *  =======
 21 *
 22 *  DTREVC computes some or all of the right and/or left eigenvectors of
 23 *  a real upper quasi-triangular matrix T.
 24 *  Matrices of this type are produced by the Schur factorization of
 25 *  a real general matrix:  A = Q*T*Q**T, as computed by DHSEQR.
 26 *  
 27 *  The right eigenvector x and the left eigenvector y of T corresponding
 28 *  to an eigenvalue w are defined by:
 29 *  
 30 *     T*x = w*x,     (y**T)*T = w*(y**T)
 31 *  
 32 *  where y**T denotes the transpose of y.
 33 *  The eigenvalues are not input to this routine, but are read directly
 34 *  from the diagonal blocks of T.
 35 *  
 36 *  This routine returns the matrices X and/or Y of right and left
 37 *  eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
 38 *  input matrix.  If Q is the orthogonal factor that reduces a matrix
 39 *  A to Schur form T, then Q*X and Q*Y are the matrices of right and
 40 *  left eigenvectors of A.
 41 *
 42 *  Arguments
 43 *  =========
 44 *
 45 *  SIDE    (input) CHARACTER*1
 46 *          = 'R':  compute right eigenvectors only;
 47 *          = 'L':  compute left eigenvectors only;
 48 *          = 'B':  compute both right and left eigenvectors.
 49 *
 50 *  HOWMNY  (input) CHARACTER*1
 51 *          = 'A':  compute all right and/or left eigenvectors;
 52 *          = 'B':  compute all right and/or left eigenvectors,
 53 *                  backtransformed by the matrices in VR and/or VL;
 54 *          = 'S':  compute selected right and/or left eigenvectors,
 55 *                  as indicated by the logical array SELECT.
 56 *
 57 *  SELECT  (input/output) LOGICAL array, dimension (N)
 58 *          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
 59 *          computed.
 60 *          If w(j) is a real eigenvalue, the corresponding real
 61 *          eigenvector is computed if SELECT(j) is .TRUE..
 62 *          If w(j) and w(j+1) are the real and imaginary parts of a
 63 *          complex eigenvalue, the corresponding complex eigenvector is
 64 *          computed if either SELECT(j) or SELECT(j+1) is .TRUE., and
 65 *          on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to
 66 *          .FALSE..
 67 *          Not referenced if HOWMNY = 'A' or 'B'.
 68 *
 69 *  N       (input) INTEGER
 70 *          The order of the matrix T. N >= 0.
 71 *
 72 *  T       (input) DOUBLE PRECISION array, dimension (LDT,N)
 73 *          The upper quasi-triangular matrix T in Schur canonical form.
 74 *
 75 *  LDT     (input) INTEGER
 76 *          The leading dimension of the array T. LDT >= max(1,N).
 77 *
 78 *  VL      (input/output) DOUBLE PRECISION array, dimension (LDVL,MM)
 79 *          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
 80 *          contain an N-by-N matrix Q (usually the orthogonal matrix Q
 81 *          of Schur vectors returned by DHSEQR).
 82 *          On exit, if SIDE = 'L' or 'B', VL contains:
 83 *          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
 84 *          if HOWMNY = 'B', the matrix Q*Y;
 85 *          if HOWMNY = 'S', the left eigenvectors of T specified by
 86 *                           SELECT, stored consecutively in the columns
 87 *                           of VL, in the same order as their
 88 *                           eigenvalues.
 89 *          A complex eigenvector corresponding to a complex eigenvalue
 90 *          is stored in two consecutive columns, the first holding the
 91 *          real part, and the second the imaginary part.
 92 *          Not referenced if SIDE = 'R'.
 93 *
 94 *  LDVL    (input) INTEGER
 95 *          The leading dimension of the array VL.  LDVL >= 1, and if
 96 *          SIDE = 'L' or 'B', LDVL >= N.
 97 *
 98 *  VR      (input/output) DOUBLE PRECISION array, dimension (LDVR,MM)
 99 *          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
100 *          contain an N-by-N matrix Q (usually the orthogonal matrix Q
101 *          of Schur vectors returned by DHSEQR).
102 *          On exit, if SIDE = 'R' or 'B', VR contains:
103 *          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
104 *          if HOWMNY = 'B', the matrix Q*X;
105 *          if HOWMNY = 'S', the right eigenvectors of T specified by
106 *                           SELECT, stored consecutively in the columns
107 *                           of VR, in the same order as their
108 *                           eigenvalues.
109 *          A complex eigenvector corresponding to a complex eigenvalue
110 *          is stored in two consecutive columns, the first holding the
111 *          real part and the second the imaginary part.
112 *          Not referenced if SIDE = 'L'.
113 *
114 *  LDVR    (input) INTEGER
115 *          The leading dimension of the array VR.  LDVR >= 1, and if
116 *          SIDE = 'R' or 'B', LDVR >= N.
117 *
118 *  MM      (input) INTEGER
119 *          The number of columns in the arrays VL and/or VR. MM >= M.
120 *
121 *  M       (output) INTEGER
122 *          The number of columns in the arrays VL and/or VR actually
123 *          used to store the eigenvectors.
124 *          If HOWMNY = 'A' or 'B', M is set to N.
125 *          Each selected real eigenvector occupies one column and each
126 *          selected complex eigenvector occupies two columns.
127 *
128 *  WORK    (workspace) DOUBLE PRECISION array, dimension (3*N)
129 *
130 *  INFO    (output) INTEGER
131 *          = 0:  successful exit
132 *          < 0:  if INFO = -i, the i-th argument had an illegal value
133 *
134 *  Further Details
135 *  ===============
136 *
137 *  The algorithm used in this program is basically backward (forward)
138 *  substitution, with scaling to make the the code robust against
139 *  possible overflow.
140 *
141 *  Each eigenvector is normalized so that the element of largest
142 *  magnitude has magnitude 1; here the magnitude of a complex number
143 *  (x,y) is taken to be |x| + |y|.
144 *
145 *  =====================================================================
146 *
147 *     .. Parameters ..
148       DOUBLE PRECISION   ZERO, ONE
149       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
150 *     ..
151 *     .. Local Scalars ..
152       LOGICAL            ALLV, BOTHV, LEFTV, OVER, PAIR, RIGHTV, SOMEV
153       INTEGER            I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI, N2
154       DOUBLE PRECISION   BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
155      $                   SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,
156      $                   XNORM
157 *     ..
158 *     .. External Functions ..
159       LOGICAL            LSAME
160       INTEGER            IDAMAX
161       DOUBLE PRECISION   DDOT, DLAMCH
162       EXTERNAL           LSAME, IDAMAX, DDOT, DLAMCH
163 *     ..
164 *     .. External Subroutines ..
165       EXTERNAL           DAXPY, DCOPY, DGEMV, DLALN2, DSCAL, XERBLA
166 *     ..
167 *     .. Intrinsic Functions ..
168       INTRINSIC          ABSMAXSQRT
169 *     ..
170 *     .. Local Arrays ..
171       DOUBLE PRECISION   X( 22 )
172 *     ..
173 *     .. Executable Statements ..
174 *
175 *     Decode and test the input parameters
176 *
177       BOTHV = LSAME( SIDE, 'B' )
178       RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
179       LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
180 *
181       ALLV = LSAME( HOWMNY, 'A' )
182       OVER = LSAME( HOWMNY, 'B' )
183       SOMEV = LSAME( HOWMNY, 'S' )
184 *
185       INFO = 0
186       IF.NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
187          INFO = -1
188       ELSE IF.NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
189          INFO = -2
190       ELSE IF( N.LT.0 ) THEN
191          INFO = -4
192       ELSE IF( LDT.LT.MAX1, N ) ) THEN
193          INFO = -6
194       ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
195          INFO = -8
196       ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
197          INFO = -10
198       ELSE
199 *
200 *        Set M to the number of columns required to store the selected
201 *        eigenvectors, standardize the array SELECT if necessary, and
202 *        test MM.
203 *
204          IF( SOMEV ) THEN
205             M = 0
206             PAIR = .FALSE.
207             DO 10 J = 1, N
208                IF( PAIR ) THEN
209                   PAIR = .FALSE.
210                   SELECT( J ) = .FALSE.
211                ELSE
212                   IF( J.LT.N ) THEN
213                      IF( T( J+1, J ).EQ.ZERO ) THEN
214                         IFSELECT( J ) )
215      $                     M = M + 1
216                      ELSE
217                         PAIR = .TRUE.
218                         IFSELECT( J ) .OR. SELECT( J+1 ) ) THEN
219                            SELECT( J ) = .TRUE.
220                            M = M + 2
221                         END IF
222                      END IF
223                   ELSE
224                      IFSELECT( N ) )
225      $                  M = M + 1
226                   END IF
227                END IF
228    10       CONTINUE
229          ELSE
230             M = N
231          END IF
232 *
233          IF( MM.LT.M ) THEN
234             INFO = -11
235          END IF
236       END IF
237       IF( INFO.NE.0 ) THEN
238          CALL XERBLA( 'DTREVC'-INFO )
239          RETURN
240       END IF
241 *
242 *     Quick return if possible.
243 *
244       IF( N.EQ.0 )
245      $   RETURN
246 *
247 *     Set the constants to control overflow.
248 *
249       UNFL = DLAMCH( 'Safe minimum' )
250       OVFL = ONE / UNFL
251       CALL DLABAD( UNFL, OVFL )
252       ULP = DLAMCH( 'Precision' )
253       SMLNUM = UNFL*( N / ULP )
254       BIGNUM = ( ONE-ULP ) / SMLNUM
255 *
256 *     Compute 1-norm of each column of strictly upper triangular
257 *     part of T to control overflow in triangular solver.
258 *
259       WORK( 1 ) = ZERO
260       DO 30 J = 2, N
261          WORK( J ) = ZERO
262          DO 20 I = 1, J - 1
263             WORK( J ) = WORK( J ) + ABS( T( I, J ) )
264    20    CONTINUE
265    30 CONTINUE
266 *
267 *     Index IP is used to specify the real or complex eigenvalue:
268 *       IP = 0, real eigenvalue,
269 *            1, first of conjugate complex pair: (wr,wi)
270 *           -1, second of conjugate complex pair: (wr,wi)
271 *
272       N2 = 2*N
273 *
274       IF( RIGHTV ) THEN
275 *
276 *        Compute right eigenvectors.
277 *
278          IP = 0
279          IS = M
280          DO 140 KI = N, 1-1
281 *
282             IF( IP.EQ.1 )
283      $         GO TO 130
284             IF( KI.EQ.1 )
285      $         GO TO 40
286             IF( T( KI, KI-1 ).EQ.ZERO )
287      $         GO TO 40
288             IP = -1
289 *
290    40       CONTINUE
291             IF( SOMEV ) THEN
292                IF( IP.EQ.0 ) THEN
293                   IF.NOT.SELECT( KI ) )
294      $               GO TO 130
295                ELSE
296                   IF.NOT.SELECT( KI-1 ) )
297      $               GO TO 130
298                END IF
299             END IF
300 *
301 *           Compute the KI-th eigenvalue (WR,WI).
302 *
303             WR = T( KI, KI )
304             WI = ZERO
305             IF( IP.NE.0 )
306      $         WI = SQRTABS( T( KI, KI-1 ) ) )*
307      $              SQRTABS( T( KI-1, KI ) ) )
308             SMIN = MAX( ULP*ABS( WR )+ABS( WI ) ), SMLNUM )
309 *
310             IF( IP.EQ.0 ) THEN
311 *
312 *              Real right eigenvector
313 *
314                WORK( KI+N ) = ONE
315 *
316 *              Form right-hand side
317 *
318                DO 50 K = 1, KI - 1
319                   WORK( K+N ) = -T( K, KI )
320    50          CONTINUE
321 *
322 *              Solve the upper quasi-triangular system:
323 *                 (T(1:KI-1,1:KI-1) - WR)*X = SCALE*WORK.
324 *
325                JNXT = KI - 1
326                DO 60 J = KI - 11-1
327                   IF( J.GT.JNXT )
328      $               GO TO 60
329                   J1 = J
330                   J2 = J
331                   JNXT = J - 1
332                   IF( J.GT.1 ) THEN
333                      IF( T( J, J-1 ).NE.ZERO ) THEN
334                         J1 = J - 1
335                         JNXT = J - 2
336                      END IF
337                   END IF
338 *
339                   IF( J1.EQ.J2 ) THEN
340 *
341 *                    1-by-1 diagonal block
342 *
343                      CALL DLALN2( .FALSE.11, SMIN, ONE, T( J, J ),
344      $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
345      $                            ZERO, X, 2SCALE, XNORM, IERR )
346 *
347 *                    Scale X(1,1) to avoid overflow when updating
348 *                    the right-hand side.
349 *
350                      IF( XNORM.GT.ONE ) THEN
351                         IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
352                            X( 11 ) = X( 11 ) / XNORM
353                            SCALE = SCALE / XNORM
354                         END IF
355                      END IF
356 *
357 *                    Scale if necessary
358 *
359                      IFSCALE.NE.ONE )
360      $                  CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
361                      WORK( J+N ) = X( 11 )
362 *
363 *                    Update right-hand side
364 *
365                      CALL DAXPY( J-1-X( 11 ), T( 1, J ), 1,
366      $                           WORK( 1+N ), 1 )
367 *
368                   ELSE
369 *
370 *                    2-by-2 diagonal block
371 *
372                      CALL DLALN2( .FALSE.21, SMIN, ONE,
373      $                            T( J-1, J-1 ), LDT, ONE, ONE,
374      $                            WORK( J-1+N ), N, WR, ZERO, X, 2,
375      $                            SCALE, XNORM, IERR )
376 *
377 *                    Scale X(1,1) and X(2,1) to avoid overflow when
378 *                    updating the right-hand side.
379 *
380                      IF( XNORM.GT.ONE ) THEN
381                         BETA = MAX( WORK( J-1 ), WORK( J ) )
382                         IF( BETA.GT.BIGNUM / XNORM ) THEN
383                            X( 11 ) = X( 11 ) / XNORM
384                            X( 21 ) = X( 21 ) / XNORM
385                            SCALE = SCALE / XNORM
386                         END IF
387                      END IF
388 *
389 *                    Scale if necessary
390 *
391                      IFSCALE.NE.ONE )
392      $                  CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
393                      WORK( J-1+N ) = X( 11 )
394                      WORK( J+N ) = X( 21 )
395 *
396 *                    Update right-hand side
397 *
398                      CALL DAXPY( J-2-X( 11 ), T( 1, J-1 ), 1,
399      $                           WORK( 1+N ), 1 )
400                      CALL DAXPY( J-2-X( 21 ), T( 1, J ), 1,
401      $                           WORK( 1+N ), 1 )
402                   END IF
403    60          CONTINUE
404 *
405 *              Copy the vector x or Q*x to VR and normalize.
406 *
407                IF.NOT.OVER ) THEN
408                   CALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS ), 1 )
409 *
410                   II = IDAMAX( KI, VR( 1, IS ), 1 )
411                   REMAX = ONE / ABS( VR( II, IS ) )
412                   CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )
413 *
414                   DO 70 K = KI + 1, N
415                      VR( K, IS ) = ZERO
416    70             CONTINUE
417                ELSE
418                   IF( KI.GT.1 )
419      $               CALL DGEMV( 'N', N, KI-1, ONE, VR, LDVR,
420      $                           WORK( 1+N ), 1, WORK( KI+N ),
421      $                           VR( 1, KI ), 1 )
422 *
423                   II = IDAMAX( N, VR( 1, KI ), 1 )
424                   REMAX = ONE / ABS( VR( II, KI ) )
425                   CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )
426                END IF
427 *
428             ELSE
429 *
430 *              Complex right eigenvector.
431 *
432 *              Initial solve
433 *                [ (T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I* WI)]*X = 0.
434 *                [ (T(KI,KI-1)   T(KI,KI)   )               ]
435 *
436                IFABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THEN
437                   WORK( KI-1+N ) = ONE
438                   WORK( KI+N2 ) = WI / T( KI-1, KI )
439                ELSE
440                   WORK( KI-1+N ) = -WI / T( KI, KI-1 )
441                   WORK( KI+N2 ) = ONE
442                END IF
443                WORK( KI+N ) = ZERO
444                WORK( KI-1+N2 ) = ZERO
445 *
446 *              Form right-hand side
447 *
448                DO 80 K = 1, KI - 2
449                   WORK( K+N ) = -WORK( KI-1+N )*T( K, KI-1 )
450                   WORK( K+N2 ) = -WORK( KI+N2 )*T( K, KI )
451    80          CONTINUE
452 *
453 *              Solve upper quasi-triangular system:
454 *              (T(1:KI-2,1:KI-2) - (WR+i*WI))*X = SCALE*(WORK+i*WORK2)
455 *
456                JNXT = KI - 2
457                DO 90 J = KI - 21-1
458                   IF( J.GT.JNXT )
459      $               GO TO 90
460                   J1 = J
461                   J2 = J
462                   JNXT = J - 1
463                   IF( J.GT.1 ) THEN
464                      IF( T( J, J-1 ).NE.ZERO ) THEN
465                         J1 = J - 1
466                         JNXT = J - 2
467                      END IF
468                   END IF
469 *
470                   IF( J1.EQ.J2 ) THEN
471 *
472 *                    1-by-1 diagonal block
473 *
474                      CALL DLALN2( .FALSE.12, SMIN, ONE, T( J, J ),
475      $                            LDT, ONE, ONE, WORK( J+N ), N, WR, WI,
476      $                            X, 2SCALE, XNORM, IERR )
477 *
478 *                    Scale X(1,1) and X(1,2) to avoid overflow when
479 *                    updating the right-hand side.
480 *
481                      IF( XNORM.GT.ONE ) THEN
482                         IF( WORK( J ).GT.BIGNUM / XNORM ) THEN
483                            X( 11 ) = X( 11 ) / XNORM
484                            X( 12 ) = X( 12 ) / XNORM
485                            SCALE = SCALE / XNORM
486                         END IF
487                      END IF
488 *
489 *                    Scale if necessary
490 *
491                      IFSCALE.NE.ONE ) THEN
492                         CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
493                         CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )
494                      END IF
495                      WORK( J+N ) = X( 11 )
496                      WORK( J+N2 ) = X( 12 )
497 *
498 *                    Update the right-hand side
499 *
500                      CALL DAXPY( J-1-X( 11 ), T( 1, J ), 1,
501      $                           WORK( 1+N ), 1 )
502                      CALL DAXPY( J-1-X( 12 ), T( 1, J ), 1,
503      $                           WORK( 1+N2 ), 1 )
504 *
505                   ELSE
506 *
507 *                    2-by-2 diagonal block
508 *
509                      CALL DLALN2( .FALSE.22, SMIN, ONE,
510      $                            T( J-1, J-1 ), LDT, ONE, ONE,
511      $                            WORK( J-1+N ), N, WR, WI, X, 2SCALE,
512      $                            XNORM, IERR )
513 *
514 *                    Scale X to avoid overflow when updating
515 *                    the right-hand side.
516 *
517                      IF( XNORM.GT.ONE ) THEN
518                         BETA = MAX( WORK( J-1 ), WORK( J ) )
519                         IF( BETA.GT.BIGNUM / XNORM ) THEN
520                            REC = ONE / XNORM
521                            X( 11 ) = X( 11 )*REC
522                            X( 12 ) = X( 12 )*REC
523                            X( 21 ) = X( 21 )*REC
524                            X( 22 ) = X( 22 )*REC
525                            SCALE = SCALE*REC
526                         END IF
527                      END IF
528 *
529 *                    Scale if necessary
530 *
531                      IFSCALE.NE.ONE ) THEN
532                         CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
533                         CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )
534                      END IF
535                      WORK( J-1+N ) = X( 11 )
536                      WORK( J+N ) = X( 21 )
537                      WORK( J-1+N2 ) = X( 12 )
538                      WORK( J+N2 ) = X( 22 )
539 *
540 *                    Update the right-hand side
541 *
542                      CALL DAXPY( J-2-X( 11 ), T( 1, J-1 ), 1,
543      $                           WORK( 1+N ), 1 )
544                      CALL DAXPY( J-2-X( 21 ), T( 1, J ), 1,
545      $                           WORK( 1+N ), 1 )
546                      CALL DAXPY( J-2-X( 12 ), T( 1, J-1 ), 1,
547      $                           WORK( 1+N2 ), 1 )
548                      CALL DAXPY( J-2-X( 22 ), T( 1, J ), 1,
549      $                           WORK( 1+N2 ), 1 )
550                   END IF
551    90          CONTINUE
552 *
553 *              Copy the vector x or Q*x to VR and normalize.
554 *
555                IF.NOT.OVER ) THEN
556                   CALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS-1 ), 1 )
557                   CALL DCOPY( KI, WORK( 1+N2 ), 1, VR( 1, IS ), 1 )
558 *
559                   EMAX = ZERO
560                   DO 100 K = 1, KI
561                      EMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+
562      $                      ABS( VR( K, IS ) ) )
563   100             CONTINUE
564 *
565                   REMAX = ONE / EMAX
566                   CALL DSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )
567                   CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )
568 *
569                   DO 110 K = KI + 1, N
570                      VR( K, IS-1 ) = ZERO
571                      VR( K, IS ) = ZERO
572   110             CONTINUE
573 *
574                ELSE
575 *
576                   IF( KI.GT.2 ) THEN
577                      CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,
578      $                           WORK( 1+N ), 1, WORK( KI-1+N ),
579      $                           VR( 1, KI-1 ), 1 )
580                      CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,
581      $                           WORK( 1+N2 ), 1, WORK( KI+N2 ),
582      $                           VR( 1, KI ), 1 )
583                   ELSE
584                      CALL DSCAL( N, WORK( KI-1+N ), VR( 1, KI-1 ), 1 )
585                      CALL DSCAL( N, WORK( KI+N2 ), VR( 1, KI ), 1 )
586                   END IF
587 *
588                   EMAX = ZERO
589                   DO 120 K = 1, N
590                      EMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+
591      $                      ABS( VR( K, KI ) ) )
592   120             CONTINUE
593                   REMAX = ONE / EMAX
594                   CALL DSCAL( N, REMAX, VR( 1, KI-1 ), 1 )
595                   CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )
596                END IF
597             END IF
598 *
599             IS = IS - 1
600             IF( IP.NE.0 )
601      $         IS = IS - 1
602   130       CONTINUE
603             IF( IP.EQ.1 )
604      $         IP = 0
605             IF( IP.EQ.-1 )
606      $         IP = 1
607   140    CONTINUE
608       END IF
609 *
610       IF( LEFTV ) THEN
611 *
612 *        Compute left eigenvectors.
613 *
614          IP = 0
615          IS = 1
616          DO 260 KI = 1, N
617 *
618             IF( IP.EQ.-1 )
619      $         GO TO 250
620             IF( KI.EQ.N )
621      $         GO TO 150
622             IF( T( KI+1, KI ).EQ.ZERO )
623      $         GO TO 150
624             IP = 1
625 *
626   150       CONTINUE
627             IF( SOMEV ) THEN
628                IF.NOT.SELECT( KI ) )
629      $            GO TO 250
630             END IF
631 *
632 *           Compute the KI-th eigenvalue (WR,WI).
633 *
634             WR = T( KI, KI )
635             WI = ZERO
636             IF( IP.NE.0 )
637      $         WI = SQRTABS( T( KI, KI+1 ) ) )*
638      $              SQRTABS( T( KI+1, KI ) ) )
639             SMIN = MAX( ULP*ABS( WR )+ABS( WI ) ), SMLNUM )
640 *
641             IF( IP.EQ.0 ) THEN
642 *
643 *              Real left eigenvector.
644 *
645                WORK( KI+N ) = ONE
646 *
647 *              Form right-hand side
648 *
649                DO 160 K = KI + 1, N
650                   WORK( K+N ) = -T( KI, K )
651   160          CONTINUE
652 *
653 *              Solve the quasi-triangular system:
654 *                 (T(KI+1:N,KI+1:N) - WR)**T*X = SCALE*WORK
655 *
656                VMAX = ONE
657                VCRIT = BIGNUM
658 *
659                JNXT = KI + 1
660                DO 170 J = KI + 1, N
661                   IF( J.LT.JNXT )
662      $               GO TO 170
663                   J1 = J
664                   J2 = J
665                   JNXT = J + 1
666                   IF( J.LT.N ) THEN
667                      IF( T( J+1, J ).NE.ZERO ) THEN
668                         J2 = J + 1
669                         JNXT = J + 2
670                      END IF
671                   END IF
672 *
673                   IF( J1.EQ.J2 ) THEN
674 *
675 *                    1-by-1 diagonal block
676 *
677 *                    Scale if necessary to avoid overflow when forming
678 *                    the right-hand side.
679 *
680                      IF( WORK( J ).GT.VCRIT ) THEN
681                         REC = ONE / VMAX
682                         CALL DSCAL( N-KI+1REC, WORK( KI+N ), 1 )
683                         VMAX = ONE
684                         VCRIT = BIGNUM
685                      END IF
686 *
687                      WORK( J+N ) = WORK( J+N ) -
688      $                             DDOT( J-KI-1, T( KI+1, J ), 1,
689      $                             WORK( KI+1+N ), 1 )
690 *
691 *                    Solve (T(J,J)-WR)**T*X = WORK
692 *
693                      CALL DLALN2( .FALSE.11, SMIN, ONE, T( J, J ),
694      $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
695      $                            ZERO, X, 2SCALE, XNORM, IERR )
696 *
697 *                    Scale if necessary
698 *
699                      IFSCALE.NE.ONE )
700      $                  CALL DSCAL( N-KI+1SCALE, WORK( KI+N ), 1 )
701                      WORK( J+N ) = X( 11 )
702                      VMAX = MAXABS( WORK( J+N ) ), VMAX )
703                      VCRIT = BIGNUM / VMAX
704 *
705                   ELSE
706 *
707 *                    2-by-2 diagonal block
708 *
709 *                    Scale if necessary to avoid overflow when forming
710 *                    the right-hand side.
711 *
712                      BETA = MAX( WORK( J ), WORK( J+1 ) )
713                      IF( BETA.GT.VCRIT ) THEN
714                         REC = ONE / VMAX
715                         CALL DSCAL( N-KI+1REC, WORK( KI+N ), 1 )
716                         VMAX = ONE
717                         VCRIT = BIGNUM
718                      END IF
719 *
720                      WORK( J+N ) = WORK( J+N ) -
721      $                             DDOT( J-KI-1, T( KI+1, J ), 1,
722      $                             WORK( KI+1+N ), 1 )
723 *
724                      WORK( J+1+N ) = WORK( J+1+N ) -
725      $                               DDOT( J-KI-1, T( KI+1, J+1 ), 1,
726      $                               WORK( KI+1+N ), 1 )
727 *
728 *                    Solve
729 *                      [T(J,J)-WR   T(J,J+1)     ]**T * X = SCALE*( WORK1 )
730 *                      [T(J+1,J)    T(J+1,J+1)-WR]                ( WORK2 )
731 *
732                      CALL DLALN2( .TRUE.21, SMIN, ONE, T( J, J ),
733      $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
734      $                            ZERO, X, 2SCALE, XNORM, IERR )
735 *
736 *                    Scale if necessary
737 *
738                      IFSCALE.NE.ONE )
739      $                  CALL DSCAL( N-KI+1SCALE, WORK( KI+N ), 1 )
740                      WORK( J+N ) = X( 11 )
741                      WORK( J+1+N ) = X( 21 )
742 *
743                      VMAX = MAXABS( WORK( J+N ) ),
744      $                      ABS( WORK( J+1+N ) ), VMAX )
745                      VCRIT = BIGNUM / VMAX
746 *
747                   END IF
748   170          CONTINUE
749 *
750 *              Copy the vector x or Q*x to VL and normalize.
751 *
752                IF.NOT.OVER ) THEN
753                   CALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )
754 *
755                   II = IDAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
756                   REMAX = ONE / ABS( VL( II, IS ) )
757                   CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
758 *
759                   DO 180 K = 1, KI - 1
760                      VL( K, IS ) = ZERO
761   180             CONTINUE
762 *
763                ELSE
764 *
765                   IF( KI.LT.N )
766      $               CALL DGEMV( 'N', N, N-KI, ONE, VL( 1, KI+1 ), LDVL,
767      $                           WORK( KI+1+N ), 1, WORK( KI+N ),
768      $                           VL( 1, KI ), 1 )
769 *
770                   II = IDAMAX( N, VL( 1, KI ), 1 )
771                   REMAX = ONE / ABS( VL( II, KI ) )
772                   CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )
773 *
774                END IF
775 *
776             ELSE
777 *
778 *              Complex left eigenvector.
779 *
780 *               Initial solve:
781 *                 ((T(KI,KI)    T(KI,KI+1) )**T - (WR - I* WI))*X = 0.
782 *                 ((T(KI+1,KI) T(KI+1,KI+1))                )
783 *
784                IFABS( T( KI, KI+1 ) ).GE.ABS( T( KI+1, KI ) ) ) THEN
785                   WORK( KI+N ) = WI / T( KI, KI+1 )
786                   WORK( KI+1+N2 ) = ONE
787                ELSE
788                   WORK( KI+N ) = ONE
789                   WORK( KI+1+N2 ) = -WI / T( KI+1, KI )
790                END IF
791                WORK( KI+1+N ) = ZERO
792                WORK( KI+N2 ) = ZERO
793 *
794 *              Form right-hand side
795 *
796                DO 190 K = KI + 2, N
797                   WORK( K+N ) = -WORK( KI+N )*T( KI, K )
798                   WORK( K+N2 ) = -WORK( KI+1+N2 )*T( KI+1, K )
799   190          CONTINUE
800 *
801 *              Solve complex quasi-triangular system:
802 *              ( T(KI+2,N:KI+2,N) - (WR-i*WI) )*X = WORK1+i*WORK2
803 *
804                VMAX = ONE
805                VCRIT = BIGNUM
806 *
807                JNXT = KI + 2
808                DO 200 J = KI + 2, N
809                   IF( J.LT.JNXT )
810      $               GO TO 200
811                   J1 = J
812                   J2 = J
813                   JNXT = J + 1
814                   IF( J.LT.N ) THEN
815                      IF( T( J+1, J ).NE.ZERO ) THEN
816                         J2 = J + 1
817                         JNXT = J + 2
818                      END IF
819                   END IF
820 *
821                   IF( J1.EQ.J2 ) THEN
822 *
823 *                    1-by-1 diagonal block
824 *
825 *                    Scale if necessary to avoid overflow when
826 *                    forming the right-hand side elements.
827 *
828                      IF( WORK( J ).GT.VCRIT ) THEN
829                         REC = ONE / VMAX
830                         CALL DSCAL( N-KI+1REC, WORK( KI+N ), 1 )
831                         CALL DSCAL( N-KI+1REC, WORK( KI+N2 ), 1 )
832                         VMAX = ONE
833                         VCRIT = BIGNUM
834                      END IF
835 *
836                      WORK( J+N ) = WORK( J+N ) -
837      $                             DDOT( J-KI-2, T( KI+2, J ), 1,
838      $                             WORK( KI+2+N ), 1 )
839                      WORK( J+N2 ) = WORK( J+N2 ) -
840      $                              DDOT( J-KI-2, T( KI+2, J ), 1,
841      $                              WORK( KI+2+N2 ), 1 )
842 *
843 *                    Solve (T(J,J)-(WR-i*WI))*(X11+i*X12)= WK+I*WK2
844 *
845                      CALL DLALN2( .FALSE.12, SMIN, ONE, T( J, J ),
846      $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
847      $                            -WI, X, 2SCALE, XNORM, IERR )
848 *
849 *                    Scale if necessary
850 *
851                      IFSCALE.NE.ONE ) THEN
852                         CALL DSCAL( N-KI+1SCALE, WORK( KI+N ), 1 )
853                         CALL DSCAL( N-KI+1SCALE, WORK( KI+N2 ), 1 )
854                      END IF
855                      WORK( J+N ) = X( 11 )
856                      WORK( J+N2 ) = X( 12 )
857                      VMAX = MAXABS( WORK( J+N ) ),
858      $                      ABS( WORK( J+N2 ) ), VMAX )
859                      VCRIT = BIGNUM / VMAX
860 *
861                   ELSE
862 *
863 *                    2-by-2 diagonal block
864 *
865 *                    Scale if necessary to avoid overflow when forming
866 *                    the right-hand side elements.
867 *
868                      BETA = MAX( WORK( J ), WORK( J+1 ) )
869                      IF( BETA.GT.VCRIT ) THEN
870                         REC = ONE / VMAX
871                         CALL DSCAL( N-KI+1REC, WORK( KI+N ), 1 )
872                         CALL DSCAL( N-KI+1REC, WORK( KI+N2 ), 1 )
873                         VMAX = ONE
874                         VCRIT = BIGNUM
875                      END IF
876 *
877                      WORK( J+N ) = WORK( J+N ) -
878      $                             DDOT( J-KI-2, T( KI+2, J ), 1,
879      $                             WORK( KI+2+N ), 1 )
880 *
881                      WORK( J+N2 ) = WORK( J+N2 ) -
882      $                              DDOT( J-KI-2, T( KI+2, J ), 1,
883      $                              WORK( KI+2+N2 ), 1 )
884 *
885                      WORK( J+1+N ) = WORK( J+1+N ) -
886      $                               DDOT( J-KI-2, T( KI+2, J+1 ), 1,
887      $                               WORK( KI+2+N ), 1 )
888 *
889                      WORK( J+1+N2 ) = WORK( J+1+N2 ) -
890      $                                DDOT( J-KI-2, T( KI+2, J+1 ), 1,
891      $                                WORK( KI+2+N2 ), 1 )
892 *
893 *                    Solve 2-by-2 complex linear equation
894 *                      ([T(j,j)   T(j,j+1)  ]**T-(wr-i*wi)*I)*X = SCALE*B
895 *                      ([T(j+1,j) T(j+1,j+1)]               )
896 *
897                      CALL DLALN2( .TRUE.22, SMIN, ONE, T( J, J ),
898      $                            LDT, ONE, ONE, WORK( J+N ), N, WR,
899      $                            -WI, X, 2SCALE, XNORM, IERR )
900 *
901 *                    Scale if necessary
902 *
903                      IFSCALE.NE.ONE ) THEN
904                         CALL DSCAL( N-KI+1SCALE, WORK( KI+N ), 1 )
905                         CALL DSCAL( N-KI+1SCALE, WORK( KI+N2 ), 1 )
906                      END IF
907                      WORK( J+N ) = X( 11 )
908                      WORK( J+N2 ) = X( 12 )
909                      WORK( J+1+N ) = X( 21 )
910                      WORK( J+1+N2 ) = X( 22 )
911                      VMAX = MAXABS( X( 11 ) ), ABS( X( 12 ) ),
912      $                      ABS( X( 21 ) ), ABS( X( 22 ) ), VMAX )
913                      VCRIT = BIGNUM / VMAX
914 *
915                   END IF
916   200          CONTINUE
917 *
918 *              Copy the vector x or Q*x to VL and normalize.
919 *
920                IF.NOT.OVER ) THEN
921                   CALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )
922                   CALL DCOPY( N-KI+1, WORK( KI+N2 ), 1, VL( KI, IS+1 ),
923      $                        1 )
924 *
925                   EMAX = ZERO
926                   DO 220 K = KI, N
927                      EMAX = MAX( EMAX, ABS( VL( K, IS ) )+
928      $                      ABS( VL( K, IS+1 ) ) )
929   220             CONTINUE
930                   REMAX = ONE / EMAX
931                   CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
932                   CALL DSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )
933 *
934                   DO 230 K = 1, KI - 1
935                      VL( K, IS ) = ZERO
936                      VL( K, IS+1 ) = ZERO
937   230             CONTINUE
938                ELSE
939                   IF( KI.LT.N-1 ) THEN
940                      CALL DGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),
941      $                           LDVL, WORK( KI+2+N ), 1, WORK( KI+N ),
942      $                           VL( 1, KI ), 1 )
943                      CALL DGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),
944      $                           LDVL, WORK( KI+2+N2 ), 1,
945      $                           WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )
946                   ELSE
947                      CALL DSCAL( N, WORK( KI+N ), VL( 1, KI ), 1 )
948                      CALL DSCAL( N, WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )
949                   END IF
950 *
951                   EMAX = ZERO
952                   DO 240 K = 1, N
953                      EMAX = MAX( EMAX, ABS( VL( K, KI ) )+
954      $                      ABS( VL( K, KI+1 ) ) )
955   240             CONTINUE
956                   REMAX = ONE / EMAX
957                   CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )
958                   CALL DSCAL( N, REMAX, VL( 1, KI+1 ), 1 )
959 *
960                END IF
961 *
962             END IF
963 *
964             IS = IS + 1
965             IF( IP.NE.0 )
966      $         IS = IS + 1
967   250       CONTINUE
968             IF( IP.EQ.-1 )
969      $         IP = 0
970             IF( IP.EQ.1 )
971      $         IP = -1
972 *
973   260    CONTINUE
974 *
975       END IF
976 *
977       RETURN
978 *
979 *     End of DTREVC
980 *
981       END