LAPACK 3.3.1 Linear Algebra PACKage

# schkbd.f

Go to the documentation of this file.
```00001       SUBROUTINE SCHKBD( NSIZES, MVAL, NVAL, NTYPES, DOTYPE, NRHS,
00002      \$                   ISEED, THRESH, A, LDA, BD, BE, S1, S2, X, LDX,
00003      \$                   Y, Z, Q, LDQ, PT, LDPT, U, VT, WORK, LWORK,
00004      \$                   IWORK, NOUT, INFO )
00005 *
00006 *  -- LAPACK test routine (version 3.1) --
00007 *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
00008 *     November 2006
00009 *
00010 *     .. Scalar Arguments ..
00011       INTEGER            INFO, LDA, LDPT, LDQ, LDX, LWORK, NOUT, NRHS,
00012      \$                   NSIZES, NTYPES
00013       REAL               THRESH
00014 *     ..
00015 *     .. Array Arguments ..
00016       LOGICAL            DOTYPE( * )
00017       INTEGER            ISEED( 4 ), IWORK( * ), MVAL( * ), NVAL( * )
00018       REAL               A( LDA, * ), BD( * ), BE( * ), PT( LDPT, * ),
00019      \$                   Q( LDQ, * ), S1( * ), S2( * ), U( LDPT, * ),
00020      \$                   VT( LDPT, * ), WORK( * ), X( LDX, * ),
00021      \$                   Y( LDX, * ), Z( LDX, * )
00022 *     ..
00023 *
00024 *  Purpose
00025 *  =======
00026 *
00027 *  SCHKBD checks the singular value decomposition (SVD) routines.
00028 *
00029 *  SGEBRD reduces a real general m by n matrix A to upper or lower
00030 *  bidiagonal form B by an orthogonal transformation:  Q' * A * P = B
00031 *  (or A = Q * B * P').  The matrix B is upper bidiagonal if m >= n
00032 *  and lower bidiagonal if m < n.
00033 *
00034 *  SORGBR generates the orthogonal matrices Q and P' from SGEBRD.
00035 *  Note that Q and P are not necessarily square.
00036 *
00037 *  SBDSQR computes the singular value decomposition of the bidiagonal
00038 *  matrix B as B = U S V'.  It is called three times to compute
00039 *     1)  B = U S1 V', where S1 is the diagonal matrix of singular
00040 *         values and the columns of the matrices U and V are the left
00041 *         and right singular vectors, respectively, of B.
00042 *     2)  Same as 1), but the singular values are stored in S2 and the
00043 *         singular vectors are not computed.
00044 *     3)  A = (UQ) S (P'V'), the SVD of the original matrix A.
00045 *  In addition, SBDSQR has an option to apply the left orthogonal matrix
00046 *  U to a matrix X, useful in least squares applications.
00047 *
00048 *  SBDSDC computes the singular value decomposition of the bidiagonal
00049 *  matrix B as B = U S V' using divide-and-conquer. It is called twice
00050 *  to compute
00051 *     1) B = U S1 V', where S1 is the diagonal matrix of singular
00052 *         values and the columns of the matrices U and V are the left
00053 *         and right singular vectors, respectively, of B.
00054 *     2) Same as 1), but the singular values are stored in S2 and the
00055 *         singular vectors are not computed.
00056 *
00057 *  For each pair of matrix dimensions (M,N) and each selected matrix
00058 *  type, an M by N matrix A and an M by NRHS matrix X are generated.
00059 *  The problem dimensions are as follows
00060 *     A:          M x N
00061 *     Q:          M x min(M,N) (but M x M if NRHS > 0)
00062 *     P:          min(M,N) x N
00063 *     B:          min(M,N) x min(M,N)
00064 *     U, V:       min(M,N) x min(M,N)
00065 *     S1, S2      diagonal, order min(M,N)
00066 *     X:          M x NRHS
00067 *
00068 *  For each generated matrix, 14 tests are performed:
00069 *
00070 *  Test SGEBRD and SORGBR
00071 *
00072 *  (1)   | A - Q B PT | / ( |A| max(M,N) ulp ), PT = P'
00073 *
00074 *  (2)   | I - Q' Q | / ( M ulp )
00075 *
00076 *  (3)   | I - PT PT' | / ( N ulp )
00077 *
00078 *  Test SBDSQR on bidiagonal matrix B
00079 *
00080 *  (4)   | B - U S1 VT | / ( |B| min(M,N) ulp ), VT = V'
00081 *
00082 *  (5)   | Y - U Z | / ( |Y| max(min(M,N),k) ulp ), where Y = Q' X
00083 *                                                   and   Z = U' Y.
00084 *  (6)   | I - U' U | / ( min(M,N) ulp )
00085 *
00086 *  (7)   | I - VT VT' | / ( min(M,N) ulp )
00087 *
00088 *  (8)   S1 contains min(M,N) nonnegative values in decreasing order.
00089 *        (Return 0 if true, 1/ULP if false.)
00090 *
00091 *  (9)   | S1 - S2 | / ( |S1| ulp ), where S2 is computed without
00092 *                                    computing U and V.
00093 *
00094 *  (10)  0 if the true singular values of B are within THRESH of
00095 *        those in S1.  2*THRESH if they are not.  (Tested using
00096 *        SSVDCH)
00097 *
00098 *  Test SBDSQR on matrix A
00099 *
00100 *  (11)  | A - (QU) S (VT PT) | / ( |A| max(M,N) ulp )
00101 *
00102 *  (12)  | X - (QU) Z | / ( |X| max(M,k) ulp )
00103 *
00104 *  (13)  | I - (QU)'(QU) | / ( M ulp )
00105 *
00106 *  (14)  | I - (VT PT) (PT'VT') | / ( N ulp )
00107 *
00108 *  Test SBDSDC on bidiagonal matrix B
00109 *
00110 *  (15)  | B - U S1 VT | / ( |B| min(M,N) ulp ), VT = V'
00111 *
00112 *  (16)  | I - U' U | / ( min(M,N) ulp )
00113 *
00114 *  (17)  | I - VT VT' | / ( min(M,N) ulp )
00115 *
00116 *  (18)  S1 contains min(M,N) nonnegative values in decreasing order.
00117 *        (Return 0 if true, 1/ULP if false.)
00118 *
00119 *  (19)  | S1 - S2 | / ( |S1| ulp ), where S2 is computed without
00120 *                                    computing U and V.
00121 *  The possible matrix types are
00122 *
00123 *  (1)  The zero matrix.
00124 *  (2)  The identity matrix.
00125 *
00126 *  (3)  A diagonal matrix with evenly spaced entries
00127 *       1, ..., ULP  and random signs.
00128 *       (ULP = (first number larger than 1) - 1 )
00129 *  (4)  A diagonal matrix with geometrically spaced entries
00130 *       1, ..., ULP  and random signs.
00131 *  (5)  A diagonal matrix with "clustered" entries 1, ULP, ..., ULP
00132 *       and random signs.
00133 *
00134 *  (6)  Same as (3), but multiplied by SQRT( overflow threshold )
00135 *  (7)  Same as (3), but multiplied by SQRT( underflow threshold )
00136 *
00137 *  (8)  A matrix of the form  U D V, where U and V are orthogonal and
00138 *       D has evenly spaced entries 1, ..., ULP with random signs
00139 *       on the diagonal.
00140 *
00141 *  (9)  A matrix of the form  U D V, where U and V are orthogonal and
00142 *       D has geometrically spaced entries 1, ..., ULP with random
00143 *       signs on the diagonal.
00144 *
00145 *  (10) A matrix of the form  U D V, where U and V are orthogonal and
00146 *       D has "clustered" entries 1, ULP,..., ULP with random
00147 *       signs on the diagonal.
00148 *
00149 *  (11) Same as (8), but multiplied by SQRT( overflow threshold )
00150 *  (12) Same as (8), but multiplied by SQRT( underflow threshold )
00151 *
00152 *  (13) Rectangular matrix with random entries chosen from (-1,1).
00153 *  (14) Same as (13), but multiplied by SQRT( overflow threshold )
00154 *  (15) Same as (13), but multiplied by SQRT( underflow threshold )
00155 *
00156 *  Special case:
00157 *  (16) A bidiagonal matrix with random entries chosen from a
00158 *       logarithmic distribution on [ulp^2,ulp^(-2)]  (I.e., each
00159 *       entry is  e^x, where x is chosen uniformly on
00160 *       [ 2 log(ulp), -2 log(ulp) ] .)  For *this* type:
00161 *       (a) SGEBRD is not called to reduce it to bidiagonal form.
00162 *       (b) the bidiagonal is  min(M,N) x min(M,N); if M<N, the
00163 *           matrix will be lower bidiagonal, otherwise upper.
00164 *       (c) only tests 5--8 and 14 are performed.
00165 *
00166 *  A subset of the full set of matrix types may be selected through
00167 *  the logical array DOTYPE.
00168 *
00169 *  Arguments
00170 *  ==========
00171 *
00172 *  NSIZES  (input) INTEGER
00173 *          The number of values of M and N contained in the vectors
00174 *          MVAL and NVAL.  The matrix sizes are used in pairs (M,N).
00175 *
00176 *  MVAL    (input) INTEGER array, dimension (NM)
00177 *          The values of the matrix row dimension M.
00178 *
00179 *  NVAL    (input) INTEGER array, dimension (NM)
00180 *          The values of the matrix column dimension N.
00181 *
00182 *  NTYPES  (input) INTEGER
00183 *          The number of elements in DOTYPE.   If it is zero, SCHKBD
00184 *          does nothing.  It must be at least zero.  If it is MAXTYP+1
00185 *          and NSIZES is 1, then an additional type, MAXTYP+1 is
00186 *          defined, which is to use whatever matrices are in A and B.
00187 *          This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and
00188 *          DOTYPE(MAXTYP+1) is .TRUE. .
00189 *
00190 *  DOTYPE  (input) LOGICAL array, dimension (NTYPES)
00191 *          If DOTYPE(j) is .TRUE., then for each size (m,n), a matrix
00192 *          of type j will be generated.  If NTYPES is smaller than the
00193 *          maximum number of types defined (PARAMETER MAXTYP), then
00194 *          types NTYPES+1 through MAXTYP will not be generated.  If
00195 *          NTYPES is larger than MAXTYP, DOTYPE(MAXTYP+1) through
00196 *          DOTYPE(NTYPES) will be ignored.
00197 *
00198 *  NRHS    (input) INTEGER
00199 *          The number of columns in the "right-hand side" matrices X, Y,
00200 *          and Z, used in testing SBDSQR.  If NRHS = 0, then the
00201 *          operations on the right-hand side will not be tested.
00202 *          NRHS must be at least 0.
00203 *
00204 *  ISEED   (input/output) INTEGER array, dimension (4)
00205 *          On entry ISEED specifies the seed of the random number
00206 *          generator. The array elements should be between 0 and 4095;
00207 *          if not they will be reduced mod 4096.  Also, ISEED(4) must
00208 *          be odd.  The values of ISEED are changed on exit, and can be
00209 *          used in the next call to SCHKBD to continue the same random
00210 *          number sequence.
00211 *
00212 *  THRESH  (input) REAL
00213 *          The threshold value for the test ratios.  A result is
00214 *          included in the output file if RESULT >= THRESH.  To have
00215 *          every test ratio printed, use THRESH = 0.  Note that the
00216 *          expected value of the test ratios is O(1), so THRESH should
00217 *          be a reasonably small multiple of 1, e.g., 10 or 100.
00218 *
00219 *  A       (workspace) REAL array, dimension (LDA,NMAX)
00220 *          where NMAX is the maximum value of N in NVAL.
00221 *
00222 *  LDA     (input) INTEGER
00223 *          The leading dimension of the array A.  LDA >= max(1,MMAX),
00224 *          where MMAX is the maximum value of M in MVAL.
00225 *
00226 *  BD      (workspace) REAL array, dimension
00227 *                      (max(min(MVAL(j),NVAL(j))))
00228 *
00229 *  BE      (workspace) REAL array, dimension
00230 *                      (max(min(MVAL(j),NVAL(j))))
00231 *
00232 *  S1      (workspace) REAL array, dimension
00233 *                      (max(min(MVAL(j),NVAL(j))))
00234 *
00235 *  S2      (workspace) REAL array, dimension
00236 *                      (max(min(MVAL(j),NVAL(j))))
00237 *
00238 *  X       (workspace) REAL array, dimension (LDX,NRHS)
00239 *
00240 *  LDX     (input) INTEGER
00241 *          The leading dimension of the arrays X, Y, and Z.
00242 *          LDX >= max(1,MMAX)
00243 *
00244 *  Y       (workspace) REAL array, dimension (LDX,NRHS)
00245 *
00246 *  Z       (workspace) REAL array, dimension (LDX,NRHS)
00247 *
00248 *  Q       (workspace) REAL array, dimension (LDQ,MMAX)
00249 *
00250 *  LDQ     (input) INTEGER
00251 *          The leading dimension of the array Q.  LDQ >= max(1,MMAX).
00252 *
00253 *  PT      (workspace) REAL array, dimension (LDPT,NMAX)
00254 *
00255 *  LDPT    (input) INTEGER
00256 *          The leading dimension of the arrays PT, U, and V.
00257 *          LDPT >= max(1, max(min(MVAL(j),NVAL(j)))).
00258 *
00259 *  U       (workspace) REAL array, dimension
00260 *                      (LDPT,max(min(MVAL(j),NVAL(j))))
00261 *
00262 *  V       (workspace) REAL array, dimension
00263 *                      (LDPT,max(min(MVAL(j),NVAL(j))))
00264 *
00265 *  WORK    (workspace) REAL array, dimension (LWORK)
00266 *
00267 *  LWORK   (input) INTEGER
00268 *          The number of entries in WORK.  This must be at least
00269 *          3(M+N) and  M(M + max(M,N,k) + 1) + N*min(M,N)  for all
00270 *          pairs  (M,N)=(MM(j),NN(j))
00271 *
00272 *  IWORK   (workspace) INTEGER array, dimension at least 8*min(M,N)
00273 *
00274 *  NOUT    (input) INTEGER
00275 *          The FORTRAN unit number for printing out error messages
00276 *          (e.g., if a routine returns IINFO not equal to 0.)
00277 *
00278 *  INFO    (output) INTEGER
00279 *          If 0, then everything ran OK.
00280 *           -1: NSIZES < 0
00281 *           -2: Some MM(j) < 0
00282 *           -3: Some NN(j) < 0
00283 *           -4: NTYPES < 0
00284 *           -6: NRHS  < 0
00285 *           -8: THRESH < 0
00286 *          -11: LDA < 1 or LDA < MMAX, where MMAX is max( MM(j) ).
00287 *          -17: LDB < 1 or LDB < MMAX.
00288 *          -21: LDQ < 1 or LDQ < MMAX.
00289 *          -23: LDPT< 1 or LDPT< MNMAX.
00290 *          -27: LWORK too small.
00291 *          If  SLATMR, SLATMS, SGEBRD, SORGBR, or SBDSQR,
00292 *              returns an error code, the
00293 *              absolute value of it is returned.
00294 *
00295 *-----------------------------------------------------------------------
00296 *
00297 *     Some Local Variables and Parameters:
00298 *     ---- ----- --------- --- ----------
00299 *
00300 *     ZERO, ONE       Real 0 and 1.
00301 *     MAXTYP          The number of types defined.
00302 *     NTEST           The number of tests performed, or which can
00303 *                     be performed so far, for the current matrix.
00304 *     MMAX            Largest value in NN.
00305 *     NMAX            Largest value in NN.
00306 *     MNMIN           min(MM(j), NN(j)) (the dimension of the bidiagonal
00307 *                     matrix.)
00308 *     MNMAX           The maximum value of MNMIN for j=1,...,NSIZES.
00309 *     NFAIL           The number of tests which have exceeded THRESH
00310 *     COND, IMODE     Values to be passed to the matrix generators.
00311 *     ANORM           Norm of A; passed to matrix generators.
00312 *
00313 *     OVFL, UNFL      Overflow and underflow thresholds.
00314 *     RTOVFL, RTUNFL  Square roots of the previous 2 values.
00315 *     ULP, ULPINV     Finest relative precision and its inverse.
00316 *
00317 *             The following four arrays decode JTYPE:
00318 *     KTYPE(j)        The general type (1-10) for type "j".
00319 *     KMODE(j)        The MODE value to be passed to the matrix
00320 *                     generator for type "j".
00321 *     KMAGN(j)        The order of magnitude ( O(1),
00322 *                     O(overflow^(1/2) ), O(underflow^(1/2) )
00323 *
00324 * ======================================================================
00325 *
00326 *     .. Parameters ..
00327       REAL               ZERO, ONE, TWO, HALF
00328       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
00329      \$                   HALF = 0.5E0 )
00330       INTEGER            MAXTYP
00331       PARAMETER          ( MAXTYP = 16 )
00332 *     ..
00333 *     .. Local Scalars ..
00335       CHARACTER          UPLO
00336       CHARACTER*3        PATH
00337       INTEGER            I, IINFO, IMODE, ITYPE, J, JCOL, JSIZE, JTYPE,
00338      \$                   LOG2UI, M, MINWRK, MMAX, MNMAX, MNMIN, MQ,
00339      \$                   MTYPES, N, NFAIL, NMAX, NTEST
00340       REAL               AMNINV, ANORM, COND, OVFL, RTOVFL, RTUNFL,
00341      \$                   TEMP1, TEMP2, ULP, ULPINV, UNFL
00342 *     ..
00343 *     .. Local Arrays ..
00344       INTEGER            IDUM( 1 ), IOLDSD( 4 ), KMAGN( MAXTYP ),
00345      \$                   KMODE( MAXTYP ), KTYPE( MAXTYP )
00346       REAL               DUM( 1 ), DUMMA( 1 ), RESULT( 19 )
00347 *     ..
00348 *     .. External Functions ..
00349       REAL               SLAMCH, SLARND
00350       EXTERNAL           SLAMCH, SLARND
00351 *     ..
00352 *     .. External Subroutines ..
00353       EXTERNAL           ALASUM, SBDSDC, SBDSQR, SBDT01, SBDT02, SBDT03,
00354      \$                   SCOPY, SGEBRD, SGEMM, SLABAD, SLACPY, SLAHD2,
00355      \$                   SLASET, SLATMR, SLATMS, SORGBR, SORT01, XERBLA
00356 *     ..
00357 *     .. Intrinsic Functions ..
00358       INTRINSIC          ABS, EXP, INT, LOG, MAX, MIN, SQRT
00359 *     ..
00360 *     .. Scalars in Common ..
00361       LOGICAL            LERR, OK
00362       CHARACTER*32       SRNAMT
00363       INTEGER            INFOT, NUNIT
00364 *     ..
00365 *     .. Common blocks ..
00366       COMMON             / INFOC / INFOT, NUNIT, OK, LERR
00367       COMMON             / SRNAMC / SRNAMT
00368 *     ..
00369 *     .. Data statements ..
00370       DATA               KTYPE / 1, 2, 5*4, 5*6, 3*9, 10 /
00371       DATA               KMAGN / 2*1, 3*1, 2, 3, 3*1, 2, 3, 1, 2, 3, 0 /
00372       DATA               KMODE / 2*0, 4, 3, 1, 4, 4, 4, 3, 1, 4, 4, 0,
00373      \$                   0, 0, 0 /
00374 *     ..
00375 *     .. Executable Statements ..
00376 *
00377 *     Check for errors
00378 *
00379       INFO = 0
00380 *
00383       MMAX = 1
00384       NMAX = 1
00385       MNMAX = 1
00386       MINWRK = 1
00387       DO 10 J = 1, NSIZES
00388          MMAX = MAX( MMAX, MVAL( J ) )
00389          IF( MVAL( J ).LT.0 )
00391          NMAX = MAX( NMAX, NVAL( J ) )
00392          IF( NVAL( J ).LT.0 )
00394          MNMAX = MAX( MNMAX, MIN( MVAL( J ), NVAL( J ) ) )
00395          MINWRK = MAX( MINWRK, 3*( MVAL( J )+NVAL( J ) ),
00396      \$            MVAL( J )*( MVAL( J )+MAX( MVAL( J ), NVAL( J ),
00397      \$            NRHS )+1 )+NVAL( J )*MIN( NVAL( J ), MVAL( J ) ) )
00398    10 CONTINUE
00399 *
00400 *     Check for errors
00401 *
00402       IF( NSIZES.LT.0 ) THEN
00403          INFO = -1
00404       ELSE IF( BADMM ) THEN
00405          INFO = -2
00406       ELSE IF( BADNN ) THEN
00407          INFO = -3
00408       ELSE IF( NTYPES.LT.0 ) THEN
00409          INFO = -4
00410       ELSE IF( NRHS.LT.0 ) THEN
00411          INFO = -6
00412       ELSE IF( LDA.LT.MMAX ) THEN
00413          INFO = -11
00414       ELSE IF( LDX.LT.MMAX ) THEN
00415          INFO = -17
00416       ELSE IF( LDQ.LT.MMAX ) THEN
00417          INFO = -21
00418       ELSE IF( LDPT.LT.MNMAX ) THEN
00419          INFO = -23
00420       ELSE IF( MINWRK.GT.LWORK ) THEN
00421          INFO = -27
00422       END IF
00423 *
00424       IF( INFO.NE.0 ) THEN
00425          CALL XERBLA( 'SCHKBD', -INFO )
00426          RETURN
00427       END IF
00428 *
00429 *     Initialize constants
00430 *
00431       PATH( 1: 1 ) = 'Single precision'
00432       PATH( 2: 3 ) = 'BD'
00433       NFAIL = 0
00434       NTEST = 0
00435       UNFL = SLAMCH( 'Safe minimum' )
00436       OVFL = SLAMCH( 'Overflow' )
00437       CALL SLABAD( UNFL, OVFL )
00438       ULP = SLAMCH( 'Precision' )
00439       ULPINV = ONE / ULP
00440       LOG2UI = INT( LOG( ULPINV ) / LOG( TWO ) )
00441       RTUNFL = SQRT( UNFL )
00442       RTOVFL = SQRT( OVFL )
00443       INFOT = 0
00444 *
00445 *     Loop over sizes, types
00446 *
00447       DO 200 JSIZE = 1, NSIZES
00448          M = MVAL( JSIZE )
00449          N = NVAL( JSIZE )
00450          MNMIN = MIN( M, N )
00451          AMNINV = ONE / MAX( M, N, 1 )
00452 *
00453          IF( NSIZES.NE.1 ) THEN
00454             MTYPES = MIN( MAXTYP, NTYPES )
00455          ELSE
00456             MTYPES = MIN( MAXTYP+1, NTYPES )
00457          END IF
00458 *
00459          DO 190 JTYPE = 1, MTYPES
00460             IF( .NOT.DOTYPE( JTYPE ) )
00461      \$         GO TO 190
00462 *
00463             DO 20 J = 1, 4
00464                IOLDSD( J ) = ISEED( J )
00465    20       CONTINUE
00466 *
00467             DO 30 J = 1, 14
00468                RESULT( J ) = -ONE
00469    30       CONTINUE
00470 *
00471             UPLO = ' '
00472 *
00473 *           Compute "A"
00474 *
00475 *           Control parameters:
00476 *
00477 *           KMAGN  KMODE        KTYPE
00478 *       =1  O(1)   clustered 1  zero
00479 *       =2  large  clustered 2  identity
00480 *       =3  small  exponential  (none)
00481 *       =4         arithmetic   diagonal, (w/ eigenvalues)
00482 *       =5         random       symmetric, w/ eigenvalues
00483 *       =6                      nonsymmetric, w/ singular values
00484 *       =7                      random diagonal
00485 *       =8                      random symmetric
00486 *       =9                      random nonsymmetric
00487 *       =10                     random bidiagonal (log. distrib.)
00488 *
00489             IF( MTYPES.GT.MAXTYP )
00490      \$         GO TO 100
00491 *
00492             ITYPE = KTYPE( JTYPE )
00493             IMODE = KMODE( JTYPE )
00494 *
00495 *           Compute norm
00496 *
00497             GO TO ( 40, 50, 60 )KMAGN( JTYPE )
00498 *
00499    40       CONTINUE
00500             ANORM = ONE
00501             GO TO 70
00502 *
00503    50       CONTINUE
00504             ANORM = ( RTOVFL*ULP )*AMNINV
00505             GO TO 70
00506 *
00507    60       CONTINUE
00508             ANORM = RTUNFL*MAX( M, N )*ULPINV
00509             GO TO 70
00510 *
00511    70       CONTINUE
00512 *
00513             CALL SLASET( 'Full', LDA, N, ZERO, ZERO, A, LDA )
00514             IINFO = 0
00515             COND = ULPINV
00516 *
00517             BIDIAG = .FALSE.
00518             IF( ITYPE.EQ.1 ) THEN
00519 *
00520 *              Zero matrix
00521 *
00522                IINFO = 0
00523 *
00524             ELSE IF( ITYPE.EQ.2 ) THEN
00525 *
00526 *              Identity
00527 *
00528                DO 80 JCOL = 1, MNMIN
00529                   A( JCOL, JCOL ) = ANORM
00530    80          CONTINUE
00531 *
00532             ELSE IF( ITYPE.EQ.4 ) THEN
00533 *
00534 *              Diagonal Matrix, [Eigen]values Specified
00535 *
00536                CALL SLATMS( MNMIN, MNMIN, 'S', ISEED, 'N', WORK, IMODE,
00537      \$                      COND, ANORM, 0, 0, 'N', A, LDA,
00538      \$                      WORK( MNMIN+1 ), IINFO )
00539 *
00540             ELSE IF( ITYPE.EQ.5 ) THEN
00541 *
00542 *              Symmetric, eigenvalues specified
00543 *
00544                CALL SLATMS( MNMIN, MNMIN, 'S', ISEED, 'S', WORK, IMODE,
00545      \$                      COND, ANORM, M, N, 'N', A, LDA,
00546      \$                      WORK( MNMIN+1 ), IINFO )
00547 *
00548             ELSE IF( ITYPE.EQ.6 ) THEN
00549 *
00550 *              Nonsymmetric, singular values specified
00551 *
00552                CALL SLATMS( M, N, 'S', ISEED, 'N', WORK, IMODE, COND,
00553      \$                      ANORM, M, N, 'N', A, LDA, WORK( MNMIN+1 ),
00554      \$                      IINFO )
00555 *
00556             ELSE IF( ITYPE.EQ.7 ) THEN
00557 *
00558 *              Diagonal, random entries
00559 *
00560                CALL SLATMR( MNMIN, MNMIN, 'S', ISEED, 'N', WORK, 6, ONE,
00561      \$                      ONE, 'T', 'N', WORK( MNMIN+1 ), 1, ONE,
00562      \$                      WORK( 2*MNMIN+1 ), 1, ONE, 'N', IWORK, 0, 0,
00563      \$                      ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
00564 *
00565             ELSE IF( ITYPE.EQ.8 ) THEN
00566 *
00567 *              Symmetric, random entries
00568 *
00569                CALL SLATMR( MNMIN, MNMIN, 'S', ISEED, 'S', WORK, 6, ONE,
00570      \$                      ONE, 'T', 'N', WORK( MNMIN+1 ), 1, ONE,
00571      \$                      WORK( M+MNMIN+1 ), 1, ONE, 'N', IWORK, M, N,
00572      \$                      ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
00573 *
00574             ELSE IF( ITYPE.EQ.9 ) THEN
00575 *
00576 *              Nonsymmetric, random entries
00577 *
00578                CALL SLATMR( M, N, 'S', ISEED, 'N', WORK, 6, ONE, ONE,
00579      \$                      'T', 'N', WORK( MNMIN+1 ), 1, ONE,
00580      \$                      WORK( M+MNMIN+1 ), 1, ONE, 'N', IWORK, M, N,
00581      \$                      ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
00582 *
00583             ELSE IF( ITYPE.EQ.10 ) THEN
00584 *
00585 *              Bidiagonal, random entries
00586 *
00587                TEMP1 = -TWO*LOG( ULP )
00588                DO 90 J = 1, MNMIN
00589                   BD( J ) = EXP( TEMP1*SLARND( 2, ISEED ) )
00590                   IF( J.LT.MNMIN )
00591      \$               BE( J ) = EXP( TEMP1*SLARND( 2, ISEED ) )
00592    90          CONTINUE
00593 *
00594                IINFO = 0
00595                BIDIAG = .TRUE.
00596                IF( M.GE.N ) THEN
00597                   UPLO = 'U'
00598                ELSE
00599                   UPLO = 'L'
00600                END IF
00601             ELSE
00602                IINFO = 1
00603             END IF
00604 *
00605             IF( IINFO.EQ.0 ) THEN
00606 *
00607 *              Generate Right-Hand Side
00608 *
00609                IF( BIDIAG ) THEN
00610                   CALL SLATMR( MNMIN, NRHS, 'S', ISEED, 'N', WORK, 6,
00611      \$                         ONE, ONE, 'T', 'N', WORK( MNMIN+1 ), 1,
00612      \$                         ONE, WORK( 2*MNMIN+1 ), 1, ONE, 'N',
00613      \$                         IWORK, MNMIN, NRHS, ZERO, ONE, 'NO', Y,
00614      \$                         LDX, IWORK, IINFO )
00615                ELSE
00616                   CALL SLATMR( M, NRHS, 'S', ISEED, 'N', WORK, 6, ONE,
00617      \$                         ONE, 'T', 'N', WORK( M+1 ), 1, ONE,
00618      \$                         WORK( 2*M+1 ), 1, ONE, 'N', IWORK, M,
00619      \$                         NRHS, ZERO, ONE, 'NO', X, LDX, IWORK,
00620      \$                         IINFO )
00621                END IF
00622             END IF
00623 *
00624 *           Error Exit
00625 *
00626             IF( IINFO.NE.0 ) THEN
00627                WRITE( NOUT, FMT = 9998 )'Generator', IINFO, M, N,
00628      \$            JTYPE, IOLDSD
00629                INFO = ABS( IINFO )
00630                RETURN
00631             END IF
00632 *
00633   100       CONTINUE
00634 *
00635 *           Call SGEBRD and SORGBR to compute B, Q, and P, do tests.
00636 *
00637             IF( .NOT.BIDIAG ) THEN
00638 *
00639 *              Compute transformations to reduce A to bidiagonal form:
00640 *              B := Q' * A * P.
00641 *
00642                CALL SLACPY( ' ', M, N, A, LDA, Q, LDQ )
00643                CALL SGEBRD( M, N, Q, LDQ, BD, BE, WORK, WORK( MNMIN+1 ),
00644      \$                      WORK( 2*MNMIN+1 ), LWORK-2*MNMIN, IINFO )
00645 *
00646 *              Check error code from SGEBRD.
00647 *
00648                IF( IINFO.NE.0 ) THEN
00649                   WRITE( NOUT, FMT = 9998 )'SGEBRD', IINFO, M, N,
00650      \$               JTYPE, IOLDSD
00651                   INFO = ABS( IINFO )
00652                   RETURN
00653                END IF
00654 *
00655                CALL SLACPY( ' ', M, N, Q, LDQ, PT, LDPT )
00656                IF( M.GE.N ) THEN
00657                   UPLO = 'U'
00658                ELSE
00659                   UPLO = 'L'
00660                END IF
00661 *
00662 *              Generate Q
00663 *
00664                MQ = M
00665                IF( NRHS.LE.0 )
00666      \$            MQ = MNMIN
00667                CALL SORGBR( 'Q', M, MQ, N, Q, LDQ, WORK,
00668      \$                      WORK( 2*MNMIN+1 ), LWORK-2*MNMIN, IINFO )
00669 *
00670 *              Check error code from SORGBR.
00671 *
00672                IF( IINFO.NE.0 ) THEN
00673                   WRITE( NOUT, FMT = 9998 )'SORGBR(Q)', IINFO, M, N,
00674      \$               JTYPE, IOLDSD
00675                   INFO = ABS( IINFO )
00676                   RETURN
00677                END IF
00678 *
00679 *              Generate P'
00680 *
00681                CALL SORGBR( 'P', MNMIN, N, M, PT, LDPT, WORK( MNMIN+1 ),
00682      \$                      WORK( 2*MNMIN+1 ), LWORK-2*MNMIN, IINFO )
00683 *
00684 *              Check error code from SORGBR.
00685 *
00686                IF( IINFO.NE.0 ) THEN
00687                   WRITE( NOUT, FMT = 9998 )'SORGBR(P)', IINFO, M, N,
00688      \$               JTYPE, IOLDSD
00689                   INFO = ABS( IINFO )
00690                   RETURN
00691                END IF
00692 *
00693 *              Apply Q' to an M by NRHS matrix X:  Y := Q' * X.
00694 *
00695                CALL SGEMM( 'Transpose', 'No transpose', M, NRHS, M, ONE,
00696      \$                     Q, LDQ, X, LDX, ZERO, Y, LDX )
00697 *
00698 *              Test 1:  Check the decomposition A := Q * B * PT
00699 *                   2:  Check the orthogonality of Q
00700 *                   3:  Check the orthogonality of PT
00701 *
00702                CALL SBDT01( M, N, 1, A, LDA, Q, LDQ, BD, BE, PT, LDPT,
00703      \$                      WORK, RESULT( 1 ) )
00704                CALL SORT01( 'Columns', M, MQ, Q, LDQ, WORK, LWORK,
00705      \$                      RESULT( 2 ) )
00706                CALL SORT01( 'Rows', MNMIN, N, PT, LDPT, WORK, LWORK,
00707      \$                      RESULT( 3 ) )
00708             END IF
00709 *
00710 *           Use SBDSQR to form the SVD of the bidiagonal matrix B:
00711 *           B := U * S1 * VT, and compute Z = U' * Y.
00712 *
00713             CALL SCOPY( MNMIN, BD, 1, S1, 1 )
00714             IF( MNMIN.GT.0 )
00715      \$         CALL SCOPY( MNMIN-1, BE, 1, WORK, 1 )
00716             CALL SLACPY( ' ', M, NRHS, Y, LDX, Z, LDX )
00717             CALL SLASET( 'Full', MNMIN, MNMIN, ZERO, ONE, U, LDPT )
00718             CALL SLASET( 'Full', MNMIN, MNMIN, ZERO, ONE, VT, LDPT )
00719 *
00720             CALL SBDSQR( UPLO, MNMIN, MNMIN, MNMIN, NRHS, S1, WORK, VT,
00721      \$                   LDPT, U, LDPT, Z, LDX, WORK( MNMIN+1 ), IINFO )
00722 *
00723 *           Check error code from SBDSQR.
00724 *
00725             IF( IINFO.NE.0 ) THEN
00726                WRITE( NOUT, FMT = 9998 )'SBDSQR(vects)', IINFO, M, N,
00727      \$            JTYPE, IOLDSD
00728                INFO = ABS( IINFO )
00729                IF( IINFO.LT.0 ) THEN
00730                   RETURN
00731                ELSE
00732                   RESULT( 4 ) = ULPINV
00733                   GO TO 170
00734                END IF
00735             END IF
00736 *
00737 *           Use SBDSQR to compute only the singular values of the
00738 *           bidiagonal matrix B;  U, VT, and Z should not be modified.
00739 *
00740             CALL SCOPY( MNMIN, BD, 1, S2, 1 )
00741             IF( MNMIN.GT.0 )
00742      \$         CALL SCOPY( MNMIN-1, BE, 1, WORK, 1 )
00743 *
00744             CALL SBDSQR( UPLO, MNMIN, 0, 0, 0, S2, WORK, VT, LDPT, U,
00745      \$                   LDPT, Z, LDX, WORK( MNMIN+1 ), IINFO )
00746 *
00747 *           Check error code from SBDSQR.
00748 *
00749             IF( IINFO.NE.0 ) THEN
00750                WRITE( NOUT, FMT = 9998 )'SBDSQR(values)', IINFO, M, N,
00751      \$            JTYPE, IOLDSD
00752                INFO = ABS( IINFO )
00753                IF( IINFO.LT.0 ) THEN
00754                   RETURN
00755                ELSE
00756                   RESULT( 9 ) = ULPINV
00757                   GO TO 170
00758                END IF
00759             END IF
00760 *
00761 *           Test 4:  Check the decomposition B := U * S1 * VT
00762 *                5:  Check the computation Z := U' * Y
00763 *                6:  Check the orthogonality of U
00764 *                7:  Check the orthogonality of VT
00765 *
00766             CALL SBDT03( UPLO, MNMIN, 1, BD, BE, U, LDPT, S1, VT, LDPT,
00767      \$                   WORK, RESULT( 4 ) )
00768             CALL SBDT02( MNMIN, NRHS, Y, LDX, Z, LDX, U, LDPT, WORK,
00769      \$                   RESULT( 5 ) )
00770             CALL SORT01( 'Columns', MNMIN, MNMIN, U, LDPT, WORK, LWORK,
00771      \$                   RESULT( 6 ) )
00772             CALL SORT01( 'Rows', MNMIN, MNMIN, VT, LDPT, WORK, LWORK,
00773      \$                   RESULT( 7 ) )
00774 *
00775 *           Test 8:  Check that the singular values are sorted in
00776 *                    non-increasing order and are non-negative
00777 *
00778             RESULT( 8 ) = ZERO
00779             DO 110 I = 1, MNMIN - 1
00780                IF( S1( I ).LT.S1( I+1 ) )
00781      \$            RESULT( 8 ) = ULPINV
00782                IF( S1( I ).LT.ZERO )
00783      \$            RESULT( 8 ) = ULPINV
00784   110       CONTINUE
00785             IF( MNMIN.GE.1 ) THEN
00786                IF( S1( MNMIN ).LT.ZERO )
00787      \$            RESULT( 8 ) = ULPINV
00788             END IF
00789 *
00790 *           Test 9:  Compare SBDSQR with and without singular vectors
00791 *
00792             TEMP2 = ZERO
00793 *
00794             DO 120 J = 1, MNMIN
00795                TEMP1 = ABS( S1( J )-S2( J ) ) /
00796      \$                 MAX( SQRT( UNFL )*MAX( S1( 1 ), ONE ),
00797      \$                 ULP*MAX( ABS( S1( J ) ), ABS( S2( J ) ) ) )
00798                TEMP2 = MAX( TEMP1, TEMP2 )
00799   120       CONTINUE
00800 *
00801             RESULT( 9 ) = TEMP2
00802 *
00803 *           Test 10:  Sturm sequence test of singular values
00804 *                     Go up by factors of two until it succeeds
00805 *
00806             TEMP1 = THRESH*( HALF-ULP )
00807 *
00808             DO 130 J = 0, LOG2UI
00809 *               CALL SSVDCH( MNMIN, BD, BE, S1, TEMP1, IINFO )
00810                IF( IINFO.EQ.0 )
00811      \$            GO TO 140
00812                TEMP1 = TEMP1*TWO
00813   130       CONTINUE
00814 *
00815   140       CONTINUE
00816             RESULT( 10 ) = TEMP1
00817 *
00818 *           Use SBDSQR to form the decomposition A := (QU) S (VT PT)
00819 *           from the bidiagonal form A := Q B PT.
00820 *
00821             IF( .NOT.BIDIAG ) THEN
00822                CALL SCOPY( MNMIN, BD, 1, S2, 1 )
00823                IF( MNMIN.GT.0 )
00824      \$            CALL SCOPY( MNMIN-1, BE, 1, WORK, 1 )
00825 *
00826                CALL SBDSQR( UPLO, MNMIN, N, M, NRHS, S2, WORK, PT, LDPT,
00827      \$                      Q, LDQ, Y, LDX, WORK( MNMIN+1 ), IINFO )
00828 *
00829 *              Test 11:  Check the decomposition A := Q*U * S2 * VT*PT
00830 *                   12:  Check the computation Z := U' * Q' * X
00831 *                   13:  Check the orthogonality of Q*U
00832 *                   14:  Check the orthogonality of VT*PT
00833 *
00834                CALL SBDT01( M, N, 0, A, LDA, Q, LDQ, S2, DUMMA, PT,
00835      \$                      LDPT, WORK, RESULT( 11 ) )
00836                CALL SBDT02( M, NRHS, X, LDX, Y, LDX, Q, LDQ, WORK,
00837      \$                      RESULT( 12 ) )
00838                CALL SORT01( 'Columns', M, MQ, Q, LDQ, WORK, LWORK,
00839      \$                      RESULT( 13 ) )
00840                CALL SORT01( 'Rows', MNMIN, N, PT, LDPT, WORK, LWORK,
00841      \$                      RESULT( 14 ) )
00842             END IF
00843 *
00844 *           Use SBDSDC to form the SVD of the bidiagonal matrix B:
00845 *           B := U * S1 * VT
00846 *
00847             CALL SCOPY( MNMIN, BD, 1, S1, 1 )
00848             IF( MNMIN.GT.0 )
00849      \$         CALL SCOPY( MNMIN-1, BE, 1, WORK, 1 )
00850             CALL SLASET( 'Full', MNMIN, MNMIN, ZERO, ONE, U, LDPT )
00851             CALL SLASET( 'Full', MNMIN, MNMIN, ZERO, ONE, VT, LDPT )
00852 *
00853             CALL SBDSDC( UPLO, 'I', MNMIN, S1, WORK, U, LDPT, VT, LDPT,
00854      \$                   DUM, IDUM, WORK( MNMIN+1 ), IWORK, IINFO )
00855 *
00856 *           Check error code from SBDSDC.
00857 *
00858             IF( IINFO.NE.0 ) THEN
00859                WRITE( NOUT, FMT = 9998 )'SBDSDC(vects)', IINFO, M, N,
00860      \$            JTYPE, IOLDSD
00861                INFO = ABS( IINFO )
00862                IF( IINFO.LT.0 ) THEN
00863                   RETURN
00864                ELSE
00865                   RESULT( 15 ) = ULPINV
00866                   GO TO 170
00867                END IF
00868             END IF
00869 *
00870 *           Use SBDSDC to compute only the singular values of the
00871 *           bidiagonal matrix B;  U and VT should not be modified.
00872 *
00873             CALL SCOPY( MNMIN, BD, 1, S2, 1 )
00874             IF( MNMIN.GT.0 )
00875      \$         CALL SCOPY( MNMIN-1, BE, 1, WORK, 1 )
00876 *
00877             CALL SBDSDC( UPLO, 'N', MNMIN, S2, WORK, DUM, 1, DUM, 1,
00878      \$                   DUM, IDUM, WORK( MNMIN+1 ), IWORK, IINFO )
00879 *
00880 *           Check error code from SBDSDC.
00881 *
00882             IF( IINFO.NE.0 ) THEN
00883                WRITE( NOUT, FMT = 9998 )'SBDSDC(values)', IINFO, M, N,
00884      \$            JTYPE, IOLDSD
00885                INFO = ABS( IINFO )
00886                IF( IINFO.LT.0 ) THEN
00887                   RETURN
00888                ELSE
00889                   RESULT( 18 ) = ULPINV
00890                   GO TO 170
00891                END IF
00892             END IF
00893 *
00894 *           Test 15:  Check the decomposition B := U * S1 * VT
00895 *                16:  Check the orthogonality of U
00896 *                17:  Check the orthogonality of VT
00897 *
00898             CALL SBDT03( UPLO, MNMIN, 1, BD, BE, U, LDPT, S1, VT, LDPT,
00899      \$                   WORK, RESULT( 15 ) )
00900             CALL SORT01( 'Columns', MNMIN, MNMIN, U, LDPT, WORK, LWORK,
00901      \$                   RESULT( 16 ) )
00902             CALL SORT01( 'Rows', MNMIN, MNMIN, VT, LDPT, WORK, LWORK,
00903      \$                   RESULT( 17 ) )
00904 *
00905 *           Test 18:  Check that the singular values are sorted in
00906 *                     non-increasing order and are non-negative
00907 *
00908             RESULT( 18 ) = ZERO
00909             DO 150 I = 1, MNMIN - 1
00910                IF( S1( I ).LT.S1( I+1 ) )
00911      \$            RESULT( 18 ) = ULPINV
00912                IF( S1( I ).LT.ZERO )
00913      \$            RESULT( 18 ) = ULPINV
00914   150       CONTINUE
00915             IF( MNMIN.GE.1 ) THEN
00916                IF( S1( MNMIN ).LT.ZERO )
00917      \$            RESULT( 18 ) = ULPINV
00918             END IF
00919 *
00920 *           Test 19:  Compare SBDSQR with and without singular vectors
00921 *
00922             TEMP2 = ZERO
00923 *
00924             DO 160 J = 1, MNMIN
00925                TEMP1 = ABS( S1( J )-S2( J ) ) /
00926      \$                 MAX( SQRT( UNFL )*MAX( S1( 1 ), ONE ),
00927      \$                 ULP*MAX( ABS( S1( 1 ) ), ABS( S2( 1 ) ) ) )
00928                TEMP2 = MAX( TEMP1, TEMP2 )
00929   160       CONTINUE
00930 *
00931             RESULT( 19 ) = TEMP2
00932 *
00933 *           End of Loop -- Check for RESULT(j) > THRESH
00934 *
00935   170       CONTINUE
00936             DO 180 J = 1, 19
00937                IF( RESULT( J ).GE.THRESH ) THEN
00938                   IF( NFAIL.EQ.0 )
00939      \$               CALL SLAHD2( NOUT, PATH )
00940                   WRITE( NOUT, FMT = 9999 )M, N, JTYPE, IOLDSD, J,
00941      \$               RESULT( J )
00942                   NFAIL = NFAIL + 1
00943                END IF
00944   180       CONTINUE
00945             IF( .NOT.BIDIAG ) THEN
00946                NTEST = NTEST + 19
00947             ELSE
00948                NTEST = NTEST + 5
00949             END IF
00950 *
00951   190    CONTINUE
00952   200 CONTINUE
00953 *
00954 *     Summary
00955 *
00956       CALL ALASUM( PATH, NOUT, NFAIL, NTEST, 0 )
00957 *
00958       RETURN
00959 *
00960 *     End of SCHKBD
00961 *
00962  9999 FORMAT( ' M=', I5, ', N=', I5, ', type ', I2, ', seed=',
00963      \$      4( I4, ',' ), ' test(', I2, ')=', G11.4 )
00964  9998 FORMAT( ' SCHKBD: ', A, ' returned INFO=', I6, '.', / 9X, 'M=',
00965      \$      I6, ', N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ),
00966      \$      I5, ')' )
00967 *
00968       END
```