218 SUBROUTINE dtrevc( 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 DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
239 DOUBLE PRECISION ZERO, ONE
240 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+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 DOUBLE PRECISION BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
246 $ smin, smlnum, ulp, unfl, vcrit, vmax, wi, wr,
252 DOUBLE PRECISION DDOT, DLAMCH
253 EXTERNAL lsame, idamax, ddot, dlamch
260 INTRINSIC abs, max, sqrt
263 DOUBLE PRECISION X( 2, 2 )
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(
'DTREVC', -info )
341 unfl = dlamch(
'Safe minimum' )
343 ulp = dlamch(
'Precision' )
344 smlnum = unfl*( 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 dlaln2( .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 dscal( ki, scale, work( 1+n ), 1 )
453 work( j+n ) = x( 1, 1 )
457 CALL daxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
464 CALL dlaln2( .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 dscal( ki, scale, work( 1+n ), 1 )
485 work( j-1+n ) = x( 1, 1 )
486 work( j+n ) = x( 2, 1 )
490 CALL daxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
492 CALL daxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
500 CALL dcopy( ki, work( 1+n ), 1, vr( 1, is ), 1 )
502 ii = idamax( ki, vr( 1, is ), 1 )
503 remax = one / abs( vr( ii, is ) )
504 CALL dscal( ki, remax, vr( 1, is ), 1 )
511 $
CALL dgemv(
'N', n, ki-1, one, vr, ldvr,
512 $ work( 1+n ), 1, work( ki+n ),
515 ii = idamax( n, vr( 1, ki ), 1 )
516 remax = one / abs( vr( ii, ki ) )
517 CALL dscal( 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 dlaln2( .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 dscal( ki, scale, work( 1+n ), 1 )
586 CALL dscal( ki, scale, work( 1+n2 ), 1 )
588 work( j+n ) = x( 1, 1 )
589 work( j+n2 ) = x( 1, 2 )
593 CALL daxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
595 CALL daxpy( j-1, -x( 1, 2 ), t( 1, j ), 1,
602 CALL dlaln2( .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 dscal( ki, scale, work( 1+n ), 1 )
626 CALL dscal( 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 daxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
637 CALL daxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
639 CALL daxpy( j-2, -x( 1, 2 ), t( 1, j-1 ), 1,
641 CALL daxpy( j-2, -x( 2, 2 ), t( 1, j ), 1,
649 CALL dcopy( ki, work( 1+n ), 1, vr( 1, is-1 ), 1 )
650 CALL dcopy( 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 dscal( ki, remax, vr( 1, is-1 ), 1 )
660 CALL dscal( ki, remax, vr( 1, is ), 1 )
670 CALL dgemv(
'N', n, ki-2, one, vr, ldvr,
671 $ work( 1+n ), 1, work( ki-1+n ),
673 CALL dgemv(
'N', n, ki-2, one, vr, ldvr,
674 $ work( 1+n2 ), 1, work( ki+n2 ),
677 CALL dscal( n, work( ki-1+n ), vr( 1, ki-1 ),
679 CALL dscal( n, work( ki+n2 ), vr( 1, ki ), 1 )
684 emax = max( emax, abs( vr( k, ki-1 ) )+
685 $ abs( vr( k, ki ) ) )
688 CALL dscal( n, remax, vr( 1, ki-1 ), 1 )
689 CALL dscal( 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 dscal( n-ki+1, rec, work( ki+n ), 1 )
781 work( j+n ) = work( j+n ) -
782 $ ddot( j-ki-1, t( ki+1, j ), 1,
783 $ work( ki+1+n ), 1 )
787 CALL dlaln2( .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 dscal( 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 dscal( n-ki+1, rec, work( ki+n ), 1 )
815 work( j+n ) = work( j+n ) -
816 $ ddot( j-ki-1, t( ki+1, j ), 1,
817 $ work( ki+1+n ), 1 )
819 work( j+1+n ) = work( j+1+n ) -
820 $ ddot( j-ki-1, t( ki+1, j+1 ), 1,
821 $ work( ki+1+n ), 1 )
827 CALL dlaln2( .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 dscal( 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 dcopy( n-ki+1, work( ki+n ), 1, vl( ki, is ),
851 ii = idamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
852 remax = one / abs( vl( ii, is ) )
853 CALL dscal( n-ki+1, remax, vl( ki, is ), 1 )
862 $
CALL dgemv(
'N', n, n-ki, one, vl( 1, ki+1 ),
864 $ work( ki+1+n ), 1, work( ki+n ),
867 ii = idamax( n, vl( 1, ki ), 1 )
868 remax = one / abs( vl( ii, ki ) )
869 CALL dscal( 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 dscal( n-ki+1, rec, work( ki+n ), 1 )
928 CALL dscal( n-ki+1, rec, work( ki+n2 ), 1 )
933 work( j+n ) = work( j+n ) -
934 $ ddot( j-ki-2, t( ki+2, j ), 1,
935 $ work( ki+2+n ), 1 )
936 work( j+n2 ) = work( j+n2 ) -
937 $ ddot( j-ki-2, t( ki+2, j ), 1,
938 $ work( ki+2+n2 ), 1 )
942 CALL dlaln2( .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 dscal( n-ki+1, scale, work( ki+n ), 1 )
951 CALL dscal( 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 dscal( n-ki+1, rec, work( ki+n ), 1 )
970 CALL dscal( n-ki+1, rec, work( ki+n2 ), 1 )
975 work( j+n ) = work( j+n ) -
976 $ ddot( j-ki-2, t( ki+2, j ), 1,
977 $ work( ki+2+n ), 1 )
979 work( j+n2 ) = work( j+n2 ) -
980 $ ddot( j-ki-2, t( ki+2, j ), 1,
981 $ work( ki+2+n2 ), 1 )
983 work( j+1+n ) = work( j+1+n ) -
984 $ ddot( 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 $ ddot( j-ki-2, t( ki+2, j+1 ),
990 $ work( ki+2+n2 ), 1 )
996 CALL dlaln2( .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 dscal( n-ki+1, scale, work( ki+n ), 1 )
1004 CALL dscal( 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 dcopy( n-ki+1, work( ki+n ), 1, vl( ki, is ),
1022 CALL dcopy( 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 dscal( n-ki+1, remax, vl( ki, is ), 1 )
1033 CALL dscal( 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 dgemv(
'N', n, n-ki-1, one, vl( 1, ki+2 ),
1042 $ ldvl, work( ki+2+n ), 1, work( ki+n ),
1044 CALL dgemv(
'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 dscal( n, work( ki+n ), vl( 1, ki ), 1 )
1049 CALL dscal( 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 dscal( n, remax, vl( 1, ki ), 1 )
1060 CALL dscal( n, remax, vl( 1, ki+1 ), 1 )