356 SUBROUTINE sdrgsx( NSIZE, NCMAX, THRESH, NIN, NOUT, A, LDA, B,
357 $ AI, BI, Z, Q, ALPHAR, ALPHAI, BETA, C, LDC, S,
358 $ WORK, LWORK, IWORK, LIWORK, BWORK, INFO )
365 INTEGER INFO, LDA, LDC, LIWORK, LWORK, NCMAX, NIN,
372 REAL A( LDA, * ), AI( LDA, * ), ALPHAI( * ),
373 $ alphar( * ), b( lda, * ), beta( * ),
374 $ bi( lda, * ), c( ldc, * ), q( lda, * ), s( * ),
375 $ work( * ), z( lda, * )
382 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0, ten = 1.0e+1 )
387 INTEGER BDSPAC, I, , IFUNC, IINFO, J, LINFO, MAXWRK,
388 $ minwrk, mm, mn2, nerrs, nptknt, ntest, ntestt,
390 REAL ABNRM, BIGNUM, DIFTRU, PLTRU, SMLNUM, TEMP1,
391 $ TEMP2, THRSH2, ULP, ULPINV, WEIGHT
394 REAL DIFEST( 2 ), PL( 2 ), RESULT( 10 )
400 EXTERNAL slctsx, ilaenv, slamch, slange
407 INTRINSIC abs,
max, sqrt
411 INTEGER K, M, MPLUSN, N
414 COMMON / mn / m, n, mplusn, k, fs
420 IF( nsize.LT.0 )
THEN
422 ELSE IF( thresh.LT.zero )
THEN
424 ELSE IF( nin.LE.0 )
THEN
426 ELSE IF( nout.LE.0 )
THEN
428 ELSE IF( lda.LT.1 .OR. lda.LT.nsize )
THEN
430 ELSE IF( ldc.LT.1 .OR. ldc.LT.nsize*nsize / 2 )
THEN
432 ELSE IF( liwork.LT.nsize+6 )
THEN
444 IF( info.EQ.0 .AND. lwork.GE.1 )
THEN
446 minwrk =
max( 10*( nsize+1 ), 5*nsize*nsize / 2 )
450 maxwrk = 9*( nsize+1 ) + nsize*
451 $ ilaenv( 1,
'SGEQRF',
' ', nsize, 1, nsize, 0 )
452 maxwrk =
max( maxwrk, 9*( nsize+1 )+nsize*
453 $ ilaenv( 1,
'SORGQR',
' ', nsize, 1, nsize, -1 ) )
457 bdspac = 5*nsize*nsize / 2
458 maxwrk =
max( maxwrk, 3*nsize*nsize / 2+nsize*nsize*
459 $ ilaenv( 1,
'SGEBRD',
' ', nsize*nsize / 2,
460 $ nsize*nsize / 2, -1, -1 ) )
461 maxwrk =
max( maxwrk, bdspac )
463 maxwrk =
max( maxwrk, minwrk )
468 IF( lwork.LT.minwrk )
472 CALL xerbla(
'SDRGSX', -info )
480 smlnum = slamch(
'S' ) / ulp
481 bignum = one / smlnum
482 CALL slabad( smlnum, bignum )
504 DO 40 m = 1, nsize - 1
505 DO 30 n = 1, nsize - m
507 weight = one / weight
515 CALL slaset(
'Full', mplusn, mplusn, zero, zero, ai,
517 CALL slaset(
'Full', mplusn, mplusn, zero, zero, bi,
520 CALL slatm5( prtype, m, n, ai, lda, ai( m+1, m+1 ),
521 $ lda, ai( 1, m+1 ), lda, bi, lda,
522 $ bi( m+1, m+1 ), lda, bi( 1, m+1 ), lda,
523 $ q, lda, z, lda, weight, qba, qbb )
530 IF( ifunc.EQ.0 )
THEN
532 ELSE IF( ifunc.EQ.1 )
THEN
534 ELSE IF( ifunc.EQ.2 )
THEN
536 ELSE IF( ifunc.EQ.3 )
THEN
540 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
541 CALL slacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
543 CALL sggesx(
'V',
'V',
'S', slctsx, sense, mplusn, ai,
544 $ lda, bi, lda, mm, alphar, alphai, beta,
545 $ q, lda, z, lda, pl, difest, work, lwork,
546 $ iwork, liwork, bwork, linfo )
548 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
550 WRITE( nout, fmt = 9999 )
'SGGESX', linfo, mplusn,
558 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, work,
560 CALL slacpy(
'Full', mplusn, mplusn, bi, lda,
561 $ work( mplusn*mplusn+1 ), mplusn )
562 abnrm = slange(
'Fro', mplusn, 2*mplusn, work, mplusn,
567 CALL sget51( 1, mplusn, a, lda, ai, lda, q, lda, z,
568 $ lda, work, result( 1 ) )
569 CALL sget51( 1, mplusn, b, lda, bi, lda, q, lda, z,
570 $ lda, work, result( 2 ) )
571 CALL sget51( 3, mplusn, b, lda, bi, lda, q, lda, q,
572 $ lda, work, result( 3 ) )
573 CALL sget51( 3, mplusn, b, lda, bi, lda, z, lda, z,
574 $ lda, work, result( 4 ) )
586 IF( alphai( j ).EQ.zero )
THEN
587 temp2 = ( abs( alphar( j )-ai( j, j ) ) /
588 $
max( smlnum, abs( alphar( j ) ),
589 $ abs( ai( j, j ) ) )+
590 $ abs( beta( j )-bi( j, j ) ) /
591 $
max( smlnum, abs( beta( j ) ),
592 $ abs( bi( j, j ) ) ) ) / ulp
593 IF( j.LT.mplusn )
THEN
594 IF( ai( j+1, j ).NE.zero )
THEN
600 IF( ai( j, j-1 ).NE.zero )
THEN
606 IF( alphai( j ).GT.zero )
THEN
611 IF( i1.LE.0 .OR. i1.GE.mplusn )
THEN
613 ELSE IF( i1.LT.mplusn-1 )
THEN
614 IF( ai( i1+2, i1+1 ).NE.zero )
THEN
618 ELSE IF( i1.GT.1 )
THEN
619 IF( ai( i1, i1-1 ).NE.zero )
THEN
624 IF( .NOT.ilabad )
THEN
625 CALL sget53( ai( i1, i1 ), lda, bi( i1, i1 ),
626 $ lda, beta( j ), alphar( j ),
627 $ alphai( j ), temp2, iinfo )
628 IF( iinfo.GE.3 )
THEN
629 WRITE( nout, fmt = 9997 )iinfo, j,
637 temp1 =
max( temp1, temp2 )
639 WRITE( nout, fmt = 9996 )j, mplusn, prtype
648 IF( linfo.EQ.mplusn+3 )
THEN
650 ELSE IF( mm.NE.n )
THEN
659 mn2 = mm*( mplusn-mm )*2
660 IF( ifunc.GE.2 .AND. mn2.LE.ncmax*ncmax )
THEN
665 CALL slakf2( mm, mplusn-mm, ai, lda,
666 $ ai( mm+1, mm+1 ), bi,
667 $ bi( mm+1, mm+1 ), c, ldc )
669 CALL sgesvd(
'N',
'N', mn2, mn2, c, ldc, s, work,
670 $ 1, work( 2 ), 1, work( 3 ), lwork-2,
674 IF( difest( 2 ).EQ.zero )
THEN
675 IF( diftru.GT.abnrm*ulp )
676 $ result( 8 ) = ulpinv
677 ELSE IF( diftru.EQ.zero )
THEN
678 IF( difest( 2 ).GT.abnrm*ulp )
679 $ result( 8 ) = ulpinv
680 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
681 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
682 result( 8 ) =
max( diftru / difest( 2 ),
683 $ difest( 2 ) / diftru )
691 IF( linfo.EQ.( mplusn+2 ) )
THEN
692 IF( diftru.GT.abnrm*ulp )
693 $ result( 9 ) = ulpinv
694 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
695 $ result( 9 ) = ulpinv
696 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
697 $ result( 9 ) = ulpinv
701 ntestt = ntestt + ntest
706 IF( result( j ).GE.thresh )
THEN
711 IF( nerrs.EQ.0 )
THEN
712 WRITE( nout, fmt = 9995 )
'SGX'
716 WRITE( nout, fmt = 9993 )
720 WRITE( nout, fmt = 9992 )
'orthogonal', '
''',
721 $ 'transpose
', ( '''', I = 1, 4 )
725.LT.
IF( RESULT( J )10000.0 ) THEN
726 WRITE( NOUT, FMT = 9991 )MPLUSN, PRTYPE,
727 $ WEIGHT, M, J, RESULT( J )
729 WRITE( NOUT, FMT = 9990 )MPLUSN, PRTYPE,
730 $ WEIGHT, M, J, RESULT( J )
750 READ( NIN, FMT = *, END = 140 )MPLUSN
753 READ( NIN, FMT = *, END = 140 )N
755 READ( NIN, FMT = * )( AI( I, J ), J = 1, MPLUSN )
758 READ( NIN, FMT = * )( BI( I, J ), J = 1, MPLUSN )
760 READ( NIN, FMT = * )PLTRU, DIFTRU
767 CALL SLACPY( 'full
', MPLUSN, MPLUSN, AI, LDA, A, LDA )
768 CALL SLACPY( 'full
', MPLUSN, MPLUSN, BI, LDA, B, LDA )
773 CALL SGGESX( 'v
', 'v
', 's
', SLCTSX, 'b
', MPLUSN, AI, LDA, BI, LDA,
774 $ MM, ALPHAR, ALPHAI, BETA, Q, LDA, Z, LDA, PL, DIFEST,
775 $ WORK, LWORK, IWORK, LIWORK, BWORK, LINFO )
777.NE..AND..NE.
IF( LINFO0 LINFOMPLUSN+2 ) THEN
779 WRITE( NOUT, FMT = 9998 )'sggesx', LINFO, MPLUSN, NPTKNT
786 CALL SLACPY( 'full
', MPLUSN, MPLUSN, AI, LDA, WORK, MPLUSN )
787 CALL SLACPY( 'full
', MPLUSN, MPLUSN, BI, LDA,
788 $ WORK( MPLUSN*MPLUSN+1 ), MPLUSN )
789 ABNRM = SLANGE( 'fro
', MPLUSN, 2*MPLUSN, WORK, MPLUSN, WORK )
793 CALL SGET51( 1, MPLUSN, A, LDA, AI, LDA, Q, LDA, Z, LDA, WORK,
795 CALL SGET51( 1, MPLUSN, B, LDA, BI, LDA, Q, LDA, Z, LDA, WORK,
797 CALL SGET51( 3, MPLUSN, B, LDA, BI, LDA, Q, LDA, Q, LDA, WORK,
799 CALL SGET51( 3, MPLUSN, B, LDA, BI, LDA, Z, LDA, Z, LDA, WORK,
812.EQ.
IF( ALPHAI( J )ZERO ) THEN
813 TEMP2 = ( ABS( ALPHAR( J )-AI( J, J ) ) /
814 $ MAX( SMLNUM, ABS( ALPHAR( J ) ), ABS( AI( J,
815 $ J ) ) )+ABS( BETA( J )-BI( J, J ) ) /
816 $ MAX( SMLNUM, ABS( BETA( J ) ), ABS( BI( J, J ) ) ) )
818.LT.
IF( JMPLUSN ) THEN
819.NE.
IF( AI( J+1, J )ZERO ) THEN
825.NE.
IF( AI( J, J-1 )ZERO ) THEN
831.GT.
IF( ALPHAI( J )ZERO ) THEN
836.LE..OR..GE.
IF( I10 I1MPLUSN ) THEN
838.LT.
ELSE IF( I1MPLUSN-1 ) THEN
839.NE.
IF( AI( I1+2, I1+1 )ZERO ) THEN
843.GT.
ELSE IF( I11 ) THEN
844.NE.
IF( AI( I1, I1-1 )ZERO ) THEN
849.NOT.
IF( ILABAD ) THEN
850 CALL SGET53( AI( I1, I1 ), LDA, BI( I1, I1 ), LDA,
851 $ BETA( J ), ALPHAR( J ), ALPHAI( J ), TEMP2,
853.GE.
IF( IINFO3 ) THEN
854 WRITE( NOUT, FMT = 9997 )IINFO, J, MPLUSN, NPTKNT
861 TEMP1 = MAX( TEMP1, TEMP2 )
863 WRITE( NOUT, FMT = 9996 )J, MPLUSN, NPTKNT
872.EQ.
IF( LINFOMPLUSN+3 )
873 $ RESULT( 7 ) = ULPINV
879.EQ.
IF( DIFEST( 2 )ZERO ) THEN
880.GT.
IF( DIFTRUABNRM*ULP )
881 $ RESULT( 8 ) = ULPINV
882.EQ.
ELSE IF( DIFTRUZERO ) THEN
883.GT.
IF( DIFEST( 2 )ABNRM*ULP )
884 $ RESULT( 8 ) = ULPINV
885.GT..OR.
ELSE IF( ( DIFTRUTHRSH2*DIFEST( 2 ) )
886.LT.
$ ( DIFTRU*THRSH2DIFEST( 2 ) ) ) THEN
887 RESULT( 8 ) = MAX( DIFTRU / DIFEST( 2 ), DIFEST( 2 ) / DIFTRU )
894.EQ.
IF( LINFO( MPLUSN+2 ) ) THEN
895.GT.
IF( DIFTRUABNRM*ULP )
896 $ RESULT( 9 ) = ULPINV
897.GT..AND..NE.
IF( ( IFUNC1 ) ( DIFEST( 2 )ZERO ) )
898 $ RESULT( 9 ) = ULPINV
899.EQ..AND..NE.
IF( ( IFUNC1 ) ( PL( 1 )ZERO ) )
900 $ RESULT( 9 ) = ULPINV
907.EQ.
IF( PL( 1 )ZERO ) THEN
908.GT.
IF( PLTRUABNRM*ULP )
909 $ RESULT( 10 ) = ULPINV
910.EQ.
ELSE IF( PLTRUZERO ) THEN
911.GT.
IF( PL( 1 )ABNRM*ULP )
912 $ RESULT( 10 ) = ULPINV
913.GT..OR.
ELSE IF( ( PLTRUTHRESH*PL( 1 ) )
914.LT.
$ ( PLTRU*THRESHPL( 1 ) ) ) THEN
915 RESULT( 10 ) = ULPINV
918 NTESTT = NTESTT + NTEST
923.GE.
IF( RESULT( J )THRESH ) THEN
928.EQ.
IF( NERRS0 ) THEN
929 WRITE( NOUT, FMT = 9995 )'sgx
'
933 WRITE( NOUT, FMT = 9994 )
937 WRITE( NOUT, FMT = 9992 )'orthogonal
', '''',
938 $ 'transpose
', ( '''', I = 1, 4 )
942.LT.
IF( RESULT( J )10000.0 ) THEN
943 WRITE( NOUT, FMT = 9989 )NPTKNT, MPLUSN, J, RESULT( J )
945 WRITE( NOUT, FMT = 9988 )NPTKNT, MPLUSN, J, RESULT( J )
959 CALL ALASVM( 'sgx
', NOUT, NERRS, NTESTT, 0 )
965 9999 FORMAT( ' sdrgsx:
', A, ' returned info=
', I6, '.
', / 9X, 'n=
',
966 $ I6, ', jtype=
', I6, ')
' )
968 9998 FORMAT( ' sdrgsx:
', A, ' returned info=
', I6, '.
', / 9X, 'n=
',
969 $ I6, ', input example
#', I2, ')' )
971 9997
FORMAT(
' SDRGSX: SGET53 returned INFO=', i1,
' for eigenvalue ',
972 $ i6,
'.', / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
974 9996
FORMAT(
' SDRGSX: S not in Schur form at eigenvalue ', i6,
'.',
975 $ / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
977 9995
FORMAT( / 1x, a3,
' -- Real Expert Generalized Schur form',
978 $
' problem driver' )
980 9994
FORMAT(
'Input Example' )
982 9993
FORMAT(
' Matrix types: ', /
983 $
' 1: A is a block diagonal matrix of Jordan blocks ',
984 $
'and B is the identity ', /
' matrix, ',
985 $ /
' 2: A and B are upper triangular matrices, ',
986 $ /
' 3: A and B are as type 2, but each second diagonal ',
987 $
'block in A_11 and ', /
988 $
' each third diaongal block in A_22 are 2x2 blocks,',
989 $ /
' 4: A and B are block diagonal matrices, ',
990 $ /
' 5: (A,B) has potentially close or common ',
991 $
'eigenvalues.', / )
993 9992
FORMAT( /
' Tests performed: (S is Schur, T is triangular, ',
994 $
'Q and Z are ', a,
',', / 19x,
995 $
' a is alpha, b is beta, and ', a,
' means ', a,
'.)',
996 $ /
' 1 = | A - Q S Z', a,
997 $
' | / ( |A| n ulp ) 2 = | B - Q T Z', a,
998 $
' | / ( |B| n ulp )', /
' 3 = | I - QQ', a,
999 $
' | / ( n ulp ) 4 = | I - ZZ', a,
1000 $
' | / ( n ulp )', /
' 5 = 1/ULP if A is not in ',
1001 $
'Schur form S', /
' 6 = difference between (alpha,beta)',
1002 $
' and diagonals of (S,T)', /
1003 $
' 7 = 1/ULP if SDIM is not the correct number of ',
1004 $
'selected eigenvalues', /
1005 $
' 8 = 1/ULP if DIFEST/DIFTRU > 10*THRESH or ',
1006 $
'DIFTRU/DIFEST > 10*THRESH',
1007 $ /
' 9 = 1/ULP if DIFEST <> 0 or DIFTRU > ULP*norm(A,B) ',
1008 $
'when reordering fails', /
1009 $
' 10 = 1/ULP if PLEST/PLTRU > THRESH or ',
1010 $
'PLTRU/PLEST > THRESH', /
1011 $
' ( Test 10 is only for input examples )', / )
1012 9991
FORMAT(
' Matrix order=', i2,
', type=', i2,
', a=', e10.3,
1013 $
', order(A_11)=', i2, ', result
', I2, ' is
', 0P, F8.2 )
1014 9990 FORMAT( ' matrix order=
', I2, ', type=
', I2, ', a=
', E10.3,
1015 $ ', order(a_11)=
', I2, ', result
', I2, ' is
', 0P, E10.3 )
1016 9989 FORMAT( ' input example
#', I2, ', matrix order=', I4, ',',
1017 $
' result ', i2,
' is', 0p, f8.2 )
1018 9988
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
1019 $
' result ', i2,
' is', 1p, e10.3 )