LAPACK 3.3.1
Linear Algebra PACKage

sdrgsx.f

Go to the documentation of this file.
00001       SUBROUTINE SDRGSX( NSIZE, NCMAX, THRESH, NIN, NOUT, A, LDA, B,
00002      $                   AI, BI, Z, Q, ALPHAR, ALPHAI, BETA, C, LDC, S,
00003      $                   WORK, LWORK, IWORK, LIWORK, BWORK, INFO )
00004 *
00005 *  -- LAPACK test routine (version 3.3.1) --
00006 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00007 *  -- April 2011                                                      --
00008 *
00009 *     .. Scalar Arguments ..
00010       INTEGER            INFO, LDA, LDC, LIWORK, LWORK, NCMAX, NIN,
00011      $                   NOUT, NSIZE
00012       REAL               THRESH
00013 *     ..
00014 *     .. Array Arguments ..
00015       LOGICAL            BWORK( * )
00016       INTEGER            IWORK( * )
00017       REAL               A( LDA, * ), AI( LDA, * ), ALPHAI( * ),
00018      $                   ALPHAR( * ), B( LDA, * ), BETA( * ),
00019      $                   BI( LDA, * ), C( LDC, * ), Q( LDA, * ), S( * ),
00020      $                   WORK( * ), Z( LDA, * )
00021 *     ..
00022 *
00023 *  Purpose
00024 *  =======
00025 *
00026 *  SDRGSX checks the nonsymmetric generalized eigenvalue (Schur form)
00027 *  problem expert driver SGGESX.
00028 *
00029 *  SGGESX factors A and B as Q S Z' and Q T Z', where ' means
00030 *  transpose, T is upper triangular, S is in generalized Schur form
00031 *  (block upper triangular, with 1x1 and 2x2 blocks on the diagonal,
00032 *  the 2x2 blocks corresponding to complex conjugate pairs of
00033 *  generalized eigenvalues), and Q and Z are orthogonal.  It also
00034 *  computes the generalized eigenvalues (alpha(1),beta(1)), ...,
00035 *  (alpha(n),beta(n)). Thus, w(j) = alpha(j)/beta(j) is a root of the
00036 *  characteristic equation
00037 *
00038 *      det( A - w(j) B ) = 0
00039 *
00040 *  Optionally it also reorders the eigenvalues so that a selected
00041 *  cluster of eigenvalues appears in the leading diagonal block of the
00042 *  Schur forms; computes a reciprocal condition number for the average
00043 *  of the selected eigenvalues; and computes a reciprocal condition
00044 *  number for the right and left deflating subspaces corresponding to
00045 *  the selected eigenvalues.
00046 *
00047 *  When SDRGSX is called with NSIZE > 0, five (5) types of built-in
00048 *  matrix pairs are used to test the routine SGGESX.
00049 *
00050 *  When SDRGSX is called with NSIZE = 0, it reads in test matrix data
00051 *  to test SGGESX.
00052 *
00053 *  For each matrix pair, the following tests will be performed and
00054 *  compared with the threshhold THRESH except for the tests (7) and (9):
00055 *
00056 *  (1)   | A - Q S Z' | / ( |A| n ulp )
00057 *
00058 *  (2)   | B - Q T Z' | / ( |B| n ulp )
00059 *
00060 *  (3)   | I - QQ' | / ( n ulp )
00061 *
00062 *  (4)   | I - ZZ' | / ( n ulp )
00063 *
00064 *  (5)   if A is in Schur form (i.e. quasi-triangular form)
00065 *
00066 *  (6)   maximum over j of D(j)  where:
00067 *
00068 *        if alpha(j) is real:
00069 *                      |alpha(j) - S(j,j)|        |beta(j) - T(j,j)|
00070 *            D(j) = ------------------------ + -----------------------
00071 *                   max(|alpha(j)|,|S(j,j)|)   max(|beta(j)|,|T(j,j)|)
00072 *
00073 *        if alpha(j) is complex:
00074 *                                  | det( s S - w T ) |
00075 *            D(j) = ---------------------------------------------------
00076 *                   ulp max( s norm(S), |w| norm(T) )*norm( s S - w T )
00077 *
00078 *            and S and T are here the 2 x 2 diagonal blocks of S and T
00079 *            corresponding to the j-th and j+1-th eigenvalues.
00080 *
00081 *  (7)   if sorting worked and SDIM is the number of eigenvalues
00082 *        which were selected.
00083 *
00084 *  (8)   the estimated value DIF does not differ from the true values of
00085 *        Difu and Difl more than a factor 10*THRESH. If the estimate DIF
00086 *        equals zero the corresponding true values of Difu and Difl
00087 *        should be less than EPS*norm(A, B). If the true value of Difu
00088 *        and Difl equal zero, the estimate DIF should be less than
00089 *        EPS*norm(A, B).
00090 *
00091 *  (9)   If INFO = N+3 is returned by SGGESX, the reordering "failed"
00092 *        and we check that DIF = PL = PR = 0 and that the true value of
00093 *        Difu and Difl is < EPS*norm(A, B). We count the events when
00094 *        INFO=N+3.
00095 *
00096 *  For read-in test matrices, the above tests are run except that the
00097 *  exact value for DIF (and PL) is input data.  Additionally, there is
00098 *  one more test run for read-in test matrices:
00099 *
00100 *  (10)  the estimated value PL does not differ from the true value of
00101 *        PLTRU more than a factor THRESH. If the estimate PL equals
00102 *        zero the corresponding true value of PLTRU should be less than
00103 *        EPS*norm(A, B). If the true value of PLTRU equal zero, the
00104 *        estimate PL should be less than EPS*norm(A, B).
00105 *
00106 *  Note that for the built-in tests, a total of 10*NSIZE*(NSIZE-1)
00107 *  matrix pairs are generated and tested. NSIZE should be kept small.
00108 *
00109 *  SVD (routine SGESVD) is used for computing the true value of DIF_u
00110 *  and DIF_l when testing the built-in test problems.
00111 *
00112 *  Built-in Test Matrices
00113 *  ======================
00114 *
00115 *  All built-in test matrices are the 2 by 2 block of triangular
00116 *  matrices
00117 *
00118 *           A = [ A11 A12 ]    and      B = [ B11 B12 ]
00119 *               [     A22 ]                 [     B22 ]
00120 *
00121 *  where for different type of A11 and A22 are given as the following.
00122 *  A12 and B12 are chosen so that the generalized Sylvester equation
00123 *
00124 *           A11*R - L*A22 = -A12
00125 *           B11*R - L*B22 = -B12
00126 *
00127 *  have prescribed solution R and L.
00128 *
00129 *  Type 1:  A11 = J_m(1,-1) and A_22 = J_k(1-a,1).
00130 *           B11 = I_m, B22 = I_k
00131 *           where J_k(a,b) is the k-by-k Jordan block with ``a'' on
00132 *           diagonal and ``b'' on superdiagonal.
00133 *
00134 *  Type 2:  A11 = (a_ij) = ( 2(.5-sin(i)) ) and
00135 *           B11 = (b_ij) = ( 2(.5-sin(ij)) ) for i=1,...,m, j=i,...,m
00136 *           A22 = (a_ij) = ( 2(.5-sin(i+j)) ) and
00137 *           B22 = (b_ij) = ( 2(.5-sin(ij)) ) for i=m+1,...,k, j=i,...,k
00138 *
00139 *  Type 3:  A11, A22 and B11, B22 are chosen as for Type 2, but each
00140 *           second diagonal block in A_11 and each third diagonal block
00141 *           in A_22 are made as 2 by 2 blocks.
00142 *
00143 *  Type 4:  A11 = ( 20(.5 - sin(ij)) ) and B22 = ( 2(.5 - sin(i+j)) )
00144 *              for i=1,...,m,  j=1,...,m and
00145 *           A22 = ( 20(.5 - sin(i+j)) ) and B22 = ( 2(.5 - sin(ij)) )
00146 *              for i=m+1,...,k,  j=m+1,...,k
00147 *
00148 *  Type 5:  (A,B) and have potentially close or common eigenvalues and
00149 *           very large departure from block diagonality A_11 is chosen
00150 *           as the m x m leading submatrix of A_1:
00151 *                   |  1  b                            |
00152 *                   | -b  1                            |
00153 *                   |        1+d  b                    |
00154 *                   |         -b 1+d                   |
00155 *            A_1 =  |                  d  1            |
00156 *                   |                 -1  d            |
00157 *                   |                        -d  1     |
00158 *                   |                        -1 -d     |
00159 *                   |                               1  |
00160 *           and A_22 is chosen as the k x k leading submatrix of A_2:
00161 *                   | -1  b                            |
00162 *                   | -b -1                            |
00163 *                   |       1-d  b                     |
00164 *                   |       -b  1-d                    |
00165 *            A_2 =  |                 d 1+b            |
00166 *                   |               -1-b d             |
00167 *                   |                       -d  1+b    |
00168 *                   |                      -1+b  -d    |
00169 *                   |                              1-d |
00170 *           and matrix B are chosen as identity matrices (see SLATM5).
00171 *
00172 *
00173 *  Arguments
00174 *  =========
00175 *
00176 *  NSIZE   (input) INTEGER
00177 *          The maximum size of the matrices to use. NSIZE >= 0.
00178 *          If NSIZE = 0, no built-in tests matrices are used, but
00179 *          read-in test matrices are used to test SGGESX.
00180 *
00181 *  NCMAX   (input) INTEGER
00182 *          Maximum allowable NMAX for generating Kroneker matrix
00183 *          in call to SLAKF2
00184 *
00185 *  THRESH  (input) REAL
00186 *          A test will count as "failed" if the "error", computed as
00187 *          described above, exceeds THRESH.  Note that the error
00188 *          is scaled to be O(1), so THRESH should be a reasonably
00189 *          small multiple of 1, e.g., 10 or 100.  In particular,
00190 *          it should not depend on the precision (single vs. double)
00191 *          or the size of the matrix.  THRESH >= 0.
00192 *
00193 *  NIN     (input) INTEGER
00194 *          The FORTRAN unit number for reading in the data file of
00195 *          problems to solve.
00196 *
00197 *  NOUT    (input) INTEGER
00198 *          The FORTRAN unit number for printing out error messages
00199 *          (e.g., if a routine returns IINFO not equal to 0.)
00200 *
00201 *  A       (workspace) REAL array, dimension (LDA, NSIZE)
00202 *          Used to store the matrix whose eigenvalues are to be
00203 *          computed.  On exit, A contains the last matrix actually used.
00204 *
00205 *  LDA     (input) INTEGER
00206 *          The leading dimension of A, B, AI, BI, Z and Q,
00207 *          LDA >= max( 1, NSIZE ). For the read-in test,
00208 *          LDA >= max( 1, N ), N is the size of the test matrices.
00209 *
00210 *  B       (workspace) REAL array, dimension (LDA, NSIZE)
00211 *          Used to store the matrix whose eigenvalues are to be
00212 *          computed.  On exit, B contains the last matrix actually used.
00213 *
00214 *  AI      (workspace) REAL array, dimension (LDA, NSIZE)
00215 *          Copy of A, modified by SGGESX.
00216 *
00217 *  BI      (workspace) REAL array, dimension (LDA, NSIZE)
00218 *          Copy of B, modified by SGGESX.
00219 *
00220 *  Z       (workspace) REAL array, dimension (LDA, NSIZE)
00221 *          Z holds the left Schur vectors computed by SGGESX.
00222 *
00223 *  Q       (workspace) REAL array, dimension (LDA, NSIZE)
00224 *          Q holds the right Schur vectors computed by SGGESX.
00225 *
00226 *  ALPHAR  (workspace) REAL array, dimension (NSIZE)
00227 *  ALPHAI  (workspace) REAL array, dimension (NSIZE)
00228 *  BETA    (workspace) REAL array, dimension (NSIZE)
00229 *          On exit, (ALPHAR + ALPHAI*i)/BETA are the eigenvalues.
00230 *
00231 *  C       (workspace) REAL array, dimension (LDC, LDC)
00232 *          Store the matrix generated by subroutine SLAKF2, this is the
00233 *          matrix formed by Kronecker products used for estimating
00234 *          DIF.
00235 *
00236 *  LDC     (input) INTEGER
00237 *          The leading dimension of C. LDC >= max(1, LDA*LDA/2 ).
00238 *
00239 *  S       (workspace) REAL array, dimension (LDC)
00240 *          Singular values of C
00241 *
00242 *  WORK    (workspace) REAL array, dimension (LWORK)
00243 *
00244 *  LWORK   (input) INTEGER
00245 *          The dimension of the array WORK.
00246 *          LWORK >= MAX( 5*NSIZE*NSIZE/2 - 2, 10*(NSIZE+1) )
00247 *
00248 *  IWORK   (workspace) INTEGER array, dimension (LIWORK)
00249 *
00250 *  LIWORK  (input) INTEGER
00251 *          The dimension of the array IWORK. LIWORK >= NSIZE + 6.
00252 *
00253 *  BWORK   (workspace) LOGICAL array, dimension (LDA)
00254 *
00255 *  INFO    (output) INTEGER
00256 *          = 0:  successful exit
00257 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00258 *          > 0:  A routine returned an error code.
00259 *
00260 *  =====================================================================
00261 *
00262 *     .. Parameters ..
00263       REAL               ZERO, ONE, TEN
00264       PARAMETER          ( ZERO = 0.0E+0, ONE = 1.0E+0, TEN = 1.0E+1 )
00265 *     ..
00266 *     .. Local Scalars ..
00267       LOGICAL            ILABAD
00268       CHARACTER          SENSE
00269       INTEGER            BDSPAC, I, I1, IFUNC, IINFO, J, LINFO, MAXWRK,
00270      $                   MINWRK, MM, MN2, NERRS, NPTKNT, NTEST, NTESTT,
00271      $                   PRTYPE, QBA, QBB
00272       REAL               ABNRM, BIGNUM, DIFTRU, PLTRU, SMLNUM, TEMP1,
00273      $                   TEMP2, THRSH2, ULP, ULPINV, WEIGHT
00274 *     ..
00275 *     .. Local Arrays ..
00276       REAL               DIFEST( 2 ), PL( 2 ), RESULT( 10 )
00277 *     ..
00278 *     .. External Functions ..
00279       LOGICAL            SLCTSX
00280       INTEGER            ILAENV
00281       REAL               SLAMCH, SLANGE
00282       EXTERNAL           SLCTSX, ILAENV, SLAMCH, SLANGE
00283 *     ..
00284 *     .. External Subroutines ..
00285       EXTERNAL           ALASVM, SGESVD, SGET51, SGET53, SGGESX, SLABAD,
00286      $                   SLACPY, SLAKF2, SLASET, SLATM5, XERBLA
00287 *     ..
00288 *     .. Intrinsic Functions ..
00289       INTRINSIC          ABS, MAX, SQRT
00290 *     ..
00291 *     .. Scalars in Common ..
00292       LOGICAL            FS
00293       INTEGER            K, M, MPLUSN, N
00294 *     ..
00295 *     .. Common blocks ..
00296       COMMON             / MN / M, N, MPLUSN, K, FS
00297 *     ..
00298 *     .. Executable Statements ..
00299 *
00300 *     Check for errors
00301 *
00302       IF( NSIZE.LT.0 ) THEN
00303          INFO = -1
00304       ELSE IF( THRESH.LT.ZERO ) THEN
00305          INFO = -2
00306       ELSE IF( NIN.LE.0 ) THEN
00307          INFO = -3
00308       ELSE IF( NOUT.LE.0 ) THEN
00309          INFO = -4
00310       ELSE IF( LDA.LT.1 .OR. LDA.LT.NSIZE ) THEN
00311          INFO = -6
00312       ELSE IF( LDC.LT.1 .OR. LDC.LT.NSIZE*NSIZE / 2 ) THEN
00313          INFO = -17
00314       ELSE IF( LIWORK.LT.NSIZE+6 ) THEN
00315          INFO = -21
00316       END IF
00317 *
00318 *     Compute workspace
00319 *      (Note: Comments in the code beginning "Workspace:" describe the
00320 *       minimal amount of workspace needed at that point in the code,
00321 *       as well as the preferred amount for good performance.
00322 *       NB refers to the optimal block size for the immediately
00323 *       following subroutine, as returned by ILAENV.)
00324 *
00325       MINWRK = 1
00326       IF( INFO.EQ.0 .AND. LWORK.GE.1 ) THEN
00327 c        MINWRK = MAX( 10*( NSIZE+1 ), 5*NSIZE*NSIZE / 2-2 )
00328          MINWRK = MAX( 10*( NSIZE+1 ), 5*NSIZE*NSIZE / 2 )
00329 *
00330 *        workspace for sggesx
00331 *
00332          MAXWRK = 9*( NSIZE+1 ) + NSIZE*
00333      $            ILAENV( 1, 'SGEQRF', ' ', NSIZE, 1, NSIZE, 0 )
00334          MAXWRK = MAX( MAXWRK, 9*( NSIZE+1 )+NSIZE*
00335      $            ILAENV( 1, 'SORGQR', ' ', NSIZE, 1, NSIZE, -1 ) )
00336 *
00337 *        workspace for sgesvd
00338 *
00339          BDSPAC = 5*NSIZE*NSIZE / 2
00340          MAXWRK = MAX( MAXWRK, 3*NSIZE*NSIZE / 2+NSIZE*NSIZE*
00341      $            ILAENV( 1, 'SGEBRD', ' ', NSIZE*NSIZE / 2,
00342      $            NSIZE*NSIZE / 2, -1, -1 ) )
00343          MAXWRK = MAX( MAXWRK, BDSPAC )
00344 *
00345          MAXWRK = MAX( MAXWRK, MINWRK )
00346 *
00347          WORK( 1 ) = MAXWRK
00348       END IF
00349 *
00350       IF( LWORK.LT.MINWRK )
00351      $   INFO = -19
00352 *
00353       IF( INFO.NE.0 ) THEN
00354          CALL XERBLA( 'SDRGSX', -INFO )
00355          RETURN
00356       END IF
00357 *
00358 *     Important constants
00359 *
00360       ULP = SLAMCH( 'P' )
00361       ULPINV = ONE / ULP
00362       SMLNUM = SLAMCH( 'S' ) / ULP
00363       BIGNUM = ONE / SMLNUM
00364       CALL SLABAD( SMLNUM, BIGNUM )
00365       THRSH2 = TEN*THRESH
00366       NTESTT = 0
00367       NERRS = 0
00368 *
00369 *     Go to the tests for read-in matrix pairs
00370 *
00371       IFUNC = 0
00372       IF( NSIZE.EQ.0 )
00373      $   GO TO 70
00374 *
00375 *     Test the built-in matrix pairs.
00376 *     Loop over different functions (IFUNC) of SGGESX, types (PRTYPE)
00377 *     of test matrices, different size (M+N)
00378 *
00379       PRTYPE = 0
00380       QBA = 3
00381       QBB = 4
00382       WEIGHT = SQRT( ULP )
00383 *
00384       DO 60 IFUNC = 0, 3
00385          DO 50 PRTYPE = 1, 5
00386             DO 40 M = 1, NSIZE - 1
00387                DO 30 N = 1, NSIZE - M
00388 *
00389                   WEIGHT = ONE / WEIGHT
00390                   MPLUSN = M + N
00391 *
00392 *                 Generate test matrices
00393 *
00394                   FS = .TRUE.
00395                   K = 0
00396 *
00397                   CALL SLASET( 'Full', MPLUSN, MPLUSN, ZERO, ZERO, AI,
00398      $                         LDA )
00399                   CALL SLASET( 'Full', MPLUSN, MPLUSN, ZERO, ZERO, BI,
00400      $                         LDA )
00401 *
00402                   CALL SLATM5( PRTYPE, M, N, AI, LDA, AI( M+1, M+1 ),
00403      $                         LDA, AI( 1, M+1 ), LDA, BI, LDA,
00404      $                         BI( M+1, M+1 ), LDA, BI( 1, M+1 ), LDA,
00405      $                         Q, LDA, Z, LDA, WEIGHT, QBA, QBB )
00406 *
00407 *                 Compute the Schur factorization and swapping the
00408 *                 m-by-m (1,1)-blocks with n-by-n (2,2)-blocks.
00409 *                 Swapping is accomplished via the function SLCTSX
00410 *                 which is supplied below.
00411 *
00412                   IF( IFUNC.EQ.0 ) THEN
00413                      SENSE = 'N'
00414                   ELSE IF( IFUNC.EQ.1 ) THEN
00415                      SENSE = 'E'
00416                   ELSE IF( IFUNC.EQ.2 ) THEN
00417                      SENSE = 'V'
00418                   ELSE IF( IFUNC.EQ.3 ) THEN
00419                      SENSE = 'B'
00420                   END IF
00421 *
00422                   CALL SLACPY( 'Full', MPLUSN, MPLUSN, AI, LDA, A, LDA )
00423                   CALL SLACPY( 'Full', MPLUSN, MPLUSN, BI, LDA, B, LDA )
00424 *
00425                   CALL SGGESX( 'V', 'V', 'S', SLCTSX, SENSE, MPLUSN, AI,
00426      $                         LDA, BI, LDA, MM, ALPHAR, ALPHAI, BETA,
00427      $                         Q, LDA, Z, LDA, PL, DIFEST, WORK, LWORK,
00428      $                         IWORK, LIWORK, BWORK, LINFO )
00429 *
00430                   IF( LINFO.NE.0 .AND. LINFO.NE.MPLUSN+2 ) THEN
00431                      RESULT( 1 ) = ULPINV
00432                      WRITE( NOUT, FMT = 9999 )'SGGESX', LINFO, MPLUSN,
00433      $                  PRTYPE
00434                      INFO = LINFO
00435                      GO TO 30
00436                   END IF
00437 *
00438 *                 Compute the norm(A, B)
00439 *
00440                   CALL SLACPY( 'Full', MPLUSN, MPLUSN, AI, LDA, WORK,
00441      $                         MPLUSN )
00442                   CALL SLACPY( 'Full', MPLUSN, MPLUSN, BI, LDA,
00443      $                         WORK( MPLUSN*MPLUSN+1 ), MPLUSN )
00444                   ABNRM = SLANGE( 'Fro', MPLUSN, 2*MPLUSN, WORK, MPLUSN,
00445      $                    WORK )
00446 *
00447 *                 Do tests (1) to (4)
00448 *
00449                   CALL SGET51( 1, MPLUSN, A, LDA, AI, LDA, Q, LDA, Z,
00450      $                         LDA, WORK, RESULT( 1 ) )
00451                   CALL SGET51( 1, MPLUSN, B, LDA, BI, LDA, Q, LDA, Z,
00452      $                         LDA, WORK, RESULT( 2 ) )
00453                   CALL SGET51( 3, MPLUSN, B, LDA, BI, LDA, Q, LDA, Q,
00454      $                         LDA, WORK, RESULT( 3 ) )
00455                   CALL SGET51( 3, MPLUSN, B, LDA, BI, LDA, Z, LDA, Z,
00456      $                         LDA, WORK, RESULT( 4 ) )
00457                   NTEST = 4
00458 *
00459 *                 Do tests (5) and (6): check Schur form of A and
00460 *                 compare eigenvalues with diagonals.
00461 *
00462                   TEMP1 = ZERO
00463                   RESULT( 5 ) = ZERO
00464                   RESULT( 6 ) = ZERO
00465 *
00466                   DO 10 J = 1, MPLUSN
00467                      ILABAD = .FALSE.
00468                      IF( ALPHAI( J ).EQ.ZERO ) THEN
00469                         TEMP2 = ( ABS( ALPHAR( J )-AI( J, J ) ) /
00470      $                          MAX( SMLNUM, ABS( ALPHAR( J ) ),
00471      $                          ABS( AI( J, J ) ) )+
00472      $                          ABS( BETA( J )-BI( J, J ) ) /
00473      $                          MAX( SMLNUM, ABS( BETA( J ) ),
00474      $                          ABS( BI( J, J ) ) ) ) / ULP
00475                         IF( J.LT.MPLUSN ) THEN
00476                            IF( AI( J+1, J ).NE.ZERO ) THEN
00477                               ILABAD = .TRUE.
00478                               RESULT( 5 ) = ULPINV
00479                            END IF
00480                         END IF
00481                         IF( J.GT.1 ) THEN
00482                            IF( AI( J, J-1 ).NE.ZERO ) THEN
00483                               ILABAD = .TRUE.
00484                               RESULT( 5 ) = ULPINV
00485                            END IF
00486                         END IF
00487                      ELSE
00488                         IF( ALPHAI( J ).GT.ZERO ) THEN
00489                            I1 = J
00490                         ELSE
00491                            I1 = J - 1
00492                         END IF
00493                         IF( I1.LE.0 .OR. I1.GE.MPLUSN ) THEN
00494                            ILABAD = .TRUE.
00495                         ELSE IF( I1.LT.MPLUSN-1 ) THEN
00496                            IF( AI( I1+2, I1+1 ).NE.ZERO ) THEN
00497                               ILABAD = .TRUE.
00498                               RESULT( 5 ) = ULPINV
00499                            END IF
00500                         ELSE IF( I1.GT.1 ) THEN
00501                            IF( AI( I1, I1-1 ).NE.ZERO ) THEN
00502                               ILABAD = .TRUE.
00503                               RESULT( 5 ) = ULPINV
00504                            END IF
00505                         END IF
00506                         IF( .NOT.ILABAD ) THEN
00507                            CALL SGET53( AI( I1, I1 ), LDA, BI( I1, I1 ),
00508      $                                  LDA, BETA( J ), ALPHAR( J ),
00509      $                                  ALPHAI( J ), TEMP2, IINFO )
00510                            IF( IINFO.GE.3 ) THEN
00511                               WRITE( NOUT, FMT = 9997 )IINFO, J,
00512      $                           MPLUSN, PRTYPE
00513                               INFO = ABS( IINFO )
00514                            END IF
00515                         ELSE
00516                            TEMP2 = ULPINV
00517                         END IF
00518                      END IF
00519                      TEMP1 = MAX( TEMP1, TEMP2 )
00520                      IF( ILABAD ) THEN
00521                         WRITE( NOUT, FMT = 9996 )J, MPLUSN, PRTYPE
00522                      END IF
00523    10             CONTINUE
00524                   RESULT( 6 ) = TEMP1
00525                   NTEST = NTEST + 2
00526 *
00527 *                 Test (7) (if sorting worked)
00528 *
00529                   RESULT( 7 ) = ZERO
00530                   IF( LINFO.EQ.MPLUSN+3 ) THEN
00531                      RESULT( 7 ) = ULPINV
00532                   ELSE IF( MM.NE.N ) THEN
00533                      RESULT( 7 ) = ULPINV
00534                   END IF
00535                   NTEST = NTEST + 1
00536 *
00537 *                 Test (8): compare the estimated value DIF and its
00538 *                 value. first, compute the exact DIF.
00539 *
00540                   RESULT( 8 ) = ZERO
00541                   MN2 = MM*( MPLUSN-MM )*2
00542                   IF( IFUNC.GE.2 .AND. MN2.LE.NCMAX*NCMAX ) THEN
00543 *
00544 *                    Note: for either following two causes, there are
00545 *                    almost same number of test cases fail the test.
00546 *
00547                      CALL SLAKF2( MM, MPLUSN-MM, AI, LDA,
00548      $                            AI( MM+1, MM+1 ), BI,
00549      $                            BI( MM+1, MM+1 ), C, LDC )
00550 *
00551                      CALL SGESVD( 'N', 'N', MN2, MN2, C, LDC, S, WORK,
00552      $                            1, WORK( 2 ), 1, WORK( 3 ), LWORK-2,
00553      $                            INFO )
00554                      DIFTRU = S( MN2 )
00555 *
00556                      IF( DIFEST( 2 ).EQ.ZERO ) THEN
00557                         IF( DIFTRU.GT.ABNRM*ULP )
00558      $                     RESULT( 8 ) = ULPINV
00559                      ELSE IF( DIFTRU.EQ.ZERO ) THEN
00560                         IF( DIFEST( 2 ).GT.ABNRM*ULP )
00561      $                     RESULT( 8 ) = ULPINV
00562                      ELSE IF( ( DIFTRU.GT.THRSH2*DIFEST( 2 ) ) .OR.
00563      $                        ( DIFTRU*THRSH2.LT.DIFEST( 2 ) ) ) THEN
00564                         RESULT( 8 ) = MAX( DIFTRU / DIFEST( 2 ),
00565      $                                DIFEST( 2 ) / DIFTRU )
00566                      END IF
00567                      NTEST = NTEST + 1
00568                   END IF
00569 *
00570 *                 Test (9)
00571 *
00572                   RESULT( 9 ) = ZERO
00573                   IF( LINFO.EQ.( MPLUSN+2 ) ) THEN
00574                      IF( DIFTRU.GT.ABNRM*ULP )
00575      $                  RESULT( 9 ) = ULPINV
00576                      IF( ( IFUNC.GT.1 ) .AND. ( DIFEST( 2 ).NE.ZERO ) )
00577      $                  RESULT( 9 ) = ULPINV
00578                      IF( ( IFUNC.EQ.1 ) .AND. ( PL( 1 ).NE.ZERO ) )
00579      $                  RESULT( 9 ) = ULPINV
00580                      NTEST = NTEST + 1
00581                   END IF
00582 *
00583                   NTESTT = NTESTT + NTEST
00584 *
00585 *                 Print out tests which fail.
00586 *
00587                   DO 20 J = 1, 9
00588                      IF( RESULT( J ).GE.THRESH ) THEN
00589 *
00590 *                       If this is the first test to fail,
00591 *                       print a header to the data file.
00592 *
00593                         IF( NERRS.EQ.0 ) THEN
00594                            WRITE( NOUT, FMT = 9995 )'SGX'
00595 *
00596 *                          Matrix types
00597 *
00598                            WRITE( NOUT, FMT = 9993 )
00599 *
00600 *                          Tests performed
00601 *
00602                            WRITE( NOUT, FMT = 9992 )'orthogonal', '''',
00603      $                        'transpose', ( '''', I = 1, 4 )
00604 *
00605                         END IF
00606                         NERRS = NERRS + 1
00607                         IF( RESULT( J ).LT.10000.0 ) THEN
00608                            WRITE( NOUT, FMT = 9991 )MPLUSN, PRTYPE,
00609      $                        WEIGHT, M, J, RESULT( J )
00610                         ELSE
00611                            WRITE( NOUT, FMT = 9990 )MPLUSN, PRTYPE,
00612      $                        WEIGHT, M, J, RESULT( J )
00613                         END IF
00614                      END IF
00615    20             CONTINUE
00616 *
00617    30          CONTINUE
00618    40       CONTINUE
00619    50    CONTINUE
00620    60 CONTINUE
00621 *
00622       GO TO 150
00623 *
00624    70 CONTINUE
00625 *
00626 *     Read in data from file to check accuracy of condition estimation
00627 *     Read input data until N=0
00628 *
00629       NPTKNT = 0
00630 *
00631    80 CONTINUE
00632       READ( NIN, FMT = *, END = 140 )MPLUSN
00633       IF( MPLUSN.EQ.0 )
00634      $   GO TO 140
00635       READ( NIN, FMT = *, END = 140 )N
00636       DO 90 I = 1, MPLUSN
00637          READ( NIN, FMT = * )( AI( I, J ), J = 1, MPLUSN )
00638    90 CONTINUE
00639       DO 100 I = 1, MPLUSN
00640          READ( NIN, FMT = * )( BI( I, J ), J = 1, MPLUSN )
00641   100 CONTINUE
00642       READ( NIN, FMT = * )PLTRU, DIFTRU
00643 *
00644       NPTKNT = NPTKNT + 1
00645       FS = .TRUE.
00646       K = 0
00647       M = MPLUSN - N
00648 *
00649       CALL SLACPY( 'Full', MPLUSN, MPLUSN, AI, LDA, A, LDA )
00650       CALL SLACPY( 'Full', MPLUSN, MPLUSN, BI, LDA, B, LDA )
00651 *
00652 *     Compute the Schur factorization while swaping the
00653 *     m-by-m (1,1)-blocks with n-by-n (2,2)-blocks.
00654 *
00655       CALL SGGESX( 'V', 'V', 'S', SLCTSX, 'B', MPLUSN, AI, LDA, BI, LDA,
00656      $             MM, ALPHAR, ALPHAI, BETA, Q, LDA, Z, LDA, PL, DIFEST,
00657      $             WORK, LWORK, IWORK, LIWORK, BWORK, LINFO )
00658 *
00659       IF( LINFO.NE.0 .AND. LINFO.NE.MPLUSN+2 ) THEN
00660          RESULT( 1 ) = ULPINV
00661          WRITE( NOUT, FMT = 9998 )'SGGESX', LINFO, MPLUSN, NPTKNT
00662          GO TO 130
00663       END IF
00664 *
00665 *     Compute the norm(A, B)
00666 *        (should this be norm of (A,B) or (AI,BI)?)
00667 *
00668       CALL SLACPY( 'Full', MPLUSN, MPLUSN, AI, LDA, WORK, MPLUSN )
00669       CALL SLACPY( 'Full', MPLUSN, MPLUSN, BI, LDA,
00670      $             WORK( MPLUSN*MPLUSN+1 ), MPLUSN )
00671       ABNRM = SLANGE( 'Fro', MPLUSN, 2*MPLUSN, WORK, MPLUSN, WORK )
00672 *
00673 *     Do tests (1) to (4)
00674 *
00675       CALL SGET51( 1, MPLUSN, A, LDA, AI, LDA, Q, LDA, Z, LDA, WORK,
00676      $             RESULT( 1 ) )
00677       CALL SGET51( 1, MPLUSN, B, LDA, BI, LDA, Q, LDA, Z, LDA, WORK,
00678      $             RESULT( 2 ) )
00679       CALL SGET51( 3, MPLUSN, B, LDA, BI, LDA, Q, LDA, Q, LDA, WORK,
00680      $             RESULT( 3 ) )
00681       CALL SGET51( 3, MPLUSN, B, LDA, BI, LDA, Z, LDA, Z, LDA, WORK,
00682      $             RESULT( 4 ) )
00683 *
00684 *     Do tests (5) and (6): check Schur form of A and compare
00685 *     eigenvalues with diagonals.
00686 *
00687       NTEST = 6
00688       TEMP1 = ZERO
00689       RESULT( 5 ) = ZERO
00690       RESULT( 6 ) = ZERO
00691 *
00692       DO 110 J = 1, MPLUSN
00693          ILABAD = .FALSE.
00694          IF( ALPHAI( J ).EQ.ZERO ) THEN
00695             TEMP2 = ( ABS( ALPHAR( J )-AI( J, J ) ) /
00696      $              MAX( SMLNUM, ABS( ALPHAR( J ) ), ABS( AI( J,
00697      $              J ) ) )+ABS( BETA( J )-BI( J, J ) ) /
00698      $              MAX( SMLNUM, ABS( BETA( J ) ), ABS( BI( J, J ) ) ) )
00699      $               / ULP
00700             IF( J.LT.MPLUSN ) THEN
00701                IF( AI( J+1, J ).NE.ZERO ) THEN
00702                   ILABAD = .TRUE.
00703                   RESULT( 5 ) = ULPINV
00704                END IF
00705             END IF
00706             IF( J.GT.1 ) THEN
00707                IF( AI( J, J-1 ).NE.ZERO ) THEN
00708                   ILABAD = .TRUE.
00709                   RESULT( 5 ) = ULPINV
00710                END IF
00711             END IF
00712          ELSE
00713             IF( ALPHAI( J ).GT.ZERO ) THEN
00714                I1 = J
00715             ELSE
00716                I1 = J - 1
00717             END IF
00718             IF( I1.LE.0 .OR. I1.GE.MPLUSN ) THEN
00719                ILABAD = .TRUE.
00720             ELSE IF( I1.LT.MPLUSN-1 ) THEN
00721                IF( AI( I1+2, I1+1 ).NE.ZERO ) THEN
00722                   ILABAD = .TRUE.
00723                   RESULT( 5 ) = ULPINV
00724                END IF
00725             ELSE IF( I1.GT.1 ) THEN
00726                IF( AI( I1, I1-1 ).NE.ZERO ) THEN
00727                   ILABAD = .TRUE.
00728                   RESULT( 5 ) = ULPINV
00729                END IF
00730             END IF
00731             IF( .NOT.ILABAD ) THEN
00732                CALL SGET53( AI( I1, I1 ), LDA, BI( I1, I1 ), LDA,
00733      $                      BETA( J ), ALPHAR( J ), ALPHAI( J ), TEMP2,
00734      $                      IINFO )
00735                IF( IINFO.GE.3 ) THEN
00736                   WRITE( NOUT, FMT = 9997 )IINFO, J, MPLUSN, NPTKNT
00737                   INFO = ABS( IINFO )
00738                END IF
00739             ELSE
00740                TEMP2 = ULPINV
00741             END IF
00742          END IF
00743          TEMP1 = MAX( TEMP1, TEMP2 )
00744          IF( ILABAD ) THEN
00745             WRITE( NOUT, FMT = 9996 )J, MPLUSN, NPTKNT
00746          END IF
00747   110 CONTINUE
00748       RESULT( 6 ) = TEMP1
00749 *
00750 *     Test (7) (if sorting worked)  <--------- need to be checked.
00751 *
00752       NTEST = 7
00753       RESULT( 7 ) = ZERO
00754       IF( LINFO.EQ.MPLUSN+3 )
00755      $   RESULT( 7 ) = ULPINV
00756 *
00757 *     Test (8): compare the estimated value of DIF and its true value.
00758 *
00759       NTEST = 8
00760       RESULT( 8 ) = ZERO
00761       IF( DIFEST( 2 ).EQ.ZERO ) THEN
00762          IF( DIFTRU.GT.ABNRM*ULP )
00763      $      RESULT( 8 ) = ULPINV
00764       ELSE IF( DIFTRU.EQ.ZERO ) THEN
00765          IF( DIFEST( 2 ).GT.ABNRM*ULP )
00766      $      RESULT( 8 ) = ULPINV
00767       ELSE IF( ( DIFTRU.GT.THRSH2*DIFEST( 2 ) ) .OR.
00768      $         ( DIFTRU*THRSH2.LT.DIFEST( 2 ) ) ) THEN
00769          RESULT( 8 ) = MAX( DIFTRU / DIFEST( 2 ), DIFEST( 2 ) / DIFTRU )
00770       END IF
00771 *
00772 *     Test (9)
00773 *
00774       NTEST = 9
00775       RESULT( 9 ) = ZERO
00776       IF( LINFO.EQ.( MPLUSN+2 ) ) THEN
00777          IF( DIFTRU.GT.ABNRM*ULP )
00778      $      RESULT( 9 ) = ULPINV
00779          IF( ( IFUNC.GT.1 ) .AND. ( DIFEST( 2 ).NE.ZERO ) )
00780      $      RESULT( 9 ) = ULPINV
00781          IF( ( IFUNC.EQ.1 ) .AND. ( PL( 1 ).NE.ZERO ) )
00782      $      RESULT( 9 ) = ULPINV
00783       END IF
00784 *
00785 *     Test (10): compare the estimated value of PL and it true value.
00786 *
00787       NTEST = 10
00788       RESULT( 10 ) = ZERO
00789       IF( PL( 1 ).EQ.ZERO ) THEN
00790          IF( PLTRU.GT.ABNRM*ULP )
00791      $      RESULT( 10 ) = ULPINV
00792       ELSE IF( PLTRU.EQ.ZERO ) THEN
00793          IF( PL( 1 ).GT.ABNRM*ULP )
00794      $      RESULT( 10 ) = ULPINV
00795       ELSE IF( ( PLTRU.GT.THRESH*PL( 1 ) ) .OR.
00796      $         ( PLTRU*THRESH.LT.PL( 1 ) ) ) THEN
00797          RESULT( 10 ) = ULPINV
00798       END IF
00799 *
00800       NTESTT = NTESTT + NTEST
00801 *
00802 *     Print out tests which fail.
00803 *
00804       DO 120 J = 1, NTEST
00805          IF( RESULT( J ).GE.THRESH ) THEN
00806 *
00807 *           If this is the first test to fail,
00808 *           print a header to the data file.
00809 *
00810             IF( NERRS.EQ.0 ) THEN
00811                WRITE( NOUT, FMT = 9995 )'SGX'
00812 *
00813 *              Matrix types
00814 *
00815                WRITE( NOUT, FMT = 9994 )
00816 *
00817 *              Tests performed
00818 *
00819                WRITE( NOUT, FMT = 9992 )'orthogonal', '''',
00820      $            'transpose', ( '''', I = 1, 4 )
00821 *
00822             END IF
00823             NERRS = NERRS + 1
00824             IF( RESULT( J ).LT.10000.0 ) THEN
00825                WRITE( NOUT, FMT = 9989 )NPTKNT, MPLUSN, J, RESULT( J )
00826             ELSE
00827                WRITE( NOUT, FMT = 9988 )NPTKNT, MPLUSN, J, RESULT( J )
00828             END IF
00829          END IF
00830 *
00831   120 CONTINUE
00832 *
00833   130 CONTINUE
00834       GO TO 80
00835   140 CONTINUE
00836 *
00837   150 CONTINUE
00838 *
00839 *     Summary
00840 *
00841       CALL ALASVM( 'SGX', NOUT, NERRS, NTESTT, 0 )
00842 *
00843       WORK( 1 ) = MAXWRK
00844 *
00845       RETURN
00846 *
00847  9999 FORMAT( ' SDRGSX: ', A, ' returned INFO=', I6, '.', / 9X, 'N=',
00848      $      I6, ', JTYPE=', I6, ')' )
00849 *
00850  9998 FORMAT( ' SDRGSX: ', A, ' returned INFO=', I6, '.', / 9X, 'N=',
00851      $      I6, ', Input Example #', I2, ')' )
00852 *
00853  9997 FORMAT( ' SDRGSX: SGET53 returned INFO=', I1, ' for eigenvalue ',
00854      $      I6, '.', / 9X, 'N=', I6, ', JTYPE=', I6, ')' )
00855 *
00856  9996 FORMAT( ' SDRGSX: S not in Schur form at eigenvalue ', I6, '.',
00857      $      / 9X, 'N=', I6, ', JTYPE=', I6, ')' )
00858 *
00859  9995 FORMAT( / 1X, A3, ' -- Real Expert Generalized Schur form',
00860      $      ' problem driver' )
00861 *
00862  9994 FORMAT( 'Input Example' )
00863 *
00864  9993 FORMAT( ' Matrix types: ', /
00865      $      '  1:  A is a block diagonal matrix of Jordan blocks ',
00866      $      'and B is the identity ', / '      matrix, ',
00867      $      / '  2:  A and B are upper triangular matrices, ',
00868      $      / '  3:  A and B are as type 2, but each second diagonal ',
00869      $      'block in A_11 and ', /
00870      $      '      each third diaongal block in A_22 are 2x2 blocks,',
00871      $      / '  4:  A and B are block diagonal matrices, ',
00872      $      / '  5:  (A,B) has potentially close or common ',
00873      $      'eigenvalues.', / )
00874 *
00875  9992 FORMAT( / ' Tests performed:  (S is Schur, T is triangular, ',
00876      $      'Q and Z are ', A, ',', / 19X,
00877      $      ' a is alpha, b is beta, and ', A, ' means ', A, '.)',
00878      $      / '  1 = | A - Q S Z', A,
00879      $      ' | / ( |A| n ulp )      2 = | B - Q T Z', A,
00880      $      ' | / ( |B| n ulp )', / '  3 = | I - QQ', A,
00881      $      ' | / ( n ulp )             4 = | I - ZZ', A,
00882      $      ' | / ( n ulp )', / '  5 = 1/ULP  if A is not in ',
00883      $      'Schur form S', / '  6 = difference between (alpha,beta)',
00884      $      ' and diagonals of (S,T)', /
00885      $      '  7 = 1/ULP  if SDIM is not the correct number of ',
00886      $      'selected eigenvalues', /
00887      $      '  8 = 1/ULP  if DIFEST/DIFTRU > 10*THRESH or ',
00888      $      'DIFTRU/DIFEST > 10*THRESH',
00889      $      / '  9 = 1/ULP  if DIFEST <> 0 or DIFTRU > ULP*norm(A,B) ',
00890      $      'when reordering fails', /
00891      $      ' 10 = 1/ULP  if PLEST/PLTRU > THRESH or ',
00892      $      'PLTRU/PLEST > THRESH', /
00893      $      '    ( Test 10 is only for input examples )', / )
00894  9991 FORMAT( ' Matrix order=', I2, ', type=', I2, ', a=', E10.3,
00895      $      ', order(A_11)=', I2, ', result ', I2, ' is ', 0P, F8.2 )
00896  9990 FORMAT( ' Matrix order=', I2, ', type=', I2, ', a=', E10.3,
00897      $      ', order(A_11)=', I2, ', result ', I2, ' is ', 0P, E10.3 )
00898  9989 FORMAT( ' Input example #', I2, ', matrix order=', I4, ',',
00899      $      ' result ', I2, ' is', 0P, F8.2 )
00900  9988 FORMAT( ' Input example #', I2, ', matrix order=', I4, ',',
00901      $      ' result ', I2, ' is', 1P, E10.3 )
00902 *
00903 *     End of SDRGSX
00904 *
00905       END
 All Files Functions