LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ strevc()

subroutine strevc ( character side,
character howmny,
logical, dimension( * ) select,
integer n,
real, dimension( ldt, * ) t,
integer ldt,
real, dimension( ldvl, * ) vl,
integer ldvl,
real, dimension( ldvr, * ) vr,
integer ldvr,
integer mm,
integer m,
real, dimension( * ) work,
integer info )

STREVC

Download STREVC + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> STREVC computes some or all of the right and/or left eigenvectors of
!> a real upper quasi-triangular matrix T.
!> Matrices of this type are produced by the Schur factorization of
!> a real general matrix:  A = Q*T*Q**T, as computed by SHSEQR.
!>
!> The right eigenvector x and the left eigenvector y of T corresponding
!> to an eigenvalue w are defined by:
!>
!>    T*x = w*x,     (y**H)*T = w*(y**H)
!>
!> where y**H denotes the conjugate transpose of y.
!> The eigenvalues are not input to this routine, but are read directly
!> from the diagonal blocks of T.
!>
!> This routine returns the matrices X and/or Y of right and left
!> eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
!> input matrix.  If Q is the orthogonal factor that reduces a matrix
!> A to Schur form T, then Q*X and Q*Y are the matrices of right and
!> left eigenvectors of A.
!> 
Parameters
[in]SIDE
!>          SIDE is CHARACTER*1
!>          = 'R':  compute right eigenvectors only;
!>          = 'L':  compute left eigenvectors only;
!>          = 'B':  compute both right and left eigenvectors.
!> 
[in]HOWMNY
!>          HOWMNY is CHARACTER*1
!>          = 'A':  compute all right and/or left eigenvectors;
!>          = 'B':  compute all right and/or left eigenvectors,
!>                  backtransformed by the matrices in VR and/or VL;
!>          = 'S':  compute selected right and/or left eigenvectors,
!>                  as indicated by the logical array SELECT.
!> 
[in,out]SELECT
!>          SELECT is LOGICAL array, dimension (N)
!>          If HOWMNY = 'S', SELECT specifies the eigenvectors to be
!>          computed.
!>          If w(j) is a real eigenvalue, the corresponding real
!>          eigenvector is computed if SELECT(j) is .TRUE..
!>          If w(j) and w(j+1) are the real and imaginary parts of a
!>          complex eigenvalue, the corresponding complex eigenvector is
!>          computed if either SELECT(j) or SELECT(j+1) is .TRUE., and
!>          on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to
!>          .FALSE..
!>          Not referenced if HOWMNY = 'A' or 'B'.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix T. N >= 0.
!> 
[in]T
!>          T is REAL array, dimension (LDT,N)
!>          The upper quasi-triangular matrix T in Schur canonical form.
!> 
[in]LDT
!>          LDT is INTEGER
!>          The leading dimension of the array T. LDT >= max(1,N).
!> 
[in,out]VL
!>          VL is REAL array, dimension (LDVL,MM)
!>          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
!>          contain an N-by-N matrix Q (usually the orthogonal matrix Q
!>          of Schur vectors returned by SHSEQR).
!>          On exit, if SIDE = 'L' or 'B', VL contains:
!>          if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
!>          if HOWMNY = 'B', the matrix Q*Y;
!>          if HOWMNY = 'S', the left eigenvectors of T specified by
!>                           SELECT, stored consecutively in the columns
!>                           of VL, in the same order as their
!>                           eigenvalues.
!>          A complex eigenvector corresponding to a complex eigenvalue
!>          is stored in two consecutive columns, the first holding the
!>          real part, and the second the imaginary part.
!>          Not referenced if SIDE = 'R'.
!> 
[in]LDVL
!>          LDVL is INTEGER
!>          The leading dimension of the array VL.  LDVL >= 1, and if
!>          SIDE = 'L' or 'B', LDVL >= N.
!> 
[in,out]VR
!>          VR is REAL array, dimension (LDVR,MM)
!>          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
!>          contain an N-by-N matrix Q (usually the orthogonal matrix Q
!>          of Schur vectors returned by SHSEQR).
!>          On exit, if SIDE = 'R' or 'B', VR contains:
!>          if HOWMNY = 'A', the matrix X of right eigenvectors of T;
!>          if HOWMNY = 'B', the matrix Q*X;
!>          if HOWMNY = 'S', the right eigenvectors of T specified by
!>                           SELECT, stored consecutively in the columns
!>                           of VR, in the same order as their
!>                           eigenvalues.
!>          A complex eigenvector corresponding to a complex eigenvalue
!>          is stored in two consecutive columns, the first holding the
!>          real part and the second the imaginary part.
!>          Not referenced if SIDE = 'L'.
!> 
[in]LDVR
!>          LDVR is INTEGER
!>          The leading dimension of the array VR.  LDVR >= 1, and if
!>          SIDE = 'R' or 'B', LDVR >= N.
!> 
[in]MM
!>          MM is INTEGER
!>          The number of columns in the arrays VL and/or VR. MM >= M.
!> 
[out]M
!>          M is INTEGER
!>          The number of columns in the arrays VL and/or VR actually
!>          used to store the eigenvectors.
!>          If HOWMNY = 'A' or 'B', M is set to N.
!>          Each selected real eigenvector occupies one column and each
!>          selected complex eigenvector occupies two columns.
!> 
[out]WORK
!>          WORK is REAL array, dimension (3*N)
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  The algorithm used in this program is basically backward (forward)
!>  substitution, with scaling to make the the code robust against
!>  possible overflow.
!>
!>  Each eigenvector is normalized so that the element of largest
!>  magnitude has magnitude 1; here the magnitude of a complex number
!>  (x,y) is taken to be |x| + |y|.
!> 

Definition at line 218 of file strevc.f.

221*
222* -- LAPACK computational routine --
223* -- LAPACK is a software package provided by Univ. of Tennessee, --
224* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
225*
226* .. Scalar Arguments ..
227 CHARACTER HOWMNY, SIDE
228 INTEGER INFO, LDT, LDVL, LDVR, M, MM, N
229* ..
230* .. Array Arguments ..
231 LOGICAL SELECT( * )
232 REAL T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
233 $ WORK( * )
234* ..
235*
236* =====================================================================
237*
238* .. Parameters ..
239 REAL ZERO, ONE
240 parameter( zero = 0.0e+0, one = 1.0e+0 )
241* ..
242* .. Local Scalars ..
243 LOGICAL ALLV, BOTHV, LEFTV, OVER, PAIR, RIGHTV, SOMEV
244 INTEGER I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI, N2
245 REAL BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
246 $ SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,
247 $ XNORM
248* ..
249* .. External Functions ..
250 LOGICAL LSAME
251 INTEGER ISAMAX
252 REAL SDOT, SLAMCH
253 EXTERNAL lsame, isamax, sdot, slamch
254* ..
255* .. External Subroutines ..
256 EXTERNAL saxpy, scopy, sgemv, slaln2, sscal,
257 $ xerbla
258* ..
259* .. Intrinsic Functions ..
260 INTRINSIC abs, max, sqrt
261* ..
262* .. Local Arrays ..
263 REAL X( 2, 2 )
264* ..
265* .. Executable Statements ..
266*
267* Decode and test the input parameters
268*
269 bothv = lsame( side, 'B' )
270 rightv = lsame( side, 'R' ) .OR. bothv
271 leftv = lsame( side, 'L' ) .OR. bothv
272*
273 allv = lsame( howmny, 'A' )
274 over = lsame( howmny, 'B' )
275 somev = lsame( howmny, 'S' )
276*
277 info = 0
278 IF( .NOT.rightv .AND. .NOT.leftv ) THEN
279 info = -1
280 ELSE IF( .NOT.allv .AND. .NOT.over .AND. .NOT.somev ) THEN
281 info = -2
282 ELSE IF( n.LT.0 ) THEN
283 info = -4
284 ELSE IF( ldt.LT.max( 1, n ) ) THEN
285 info = -6
286 ELSE IF( ldvl.LT.1 .OR. ( leftv .AND. ldvl.LT.n ) ) THEN
287 info = -8
288 ELSE IF( ldvr.LT.1 .OR. ( rightv .AND. ldvr.LT.n ) ) THEN
289 info = -10
290 ELSE
291*
292* Set M to the number of columns required to store the selected
293* eigenvectors, standardize the array SELECT if necessary, and
294* test MM.
295*
296 IF( somev ) THEN
297 m = 0
298 pair = .false.
299 DO 10 j = 1, n
300 IF( pair ) THEN
301 pair = .false.
302 SELECT( j ) = .false.
303 ELSE
304 IF( j.LT.n ) THEN
305 IF( t( j+1, j ).EQ.zero ) THEN
306 IF( SELECT( j ) )
307 $ m = m + 1
308 ELSE
309 pair = .true.
310 IF( SELECT( j ) .OR. SELECT( j+1 ) ) THEN
311 SELECT( j ) = .true.
312 m = m + 2
313 END IF
314 END IF
315 ELSE
316 IF( SELECT( n ) )
317 $ m = m + 1
318 END IF
319 END IF
320 10 CONTINUE
321 ELSE
322 m = n
323 END IF
324*
325 IF( mm.LT.m ) THEN
326 info = -11
327 END IF
328 END IF
329 IF( info.NE.0 ) THEN
330 CALL xerbla( 'STREVC', -info )
331 RETURN
332 END IF
333*
334* Quick return if possible.
335*
336 IF( n.EQ.0 )
337 $ RETURN
338*
339* Set the constants to control overflow.
340*
341 unfl = slamch( 'Safe minimum' )
342 ovfl = one / unfl
343 ulp = slamch( 'Precision' )
344 smlnum = unfl*( real( n ) / ulp )
345 bignum = ( one-ulp ) / smlnum
346*
347* Compute 1-norm of each column of strictly upper triangular
348* part of T to control overflow in triangular solver.
349*
350 work( 1 ) = zero
351 DO 30 j = 2, n
352 work( j ) = zero
353 DO 20 i = 1, j - 1
354 work( j ) = work( j ) + abs( t( i, j ) )
355 20 CONTINUE
356 30 CONTINUE
357*
358* Index IP is used to specify the real or complex eigenvalue:
359* IP = 0, real eigenvalue,
360* 1, first of conjugate complex pair: (wr,wi)
361* -1, second of conjugate complex pair: (wr,wi)
362*
363 n2 = 2*n
364*
365 IF( rightv ) THEN
366*
367* Compute right eigenvectors.
368*
369 ip = 0
370 is = m
371 DO 140 ki = n, 1, -1
372*
373 IF( ip.EQ.1 )
374 $ GO TO 130
375 IF( ki.EQ.1 )
376 $ GO TO 40
377 IF( t( ki, ki-1 ).EQ.zero )
378 $ GO TO 40
379 ip = -1
380*
381 40 CONTINUE
382 IF( somev ) THEN
383 IF( ip.EQ.0 ) THEN
384 IF( .NOT.SELECT( ki ) )
385 $ GO TO 130
386 ELSE
387 IF( .NOT.SELECT( ki-1 ) )
388 $ GO TO 130
389 END IF
390 END IF
391*
392* Compute the KI-th eigenvalue (WR,WI).
393*
394 wr = t( ki, ki )
395 wi = zero
396 IF( ip.NE.0 )
397 $ wi = sqrt( abs( t( ki, ki-1 ) ) )*
398 $ sqrt( abs( t( ki-1, ki ) ) )
399 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
400*
401 IF( ip.EQ.0 ) THEN
402*
403* Real right eigenvector
404*
405 work( ki+n ) = one
406*
407* Form right-hand side
408*
409 DO 50 k = 1, ki - 1
410 work( k+n ) = -t( k, ki )
411 50 CONTINUE
412*
413* Solve the upper quasi-triangular system:
414* (T(1:KI-1,1:KI-1) - WR)*X = SCALE*WORK.
415*
416 jnxt = ki - 1
417 DO 60 j = ki - 1, 1, -1
418 IF( j.GT.jnxt )
419 $ GO TO 60
420 j1 = j
421 j2 = j
422 jnxt = j - 1
423 IF( j.GT.1 ) THEN
424 IF( t( j, j-1 ).NE.zero ) THEN
425 j1 = j - 1
426 jnxt = j - 2
427 END IF
428 END IF
429*
430 IF( j1.EQ.j2 ) THEN
431*
432* 1-by-1 diagonal block
433*
434 CALL slaln2( .false., 1, 1, smin, one, t( j,
435 $ j ),
436 $ ldt, one, one, work( j+n ), n, wr,
437 $ zero, x, 2, scale, xnorm, ierr )
438*
439* Scale X(1,1) to avoid overflow when updating
440* the right-hand side.
441*
442 IF( xnorm.GT.one ) THEN
443 IF( work( j ).GT.bignum / xnorm ) THEN
444 x( 1, 1 ) = x( 1, 1 ) / xnorm
445 scale = scale / xnorm
446 END IF
447 END IF
448*
449* Scale if necessary
450*
451 IF( scale.NE.one )
452 $ CALL sscal( ki, scale, work( 1+n ), 1 )
453 work( j+n ) = x( 1, 1 )
454*
455* Update right-hand side
456*
457 CALL saxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
458 $ work( 1+n ), 1 )
459*
460 ELSE
461*
462* 2-by-2 diagonal block
463*
464 CALL slaln2( .false., 2, 1, smin, one,
465 $ t( j-1, j-1 ), ldt, one, one,
466 $ work( j-1+n ), n, wr, zero, x, 2,
467 $ scale, xnorm, ierr )
468*
469* Scale X(1,1) and X(2,1) to avoid overflow when
470* updating the right-hand side.
471*
472 IF( xnorm.GT.one ) THEN
473 beta = max( work( j-1 ), work( j ) )
474 IF( beta.GT.bignum / xnorm ) THEN
475 x( 1, 1 ) = x( 1, 1 ) / xnorm
476 x( 2, 1 ) = x( 2, 1 ) / xnorm
477 scale = scale / xnorm
478 END IF
479 END IF
480*
481* Scale if necessary
482*
483 IF( scale.NE.one )
484 $ CALL sscal( ki, scale, work( 1+n ), 1 )
485 work( j-1+n ) = x( 1, 1 )
486 work( j+n ) = x( 2, 1 )
487*
488* Update right-hand side
489*
490 CALL saxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
491 $ work( 1+n ), 1 )
492 CALL saxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
493 $ work( 1+n ), 1 )
494 END IF
495 60 CONTINUE
496*
497* Copy the vector x or Q*x to VR and normalize.
498*
499 IF( .NOT.over ) THEN
500 CALL scopy( ki, work( 1+n ), 1, vr( 1, is ), 1 )
501*
502 ii = isamax( ki, vr( 1, is ), 1 )
503 remax = one / abs( vr( ii, is ) )
504 CALL sscal( ki, remax, vr( 1, is ), 1 )
505*
506 DO 70 k = ki + 1, n
507 vr( k, is ) = zero
508 70 CONTINUE
509 ELSE
510 IF( ki.GT.1 )
511 $ CALL sgemv( 'N', n, ki-1, one, vr, ldvr,
512 $ work( 1+n ), 1, work( ki+n ),
513 $ vr( 1, ki ), 1 )
514*
515 ii = isamax( n, vr( 1, ki ), 1 )
516 remax = one / abs( vr( ii, ki ) )
517 CALL sscal( n, remax, vr( 1, ki ), 1 )
518 END IF
519*
520 ELSE
521*
522* Complex right eigenvector.
523*
524* Initial solve
525* [ (T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I* WI)]*X = 0.
526* [ (T(KI,KI-1) T(KI,KI) ) ]
527*
528 IF( abs( t( ki-1, ki ) ).GE.abs( t( ki, ki-1 ) ) ) THEN
529 work( ki-1+n ) = one
530 work( ki+n2 ) = wi / t( ki-1, ki )
531 ELSE
532 work( ki-1+n ) = -wi / t( ki, ki-1 )
533 work( ki+n2 ) = one
534 END IF
535 work( ki+n ) = zero
536 work( ki-1+n2 ) = zero
537*
538* Form right-hand side
539*
540 DO 80 k = 1, ki - 2
541 work( k+n ) = -work( ki-1+n )*t( k, ki-1 )
542 work( k+n2 ) = -work( ki+n2 )*t( k, ki )
543 80 CONTINUE
544*
545* Solve upper quasi-triangular system:
546* (T(1:KI-2,1:KI-2) - (WR+i*WI))*X = SCALE*(WORK+i*WORK2)
547*
548 jnxt = ki - 2
549 DO 90 j = ki - 2, 1, -1
550 IF( j.GT.jnxt )
551 $ GO TO 90
552 j1 = j
553 j2 = j
554 jnxt = j - 1
555 IF( j.GT.1 ) THEN
556 IF( t( j, j-1 ).NE.zero ) THEN
557 j1 = j - 1
558 jnxt = j - 2
559 END IF
560 END IF
561*
562 IF( j1.EQ.j2 ) THEN
563*
564* 1-by-1 diagonal block
565*
566 CALL slaln2( .false., 1, 2, smin, one, t( j,
567 $ j ),
568 $ ldt, one, one, work( j+n ), n, wr, wi,
569 $ x, 2, scale, xnorm, ierr )
570*
571* Scale X(1,1) and X(1,2) to avoid overflow when
572* updating the right-hand side.
573*
574 IF( xnorm.GT.one ) THEN
575 IF( work( j ).GT.bignum / xnorm ) THEN
576 x( 1, 1 ) = x( 1, 1 ) / xnorm
577 x( 1, 2 ) = x( 1, 2 ) / xnorm
578 scale = scale / xnorm
579 END IF
580 END IF
581*
582* Scale if necessary
583*
584 IF( scale.NE.one ) THEN
585 CALL sscal( ki, scale, work( 1+n ), 1 )
586 CALL sscal( ki, scale, work( 1+n2 ), 1 )
587 END IF
588 work( j+n ) = x( 1, 1 )
589 work( j+n2 ) = x( 1, 2 )
590*
591* Update the right-hand side
592*
593 CALL saxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
594 $ work( 1+n ), 1 )
595 CALL saxpy( j-1, -x( 1, 2 ), t( 1, j ), 1,
596 $ work( 1+n2 ), 1 )
597*
598 ELSE
599*
600* 2-by-2 diagonal block
601*
602 CALL slaln2( .false., 2, 2, smin, one,
603 $ t( j-1, j-1 ), ldt, one, one,
604 $ work( j-1+n ), n, wr, wi, x, 2, scale,
605 $ xnorm, ierr )
606*
607* Scale X to avoid overflow when updating
608* the right-hand side.
609*
610 IF( xnorm.GT.one ) THEN
611 beta = max( work( j-1 ), work( j ) )
612 IF( beta.GT.bignum / xnorm ) THEN
613 rec = one / xnorm
614 x( 1, 1 ) = x( 1, 1 )*rec
615 x( 1, 2 ) = x( 1, 2 )*rec
616 x( 2, 1 ) = x( 2, 1 )*rec
617 x( 2, 2 ) = x( 2, 2 )*rec
618 scale = scale*rec
619 END IF
620 END IF
621*
622* Scale if necessary
623*
624 IF( scale.NE.one ) THEN
625 CALL sscal( ki, scale, work( 1+n ), 1 )
626 CALL sscal( ki, scale, work( 1+n2 ), 1 )
627 END IF
628 work( j-1+n ) = x( 1, 1 )
629 work( j+n ) = x( 2, 1 )
630 work( j-1+n2 ) = x( 1, 2 )
631 work( j+n2 ) = x( 2, 2 )
632*
633* Update the right-hand side
634*
635 CALL saxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
636 $ work( 1+n ), 1 )
637 CALL saxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
638 $ work( 1+n ), 1 )
639 CALL saxpy( j-2, -x( 1, 2 ), t( 1, j-1 ), 1,
640 $ work( 1+n2 ), 1 )
641 CALL saxpy( j-2, -x( 2, 2 ), t( 1, j ), 1,
642 $ work( 1+n2 ), 1 )
643 END IF
644 90 CONTINUE
645*
646* Copy the vector x or Q*x to VR and normalize.
647*
648 IF( .NOT.over ) THEN
649 CALL scopy( ki, work( 1+n ), 1, vr( 1, is-1 ), 1 )
650 CALL scopy( ki, work( 1+n2 ), 1, vr( 1, is ), 1 )
651*
652 emax = zero
653 DO 100 k = 1, ki
654 emax = max( emax, abs( vr( k, is-1 ) )+
655 $ abs( vr( k, is ) ) )
656 100 CONTINUE
657*
658 remax = one / emax
659 CALL sscal( ki, remax, vr( 1, is-1 ), 1 )
660 CALL sscal( ki, remax, vr( 1, is ), 1 )
661*
662 DO 110 k = ki + 1, n
663 vr( k, is-1 ) = zero
664 vr( k, is ) = zero
665 110 CONTINUE
666*
667 ELSE
668*
669 IF( ki.GT.2 ) THEN
670 CALL sgemv( 'N', n, ki-2, one, vr, ldvr,
671 $ work( 1+n ), 1, work( ki-1+n ),
672 $ vr( 1, ki-1 ), 1 )
673 CALL sgemv( 'N', n, ki-2, one, vr, ldvr,
674 $ work( 1+n2 ), 1, work( ki+n2 ),
675 $ vr( 1, ki ), 1 )
676 ELSE
677 CALL sscal( n, work( ki-1+n ), vr( 1, ki-1 ),
678 $ 1 )
679 CALL sscal( n, work( ki+n2 ), vr( 1, ki ), 1 )
680 END IF
681*
682 emax = zero
683 DO 120 k = 1, n
684 emax = max( emax, abs( vr( k, ki-1 ) )+
685 $ abs( vr( k, ki ) ) )
686 120 CONTINUE
687 remax = one / emax
688 CALL sscal( n, remax, vr( 1, ki-1 ), 1 )
689 CALL sscal( n, remax, vr( 1, ki ), 1 )
690 END IF
691 END IF
692*
693 is = is - 1
694 IF( ip.NE.0 )
695 $ is = is - 1
696 130 CONTINUE
697 IF( ip.EQ.1 )
698 $ ip = 0
699 IF( ip.EQ.-1 )
700 $ ip = 1
701 140 CONTINUE
702 END IF
703*
704 IF( leftv ) THEN
705*
706* Compute left eigenvectors.
707*
708 ip = 0
709 is = 1
710 DO 260 ki = 1, n
711*
712 IF( ip.EQ.-1 )
713 $ GO TO 250
714 IF( ki.EQ.n )
715 $ GO TO 150
716 IF( t( ki+1, ki ).EQ.zero )
717 $ GO TO 150
718 ip = 1
719*
720 150 CONTINUE
721 IF( somev ) THEN
722 IF( .NOT.SELECT( ki ) )
723 $ GO TO 250
724 END IF
725*
726* Compute the KI-th eigenvalue (WR,WI).
727*
728 wr = t( ki, ki )
729 wi = zero
730 IF( ip.NE.0 )
731 $ wi = sqrt( abs( t( ki, ki+1 ) ) )*
732 $ sqrt( abs( t( ki+1, ki ) ) )
733 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
734*
735 IF( ip.EQ.0 ) THEN
736*
737* Real left eigenvector.
738*
739 work( ki+n ) = one
740*
741* Form right-hand side
742*
743 DO 160 k = ki + 1, n
744 work( k+n ) = -t( ki, k )
745 160 CONTINUE
746*
747* Solve the quasi-triangular system:
748* (T(KI+1:N,KI+1:N) - WR)**T*X = SCALE*WORK
749*
750 vmax = one
751 vcrit = bignum
752*
753 jnxt = ki + 1
754 DO 170 j = ki + 1, n
755 IF( j.LT.jnxt )
756 $ GO TO 170
757 j1 = j
758 j2 = j
759 jnxt = j + 1
760 IF( j.LT.n ) THEN
761 IF( t( j+1, j ).NE.zero ) THEN
762 j2 = j + 1
763 jnxt = j + 2
764 END IF
765 END IF
766*
767 IF( j1.EQ.j2 ) THEN
768*
769* 1-by-1 diagonal block
770*
771* Scale if necessary to avoid overflow when forming
772* the right-hand side.
773*
774 IF( work( j ).GT.vcrit ) THEN
775 rec = one / vmax
776 CALL sscal( n-ki+1, rec, work( ki+n ), 1 )
777 vmax = one
778 vcrit = bignum
779 END IF
780*
781 work( j+n ) = work( j+n ) -
782 $ sdot( j-ki-1, t( ki+1, j ), 1,
783 $ work( ki+1+n ), 1 )
784*
785* Solve (T(J,J)-WR)**T*X = WORK
786*
787 CALL slaln2( .false., 1, 1, smin, one, t( j,
788 $ 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 sscal( 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 sscal( 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 $ sdot( 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 $ sdot( 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 slaln2( .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 sscal( 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 scopy( n-ki+1, work( ki+n ), 1, vl( ki, is ),
849 $ 1 )
850*
851 ii = isamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
852 remax = one / abs( vl( ii, is ) )
853 CALL sscal( n-ki+1, remax, vl( ki, is ), 1 )
854*
855 DO 180 k = 1, ki - 1
856 vl( k, is ) = zero
857 180 CONTINUE
858*
859 ELSE
860*
861 IF( ki.LT.n )
862 $ CALL sgemv( 'N', n, n-ki, one, vl( 1, ki+1 ),
863 $ ldvl,
864 $ work( ki+1+n ), 1, work( ki+n ),
865 $ vl( 1, ki ), 1 )
866*
867 ii = isamax( n, vl( 1, ki ), 1 )
868 remax = one / abs( vl( ii, ki ) )
869 CALL sscal( n, remax, vl( 1, ki ), 1 )
870*
871 END IF
872*
873 ELSE
874*
875* Complex left eigenvector.
876*
877* Initial solve:
878* ((T(KI,KI) T(KI,KI+1) )**T - (WR - I* WI))*X = 0.
879* ((T(KI+1,KI) T(KI+1,KI+1)) )
880*
881 IF( abs( t( ki, ki+1 ) ).GE.abs( t( ki+1, ki ) ) ) THEN
882 work( ki+n ) = wi / t( ki, ki+1 )
883 work( ki+1+n2 ) = one
884 ELSE
885 work( ki+n ) = one
886 work( ki+1+n2 ) = -wi / t( ki+1, ki )
887 END IF
888 work( ki+1+n ) = zero
889 work( ki+n2 ) = zero
890*
891* Form right-hand side
892*
893 DO 190 k = ki + 2, n
894 work( k+n ) = -work( ki+n )*t( ki, k )
895 work( k+n2 ) = -work( ki+1+n2 )*t( ki+1, k )
896 190 CONTINUE
897*
898* Solve complex quasi-triangular system:
899* ( T(KI+2,N:KI+2,N) - (WR-i*WI) )*X = WORK1+i*WORK2
900*
901 vmax = one
902 vcrit = bignum
903*
904 jnxt = ki + 2
905 DO 200 j = ki + 2, n
906 IF( j.LT.jnxt )
907 $ GO TO 200
908 j1 = j
909 j2 = j
910 jnxt = j + 1
911 IF( j.LT.n ) THEN
912 IF( t( j+1, j ).NE.zero ) THEN
913 j2 = j + 1
914 jnxt = j + 2
915 END IF
916 END IF
917*
918 IF( j1.EQ.j2 ) THEN
919*
920* 1-by-1 diagonal block
921*
922* Scale if necessary to avoid overflow when
923* forming the right-hand side elements.
924*
925 IF( work( j ).GT.vcrit ) THEN
926 rec = one / vmax
927 CALL sscal( n-ki+1, rec, work( ki+n ), 1 )
928 CALL sscal( n-ki+1, rec, work( ki+n2 ), 1 )
929 vmax = one
930 vcrit = bignum
931 END IF
932*
933 work( j+n ) = work( j+n ) -
934 $ sdot( j-ki-2, t( ki+2, j ), 1,
935 $ work( ki+2+n ), 1 )
936 work( j+n2 ) = work( j+n2 ) -
937 $ sdot( j-ki-2, t( ki+2, j ), 1,
938 $ work( ki+2+n2 ), 1 )
939*
940* Solve (T(J,J)-(WR-i*WI))*(X11+i*X12)= WK+I*WK2
941*
942 CALL slaln2( .false., 1, 2, smin, one, t( j,
943 $ j ),
944 $ ldt, one, one, work( j+n ), n, wr,
945 $ -wi, x, 2, scale, xnorm, ierr )
946*
947* Scale if necessary
948*
949 IF( scale.NE.one ) THEN
950 CALL sscal( n-ki+1, scale, work( ki+n ), 1 )
951 CALL sscal( n-ki+1, scale, work( ki+n2 ), 1 )
952 END IF
953 work( j+n ) = x( 1, 1 )
954 work( j+n2 ) = x( 1, 2 )
955 vmax = max( abs( work( j+n ) ),
956 $ abs( work( j+n2 ) ), vmax )
957 vcrit = bignum / vmax
958*
959 ELSE
960*
961* 2-by-2 diagonal block
962*
963* Scale if necessary to avoid overflow when forming
964* the right-hand side elements.
965*
966 beta = max( work( j ), work( j+1 ) )
967 IF( beta.GT.vcrit ) THEN
968 rec = one / vmax
969 CALL sscal( n-ki+1, rec, work( ki+n ), 1 )
970 CALL sscal( n-ki+1, rec, work( ki+n2 ), 1 )
971 vmax = one
972 vcrit = bignum
973 END IF
974*
975 work( j+n ) = work( j+n ) -
976 $ sdot( j-ki-2, t( ki+2, j ), 1,
977 $ work( ki+2+n ), 1 )
978*
979 work( j+n2 ) = work( j+n2 ) -
980 $ sdot( j-ki-2, t( ki+2, j ), 1,
981 $ work( ki+2+n2 ), 1 )
982*
983 work( j+1+n ) = work( j+1+n ) -
984 $ sdot( j-ki-2, t( ki+2, j+1 ), 1,
985 $ work( ki+2+n ), 1 )
986*
987 work( j+1+n2 ) = work( j+1+n2 ) -
988 $ sdot( j-ki-2, t( ki+2, j+1 ),
989 $ 1,
990 $ work( ki+2+n2 ), 1 )
991*
992* Solve 2-by-2 complex linear equation
993* ([T(j,j) T(j,j+1) ]**T-(wr-i*wi)*I)*X = SCALE*B
994* ([T(j+1,j) T(j+1,j+1)] )
995*
996 CALL slaln2( .true., 2, 2, smin, one, t( j, j ),
997 $ ldt, one, one, work( j+n ), n, wr,
998 $ -wi, x, 2, scale, xnorm, ierr )
999*
1000* Scale if necessary
1001*
1002 IF( scale.NE.one ) THEN
1003 CALL sscal( n-ki+1, scale, work( ki+n ), 1 )
1004 CALL sscal( n-ki+1, scale, work( ki+n2 ), 1 )
1005 END IF
1006 work( j+n ) = x( 1, 1 )
1007 work( j+n2 ) = x( 1, 2 )
1008 work( j+1+n ) = x( 2, 1 )
1009 work( j+1+n2 ) = x( 2, 2 )
1010 vmax = max( abs( x( 1, 1 ) ), abs( x( 1, 2 ) ),
1011 $ abs( x( 2, 1 ) ), abs( x( 2, 2 ) ), vmax )
1012 vcrit = bignum / vmax
1013*
1014 END IF
1015 200 CONTINUE
1016*
1017* Copy the vector x or Q*x to VL and normalize.
1018*
1019 IF( .NOT.over ) THEN
1020 CALL scopy( n-ki+1, work( ki+n ), 1, vl( ki, is ),
1021 $ 1 )
1022 CALL scopy( n-ki+1, work( ki+n2 ), 1, vl( ki,
1023 $ is+1 ),
1024 $ 1 )
1025*
1026 emax = zero
1027 DO 220 k = ki, n
1028 emax = max( emax, abs( vl( k, is ) )+
1029 $ abs( vl( k, is+1 ) ) )
1030 220 CONTINUE
1031 remax = one / emax
1032 CALL sscal( n-ki+1, remax, vl( ki, is ), 1 )
1033 CALL sscal( n-ki+1, remax, vl( ki, is+1 ), 1 )
1034*
1035 DO 230 k = 1, ki - 1
1036 vl( k, is ) = zero
1037 vl( k, is+1 ) = zero
1038 230 CONTINUE
1039 ELSE
1040 IF( ki.LT.n-1 ) THEN
1041 CALL sgemv( 'N', n, n-ki-1, one, vl( 1, ki+2 ),
1042 $ ldvl, work( ki+2+n ), 1, work( ki+n ),
1043 $ vl( 1, ki ), 1 )
1044 CALL sgemv( 'N', n, n-ki-1, one, vl( 1, ki+2 ),
1045 $ ldvl, work( ki+2+n2 ), 1,
1046 $ work( ki+1+n2 ), vl( 1, ki+1 ), 1 )
1047 ELSE
1048 CALL sscal( n, work( ki+n ), vl( 1, ki ), 1 )
1049 CALL sscal( n, work( ki+1+n2 ), vl( 1, ki+1 ),
1050 $ 1 )
1051 END IF
1052*
1053 emax = zero
1054 DO 240 k = 1, n
1055 emax = max( emax, abs( vl( k, ki ) )+
1056 $ abs( vl( k, ki+1 ) ) )
1057 240 CONTINUE
1058 remax = one / emax
1059 CALL sscal( n, remax, vl( 1, ki ), 1 )
1060 CALL sscal( n, remax, vl( 1, ki+1 ), 1 )
1061*
1062 END IF
1063*
1064 END IF
1065*
1066 is = is + 1
1067 IF( ip.NE.0 )
1068 $ is = is + 1
1069 250 CONTINUE
1070 IF( ip.EQ.-1 )
1071 $ ip = 0
1072 IF( ip.EQ.1 )
1073 $ ip = -1
1074*
1075 260 CONTINUE
1076*
1077 END IF
1078*
1079 RETURN
1080*
1081* End of STREVC
1082*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine saxpy(n, sa, sx, incx, sy, incy)
SAXPY
Definition saxpy.f:89
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
Definition scopy.f:82
real function sdot(n, sx, incx, sy, incy)
SDOT
Definition sdot.f:82
subroutine sgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
SGEMV
Definition sgemv.f:158
integer function isamax(n, sx, incx)
ISAMAX
Definition isamax.f:71
subroutine slaln2(ltrans, na, nw, smin, ca, a, lda, d1, d2, b, ldb, wr, wi, x, ldx, scale, xnorm, info)
SLALN2 solves a 1-by-1 or 2-by-2 linear system of equations of the specified form.
Definition slaln2.f:216
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine sscal(n, sa, sx, incx)
SSCAL
Definition sscal.f:79
Here is the call graph for this function:
Here is the caller graph for this function: