356 SUBROUTINE sdrgsx( NSIZE, NCMAX, THRESH, NIN, NOUT, A, LDA, B,
357 $ AI, BI, Z, Q, ALPHAR, ALPHAI, BETA, C, LDC, S,
358 $ WORK, LWORK, IWORK, LIWORK, BWORK, INFO )
365 INTEGER INFO, LDA, LDC, LIWORK, LWORK, NCMAX, NIN,
372 REAL A( LDA, * ), AI( LDA, * ), ALPHAI( * ),
373 $ alphar( * ), b( lda, * ), beta( * ),
374 $ bi( lda, * ), c( ldc, * ), q( lda, * ), s( * ),
375 $ work( * ), z( lda, * )
382 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0, ten = 1.0e+1 )
387 INTEGER BDSPAC, I, I1, IFUNC, IINFO, J, LINFO, MAXWRK,
388 $ minwrk, mm, mn2, nerrs, nptknt, ntest, ntestt,
390 REAL ABNRM, BIGNUM, DIFTRU, PLTRU, SMLNUM, TEMP1,
391 $ TEMP2, THRSH2, ULP, ULPINV, WEIGHT
394 REAL DIFEST( 2 ), PL( 2 ), RESULT( 10 )
400 EXTERNAL slctsx, ilaenv, slamch, slange
407 INTRINSIC abs, max, sqrt
411 INTEGER K, M, MPLUSN, N
414 COMMON / mn / m, n, mplusn, k, fs
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+6 )
THEN
444 IF( info.EQ.0 .AND. lwork.GE.1 )
THEN
446 minwrk = max( 10*( nsize+1 ), 5*nsize*nsize / 2 )
450 maxwrk = 9*( nsize+1 ) + nsize*
451 $ ilaenv( 1,
'SGEQRF',
' ', nsize, 1, nsize, 0 )
452 maxwrk = max( maxwrk, 9*( nsize+1 )+nsize*
453 $ ilaenv( 1,
'SORGQR',
' ', nsize, 1, nsize, -1 ) )
457 bdspac = 5*nsize*nsize / 2
458 maxwrk = max( maxwrk, 3*nsize*nsize / 2+nsize*nsize*
459 $ ilaenv( 1,
'SGEBRD',
' ', 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(
'SDRGSX', -info )
480 smlnum = slamch(
'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 slaset(
'Full', mplusn, mplusn, zero, zero, ai,
516 CALL slaset(
'Full', mplusn, mplusn, zero, zero, bi,
519 CALL slatm5( 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 slacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
540 CALL slacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
542 CALL sggesx(
'V',
'V',
'S', slctsx, sense, mplusn, ai,
543 $ lda, bi, lda, mm, alphar, alphai, beta,
544 $ q, lda, z, lda, pl, difest, work, lwork,
545 $ iwork, liwork, bwork, linfo )
547 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
549 WRITE( nout, fmt = 9999 )
'SGGESX', linfo, mplusn,
557 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, work,
559 CALL slacpy(
'Full', mplusn, mplusn, bi, lda,
560 $ work( mplusn*mplusn+1 ), mplusn )
561 abnrm = slange(
'Fro', mplusn, 2*mplusn, work, mplusn,
566 CALL sget51( 1, mplusn, a, lda, ai, lda, q, lda, z,
567 $ lda, work, result( 1 ) )
568 CALL sget51( 1, mplusn, b, lda, bi, lda, q, lda, z,
569 $ lda, work, result( 2 ) )
570 CALL sget51( 3, mplusn, b, lda, bi, lda, q, lda, q,
571 $ lda, work, result( 3 ) )
572 CALL sget51( 3, mplusn, b, lda, bi, lda, z, lda, z,
573 $ lda, work, result( 4 ) )
585 IF( alphai( j ).EQ.zero )
THEN
586 temp2 = ( abs( alphar( j )-ai( j, j ) ) /
587 $ max( smlnum, abs( alphar( j ) ),
588 $ abs( ai( j, j ) ) )+
589 $ abs( beta( j )-bi( j, j ) ) /
590 $ max( smlnum, abs( beta( j ) ),
591 $ abs( 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
605 IF( alphai( j ).GT.zero )
THEN
610 IF( i1.LE.0 .OR. i1.GE.mplusn )
THEN
612 ELSE IF( i1.LT.mplusn-1 )
THEN
613 IF( ai( i1+2, i1+1 ).NE.zero )
THEN
617 ELSE IF( i1.GT.1 )
THEN
618 IF( ai( i1, i1-1 ).NE.zero )
THEN
623 IF( .NOT.ilabad )
THEN
624 CALL sget53( ai( i1, i1 ), lda, bi( i1, i1 ),
625 $ lda, beta( j ), alphar( j ),
626 $ alphai( j ), temp2, iinfo )
627 IF( iinfo.GE.3 )
THEN
628 WRITE( nout, fmt = 9997 )iinfo, j,
636 temp1 = max( temp1, temp2 )
638 WRITE( nout, fmt = 9996 )j, mplusn, prtype
647 IF( linfo.EQ.mplusn+3 )
THEN
649 ELSE IF( mm.NE.n )
THEN
658 mn2 = mm*( mplusn-mm )*2
659 IF( ifunc.GE.2 .AND. mn2.LE.ncmax*ncmax )
THEN
664 CALL slakf2( mm, mplusn-mm, ai, lda,
665 $ ai( mm+1, mm+1 ), bi,
666 $ bi( mm+1, mm+1 ), c, ldc )
668 CALL sgesvd(
'N',
'N', mn2, mn2, c, ldc, s, work,
669 $ 1, work( 2 ), 1, work( 3 ), lwork-2,
673 IF( difest( 2 ).EQ.zero )
THEN
674 IF( diftru.GT.abnrm*ulp )
675 $ result( 8 ) = ulpinv
676 ELSE IF( diftru.EQ.zero )
THEN
677 IF( difest( 2 ).GT.abnrm*ulp )
678 $ result( 8 ) = ulpinv
679 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
680 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
681 result( 8 ) = max( diftru / difest( 2 ),
682 $ difest( 2 ) / diftru )
690 IF( linfo.EQ.( mplusn+2 ) )
THEN
691 IF( diftru.GT.abnrm*ulp )
692 $ result( 9 ) = ulpinv
693 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
694 $ result( 9 ) = ulpinv
695 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
696 $ result( 9 ) = ulpinv
700 ntestt = ntestt + ntest
705 IF( result( j ).GE.thresh )
THEN
710 IF( nerrs.EQ.0 )
THEN
711 WRITE( nout, fmt = 9995 )
'SGX'
715 WRITE( nout, fmt = 9993 )
719 WRITE( nout, fmt = 9992 )
'orthogonal',
'''',
720 $
'transpose', (
'''', i = 1, 4 )
724 IF( result( j ).LT.10000.0 )
THEN
725 WRITE( nout, fmt = 9991 )mplusn, prtype,
726 $ weight, m, j, result( j )
728 WRITE( nout, fmt = 9990 )mplusn, prtype,
729 $ weight, m, j, result( j )
749 READ( nin, fmt = *,
END = 140 )mplusn
752 READ( nin, fmt = *,
END = 140 )n
754 READ( nin, fmt = * )( ai( i, j ), j = 1, mplusn )
757 READ( nin, fmt = * )( bi( i, j ), j = 1, mplusn )
759 READ( nin, fmt = * )pltru, diftru
766 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, a, lda )
767 CALL slacpy(
'Full', mplusn, mplusn, bi, lda, b, lda )
772 CALL sggesx(
'V',
'V',
'S',
slctsx,
'B', mplusn, ai, lda, bi, lda,
773 $ mm, alphar, alphai, beta, q, lda, z, lda, pl, difest,
774 $ work, lwork, iwork, liwork, bwork, linfo )
776 IF( linfo.NE.0 .AND. linfo.NE.mplusn+2 )
THEN
778 WRITE( nout, fmt = 9998 )
'SGGESX', linfo, mplusn, nptknt
785 CALL slacpy(
'Full', mplusn, mplusn, ai, lda, work, mplusn )
786 CALL slacpy(
'Full', mplusn, mplusn, bi, lda,
787 $ work( mplusn*mplusn+1 ), mplusn )
788 abnrm =
slange(
'Fro', mplusn, 2*mplusn, work, mplusn, work )
792 CALL sget51( 1, mplusn, a, lda, ai, lda, q, lda, z, lda, work,
794 CALL sget51( 1, mplusn, b, lda, bi, lda, q, lda, z, lda, work,
796 CALL sget51( 3, mplusn, b, lda, bi, lda, q, lda, q, lda, work,
798 CALL sget51( 3, mplusn, b, lda, bi, lda, z, lda, z, lda, work,
811 IF( alphai( j ).EQ.zero )
THEN
812 temp2 = ( abs( alphar( j )-ai( j, j ) ) /
813 $ max( smlnum, abs( alphar( j ) ), abs( ai( j,
814 $ j ) ) )+abs( beta( j )-bi( j, j ) ) /
815 $ max( smlnum, abs( beta( j ) ), abs( bi( j, j ) ) ) )
817 IF( j.LT.mplusn )
THEN
818 IF( ai( j+1, j ).NE.zero )
THEN
824 IF( ai( j, j-1 ).NE.zero )
THEN
830 IF( alphai( j ).GT.zero )
THEN
835 IF( i1.LE.0 .OR. i1.GE.mplusn )
THEN
837 ELSE IF( i1.LT.mplusn-1 )
THEN
838 IF( ai( i1+2, i1+1 ).NE.zero )
THEN
842 ELSE IF( i1.GT.1 )
THEN
843 IF( ai( i1, i1-1 ).NE.zero )
THEN
848 IF( .NOT.ilabad )
THEN
849 CALL sget53( ai( i1, i1 ), lda, bi( i1, i1 ), lda,
850 $ beta( j ), alphar( j ), alphai( j ), temp2,
852 IF( iinfo.GE.3 )
THEN
853 WRITE( nout, fmt = 9997 )iinfo, j, mplusn, nptknt
860 temp1 = max( temp1, temp2 )
862 WRITE( nout, fmt = 9996 )j, mplusn, nptknt
871 IF( linfo.EQ.mplusn+3 )
872 $ result( 7 ) = ulpinv
878 IF( difest( 2 ).EQ.zero )
THEN
879 IF( diftru.GT.abnrm*ulp )
880 $ result( 8 ) = ulpinv
881 ELSE IF( diftru.EQ.zero )
THEN
882 IF( difest( 2 ).GT.abnrm*ulp )
883 $ result( 8 ) = ulpinv
884 ELSE IF( ( diftru.GT.thrsh2*difest( 2 ) ) .OR.
885 $ ( diftru*thrsh2.LT.difest( 2 ) ) )
THEN
886 result( 8 ) = max( diftru / difest( 2 ), difest( 2 ) / diftru )
893 IF( linfo.EQ.( mplusn+2 ) )
THEN
894 IF( diftru.GT.abnrm*ulp )
895 $ result( 9 ) = ulpinv
896 IF( ( ifunc.GT.1 ) .AND. ( difest( 2 ).NE.zero ) )
897 $ result( 9 ) = ulpinv
898 IF( ( ifunc.EQ.1 ) .AND. ( pl( 1 ).NE.zero ) )
899 $ result( 9 ) = ulpinv
906 IF( pl( 1 ).EQ.zero )
THEN
907 IF( pltru.GT.abnrm*ulp )
908 $ result( 10 ) = ulpinv
909 ELSE IF( pltru.EQ.zero )
THEN
910 IF( pl( 1 ).GT.abnrm*ulp )
911 $ result( 10 ) = ulpinv
912 ELSE IF( ( pltru.GT.thresh*pl( 1 ) ) .OR.
913 $ ( pltru*thresh.LT.pl( 1 ) ) )
THEN
914 result( 10 ) = ulpinv
917 ntestt = ntestt + ntest
922 IF( result( j ).GE.thresh )
THEN
927 IF( nerrs.EQ.0 )
THEN
928 WRITE( nout, fmt = 9995 )
'SGX'
932 WRITE( nout, fmt = 9994 )
936 WRITE( nout, fmt = 9992 )
'orthogonal',
'''',
937 $
'transpose', (
'''', i = 1, 4 )
941 IF( result( j ).LT.10000.0 )
THEN
942 WRITE( nout, fmt = 9989 )nptknt, mplusn, j, result( j )
944 WRITE( nout, fmt = 9988 )nptknt, mplusn, j, result( j )
958 CALL alasvm(
'SGX', nout, nerrs, ntestt, 0 )
964 9999
FORMAT(
' SDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
965 $ i6,
', JTYPE=', i6,
')' )
967 9998
FORMAT(
' SDRGSX: ', a,
' returned INFO=', i6,
'.', / 9x,
'N=',
968 $ i6,
', Input Example #', i2,
')' )
970 9997
FORMAT(
' SDRGSX: SGET53 returned INFO=', i1,
' for eigenvalue ',
971 $ i6,
'.', / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
973 9996
FORMAT(
' SDRGSX: S not in Schur form at eigenvalue ', i6,
'.',
974 $ / 9x,
'N=', i6,
', JTYPE=', i6,
')' )
976 9995
FORMAT( / 1x, a3,
' -- Real Expert Generalized Schur form',
977 $
' problem driver' )
979 9994
FORMAT(
'Input Example' )
981 9993
FORMAT(
' Matrix types: ', /
982 $
' 1: A is a block diagonal matrix of Jordan blocks ',
983 $
'and B is the identity ', /
' matrix, ',
984 $ /
' 2: A and B are upper triangular matrices, ',
985 $ /
' 3: A and B are as type 2, but each second diagonal ',
986 $
'block in A_11 and ', /
987 $
' each third diagonal block in A_22 are 2x2 blocks,',
988 $ /
' 4: A and B are block diagonal matrices, ',
989 $ /
' 5: (A,B) has potentially close or common ',
990 $
'eigenvalues.', / )
992 9992
FORMAT( /
' Tests performed: (S is Schur, T is triangular, ',
993 $
'Q and Z are ', a,
',', / 19x,
994 $
' a is alpha, b is beta, and ', a,
' means ', a,
'.)',
995 $ /
' 1 = | A - Q S Z', a,
996 $
' | / ( |A| n ulp ) 2 = | B - Q T Z', a,
997 $
' | / ( |B| n ulp )', /
' 3 = | I - QQ', a,
998 $
' | / ( n ulp ) 4 = | I - ZZ', a,
999 $
' | / ( n ulp )', /
' 5 = 1/ULP if A is not in ',
1000 $
'Schur form S', /
' 6 = difference between (alpha,beta)',
1001 $
' and diagonals of (S,T)', /
1002 $
' 7 = 1/ULP if SDIM is not the correct number of ',
1003 $
'selected eigenvalues', /
1004 $
' 8 = 1/ULP if DIFEST/DIFTRU > 10*THRESH or ',
1005 $
'DIFTRU/DIFEST > 10*THRESH',
1006 $ /
' 9 = 1/ULP if DIFEST <> 0 or DIFTRU > ULP*norm(A,B) ',
1007 $
'when reordering fails', /
1008 $
' 10 = 1/ULP if PLEST/PLTRU > THRESH or ',
1009 $
'PLTRU/PLEST > THRESH', /
1010 $
' ( Test 10 is only for input examples )', / )
1011 9991
FORMAT(
' Matrix order=', i2,
', type=', i2,
', a=', e10.3,
1012 $
', order(A_11)=', i2,
', result ', i2,
' is ', 0p, f8.2 )
1013 9990
FORMAT(
' Matrix order=', i2,
', type=', i2,
', a=', e10.3,
1014 $
', order(A_11)=', i2,
', result ', i2,
' is ', 0p, e10.3 )
1015 9989
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
1016 $
' result ', i2,
' is', 0p, f8.2 )
1017 9988
FORMAT(
' Input example #', i2,
', matrix order=', i4,
',',
1018 $
' result ', i2,
' is', 1p, e10.3 )
subroutine alasvm(type, nout, nfail, nrun, nerrs)
ALASVM
subroutine xerbla(srname, info)
subroutine sgesvd(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, info)
SGESVD computes the singular value decomposition (SVD) for GE matrices
subroutine sggesx(jobvsl, jobvsr, sort, selctg, sense, n, a, lda, b, ldb, sdim, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, rconde, rcondv, work, lwork, iwork, liwork, bwork, info)
SGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE ...
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
real function slange(norm, m, n, a, lda, work)
SLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine sdrgsx(nsize, ncmax, thresh, nin, nout, a, lda, b, ai, bi, z, q, alphar, alphai, beta, c, ldc, s, work, lwork, iwork, liwork, bwork, info)
SDRGSX
subroutine sget51(itype, n, a, lda, b, ldb, u, ldu, v, ldv, work, result)
SGET51
subroutine sget53(a, lda, b, ldb, scale, wr, wi, result, info)
SGET53
subroutine slakf2(m, n, a, lda, b, d, e, z, ldz)
SLAKF2
subroutine slatm5(prtype, m, n, a, lda, b, ldb, c, ldc, d, ldd, e, lde, f, ldf, r, ldr, l, ldl, alpha, qblcka, qblckb)
SLATM5
logical function slctsx(ar, ai, beta)
SLCTSX