235 SUBROUTINE strevc3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
236 $ VR, LDVR, MM, M, WORK, LWORK, INFO )
244 CHARACTER HOWMNY, SIDE
245 INTEGER INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
249 REAL T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
257 parameter( zero = 0.0e+0, one = 1.0e+0 )
259 parameter( nbmin = 8, nbmax = 128 )
262 LOGICAL ALLV, BOTHV, LEFTV, LQUERY, OVER, PAIR,
264 INTEGER I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI,
265 $ iv, maxwrk, nb, ki2
266 REAL BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
267 $ smin, smlnum, ulp, unfl, vcrit, vmax, wi, wr,
272 INTEGER ISAMAX, ILAENV
274 EXTERNAL lsame, isamax, ilaenv, sdot, slamch
281 INTRINSIC abs, max, sqrt
285 INTEGER ISCOMPLEX( NBMAX )
291 bothv = lsame( side,
'B' )
292 rightv = lsame( side,
'R' ) .OR. bothv
293 leftv = lsame( side,
'L' ) .OR. bothv
295 allv = lsame( howmny,
'A' )
296 over = lsame( howmny,
'B' )
297 somev = lsame( howmny,
'S' )
300 nb = ilaenv( 1,
'STREVC', side // howmny, n, -1, -1, -1 )
301 maxwrk = max( 1, n + 2*n*nb )
303 lquery = ( lwork.EQ.-1 )
304 IF( .NOT.rightv .AND. .NOT.leftv )
THEN
306 ELSE IF( .NOT.allv .AND. .NOT.over .AND. .NOT.somev )
THEN
308 ELSE IF( n.LT.0 )
THEN
310 ELSE IF( ldt.LT.max( 1, n ) )
THEN
312 ELSE IF( ldvl.LT.1 .OR. ( leftv .AND. ldvl.LT.n ) )
THEN
314 ELSE IF( ldvr.LT.1 .OR. ( rightv .AND. ldvr.LT.n ) )
THEN
316 ELSE IF( lwork.LT.max( 1, 3*n ) .AND. .NOT.lquery )
THEN
330 SELECT( j ) = .false.
333 IF( t( j+1, j ).EQ.zero )
THEN
338 IF(
SELECT( j ) .OR.
SELECT( j+1 ) )
THEN
358 CALL xerbla(
'STREVC3', -info )
360 ELSE IF( lquery )
THEN
372 IF( over .AND. lwork .GE. n + 2*n*nbmin )
THEN
373 nb = (lwork - n) / (2*n)
374 nb = min( nb, nbmax )
375 CALL slaset(
'F', n, 1+2*nb, zero, zero, work, n )
382 unfl = slamch(
'Safe minimum' )
384 ulp = slamch(
'Precision' )
385 smlnum = unfl*( n / ulp )
386 bignum = ( one-ulp ) / smlnum
395 work( j ) = work( j ) + abs( t( i, j ) )
428 ELSE IF( ki.EQ.1 )
THEN
431 ELSE IF( t( ki, ki-1 ).EQ.zero )
THEN
441 IF( .NOT.
SELECT( ki ) )
444 IF( .NOT.
SELECT( ki-1 ) )
454 $ wi = sqrt( abs( t( ki, ki-1 ) ) )*
455 $ sqrt( abs( t( ki-1, ki ) ) )
456 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
463 work( ki + iv*n ) = one
468 work( k + iv*n ) = -t( k, ki )
475 DO 60 j = ki - 1, 1, -1
482 IF( t( j, j-1 ).NE.zero )
THEN
492 CALL slaln2( .false., 1, 1, smin, one, t( j, j ),
493 $ ldt, one, one, work( j+iv*n ), n, wr,
494 $ zero, x, 2, scale, xnorm, ierr )
499 IF( xnorm.GT.one )
THEN
500 IF( work( j ).GT.bignum / xnorm )
THEN
501 x( 1, 1 ) = x( 1, 1 ) / xnorm
502 scale = scale / xnorm
509 $
CALL sscal( ki, scale, work( 1+iv*n ), 1 )
510 work( j+iv*n ) = x( 1, 1 )
514 CALL saxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
515 $ work( 1+iv*n ), 1 )
521 CALL slaln2( .false., 2, 1, smin, one,
522 $ t( j-1, j-1 ), ldt, one, one,
523 $ work( j-1+iv*n ), n, wr, zero, x, 2,
524 $ scale, xnorm, ierr )
529 IF( xnorm.GT.one )
THEN
530 beta = max( work( j-1 ), work( j ) )
531 IF( beta.GT.bignum / xnorm )
THEN
532 x( 1, 1 ) = x( 1, 1 ) / xnorm
533 x( 2, 1 ) = x( 2, 1 ) / xnorm
534 scale = scale / xnorm
541 $
CALL sscal( ki, scale, work( 1+iv*n ), 1 )
542 work( j-1+iv*n ) = x( 1, 1 )
543 work( j +iv*n ) = x( 2, 1 )
547 CALL saxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
548 $ work( 1+iv*n ), 1 )
549 CALL saxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
550 $ work( 1+iv*n ), 1 )
559 CALL scopy( ki, work( 1 + iv*n ), 1, vr( 1, is ), 1 )
561 ii = isamax( ki, vr( 1, is ), 1 )
562 remax = one / abs( vr( ii, is ) )
563 CALL sscal( ki, remax, vr( 1, is ), 1 )
569 ELSE IF( nb.EQ.1 )
THEN
573 $
CALL sgemv(
'N', n, ki-1, one, vr, ldvr,
574 $ work( 1 + iv*n ), 1, work( ki + iv*n ),
577 ii = isamax( n, vr( 1, ki ), 1 )
578 remax = one / abs( vr( ii, ki ) )
579 CALL sscal( n, remax, vr( 1, ki ), 1 )
586 work( k + iv*n ) = zero
600 IF( abs( t( ki-1, ki ) ).GE.abs( t( ki, ki-1 ) ) )
THEN
601 work( ki-1 + (iv-1)*n ) = one
602 work( ki + (iv )*n ) = wi / t( ki-1, ki )
604 work( ki-1 + (iv-1)*n ) = -wi / t( ki, ki-1 )
605 work( ki + (iv )*n ) = one
607 work( ki + (iv-1)*n ) = zero
608 work( ki-1 + (iv )*n ) = zero
613 work( k+(iv-1)*n ) = -work( ki-1+(iv-1)*n )*t(k,ki-1)
614 work( k+(iv )*n ) = -work( ki +(iv )*n )*t(k,ki )
621 DO 90 j = ki - 2, 1, -1
628 IF( t( j, j-1 ).NE.zero )
THEN
638 CALL slaln2( .false., 1, 2, smin, one, t( j, j ),
639 $ ldt, one, one, work( j+(iv-1)*n ), n,
640 $ wr, wi, x, 2, scale, xnorm, ierr )
645 IF( xnorm.GT.one )
THEN
646 IF( work( j ).GT.bignum / xnorm )
THEN
647 x( 1, 1 ) = x( 1, 1 ) / xnorm
648 x( 1, 2 ) = x( 1, 2 ) / xnorm
649 scale = scale / xnorm
655 IF( scale.NE.one )
THEN
656 CALL sscal( ki, scale, work( 1+(iv-1)*n ), 1 )
657 CALL sscal( ki, scale, work( 1+(iv )*n ), 1 )
659 work( j+(iv-1)*n ) = x( 1, 1 )
660 work( j+(iv )*n ) = x( 1, 2 )
664 CALL saxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
665 $ work( 1+(iv-1)*n ), 1 )
666 CALL saxpy( j-1, -x( 1, 2 ), t( 1, j ), 1,
667 $ work( 1+(iv )*n ), 1 )
673 CALL slaln2( .false., 2, 2, smin, one,
674 $ t( j-1, j-1 ), ldt, one, one,
675 $ work( j-1+(iv-1)*n ), n, wr, wi, x, 2,
676 $ scale, xnorm, ierr )
681 IF( xnorm.GT.one )
THEN
682 beta = max( work( j-1 ), work( j ) )
683 IF( beta.GT.bignum / xnorm )
THEN
685 x( 1, 1 ) = x( 1, 1 )*rec
686 x( 1, 2 ) = x( 1, 2 )*rec
687 x( 2, 1 ) = x( 2, 1 )*rec
688 x( 2, 2 ) = x( 2, 2 )*rec
695 IF( scale.NE.one )
THEN
696 CALL sscal( ki, scale, work( 1+(iv-1)*n ), 1 )
697 CALL sscal( ki, scale, work( 1+(iv )*n ), 1 )
699 work( j-1+(iv-1)*n ) = x( 1, 1 )
700 work( j +(iv-1)*n ) = x( 2, 1 )
701 work( j-1+(iv )*n ) = x( 1, 2 )
702 work( j +(iv )*n ) = x( 2, 2 )
706 CALL saxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
707 $ work( 1+(iv-1)*n ), 1 )
708 CALL saxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
709 $ work( 1+(iv-1)*n ), 1 )
710 CALL saxpy( j-2, -x( 1, 2 ), t( 1, j-1 ), 1,
711 $ work( 1+(iv )*n ), 1 )
712 CALL saxpy( j-2, -x( 2, 2 ), t( 1, j ), 1,
713 $ work( 1+(iv )*n ), 1 )
722 CALL scopy( ki, work( 1+(iv-1)*n ), 1, vr(1,is-1), 1 )
723 CALL scopy( ki, work( 1+(iv )*n ), 1, vr(1,is ), 1 )
727 emax = max( emax, abs( vr( k, is-1 ) )+
728 $ abs( vr( k, is ) ) )
731 CALL sscal( ki, remax, vr( 1, is-1 ), 1 )
732 CALL sscal( ki, remax, vr( 1, is ), 1 )
739 ELSE IF( nb.EQ.1 )
THEN
743 CALL sgemv(
'N', n, ki-2, one, vr, ldvr,
744 $ work( 1 + (iv-1)*n ), 1,
745 $ work( ki-1 + (iv-1)*n ), vr(1,ki-1), 1)
746 CALL sgemv(
'N', n, ki-2, one, vr, ldvr,
747 $ work( 1 + (iv)*n ), 1,
748 $ work( ki + (iv)*n ), vr( 1, ki ), 1 )
750 CALL sscal( n, work(ki-1+(iv-1)*n), vr(1,ki-1), 1)
751 CALL sscal( n, work(ki +(iv )*n), vr(1,ki ), 1)
756 emax = max( emax, abs( vr( k, ki-1 ) )+
757 $ abs( vr( k, ki ) ) )
760 CALL sscal( n, remax, vr( 1, ki-1 ), 1 )
761 CALL sscal( n, remax, vr( 1, ki ), 1 )
768 work( k + (iv-1)*n ) = zero
769 work( k + (iv )*n ) = zero
771 iscomplex( iv-1 ) = -ip
791 IF( (iv.LE.2) .OR. (ki2.EQ.1) )
THEN
792 CALL sgemm(
'N',
'N', n, nb-iv+1, ki2+nb-iv, one,
794 $ work( 1 + (iv)*n ), n,
796 $ work( 1 + (nb+iv)*n ), n )
799 IF( iscomplex(k).EQ.0 )
THEN
801 ii = isamax( n, work( 1 + (nb+k)*n ), 1 )
802 remax = one / abs( work( ii + (nb+k)*n ) )
803 ELSE IF( iscomplex(k).EQ.1 )
THEN
808 $ abs( work( ii + (nb+k )*n ) )+
809 $ abs( work( ii + (nb+k+1)*n ) ) )
816 CALL sscal( n, remax, work( 1 + (nb+k)*n ), 1 )
818 CALL slacpy(
'F', n, nb-iv+1,
819 $ work( 1 + (nb+iv)*n ), n,
820 $ vr( 1, ki2 ), ldvr )
852 ELSE IF( ki.EQ.n )
THEN
855 ELSE IF( t( ki+1, ki ).EQ.zero )
THEN
864 IF( .NOT.
SELECT( ki ) )
873 $ wi = sqrt( abs( t( ki, ki+1 ) ) )*
874 $ sqrt( abs( t( ki+1, ki ) ) )
875 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
882 work( ki + iv*n ) = one
887 work( k + iv*n ) = -t( ki, k )
904 IF( t( j+1, j ).NE.zero )
THEN
917 IF( work( j ).GT.vcrit )
THEN
919 CALL sscal( n-ki+1, rec, work( ki+iv*n ), 1 )
924 work( j+iv*n ) = work( j+iv*n ) -
925 $ sdot( j-ki-1, t( ki+1, j ), 1,
926 $ work( ki+1+iv*n ), 1 )
930 CALL slaln2( .false., 1, 1, smin, one, t( j, j ),
931 $ ldt, one, one, work( j+iv*n ), n, wr,
932 $ zero, x, 2, scale, xnorm, ierr )
937 $
CALL sscal( n-ki+1, scale, work( ki+iv*n ), 1 )
938 work( j+iv*n ) = x( 1, 1 )
939 vmax = max( abs( work( j+iv*n ) ), vmax )
940 vcrit = bignum / vmax
949 beta = max( work( j ), work( j+1 ) )
950 IF( beta.GT.vcrit )
THEN
952 CALL sscal( n-ki+1, rec, work( ki+iv*n ), 1 )
957 work( j+iv*n ) = work( j+iv*n ) -
958 $ sdot( j-ki-1, t( ki+1, j ), 1,
959 $ work( ki+1+iv*n ), 1 )
961 work( j+1+iv*n ) = work( j+1+iv*n ) -
962 $ sdot( j-ki-1, t( ki+1, j+1 ), 1,
963 $ work( ki+1+iv*n ), 1 )
969 CALL slaln2( .true., 2, 1, smin, one, t( j, j ),
970 $ ldt, one, one, work( j+iv*n ), n, wr,
971 $ zero, x, 2, scale, xnorm, ierr )
976 $
CALL sscal( n-ki+1, scale, work( ki+iv*n ), 1 )
977 work( j +iv*n ) = x( 1, 1 )
978 work( j+1+iv*n ) = x( 2, 1 )
980 vmax = max( abs( work( j +iv*n ) ),
981 $ abs( work( j+1+iv*n ) ), vmax )
982 vcrit = bignum / vmax
992 CALL scopy( n-ki+1, work( ki + iv*n ), 1,
995 ii = isamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
996 remax = one / abs( vl( ii, is ) )
997 CALL sscal( n-ki+1, remax, vl( ki, is ), 1 )
1003 ELSE IF( nb.EQ.1 )
THEN
1007 $
CALL sgemv(
'N', n, n-ki, one,
1008 $ vl( 1, ki+1 ), ldvl,
1009 $ work( ki+1 + iv*n ), 1,
1010 $ work( ki + iv*n ), vl( 1, ki ), 1 )
1012 ii = isamax( n, vl( 1, ki ), 1 )
1013 remax = one / abs( vl( ii, ki ) )
1014 CALL sscal( n, remax, vl( 1, ki ), 1 )
1022 work( k + iv*n ) = zero
1024 iscomplex( iv ) = ip
1036 IF( abs( t( ki, ki+1 ) ).GE.abs( t( ki+1, ki ) ) )
THEN
1037 work( ki + (iv )*n ) = wi / t( ki, ki+1 )
1038 work( ki+1 + (iv+1)*n ) = one
1040 work( ki + (iv )*n ) = one
1041 work( ki+1 + (iv+1)*n ) = -wi / t( ki+1, ki )
1043 work( ki+1 + (iv )*n ) = zero
1044 work( ki + (iv+1)*n ) = zero
1048 DO 190 k = ki + 2, n
1049 work( k+(iv )*n ) = -work( ki +(iv )*n )*t(ki, k)
1050 work( k+(iv+1)*n ) = -work( ki+1+(iv+1)*n )*t(ki+1,k)
1060 DO 200 j = ki + 2, n
1067 IF( t( j+1, j ).NE.zero )
THEN
1080 IF( work( j ).GT.vcrit )
THEN
1082 CALL sscal( n-ki+1, rec, work(ki+(iv )*n), 1 )
1083 CALL sscal( n-ki+1, rec, work(ki+(iv+1)*n), 1 )
1088 work( j+(iv )*n ) = work( j+(iv)*n ) -
1089 $ sdot( j-ki-2, t( ki+2, j ), 1,
1090 $ work( ki+2+(iv)*n ), 1 )
1091 work( j+(iv+1)*n ) = work( j+(iv+1)*n ) -
1092 $ sdot( j-ki-2, t( ki+2, j ), 1,
1093 $ work( ki+2+(iv+1)*n ), 1 )
1097 CALL slaln2( .false., 1, 2, smin, one, t( j, j ),
1098 $ ldt, one, one, work( j+iv*n ), n, wr,
1099 $ -wi, x, 2, scale, xnorm, ierr )
1103 IF( scale.NE.one )
THEN
1104 CALL sscal( n-ki+1, scale, work(ki+(iv )*n), 1)
1105 CALL sscal( n-ki+1, scale, work(ki+(iv+1)*n), 1)
1107 work( j+(iv )*n ) = x( 1, 1 )
1108 work( j+(iv+1)*n ) = x( 1, 2 )
1109 vmax = max( abs( work( j+(iv )*n ) ),
1110 $ abs( work( j+(iv+1)*n ) ), vmax )
1111 vcrit = bignum / vmax
1120 beta = max( work( j ), work( j+1 ) )
1121 IF( beta.GT.vcrit )
THEN
1123 CALL sscal( n-ki+1, rec, work(ki+(iv )*n), 1 )
1124 CALL sscal( n-ki+1, rec, work(ki+(iv+1)*n), 1 )
1129 work( j +(iv )*n ) = work( j+(iv)*n ) -
1130 $ sdot( j-ki-2, t( ki+2, j ), 1,
1131 $ work( ki+2+(iv)*n ), 1 )
1133 work( j +(iv+1)*n ) = work( j+(iv+1)*n ) -
1134 $ sdot( j-ki-2, t( ki+2, j ), 1,
1135 $ work( ki+2+(iv+1)*n ), 1 )
1137 work( j+1+(iv )*n ) = work( j+1+(iv)*n ) -
1138 $ sdot( j-ki-2, t( ki+2, j+1 ), 1,
1139 $ work( ki+2+(iv)*n ), 1 )
1141 work( j+1+(iv+1)*n ) = work( j+1+(iv+1)*n ) -
1142 $ sdot( j-ki-2, t( ki+2, j+1 ), 1,
1143 $ work( ki+2+(iv+1)*n ), 1 )
1149 CALL slaln2( .true., 2, 2, smin, one, t( j, j ),
1150 $ ldt, one, one, work( j+iv*n ), n, wr,
1151 $ -wi, x, 2, scale, xnorm, ierr )
1155 IF( scale.NE.one )
THEN
1156 CALL sscal( n-ki+1, scale, work(ki+(iv )*n), 1)
1157 CALL sscal( n-ki+1, scale, work(ki+(iv+1)*n), 1)
1159 work( j +(iv )*n ) = x( 1, 1 )
1160 work( j +(iv+1)*n ) = x( 1, 2 )
1161 work( j+1+(iv )*n ) = x( 2, 1 )
1162 work( j+1+(iv+1)*n ) = x( 2, 2 )
1163 vmax = max( abs( x( 1, 1 ) ), abs( x( 1, 2 ) ),
1164 $ abs( x( 2, 1 ) ), abs( x( 2, 2 ) ),
1166 vcrit = bignum / vmax
1173 IF( .NOT.over )
THEN
1176 CALL scopy( n-ki+1, work( ki + (iv )*n ), 1,
1178 CALL scopy( n-ki+1, work( ki + (iv+1)*n ), 1,
1179 $ vl( ki, is+1 ), 1 )
1183 emax = max( emax, abs( vl( k, is ) )+
1184 $ abs( vl( k, is+1 ) ) )
1187 CALL sscal( n-ki+1, remax, vl( ki, is ), 1 )
1188 CALL sscal( n-ki+1, remax, vl( ki, is+1 ), 1 )
1190 DO 230 k = 1, ki - 1
1192 vl( k, is+1 ) = zero
1195 ELSE IF( nb.EQ.1 )
THEN
1198 IF( ki.LT.n-1 )
THEN
1199 CALL sgemv(
'N', n, n-ki-1, one,
1200 $ vl( 1, ki+2 ), ldvl,
1201 $ work( ki+2 + (iv)*n ), 1,
1202 $ work( ki + (iv)*n ),
1204 CALL sgemv(
'N', n, n-ki-1, one,
1205 $ vl( 1, ki+2 ), ldvl,
1206 $ work( ki+2 + (iv+1)*n ), 1,
1207 $ work( ki+1 + (iv+1)*n ),
1208 $ vl( 1, ki+1 ), 1 )
1210 CALL sscal( n, work(ki+ (iv )*n), vl(1, ki ), 1)
1211 CALL sscal( n, work(ki+1+(iv+1)*n), vl(1, ki+1), 1)
1216 emax = max( emax, abs( vl( k, ki ) )+
1217 $ abs( vl( k, ki+1 ) ) )
1220 CALL sscal( n, remax, vl( 1, ki ), 1 )
1221 CALL sscal( n, remax, vl( 1, ki+1 ), 1 )
1229 work( k + (iv )*n ) = zero
1230 work( k + (iv+1)*n ) = zero
1232 iscomplex( iv ) = ip
1233 iscomplex( iv+1 ) = -ip
1252 IF( (iv.GE.nb-1) .OR. (ki2.EQ.n) )
THEN
1253 CALL sgemm(
'N',
'N', n, iv, n-ki2+iv, one,
1254 $ vl( 1, ki2-iv+1 ), ldvl,
1255 $ work( ki2-iv+1 + (1)*n ), n,
1257 $ work( 1 + (nb+1)*n ), n )
1260 IF( iscomplex(k).EQ.0)
THEN
1262 ii = isamax( n, work( 1 + (nb+k)*n ), 1 )
1263 remax = one / abs( work( ii + (nb+k)*n ) )
1264 ELSE IF( iscomplex(k).EQ.1)
THEN
1269 $ abs( work( ii + (nb+k )*n ) )+
1270 $ abs( work( ii + (nb+k+1)*n ) ) )
1277 CALL sscal( n, remax, work( 1 + (nb+k)*n ), 1 )
1280 $ work( 1 + (nb+1)*n ), n,
1281 $ vl( 1, ki2-iv+1 ), ldvl )
subroutine xerbla(srname, info)
subroutine saxpy(n, sa, sx, incx, sy, incy)
SAXPY
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine sgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
SGEMV
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
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.
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine sscal(n, sa, sx, incx)
SSCAL
subroutine strevc3(side, howmny, select, n, t, ldt, vl, ldvl, vr, ldvr, mm, m, work, lwork, info)
STREVC3