295 SUBROUTINE stgevc( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
296 $ ldvl, vr, ldvr, mm, m, work, info )
304 CHARACTER howmny, side
305 INTEGER info, ldp, lds, ldvl, ldvr, m, mm, n
309 REAL p( ldp, * ), s( lds, * ), vl( ldvl, * ),
310 $ vr( ldvr, * ), work( * )
317 REAL zero, one, safety
318 parameter( zero = 0.0e+0, one = 1.0e+0,
322 LOGICAL compl, compr, il2by2, ilabad, ilall, ilback,
323 $ ilbbad, ilcomp, ilcplx, lsa, lsb
324 INTEGER i, ibeg, ieig, iend, ihwmny, iinfo, im, iside,
325 $ j, ja, jc, je, jr, jw, na, nw
326 REAL acoef, acoefa, anorm, ascale, bcoefa, bcoefi,
327 $ bcoefr, big, bignum, bnorm, bscale, cim2a,
328 $ cim2b, cimaga, cimagb, cre2a, cre2b, creala,
329 $ crealb, dmin, safmin, salfar, sbeta, scale,
330 $ small, temp, temp2, temp2i, temp2r, ulp, xmax,
334 REAL bdiag( 2 ), sum( 2, 2 ), sums( 2, 2 ),
346 INTRINSIC abs, max, min
352 IF(
lsame( howmny,
'A' ) )
THEN
356 ELSE IF(
lsame( howmny,
'S' ) )
THEN
360 ELSE IF(
lsame( howmny,
'B' ) )
THEN
369 IF(
lsame( side,
'R' ) )
THEN
373 ELSE IF(
lsame( side,
'L' ) )
THEN
377 ELSE IF(
lsame( side,
'B' ) )
THEN
386 IF( iside.LT.0 )
THEN
388 ELSE IF( ihwmny.LT.0 )
THEN
390 ELSE IF( n.LT.0 )
THEN
392 ELSE IF( lds.LT.max( 1, n ) )
THEN
394 ELSE IF( ldp.LT.max( 1, n ) )
THEN
398 CALL
xerbla(
'STGEVC', -info )
404 IF( .NOT.ilall )
THEN
413 IF( s( j+1, j ).NE.zero )
417 IF(
SELECT( j ) .OR.
SELECT( j+1 ) )
433 IF( s( j+1, j ).NE.zero )
THEN
434 IF( p( j, j ).EQ.zero .OR. p( j+1, j+1 ).EQ.zero .OR.
435 $ p( j, j+1 ).NE.zero )ilbbad = .true.
437 IF( s( j+2, j+1 ).NE.zero )
445 ELSE IF( ilbbad )
THEN
447 ELSE IF( compl .AND. ldvl.LT.n .OR. ldvl.LT.1 )
THEN
449 ELSE IF( compr .AND. ldvr.LT.n .OR. ldvr.LT.1 )
THEN
451 ELSE IF( mm.LT.im )
THEN
455 CALL
xerbla(
'STGEVC', -info )
467 safmin =
slamch(
'Safe minimum' )
469 CALL
slabad( safmin, big )
471 small = safmin*n / ulp
473 bignum = one / ( safmin*n )
480 anorm = abs( s( 1, 1 ) )
482 $ anorm = anorm + abs( s( 2, 1 ) )
483 bnorm = abs( p( 1, 1 ) )
490 IF( s( j, j-1 ).EQ.zero )
THEN
496 temp = temp + abs( s( i, j ) )
497 temp2 = temp2 + abs( p( i, j ) )
501 DO 40 i = iend + 1, min( j+1, n )
502 temp = temp + abs( s( i, j ) )
503 temp2 = temp2 + abs( p( i, j ) )
505 anorm = max( anorm, temp )
506 bnorm = max( bnorm, temp2 )
509 ascale = one / max( anorm, safmin )
510 bscale = one / max( bnorm, safmin )
533 IF( s( je+1, je ).NE.zero )
THEN
540 ELSE IF( ilcplx )
THEN
541 ilcomp =
SELECT( je ) .OR.
SELECT( je+1 )
543 ilcomp =
SELECT( je )
551 IF( .NOT.ilcplx )
THEN
552 IF( abs( s( je, je ) ).LE.safmin .AND.
553 $ abs( p( je, je ) ).LE.safmin )
THEN
559 vl( jr, ieig ) = zero
561 vl( ieig, ieig ) = one
569 work( 2*n+jr ) = zero
576 IF( .NOT.ilcplx )
THEN
580 temp = one / max( abs( s( je, je ) )*ascale,
581 $ abs( p( je, je ) )*bscale, safmin )
582 salfar = ( temp*s( je, je ) )*ascale
583 sbeta = ( temp*p( je, je ) )*bscale
585 bcoefr = salfar*bscale
591 lsa = abs( sbeta ).GE.safmin .AND. abs( acoef ).LT.small
592 lsb = abs( salfar ).GE.safmin .AND. abs( bcoefr ).LT.
595 $ scale = ( small / abs( sbeta ) )*min( anorm, big )
597 $ scale = max( scale, ( small / abs( salfar ) )*
598 $ min( bnorm, big ) )
599 IF( lsa .OR. lsb )
THEN
600 scale = min( scale, one /
601 $ ( safmin*max( one, abs( acoef ),
602 $ abs( bcoefr ) ) ) )
604 acoef = ascale*( scale*sbeta )
609 bcoefr = bscale*( scale*salfar )
611 bcoefr = scale*bcoefr
614 acoefa = abs( acoef )
615 bcoefa = abs( bcoefr )
625 CALL
slag2( s( je, je ), lds, p( je, je ), ldp,
626 $ safmin*safety, acoef, temp, bcoefr, temp2,
629 IF( bcoefi.EQ.zero )
THEN
636 acoefa = abs( acoef )
637 bcoefa = abs( bcoefr ) + abs( bcoefi )
639 IF( acoefa*ulp.LT.safmin .AND. acoefa.GE.safmin )
640 $ scale = ( safmin / ulp ) / acoefa
641 IF( bcoefa*ulp.LT.safmin .AND. bcoefa.GE.safmin )
642 $ scale = max( scale, ( safmin / ulp ) / bcoefa )
643 IF( safmin*acoefa.GT.ascale )
644 $ scale = ascale / ( safmin*acoefa )
645 IF( safmin*bcoefa.GT.bscale )
646 $ scale = min( scale, bscale / ( safmin*bcoefa ) )
647 IF( scale.NE.one )
THEN
649 acoefa = abs( acoef )
650 bcoefr = scale*bcoefr
651 bcoefi = scale*bcoefi
652 bcoefa = abs( bcoefr ) + abs( bcoefi )
657 temp = acoef*s( je+1, je )
658 temp2r = acoef*s( je, je ) - bcoefr*p( je, je )
659 temp2i = -bcoefi*p( je, je )
660 IF( abs( temp ).GT.abs( temp2r )+abs( temp2i ) )
THEN
662 work( 3*n+je ) = zero
663 work( 2*n+je+1 ) = -temp2r / temp
664 work( 3*n+je+1 ) = -temp2i / temp
666 work( 2*n+je+1 ) = one
667 work( 3*n+je+1 ) = zero
668 temp = acoef*s( je, je+1 )
669 work( 2*n+je ) = ( bcoefr*p( je+1, je+1 )-acoef*
670 $ s( je+1, je+1 ) ) / temp
671 work( 3*n+je ) = bcoefi*p( je+1, je+1 ) / temp
673 xmax = max( abs( work( 2*n+je ) )+abs( work( 3*n+je ) ),
674 $ abs( work( 2*n+je+1 ) )+abs( work( 3*n+je+1 ) ) )
677 dmin = max( ulp*acoefa*anorm, ulp*bcoefa*bnorm, safmin )
687 DO 160 j = je + nw, n
694 bdiag( 1 ) = p( j, j )
696 IF( s( j+1, j ).NE.zero )
THEN
698 bdiag( 2 ) = p( j+1, j+1 )
705 xscale = one / max( one, xmax )
706 temp = max( work( j ), work( n+j ),
707 $ acoefa*work( j )+bcoefa*work( n+j ) )
709 $ temp = max( temp, work( j+1 ), work( n+j+1 ),
710 $ acoefa*work( j+1 )+bcoefa*work( n+j+1 ) )
711 IF( temp.GT.bignum*xscale )
THEN
714 work( ( jw+2 )*n+jr ) = xscale*
715 $ work( ( jw+2 )*n+jr )
739 sums( ja, jw ) = zero
740 sump( ja, jw ) = zero
742 DO 100 jr = je, j - 1
743 sums( ja, jw ) = sums( ja, jw ) +
745 $ work( ( jw+1 )*n+jr )
746 sump( ja, jw ) = sump( ja, jw ) +
748 $ work( ( jw+1 )*n+jr )
755 sum( ja, 1 ) = -acoef*sums( ja, 1 ) +
756 $ bcoefr*sump( ja, 1 ) -
757 $ bcoefi*sump( ja, 2 )
758 sum( ja, 2 ) = -acoef*sums( ja, 2 ) +
759 $ bcoefr*sump( ja, 2 ) +
760 $ bcoefi*sump( ja, 1 )
762 sum( ja, 1 ) = -acoef*sums( ja, 1 ) +
763 $ bcoefr*sump( ja, 1 )
771 CALL
slaln2( .true., na, nw, dmin, acoef, s( j, j ), lds,
772 $ bdiag( 1 ), bdiag( 2 ), sum, 2, bcoefr,
773 $ bcoefi, work( 2*n+j ), n, scale, temp,
775 IF( scale.LT.one )
THEN
776 DO 150 jw = 0, nw - 1
777 DO 140 jr = je, j - 1
778 work( ( jw+2 )*n+jr ) = scale*
779 $ work( ( jw+2 )*n+jr )
784 xmax = max( xmax, temp )
792 DO 170 jw = 0, nw - 1
793 CALL
sgemv(
'N', n, n+1-je, one, vl( 1, je ), ldvl,
794 $ work( ( jw+2 )*n+je ), 1, zero,
795 $ work( ( jw+4 )*n+1 ), 1 )
797 CALL
slacpy(
' ', n, nw, work( 4*n+1 ), n, vl( 1, je ),
801 CALL
slacpy(
' ', n, nw, work( 2*n+1 ), n, vl( 1, ieig ),
811 xmax = max( xmax, abs( vl( j, ieig ) )+
812 $ abs( vl( j, ieig+1 ) ) )
816 xmax = max( xmax, abs( vl( j, ieig ) ) )
820 IF( xmax.GT.safmin )
THEN
823 DO 210 jw = 0, nw - 1
825 vl( jr, ieig+jw ) = xscale*vl( jr, ieig+jw )
858 IF( s( je, je-1 ).NE.zero )
THEN
865 ELSE IF( ilcplx )
THEN
866 ilcomp =
SELECT( je ) .OR.
SELECT( je-1 )
868 ilcomp =
SELECT( je )
876 IF( .NOT.ilcplx )
THEN
877 IF( abs( s( je, je ) ).LE.safmin .AND.
878 $ abs( p( je, je ) ).LE.safmin )
THEN
884 vr( jr, ieig ) = zero
886 vr( ieig, ieig ) = one
893 DO 250 jw = 0, nw - 1
895 work( ( jw+2 )*n+jr ) = zero
903 IF( .NOT.ilcplx )
THEN
907 temp = one / max( abs( s( je, je ) )*ascale,
908 $ abs( p( je, je ) )*bscale, safmin )
909 salfar = ( temp*s( je, je ) )*ascale
910 sbeta = ( temp*p( je, je ) )*bscale
912 bcoefr = salfar*bscale
918 lsa = abs( sbeta ).GE.safmin .AND. abs( acoef ).LT.small
919 lsb = abs( salfar ).GE.safmin .AND. abs( bcoefr ).LT.
922 $ scale = ( small / abs( sbeta ) )*min( anorm, big )
924 $ scale = max( scale, ( small / abs( salfar ) )*
925 $ min( bnorm, big ) )
926 IF( lsa .OR. lsb )
THEN
927 scale = min( scale, one /
928 $ ( safmin*max( one, abs( acoef ),
929 $ abs( bcoefr ) ) ) )
931 acoef = ascale*( scale*sbeta )
936 bcoefr = bscale*( scale*salfar )
938 bcoefr = scale*bcoefr
941 acoefa = abs( acoef )
942 bcoefa = abs( bcoefr )
952 DO 260 jr = 1, je - 1
953 work( 2*n+jr ) = bcoefr*p( jr, je ) -
960 CALL
slag2( s( je-1, je-1 ), lds, p( je-1, je-1 ), ldp,
961 $ safmin*safety, acoef, temp, bcoefr, temp2,
963 IF( bcoefi.EQ.zero )
THEN
970 acoefa = abs( acoef )
971 bcoefa = abs( bcoefr ) + abs( bcoefi )
973 IF( acoefa*ulp.LT.safmin .AND. acoefa.GE.safmin )
974 $ scale = ( safmin / ulp ) / acoefa
975 IF( bcoefa*ulp.LT.safmin .AND. bcoefa.GE.safmin )
976 $ scale = max( scale, ( safmin / ulp ) / bcoefa )
977 IF( safmin*acoefa.GT.ascale )
978 $ scale = ascale / ( safmin*acoefa )
979 IF( safmin*bcoefa.GT.bscale )
980 $ scale = min( scale, bscale / ( safmin*bcoefa ) )
981 IF( scale.NE.one )
THEN
983 acoefa = abs( acoef )
984 bcoefr = scale*bcoefr
985 bcoefi = scale*bcoefi
986 bcoefa = abs( bcoefr ) + abs( bcoefi )
992 temp = acoef*s( je, je-1 )
993 temp2r = acoef*s( je, je ) - bcoefr*p( je, je )
994 temp2i = -bcoefi*p( je, je )
995 IF( abs( temp ).GE.abs( temp2r )+abs( temp2i ) )
THEN
997 work( 3*n+je ) = zero
998 work( 2*n+je-1 ) = -temp2r / temp
999 work( 3*n+je-1 ) = -temp2i / temp
1001 work( 2*n+je-1 ) = one
1002 work( 3*n+je-1 ) = zero
1003 temp = acoef*s( je-1, je )
1004 work( 2*n+je ) = ( bcoefr*p( je-1, je-1 )-acoef*
1005 $ s( je-1, je-1 ) ) / temp
1006 work( 3*n+je ) = bcoefi*p( je-1, je-1 ) / temp
1009 xmax = max( abs( work( 2*n+je ) )+abs( work( 3*n+je ) ),
1010 $ abs( work( 2*n+je-1 ) )+abs( work( 3*n+je-1 ) ) )
1015 creala = acoef*work( 2*n+je-1 )
1016 cimaga = acoef*work( 3*n+je-1 )
1017 crealb = bcoefr*work( 2*n+je-1 ) -
1018 $ bcoefi*work( 3*n+je-1 )
1019 cimagb = bcoefi*work( 2*n+je-1 ) +
1020 $ bcoefr*work( 3*n+je-1 )
1021 cre2a = acoef*work( 2*n+je )
1022 cim2a = acoef*work( 3*n+je )
1023 cre2b = bcoefr*work( 2*n+je ) - bcoefi*work( 3*n+je )
1024 cim2b = bcoefi*work( 2*n+je ) + bcoefr*work( 3*n+je )
1025 DO 270 jr = 1, je - 2
1026 work( 2*n+jr ) = -creala*s( jr, je-1 ) +
1027 $ crealb*p( jr, je-1 ) -
1028 $ cre2a*s( jr, je ) + cre2b*p( jr, je )
1029 work( 3*n+jr ) = -cimaga*s( jr, je-1 ) +
1030 $ cimagb*p( jr, je-1 ) -
1031 $ cim2a*s( jr, je ) + cim2b*p( jr, je )
1035 dmin = max( ulp*acoefa*anorm, ulp*bcoefa*bnorm, safmin )
1040 DO 370 j = je - nw, 1, -1
1045 IF( .NOT.il2by2 .AND. j.GT.1 )
THEN
1046 IF( s( j, j-1 ).NE.zero )
THEN
1051 bdiag( 1 ) = p( j, j )
1054 bdiag( 2 ) = p( j+1, j+1 )
1061 CALL
slaln2( .false., na, nw, dmin, acoef, s( j, j ),
1062 $ lds, bdiag( 1 ), bdiag( 2 ), work( 2*n+j ),
1063 $ n, bcoefr, bcoefi, sum, 2, scale, temp,
1065 IF( scale.LT.one )
THEN
1067 DO 290 jw = 0, nw - 1
1069 work( ( jw+2 )*n+jr ) = scale*
1070 $ work( ( jw+2 )*n+jr )
1074 xmax = max( scale*xmax, temp )
1078 work( ( jw+1 )*n+j+ja-1 ) = sum( ja, jw )
1088 xscale = one / max( one, xmax )
1089 temp = acoefa*work( j ) + bcoefa*work( n+j )
1091 $ temp = max( temp, acoefa*work( j+1 )+bcoefa*
1093 temp = max( temp, acoefa, bcoefa )
1094 IF( temp.GT.bignum*xscale )
THEN
1096 DO 330 jw = 0, nw - 1
1098 work( ( jw+2 )*n+jr ) = xscale*
1099 $ work( ( jw+2 )*n+jr )
1112 creala = acoef*work( 2*n+j+ja-1 )
1113 cimaga = acoef*work( 3*n+j+ja-1 )
1114 crealb = bcoefr*work( 2*n+j+ja-1 ) -
1115 $ bcoefi*work( 3*n+j+ja-1 )
1116 cimagb = bcoefi*work( 2*n+j+ja-1 ) +
1117 $ bcoefr*work( 3*n+j+ja-1 )
1118 DO 340 jr = 1, j - 1
1119 work( 2*n+jr ) = work( 2*n+jr ) -
1120 $ creala*s( jr, j+ja-1 ) +
1121 $ crealb*p( jr, j+ja-1 )
1122 work( 3*n+jr ) = work( 3*n+jr ) -
1123 $ cimaga*s( jr, j+ja-1 ) +
1124 $ cimagb*p( jr, j+ja-1 )
1127 creala = acoef*work( 2*n+j+ja-1 )
1128 crealb = bcoefr*work( 2*n+j+ja-1 )
1129 DO 350 jr = 1, j - 1
1130 work( 2*n+jr ) = work( 2*n+jr ) -
1131 $ creala*s( jr, j+ja-1 ) +
1132 $ crealb*p( jr, j+ja-1 )
1147 DO 410 jw = 0, nw - 1
1149 work( ( jw+4 )*n+jr ) = work( ( jw+2 )*n+1 )*
1159 work( ( jw+4 )*n+jr ) = work( ( jw+4 )*n+jr ) +
1160 $ work( ( jw+2 )*n+jc )*vr( jr, jc )
1165 DO 430 jw = 0, nw - 1
1167 vr( jr, ieig+jw ) = work( ( jw+4 )*n+jr )
1173 DO 450 jw = 0, nw - 1
1175 vr( jr, ieig+jw ) = work( ( jw+2 )*n+jr )
1187 xmax = max( xmax, abs( vr( j, ieig ) )+
1188 $ abs( vr( j, ieig+1 ) ) )
1192 xmax = max( xmax, abs( vr( j, ieig ) ) )
1196 IF( xmax.GT.safmin )
THEN
1198 DO 490 jw = 0, nw - 1
1200 vr( jr, ieig+jw ) = xscale*vr( jr, ieig+jw )