346 SUBROUTINE cdrgsx( NSIZE, NCMAX, THRESH, NIN, NOUT, A, LDA, B,
347 $ AI, BI, Z, Q, ALPHA, BETA, C, LDC, S, WORK,
348 $ LWORK, RWORK, IWORK, LIWORK, BWORK, INFO )
355 INTEGER INFO, LDA, LDC, LIWORK, LWORK, NCMAX, NIN,
362 REAL RWORK( * ), S( * )
363 COMPLEX A( LDA, * ), AI( LDA, * ), ALPHA( * ),
364 $ b( lda, * ), beta( * ), bi( lda, * ),
365 $ c( ldc, * ), q( lda, * ), work( * ),
373 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0, ten = 1.0e+1 )
375 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
380 INTEGER BDSPAC, I, IFUNC, J, LINFO, MAXWRK, MINWRK, MM,
381 $ mn2, nerrs, nptknt, ntest, ntestt, prtype, qba,
383 REAL ABNRM, BIGNUM, DIFTRU, PLTRU, SMLNUM, TEMP1,
384 $ TEMP2, THRSH2, ULP, ULPINV, WEIGHT
388 REAL DIFEST( 2 ), PL( 2 ), RESULT( 10 )
394 EXTERNAL clctsx, ilaenv, clange, slamch
402 INTEGER K, M, MPLUSN, N
405 COMMON / mn / m, n, mplusn, k, fs
408 INTRINSIC abs, aimag, max, real, sqrt
414 abs1( x ) = abs( real( x ) ) + abs( aimag( x ) )
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+2 )
THEN
444 IF( info.EQ.0 .AND. lwork.GE.1 )
THEN
445 minwrk = 3*nsize*nsize / 2
449 maxwrk = nsize*( 1+ilaenv( 1,
'CGEQRF',
' ', nsize, 1, nsize,
451 maxwrk = max( maxwrk, nsize*( 1+ilaenv( 1,
'CUNGQR',
' ',
452 $ nsize, 1, nsize, -1 ) ) )
456 bdspac = 3*nsize*nsize / 2
457 maxwrk = max( maxwrk, nsize*nsize*
458 $ ( 1+ilaenv( 1,
'CGEBRD',
' ', nsize*nsize / 2,
459 $ nsize*nsize / 2, -1, -1 ) ) )
460 maxwrk = max( maxwrk, bdspac )
462 maxwrk = max( maxwrk, minwrk )
467 IF( lwork.LT.minwrk )
471 CALL xerbla(
'CDRGSX', -info )
479 smlnum = slamch(
'S' ) / ulp
480 bignum = one / smlnum
502 DO 40 m = 1, nsize - 1
503 DO 30 n = 1, nsize - m
505 weight = one / weight
513 CALL claset(
'Full', mplusn, mplusn, czero, czero, ai,
515 CALL claset(
'Full', mplusn, mplusn, czero, czero, bi,
518 CALL clatm5( prtype, m, n, ai, lda, ai( m+1, m+1 ),
519 $ lda, ai( 1, m+1 ), lda, bi, lda,
520 $ bi( m+1, m+1 ), lda, bi( 1, m+1 ), lda,
521 $ q, lda, z, lda, weight, qba, qbb )
528 IF( ifunc.EQ.0 )
THEN
530 ELSE IF( ifunc.EQ.1 )
THEN
532 ELSE IF( ifunc.EQ.2 )
THEN
534 ELSE IF( ifunc.EQ.3 )
THEN
538 CALL clacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
539 CALL clacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
541 CALL cggesx(
'V',
'V',
'S', clctsx, sense, mplusn, ai,
542 $ lda, bi, lda, mm, alpha, beta, q, lda, z,
543 $ lda, pl, difest, work, lwork, rwork,
544 $ iwork, liwork, bwork, linfo )
546 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
548 WRITE( nout, fmt = 9999 )
'CGGESX', linfo, mplusn,
556 CALL clacpy(
'Full', mplusn, mplusn, ai, lda, work,
558 CALL clacpy(
'Full', mplusn, mplusn, bi, lda,
559 $ work( mplusn*mplusn+1 ), mplusn )
560 abnrm = clange(
'Fro', mplusn, 2*mplusn, work, mplusn,
566 CALL cget51( 1, mplusn, a, lda, ai, lda, q, lda, z,
567 $ lda, work, rwork, result( 1 ) )
568 CALL cget51( 1, mplusn, b, lda, bi, lda, q, lda, z,
569 $ lda, work, rwork, result( 2 ) )
570 CALL cget51( 3, mplusn, b, lda, bi, lda, q, lda, q,
571 $ lda, work, rwork, result( 3 ) )
572 CALL cget51( 3, mplusn, b, lda, bi, lda, z, lda, z,
573 $ lda, work, rwork, result( 4 ) )
585 temp2 = ( abs1( alpha( j )-ai( j, j ) ) /
586 $ max( smlnum, abs1( alpha( j ) ),
587 $ abs1( ai( j, j ) ) )+
588 $ abs1( beta( j )-bi( j, j ) ) /
589 $ max( smlnum, abs1( beta( j ) ),
590 $ abs1( bi( j, j ) ) ) ) / ulp
591 IF( j.LT.mplusn )
THEN
592 IF( ai( j+1, j ).NE.zero )
THEN
598 IF( ai( j, j-1 ).NE.zero )
THEN
603 temp1 = max( temp1, temp2 )
605 WRITE( nout, fmt = 9997 )j, mplusn, prtype
614 IF( linfo.EQ.mplusn+3 )
THEN
616 ELSE IF( mm.NE.n )
THEN
625 mn2 = mm*( mplusn-mm )*2
626 IF( ifunc.GE.2 .AND. mn2.LE.ncmax*ncmax )
THEN
631 CALL clakf2( mm, mplusn-mm, ai, lda,
632 $ ai( mm+1, mm+1 ), bi,
633 $ bi( mm+1, mm+1 ), c, ldc )
635 CALL cgesvd(
'N',
'N', mn2, mn2, c, ldc, s, work,
636 $ 1, work( 2 ), 1, work( 3 ), lwork-2,
640 IF( difest( 2 ).EQ.zero )
THEN
641 IF( diftru.GT.abnrm*ulp )
642 $ result( 8 ) = ulpinv
643 ELSE IF( diftru.EQ.zero )
THEN
644 IF( difest( 2 ).GT.abnrm*ulp )
645 $ result( 8 ) = ulpinv
646 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
647 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
648 result( 8 ) = max( diftru / difest( 2 ),
649 $ difest( 2 ) / diftru )
657 IF( linfo.EQ.( mplusn+2 ) )
THEN
658 IF( diftru.GT.abnrm*ulp )
659 $ result( 9 ) = ulpinv
660 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
661 $ result( 9 ) = ulpinv
662 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
663 $ result( 9 ) = ulpinv
667 ntestt = ntestt + ntest
672 IF( result( j ).GE.thresh )
THEN
677 IF( nerrs.EQ.0 )
THEN
678 WRITE( nout, fmt = 9996 )
'CGX'
682 WRITE( nout, fmt = 9994 )
686 WRITE( nout, fmt = 9993 )
'unitary',
'''',
687 $
'transpose', (
'''', i = 1, 4 )
691 IF( result( j ).LT.10000.0 )
THEN
692 WRITE( nout, fmt = 9992 )mplusn, prtype,
693 $ weight, m, j, result( j )
695 WRITE( nout, fmt = 9991 )mplusn, prtype,
696 $ weight, m, j, result( j )
716 READ( nin, fmt = *,
END = 140 )mplusn
719 READ( nin, fmt = *,
END = 140 )n
721 READ( nin, fmt = * )( ai( i, j ), j = 1, mplusn )
724 READ( nin, fmt = * )( bi( i, j ), j = 1, mplusn )
726 READ( nin, fmt = * )pltru, diftru
733 CALL clacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
734 CALL clacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
739 CALL cggesx(
'V',
'V',
'S',
clctsx,
'B', mplusn, ai, lda, bi, lda,
740 $ mm, alpha, beta, q, lda, z, lda, pl, difest, work,
741 $ lwork, rwork, iwork, liwork, bwork, linfo )
743 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
745 WRITE( nout, fmt = 9998 )
'CGGESX', linfo, mplusn, nptknt
752 CALL clacpy(
'Full', mplusn, mplusn, ai, lda, work, mplusn )
753 CALL clacpy(
'Full', mplusn, mplusn, bi, lda,
754 $ work( mplusn*mplusn+1 ), mplusn )
755 abnrm =
clange(
'Fro', mplusn, 2*mplusn, work, mplusn, rwork )
759 CALL cget51( 1, mplusn, a, lda, ai, lda, q, lda, z, lda, work,
760 $ rwork, result( 1 ) )
761 CALL cget51( 1, mplusn, b, lda, bi, lda, q, lda, z, lda, work,
762 $ rwork, result( 2 ) )
763 CALL cget51( 3, mplusn, b, lda, bi, lda, q, lda, q, lda, work,
764 $ rwork, result( 3 ) )
765 CALL cget51( 3, mplusn, b, lda, bi, lda, z, lda, z, lda, work,
766 $ rwork, result( 4 ) )
778 temp2 = ( abs1( alpha( j )-ai( j, j ) ) /
779 $ max( smlnum, abs1( alpha( j ) ), abs1( ai( j, j ) ) )+
780 $ abs1( beta( j )-bi( j, j ) ) /
781 $ max( smlnum, abs1( beta( j ) ), abs1( bi( j, j ) ) ) )
783 IF( j.LT.mplusn )
THEN
784 IF( ai( j+1, j ).NE.zero )
THEN
790 IF( ai( j, j-1 ).NE.zero )
THEN
795 temp1 = max( temp1, temp2 )
797 WRITE( nout, fmt = 9997 )j, mplusn, nptknt
806 IF( linfo.EQ.mplusn+3 )
807 $ result( 7 ) = ulpinv
813 IF( difest( 2 ).EQ.zero )
THEN
814 IF( diftru.GT.abnrm*ulp )
815 $ result( 8 ) = ulpinv
816 ELSE IF( diftru.EQ.zero )
THEN
817 IF( difest( 2 ).GT.abnrm*ulp )
818 $ result( 8 ) = ulpinv
819 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
820 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
821 result( 8 ) = max( diftru / difest( 2 ), difest( 2 ) / diftru )
828 IF( linfo.EQ.( mplusn+2 ) )
THEN
829 IF( diftru.GT.abnrm*ulp )
830 $ result( 9 ) = ulpinv
831 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
832 $ result( 9 ) = ulpinv
833 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
834 $ result( 9 ) = ulpinv
841 IF( pl( 1 ).EQ.zero )
THEN
842 IF( pltru.GT.abnrm*ulp )
843 $ result( 10 ) = ulpinv
844 ELSE IF( pltru.EQ.zero )
THEN
845 IF( pl( 1 ).GT.abnrm*ulp )
846 $ result( 10 ) = ulpinv
847 ELSE IF( ( pltru.GT.thresh*pl( 1 ) ) .OR.
848 $ ( pltru*thresh.LT.pl( 1 ) ) )
THEN
849 result( 10 ) = ulpinv
852 ntestt = ntestt + ntest
857 IF( result( j ).GE.thresh )
THEN
862 IF( nerrs.EQ.0 )
THEN
863 WRITE( nout, fmt = 9996 )
'CGX'
867 WRITE( nout, fmt = 9995 )
871 WRITE( nout, fmt = 9993 )
'unitary',
'''',
'transpose',
876 IF( result( j ).LT.10000.0 )
THEN
877 WRITE( nout, fmt = 9990 )nptknt, mplusn, j, result( j )
879 WRITE( nout, fmt = 9989 )nptknt, mplusn, j, result( j )
893 CALL alasvm(
'CGX', nout, nerrs, ntestt, 0 )
899 9999
FORMAT(
' CDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
900 $ i6,
', JTYPE=', i6,
')' )
902 9998
FORMAT(
' CDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
903 $ i6,
', Input Example #', i2,
')' )
905 9997
FORMAT(
' CDRGSX: S not in Schur form at eigenvalue ', i6,
'.',
906 $ / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
908 9996
FORMAT( / 1x, a3,
' -- Complex Expert Generalized Schur form',
909 $
' problem driver' )
911 9995
FORMAT(
'Input Example' )
913 9994
FORMAT(
' Matrix types: ', /
914 $
' 1: A is a block diagonal matrix of Jordan blocks ',
915 $
'and B is the identity ', /
' matrix, ',
916 $ /
' 2: A and B are upper triangular matrices, ',
917 $ /
' 3: A and B are as type 2, but each second diagonal ',
918 $
'block in A_11 and ', /
919 $
' each third diagonal block in A_22 are 2x2 blocks,',
920 $ /
' 4: A and B are block diagonal matrices, ',
921 $ /
' 5: (A,B) has potentially close or common ',
922 $
'eigenvalues.', / )
924 9993
FORMAT( /
' Tests performed: (S is Schur, T is triangular, ',
925 $
'Q and Z are ', a,
',', / 19x,
926 $
' a is alpha, b is beta, and ', a,
' means ', a,
'.)',
927 $ /
' 1 = | A - Q S Z', a,
928 $
' | / ( |A| n ulp ) 2 = | B - Q T Z', a,
929 $
' | / ( |B| n ulp )', /
' 3 = | I - QQ', a,
930 $
' | / ( n ulp ) 4 = | I - ZZ', a,
931 $
' | / ( n ulp )', /
' 5 = 1/ULP if A is not in ',
932 $
'Schur form S', /
' 6 = difference between (alpha,beta)',
933 $
' and diagonals of (S,T)', /
934 $
' 7 = 1/ULP if SDIM is not the correct number of ',
935 $
'selected eigenvalues', /
936 $
' 8 = 1/ULP if DIFEST/DIFTRU > 10*THRESH or ',
937 $
'DIFTRU/DIFEST > 10*THRESH',
938 $ /
' 9 = 1/ULP if DIFEST <> 0 or DIFTRU > ULP*norm(A,B) ',
939 $
'when reordering fails', /
940 $
' 10 = 1/ULP if PLEST/PLTRU > THRESH or ',
941 $
'PLTRU/PLEST > THRESH', /
942 $
' ( Test 10 is only for input examples )', / )
943 9992
FORMAT(
' Matrix order=', i2,
', type=', i2,
', a=', e10.3,
944 $
', order(A_11)=', i2,
', result ', i2,
' is ', 0p, f8.2 )
945 9991
FORMAT(
' Matrix order=', i2,
', type=', i2,
', a=', e10.3,
946 $
', order(A_11)=', i2,
', result ', i2,
' is ', 0p, e10.3 )
947 9990
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
948 $
' result ', i2,
' is', 0p, f8.2 )
949 9989
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
950 $
' result ', i2,
' is', 1p, e10.3 )