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, * ), ( * ),
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
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
481 CALL slabad( smlnum, bignum )
503 DO 40 m = 1, nsize - 1
504 DO 30 n = 1, nsize - m
506 weight = one / weight
514 CALL claset(
'Full', mplusn, mplusn, czero, czero, ai,
516 CALL claset(
'Full', mplusn, mplusn, czero, czero, bi,
519 CALL clatm5( prtype, m, n, ai, lda, ai( m+1, m+1 ),
520 $ lda, ai( 1, m+1 ), lda, bi, lda
521 $ bi( m+1, m+1 ), lda, bi( 1, m+1 ), lda,
522 $ q, lda, z, lda, weight, qba, qbb )
529 IF( ifunc.EQ.0 )
THEN
531 ELSE IF( ifunc.EQ.1 )
THEN
533 ELSE IF( ifunc.EQ.2 )
THEN
535 ELSE IF( ifunc.EQ.3 )
THEN
539 CALL clacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
540 CALL clacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
542 CALL cggesx(
'V',
'V',
'S', clctsx, sense, mplusn, ai,
543 $ lda, bi, lda, mm,
alpha, beta, q, lda, z,
544 $ lda, pl, difest, work, lwork, rwork,
545 $ iwork, liwork, bwork, linfo )
547 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
549 WRITE( nout, fmt = 9999 )
'CGGESX', linfo, mplusn,
557 CALL clacpy(
'Full', mplusn, mplusn, ai, lda, work,
559 CALL clacpy(
'Full', mplusn, mplusn, bi, lda,
560 $ work( mplusn*mplusn+1 ), mplusn )
561 abnrm = clange(
'Fro', mplusn, 2*mplusn, work, mplusn,
567 CALL cget51( 1, mplusn, a, lda, ai, lda, q, lda, z,
568 $ lda, work, rwork, result( 1 ) )
569 CALL cget51( 1, mplusn, b, lda, bi, lda, q, lda, z,
570 $ lda, work, rwork, result( 2 ) )
571 CALL cget51( 3, mplusn, b, lda, bi, lda, q, lda, q,
572 $ lda, work, rwork, result( 3 ) )
573 CALL cget51( 3, mplusn, b, lda, bi, lda, z, lda, z,
574 $ lda, work, rwork, result( 4 ) )
586 temp2 = ( abs1(
alpha( j )-ai( j, j ) ) /
588 $ abs1( ai( j, j ) ) )+
589 $ abs1( beta( j )-bi( j, j ) ) /
590 $
max( smlnum, abs1( beta( j ) ),
591 $ abs1( bi( j, j ) ) ) ) / ulp
592 IF( j.LT.mplusn )
THEN
593 IF( ai( j+1, j ).NE.zero )
THEN
599 IF( ai( j, j-1 ).NE.zero )
THEN
604 temp1 =
max( temp1, temp2 )
606 WRITE( nout, fmt = 9997 )j, mplusn, prtype
615 IF( linfo.EQ.mplusn+3 )
THEN
617 ELSE IF( mm.NE.n )
THEN
626 mn2 = mm*( mplusn-mm )*2
627 IF( ifunc.GE.2 .AND. mn2.LE.ncmax*ncmax )
THEN
632 CALL clakf2( mm, mplusn-mm, ai, lda,
633 $ ai( mm+1, mm+1 ), bi,
634 $ bi( mm+1, mm+1 ), c, ldc )
636 CALL cgesvd(
'N',
'N', mn2, mn2, c, ldc, s, work,
637 $ 1, work( 2 ), 1, work( 3 ), lwork-2,
641 IF( difest( 2 ).EQ.zero )
THEN
642 IF( diftru.GT.abnrm*ulp )
643 $ result( 8 ) = ulpinv
644 ELSE IF( diftru.EQ.zero )
THEN
645 IF( difest( 2 ).GT.abnrm*ulp )
646 $ result( 8 ) = ulpinv
647 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
648 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
649 result( 8 ) =
max( diftru / difest( 2 ),
650 $ difest( 2 ) / diftru )
658 IF( linfo.EQ.( mplusn+2 ) )
THEN
659 IF( diftru.GT.abnrm*ulp )
660 $ result( 9 ) = ulpinv
661 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
662 $ result( 9 ) = ulpinv
663 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
664 $ result( 9 ) = ulpinv
668 ntestt = ntestt + ntest
673 IF( result( j ).GE.thresh )
THEN
678 IF( nerrs.EQ.0 )
THEN
679 WRITE( nout, fmt = 9996 )
'CGX'
683 WRITE( nout, fmt = 9994 )
687 WRITE( nout, fmt = 9993 )
'unitary',
'''',
688 $
'transpose', (
'''', i = 1, 4 )
692 IF( result( j ).LT.10000.0 )
THEN
693 WRITE( nout, fmt = 9992 )mplusn, prtype,
694 $ weight, m, j, result( j )
696 WRITE( nout, fmt = 9991 )mplusn, prtype,
697 $ weight, m, j, result( j )
717 READ( nin, fmt = *,
END = 140 )mplusn
720 READ( nin, fmt = *,
END = 140 )n
722 READ( nin, fmt = * )( ai( i, j ), j = 1, mplusn )
725 READ( nin, fmt = * )( bi( i, j ), j = 1, mplusn )
727 READ( nin, fmt = * )pltru, diftru
734 CALL clacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
735 CALL clacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
740 CALL cggesx(
'V',
'V',
'S',
clctsx,
'B', mplusn, ai, lda, bi, lda,
741 $ mm,
alpha, beta, q, lda, z, lda, pl, difest, work,
742 $ lwork, rwork, iwork, liwork, bwork, linfo )
744 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
746 WRITE( nout, fmt = 9998 )
'CGGESX', linfo, mplusn, nptknt
753 CALL clacpy(
'Full', mplusn, mplusn, ai, lda, work, mplusn )
754 CALL clacpy(
'Full', mplusn, mplusn, bi, lda,
755 $ work( mplusn*mplusn+1 ), mplusn )
756 abnrm =
clange(
'Fro', mplusn, 2*mplusn, work, mplusn, rwork )
760 CALL cget51( 1, mplusn, a, lda, ai, lda, q, lda, z, lda, work,
761 $ rwork, result( 1 ) )
762 CALL cget51( 1, mplusn, b, lda, bi, lda, q, lda, z, lda, work,
763 $ rwork, result( 2 ) )
764 CALL cget51( 3, mplusn, b, lda, bi, lda, q, lda, q, lda, work,
765 $ rwork, result( 3 ) )
766 CALL cget51( 3, mplusn, b, lda, bi, lda, z, lda, z, lda, work,
767 $ rwork, result( 4 ) )
779 temp2 = ( abs1(
alpha( j )-ai( j, j ) ) /
780 $
max( smlnum, abs1(
alpha( j ) ), abs1( ai( j, j ) ) )+
781 $ abs1( beta( j )-bi( j, j ) ) /
782 $
max( smlnum, abs1( beta( j ) ), abs1( bi( j, j ) ) ) )
784 IF( j.LT.mplusn )
THEN
785 IF( ai( j+1, j ).NE.zero )
THEN
791 IF( ai( j, j-1 ).NE.zero )
THEN
796 temp1 =
max( temp1, temp2 )
798 WRITE( nout, fmt = 9997 )j, mplusn, nptknt
807 IF( linfo.EQ.mplusn+3 )
808 $ result( 7 ) = ulpinv
814 IF( difest( 2 ).EQ.zero )
THEN
815 IF( diftru.GT.abnrm*ulp )
816 $ result( 8 ) = ulpinv
817 ELSE IF( diftru.EQ.zero )
THEN
818 IF( difest( 2 ).GT.abnrm*ulp )
819 $ result( 8 ) = ulpinv
820 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
821 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
822 result( 8 ) =
max( diftru / difest( 2 ), difest( 2 ) / diftru )
829 IF( linfo.EQ.( mplusn+2 ) )
THEN
830 IF( diftru.GT.abnrm*ulp )
831 $ result( 9 ) = ulpinv
832 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
833 $ result( 9 ) = ulpinv
834 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
835 $ result( 9 ) = ulpinv
842 IF( pl( 1 ).EQ.zero )
THEN
843 IF( pltru.GT.abnrm*ulp )
844 $ result( 10 ) = ulpinv
845 ELSE IF( pltru.EQ.zero )
THEN
846 IF( pl( 1 ).GT.abnrm*ulp )
847 $ result( 10 ) = ulpinv
848 ELSE IF( ( pltru.GT.thresh*pl( 1 ) ) .OR.
849 $ ( pltru*thresh.LT.pl( 1 ) ) )
THEN
850 result( 10 ) = ulpinv
853 ntestt = ntestt + ntest
858 IF( result( j ).GE.thresh )
THEN
863 IF( nerrs.EQ.0 )
THEN
864 WRITE( nout, fmt = 9996 )
'CGX'
868 WRITE( nout, fmt = 9995 )
872 WRITE( nout, fmt = 9993 )
'unitary',
'''',
'transpose',
877 IF( result( j ).LT.10000.0 )
THEN
878 WRITE( nout, fmt = 9990 )nptknt, mplusn, j, result( j )
880 WRITE( nout, fmt = 9989 )nptknt, mplusn, j, result( j )
894 CALL alasvm(
'CGX', nout, nerrs, ntestt, 0 )
900 9999
FORMAT(
' CDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
901 $ i6,
', JTYPE=', i6,
')' )
903 9998
FORMAT(
' CDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
904 $ i6,
', Input Example #', i2,
')' )
906 9997
FORMAT(
' CDRGSX: S not in Schur form at eigenvalue ', i6,
'.',
907 $ / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
909 9996
FORMAT( / 1x, a3,
' -- Complex Expert Generalized Schur form',
910 $
' problem driver' )
912 9995
FORMAT(
'Input Example' )
914 9994
FORMAT(
' Matrix types: ', /
915 $ ' 1: a is a block diagonal matrix of jordan blocks
',
916 $ 'and b is
the identity
', / ' matrix,
',
917 $ / ' 2: a and b are upper triangular matrices,
',
918 $ / ' 3: a and b are as
type 2, but each
second diagonal
',
919 $ 'block in a_11 and
', /
920 $ ' each third diaongal block in a_22 are 2x2 blocks,
',
921 $ / ' 4: a and b are block diagonal matrices,
',
922 $ / ' 5: (a,b) has potentially
close or
common ',
923 $ 'eigenvalues.
', / )
925 9993 FORMAT( / ' tests performed: (s is schur, t is triangular,
',
926 $ 'q and z are
', A, ',
', / 19X,
927 $ ' a is
alpha, b is beta, and
', A, ' means
', A, '.)
',
928 $ / ' 1 = | a - q s z
', A,
929 $ ' | / ( |a| n ulp ) 2 = | b - q t z
', A,
930 $ ' | / ( |b| n ulp )
', / ' 3 = | i - qq
', A,
931 $ ' | / ( n ulp ) 4 = | i - zz
', A,
932 $ ' | / ( n ulp )
', / ' 5 = 1/ulp
if a is not in
',
933 $ 'schur form s
', / ' 6 = difference between(
alpha,beta)
',
934 $ ' and diagonals of(s,t)
', /
935 $ ' 7 = 1/ulp
if sdim is not
the correct number of
',
936 $ 'selected eigenvalues
', /
937 $ ' 8 = 1/ulp
if difest/diftru > 10*thresh or
',
938 $ 'diftru/difest > 10*thresh
',
939 $ / ' 9 = 1/ulp
if difest <> 0 or diftru > ulp*
norm(a,b)
',
940 $ 'when reordering fails
', /
941 $ ' 10 = 1/ulp
if plest/pltru > thresh or
',
942 $ 'pltru/plest > thresh
', /
943 $ ' ( test 10 is only
for input examples )
', / )
944 9992 FORMAT( ' matrix order=
', I2, ', type=
', I2, ', a=
', E10.3,
945 $ ', order(a_11)=
', I2, ', result
', I2, ' is
', 0P, F8.2 )
946 9991 FORMAT( ' matrix order=
', I2, ', type=
', I2, ', a=
', E10.3,
947 $ ', order(a_11)=
', I2, ', result
', I2, ' is
', 0P, E10.3 )
948 9990 FORMAT( ' input example
#', I2, ', matrix order=', I4, ',',
949 $
' result ', i2,
' is', 0p, f8.2 )
950 9989
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
951 $
' result ', i2,
' is', 1p, e10.3 )