218 SUBROUTINE strevc( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
220 $ LDVR, MM, M, WORK, INFO )
227 CHARACTER HOWMNY, SIDE
228 INTEGER INFO, LDT, LDVL, LDVR, M, MM, N
232 REAL T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
240 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
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,
253 EXTERNAL lsame, isamax, sdot, slamch
260 INTRINSIC abs, max, sqrt
269 bothv = lsame( side,
'B' )
270 rightv = lsame( side,
'R' ) .OR. bothv
271 leftv = lsame( side,
'L' ) .OR. bothv
273 allv = lsame( howmny,
'A' )
274 over = lsame( howmny,
'B' )
275 somev = lsame( howmny,
'S' )
278 IF( .NOT.rightv .AND. .NOT.leftv )
THEN
280 ELSE IF( .NOT.allv .AND. .NOT.over .AND. .NOT.somev )
THEN
282 ELSE IF( n.LT.0 )
THEN
284 ELSE IF( ldt.LT.max( 1, n ) )
THEN
286 ELSE IF( ldvl.LT.1 .OR. ( leftv .AND. ldvl.LT.n ) )
THEN
288 ELSE IF( ldvr.LT.1 .OR. ( rightv .AND. ldvr.LT.n ) )
THEN
302 SELECT( j ) = .false.
305 IF( t( j+1, j ).EQ.zero )
THEN
310 IF(
SELECT( j ) .OR.
SELECT( j+1 ) )
THEN
330 CALL xerbla(
'STREVC', -info )
341 unfl = slamch(
'Safe minimum' )
343 ulp = slamch(
'Precision' )
344 smlnum = unfl*( real( n ) / ulp )
345 bignum = ( one-ulp ) / smlnum
354 work( j ) = work( j ) + abs( t( i, j ) )
377 IF( t( ki, ki-1 ).EQ.zero )
384 IF( .NOT.
SELECT( ki ) )
387 IF( .NOT.
SELECT( ki-1 ) )
397 $ wi = sqrt( abs( t( ki, ki-1 ) ) )*
398 $ sqrt( abs( t( ki-1, ki ) ) )
399 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
410 work( k+n ) = -t( k, ki )
417 DO 60 j = ki - 1, 1, -1
424 IF( t( j, j-1 ).NE.zero )
THEN
434 CALL slaln2( .false., 1, 1, smin, one, t( j,
436 $ ldt, one, one, work( j+n ), n, wr,
437 $ zero, x, 2, scale, xnorm, ierr )
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
452 $
CALL sscal( ki, scale, work( 1+n ), 1 )
453 work( j+n ) = x( 1, 1 )
457 CALL saxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
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 )
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
484 $
CALL sscal( ki, scale, work( 1+n ), 1 )
485 work( j-1+n ) = x( 1, 1 )
486 work( j+n ) = x( 2, 1 )
490 CALL saxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
492 CALL saxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
500 CALL scopy( ki, work( 1+n ), 1, vr( 1, is ), 1 )
502 ii = isamax( ki, vr( 1, is ), 1 )
503 remax = one / abs( vr( ii, is ) )
504 CALL sscal( ki, remax, vr( 1, is ), 1 )
511 $
CALL sgemv(
'N', n, ki-1, one, vr, ldvr,
512 $ work( 1+n ), 1, work( ki+n ),
515 ii = isamax( n, vr( 1, ki ), 1 )
516 remax = one / abs( vr( ii, ki ) )
517 CALL sscal( n, remax, vr( 1, ki ), 1 )
528 IF( abs( t( ki-1, ki ) ).GE.abs( t( ki, ki-1 ) ) )
THEN
530 work( ki+n2 ) = wi / t( ki-1, ki )
532 work( ki-1+n ) = -wi / t( ki, ki-1 )
536 work( ki-1+n2 ) = zero
541 work( k+n ) = -work( ki-1+n )*t( k, ki-1 )
542 work( k+n2 ) = -work( ki+n2 )*t( k, ki )
549 DO 90 j = ki - 2, 1, -1
556 IF( t( j, j-1 ).NE.zero )
THEN
566 CALL slaln2( .false., 1, 2, smin, one, t( j,
568 $ ldt, one, one, work( j+n ), n, wr, wi,
569 $ x, 2, scale, xnorm, ierr )
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
584 IF( scale.NE.one )
THEN
585 CALL sscal( ki, scale, work( 1+n ), 1 )
586 CALL sscal( ki, scale, work( 1+n2 ), 1 )
588 work( j+n ) = x( 1, 1 )
589 work( j+n2 ) = x( 1, 2 )
593 CALL saxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
595 CALL saxpy( j-1, -x( 1, 2 ), t( 1, j ), 1,
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,
610 IF( xnorm.GT.one )
THEN
611 beta = max( work( j-1 ), work( j ) )
612 IF( beta.GT.bignum / xnorm )
THEN
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
624 IF( scale.NE.one )
THEN
625 CALL sscal( ki, scale, work( 1+n ), 1 )
626 CALL sscal( ki, scale, work( 1+n2 ), 1 )
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 )
635 CALL saxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
637 CALL saxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
639 CALL saxpy( j-2, -x( 1, 2 ), t( 1, j-1 ), 1,
641 CALL saxpy( j-2, -x( 2, 2 ), t( 1, j ), 1,
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 )
654 emax = max( emax, abs( vr( k, is-1 ) )+
655 $ abs( vr( k, is ) ) )
659 CALL sscal( ki, remax, vr( 1, is-1 ), 1 )
660 CALL sscal( ki, remax, vr( 1, is ), 1 )
670 CALL sgemv(
'N', n, ki-2, one, vr, ldvr,
671 $ work( 1+n ), 1, work( ki-1+n ),
673 CALL sgemv(
'N', n, ki-2, one, vr, ldvr,
674 $ work( 1+n2 ), 1, work( ki+n2 ),
677 CALL sscal( n, work( ki-1+n ), vr( 1, ki-1 ),
679 CALL sscal( n, work( ki+n2 ), vr( 1, ki ), 1 )
684 emax = max( emax, abs( vr( k, ki-1 ) )+
685 $ abs( vr( k, ki ) ) )
688 CALL sscal( n, remax, vr( 1, ki-1 ), 1 )
689 CALL sscal( n, remax, vr( 1, ki ), 1 )
716 IF( t( ki+1, ki ).EQ.zero )
722 IF( .NOT.
SELECT( ki ) )
731 $ wi = sqrt( abs( t( ki, ki+1 ) ) )*
732 $ sqrt( abs( t( ki+1, ki ) ) )
733 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
744 work( k+n ) = -t( ki, k )
761 IF( t( j+1, j ).NE.zero )
THEN
774 IF( work( j ).GT.vcrit )
THEN
776 CALL sscal( n-ki+1, rec, work( ki+n ), 1 )
781 work( j+n ) = work( j+n ) -
782 $ sdot( j-ki-1, t( ki+1, j ), 1,
783 $ work( ki+1+n ), 1 )
787 CALL slaln2( .false., 1, 1, smin, one, t( j,
789 $ ldt, one, one, work( j+n ), n, wr,
790 $ zero, x, 2, scale, xnorm, ierr )
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
807 beta = max( work( j ), work( j+1 ) )
808 IF( beta.GT.vcrit )
THEN
810 CALL sscal( n-ki+1, rec, work( ki+n ), 1 )
815 work( j+n ) = work( j+n ) -
816 $ sdot( j-ki-1, t( ki+1, j ), 1,
817 $ work( ki+1+n ), 1 )
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 )
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 )
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 )
838 vmax = max( abs( work( j+n ) ),
839 $ abs( work( j+1+n ) ), vmax )
840 vcrit = bignum / vmax
848 CALL scopy( n-ki+1, work( ki+n ), 1, vl( ki, is ),
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 )
862 $
CALL sgemv(
'N', n, n-ki, one, vl( 1, ki+1 ),
864 $ work( ki+1+n ), 1, work( ki+n ),
867 ii = isamax( n, vl( 1, ki ), 1 )
868 remax = one / abs( vl( ii, ki ) )
869 CALL sscal( n, remax, vl( 1, ki ), 1 )
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
886 work( ki+1+n2 ) = -wi / t( ki+1, ki )
888 work( ki+1+n ) = zero
894 work( k+n ) = -work( ki+n )*t( ki, k )
895 work( k+n2 ) = -work( ki+1+n2 )*t( ki+1, k )
912 IF( t( j+1, j ).NE.zero )
THEN
925 IF( work( j ).GT.vcrit )
THEN
927 CALL sscal( n-ki+1, rec, work( ki+n ), 1 )
928 CALL sscal( n-ki+1, rec, work( ki+n2 ), 1 )
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 )
942 CALL slaln2( .false., 1, 2, smin, one, t( j,
944 $ ldt, one, one, work( j+n ), n, wr,
945 $ -wi, x, 2, scale, xnorm, ierr )
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 )
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
966 beta = max( work( j ), work( j+1 ) )
967 IF( beta.GT.vcrit )
THEN
969 CALL sscal( n-ki+1, rec, work( ki+n ), 1 )
970 CALL sscal( n-ki+1, rec, work( ki+n2 ), 1 )
975 work( j+n ) = work( j+n ) -
976 $ sdot( j-ki-2, t( ki+2, j ), 1,
977 $ work( ki+2+n ), 1 )
979 work( j+n2 ) = work( j+n2 ) -
980 $ sdot( j-ki-2, t( ki+2, j ), 1,
981 $ work( ki+2+n2 ), 1 )
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 )
987 work( j+1+n2 ) = work( j+1+n2 ) -
988 $ sdot( j-ki-2, t( ki+2, j+1 ),
990 $ work( ki+2+n2 ), 1 )
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 )
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 )
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
1019 IF( .NOT.over )
THEN
1020 CALL scopy( n-ki+1, work( ki+n ), 1, vl( ki, is ),
1022 CALL scopy( n-ki+1, work( ki+n2 ), 1, vl( ki,
1028 emax = max( emax, abs( vl( k, is ) )+
1029 $ abs( vl( k, is+1 ) ) )
1032 CALL sscal( n-ki+1, remax, vl( ki, is ), 1 )
1033 CALL sscal( n-ki+1, remax, vl( ki, is+1 ), 1 )
1035 DO 230 k = 1, ki - 1
1037 vl( k, is+1 ) = zero
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 ),
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 )
1048 CALL sscal( n, work( ki+n ), vl( 1, ki ), 1 )
1049 CALL sscal( n, work( ki+1+n2 ), vl( 1, ki+1 ),
1055 emax = max( emax, abs( vl( k, ki ) )+
1056 $ abs( vl( k, ki+1 ) ) )
1059 CALL sscal( n, remax, vl( 1, ki ), 1 )
1060 CALL sscal( n, remax, vl( 1, ki+1 ), 1 )