239 SUBROUTINE dtrevc3( 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 DOUBLE PRECISION T( ldt, * ), VL( ldvl, * ), VR( ldvr, * ),
261 DOUBLE PRECISION ZERO, ONE
262 parameter ( zero = 0.0d+0, one = 1.0d+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 DOUBLE PRECISION BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
272 $ smin, smlnum, ulp, unfl, vcrit, vmax, wi, wr,
277 INTEGER IDAMAX, ILAENV
278 DOUBLE PRECISION DDOT, DLAMCH
279 EXTERNAL lsame, idamax, ilaenv, ddot, dlamch
285 INTRINSIC abs, max, sqrt
288 DOUBLE PRECISION X( 2, 2 )
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,
'DTREVC', 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(
'DTREVC3', -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 dlaset(
'F', n, 1+2*nb, zero, zero, work, n )
386 unfl = dlamch(
'Safe minimum' )
389 ulp = dlamch(
'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 dlaln2( .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 dscal( ki, scale, work( 1+iv*n ), 1 )
515 work( j+iv*n ) = x( 1, 1 )
519 CALL daxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
520 $ work( 1+iv*n ), 1 )
526 CALL dlaln2( .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 dscal( 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 daxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
553 $ work( 1+iv*n ), 1 )
554 CALL daxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
555 $ work( 1+iv*n ), 1 )
564 CALL dcopy( ki, work( 1 + iv*n ), 1, vr( 1, is ), 1 )
566 ii = idamax( ki, vr( 1, is ), 1 )
567 remax = one / abs( vr( ii, is ) )
568 CALL dscal( ki, remax, vr( 1, is ), 1 )
574 ELSE IF( nb.EQ.1 )
THEN
578 $
CALL dgemv(
'N', n, ki-1, one, vr, ldvr,
579 $ work( 1 + iv*n ), 1, work( ki + iv*n ),
582 ii = idamax( n, vr( 1, ki ), 1 )
583 remax = one / abs( vr( ii, ki ) )
584 CALL dscal( 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 dlaln2( .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 dscal( ki, scale, work( 1+(iv-1)*n ), 1 )
662 CALL dscal( 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 daxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
670 $ work( 1+(iv-1)*n ), 1 )
671 CALL daxpy( j-1, -x( 1, 2 ), t( 1, j ), 1,
672 $ work( 1+(iv )*n ), 1 )
678 CALL dlaln2( .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 dscal( ki, scale, work( 1+(iv-1)*n ), 1 )
702 CALL dscal( 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 daxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
712 $ work( 1+(iv-1)*n ), 1 )
713 CALL daxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
714 $ work( 1+(iv-1)*n ), 1 )
715 CALL daxpy( j-2, -x( 1, 2 ), t( 1, j-1 ), 1,
716 $ work( 1+(iv )*n ), 1 )
717 CALL daxpy( j-2, -x( 2, 2 ), t( 1, j ), 1,
718 $ work( 1+(iv )*n ), 1 )
727 CALL dcopy( ki, work( 1+(iv-1)*n ), 1, vr(1,is-1), 1 )
728 CALL dcopy( 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 dscal( ki, remax, vr( 1, is-1 ), 1 )
737 CALL dscal( ki, remax, vr( 1, is ), 1 )
744 ELSE IF( nb.EQ.1 )
THEN
748 CALL dgemv(
'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 dgemv(
'N', n, ki-2, one, vr, ldvr,
752 $ work( 1 + (iv)*n ), 1,
753 $ work( ki + (iv)*n ), vr( 1, ki ), 1 )
755 CALL dscal( n, work(ki-1+(iv-1)*n), vr(1,ki-1), 1)
756 CALL dscal( 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 dscal( n, remax, vr( 1, ki-1 ), 1 )
766 CALL dscal( 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 dgemm(
'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 = idamax( 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 dscal( n, remax, work( 1 + (nb+k)*n ), 1 )
823 CALL dlacpy(
'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 dscal( n-ki+1, rec, work( ki+iv*n ), 1 )
929 work( j+iv*n ) = work( j+iv*n ) -
930 $ ddot( j-ki-1, t( ki+1, j ), 1,
931 $ work( ki+1+iv*n ), 1 )
935 CALL dlaln2( .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 dscal( 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 dscal( n-ki+1, rec, work( ki+iv*n ), 1 )
962 work( j+iv*n ) = work( j+iv*n ) -
963 $ ddot( 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 $ ddot( j-ki-1, t( ki+1, j+1 ), 1,
968 $ work( ki+1+iv*n ), 1 )
974 CALL dlaln2( .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 dscal( 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 dcopy( n-ki+1, work( ki + iv*n ), 1,
1000 ii = idamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
1001 remax = one / abs( vl( ii, is ) )
1002 CALL dscal( n-ki+1, remax, vl( ki, is ), 1 )
1004 DO 180 k = 1, ki - 1
1008 ELSE IF( nb.EQ.1 )
THEN
1012 $
CALL dgemv(
'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 = idamax( n, vl( 1, ki ), 1 )
1018 remax = one / abs( vl( ii, ki ) )
1019 CALL dscal( 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 dscal( n-ki+1, rec, work(ki+(iv )*n), 1 )
1088 CALL dscal( n-ki+1, rec, work(ki+(iv+1)*n), 1 )
1093 work( j+(iv )*n ) = work( j+(iv)*n ) -
1094 $ ddot( 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 $ ddot( j-ki-2, t( ki+2, j ), 1,
1098 $ work( ki+2+(iv+1)*n ), 1 )
1102 CALL dlaln2( .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 dscal( n-ki+1, scale, work(ki+(iv )*n), 1)
1110 CALL dscal( 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 dscal( n-ki+1, rec, work(ki+(iv )*n), 1 )
1129 CALL dscal( n-ki+1, rec, work(ki+(iv+1)*n), 1 )
1134 work( j +(iv )*n ) = work( j+(iv)*n ) -
1135 $ ddot( 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 $ ddot( 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 $ ddot( 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 $ ddot( j-ki-2, t( ki+2, j+1 ), 1,
1148 $ work( ki+2+(iv+1)*n ), 1 )
1154 CALL dlaln2( .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 dscal( n-ki+1, scale, work(ki+(iv )*n), 1)
1162 CALL dscal( 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 dcopy( n-ki+1, work( ki + (iv )*n ), 1,
1183 CALL dcopy( 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 dscal( n-ki+1, remax, vl( ki, is ), 1 )
1193 CALL dscal( 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 dgemv(
'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 dgemv(
'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 dscal( n, work(ki+ (iv )*n), vl(1, ki ), 1)
1216 CALL dscal( 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 dscal( n, remax, vl( 1, ki ), 1 )
1226 CALL dscal( 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 dgemm(
'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 = idamax( 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 dscal( n, remax, work( 1 + (nb+k)*n ), 1 )
1285 $ work( 1 + (nb+1)*n ), n,
1286 $ vl( 1, ki2-iv+1 ), ldvl )
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 dcopy(N, DX, INCX, DY, INCY)
DCOPY
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 dtrevc3(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, LWORK, INFO)
DTREVC3
subroutine daxpy(N, DA, DX, INCX, DY, INCY)
DAXPY
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dlabad(SMALL, LARGE)
DLABAD
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 dscal(N, DA, DX, INCX)
DSCAL