3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DTREVC + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrevc.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrevc.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrevc.f">
21 * SUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
22 * LDVR, MM, M, WORK, INFO )
24 * .. Scalar Arguments ..
25 * CHARACTER HOWMNY, SIDE
26 * INTEGER INFO, LDT, LDVL, LDVR, M, MM, N
28 * .. Array Arguments ..
30 * DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
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.
45 *> The right eigenvector x and the left eigenvector y of T corresponding
46 *> to an eigenvalue w are defined by:
48 *> T*x = w*x, (y**T)*T = w*(y**T)
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.
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.
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.
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.
82 *> \param[in,out] SELECT
84 *> SELECT is LOGICAL array, dimension (N)
85 *> If HOWMNY = 'S', SELECT specifies the eigenvectors to be
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
94 *> Not referenced if HOWMNY = 'A' or 'B'.
100 *> The order of the matrix T. N >= 0.
105 *> T is DOUBLE PRECISION array, dimension (LDT,N)
106 *> The upper quasi-triangular matrix T in Schur canonical form.
112 *> The leading dimension of the array T. LDT >= max(1,N).
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
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'.
137 *> The leading dimension of the array VL. LDVL >= 1, and if
138 *> SIDE = 'L' or 'B', LDVL >= N.
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
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'.
163 *> The leading dimension of the array VR. LDVR >= 1, and if
164 *> SIDE = 'R' or 'B', LDVR >= N.
170 *> The number of columns in the arrays VL and/or VR. MM >= M.
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.
185 *> WORK is DOUBLE PRECISION array, dimension (3*N)
191 *> = 0: successful exit
192 *> < 0: if INFO = -i, the i-th argument had an illegal value
198 *> \author Univ. of Tennessee
199 *> \author Univ. of California Berkeley
200 *> \author Univ. of Colorado Denver
203 *> \date November 2011
205 *> \ingroup doubleOTHERcomputational
207 *> \par Further Details:
208 * =====================
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.
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|.
221 * =====================================================================
222 SUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
223 $ LDVR, MM, M, WORK, INFO )
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..--
230 * .. Scalar Arguments ..
231 CHARACTER HOWMNY, SIDE
232 INTEGER INFO, LDT, LDVL, LDVR, M, MM, N
234 * .. Array Arguments ..
236 DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
240 * =====================================================================
243 DOUBLE PRECISION ZERO, ONE
244 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
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,
253 * .. External Functions ..
256 DOUBLE PRECISION DDOT, DLAMCH
257 EXTERNAL LSAME, IDAMAX, DDOT, DLAMCH
259 * .. External Subroutines ..
260 EXTERNAL DAXPY, DCOPY, DGEMV, DLALN2, DSCAL, XERBLA
262 * .. Intrinsic Functions ..
263 INTRINSIC ABS, MAX, SQRT
266 DOUBLE PRECISION X( 2, 2 )
268 * .. Executable Statements ..
270 * Decode and test the input parameters
272 BOTHV = LSAME( SIDE, 'B' )
273 RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
274 LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
276 ALLV = LSAME( HOWMNY, 'A' )
277 OVER = LSAME( HOWMNY, 'B' )
278 SOMEV = LSAME( HOWMNY, 'S' )
281 IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
283 ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
285 ELSE IF( N.LT.0 ) THEN
287 ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
289 ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
291 ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
295 * Set M to the number of columns required to store the selected
296 * eigenvectors, standardize the array SELECT if necessary, and
305 SELECT( J ) = .FALSE.
308 IF( T( J+1, J ).EQ.ZERO ) THEN
313 IF( SELECT( J ) .OR. SELECT( J+1 ) ) THEN
333 CALL XERBLA( 'DTREVC', -INFO )
337 * Quick return if possible.
342 * Set the constants to control overflow.
344 UNFL = DLAMCH( 'Safe minimum' )
346 CALL DLABAD( UNFL, OVFL )
347 ULP = DLAMCH( 'Precision' )
348 SMLNUM = UNFL*( N / ULP )
349 BIGNUM = ( ONE-ULP ) / SMLNUM
351 * Compute 1-norm of each column of strictly upper triangular
352 * part of T to control overflow in triangular solver.
358 WORK( J ) = WORK( J ) + ABS( T( I, J ) )
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)
371 * Compute right eigenvectors.
381 IF( T( KI, KI-1 ).EQ.ZERO )
388 IF( .NOT.SELECT( KI ) )
391 IF( .NOT.SELECT( KI-1 ) )
396 * Compute the KI-th eigenvalue (WR,WI).
401 $ WI = SQRT( ABS( T( KI, KI-1 ) ) )*
402 $ SQRT( ABS( T( KI-1, KI ) ) )
403 SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
407 * Real right eigenvector
411 * Form right-hand side
414 WORK( K+N ) = -T( K, KI )
417 * Solve the upper quasi-triangular system:
418 * (T(1:KI-1,1:KI-1) - WR)*X = SCALE*WORK.
421 DO 60 J = KI - 1, 1, -1
428 IF( T( J, J-1 ).NE.ZERO ) THEN
436 * 1-by-1 diagonal block
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 )
442 * Scale X(1,1) to avoid overflow when updating
443 * the right-hand side.
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
455 $ CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
456 WORK( J+N ) = X( 1, 1 )
458 * Update right-hand side
460 CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
465 * 2-by-2 diagonal block
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 )
472 * Scale X(1,1) and X(2,1) to avoid overflow when
473 * updating the right-hand side.
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
487 $ CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
488 WORK( J-1+N ) = X( 1, 1 )
489 WORK( J+N ) = X( 2, 1 )
491 * Update right-hand side
493 CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
495 CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
500 * Copy the vector x or Q*x to VR and normalize.
503 CALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS ), 1 )
505 II = IDAMAX( KI, VR( 1, IS ), 1 )
506 REMAX = ONE / ABS( VR( II, IS ) )
507 CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )
514 $ CALL DGEMV( 'N', N, KI-1, ONE, VR, LDVR,
515 $ WORK( 1+N ), 1, WORK( KI+N ),
518 II = IDAMAX( N, VR( 1, KI ), 1 )
519 REMAX = ONE / ABS( VR( II, KI ) )
520 CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )
525 * Complex right eigenvector.
528 * [ (T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I* WI)]*X = 0.
529 * [ (T(KI,KI-1) T(KI,KI) ) ]
531 IF( ABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THEN
533 WORK( KI+N2 ) = WI / T( KI-1, KI )
535 WORK( KI-1+N ) = -WI / T( KI, KI-1 )
539 WORK( KI-1+N2 ) = ZERO
541 * Form right-hand side
544 WORK( K+N ) = -WORK( KI-1+N )*T( K, KI-1 )
545 WORK( K+N2 ) = -WORK( KI+N2 )*T( K, KI )
548 * Solve upper quasi-triangular system:
549 * (T(1:KI-2,1:KI-2) - (WR+i*WI))*X = SCALE*(WORK+i*WORK2)
552 DO 90 J = KI - 2, 1, -1
559 IF( T( J, J-1 ).NE.ZERO ) THEN
567 * 1-by-1 diagonal block
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 )
573 * Scale X(1,1) and X(1,2) to avoid overflow when
574 * updating the right-hand side.
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
586 IF( SCALE.NE.ONE ) THEN
587 CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
588 CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )
590 WORK( J+N ) = X( 1, 1 )
591 WORK( J+N2 ) = X( 1, 2 )
593 * Update the right-hand side
595 CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,
597 CALL DAXPY( J-1, -X( 1, 2 ), T( 1, J ), 1,
602 * 2-by-2 diagonal block
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,
609 * Scale X to avoid overflow when updating
610 * the right-hand side.
612 IF( XNORM.GT.ONE ) THEN
613 BETA = MAX( WORK( J-1 ), WORK( J ) )
614 IF( BETA.GT.BIGNUM / XNORM ) THEN
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
626 IF( SCALE.NE.ONE ) THEN
627 CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )
628 CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )
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 )
635 * Update the right-hand side
637 CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,
639 CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,
641 CALL DAXPY( J-2, -X( 1, 2 ), T( 1, J-1 ), 1,
643 CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1,
648 * Copy the vector x or Q*x to VR and normalize.
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 )
656 EMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+
657 $ ABS( VR( K, IS ) ) )
661 CALL DSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )
662 CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )
672 CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,
673 $ WORK( 1+N ), 1, WORK( KI-1+N ),
675 CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,
676 $ WORK( 1+N2 ), 1, WORK( KI+N2 ),
679 CALL DSCAL( N, WORK( KI-1+N ), VR( 1, KI-1 ), 1 )
680 CALL DSCAL( N, WORK( KI+N2 ), VR( 1, KI ), 1 )
685 EMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+
686 $ ABS( VR( K, KI ) ) )
689 CALL DSCAL( N, REMAX, VR( 1, KI-1 ), 1 )
690 CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )
707 * Compute left eigenvectors.
717 IF( T( KI+1, KI ).EQ.ZERO )
723 IF( .NOT.SELECT( KI ) )
727 * Compute the KI-th eigenvalue (WR,WI).
732 $ WI = SQRT( ABS( T( KI, KI+1 ) ) )*
733 $ SQRT( ABS( T( KI+1, KI ) ) )
734 SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )
738 * Real left eigenvector.
742 * Form right-hand side
745 WORK( K+N ) = -T( KI, K )
748 * Solve the quasi-triangular system:
749 * (T(KI+1:N,KI+1:N) - WR)**T*X = SCALE*WORK
762 IF( T( J+1, J ).NE.ZERO ) THEN
770 * 1-by-1 diagonal block
772 * Scale if necessary to avoid overflow when forming
773 * the right-hand side.
775 IF( WORK( J ).GT.VCRIT ) THEN
777 CALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
782 WORK( J+N ) = WORK( J+N ) -
783 $ DDOT( J-KI-1, T( KI+1, J ), 1,
784 $ WORK( KI+1+N ), 1 )
786 * Solve (T(J,J)-WR)**T*X = WORK
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 )
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
802 * 2-by-2 diagonal block
804 * Scale if necessary to avoid overflow when forming
805 * the right-hand side.
807 BETA = MAX( WORK( J ), WORK( J+1 ) )
808 IF( BETA.GT.VCRIT ) THEN
810 CALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
815 WORK( J+N ) = WORK( J+N ) -
816 $ DDOT( J-KI-1, T( KI+1, J ), 1,
817 $ WORK( KI+1+N ), 1 )
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 )
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 )
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 )
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 )
838 VMAX = MAX( ABS( WORK( J+N ) ),
839 $ ABS( WORK( J+1+N ) ), VMAX )
840 VCRIT = BIGNUM / VMAX
845 * Copy the vector x or Q*x to VL and normalize.
848 CALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )
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 )
861 $ CALL DGEMV( 'N', N, N-KI, ONE, VL( 1, KI+1 ), LDVL,
862 $ WORK( KI+1+N ), 1, WORK( KI+N ),
865 II = IDAMAX( N, VL( 1, KI ), 1 )
866 REMAX = ONE / ABS( VL( II, KI ) )
867 CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )
873 * Complex left eigenvector.
876 * ((T(KI,KI) T(KI,KI+1) )**T - (WR - I* WI))*X = 0.
877 * ((T(KI+1,KI) T(KI+1,KI+1)) )
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
884 WORK( KI+1+N2 ) = -WI / T( KI+1, KI )
886 WORK( KI+1+N ) = ZERO
889 * Form right-hand side
892 WORK( K+N ) = -WORK( KI+N )*T( KI, K )
893 WORK( K+N2 ) = -WORK( KI+1+N2 )*T( KI+1, K )
896 * Solve complex quasi-triangular system:
897 * ( T(KI+2,N:KI+2,N) - (WR-i*WI) )*X = WORK1+i*WORK2
910 IF( T( J+1, J ).NE.ZERO ) THEN
918 * 1-by-1 diagonal block
920 * Scale if necessary to avoid overflow when
921 * forming the right-hand side elements.
923 IF( WORK( J ).GT.VCRIT ) THEN
925 CALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
926 CALL DSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )
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 )
938 * Solve (T(J,J)-(WR-i*WI))*(X11+i*X12)= WK+I*WK2
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 )
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 )
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
958 * 2-by-2 diagonal block
960 * Scale if necessary to avoid overflow when forming
961 * the right-hand side elements.
963 BETA = MAX( WORK( J ), WORK( J+1 ) )
964 IF( BETA.GT.VCRIT ) THEN
966 CALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )
967 CALL DSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )
972 WORK( J+N ) = WORK( J+N ) -
973 $ DDOT( J-KI-2, T( KI+2, J ), 1,
974 $ WORK( KI+2+N ), 1 )
976 WORK( J+N2 ) = WORK( J+N2 ) -
977 $ DDOT( J-KI-2, T( KI+2, J ), 1,
978 $ WORK( KI+2+N2 ), 1 )
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 )
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 )
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)] )
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 )
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 )
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
1013 * Copy the vector x or Q*x to VL and normalize.
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 ),
1022 EMAX = MAX( EMAX, ABS( VL( K, IS ) )+
1023 $ ABS( VL( K, IS+1 ) ) )
1026 CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
1027 CALL DSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )
1029 DO 230 K = 1, KI - 1
1031 VL( K, IS+1 ) = ZERO
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 ),
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 )
1042 CALL DSCAL( N, WORK( KI+N ), VL( 1, KI ), 1 )
1043 CALL DSCAL( N, WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )
1048 EMAX = MAX( EMAX, ABS( VL( K, KI ) )+
1049 $ ABS( VL( K, KI+1 ) ) )
1052 CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )
1053 CALL DSCAL( N, REMAX, VL( 1, KI+1 ), 1 )