358 SUBROUTINE sdrgsx( NSIZE, NCMAX, THRESH, NIN, NOUT, A, LDA, B,
359 $ ai, bi, z, q, alphar, alphai, beta, c, ldc, s,
360 $ work, lwork, iwork, liwork, bwork, info )
368 INTEGER INFO, LDA, LDC, LIWORK, LWORK, NCMAX, NIN,
375 REAL A( lda, * ), AI( lda, * ), ALPHAI( * ),
376 $ alphar( * ), b( lda, * ), beta( * ),
377 $ bi( lda, * ), c( ldc, * ), q( lda, * ), s( * ),
378 $ work( * ), z( lda, * )
385 parameter ( zero = 0.0e+0, one = 1.0e+0, ten = 1.0e+1 )
390 INTEGER BDSPAC, I, I1, IFUNC, IINFO, J, LINFO, MAXWRK,
391 $ minwrk, mm, mn2, nerrs, nptknt, ntest, ntestt,
393 REAL ABNRM, BIGNUM, DIFTRU, PLTRU, SMLNUM, TEMP1,
394 $ temp2, thrsh2, ulp, ulpinv, weight
397 REAL DIFEST( 2 ), PL( 2 ), RESULT( 10 )
403 EXTERNAL slctsx, ilaenv, slamch, slange
410 INTRINSIC abs, max, sqrt
414 INTEGER K, M, MPLUSN, N
417 COMMON / mn / m, n, mplusn, k, fs
423 IF( nsize.LT.0 )
THEN
425 ELSE IF( thresh.LT.zero )
THEN
427 ELSE IF( nin.LE.0 )
THEN
429 ELSE IF( nout.LE.0 )
THEN
431 ELSE IF( lda.LT.1 .OR. lda.LT.nsize )
THEN
433 ELSE IF( ldc.LT.1 .OR. ldc.LT.nsize*nsize / 2 )
THEN
435 ELSE IF( liwork.LT.nsize+6 )
THEN
447 IF( info.EQ.0 .AND. lwork.GE.1 )
THEN
449 minwrk = max( 10*( nsize+1 ), 5*nsize*nsize / 2 )
453 maxwrk = 9*( nsize+1 ) + nsize*
454 $ ilaenv( 1,
'SGEQRF',
' ', nsize, 1, nsize, 0 )
455 maxwrk = max( maxwrk, 9*( nsize+1 )+nsize*
456 $ ilaenv( 1,
'SORGQR',
' ', nsize, 1, nsize, -1 ) )
460 bdspac = 5*nsize*nsize / 2
461 maxwrk = max( maxwrk, 3*nsize*nsize / 2+nsize*nsize*
462 $ ilaenv( 1,
'SGEBRD',
' ', nsize*nsize / 2,
463 $ nsize*nsize / 2, -1, -1 ) )
464 maxwrk = max( maxwrk, bdspac )
466 maxwrk = max( maxwrk, minwrk )
471 IF( lwork.LT.minwrk )
475 CALL xerbla(
'SDRGSX', -info )
483 smlnum = slamch(
'S' ) / ulp
484 bignum = one / smlnum
485 CALL slabad( smlnum, bignum )
507 DO 40 m = 1, nsize - 1
508 DO 30 n = 1, nsize - m
510 weight = one / weight
518 CALL slaset(
'Full', mplusn, mplusn, zero, zero, ai,
520 CALL slaset(
'Full', mplusn, mplusn, zero, zero, bi,
523 CALL slatm5( prtype, m, n, ai, lda, ai( m+1, m+1 ),
524 $ lda, ai( 1, m+1 ), lda, bi, lda,
525 $ bi( m+1, m+1 ), lda, bi( 1, m+1 ), lda,
526 $ q, lda, z, lda, weight, qba, qbb )
533 IF( ifunc.EQ.0 )
THEN
535 ELSE IF( ifunc.EQ.1 )
THEN
537 ELSE IF( ifunc.EQ.2 )
THEN
539 ELSE IF( ifunc.EQ.3 )
THEN
543 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
544 CALL slacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
546 CALL sggesx(
'V',
'V',
'S', slctsx, sense, mplusn, ai,
547 $ lda, bi, lda, mm, alphar, alphai, beta,
548 $ q, lda, z, lda, pl, difest, work, lwork,
549 $ iwork, liwork, bwork, linfo )
551 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
553 WRITE( nout, fmt = 9999 )
'SGGESX', linfo, mplusn,
561 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, work,
563 CALL slacpy(
'Full', mplusn, mplusn, bi, lda,
564 $ work( mplusn*mplusn+1 ), mplusn )
565 abnrm = slange(
'Fro', mplusn, 2*mplusn, work, mplusn,
570 CALL sget51( 1, mplusn, a, lda, ai, lda, q, lda, z,
571 $ lda, work, result( 1 ) )
572 CALL sget51( 1, mplusn, b, lda, bi, lda, q, lda, z,
573 $ lda, work, result( 2 ) )
574 CALL sget51( 3, mplusn, b, lda, bi, lda, q, lda, q,
575 $ lda, work, result( 3 ) )
576 CALL sget51( 3, mplusn, b, lda, bi, lda, z, lda, z,
577 $ lda, work, result( 4 ) )
589 IF( alphai( j ).EQ.zero )
THEN
590 temp2 = ( abs( alphar( j )-ai( j, j ) ) /
591 $ max( smlnum, abs( alphar( j ) ),
592 $ abs( ai( j, j ) ) )+
593 $ abs( beta( j )-bi( j, j ) ) /
594 $ max( smlnum, abs( beta( j ) ),
595 $ abs( bi( j, j ) ) ) ) / ulp
596 IF( j.LT.mplusn )
THEN
597 IF( ai( j+1, j ).NE.zero )
THEN
603 IF( ai( j, j-1 ).NE.zero )
THEN
609 IF( alphai( j ).GT.zero )
THEN
614 IF( i1.LE.0 .OR. i1.GE.mplusn )
THEN
616 ELSE IF( i1.LT.mplusn-1 )
THEN
617 IF( ai( i1+2, i1+1 ).NE.zero )
THEN
621 ELSE IF( i1.GT.1 )
THEN
622 IF( ai( i1, i1-1 ).NE.zero )
THEN
627 IF( .NOT.ilabad )
THEN
628 CALL sget53( ai( i1, i1 ), lda, bi( i1, i1 ),
629 $ lda, beta( j ), alphar( j ),
630 $ alphai( j ), temp2, iinfo )
631 IF( iinfo.GE.3 )
THEN
632 WRITE( nout, fmt = 9997 )iinfo, j,
640 temp1 = max( temp1, temp2 )
642 WRITE( nout, fmt = 9996 )j, mplusn, prtype
651 IF( linfo.EQ.mplusn+3 )
THEN
653 ELSE IF( mm.NE.n )
THEN
662 mn2 = mm*( mplusn-mm )*2
663 IF( ifunc.GE.2 .AND. mn2.LE.ncmax*ncmax )
THEN
668 CALL slakf2( mm, mplusn-mm, ai, lda,
669 $ ai( mm+1, mm+1 ), bi,
670 $ bi( mm+1, mm+1 ), c, ldc )
672 CALL sgesvd(
'N',
'N', mn2, mn2, c, ldc, s, work,
673 $ 1, work( 2 ), 1, work( 3 ), lwork-2,
677 IF( difest( 2 ).EQ.zero )
THEN
678 IF( diftru.GT.abnrm*ulp )
679 $ result( 8 ) = ulpinv
680 ELSE IF( diftru.EQ.zero )
THEN
681 IF( difest( 2 ).GT.abnrm*ulp )
682 $ result( 8 ) = ulpinv
683 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
684 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
685 result( 8 ) = max( diftru / difest( 2 ),
686 $ difest( 2 ) / diftru )
694 IF( linfo.EQ.( mplusn+2 ) )
THEN
695 IF( diftru.GT.abnrm*ulp )
696 $ result( 9 ) = ulpinv
697 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
698 $ result( 9 ) = ulpinv
699 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
700 $ result( 9 ) = ulpinv
704 ntestt = ntestt + ntest
709 IF( result( j ).GE.thresh )
THEN
714 IF( nerrs.EQ.0 )
THEN
715 WRITE( nout, fmt = 9995 )
'SGX'
719 WRITE( nout, fmt = 9993 )
723 WRITE( nout, fmt = 9992 )
'orthogonal',
'''',
724 $
'transpose', (
'''', i = 1, 4 )
728 IF( result( j ).LT.10000.0 )
THEN
729 WRITE( nout, fmt = 9991 )mplusn, prtype,
730 $ weight, m, j, result( j )
732 WRITE( nout, fmt = 9990 )mplusn, prtype,
733 $ weight, m, j, result( j )
753 READ( nin, fmt = *, end = 140 )mplusn
756 READ( nin, fmt = *, end = 140 )n
758 READ( nin, fmt = * )( ai( i, j ), j = 1, mplusn )
761 READ( nin, fmt = * )( bi( i, j ), j = 1, mplusn )
763 READ( nin, fmt = * )pltru, diftru
770 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
771 CALL slacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
776 CALL sggesx(
'V',
'V',
'S', slctsx,
'B', mplusn, ai, lda, bi, lda,
777 $ mm, alphar, alphai, beta, q, lda, z, lda, pl, difest,
778 $ work, lwork, iwork, liwork, bwork, linfo )
780 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
782 WRITE( nout, fmt = 9998 )
'SGGESX', linfo, mplusn, nptknt
789 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, work, mplusn )
790 CALL slacpy(
'Full', mplusn, mplusn, bi, lda,
791 $ work( mplusn*mplusn+1 ), mplusn )
792 abnrm = slange(
'Fro', mplusn, 2*mplusn, work, mplusn, work )
796 CALL sget51( 1, mplusn, a, lda, ai, lda, q, lda, z, lda, work,
798 CALL sget51( 1, mplusn, b, lda, bi, lda, q, lda, z, lda, work,
800 CALL sget51( 3, mplusn, b, lda, bi, lda, q, lda, q, lda, work,
802 CALL sget51( 3, mplusn, b, lda, bi, lda, z, lda, z, lda, work,
815 IF( alphai( j ).EQ.zero )
THEN
816 temp2 = ( abs( alphar( j )-ai( j, j ) ) /
817 $ max( smlnum, abs( alphar( j ) ), abs( ai( j,
818 $ j ) ) )+abs( beta( j )-bi( j, j ) ) /
819 $ max( smlnum, abs( beta( j ) ), abs( bi( j, j ) ) ) )
821 IF( j.LT.mplusn )
THEN
822 IF( ai( j+1, j ).NE.zero )
THEN
828 IF( ai( j, j-1 ).NE.zero )
THEN
834 IF( alphai( j ).GT.zero )
THEN
839 IF( i1.LE.0 .OR. i1.GE.mplusn )
THEN
841 ELSE IF( i1.LT.mplusn-1 )
THEN
842 IF( ai( i1+2, i1+1 ).NE.zero )
THEN
846 ELSE IF( i1.GT.1 )
THEN
847 IF( ai( i1, i1-1 ).NE.zero )
THEN
852 IF( .NOT.ilabad )
THEN
853 CALL sget53( ai( i1, i1 ), lda, bi( i1, i1 ), lda,
854 $ beta( j ), alphar( j ), alphai( j ), temp2,
856 IF( iinfo.GE.3 )
THEN
857 WRITE( nout, fmt = 9997 )iinfo, j, mplusn, nptknt
864 temp1 = max( temp1, temp2 )
866 WRITE( nout, fmt = 9996 )j, mplusn, nptknt
875 IF( linfo.EQ.mplusn+3 )
876 $ result( 7 ) = ulpinv
882 IF( difest( 2 ).EQ.zero )
THEN
883 IF( diftru.GT.abnrm*ulp )
884 $ result( 8 ) = ulpinv
885 ELSE IF( diftru.EQ.zero )
THEN
886 IF( difest( 2 ).GT.abnrm*ulp )
887 $ result( 8 ) = ulpinv
888 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
889 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
890 result( 8 ) = max( diftru / difest( 2 ), difest( 2 ) / diftru )
897 IF( linfo.EQ.( mplusn+2 ) )
THEN
898 IF( diftru.GT.abnrm*ulp )
899 $ result( 9 ) = ulpinv
900 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
901 $ result( 9 ) = ulpinv
902 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
903 $ result( 9 ) = ulpinv
910 IF( pl( 1 ).EQ.zero )
THEN
911 IF( pltru.GT.abnrm*ulp )
912 $ result( 10 ) = ulpinv
913 ELSE IF( pltru.EQ.zero )
THEN
914 IF( pl( 1 ).GT.abnrm*ulp )
915 $ result( 10 ) = ulpinv
916 ELSE IF( ( pltru.GT.thresh*pl( 1 ) ) .OR.
917 $ ( pltru*thresh.LT.pl( 1 ) ) )
THEN
918 result( 10 ) = ulpinv
921 ntestt = ntestt + ntest
926 IF( result( j ).GE.thresh )
THEN
931 IF( nerrs.EQ.0 )
THEN
932 WRITE( nout, fmt = 9995 )
'SGX'
936 WRITE( nout, fmt = 9994 )
940 WRITE( nout, fmt = 9992 )
'orthogonal',
'''',
941 $
'transpose', (
'''', i = 1, 4 )
945 IF( result( j ).LT.10000.0 )
THEN
946 WRITE( nout, fmt = 9989 )nptknt, mplusn, j, result( j )
948 WRITE( nout, fmt = 9988 )nptknt, mplusn, j, result( j )
962 CALL alasvm(
'SGX', nout, nerrs, ntestt, 0 )
968 9999
FORMAT(
' SDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
969 $ i6,
', JTYPE=', i6,
')' )
971 9998
FORMAT(
' SDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
972 $ i6,
', Input Example #', i2,
')' )
974 9997
FORMAT(
' SDRGSX: SGET53 returned INFO=', i1,
' for eigenvalue ',
975 $ i6,
'.', / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
977 9996
FORMAT(
' SDRGSX: S not in Schur form at eigenvalue ', i6,
'.',
978 $ / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
980 9995
FORMAT( / 1x, a3,
' -- Real Expert Generalized Schur form',
981 $
' problem driver' )
983 9994
FORMAT(
'Input Example' )
985 9993
FORMAT(
' Matrix types: ', /
986 $
' 1: A is a block diagonal matrix of Jordan blocks ',
987 $
'and B is the identity ', /
' matrix, ',
988 $ /
' 2: A and B are upper triangular matrices, ',
989 $ /
' 3: A and B are as type 2, but each second diagonal ',
990 $
'block in A_11 and ', /
991 $
' each third diaongal block in A_22 are 2x2 blocks,',
992 $ /
' 4: A and B are block diagonal matrices, ',
993 $ /
' 5: (A,B) has potentially close or common ',
994 $
'eigenvalues.', / )
996 9992
FORMAT( /
' Tests performed: (S is Schur, T is triangular, ',
997 $
'Q and Z are ', a,
',', / 19x,
998 $
' a is alpha, b is beta, and ', a,
' means ', a,
'.)',
999 $ /
' 1 = | A - Q S Z', a,
1000 $
' | / ( |A| n ulp ) 2 = | B - Q T Z', a,
1001 $
' | / ( |B| n ulp )', /
' 3 = | I - QQ', a,
1002 $
' | / ( n ulp ) 4 = | I - ZZ', a,
1003 $
' | / ( n ulp )', /
' 5 = 1/ULP if A is not in ',
1004 $
'Schur form S', /
' 6 = difference between (alpha,beta)',
1005 $
' and diagonals of (S,T)', /
1006 $
' 7 = 1/ULP if SDIM is not the correct number of ',
1007 $
'selected eigenvalues', /
1008 $
' 8 = 1/ULP if DIFEST/DIFTRU > 10*THRESH or ',
1009 $
'DIFTRU/DIFEST > 10*THRESH',
1010 $ /
' 9 = 1/ULP if DIFEST <> 0 or DIFTRU > ULP*norm(A,B) ',
1011 $
'when reordering fails', /
1012 $
' 10 = 1/ULP if PLEST/PLTRU > THRESH or ',
1013 $
'PLTRU/PLEST > THRESH', /
1014 $
' ( Test 10 is only for input examples )', / )
1015 9991
FORMAT(
' Matrix order=', i2,
', type=', i2,
', a=', e10.3,
1016 $
', order(A_11)=', i2,
', result ', i2,
' is ', 0p, f8.2 )
1017 9990
FORMAT(
' Matrix order=', i2,
', type=', i2,
', a=', e10.3,
1018 $
', order(A_11)=', i2,
', result ', i2,
' is ', 0p, e10.3 )
1019 9989
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
1020 $
' result ', i2,
' is', 0p, f8.2 )
1021 9988
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
1022 $
' result ', i2,
' is', 1p, e10.3 )
subroutine alasvm(TYPE, NOUT, NFAIL, NRUN, NERRS)
ALASVM
subroutine sggesx(JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA, B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK, LIWORK, BWORK, INFO)
SGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE...
subroutine slabad(SMALL, LARGE)
SLABAD
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slaset(UPLO, M, N, ALPHA, BETA, A, LDA)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine sget51(ITYPE, N, A, LDA, B, LDB, U, LDU, V, LDV, WORK, RESULT)
SGET51
subroutine sdrgsx(NSIZE, NCMAX, THRESH, NIN, NOUT, A, LDA, B, AI, BI, Z, Q, ALPHAR, ALPHAI, BETA, C, LDC, S, WORK, LWORK, IWORK, LIWORK, BWORK, INFO)
SDRGSX
subroutine slakf2(M, N, A, LDA, B, D, E, Z, LDZ)
SLAKF2
subroutine sget53(A, LDA, B, LDB, SCALE, WR, WI, RESULT, INFO)
SGET53
subroutine sgesvd(JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO)
SGESVD computes the singular value decomposition (SVD) for GE matrices
subroutine slatm5(PRTYPE, M, N, A, LDA, B, LDB, C, LDC, D, LDD, E, LDE, F, LDF, R, LDR, L, LDL, ALPHA, QBLCKA, QBLCKB)
SLATM5