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 A( 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, WEIGHT
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
503 DO 40 m = 1, nsize - 1
504 DO 30 n = 1, nsize - m
506 weight = one / weight
514 CALL zlaset(
'Full', mplusn, mplusn, czero, czero, ai,
516 CALL zlaset(
'Full', mplusn, mplusn, czero, czero, bi,
519 CALL zlatm5( 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 zlacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
540 CALL zlacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
542 CALL zggesx(
'V',
'V',
'S', zlctsx, 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 )
'ZGGESX', linfo, mplusn,
557 CALL zlacpy(
'Full', mplusn, mplusn, ai, lda, work,
559 CALL zlacpy(
'Full', mplusn, mplusn, bi, lda,
560 $ work( mplusn*mplusn+1 ), mplusn )
561 abnrm = zlange(
'Fro', mplusn, 2*mplusn, work, mplusn,
567 CALL zget51( 1, mplusn, a, lda, ai, lda, q, lda, z,
568 $ lda, work, rwork, result( 1 ) )
569 CALL zget51( 1, mplusn, b, lda, bi, lda, q, lda, z,
570 $ lda, work, rwork, result( 2 ) )
571 CALL zget51( 3, mplusn, b, lda, bi, lda, q, lda, q,
572 $ lda, work, rwork, result( 3 ) )
573 CALL zget51( 3, mplusn, b, lda, bi, lda, z, lda, z,
574 $ lda, work, rwork, result( 4 ) )
586 temp2 = ( abs1( alpha( j )-ai( j, j ) ) /
587 $ max( smlnum, abs1( alpha( 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 zlakf2( mm, mplusn-mm, ai, lda,
633 $ ai( mm+1, mm+1 ), bi,
634 $ bi( mm+1, mm+1 ), c, ldc )
636 CALL zgesvd(
'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 )
'ZGX'
683 WRITE( nout, fmt = 9994 )
687 WRITE( nout, fmt = 9993 )
'unitary',
'''',
688 $
'transpose', (
'''', i = 1, 4 )
692 IF( result( j ).LT.10000.0d0 )
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 zlacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
735 CALL zlacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
740 CALL zggesx(
'V',
'V',
'S',
zlctsx,
'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 )
'ZGGESX', linfo, mplusn, nptknt
753 CALL zlacpy(
'Full', mplusn, mplusn, ai, lda, work, mplusn )
754 CALL zlacpy(
'Full', mplusn, mplusn, bi, lda,
755 $ work( mplusn*mplusn+1 ), mplusn )
756 abnrm =
zlange(
'Fro', mplusn, 2*mplusn, work, mplusn, rwork )
760 CALL zget51( 1, mplusn, a, lda, ai, lda, q, lda, z, lda, work,
761 $ rwork, result( 1 ) )
762 CALL zget51( 1, mplusn, b, lda, bi, lda, q, lda, z, lda, work,
763 $ rwork, result( 2 ) )
764 CALL zget51( 3, mplusn, b, lda, bi, lda, q, lda, q, lda, work,
765 $ rwork, result( 3 ) )
766 CALL zget51( 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 )
'ZGX'
868 WRITE( nout, fmt = 9995 )
872 WRITE( nout, fmt = 9993 )
'unitary',
'''',
'transpose',
877 IF( result( j ).LT.10000.0d0 )
THEN
878 WRITE( nout, fmt = 9990 )nptknt, mplusn, j, result( j )
880 WRITE( nout, fmt = 9989 )nptknt, mplusn, j, result( j )
894 CALL alasvm(
'ZGX', nout, nerrs, ntestt, 0 )
900 9999
FORMAT(
' ZDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
901 $ i6,
', JTYPE=', i6,
')' )
903 9998
FORMAT(
' ZDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
904 $ i6,
', Input Example #', i2,
')' )
906 9997
FORMAT(
' ZDRGSX: 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 diagonal 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=', d10.3,
945 $
', order(A_11)=', i2,
', result ', i2,
' is ', 0p, f8.2 )
946 9991
FORMAT(
' Matrix order=', i2,
', type=', i2,
', a=', d10.3,
947 $
', order(A_11)=', i2,
', result ', i2,
' is ', 0p, d10.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, d10.3 )
subroutine alasvm(type, nout, nfail, nrun, nerrs)
ALASVM
subroutine xerbla(srname, info)
subroutine zgesvd(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info)
ZGESVD computes the singular value decomposition (SVD) for GE matrices
subroutine zggesx(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)
ZGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE ...
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
double precision function zlange(norm, m, n, a, lda, work)
ZLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine zdrgsx(nsize, ncmax, thresh, nin, nout, a, lda, b, ai, bi, z, q, alpha, beta, c, ldc, s, work, lwork, rwork, iwork, liwork, bwork, info)
ZDRGSX
subroutine zget51(itype, n, a, lda, b, ldb, u, ldu, v, ldv, work, rwork, result)
ZGET51
subroutine zlakf2(m, n, a, lda, b, d, e, z, ldz)
ZLAKF2
subroutine zlatm5(prtype, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, r, ldr, l, ldl, alpha, qblcka, qblckb)
ZLATM5
logical function zlctsx(alpha, beta)
ZLCTSX