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 )
subroutine alasvm(type, nout, nfail, nrun, nerrs)
ALASVM
subroutine xerbla(srname, info)
subroutine cdrgsx(nsize, ncmax, thresh, nin, nout, a, lda, b, ai, bi, z, q, alpha, beta, c, ldc, s, work, lwork, rwork, iwork, liwork, bwork, info)
CDRGSX
subroutine cget51(itype, n, a, lda, b, ldb, u, ldu, v, ldv, work, rwork, result)
CGET51
subroutine clakf2(m, n, a, lda, b, d, e, z, ldz)
CLAKF2
subroutine clatm5(prtype, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, r, ldr, l, ldl, alpha, qblcka, qblckb)
CLATM5
logical function clctsx(alpha, beta)
CLCTSX
subroutine cgesvd(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info)
CGESVD computes the singular value decomposition (SVD) for GE matrices
subroutine cggesx(jobvsl, jobvsr, sort, selctg, sense, n, a, lda, b, ldb, sdim, alpha, beta, vsl, ldvsl, vsr, ldvsr, rconde, rcondv, work, lwork, rwork, iwork, liwork, bwork, info)
CGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE ...
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
real function clange(norm, m, n, a, lda, work)
CLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.