346 SUBROUTINE zdrgsx( NSIZE, NCMAX, THRESH, NIN, NOUT, A, LDA, B, AI,
347 $ BI, Z, Q, ALPHA, BETA, C, LDC, S, WORK, LWORK,
348 $ RWORK, IWORK, LIWORK, BWORK, INFO )
355 INTEGER INFO, LDA, LDC, LIWORK, LWORK, NCMAX, NIN,
357 DOUBLE PRECISION THRESH
362 DOUBLE PRECISION RWORK( * ), S( * )
363 COMPLEX*16 ( LDA, * ), AI( LDA, * ), ALPHA( * ),
364 $ b( lda, * ), beta( * ), bi( lda, * ),
365 $ c( ldc, * ), q( lda, * ), work( * ),
372 DOUBLE PRECISION ZERO, ONE, TEN
373 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0, ten = 1.0d+1 )
375 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
380 INTEGER BDSPAC, I, IFUNC, J, LINFO, MAXWRK, MINWRK, MM,
381 $ mn2, nerrs, nptknt, ntest, ntestt, prtype, qba,
383 DOUBLE PRECISION ABNRM, BIGNUM, DIFTRU, PLTRU, SMLNUM, TEMP1,
384 $ TEMP2, THRSH2, ULP, ULPINV,
388 DOUBLE PRECISION DIFEST( 2 ), PL( 2 ), RESULT( 10 )
393 DOUBLE PRECISION DLAMCH, ZLANGE
394 EXTERNAL zlctsx, ilaenv, dlamch, zlange
402 INTEGER K, M, MPLUSN, N
405 COMMON / mn / m, n, mplusn, k, fs
408 INTRINSIC abs, dble, dimag,
max, sqrt
411 DOUBLE PRECISION ABS1
414 abs1( x ) = abs( dble( x ) ) + abs( dimag( x ) )
421 IF( nsize.LT.0 )
THEN
423 ELSE IF( thresh.LT.zero )
THEN
425 ELSE IF( nin.LE.0 )
THEN
427 ELSE IF( nout.LE.0 )
THEN
429 ELSE IF( lda.LT.1 .OR. lda.LT.nsize )
THEN
431 ELSE IF( ldc.LT.1 .OR. ldc.LT.nsize*nsize / 2 )
THEN
433 ELSE IF( liwork.LT.nsize+2 )
THEN
445 IF( info.EQ.0 .AND. lwork.GE.1 )
THEN
446 minwrk = 3*nsize*nsize / 2
450 maxwrk = nsize*( 1+ilaenv( 1,
'ZGEQRF',
' ', nsize, 1, nsize,
452 maxwrk =
max( maxwrk, nsize*( 1+ilaenv( 1,
'ZUNGQR',
' ',
453 $ nsize, 1, nsize, -1 ) ) )
457 bdspac = 3*nsize*nsize / 2
458 maxwrk =
max( maxwrk, nsize*nsize*
459 $ ( 1+ilaenv( 1,
'ZGEBRD',
' ', 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(
'ZDRGSX', -info )
480 smlnum = dlamch(
'S' ) / ulp
481 bignum = one / smlnum
482 CALL dlabad( smlnum, bignum )
504 DO 40 m = 1, nsize - 1
505 DO 30 n = 1, nsize - m
507 weight = one / weight
515 CALL zlaset(
'Full', mplusn, mplusn, czero, czero, ai,
517 CALL zlaset(
'Full', mplusn, mplusn, czero, czero, bi,
520 CALL zlatm5( prtype, m, n, ai, lda, ai( m+1, m+1 ),
521 $ lda, ai( 1, m+1 ), lda, bi, 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 zlacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
541 CALL zlacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
543 CALL zggesx(
'V',
'V',
'S', zlctsx, sense, mplusn, ai,
544 $ lda, bi, lda, mm, alpha, beta, q, lda, z,
545 $ lda, pl, difest, work, lwork, rwork,
546 $ iwork, liwork, bwork, linfo )
548 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
550 WRITE( nout, fmt = 9999 )
'ZGGESX', linfo, mplusn,
558 CALL zlacpy(
'Full', mplusn, mplusn, ai, lda, work,
560 CALL zlacpy(
'Full', mplusn, mplusn, bi, lda,
561 $ work( mplusn*mplusn+1 ), mplusn )
562 abnrm = zlange(
'Fro', mplusn, 2*mplusn, work, mplusn,
568 CALL zget51( 1, mplusn, a, lda, ai, lda, q, lda, z,
569 $ lda, work, rwork, result( 1 ) )
570 CALL zget51( 1, mplusn, b, lda, bi, lda, q, lda, z,
571 $ lda, work, rwork, result( 2 ) )
572 CALL zget51( 3, mplusn, b, lda, bi, lda, q, lda, q,
573 $ lda, work, rwork, result( 3 ) )
574 CALL zget51( 3, mplusn, b, lda, bi, lda, z, lda, z,
575 $ lda, work, rwork, result( 4 ) )
587 temp2 = ( abs1( alpha( j )-ai( j, j ) ) /
588 $
max( smlnum, abs1( alpha( j ) ),
589 $ abs1( ai( j, j ) ) )+
590 $ abs1( beta( j )-bi( j, j ) ) /
591 $
max( smlnum, abs1( beta( j ) ),
592 $ abs1( 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
605 temp1 =
max( temp1, temp2 )
607 WRITE( nout, fmt = 9997 )j, mplusn, prtype
616 IF( linfo.EQ.mplusn+3 )
THEN
618 ELSE IF( mm.NE.n )
THEN
627 mn2 = mm*( mplusn-mm )*2
628 IF( ifunc.GE.2 .AND. mn2.LE.ncmax*ncmax )
THEN
633 CALL zlakf2( mm, mplusn-mm, ai, lda,
635 $ bi( mm+1, mm+1 ), c, ldc )
637 CALL zgesvd(
'N',
'N', mn2, mn2, c, ldc, s, work,
638 $ 1, work( 2 ), 1, work( 3 ), lwork-2,
642 IF( difest( 2 ).EQ.zero )
THEN
643 IF( diftru.GT.abnrm*ulp )
644 $ result( 8 ) = ulpinv
645 ELSE IF( diftru.EQ.zero )
THEN
646 IF( difest( 2 ).GT.abnrm*ulp )
647 $ result( 8 ) = ulpinv
648 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
649 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
650 result( 8 ) =
max( diftru / difest( 2 ),
651 $ difest( 2 ) / diftru )
659 IF( linfo.EQ.( mplusn+2 ) )
THEN
660 IF( diftru.GT.abnrm*ulp )
661 $ result( 9 ) = ulpinv
662 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
663 $ result( 9 ) = ulpinv
664 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
665 $ result( 9 ) = ulpinv
669 ntestt = ntestt + ntest
674 IF( result( j ).GE.thresh )
THEN
679 IF( nerrs.EQ.0 )
THEN
680 WRITE( nout, fmt = 9996 )
'ZGX'
684 WRITE( nout, fmt = 9994 )
688 WRITE( nout, fmt = 9993 )'unitary
', '''',
689 $ 'transpose
', ( '''', I = 1, 4 )
693.LT.
IF( RESULT( J )10000.0D0 ) THEN
694 WRITE( NOUT, FMT = 9992 )MPLUSN, PRTYPE,
695 $ WEIGHT, M, J, RESULT( J )
697 WRITE( NOUT, FMT = 9991 )MPLUSN, PRTYPE,
698 $ WEIGHT, M, J, RESULT( J )
718 READ( NIN, FMT = *, END = 140 )MPLUSN
721 READ( NIN, FMT = *, END = 140 )N
723 READ( NIN, FMT = * )( AI( I, J ), J = 1, MPLUSN )
726 READ( NIN, FMT = * )( BI( I, J ), J = 1, MPLUSN )
728 READ( NIN, FMT = * )PLTRU, DIFTRU
735 CALL ZLACPY( 'full
', MPLUSN, MPLUSN, AI, LDA, A, LDA )
736 CALL ZLACPY( 'full
', MPLUSN, MPLUSN, BI, LDA, B, LDA )
741 CALL ZGGESX( 'v
', 'v
', 's
', ZLCTSX, 'b
', MPLUSN, AI, LDA, BI, LDA,
742 $ MM, ALPHA, BETA, Q, LDA, Z, LDA, PL, DIFEST, WORK,
743 $ LWORK, RWORK, IWORK, LIWORK, BWORK, LINFO )
745.NE..AND..NE.
IF( LINFO0 LINFOMPLUSN+2 ) THEN
747 WRITE( NOUT, FMT = 9998 )'zggesx', LINFO, MPLUSN, NPTKNT
754 CALL ZLACPY( 'full
', MPLUSN, MPLUSN, AI, LDA, WORK, MPLUSN )
755 CALL ZLACPY( 'full
', MPLUSN, MPLUSN, BI, LDA,
756 $ WORK( MPLUSN*MPLUSN+1 ), MPLUSN )
757 ABNRM = ZLANGE( 'fro
', MPLUSN, 2*MPLUSN, WORK, MPLUSN, RWORK )
761 CALL ZGET51( 1, MPLUSN, A, LDA, AI, LDA, Q, LDA, Z, LDA, WORK,
762 $ RWORK, RESULT( 1 ) )
763 CALL ZGET51( 1, MPLUSN, B, LDA, BI, LDA, Q, LDA, Z, LDA, WORK,
764 $ RWORK, RESULT( 2 ) )
765 CALL ZGET51( 3, MPLUSN, B, LDA, BI, LDA, Q, LDA, Q, LDA, WORK,
766 $ RWORK, RESULT( 3 ) )
767 CALL ZGET51( 3, MPLUSN, B, LDA, BI, LDA, Z, LDA, Z, LDA, WORK,
768 $ RWORK, RESULT( 4 ) )
780 TEMP2 = ( ABS1( ALPHA( J )-AI( J, J ) ) /
781 $ MAX( SMLNUM, ABS1( ALPHA( J ) ), ABS1( AI( J, J ) ) )+
782 $ ABS1( BETA( J )-BI( J, J ) ) /
783 $ MAX( SMLNUM, ABS1( BETA( J ) ), ABS1( BI( J, J ) ) ) )
785.LT.
IF( JMPLUSN ) THEN
786.NE.
IF( AI( J+1, J )ZERO ) THEN
792.NE.
IF( AI( J, J-1 )ZERO ) THEN
797 TEMP1 = MAX( TEMP1, TEMP2 )
799 WRITE( NOUT, FMT = 9997 )J, MPLUSN, NPTKNT
808.EQ.
IF( LINFOMPLUSN+3 )
809 $ RESULT( 7 ) = ULPINV
815.EQ.
IF( DIFEST( 2 )ZERO ) THEN
816.GT.
IF( DIFTRUABNRM*ULP )
817 $ RESULT( 8 ) = ULPINV
818.EQ.
ELSE IF( DIFTRUZERO ) THEN
819.GT.
IF( DIFEST( 2 )ABNRM*ULP )
820 $ RESULT( 8 ) = ULPINV
821.GT..OR.
ELSE IF( ( DIFTRUTHRSH2*DIFEST( 2 ) )
822.LT.
$ ( DIFTRU*THRSH2DIFEST( 2 ) ) ) THEN
823 RESULT( 8 ) = MAX( DIFTRU / DIFEST( 2 ), DIFEST( 2 ) / DIFTRU )
830.EQ.
IF( LINFO( MPLUSN+2 ) ) THEN
831.GT.
IF( DIFTRUABNRM*ULP )
832 $ RESULT( 9 ) = ULPINV
833.GT..AND..NE.
IF( ( IFUNC1 ) ( DIFEST( 2 )ZERO ) )
834 $ RESULT( 9 ) = ULPINV
835.EQ..AND..NE.
IF( ( IFUNC1 ) ( PL( 1 )ZERO ) )
836 $ RESULT( 9 ) = ULPINV
843.EQ.
IF( PL( 1 )ZERO ) THEN
844.GT.
IF( PLTRUABNRM*ULP )
845 $ RESULT( 10 ) = ULPINV
846.EQ.
ELSE IF( PLTRUZERO ) THEN
847.GT.
IF( PL( 1 )ABNRM*ULP )
848 $ RESULT( 10 ) = ULPINV
849.GT..OR.
ELSE IF( ( PLTRUTHRESH*PL( 1 ) )
850.LT.
$ ( PLTRU*THRESHPL( 1 ) ) ) THEN
851 RESULT( 10 ) = ULPINV
854 NTESTT = NTESTT + NTEST
859.GE.
IF( RESULT( J )THRESH ) THEN
864.EQ.
IF( NERRS0 ) THEN
865 WRITE( NOUT, FMT = 9996 )'zgx
'
869 WRITE( NOUT, FMT = 9995 )
873 WRITE( NOUT, FMT = 9993 )'unitary
', '''', 'transpose
',
878.LT.
IF( RESULT( J )10000.0D0 ) THEN
879 WRITE( NOUT, FMT = 9990 )NPTKNT, MPLUSN, J, RESULT( J )
881 WRITE( NOUT, FMT = 9989 )NPTKNT, MPLUSN, J, RESULT( J )
895 CALL ALASVM( 'zgx
', NOUT, NERRS, NTESTT, 0 )
901 9999 FORMAT( ' zdrgsx:
', A, ' returned info=
', I6, '.
', / 9X, 'n=
',
902 $ I6, ', jtype=
', I6, ')
' )
904 9998 FORMAT( ' zdrgsx:
', A, ' returned info=
', I6, '.
', / 9X, 'n=
',
905 $ I6, ', input example
#', I2, ')' )
907 9997
FORMAT(
' ZDRGSX: S not in Schur form at eigenvalue ', i6,
'.',
908 $ / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
910 9996
FORMAT( / 1x, a3,
' -- Complex Expert Generalized Schur form',
911 $
' problem driver' )
913 9995
FORMAT(
'Input Example' )
915 9994
FORMAT(
' Matrix types: ', /
916 $
' 1: A is a block diagonal matrix of Jordan blocks ',
917 $
'and B is the identity ', /
' matrix, ',
918 $ /
' 2: A and B are upper triangular matrices, ',
919 $ /
' 3: A and B are as type 2, but each second diagonal ',
920 $
'block in A_11 and ', /
921 $
' each third diaongal block in A_22 are 2x2 blocks,',
922 $ /
' 4: A and B are block diagonal matrices, ',
923 $ /
' 5: (A,B) has potentially close or common ',
924 $
'eigenvalues.', / )
926 9993
FORMAT( /
' Tests performed: (S is Schur, T is triangular, ',
927 $
'Q and Z are ', a,
',', / 19x,
928 $
' a is alpha, b is beta, and ', a,
' means ', a,
'.)',
929 $ /
' 1 = | A - Q S Z', a,
930 $
' | / ( |A| n ulp ) 2 = | B - Q T Z', a,
931 $
' | / ( |B| n ulp )', /
' 3 = | I - QQ', a,
932 $
' | / ( n ulp ) 4 = | I - ZZ', a,
933 $
' | / ( n ulp )', /
' 5 = 1/ULP if A is not in ',
934 $
'Schur form S', /
' 6 = difference between (alpha,beta)',
935 $
' and diagonals of (S,T)', /
936 $
' 7 = 1/ULP if SDIM is not the correct number of ',
937 $
'selected eigenvalues', /
938 $
' 8 = 1/ULP if DIFEST/DIFTRU > 10*THRESH or ',
939 $
'DIFTRU/DIFEST > 10*THRESH',
940 $ /
' 9 = 1/ULP if DIFEST <> 0 or DIFTRU > ULP*norm(A,B) '
941 $
'when reordering fails', /
942 $
' 10 = 1/ULP if PLEST/PLTRU > THRESH or ',
943 $ 'pltru/plest > thresh
', /
944 $ ' ( test 10 is only
for input examples )
', / )
945 9992 FORMAT( ' matrix order=
', I2, ', type=
', I2, ', a=
', D10.3,
946 $ ', order(a_11)=
', I2, ', result
', I2, ' is
', 0P, F8.2 )
947 9991 FORMAT( ' matrix order=
', I2, ', type=
', I2, ', a=
', D10.3,
948 $ ', order(a_11)=
', I2, ', result
', I2, ' is
', 0P, D10.3 )
949 9990 FORMAT( ' input example
#', I2, ', matrix order=', I4, ',',
950 $
' result ', i2,
' is', 0p, f8.2 )
951 9989
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
952 $
' result ', i2,
' is', 1p, d10.3 )