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 )
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 )
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 )