1 SUBROUTINE dtrevc( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
2 $ LDVR, MM, M, WORK, INFO )
10 CHARACTER HOWMNY, SIDE
11 INTEGER INFO, LDT, LDVL, LDVR, M, MM, N
15 DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
171 DOUBLE PRECISION ZERO, ONE
172 parameter( zero = 0.0d+0, one = 1.0d+0 )
175 LOGICAL ALLV, BOTHV, LEFTV, OVER, PAIR, RIGHTV, SOMEV
176 INTEGER I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI, N2
177 DOUBLE PRECISION BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,
178 $ smin, smlnum, ulp, unfl, vcrit, vmax, wi, wr,
184 DOUBLE PRECISION DDOT, DLAMCH
185 EXTERNAL lsame, idamax, ddot, dlamch
191 INTRINSIC abs, max, sqrt
194 DOUBLE PRECISION X( 2, 2 )
200 bothv = lsame( side,
'B' )
201 rightv = lsame( side,
'R' ) .OR. bothv
202 leftv = lsame( side,
'L' ) .OR. bothv
204 allv = lsame( howmny,
'A' )
205 over = lsame( howmny,
'B' )
206 somev = lsame( howmny,
'S' )
209 IF( .NOT.rightv .AND. .NOT.leftv )
THEN
211 ELSE IF( .NOT.allv .AND. .NOT.over .AND. .NOT.somev )
THEN
213 ELSE IF( n.LT.0 )
THEN
215 ELSE IF( ldt.LT.max( 1, n ) )
THEN
217 ELSE IF( ldvl.LT.1 .OR. ( leftv .AND. ldvl.LT.n ) )
THEN
219 ELSE IF( ldvr.LT.1 .OR. ( rightv .AND. ldvr.LT.n ) )
THEN
233 SELECT( j ) = .false.
236 IF( t( j+1, j ).EQ.zero )
THEN
241 IF(
SELECT( j ) .OR.
SELECT( j+1 ) )
THEN
261 CALL xerbla(
'DTREVC', -info )
272 unfl = dlamch(
'Safe minimum' )
275 ulp = dlamch(
'Precision' )
276 smlnum = unfl*( n / ulp )
277 bignum = ( one-ulp ) / smlnum
286 work( j ) = work( j ) + abs( t( i, j ) )
309 IF( t( ki, ki-1 ).EQ.zero )
316 IF( .NOT.
SELECT( ki ) )
319 IF( .NOT.
SELECT( ki-1 ) )
329 $ wi = sqrt( abs( t( ki, ki-1 ) ) )*
330 $ sqrt( abs( t( ki-1, ki ) ) )
331 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
342 work( k+n ) = -t( k, ki )
349 DO 60 j = ki - 1, 1, -1
356 IF( t( j, j-1 ).NE.zero )
THEN
366 CALL dlaln2( .false., 1, 1, smin, one, t( j, j ),
367 $ ldt, one, one, work( j+n ), n, wr,
368 $ zero, x, 2, scale, xnorm, ierr )
373 IF( xnorm.GT.one )
THEN
374 IF( work( j ).GT.bignum / xnorm )
THEN
375 x( 1, 1 ) = x( 1, 1 ) / xnorm
376 scale = scale / xnorm
383 $
CALL dscal( ki, scale, work( 1+n ), 1 )
384 work( j+n ) = x( 1, 1 )
388 CALL daxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
395 CALL dlaln2( .false., 2, 1, smin, one,
396 $ t( j-1, j-1 ), ldt, one, one,
397 $ work( j-1+n ), n, wr, zero, x, 2,
398 $ scale, xnorm, ierr )
403 IF( xnorm.GT.one )
THEN
404 beta = max( work( j-1 ), work( j ) )
405 IF( beta.GT.bignum / xnorm )
THEN
406 x( 1, 1 ) = x( 1, 1 ) / xnorm
407 x( 2, 1 ) = x( 2, 1 ) / xnorm
408 scale = scale / xnorm
415 $
CALL dscal( ki, scale, work( 1+n ), 1 )
416 work( j-1+n ) = x( 1, 1 )
417 work( j+n ) = x( 2, 1 )
421 CALL daxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
423 CALL daxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
431 CALL dcopy( ki, work( 1+n ), 1, vr( 1, is ), 1 )
433 ii = idamax( ki, vr( 1, is ), 1 )
434 remax = one / abs( vr( ii, is ) )
435 CALL dscal( ki, remax, vr( 1, is ), 1 )
442 $
CALL dgemv(
'N', n, ki-1, one, vr, ldvr,
443 $ work( 1+n ), 1, work( ki+n ),
446 ii = idamax( n, vr( 1, ki ), 1 )
447 remax = one / abs( vr( ii, ki ) )
448 CALL dscal( n, remax, vr( 1, ki ), 1 )
459 IF( abs( t( ki-1, ki ) ).GE.abs( t( ki, ki-1 ) ) )
THEN
461 work( ki+n2 ) = wi / t( ki-1, ki )
463 work( ki-1+n ) = -wi / t( ki, ki-1 )
467 work( ki-1+n2 ) = zero
472 work( k+n ) = -work( ki-1+n )*t( k, ki-1 )
473 work( k+n2 ) = -work( ki+n2 )*t( k, ki )
480 DO 90 j = ki - 2, 1, -1
487 IF( t( j, j-1 ).NE.zero )
THEN
497 CALL dlaln2( .false., 1, 2, smin, one, t( j, j ),
498 $ ldt, one, one, work( j+n ), n, wr, wi,
499 $ 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 x( 1, 2 ) = x( 1, 2 ) / xnorm
508 scale = scale / xnorm
514 IF( scale.NE.one )
THEN
515 CALL dscal( ki, scale, work( 1+n ), 1 )
516 CALL dscal( ki, scale, work( 1+n2 ), 1 )
518 work( j+n ) = x( 1, 1 )
519 work( j+n2 ) = x( 1, 2 )
523 CALL daxpy( j-1, -x( 1, 1 ), t( 1, j ), 1,
525 CALL daxpy( j-1, -x( 1, 2 ), t( 1, j ), 1,
532 CALL dlaln2( .false., 2, 2, smin, one,
533 $ t( j-1, j-1 ), ldt, one, one,
534 $ work( j-1+n ), n, wr, wi, x, 2, scale,
540 IF( xnorm.GT.one )
THEN
541 beta = max( work( j-1 ), work( j ) )
542 IF( beta.GT.bignum / xnorm )
THEN
544 x( 1, 1 ) = x( 1, 1 )*rec
545 x( 1, 2 ) = x( 1, 2 )*rec
546 x( 2, 1 ) = x( 2, 1 )*rec
547 x( 2, 2 ) = x( 2, 2 )*rec
554 IF( scale.NE.one )
THEN
555 CALL dscal( ki, scale, work( 1+n ), 1 )
556 CALL dscal( ki, scale, work( 1+n2 ), 1 )
558 work( j-1+n ) = x( 1, 1 )
559 work( j+n ) = x( 2, 1 )
560 work( j-1+n2 ) = x( 1, 2 )
561 work( j+n2 ) = x( 2, 2 )
565 CALL daxpy( j-2, -x( 1, 1 ), t( 1, j-1 ), 1,
567 CALL daxpy( j-2, -x( 2, 1 ), t( 1, j ), 1,
569 CALL daxpy( j-2, -x( 1, 2 ), t( 1, j-1 ), 1,
571 CALL daxpy( j-2, -x( 2, 2 ), t( 1, j ), 1,
579 CALL dcopy( ki, work( 1+n ), 1, vr( 1, is-1 ), 1 )
580 CALL dcopy( ki, work( 1+n2 ), 1, vr( 1, is ), 1 )
584 emax = max( emax, abs( vr( k, is-1 ) )+
585 $ abs( vr( k, is ) ) )
589 CALL dscal( ki, remax, vr( 1, is-1 ), 1 )
590 CALL dscal( ki, remax, vr( 1, is ), 1 )
600 CALL dgemv(
'N', n, ki-2, one, vr, ldvr,
601 $ work( 1+n ), 1, work( ki-1+n ),
603 CALL dgemv(
'N', n, ki-2, one, vr, ldvr,
604 $ work( 1+n2 ), 1, work( ki+n2 ),
607 CALL dscal( n, work( ki-1+n ), vr( 1, ki-1 ), 1 )
608 CALL dscal( n, work( ki+n2 ), vr( 1, ki ), 1 )
613 emax = max( emax, abs( vr( k, ki-1 ) )+
614 $ abs( vr( k, ki ) ) )
617 CALL dscal( n, remax, vr( 1, ki-1 ), 1 )
618 CALL dscal( n, remax, vr( 1, ki ), 1 )
645 IF( t( ki+1, ki ).EQ.zero )
651 IF( .NOT.
SELECT( ki ) )
660 $ wi = sqrt( abs( t( ki, ki+1 ) ) )*
661 $ sqrt( abs( t( ki+1, ki ) ) )
662 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
673 work( k+n ) = -t( ki, k )
690 IF( t( j+1, j ).NE.zero )
THEN
703 IF( work( j ).GT.vcrit )
THEN
705 CALL dscal( n-ki+1, rec, work( ki+n ), 1 )
710 work( j+n ) = work( j+n ) -
711 $ ddot( j-ki-1, t( ki+1, j ), 1,
712 $ work( ki+1+n ), 1 )
716 CALL dlaln2( .false., 1, 1, smin, one, t( j, j ),
717 $ ldt, one, one, work( j+n ), n, wr,
718 $ zero, x, 2, scale, xnorm, ierr )
723 $
CALL dscal( n-ki+1, scale, work( ki+n ), 1 )
724 work( j+n ) = x( 1, 1 )
725 vmax = max( abs( work( j+n ) ), vmax )
726 vcrit = bignum / vmax
735 beta = max( work( j ), work( j+1 ) )
736 IF( beta.GT.vcrit )
THEN
738 CALL dscal( n-ki+1, rec, work( ki+n ), 1 )
743 work( j+n ) = work( j+n ) -
744 $ ddot( j-ki-1, t( ki+1, j ), 1,
745 $ work( ki+1+n ), 1 )
747 work( j+1+n ) = work( j+1+n ) -
748 $ ddot( j-ki-1, t( ki+1, j+1 ), 1,
749 $ work( ki+1+n ), 1 )
755 CALL dlaln2( .true., 2, 1, smin, one, t( j, j ),
756 $ ldt, one, one, work( j+n ), n, wr,
757 $ zero, x, 2, scale, xnorm, ierr )
762 $
CALL dscal( n-ki+1, scale, work( ki+n ), 1 )
763 work( j+n ) = x( 1, 1 )
764 work( j+1+n ) = x( 2, 1 )
766 vmax = max( abs( work( j+n ) ),
767 $ abs( work( j+1+n ) ), vmax )
768 vcrit = bignum / vmax
776 CALL dcopy( n-ki+1, work( ki+n ), 1, vl( ki, is ), 1 )
778 ii = idamax( n-ki+1, vl( ki, is ), 1 ) + ki - 1
779 remax = one / abs( vl( ii, is ) )
780 CALL dscal( n-ki+1, remax, vl( ki, is ), 1 )
789 $
CALL dgemv(
'N', n, n-ki, one, vl( 1, ki+1 ), ldvl,
790 $ work( ki+1+n ), 1, work( ki+n ),
793 ii = idamax( n, vl( 1, ki ), 1 )
794 remax = one / abs( vl( ii, ki ) )
795 CALL dscal( n, remax, vl( 1, ki ), 1 )
807 IF( abs( t( ki, ki+1 ) ).GE.abs( t( ki+1, ki ) ) )
THEN
808 work( ki+n ) = wi / t( ki, ki+1 )
809 work( ki+1+n2 ) = one
812 work( ki+1+n2 ) = -wi / t( ki+1, ki )
814 work( ki+1+n ) = zero
820 work( k+n ) = -work( ki+n )*t( ki, k )
821 work( k+n2 ) = -work( ki+1+n2 )*t( ki+1, k )
838 IF( t( j+1, j ).NE.zero )
THEN
851 IF( work( j ).GT.vcrit )
THEN
853 CALL dscal( n-ki+1, rec, work( ki+n ), 1 )
854 CALL dscal( n-ki+1, rec, work( ki+n2 ), 1 )
859 work( j+n ) = work( j+n ) -
860 $ ddot( j-ki-2, t( ki+2, j ), 1,
861 $ work( ki+2+n ), 1 )
862 work( j+n2 ) = work( j+n2 ) -
863 $ ddot( j-ki-2, t( ki+2, j ), 1,
864 $ work( ki+2+n2 ), 1 )
868 CALL dlaln2( .false., 1, 2, smin, one, t( j, j ),
869 $ ldt, one, one, work( j+n ), n, wr,
870 $ -wi, x, 2, scale, xnorm, ierr )
874 IF( scale.NE.one )
THEN
875 CALL dscal( n-ki+1, scale, work( ki+n ), 1 )
876 CALL dscal( n-ki+1, scale, work( ki+n2 ), 1 )
878 work( j+n ) = x( 1, 1 )
879 work( j+n2 ) = x( 1, 2 )
880 vmax = max( abs( work( j+n ) ),
881 $ abs( work( j+n2 ) ), vmax )
882 vcrit = bignum / vmax
891 beta = max( work( j ), work( j+1 ) )
892 IF( beta.GT.vcrit )
THEN
894 CALL dscal( n-ki+1, rec, work( ki+n ), 1 )
895 CALL dscal( n-ki+1, rec, work( ki+n2 ), 1 )
900 work( j+n ) = work( j+n ) -
901 $ ddot( j-ki-2, t( ki+2, j ), 1,
902 $ work( ki+2+n ), 1 )
904 work( j+n2 ) = work( j+n2 ) -
905 $ ddot( j-ki-2, t( ki+2, j ), 1,
906 $ work( ki+2+n2 ), 1 )
908 work( j+1+n ) = work( j+1+n ) -
909 $ ddot( j-ki-2, t( ki+2, j+1 ), 1,
910 $ work( ki+2+n ), 1 )
912 work( j+1+n2 ) = work( j+1+n2 ) -
913 $ ddot( j-ki-2, t( ki+2, j+1 ), 1,
914 $ work( ki+2+n2 ), 1 )
920 CALL dlaln2( .true., 2, 2, smin, one, t( j, j ),
921 $ ldt, one, one, work( j+n ), n, wr,
922 $ -wi, x, 2, scale, xnorm, ierr )
926 IF( scale.NE.one )
THEN
927 CALL dscal( n-ki+1, scale, work( ki+n ), 1 )
928 CALL dscal( n-ki+1, scale, work( ki+n2 ), 1 )
930 work( j+n ) = x( 1, 1 )
931 work( j+n2 ) = x( 1, 2 )
932 work( j+1+n ) = x( 2, 1 )
933 work( j+1+n2 ) = x( 2, 2 )
934 vmax = max( abs( x( 1, 1 ) ), abs( x( 1, 2 ) ),
935 $ abs( x( 2, 1 ) ), abs( x( 2, 2 ) ), vmax )
936 vcrit = bignum / vmax
945 CALL dcopy( n-ki+1, work( ki+n ), 1, vl( ki, is ), 1 )
946 CALL dcopy( n-ki+1, work( ki+n2 ), 1, vl( ki, is+1 ),
951 emax = max( emax, abs( vl( k, is ) )+
952 $ abs( vl( k, is+1 ) ) )
955 CALL dscal( n-ki+1, remax, vl( ki, is ), 1 )
956 CALL dscal( n-ki+1, remax, vl( ki, is+1 ), 1 )
964 CALL dgemv(
'N', n, n-ki-1, one, vl( 1, ki+2 ),
965 $ ldvl, work( ki+2+n ), 1, work( ki+n ),
967 CALL dgemv(
'N', n, n-ki-1, one, vl( 1, ki+2 ),
968 $ ldvl, work( ki+2+n2 ), 1,
969 $ work( ki+1+n2 ), vl( 1, ki+1 ), 1 )
971 CALL dscal( n, work( ki+n ), vl( 1, ki ), 1 )
972 CALL dscal( n, work( ki+1+n2 ), vl( 1, ki+1 ), 1 )
977 emax = max( emax, abs( vl( k, ki ) )+
978 $ abs( vl( k, ki+1 ) ) )
981 CALL dscal( n, remax, vl( 1, ki ), 1 )
982 CALL dscal( n, remax, vl( 1, ki+1 ), 1 )
subroutine daxpy(n, da, dx, incx, dy, incy)
subroutine dcopy(n, dx, incx, dy, incy)
subroutine dgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
subroutine dlabad(SMALL, LARGE)
subroutine dlaln2(LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B, LDB, WR, WI, X, LDX, SCALE, XNORM, INFO)
subroutine dscal(n, da, dx, incx)
subroutine dtrevc(SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, INFO)
subroutine xerbla(SRNAME, INFO)