239 SUBROUTINE strevc3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
240 $ vr, ldvr, mm, m, work, lwork, info )
249 CHARACTER HOWMNY, SIDE
250 INTEGER INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
254 REAL T( ldt, * ), VL( ldvl, * ), VR( ldvr, * ),
262 parameter ( zero = 0.0e+0, one = 1.0e+0 )
264 parameter ( nbmin = 8, nbmax = 128 )
267 LOGICAL ALLV, BOTHV, LEFTV, LQUERY, OVER, PAIR,
269 INTEGER I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI,
270 $ iv, maxwrk, nb, ki2
271 REAL BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
272 $ smin, smlnum, ulp, unfl, vcrit, vmax, wi, wr,
277 INTEGER ISAMAX, ILAENV
279 EXTERNAL lsame, isamax, ilaenv, sdot, slamch
285 INTRINSIC abs, max, sqrt
289 INTEGER ISCOMPLEX( nbmax )
295 bothv = lsame( side,
'B' )
296 rightv = lsame( side,
'R' ) .OR. bothv
297 leftv = lsame( side,
'L' ) .OR. bothv
299 allv = lsame( howmny,
'A' )
300 over = lsame( howmny,
'B' )
301 somev = lsame( howmny,
'S' )
304 nb = ilaenv( 1,
'STREVC', side // howmny, n, -1, -1, -1 )
307 lquery = ( lwork.EQ.-1 )
308 IF( .NOT.rightv .AND. .NOT.leftv )
THEN
310 ELSE IF( .NOT.allv .AND. .NOT.over .AND. .NOT.somev )
THEN
312 ELSE IF( n.LT.0 )
THEN
314 ELSE IF( ldt.LT.max( 1, n ) )
THEN
316 ELSE IF( ldvl.LT.1 .OR. ( leftv .AND. ldvl.LT.n ) )
THEN
318 ELSE IF( ldvr.LT.1 .OR. ( rightv .AND. ldvr.LT.n ) )
THEN
320 ELSE IF( lwork.LT.max( 1, 3*n ) .AND. .NOT.lquery )
THEN
334 SELECT( j ) = .false.
337 IF( t( j+1, j ).EQ.zero )
THEN
342 IF(
SELECT( j ) .OR.
SELECT( j+1 ) )
THEN
362 CALL xerbla(
'STREVC3', -info )
364 ELSE IF( lquery )
THEN
376 IF( over .AND. lwork .GE. n + 2*n*nbmin )
THEN
377 nb = (lwork - n) / (2*n)
378 nb = min( nb, nbmax )
379 CALL slaset(
'F', n, 1+2*nb, zero, zero, work, n )
386 unfl = slamch(
'Safe minimum' )
389 ulp = slamch(
'Precision' )
390 smlnum = unfl*( n / ulp )
391 bignum = ( one-ulp ) / smlnum
400 work( j ) = work( j ) + abs( t( i, j ) )
433 ELSE IF( ki.EQ.1 )
THEN
436 ELSE IF( t( ki, ki-1 ).EQ.zero )
THEN
446 IF( .NOT.
SELECT( ki ) )
449 IF( .NOT.
SELECT( ki-1 ) )
459 $ wi = sqrt( abs( t( ki, ki-1 ) ) )*
460 $ sqrt( abs( t( ki-1, ki ) ) )
461 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
468 work( ki + iv*n ) = one
473 work( k + iv*n ) = -t( k, ki )
480 DO 60 j = ki - 1, 1, -1
487 IF( t( j, j-1 ).NE.zero )
THEN
497 CALL slaln2( .false., 1, 1, smin, one, t( j, j ),
498 $ ldt, one, one, work( j+iv*n ), n, wr,
499 $ zero, x, 2, scale, xnorm, ierr )
504 IF( xnorm.GT.one )
THEN
505 IF( work( j ).GT.bignum / xnorm )
THEN
506 x( 1, 1 ) = x( 1, 1 ) / xnorm
507 scale = scale / xnorm
514 $
CALL sscal( ki, scale, work( 1+iv*n ), 1 )
515 work( j+iv*n ) = x( 1, 1 )
519 CALL saxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
520 $ work( 1+iv*n ), 1 )
526 CALL slaln2( .false., 2, 1, smin, one,
527 $ t( j-1, j-1 ), ldt, one, one,
528 $ work( j-1+iv*n ), n, wr, zero, x, 2,
529 $ scale, xnorm, ierr )
534 IF( xnorm.GT.one )
THEN
535 beta = max( work( j-1 ), work( j ) )
536 IF( beta.GT.bignum / xnorm )
THEN
537 x( 1, 1 ) = x( 1, 1 ) / xnorm
538 x( 2, 1 ) = x( 2, 1 ) / xnorm
539 scale = scale / xnorm
546 $
CALL sscal( ki, scale, work( 1+iv*n ), 1 )
547 work( j-1+iv*n ) = x( 1, 1 )
548 work( j +iv*n ) = x( 2, 1 )
552 CALL saxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
553 $ work( 1+iv*n ), 1 )
554 CALL saxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
555 $ work( 1+iv*n ), 1 )
564 CALL scopy( ki, work( 1 + iv*n ), 1, vr( 1, is ), 1 )
566 ii = isamax( ki, vr( 1, is ), 1 )
567 remax = one / abs( vr( ii, is ) )
568 CALL sscal( ki, remax, vr( 1, is ), 1 )
574 ELSE IF( nb.EQ.1 )
THEN
578 $
CALL sgemv(
'N', n, ki-1, one, vr, ldvr,
579 $ work( 1 + iv*n ), 1, work( ki + iv*n ),
582 ii = isamax( n, vr( 1, ki ), 1 )
583 remax = one / abs( vr( ii, ki ) )
584 CALL sscal( n, remax, vr( 1, ki ), 1 )
591 work( k + iv*n ) = zero
605 IF( abs( t( ki-1, ki ) ).GE.abs( t( ki, ki-1 ) ) )
THEN
606 work( ki-1 + (iv-1)*n ) = one
607 work( ki + (iv )*n ) = wi / t( ki-1, ki )
609 work( ki-1 + (iv-1)*n ) = -wi / t( ki, ki-1 )
610 work( ki + (iv )*n ) = one
612 work( ki + (iv-1)*n ) = zero
613 work( ki-1 + (iv )*n ) = zero
618 work( k+(iv-1)*n ) = -work( ki-1+(iv-1)*n )*t(k,ki-1)
619 work( k+(iv )*n ) = -work( ki +(iv )*n )*t(k,ki )
626 DO 90 j = ki - 2, 1, -1
633 IF( t( j, j-1 ).NE.zero )
THEN
643 CALL slaln2( .false., 1, 2, smin, one, t( j, j ),
644 $ ldt, one, one, work( j+(iv-1)*n ), n,
645 $ wr, wi, x, 2, scale, xnorm, ierr )
650 IF( xnorm.GT.one )
THEN
651 IF( work( j ).GT.bignum / xnorm )
THEN
652 x( 1, 1 ) = x( 1, 1 ) / xnorm
653 x( 1, 2 ) = x( 1, 2 ) / xnorm
654 scale = scale / xnorm
660 IF( scale.NE.one )
THEN
661 CALL sscal( ki, scale, work( 1+(iv-1)*n ), 1 )
662 CALL sscal( ki, scale, work( 1+(iv )*n ), 1 )
664 work( j+(iv-1)*n ) = x( 1, 1 )
665 work( j+(iv )*n ) = x( 1, 2 )
669 CALL saxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
670 $ work( 1+(iv-1)*n ), 1 )
671 CALL saxpy( j-1, -x( 1, 2 ), t( 1, j ), 1,
672 $ work( 1+(iv )*n ), 1 )
678 CALL slaln2( .false., 2, 2, smin, one,
679 $ t( j-1, j-1 ), ldt, one, one,
680 $ work( j-1+(iv-1)*n ), n, wr, wi, x, 2,
681 $ scale, xnorm, ierr )
686 IF( xnorm.GT.one )
THEN
687 beta = max( work( j-1 ), work( j ) )
688 IF( beta.GT.bignum / xnorm )
THEN
690 x( 1, 1 ) = x( 1, 1 )*rec
691 x( 1, 2 ) = x( 1, 2 )*rec
692 x( 2, 1 ) = x( 2, 1 )*rec
693 x( 2, 2 ) = x( 2, 2 )*rec
700 IF( scale.NE.one )
THEN
701 CALL sscal( ki, scale, work( 1+(iv-1)*n ), 1 )
702 CALL sscal( ki, scale, work( 1+(iv )*n ), 1 )
704 work( j-1+(iv-1)*n ) = x( 1, 1 )
705 work( j +(iv-1)*n ) = x( 2, 1 )
706 work( j-1+(iv )*n ) = x( 1, 2 )
707 work( j +(iv )*n ) = x( 2, 2 )
711 CALL saxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
712 $ work( 1+(iv-1)*n ), 1 )
713 CALL saxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
714 $ work( 1+(iv-1)*n ), 1 )
715 CALL saxpy( j-2, -x( 1, 2 ), t( 1, j-1 ), 1,
716 $ work( 1+(iv )*n ), 1 )
717 CALL saxpy( j-2, -x( 2, 2 ), t( 1, j ), 1,
718 $ work( 1+(iv )*n ), 1 )
727 CALL scopy( ki, work( 1+(iv-1)*n ), 1, vr(1,is-1), 1 )
728 CALL scopy( ki, work( 1+(iv )*n ), 1, vr(1,is ), 1 )
732 emax = max( emax, abs( vr( k, is-1 ) )+
733 $ abs( vr( k, is ) ) )
736 CALL sscal( ki, remax, vr( 1, is-1 ), 1 )
737 CALL sscal( ki, remax, vr( 1, is ), 1 )
744 ELSE IF( nb.EQ.1 )
THEN
748 CALL sgemv(
'N', n, ki-2, one, vr, ldvr,
749 $ work( 1 + (iv-1)*n ), 1,
750 $ work( ki-1 + (iv-1)*n ), vr(1,ki-1), 1)
751 CALL sgemv(
'N', n, ki-2, one, vr, ldvr,
752 $ work( 1 + (iv)*n ), 1,
753 $ work( ki + (iv)*n ), vr( 1, ki ), 1 )
755 CALL sscal( n, work(ki-1+(iv-1)*n), vr(1,ki-1), 1)
756 CALL sscal( n, work(ki +(iv )*n), vr(1,ki ), 1)
761 emax = max( emax, abs( vr( k, ki-1 ) )+
762 $ abs( vr( k, ki ) ) )
765 CALL sscal( n, remax, vr( 1, ki-1 ), 1 )
766 CALL sscal( n, remax, vr( 1, ki ), 1 )
773 work( k + (iv-1)*n ) = zero
774 work( k + (iv )*n ) = zero
776 iscomplex( iv-1 ) = -ip
796 IF( (iv.LE.2) .OR. (ki2.EQ.1) )
THEN
797 CALL sgemm(
'N',
'N', n, nb-iv+1, ki2+nb-iv, one,
799 $ work( 1 + (iv)*n ), n,
801 $ work( 1 + (nb+iv)*n ), n )
804 IF( iscomplex(k).EQ.0 )
THEN
806 ii = isamax( n, work( 1 + (nb+k)*n ), 1 )
807 remax = one / abs( work( ii + (nb+k)*n ) )
808 ELSE IF( iscomplex(k).EQ.1 )
THEN
813 $ abs( work( ii + (nb+k )*n ) )+
814 $ abs( work( ii + (nb+k+1)*n ) ) )
821 CALL sscal( n, remax, work( 1 + (nb+k)*n ), 1 )
823 CALL slacpy(
'F', n, nb-iv+1,
824 $ work( 1 + (nb+iv)*n ), n,
825 $ vr( 1, ki2 ), ldvr )
857 ELSE IF( ki.EQ.n )
THEN
860 ELSE IF( t( ki+1, ki ).EQ.zero )
THEN
869 IF( .NOT.
SELECT( ki ) )
878 $ wi = sqrt( abs( t( ki, ki+1 ) ) )*
879 $ sqrt( abs( t( ki+1, ki ) ) )
880 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
887 work( ki + iv*n ) = one
892 work( k + iv*n ) = -t( ki, k )
909 IF( t( j+1, j ).NE.zero )
THEN
922 IF( work( j ).GT.vcrit )
THEN
924 CALL sscal( n-ki+1, rec, work( ki+iv*n ), 1 )
929 work( j+iv*n ) = work( j+iv*n ) -
930 $ sdot( j-ki-1, t( ki+1, j ), 1,
931 $ work( ki+1+iv*n ), 1 )
935 CALL slaln2( .false., 1, 1, smin, one, t( j, j ),
936 $ ldt, one, one, work( j+iv*n ), n, wr,
937 $ zero, x, 2, scale, xnorm, ierr )
942 $
CALL sscal( n-ki+1, scale, work( ki+iv*n ), 1 )
943 work( j+iv*n ) = x( 1, 1 )
944 vmax = max( abs( work( j+iv*n ) ), vmax )
945 vcrit = bignum / vmax
954 beta = max( work( j ), work( j+1 ) )
955 IF( beta.GT.vcrit )
THEN
957 CALL sscal( n-ki+1, rec, work( ki+iv*n ), 1 )
962 work( j+iv*n ) = work( j+iv*n ) -
963 $ sdot( j-ki-1, t( ki+1, j ), 1,
964 $ work( ki+1+iv*n ), 1 )
966 work( j+1+iv*n ) = work( j+1+iv*n ) -
967 $ sdot( j-ki-1, t( ki+1, j+1 ), 1,
968 $ work( ki+1+iv*n ), 1 )
974 CALL slaln2( .true., 2, 1, smin, one, t( j, j ),
975 $ ldt, one, one, work( j+iv*n ), n, wr,
976 $ zero, x, 2, scale, xnorm, ierr )
981 $
CALL sscal( n-ki+1, scale, work( ki+iv*n ), 1 )
982 work( j +iv*n ) = x( 1, 1 )
983 work( j+1+iv*n ) = x( 2, 1 )
985 vmax = max( abs( work( j +iv*n ) ),
986 $ abs( work( j+1+iv*n ) ), vmax )
987 vcrit = bignum / vmax
997 CALL scopy( n-ki+1, work( ki + iv*n ), 1,
1000 ii = isamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
1001 remax = one / abs( vl( ii, is ) )
1002 CALL sscal( n-ki+1, remax, vl( ki, is ), 1 )
1004 DO 180 k = 1, ki - 1
1008 ELSE IF( nb.EQ.1 )
THEN
1012 $
CALL sgemv(
'N', n, n-ki, one,
1013 $ vl( 1, ki+1 ), ldvl,
1014 $ work( ki+1 + iv*n ), 1,
1015 $ work( ki + iv*n ), vl( 1, ki ), 1 )
1017 ii = isamax( n, vl( 1, ki ), 1 )
1018 remax = one / abs( vl( ii, ki ) )
1019 CALL sscal( n, remax, vl( 1, ki ), 1 )
1027 work( k + iv*n ) = zero
1029 iscomplex( iv ) = ip
1041 IF( abs( t( ki, ki+1 ) ).GE.abs( t( ki+1, ki ) ) )
THEN
1042 work( ki + (iv )*n ) = wi / t( ki, ki+1 )
1043 work( ki+1 + (iv+1)*n ) = one
1045 work( ki + (iv )*n ) = one
1046 work( ki+1 + (iv+1)*n ) = -wi / t( ki+1, ki )
1048 work( ki+1 + (iv )*n ) = zero
1049 work( ki + (iv+1)*n ) = zero
1053 DO 190 k = ki + 2, n
1054 work( k+(iv )*n ) = -work( ki +(iv )*n )*t(ki, k)
1055 work( k+(iv+1)*n ) = -work( ki+1+(iv+1)*n )*t(ki+1,k)
1065 DO 200 j = ki + 2, n
1072 IF( t( j+1, j ).NE.zero )
THEN
1085 IF( work( j ).GT.vcrit )
THEN
1087 CALL sscal( n-ki+1, rec, work(ki+(iv )*n), 1 )
1088 CALL sscal( n-ki+1, rec, work(ki+(iv+1)*n), 1 )
1093 work( j+(iv )*n ) = work( j+(iv)*n ) -
1094 $ sdot( j-ki-2, t( ki+2, j ), 1,
1095 $ work( ki+2+(iv)*n ), 1 )
1096 work( j+(iv+1)*n ) = work( j+(iv+1)*n ) -
1097 $ sdot( j-ki-2, t( ki+2, j ), 1,
1098 $ work( ki+2+(iv+1)*n ), 1 )
1102 CALL slaln2( .false., 1, 2, smin, one, t( j, j ),
1103 $ ldt, one, one, work( j+iv*n ), n, wr,
1104 $ -wi, x, 2, scale, xnorm, ierr )
1108 IF( scale.NE.one )
THEN
1109 CALL sscal( n-ki+1, scale, work(ki+(iv )*n), 1)
1110 CALL sscal( n-ki+1, scale, work(ki+(iv+1)*n), 1)
1112 work( j+(iv )*n ) = x( 1, 1 )
1113 work( j+(iv+1)*n ) = x( 1, 2 )
1114 vmax = max( abs( work( j+(iv )*n ) ),
1115 $ abs( work( j+(iv+1)*n ) ), vmax )
1116 vcrit = bignum / vmax
1125 beta = max( work( j ), work( j+1 ) )
1126 IF( beta.GT.vcrit )
THEN
1128 CALL sscal( n-ki+1, rec, work(ki+(iv )*n), 1 )
1129 CALL sscal( n-ki+1, rec, work(ki+(iv+1)*n), 1 )
1134 work( j +(iv )*n ) = work( j+(iv)*n ) -
1135 $ sdot( j-ki-2, t( ki+2, j ), 1,
1136 $ work( ki+2+(iv)*n ), 1 )
1138 work( j +(iv+1)*n ) = work( j+(iv+1)*n ) -
1139 $ sdot( j-ki-2, t( ki+2, j ), 1,
1140 $ work( ki+2+(iv+1)*n ), 1 )
1142 work( j+1+(iv )*n ) = work( j+1+(iv)*n ) -
1143 $ sdot( j-ki-2, t( ki+2, j+1 ), 1,
1144 $ work( ki+2+(iv)*n ), 1 )
1146 work( j+1+(iv+1)*n ) = work( j+1+(iv+1)*n ) -
1147 $ sdot( j-ki-2, t( ki+2, j+1 ), 1,
1148 $ work( ki+2+(iv+1)*n ), 1 )
1154 CALL slaln2( .true., 2, 2, smin, one, t( j, j ),
1155 $ ldt, one, one, work( j+iv*n ), n, wr,
1156 $ -wi, x, 2, scale, xnorm, ierr )
1160 IF( scale.NE.one )
THEN
1161 CALL sscal( n-ki+1, scale, work(ki+(iv )*n), 1)
1162 CALL sscal( n-ki+1, scale, work(ki+(iv+1)*n), 1)
1164 work( j +(iv )*n ) = x( 1, 1 )
1165 work( j +(iv+1)*n ) = x( 1, 2 )
1166 work( j+1+(iv )*n ) = x( 2, 1 )
1167 work( j+1+(iv+1)*n ) = x( 2, 2 )
1168 vmax = max( abs( x( 1, 1 ) ), abs( x( 1, 2 ) ),
1169 $ abs( x( 2, 1 ) ), abs( x( 2, 2 ) ),
1171 vcrit = bignum / vmax
1178 IF( .NOT.over )
THEN
1181 CALL scopy( n-ki+1, work( ki + (iv )*n ), 1,
1183 CALL scopy( n-ki+1, work( ki + (iv+1)*n ), 1,
1184 $ vl( ki, is+1 ), 1 )
1188 emax = max( emax, abs( vl( k, is ) )+
1189 $ abs( vl( k, is+1 ) ) )
1192 CALL sscal( n-ki+1, remax, vl( ki, is ), 1 )
1193 CALL sscal( n-ki+1, remax, vl( ki, is+1 ), 1 )
1195 DO 230 k = 1, ki - 1
1197 vl( k, is+1 ) = zero
1200 ELSE IF( nb.EQ.1 )
THEN
1203 IF( ki.LT.n-1 )
THEN
1204 CALL sgemv(
'N', n, n-ki-1, one,
1205 $ vl( 1, ki+2 ), ldvl,
1206 $ work( ki+2 + (iv)*n ), 1,
1207 $ work( ki + (iv)*n ),
1209 CALL sgemv(
'N', n, n-ki-1, one,
1210 $ vl( 1, ki+2 ), ldvl,
1211 $ work( ki+2 + (iv+1)*n ), 1,
1212 $ work( ki+1 + (iv+1)*n ),
1213 $ vl( 1, ki+1 ), 1 )
1215 CALL sscal( n, work(ki+ (iv )*n), vl(1, ki ), 1)
1216 CALL sscal( n, work(ki+1+(iv+1)*n), vl(1, ki+1), 1)
1221 emax = max( emax, abs( vl( k, ki ) )+
1222 $ abs( vl( k, ki+1 ) ) )
1225 CALL sscal( n, remax, vl( 1, ki ), 1 )
1226 CALL sscal( n, remax, vl( 1, ki+1 ), 1 )
1234 work( k + (iv )*n ) = zero
1235 work( k + (iv+1)*n ) = zero
1237 iscomplex( iv ) = ip
1238 iscomplex( iv+1 ) = -ip
1257 IF( (iv.GE.nb-1) .OR. (ki2.EQ.n) )
THEN
1258 CALL sgemm(
'N',
'N', n, iv, n-ki2+iv, one,
1259 $ vl( 1, ki2-iv+1 ), ldvl,
1260 $ work( ki2-iv+1 + (1)*n ), n,
1262 $ work( 1 + (nb+1)*n ), n )
1265 IF( iscomplex(k).EQ.0)
THEN
1267 ii = isamax( n, work( 1 + (nb+k)*n ), 1 )
1268 remax = one / abs( work( ii + (nb+k)*n ) )
1269 ELSE IF( iscomplex(k).EQ.1)
THEN
1274 $ abs( work( ii + (nb+k )*n ) )+
1275 $ abs( work( ii + (nb+k+1)*n ) ) )
1282 CALL sscal( n, remax, work( 1 + (nb+k)*n ), 1 )
1285 $ work( 1 + (nb+1)*n ), n,
1286 $ vl( 1, ki2-iv+1 ), ldvl )
subroutine slabad(SMALL, LARGE)
SLABAD
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
subroutine xerbla(SRNAME, INFO)
XERBLA
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 strevc3(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, LWORK, INFO)
STREVC3
subroutine saxpy(N, SA, SX, INCX, SY, INCY)
SAXPY
subroutine sscal(N, SA, SX, INCX)
SSCAL
subroutine scopy(N, SX, INCX, SY, INCY)
SCOPY