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 ),
340 EXTERNAL lsame, slamch
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 )
470 ulp = slamch(
'Epsilon' )*slamch(
'Base' )
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 )
subroutine stgevc(SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL, LDVL, VR, LDVR, MM, M, WORK, INFO)
STGEVC
subroutine slabad(SMALL, LARGE)
SLABAD
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine sgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
SGEMV
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slaln2(LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B, LDB, WR, WI, X, LDX, SCALE, XNORM, INFO)
SLALN2 solves a 1-by-1 or 2-by-2 linear system of equations of the specified form.
subroutine slag2(A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1, WR2, WI)
SLAG2 computes the eigenvalues of a 2-by-2 generalized eigenvalue problem, with scaling as necessary ...