LAPACK 3.3.1 Linear Algebra PACKage

# sdrvbd.f

Go to the documentation of this file.
```00001       SUBROUTINE SDRVBD( NSIZES, MM, NN, NTYPES, DOTYPE, ISEED, THRESH,
00002      \$                   A, LDA, U, LDU, VT, LDVT, ASAV, USAV, VTSAV, S,
00003      \$                   SSAV, E, WORK, LWORK, IWORK, NOUT, INFO )
00004 *
00005 *  -- LAPACK test routine (version 3.1) --
00006 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00007 *     November 2006
00008 *
00009 *     .. Scalar Arguments ..
00010       INTEGER            INFO, LDA, LDU, LDVT, LWORK, NOUT, NSIZES,
00011      \$                   NTYPES
00012       REAL               THRESH
00013 *     ..
00014 *     .. Array Arguments ..
00015       LOGICAL            DOTYPE( * )
00016       INTEGER            ISEED( 4 ), IWORK( * ), MM( * ), NN( * )
00017       REAL               A( LDA, * ), ASAV( LDA, * ), E( * ), S( * ),
00018      \$                   SSAV( * ), U( LDU, * ), USAV( LDU, * ),
00019      \$                   VT( LDVT, * ), VTSAV( LDVT, * ), WORK( * )
00020 *     ..
00021 *
00022 *  Purpose
00023 *  =======
00024 *
00025 *  SDRVBD checks the singular value decomposition (SVD) drivers
00026 *  SGESVD, SGESDD, SGESVJ, and SGEJSV.
00027 *
00028 *  Both SGESVD and SGESDD factor A = U diag(S) VT, where U and VT are
00029 *  orthogonal and diag(S) is diagonal with the entries of the array S
00030 *  on its diagonal. The entries of S are the singular values,
00031 *  nonnegative and stored in decreasing order.  U and VT can be
00032 *  optionally not computed, overwritten on A, or computed partially.
00033 *
00034 *  A is M by N. Let MNMIN = min( M, N ). S has dimension MNMIN.
00035 *  U can be M by M or M by MNMIN. VT can be N by N or MNMIN by N.
00036 *
00037 *  When SDRVBD is called, a number of matrix "sizes" (M's and N's)
00038 *  and a number of matrix "types" are specified.  For each size (M,N)
00039 *  and each type of matrix, and for the minimal workspace as well as
00040 *  workspace adequate to permit blocking, an  M x N  matrix "A" will be
00041 *  generated and used to test the SVD routines.  For each matrix, A will
00042 *  be factored as A = U diag(S) VT and the following 12 tests computed:
00043 *
00044 *  Test for SGESVD:
00045 *
00046 *  (1)    | A - U diag(S) VT | / ( |A| max(M,N) ulp )
00047 *
00048 *  (2)    | I - U'U | / ( M ulp )
00049 *
00050 *  (3)    | I - VT VT' | / ( N ulp )
00051 *
00052 *  (4)    S contains MNMIN nonnegative values in decreasing order.
00053 *         (Return 0 if true, 1/ULP if false.)
00054 *
00055 *  (5)    | U - Upartial | / ( M ulp ) where Upartial is a partially
00056 *         computed U.
00057 *
00058 *  (6)    | VT - VTpartial | / ( N ulp ) where VTpartial is a partially
00059 *         computed VT.
00060 *
00061 *  (7)    | S - Spartial | / ( MNMIN ulp |S| ) where Spartial is the
00062 *         vector of singular values from the partial SVD
00063 *
00064 *  Test for SGESDD:
00065 *
00066 *  (8)    | A - U diag(S) VT | / ( |A| max(M,N) ulp )
00067 *
00068 *  (9)    | I - U'U | / ( M ulp )
00069 *
00070 *  (10)   | I - VT VT' | / ( N ulp )
00071 *
00072 *  (11)   S contains MNMIN nonnegative values in decreasing order.
00073 *         (Return 0 if true, 1/ULP if false.)
00074 *
00075 *  (12)   | U - Upartial | / ( M ulp ) where Upartial is a partially
00076 *         computed U.
00077 *
00078 *  (13)   | VT - VTpartial | / ( N ulp ) where VTpartial is a partially
00079 *         computed VT.
00080 *
00081 *  (14)   | S - Spartial | / ( MNMIN ulp |S| ) where Spartial is the
00082 *         vector of singular values from the partial SVD
00083 *
00084 *  Test for SGESVJ:
00085 *
00086 *  (15)    | A - U diag(S) VT | / ( |A| max(M,N) ulp )
00087 *
00088 *  (16)    | I - U'U | / ( M ulp )
00089 *
00090 *  (17)   | I - VT VT' | / ( N ulp )
00091 *
00092 *  (18)   S contains MNMIN nonnegative values in decreasing order.
00093 *         (Return 0 if true, 1/ULP if false.)
00094 *
00095 *  Test for SGEJSV:
00096 *
00097 *  (19)    | A - U diag(S) VT | / ( |A| max(M,N) ulp )
00098 *
00099 *  (20)    | I - U'U | / ( M ulp )
00100 *
00101 *  (21)   | I - VT VT' | / ( N ulp )
00102 *
00103 *  (22)   S contains MNMIN nonnegative values in decreasing order.
00104 *         (Return 0 if true, 1/ULP if false.)
00105 *
00106 *  The "sizes" are specified by the arrays MM(1:NSIZES) and
00107 *  NN(1:NSIZES); the value of each element pair (MM(j),NN(j))
00108 *  specifies one size.  The "types" are specified by a logical array
00109 *  DOTYPE( 1:NTYPES ); if DOTYPE(j) is .TRUE., then matrix type "j"
00110 *  will be generated.
00111 *  Currently, the list of possible types is:
00112 *
00113 *  (1)  The zero matrix.
00114 *  (2)  The identity matrix.
00115 *  (3)  A matrix of the form  U D V, where U and V are orthogonal and
00116 *       D has evenly spaced entries 1, ..., ULP with random signs
00117 *       on the diagonal.
00118 *  (4)  Same as (3), but multiplied by the underflow-threshold / ULP.
00119 *  (5)  Same as (3), but multiplied by the overflow-threshold * ULP.
00120 *
00121 *  Arguments
00122 *  ==========
00123 *
00124 *  NSIZES  (input) INTEGER
00125 *          The number of matrix sizes (M,N) contained in the vectors
00126 *          MM and NN.
00127 *
00128 *  MM      (input) INTEGER array, dimension (NSIZES)
00129 *          The values of the matrix row dimension M.
00130 *
00131 *  NN      (input) INTEGER array, dimension (NSIZES)
00132 *          The values of the matrix column dimension N.
00133 *
00134 *  NTYPES  (input) INTEGER
00135 *          The number of elements in DOTYPE.   If it is zero, SDRVBD
00136 *          does nothing.  It must be at least zero.  If it is MAXTYP+1
00137 *          and NSIZES is 1, then an additional type, MAXTYP+1 is
00138 *          defined, which is to use whatever matrices are in A and B.
00139 *          This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and
00140 *          DOTYPE(MAXTYP+1) is .TRUE. .
00141 *
00142 *  DOTYPE  (input) LOGICAL array, dimension (NTYPES)
00143 *          If DOTYPE(j) is .TRUE., then for each size (m,n), a matrix
00144 *          of type j will be generated.  If NTYPES is smaller than the
00145 *          maximum number of types defined (PARAMETER MAXTYP), then
00146 *          types NTYPES+1 through MAXTYP will not be generated.  If
00147 *          NTYPES is larger than MAXTYP, DOTYPE(MAXTYP+1) through
00148 *          DOTYPE(NTYPES) will be ignored.
00149 *
00150 *  ISEED   (input/output) INTEGER array, dimension (4)
00151 *          On entry, the seed of the random number generator.  The array
00152 *          elements should be between 0 and 4095; if not they will be
00153 *          reduced mod 4096.  Also, ISEED(4) must be odd.
00154 *          On exit, ISEED is changed and can be used in the next call to
00155 *          SDRVBD to continue the same random number sequence.
00156 *
00157 *  THRESH  (input) REAL
00158 *          The threshold value for the test ratios.  A result is
00159 *          included in the output file if RESULT >= THRESH.  The test
00160 *          ratios are scaled to be O(1), so THRESH should be a small
00161 *          multiple of 1, e.g., 10 or 100.  To have every test ratio
00162 *          printed, use THRESH = 0.
00163 *
00164 *  A       (workspace) REAL array, dimension (LDA,NMAX)
00165 *          where NMAX is the maximum value of N in NN.
00166 *
00167 *  LDA     (input) INTEGER
00168 *          The leading dimension of the array A.  LDA >= max(1,MMAX),
00169 *          where MMAX is the maximum value of M in MM.
00170 *
00171 *  U       (workspace) REAL array, dimension (LDU,MMAX)
00172 *
00173 *  LDU     (input) INTEGER
00174 *          The leading dimension of the array U.  LDU >= max(1,MMAX).
00175 *
00176 *  VT      (workspace) REAL array, dimension (LDVT,NMAX)
00177 *
00178 *  LDVT    (input) INTEGER
00179 *          The leading dimension of the array VT.  LDVT >= max(1,NMAX).
00180 *
00181 *  ASAV    (workspace) REAL array, dimension (LDA,NMAX)
00182 *
00183 *  USAV    (workspace) REAL array, dimension (LDU,MMAX)
00184 *
00185 *  VTSAV   (workspace) REAL array, dimension (LDVT,NMAX)
00186 *
00187 *  S       (workspace) REAL array, dimension
00188 *                      (max(min(MM,NN)))
00189 *
00190 *  SSAV    (workspace) REAL array, dimension
00191 *                      (max(min(MM,NN)))
00192 *
00193 *  E       (workspace) REAL array, dimension
00194 *                      (max(min(MM,NN)))
00195 *
00196 *  WORK    (workspace) REAL array, dimension (LWORK)
00197 *
00198 *  LWORK   (input) INTEGER
00199 *          The number of entries in WORK.  This must be at least
00200 *          max(3*MN+MX,5*MN-4)+2*MN**2 for all pairs
00201 *          pairs  (MN,MX)=( min(MM(j),NN(j), max(MM(j),NN(j)) )
00202 *
00203 *  IWORK   (workspace) INTEGER array, dimension at least 8*min(M,N)
00204 *
00205 *  NOUT    (input) INTEGER
00206 *          The FORTRAN unit number for printing out error messages
00207 *          (e.g., if a routine returns IINFO not equal to 0.)
00208 *
00209 *  INFO    (output) INTEGER
00210 *          If 0, then everything ran OK.
00211 *           -1: NSIZES < 0
00212 *           -2: Some MM(j) < 0
00213 *           -3: Some NN(j) < 0
00214 *           -4: NTYPES < 0
00215 *           -7: THRESH < 0
00216 *          -10: LDA < 1 or LDA < MMAX, where MMAX is max( MM(j) ).
00217 *          -12: LDU < 1 or LDU < MMAX.
00218 *          -14: LDVT < 1 or LDVT < NMAX, where NMAX is max( NN(j) ).
00219 *          -21: LWORK too small.
00220 *          If  SLATMS, or SGESVD returns an error code, the
00221 *              absolute value of it is returned.
00222 *
00223 *  =====================================================================
00224 *
00225 *     .. Parameters ..
00226       REAL               ZERO, ONE
00227       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
00228       INTEGER            MAXTYP
00229       PARAMETER          ( MAXTYP = 5 )
00230 *     ..
00231 *     .. Local Scalars ..
00233       CHARACTER          JOBQ, JOBU, JOBVT
00234       CHARACTER*3        PATH
00235       INTEGER            I, IINFO, IJQ, IJU, IJVT, IWS, IWTMP, J, JSIZE,
00236      \$                   JTYPE, LSWORK, M, MINWRK, MMAX, MNMAX, MNMIN,
00237      \$                   MTYPES, N, NFAIL, NMAX, NTEST
00238       REAL               ANORM, DIF, DIV, OVFL, ULP, ULPINV, UNFL
00239 *     ..
00240 *     .. Local Arrays ..
00241       CHARACTER          CJOB( 4 )
00242       INTEGER            IOLDSD( 4 )
00243       REAL               RESULT( 22 )
00244 *     ..
00245 *     .. External Functions ..
00246       REAL               SLAMCH
00247       EXTERNAL           SLAMCH
00248 *     ..
00249 *     .. External Subroutines ..
00250       EXTERNAL           ALASVM, SBDT01, SGESDD, SGESVD, SLABAD, SLACPY,
00251      \$                   SLASET, SLATMS, SORT01, SORT03, XERBLA, SGESVJ,
00252      \$                   SGEJSV
00253 *     ..
00254 *     .. Intrinsic Functions ..
00255       INTRINSIC          ABS, MAX, MIN, REAL
00256 *     ..
00257 *     .. Scalars in Common ..
00258       LOGICAL            LERR, OK
00259       CHARACTER*32       SRNAMT
00260       INTEGER            INFOT, NUNIT
00261 *     ..
00262 *     .. Common blocks ..
00263       COMMON             / INFOC / INFOT, NUNIT, OK, LERR
00264       COMMON             / SRNAMC / SRNAMT
00265 *     ..
00266 *     .. Data statements ..
00267       DATA               CJOB / 'N', 'O', 'S', 'A' /
00268 *     ..
00269 *     .. Executable Statements ..
00270 *
00271 *     Check for errors
00272 *
00273       INFO = 0
00276       MMAX = 1
00277       NMAX = 1
00278       MNMAX = 1
00279       MINWRK = 1
00280       DO 10 J = 1, NSIZES
00281          MMAX = MAX( MMAX, MM( J ) )
00282          IF( MM( J ).LT.0 )
00284          NMAX = MAX( NMAX, NN( J ) )
00285          IF( NN( J ).LT.0 )
00287          MNMAX = MAX( MNMAX, MIN( MM( J ), NN( J ) ) )
00288          MINWRK = MAX( MINWRK, MAX( 3*MIN( MM( J ),
00289      \$            NN( J ) )+MAX( MM( J ), NN( J ) ), 5*MIN( MM( J ),
00290      \$            NN( J )-4 ) )+2*MIN( MM( J ), NN( J ) )**2 )
00291    10 CONTINUE
00292 *
00293 *     Check for errors
00294 *
00295       IF( NSIZES.LT.0 ) THEN
00296          INFO = -1
00297       ELSE IF( BADMM ) THEN
00298          INFO = -2
00299       ELSE IF( BADNN ) THEN
00300          INFO = -3
00301       ELSE IF( NTYPES.LT.0 ) THEN
00302          INFO = -4
00303       ELSE IF( LDA.LT.MAX( 1, MMAX ) ) THEN
00304          INFO = -10
00305       ELSE IF( LDU.LT.MAX( 1, MMAX ) ) THEN
00306          INFO = -12
00307       ELSE IF( LDVT.LT.MAX( 1, NMAX ) ) THEN
00308          INFO = -14
00309       ELSE IF( MINWRK.GT.LWORK ) THEN
00310          INFO = -21
00311       END IF
00312 *
00313       IF( INFO.NE.0 ) THEN
00314          CALL XERBLA( 'SDRVBD', -INFO )
00315          RETURN
00316       END IF
00317 *
00318 *     Initialize constants
00319 *
00320       PATH( 1: 1 ) = 'Single precision'
00321       PATH( 2: 3 ) = 'BD'
00322       NFAIL = 0
00323       NTEST = 0
00324       UNFL = SLAMCH( 'Safe minimum' )
00325       OVFL = ONE / UNFL
00326       CALL SLABAD( UNFL, OVFL )
00327       ULP = SLAMCH( 'Precision' )
00328       ULPINV = ONE / ULP
00329       INFOT = 0
00330 *
00331 *     Loop over sizes, types
00332 *
00333       DO 150 JSIZE = 1, NSIZES
00334          M = MM( JSIZE )
00335          N = NN( JSIZE )
00336          MNMIN = MIN( M, N )
00337 *
00338          IF( NSIZES.NE.1 ) THEN
00339             MTYPES = MIN( MAXTYP, NTYPES )
00340          ELSE
00341             MTYPES = MIN( MAXTYP+1, NTYPES )
00342          END IF
00343 *
00344          DO 140 JTYPE = 1, MTYPES
00345             IF( .NOT.DOTYPE( JTYPE ) )
00346      \$         GO TO 140
00347 *
00348             DO 20 J = 1, 4
00349                IOLDSD( J ) = ISEED( J )
00350    20       CONTINUE
00351 *
00352 *           Compute "A"
00353 *
00354             IF( MTYPES.GT.MAXTYP )
00355      \$         GO TO 30
00356 *
00357             IF( JTYPE.EQ.1 ) THEN
00358 *
00359 *              Zero matrix
00360 *
00361                CALL SLASET( 'Full', M, N, ZERO, ZERO, A, LDA )
00362 *
00363             ELSE IF( JTYPE.EQ.2 ) THEN
00364 *
00365 *              Identity matrix
00366 *
00367                CALL SLASET( 'Full', M, N, ZERO, ONE, A, LDA )
00368 *
00369             ELSE
00370 *
00371 *              (Scaled) random matrix
00372 *
00373                IF( JTYPE.EQ.3 )
00374      \$            ANORM = ONE
00375                IF( JTYPE.EQ.4 )
00376      \$            ANORM = UNFL / ULP
00377                IF( JTYPE.EQ.5 )
00378      \$            ANORM = OVFL*ULP
00379                CALL SLATMS( M, N, 'U', ISEED, 'N', S, 4, REAL( MNMIN ),
00380      \$                      ANORM, M-1, N-1, 'N', A, LDA, WORK, IINFO )
00381                IF( IINFO.NE.0 ) THEN
00382                   WRITE( NOUT, FMT = 9996 )'Generator', IINFO, M, N,
00383      \$               JTYPE, IOLDSD
00384                   INFO = ABS( IINFO )
00385                   RETURN
00386                END IF
00387             END IF
00388 *
00389    30       CONTINUE
00390             CALL SLACPY( 'F', M, N, A, LDA, ASAV, LDA )
00391 *
00392 *           Do for minimal and adequate (for blocking) workspace
00393 *
00394             DO 130 IWS = 1, 4
00395 *
00396                DO 40 J = 1, 14
00397                   RESULT( J ) = -ONE
00398    40          CONTINUE
00399 *
00400 *              Test SGESVD: Factorize A
00401 *
00402                IWTMP = MAX( 3*MIN( M, N )+MAX( M, N ), 5*MIN( M, N ) )
00403                LSWORK = IWTMP + ( IWS-1 )*( LWORK-IWTMP ) / 3
00404                LSWORK = MIN( LSWORK, LWORK )
00405                LSWORK = MAX( LSWORK, 1 )
00406                IF( IWS.EQ.4 )
00407      \$            LSWORK = LWORK
00408 *
00409                IF( IWS.GT.1 )
00410      \$            CALL SLACPY( 'F', M, N, ASAV, LDA, A, LDA )
00411                SRNAMT = 'SGESVD'
00412                CALL SGESVD( 'A', 'A', M, N, A, LDA, SSAV, USAV, LDU,
00413      \$                      VTSAV, LDVT, WORK, LSWORK, IINFO )
00414                IF( IINFO.NE.0 ) THEN
00415                   WRITE( NOUT, FMT = 9995 )'GESVD', IINFO, M, N, JTYPE,
00416      \$               LSWORK, IOLDSD
00417                   INFO = ABS( IINFO )
00418                   RETURN
00419                END IF
00420 *
00421 *              Do tests 1--4
00422 *
00423                CALL SBDT01( M, N, 0, ASAV, LDA, USAV, LDU, SSAV, E,
00424      \$                      VTSAV, LDVT, WORK, RESULT( 1 ) )
00425                IF( M.NE.0 .AND. N.NE.0 ) THEN
00426                   CALL SORT01( 'Columns', M, M, USAV, LDU, WORK, LWORK,
00427      \$                         RESULT( 2 ) )
00428                   CALL SORT01( 'Rows', N, N, VTSAV, LDVT, WORK, LWORK,
00429      \$                         RESULT( 3 ) )
00430                END IF
00431                RESULT( 4 ) = ZERO
00432                DO 50 I = 1, MNMIN - 1
00433                   IF( SSAV( I ).LT.SSAV( I+1 ) )
00434      \$               RESULT( 4 ) = ULPINV
00435                   IF( SSAV( I ).LT.ZERO )
00436      \$               RESULT( 4 ) = ULPINV
00437    50          CONTINUE
00438                IF( MNMIN.GE.1 ) THEN
00439                   IF( SSAV( MNMIN ).LT.ZERO )
00440      \$               RESULT( 4 ) = ULPINV
00441                END IF
00442 *
00443 *              Do partial SVDs, comparing to SSAV, USAV, and VTSAV
00444 *
00445                RESULT( 5 ) = ZERO
00446                RESULT( 6 ) = ZERO
00447                RESULT( 7 ) = ZERO
00448                DO 80 IJU = 0, 3
00449                   DO 70 IJVT = 0, 3
00450                      IF( ( IJU.EQ.3 .AND. IJVT.EQ.3 ) .OR.
00451      \$                   ( IJU.EQ.1 .AND. IJVT.EQ.1 ) )GO TO 70
00452                      JOBU = CJOB( IJU+1 )
00453                      JOBVT = CJOB( IJVT+1 )
00454                      CALL SLACPY( 'F', M, N, ASAV, LDA, A, LDA )
00455                      SRNAMT = 'SGESVD'
00456                      CALL SGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU,
00457      \$                            VT, LDVT, WORK, LSWORK, IINFO )
00458 *
00459 *                    Compare U
00460 *
00461                      DIF = ZERO
00462                      IF( M.GT.0 .AND. N.GT.0 ) THEN
00463                         IF( IJU.EQ.1 ) THEN
00464                            CALL SORT03( 'C', M, MNMIN, M, MNMIN, USAV,
00465      \$                                  LDU, A, LDA, WORK, LWORK, DIF,
00466      \$                                  IINFO )
00467                         ELSE IF( IJU.EQ.2 ) THEN
00468                            CALL SORT03( 'C', M, MNMIN, M, MNMIN, USAV,
00469      \$                                  LDU, U, LDU, WORK, LWORK, DIF,
00470      \$                                  IINFO )
00471                         ELSE IF( IJU.EQ.3 ) THEN
00472                            CALL SORT03( 'C', M, M, M, MNMIN, USAV, LDU,
00473      \$                                  U, LDU, WORK, LWORK, DIF,
00474      \$                                  IINFO )
00475                         END IF
00476                      END IF
00477                      RESULT( 5 ) = MAX( RESULT( 5 ), DIF )
00478 *
00479 *                    Compare VT
00480 *
00481                      DIF = ZERO
00482                      IF( M.GT.0 .AND. N.GT.0 ) THEN
00483                         IF( IJVT.EQ.1 ) THEN
00484                            CALL SORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
00485      \$                                  LDVT, A, LDA, WORK, LWORK, DIF,
00486      \$                                  IINFO )
00487                         ELSE IF( IJVT.EQ.2 ) THEN
00488                            CALL SORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
00489      \$                                  LDVT, VT, LDVT, WORK, LWORK,
00490      \$                                  DIF, IINFO )
00491                         ELSE IF( IJVT.EQ.3 ) THEN
00492                            CALL SORT03( 'R', N, N, N, MNMIN, VTSAV,
00493      \$                                  LDVT, VT, LDVT, WORK, LWORK,
00494      \$                                  DIF, IINFO )
00495                         END IF
00496                      END IF
00497                      RESULT( 6 ) = MAX( RESULT( 6 ), DIF )
00498 *
00499 *                    Compare S
00500 *
00501                      DIF = ZERO
00502                      DIV = MAX( REAL( MNMIN )*ULP*S( 1 ), UNFL )
00503                      DO 60 I = 1, MNMIN - 1
00504                         IF( SSAV( I ).LT.SSAV( I+1 ) )
00505      \$                     DIF = ULPINV
00506                         IF( SSAV( I ).LT.ZERO )
00507      \$                     DIF = ULPINV
00508                         DIF = MAX( DIF, ABS( SSAV( I )-S( I ) ) / DIV )
00509    60                CONTINUE
00510                      RESULT( 7 ) = MAX( RESULT( 7 ), DIF )
00511    70             CONTINUE
00512    80          CONTINUE
00513 *
00514 *              Test SGESDD: Factorize A
00515 *
00516                IWTMP = 5*MNMIN*MNMIN + 9*MNMIN + MAX( M, N )
00517                LSWORK = IWTMP + ( IWS-1 )*( LWORK-IWTMP ) / 3
00518                LSWORK = MIN( LSWORK, LWORK )
00519                LSWORK = MAX( LSWORK, 1 )
00520                IF( IWS.EQ.4 )
00521      \$            LSWORK = LWORK
00522 *
00523                CALL SLACPY( 'F', M, N, ASAV, LDA, A, LDA )
00524                SRNAMT = 'SGESDD'
00525                CALL SGESDD( 'A', M, N, A, LDA, SSAV, USAV, LDU, VTSAV,
00526      \$                      LDVT, WORK, LSWORK, IWORK, IINFO )
00527                IF( IINFO.NE.0 ) THEN
00528                   WRITE( NOUT, FMT = 9995 )'GESDD', IINFO, M, N, JTYPE,
00529      \$               LSWORK, IOLDSD
00530                   INFO = ABS( IINFO )
00531                   RETURN
00532                END IF
00533 *
00534 *              Do tests 8--11
00535 *
00536                CALL SBDT01( M, N, 0, ASAV, LDA, USAV, LDU, SSAV, E,
00537      \$                      VTSAV, LDVT, WORK, RESULT( 8 ) )
00538                IF( M.NE.0 .AND. N.NE.0 ) THEN
00539                   CALL SORT01( 'Columns', M, M, USAV, LDU, WORK, LWORK,
00540      \$                         RESULT( 9 ) )
00541                   CALL SORT01( 'Rows', N, N, VTSAV, LDVT, WORK, LWORK,
00542      \$                         RESULT( 10 ) )
00543                END IF
00544                RESULT( 11 ) = ZERO
00545                DO 90 I = 1, MNMIN - 1
00546                   IF( SSAV( I ).LT.SSAV( I+1 ) )
00547      \$               RESULT( 11 ) = ULPINV
00548                   IF( SSAV( I ).LT.ZERO )
00549      \$               RESULT( 11 ) = ULPINV
00550    90          CONTINUE
00551                IF( MNMIN.GE.1 ) THEN
00552                   IF( SSAV( MNMIN ).LT.ZERO )
00553      \$               RESULT( 11 ) = ULPINV
00554                END IF
00555 *
00556 *              Do partial SVDs, comparing to SSAV, USAV, and VTSAV
00557 *
00558                RESULT( 12 ) = ZERO
00559                RESULT( 13 ) = ZERO
00560                RESULT( 14 ) = ZERO
00561                DO 110 IJQ = 0, 2
00562                   JOBQ = CJOB( IJQ+1 )
00563                   CALL SLACPY( 'F', M, N, ASAV, LDA, A, LDA )
00564                   SRNAMT = 'SGESDD'
00565                   CALL SGESDD( JOBQ, M, N, A, LDA, S, U, LDU, VT, LDVT,
00566      \$                         WORK, LSWORK, IWORK, IINFO )
00567 *
00568 *                 Compare U
00569 *
00570                   DIF = ZERO
00571                   IF( M.GT.0 .AND. N.GT.0 ) THEN
00572                      IF( IJQ.EQ.1 ) THEN
00573                         IF( M.GE.N ) THEN
00574                            CALL SORT03( 'C', M, MNMIN, M, MNMIN, USAV,
00575      \$                                  LDU, A, LDA, WORK, LWORK, DIF,
00576      \$                                  INFO )
00577                         ELSE
00578                            CALL SORT03( 'C', M, MNMIN, M, MNMIN, USAV,
00579      \$                                  LDU, U, LDU, WORK, LWORK, DIF,
00580      \$                                  INFO )
00581                         END IF
00582                      ELSE IF( IJQ.EQ.2 ) THEN
00583                         CALL SORT03( 'C', M, MNMIN, M, MNMIN, USAV, LDU,
00584      \$                               U, LDU, WORK, LWORK, DIF, INFO )
00585                      END IF
00586                   END IF
00587                   RESULT( 12 ) = MAX( RESULT( 12 ), DIF )
00588 *
00589 *                 Compare VT
00590 *
00591                   DIF = ZERO
00592                   IF( M.GT.0 .AND. N.GT.0 ) THEN
00593                      IF( IJQ.EQ.1 ) THEN
00594                         IF( M.GE.N ) THEN
00595                            CALL SORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
00596      \$                                  LDVT, VT, LDVT, WORK, LWORK,
00597      \$                                  DIF, INFO )
00598                         ELSE
00599                            CALL SORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
00600      \$                                  LDVT, A, LDA, WORK, LWORK, DIF,
00601      \$                                  INFO )
00602                         END IF
00603                      ELSE IF( IJQ.EQ.2 ) THEN
00604                         CALL SORT03( 'R', N, MNMIN, N, MNMIN, VTSAV,
00605      \$                               LDVT, VT, LDVT, WORK, LWORK, DIF,
00606      \$                               INFO )
00607                      END IF
00608                   END IF
00609                   RESULT( 13 ) = MAX( RESULT( 13 ), DIF )
00610 *
00611 *                 Compare S
00612 *
00613                   DIF = ZERO
00614                   DIV = MAX( REAL( MNMIN )*ULP*S( 1 ), UNFL )
00615                   DO 100 I = 1, MNMIN - 1
00616                      IF( SSAV( I ).LT.SSAV( I+1 ) )
00617      \$                  DIF = ULPINV
00618                      IF( SSAV( I ).LT.ZERO )
00619      \$                  DIF = ULPINV
00620                      DIF = MAX( DIF, ABS( SSAV( I )-S( I ) ) / DIV )
00621   100             CONTINUE
00622                   RESULT( 14 ) = MAX( RESULT( 14 ), DIF )
00623   110          CONTINUE
00624 *
00625 *              Test SGESVJ: Factorize A
00626 *              Note: SGESVJ does not work for M < N
00627 *
00628                RESULT( 15 ) = ZERO
00629                RESULT( 16 ) = ZERO
00630                RESULT( 17 ) = ZERO
00631                RESULT( 18 ) = ZERO
00632 *
00633                IF( M.GE.N ) THEN
00634                   IWTMP = 5*MNMIN*MNMIN + 9*MNMIN + MAX( M, N )
00635                   LSWORK = IWTMP + ( IWS-1 )*( LWORK-IWTMP ) / 3
00636                   LSWORK = MIN( LSWORK, LWORK )
00637                   LSWORK = MAX( LSWORK, 1 )
00638                   IF( IWS.EQ.4 )
00639      \$               LSWORK = LWORK
00640 *
00641                   CALL SLACPY( 'F', M, N, ASAV, LDA, USAV, LDA )
00642                   SRNAMT = 'SGESVJ'
00643                   CALL SGESVJ( 'G', 'U', 'V', M, N, USAV, LDA, SSAV,
00644      &                        0, A, LDVT, WORK, LWORK, INFO )
00645 *
00646 *                 SGESVJ retuns V not VT, so we transpose to use the same
00647 *                 test suite.
00648 *
00649                   DO J=1,N
00650                      DO I=1,N
00651                         VTSAV(J,I) = A(I,J)
00652                      END DO
00653                   END DO
00654 *
00655                   IF( IINFO.NE.0 ) THEN
00656                      WRITE( NOUT, FMT = 9995 )'GESVJ', IINFO, M, N,
00657      \$               JTYPE, LSWORK, IOLDSD
00658                      INFO = ABS( IINFO )
00659                      RETURN
00660                   END IF
00661 *
00662 *                 Do tests 15--18
00663 *
00664                   CALL SBDT01( M, N, 0, ASAV, LDA, USAV, LDU, SSAV, E,
00665      \$                         VTSAV, LDVT, WORK, RESULT( 15 ) )
00666                   IF( M.NE.0 .AND. N.NE.0 ) THEN
00667                      CALL SORT01( 'Columns', M, M, USAV, LDU, WORK,
00668      \$                            LWORK, RESULT( 16 ) )
00669                      CALL SORT01( 'Rows', N, N, VTSAV, LDVT, WORK,
00670      \$                            LWORK, RESULT( 17 ) )
00671                   END IF
00672                   RESULT( 18 ) = ZERO
00673                   DO 200 I = 1, MNMIN - 1
00674                      IF( SSAV( I ).LT.SSAV( I+1 ) )
00675      \$                  RESULT( 18 ) = ULPINV
00676                      IF( SSAV( I ).LT.ZERO )
00677      \$                  RESULT( 18 ) = ULPINV
00678   200             CONTINUE
00679                   IF( MNMIN.GE.1 ) THEN
00680                      IF( SSAV( MNMIN ).LT.ZERO )
00681      \$                  RESULT( 18 ) = ULPINV
00682                   END IF
00683                END IF
00684 *
00685 *              Test SGEJSV: Factorize A
00686 *              Note: SGEJSV does not work for M < N
00687 *
00688                RESULT( 19 ) = ZERO
00689                RESULT( 20 ) = ZERO
00690                RESULT( 21 ) = ZERO
00691                RESULT( 22 ) = ZERO
00692                IF( M.GE.N ) THEN
00693                   IWTMP = 5*MNMIN*MNMIN + 9*MNMIN + MAX( M, N )
00694                   LSWORK = IWTMP + ( IWS-1 )*( LWORK-IWTMP ) / 3
00695                   LSWORK = MIN( LSWORK, LWORK )
00696                   LSWORK = MAX( LSWORK, 1 )
00697                   IF( IWS.EQ.4 )
00698      \$               LSWORK = LWORK
00699 *
00700                   CALL SLACPY( 'F', M, N, ASAV, LDA, VTSAV, LDA )
00701                   SRNAMT = 'SGEJSV'
00702                   CALL SGEJSV( 'G', 'U', 'V', 'R', 'N', 'N',
00703      &                   M, N, VTSAV, LDA, SSAV, USAV, LDU, A, LDVT,
00704      &                   WORK, LWORK, IWORK, INFO )
00705 *
00706 *                 SGEJSV retuns V not VT, so we transpose to use the same
00707 *                 test suite.
00708 *
00709                   DO J=1,N
00710                      DO I=1,N
00711                         VTSAV(J,I) = A(I,J)
00712                      END DO
00713                   END DO
00714 *
00715                   IF( IINFO.NE.0 ) THEN
00716                      WRITE( NOUT, FMT = 9995 )'GESVJ', IINFO, M, N,
00717      \$               JTYPE, LSWORK, IOLDSD
00718                      INFO = ABS( IINFO )
00719                      RETURN
00720                   END IF
00721 *
00722 *                 Do tests 19--22
00723 *
00724                   CALL SBDT01( M, N, 0, ASAV, LDA, USAV, LDU, SSAV, E,
00725      \$                         VTSAV, LDVT, WORK, RESULT( 19 ) )
00726                   IF( M.NE.0 .AND. N.NE.0 ) THEN
00727                      CALL SORT01( 'Columns', M, M, USAV, LDU, WORK,
00728      \$                            LWORK, RESULT( 20 ) )
00729                      CALL SORT01( 'Rows', N, N, VTSAV, LDVT, WORK,
00730      \$                            LWORK, RESULT( 21 ) )
00731                   END IF
00732                   RESULT( 22 ) = ZERO
00733                   DO 300 I = 1, MNMIN - 1
00734                      IF( SSAV( I ).LT.SSAV( I+1 ) )
00735      \$                  RESULT( 22 ) = ULPINV
00736                      IF( SSAV( I ).LT.ZERO )
00737      \$                  RESULT( 22 ) = ULPINV
00738   300             CONTINUE
00739                   IF( MNMIN.GE.1 ) THEN
00740                      IF( SSAV( MNMIN ).LT.ZERO )
00741      \$                  RESULT( 22 ) = ULPINV
00742                   END IF
00743                END IF
00744 *
00745 *              End of Loop -- Check for RESULT(j) > THRESH
00746 *
00747                DO 120 J = 1, 22
00748                   IF( RESULT( J ).GE.THRESH ) THEN
00749                      IF( NFAIL.EQ.0 ) THEN
00750                         WRITE( NOUT, FMT = 9999 )
00751                         WRITE( NOUT, FMT = 9998 )
00752                      END IF
00753                      WRITE( NOUT, FMT = 9997 )M, N, JTYPE, IWS, IOLDSD,
00754      \$                  J, RESULT( J )
00755                      NFAIL = NFAIL + 1
00756                   END IF
00757   120          CONTINUE
00758                NTEST = NTEST + 22
00759 *
00760   130       CONTINUE
00761   140    CONTINUE
00762   150 CONTINUE
00763 *
00764 *     Summary
00765 *
00766       CALL ALASVM( PATH, NOUT, NFAIL, NTEST, 0 )
00767 *
00768  9999 FORMAT( ' SVD -- Real Singular Value Decomposition Driver ',
00769      \$      / ' Matrix types (see SDRVBD for details):',
00770      \$      / / ' 1 = Zero matrix', / ' 2 = Identity matrix',
00771      \$      / ' 3 = Evenly spaced singular values near 1',
00772      \$      / ' 4 = Evenly spaced singular values near underflow',
00773      \$      / ' 5 = Evenly spaced singular values near overflow', / /
00774      \$      ' Tests performed: ( A is dense, U and V are orthogonal,',
00775      \$      / 19X, ' S is an array, and Upartial, VTpartial, and',
00776      \$      / 19X, ' Spartial are partially computed U, VT and S),', / )
00777  9998 FORMAT( ' 1 = | A - U diag(S) VT | / ( |A| max(M,N) ulp ) ',
00778      \$      / ' 2 = | I - U**T U | / ( M ulp ) ',
00779      \$      / ' 3 = | I - VT VT**T | / ( N ulp ) ',
00780      \$      / ' 4 = 0 if S contains min(M,N) nonnegative values in',
00781      \$      ' decreasing order, else 1/ulp',
00782      \$      / ' 5 = | U - Upartial | / ( M ulp )',
00783      \$      / ' 6 = | VT - VTpartial | / ( N ulp )',
00784      \$      / ' 7 = | S - Spartial | / ( min(M,N) ulp |S| )',
00785      \$      / ' 8 = | A - U diag(S) VT | / ( |A| max(M,N) ulp ) ',
00786      \$      / ' 9 = | I - U**T U | / ( M ulp ) ',
00787      \$      / '10 = | I - VT VT**T | / ( N ulp ) ',
00788      \$      / '11 = 0 if S contains min(M,N) nonnegative values in',
00789      \$      ' decreasing order, else 1/ulp',
00790      \$      / '12 = | U - Upartial | / ( M ulp )',
00791      \$      / '13 = | VT - VTpartial | / ( N ulp )',
00792      \$      / '14 = | S - Spartial | / ( min(M,N) ulp |S| )',
00793      \$      / '15 = | A - U diag(S) VT | / ( |A| max(M,N) ulp ) ',
00794      \$      / '16 = | I - U**T U | / ( M ulp ) ',
00795      \$      / '17 = | I - VT VT**T | / ( N ulp ) ',
00796      \$      / '18 = 0 if S contains min(M,N) nonnegative values in',
00797      \$      ' decreasing order, else 1/ulp',
00798      \$      / '19 = | U - Upartial | / ( M ulp )',
00799      \$      / '20 = | VT - VTpartial | / ( N ulp )',
00800      \$      / '21 = | S - Spartial | / ( min(M,N) ulp |S| )', / / )
00801  9997 FORMAT( ' M=', I5, ', N=', I5, ', type ', I1, ', IWS=', I1,
00802      \$      ', seed=', 4( I4, ',' ), ' test(', I2, ')=', G11.4 )
00803  9996 FORMAT( ' SDRVBD: ', A, ' returned INFO=', I6, '.', / 9X, 'M=',
00804      \$      I6, ', N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ),
00805      \$      I5, ')' )
00806  9995 FORMAT( ' SDRVBD: ', A, ' returned INFO=', I6, '.', / 9X, 'M=',
00807      \$      I6, ', N=', I6, ', JTYPE=', I6, ', LSWORK=', I6, / 9X,
00808      \$      'ISEED=(', 3( I5, ',' ), I5, ')' )
00809 *
00810       RETURN
00811 *
00812 *     End of SDRVBD
00813 *
00814       END
```