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