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 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 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 xerbla(SRNAME, INFO)
XERBLA
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 slatm5(PRTYPE, M, N, A, LDA, B, LDB, C, LDC, D, LDD, E, LDE, F, LDF, R, LDR, L, LDL, ALPHA, QBLCKA, QBLCKB)
SLATM5
subroutine slabad(SMALL, LARGE)
SLABAD
subroutine sget53(A, LDA, B, LDB, SCALE, WR, WI, RESULT, INFO)
SGET53
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.