LAPACK 3.3.1
Linear Algebra PACKage

cchkbd.f

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