291 SUBROUTINE stgevc( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
292 $ LDVL, VR, LDVR, MM, M, WORK, INFO )
299 CHARACTER HOWMNY, SIDE
300 INTEGER INFO, LDP, LDS, LDVL, LDVR, M, MM, N
304 REAL P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
305 $ vr( ldvr, * ), work( * )
312 REAL ZERO, ONE, SAFETY
313 parameter( zero = 0.0e+0, one = 1.0e+0,
317 LOGICAL COMPL, COMPR, IL2BY2, ILABAD, ILALL, ILBACK,
318 $ ilbbad, ilcomp, ilcplx, lsa, lsb
319 INTEGER I, IBEG, IEIG, IEND, IHWMNY, IINFO, IM, ISIDE,
320 $ j, ja, jc, je, jr, jw, na, nw
321 REAL ACOEF, ACOEFA, ANORM, ASCALE, BCOEFA, BCOEFI,
322 $ bcoefr, big, bignum, bnorm, bscale, cim2a,
323 $ cim2b, cimaga, cimagb, cre2a, cre2b, creala,
324 $ crealb, dmin, safmin, salfar, sbeta, scale,
325 $ small, temp, temp2, temp2i, temp2r, ulp, xmax,
329 REAL BDIAG( 2 ), SUM( 2, 2 ), SUMS( 2, 2 ),
335 EXTERNAL lsame, slamch
342 INTRINSIC abs, max, min
348 IF( lsame( howmny,
'A' ) )
THEN
352 ELSE IF( lsame( howmny,
'S' ) )
THEN
356 ELSE IF( lsame( howmny,
'B' ) )
THEN
365 IF( lsame( side,
'R' ) )
THEN
369 ELSE IF( lsame( side,
'L' ) )
THEN
373 ELSE IF( lsame( side,
'B' ) )
THEN
382 IF( iside.LT.0 )
THEN
384 ELSE IF( ihwmny.LT.0 )
THEN
386 ELSE IF( n.LT.0 )
THEN
388 ELSE IF( lds.LT.max( 1, n ) )
THEN
390 ELSE IF( ldp.LT.max( 1, n ) )
THEN
394 CALL xerbla(
'STGEVC', -info )
400 IF( .NOT.ilall )
THEN
409 IF( s( j+1, j ).NE.zero )
413 IF(
SELECT( j ) .OR.
SELECT( j+1 ) )
429 IF( s( j+1, j ).NE.zero )
THEN
430 IF( p( j, j ).EQ.zero .OR. p( j+1, j+1 ).EQ.zero .OR.
431 $ p( j, j+1 ).NE.zero )ilbbad = .true.
433 IF( s( j+2, j+1 ).NE.zero )
441 ELSE IF( ilbbad )
THEN
443 ELSE IF( compl .AND. ldvl.LT.n .OR. ldvl.LT.1 )
THEN
445 ELSE IF( compr .AND. ldvr.LT.n .OR. ldvr.LT.1 )
THEN
447 ELSE IF( mm.LT.im )
THEN
451 CALL xerbla(
'STGEVC', -info )
463 safmin = slamch(
'Safe minimum' )
465 ulp = slamch(
'Epsilon' )*slamch(
'Base' )
466 small = safmin*real( n ) / ulp
468 bignum = one / ( safmin*real( n ) )
475 anorm = abs( s( 1, 1 ) )
477 $ anorm = anorm + abs( s( 2, 1 ) )
478 bnorm = abs( p( 1, 1 ) )
485 IF( s( j, j-1 ).EQ.zero )
THEN
491 temp = temp + abs( s( i, j ) )
492 temp2 = temp2 + abs( p( i, j ) )
496 DO 40 i = iend + 1, min( j+1, n )
497 temp = temp + abs( s( i, j ) )
498 temp2 = temp2 + abs( p( i, j ) )
500 anorm = max( anorm, temp )
501 bnorm = max( bnorm, temp2 )
504 ascale = one / max( anorm, safmin )
505 bscale = one / max( bnorm, safmin )
528 IF( s( je+1, je ).NE.zero )
THEN
535 ELSE IF( ilcplx )
THEN
536 ilcomp =
SELECT( je ) .OR.
SELECT( je+1 )
538 ilcomp =
SELECT( je )
546 IF( .NOT.ilcplx )
THEN
547 IF( abs( s( je, je ) ).LE.safmin .AND.
548 $ abs( p( je, je ) ).LE.safmin )
THEN
554 vl( jr, ieig ) = zero
556 vl( ieig, ieig ) = one
564 work( 2*n+jr ) = zero
571 IF( .NOT.ilcplx )
THEN
575 temp = one / max( abs( s( je, je ) )*ascale,
576 $ abs( p( je, je ) )*bscale, safmin )
577 salfar = ( temp*s( je, je ) )*ascale
578 sbeta = ( temp*p( je, je ) )*bscale
580 bcoefr = salfar*bscale
586 lsa = abs( sbeta ).GE.safmin .AND. abs( acoef ).LT.small
587 lsb = abs( salfar ).GE.safmin .AND. abs( bcoefr ).LT.
590 $ scale = ( small / abs( sbeta ) )*min( anorm, big )
592 $ scale = max( scale, ( small / abs( salfar ) )*
593 $ min( bnorm, big ) )
594 IF( lsa .OR. lsb )
THEN
595 scale = min( scale, one /
596 $ ( safmin*max( one, abs( acoef ),
597 $ abs( bcoefr ) ) ) )
599 acoef = ascale*( scale*sbeta )
604 bcoefr = bscale*( scale*salfar )
606 bcoefr = scale*bcoefr
609 acoefa = abs( acoef )
610 bcoefa = abs( bcoefr )
620 CALL slag2( s( je, je ), lds, p( je, je ), ldp,
621 $ safmin*safety, acoef, temp, bcoefr, temp2,
624 IF( bcoefi.EQ.zero )
THEN
631 acoefa = abs( acoef )
632 bcoefa = abs( bcoefr ) + abs( bcoefi )
634 IF( acoefa*ulp.LT.safmin .AND. acoefa.GE.safmin )
635 $ scale = ( safmin / ulp ) / acoefa
636 IF( bcoefa*ulp.LT.safmin .AND. bcoefa.GE.safmin )
637 $ scale = max( scale, ( safmin / ulp ) / bcoefa )
638 IF( safmin*acoefa.GT.ascale )
639 $ scale = ascale / ( safmin*acoefa )
640 IF( safmin*bcoefa.GT.bscale )
641 $ scale = min( scale, bscale / ( safmin*bcoefa ) )
642 IF( scale.NE.one )
THEN
644 acoefa = abs( acoef )
645 bcoefr = scale*bcoefr
646 bcoefi = scale*bcoefi
647 bcoefa = abs( bcoefr ) + abs( bcoefi )
652 temp = acoef*s( je+1, je )
653 temp2r = acoef*s( je, je ) - bcoefr*p( je, je )
654 temp2i = -bcoefi*p( je, je )
655 IF( abs( temp ).GT.abs( temp2r )+abs( temp2i ) )
THEN
657 work( 3*n+je ) = zero
658 work( 2*n+je+1 ) = -temp2r / temp
659 work( 3*n+je+1 ) = -temp2i / temp
661 work( 2*n+je+1 ) = one
662 work( 3*n+je+1 ) = zero
663 temp = acoef*s( je, je+1 )
664 work( 2*n+je ) = ( bcoefr*p( je+1, je+1 )-acoef*
665 $ s( je+1, je+1 ) ) / temp
666 work( 3*n+je ) = bcoefi*p( je+1, je+1 ) / temp
668 xmax = max( abs( work( 2*n+je ) )+abs( work( 3*n+je ) ),
669 $ abs( work( 2*n+je+1 ) )+abs( work( 3*n+je+1 ) ) )
672 dmin = max( ulp*acoefa*anorm, ulp*bcoefa*bnorm, safmin )
682 DO 160 j = je + nw, n
689 bdiag( 1 ) = p( j, j )
691 IF( s( j+1, j ).NE.zero )
THEN
693 bdiag( 2 ) = p( j+1, j+1 )
700 xscale = one / max( one, xmax )
701 temp = max( work( j ), work( n+j ),
702 $ acoefa*work( j )+bcoefa*work( n+j ) )
704 $ temp = max( temp, work( j+1 ), work( n+j+1 ),
705 $ acoefa*work( j+1 )+bcoefa*work( n+j+1 ) )
706 IF( temp.GT.bignum*xscale )
THEN
709 work( ( jw+2 )*n+jr ) = xscale*
710 $ work( ( jw+2 )*n+jr )
734 sums( ja, jw ) = zero
735 sump( ja, jw ) = zero
737 DO 100 jr = je, j - 1
738 sums( ja, jw ) = sums( ja, jw ) +
740 $ work( ( jw+1 )*n+jr )
741 sump( ja, jw ) = sump( ja, jw ) +
743 $ work( ( jw+1 )*n+jr )
750 sum( ja, 1 ) = -acoef*sums( ja, 1 ) +
751 $ bcoefr*sump( ja, 1 ) -
752 $ bcoefi*sump( ja, 2 )
753 sum( ja, 2 ) = -acoef*sums( ja, 2 ) +
754 $ bcoefr*sump( ja, 2 ) +
755 $ bcoefi*sump( ja, 1 )
757 sum( ja, 1 ) = -acoef*sums( ja, 1 ) +
758 $ bcoefr*sump( ja, 1 )
766 CALL slaln2( .true., na, nw, dmin, acoef, s( j, j ),
768 $ bdiag( 1 ), bdiag( 2 ), sum, 2, bcoefr,
769 $ bcoefi, work( 2*n+j ), n, scale, temp,
771 IF( scale.LT.one )
THEN
772 DO 150 jw = 0, nw - 1
773 DO 140 jr = je, j - 1
774 work( ( jw+2 )*n+jr ) = scale*
775 $ work( ( jw+2 )*n+jr )
780 xmax = max( xmax, temp )
788 DO 170 jw = 0, nw - 1
789 CALL sgemv(
'N', n, n+1-je, one, vl( 1, je ), ldvl,
790 $ work( ( jw+2 )*n+je ), 1, zero,
791 $ work( ( jw+4 )*n+1 ), 1 )
793 CALL slacpy(
' ', n, nw, work( 4*n+1 ), n, vl( 1,
798 CALL slacpy(
' ', n, nw, work( 2*n+1 ), n, vl( 1,
809 xmax = max( xmax, abs( vl( j, ieig ) )+
810 $ abs( vl( j, ieig+1 ) ) )
814 xmax = max( xmax, abs( vl( j, ieig ) ) )
818 IF( xmax.GT.safmin )
THEN
821 DO 210 jw = 0, nw - 1
823 vl( jr, ieig+jw ) = xscale*vl( jr, ieig+jw )
856 IF( s( je, je-1 ).NE.zero )
THEN
863 ELSE IF( ilcplx )
THEN
864 ilcomp =
SELECT( je ) .OR.
SELECT( je-1 )
866 ilcomp =
SELECT( je )
874 IF( .NOT.ilcplx )
THEN
875 IF( abs( s( je, je ) ).LE.safmin .AND.
876 $ abs( p( je, je ) ).LE.safmin )
THEN
882 vr( jr, ieig ) = zero
884 vr( ieig, ieig ) = one
891 DO 250 jw = 0, nw - 1
893 work( ( jw+2 )*n+jr ) = zero
901 IF( .NOT.ilcplx )
THEN
905 temp = one / max( abs( s( je, je ) )*ascale,
906 $ abs( p( je, je ) )*bscale, safmin )
907 salfar = ( temp*s( je, je ) )*ascale
908 sbeta = ( temp*p( je, je ) )*bscale
910 bcoefr = salfar*bscale
916 lsa = abs( sbeta ).GE.safmin .AND. abs( acoef ).LT.small
917 lsb = abs( salfar ).GE.safmin .AND. abs( bcoefr ).LT.
920 $ scale = ( small / abs( sbeta ) )*min( anorm, big )
922 $ scale = max( scale, ( small / abs( salfar ) )*
923 $ min( bnorm, big ) )
924 IF( lsa .OR. lsb )
THEN
925 scale = min( scale, one /
926 $ ( safmin*max( one, abs( acoef ),
927 $ abs( bcoefr ) ) ) )
929 acoef = ascale*( scale*sbeta )
934 bcoefr = bscale*( scale*salfar )
936 bcoefr = scale*bcoefr
939 acoefa = abs( acoef )
940 bcoefa = abs( bcoefr )
950 DO 260 jr = 1, je - 1
951 work( 2*n+jr ) = bcoefr*p( jr, je ) -
958 CALL slag2( s( je-1, je-1 ), lds, p( je-1, je-1 ),
960 $ safmin*safety, acoef, temp, bcoefr, temp2,
962 IF( bcoefi.EQ.zero )
THEN
969 acoefa = abs( acoef )
970 bcoefa = abs( bcoefr ) + abs( bcoefi )
972 IF( acoefa*ulp.LT.safmin .AND. acoefa.GE.safmin )
973 $ scale = ( safmin / ulp ) / acoefa
974 IF( bcoefa*ulp.LT.safmin .AND. bcoefa.GE.safmin )
975 $ scale = max( scale, ( safmin / ulp ) / bcoefa )
976 IF( safmin*acoefa.GT.ascale )
977 $ scale = ascale / ( safmin*acoefa )
978 IF( safmin*bcoefa.GT.bscale )
979 $ scale = min( scale, bscale / ( safmin*bcoefa ) )
980 IF( scale.NE.one )
THEN
982 acoefa = abs( acoef )
983 bcoefr = scale*bcoefr
984 bcoefi = scale*bcoefi
985 bcoefa = abs( bcoefr ) + abs( bcoefi )
991 temp = acoef*s( je, je-1 )
992 temp2r = acoef*s( je, je ) - bcoefr*p( je, je )
993 temp2i = -bcoefi*p( je, je )
994 IF( abs( temp ).GE.abs( temp2r )+abs( temp2i ) )
THEN
996 work( 3*n+je ) = zero
997 work( 2*n+je-1 ) = -temp2r / temp
998 work( 3*n+je-1 ) = -temp2i / temp
1000 work( 2*n+je-1 ) = one
1001 work( 3*n+je-1 ) = zero
1002 temp = acoef*s( je-1, je )
1003 work( 2*n+je ) = ( bcoefr*p( je-1, je-1 )-acoef*
1004 $ s( je-1, je-1 ) ) / temp
1005 work( 3*n+je ) = bcoefi*p( je-1, je-1 ) / temp
1008 xmax = max( abs( work( 2*n+je ) )+abs( work( 3*n+je ) ),
1009 $ abs( work( 2*n+je-1 ) )+abs( work( 3*n+je-1 ) ) )
1014 creala = acoef*work( 2*n+je-1 )
1015 cimaga = acoef*work( 3*n+je-1 )
1016 crealb = bcoefr*work( 2*n+je-1 ) -
1017 $ bcoefi*work( 3*n+je-1 )
1018 cimagb = bcoefi*work( 2*n+je-1 ) +
1019 $ bcoefr*work( 3*n+je-1 )
1020 cre2a = acoef*work( 2*n+je )
1021 cim2a = acoef*work( 3*n+je )
1022 cre2b = bcoefr*work( 2*n+je ) - bcoefi*work( 3*n+je )
1023 cim2b = bcoefi*work( 2*n+je ) + bcoefr*work( 3*n+je )
1024 DO 270 jr = 1, je - 2
1025 work( 2*n+jr ) = -creala*s( jr, je-1 ) +
1026 $ crealb*p( jr, je-1 ) -
1027 $ cre2a*s( jr, je ) + cre2b*p( jr, je )
1028 work( 3*n+jr ) = -cimaga*s( jr, je-1 ) +
1029 $ cimagb*p( jr, je-1 ) -
1030 $ cim2a*s( jr, je ) + cim2b*p( jr, je )
1034 dmin = max( ulp*acoefa*anorm, ulp*bcoefa*bnorm, safmin )
1039 DO 370 j = je - nw, 1, -1
1044 IF( .NOT.il2by2 .AND. j.GT.1 )
THEN
1045 IF( s( j, j-1 ).NE.zero )
THEN
1050 bdiag( 1 ) = p( j, j )
1053 bdiag( 2 ) = p( j+1, j+1 )
1060 CALL slaln2( .false., na, nw, dmin, acoef, s( j, j ),
1061 $ lds, bdiag( 1 ), bdiag( 2 ), work( 2*n+j ),
1062 $ n, bcoefr, bcoefi, sum, 2, scale, temp,
1064 IF( scale.LT.one )
THEN
1066 DO 290 jw = 0, nw - 1
1068 work( ( jw+2 )*n+jr ) = scale*
1069 $ work( ( jw+2 )*n+jr )
1073 xmax = max( scale*xmax, temp )
1077 work( ( jw+1 )*n+j+ja-1 ) = sum( ja, jw )
1087 xscale = one / max( one, xmax )
1088 temp = acoefa*work( j ) + bcoefa*work( n+j )
1090 $ temp = max( temp, acoefa*work( j+1 )+bcoefa*
1092 temp = max( temp, acoefa, bcoefa )
1093 IF( temp.GT.bignum*xscale )
THEN
1095 DO 330 jw = 0, nw - 1
1097 work( ( jw+2 )*n+jr ) = xscale*
1098 $ work( ( jw+2 )*n+jr )
1111 creala = acoef*work( 2*n+j+ja-1 )
1112 cimaga = acoef*work( 3*n+j+ja-1 )
1113 crealb = bcoefr*work( 2*n+j+ja-1 ) -
1114 $ bcoefi*work( 3*n+j+ja-1 )
1115 cimagb = bcoefi*work( 2*n+j+ja-1 ) +
1116 $ bcoefr*work( 3*n+j+ja-1 )
1117 DO 340 jr = 1, j - 1
1118 work( 2*n+jr ) = work( 2*n+jr ) -
1119 $ creala*s( jr, j+ja-1 ) +
1120 $ crealb*p( jr, j+ja-1 )
1121 work( 3*n+jr ) = work( 3*n+jr ) -
1122 $ cimaga*s( jr, j+ja-1 ) +
1123 $ cimagb*p( jr, j+ja-1 )
1126 creala = acoef*work( 2*n+j+ja-1 )
1127 crealb = bcoefr*work( 2*n+j+ja-1 )
1128 DO 350 jr = 1, j - 1
1129 work( 2*n+jr ) = work( 2*n+jr ) -
1130 $ creala*s( jr, j+ja-1 ) +
1131 $ crealb*p( jr, j+ja-1 )
1146 DO 410 jw = 0, nw - 1
1148 work( ( jw+4 )*n+jr ) = work( ( jw+2 )*n+1 )*
1158 work( ( jw+4 )*n+jr ) = work( ( jw+4 )*n+jr ) +
1159 $ work( ( jw+2 )*n+jc )*vr( jr, jc )
1164 DO 430 jw = 0, nw - 1
1166 vr( jr, ieig+jw ) = work( ( jw+4 )*n+jr )
1172 DO 450 jw = 0, nw - 1
1174 vr( jr, ieig+jw ) = work( ( jw+2 )*n+jr )
1186 xmax = max( xmax, abs( vr( j, ieig ) )+
1187 $ abs( vr( j, ieig+1 ) ) )
1191 xmax = max( xmax, abs( vr( j, ieig ) ) )
1195 IF( xmax.GT.safmin )
THEN
1197 DO 490 jw = 0, nw - 1
1199 vr( jr, ieig+jw ) = xscale*vr( jr, ieig+jw )