235 SUBROUTINE dtrevc3( 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 DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
256 DOUBLE PRECISION ZERO, ONE
257 parameter( zero = 0.0d+0, one = 1.0d+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 DOUBLE PRECISION BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
267 $ smin, smlnum, ulp, unfl, vcrit, vmax, wi, wr,
272 INTEGER IDAMAX, ILAENV
273 DOUBLE PRECISION DDOT, DLAMCH
274 EXTERNAL lsame, idamax, ilaenv, ddot, dlamch
281 INTRINSIC abs, max, sqrt
284 DOUBLE PRECISION X( 2, 2 )
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,
'DTREVC', 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(
'DTREVC3', -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 dlaset(
'F', n, 1+2*nb, zero, zero, work, n )
382 unfl = dlamch(
'Safe minimum' )
384 ulp = dlamch(
'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 dlaln2( .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 dscal( ki, scale, work( 1+iv*n ), 1 )
510 work( j+iv*n ) = x( 1, 1 )
514 CALL daxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
515 $ work( 1+iv*n ), 1 )
521 CALL dlaln2( .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 dscal( 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 daxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
548 $ work( 1+iv*n ), 1 )
549 CALL daxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
550 $ work( 1+iv*n ), 1 )
559 CALL dcopy( ki, work( 1 + iv*n ), 1, vr( 1, is ), 1 )
561 ii = idamax( ki, vr( 1, is ), 1 )
562 remax = one / abs( vr( ii, is ) )
563 CALL dscal( ki, remax, vr( 1, is ), 1 )
569 ELSE IF( nb.EQ.1 )
THEN
573 $
CALL dgemv(
'N', n, ki-1, one, vr, ldvr,
574 $ work( 1 + iv*n ), 1, work( ki + iv*n ),
577 ii = idamax( n, vr( 1, ki ), 1 )
578 remax = one / abs( vr( ii, ki ) )
579 CALL dscal( 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 dlaln2( .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 dscal( ki, scale, work( 1+(iv-1)*n ), 1 )
657 CALL dscal( 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 daxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
665 $ work( 1+(iv-1)*n ), 1 )
666 CALL daxpy( j-1, -x( 1, 2 ), t( 1, j ), 1,
667 $ work( 1+(iv )*n ), 1 )
673 CALL dlaln2( .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 dscal( ki, scale, work( 1+(iv-1)*n ), 1 )
697 CALL dscal( 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 daxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
707 $ work( 1+(iv-1)*n ), 1 )
708 CALL daxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
709 $ work( 1+(iv-1)*n ), 1 )
710 CALL daxpy( j-2, -x( 1, 2 ), t( 1, j-1 ), 1,
711 $ work( 1+(iv )*n ), 1 )
712 CALL daxpy( j-2, -x( 2, 2 ), t( 1, j ), 1,
713 $ work( 1+(iv )*n ), 1 )
722 CALL dcopy( ki, work( 1+(iv-1)*n ), 1, vr(1,is-1), 1 )
723 CALL dcopy( 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 dscal( ki, remax, vr( 1, is-1 ), 1 )
732 CALL dscal( ki, remax, vr( 1, is ), 1 )
739 ELSE IF( nb.EQ.1 )
THEN
743 CALL dgemv(
'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 dgemv(
'N', n, ki-2, one, vr, ldvr,
747 $ work( 1 + (iv)*n ), 1,
748 $ work( ki + (iv)*n ), vr( 1, ki ), 1 )
750 CALL dscal( n, work(ki-1+(iv-1)*n), vr(1,ki-1), 1)
751 CALL dscal( 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 dscal( n, remax, vr( 1, ki-1 ), 1 )
761 CALL dscal( 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 dgemm(
'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 = idamax( 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 dscal( n, remax, work( 1 + (nb+k)*n ), 1 )
818 CALL dlacpy(
'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 dscal( n-ki+1, rec, work( ki+iv*n ), 1 )
924 work( j+iv*n ) = work( j+iv*n ) -
925 $ ddot( j-ki-1, t( ki+1, j ), 1,
926 $ work( ki+1+iv*n ), 1 )
930 CALL dlaln2( .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 dscal( 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 dscal( n-ki+1, rec, work( ki+iv*n ), 1 )
957 work( j+iv*n ) = work( j+iv*n ) -
958 $ ddot( 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 $ ddot( j-ki-1, t( ki+1, j+1 ), 1,
963 $ work( ki+1+iv*n ), 1 )
969 CALL dlaln2( .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 dscal( 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 dcopy( n-ki+1, work( ki + iv*n ), 1,
995 ii = idamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
996 remax = one / abs( vl( ii, is ) )
997 CALL dscal( n-ki+1, remax, vl( ki, is ), 1 )
1003 ELSE IF( nb.EQ.1 )
THEN
1007 $
CALL dgemv(
'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 = idamax( n, vl( 1, ki ), 1 )
1013 remax = one / abs( vl( ii, ki ) )
1014 CALL dscal( 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 dscal( n-ki+1, rec, work(ki+(iv )*n), 1 )
1083 CALL dscal( n-ki+1, rec, work(ki+(iv+1)*n), 1 )
1088 work( j+(iv )*n ) = work( j+(iv)*n ) -
1089 $ ddot( 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 $ ddot( j-ki-2, t( ki+2, j ), 1,
1093 $ work( ki+2+(iv+1)*n ), 1 )
1097 CALL dlaln2( .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 dscal( n-ki+1, scale, work(ki+(iv )*n), 1)
1105 CALL dscal( 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 dscal( n-ki+1, rec, work(ki+(iv )*n), 1 )
1124 CALL dscal( n-ki+1, rec, work(ki+(iv+1)*n), 1 )
1129 work( j +(iv )*n ) = work( j+(iv)*n ) -
1130 $ ddot( 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 $ ddot( 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 $ ddot( 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 $ ddot( j-ki-2, t( ki+2, j+1 ), 1,
1143 $ work( ki+2+(iv+1)*n ), 1 )
1149 CALL dlaln2( .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 dscal( n-ki+1, scale, work(ki+(iv )*n), 1)
1157 CALL dscal( 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 dcopy( n-ki+1, work( ki + (iv )*n ), 1,
1178 CALL dcopy( 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 dscal( n-ki+1, remax, vl( ki, is ), 1 )
1188 CALL dscal( 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 dgemv(
'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 dgemv(
'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 dscal( n, work(ki+ (iv )*n), vl(1, ki ), 1)
1211 CALL dscal( 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 dscal( n, remax, vl( 1, ki ), 1 )
1221 CALL dscal( 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 dgemm(
'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 = idamax( 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 dscal( 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 daxpy(n, da, dx, incx, dy, incy)
DAXPY
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
DGEMV
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlaln2(ltrans, na, nw, smin, ca, a, lda, d1, d2, b, ldb, wr, wi, x, ldx, scale, xnorm, info)
DLALN2 solves a 1-by-1 or 2-by-2 linear system of equations of the specified form.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine dtrevc3(side, howmny, select, n, t, ldt, vl, ldvl, vr, ldvr, mm, m, work, lwork, info)
DTREVC3