b093e871baf9050afc1ddb1f79559ef186af62c0
[platform/upstream/lapack.git] / TESTING / EIG / dchkbd.f
1 *> \brief \b DCHKBD
2 *
3 *  =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at 
6 *            http://www.netlib.org/lapack/explore-html/ 
7 *
8 *  Definition:
9 *  ===========
10 *
11 *       SUBROUTINE DCHKBD( NSIZES, MVAL, NVAL, NTYPES, DOTYPE, NRHS,
12 *                          ISEED, THRESH, A, LDA, BD, BE, S1, S2, X, LDX,
13 *                          Y, Z, Q, LDQ, PT, LDPT, U, VT, WORK, LWORK,
14 *                          IWORK, NOUT, INFO )
15
16 *       .. Scalar Arguments ..
17 *       INTEGER            INFO, LDA, LDPT, LDQ, LDX, LWORK, NOUT, NRHS,
18 *      $                   NSIZES, NTYPES
19 *       DOUBLE PRECISION   THRESH
20 *       ..
21 *       .. Array Arguments ..
22 *       LOGICAL            DOTYPE( * )
23 *       INTEGER            ISEED( 4 ), IWORK( * ), MVAL( * ), NVAL( * )
24 *       DOUBLE PRECISION   A( LDA, * ), BD( * ), BE( * ), PT( LDPT, * ),
25 *      $                   Q( LDQ, * ), S1( * ), S2( * ), U( LDPT, * ),
26 *      $                   VT( LDPT, * ), WORK( * ), X( LDX, * ),
27 *      $                   Y( LDX, * ), Z( LDX, * )
28 *       ..
29 *  
30 *
31 *> \par Purpose:
32 *  =============
33 *>
34 *> \verbatim
35 *>
36 *> DCHKBD checks the singular value decomposition (SVD) routines.
37 *>
38 *> DGEBRD reduces a real general m by n matrix A to upper or lower
39 *> bidiagonal form B by an orthogonal transformation:  Q' * A * P = B
40 *> (or A = Q * B * P').  The matrix B is upper bidiagonal if m >= n
41 *> and lower bidiagonal if m < n.
42 *>
43 *> DORGBR generates the orthogonal matrices Q and P' from DGEBRD.
44 *> Note that Q and P are not necessarily square.
45 *>
46 *> DBDSQR computes the singular value decomposition of the bidiagonal
47 *> matrix B as B = U S V'.  It is called three times to compute
48 *>    1)  B = U S1 V', where S1 is the diagonal matrix of singular
49 *>        values and the columns of the matrices U and V are the left
50 *>        and right singular vectors, respectively, of B.
51 *>    2)  Same as 1), but the singular values are stored in S2 and the
52 *>        singular vectors are not computed.
53 *>    3)  A = (UQ) S (P'V'), the SVD of the original matrix A.
54 *> In addition, DBDSQR has an option to apply the left orthogonal matrix
55 *> U to a matrix X, useful in least squares applications.
56 *>
57 *> DBDSDC computes the singular value decomposition of the bidiagonal
58 *> matrix B as B = U S V' using divide-and-conquer. It is called twice
59 *> to compute
60 *>    1) B = U S1 V', where S1 is the diagonal matrix of singular
61 *>        values and the columns of the matrices U and V are the left
62 *>        and right singular vectors, respectively, of B.
63 *>    2) Same as 1), but the singular values are stored in S2 and the
64 *>        singular vectors are not computed.
65 *>
66 *>  DBDSVDX computes the singular value decomposition of the bidiagonal
67 *>  matrix B as B = U S V' using bisection and inverse iteration. It is 
68 *>  called six times to compute
69 *>     1) B = U S1 V', RANGE='A', where S1 is the diagonal matrix of singular
70 *>         values and the columns of the matrices U and V are the left
71 *>         and right singular vectors, respectively, of B.
72 *>     2) Same as 1), but the singular values are stored in S2 and the
73 *>         singular vectors are not computed.
74 *>     3) B = U S1 V', RANGE='I', with where S1 is the diagonal matrix of singular
75 *>         values and the columns of the matrices U and V are the left
76 *>         and right singular vectors, respectively, of B
77 *>     4) Same as 3), but the singular values are stored in S2 and the
78 *>         singular vectors are not computed.
79 *>     5) B = U S1 V', RANGE='V', with where S1 is the diagonal matrix of singular
80 *>         values and the columns of the matrices U and V are the left
81 *>         and right singular vectors, respectively, of B
82 *>     6) Same as 5), but the singular values are stored in S2 and the
83 *>         singular vectors are not computed.
84 *>
85 *> For each pair of matrix dimensions (M,N) and each selected matrix
86 *> type, an M by N matrix A and an M by NRHS matrix X are generated.
87 *> The problem dimensions are as follows
88 *>    A:          M x N
89 *>    Q:          M x min(M,N) (but M x M if NRHS > 0)
90 *>    P:          min(M,N) x N
91 *>    B:          min(M,N) x min(M,N)
92 *>    U, V:       min(M,N) x min(M,N)
93 *>    S1, S2      diagonal, order min(M,N)
94 *>    X:          M x NRHS
95 *>
96 *> For each generated matrix, 14 tests are performed:
97 *>
98 *> Test DGEBRD and DORGBR
99 *>
100 *> (1)   | A - Q B PT | / ( |A| max(M,N) ulp ), PT = P'
101 *>
102 *> (2)   | I - Q' Q | / ( M ulp )
103 *>
104 *> (3)   | I - PT PT' | / ( N ulp )
105 *>
106 *> Test DBDSQR on bidiagonal matrix B
107 *>
108 *> (4)   | B - U S1 VT | / ( |B| min(M,N) ulp ), VT = V'
109 *>
110 *> (5)   | Y - U Z | / ( |Y| max(min(M,N),k) ulp ), where Y = Q' X
111 *>                                                  and   Z = U' Y.
112 *> (6)   | I - U' U | / ( min(M,N) ulp )
113 *>
114 *> (7)   | I - VT VT' | / ( min(M,N) ulp )
115 *>
116 *> (8)   S1 contains min(M,N) nonnegative values in decreasing order.
117 *>       (Return 0 if true, 1/ULP if false.)
118 *>
119 *> (9)   | S1 - S2 | / ( |S1| ulp ), where S2 is computed without
120 *>                                   computing U and V.
121 *>
122 *> (10)  0 if the true singular values of B are within THRESH of
123 *>       those in S1.  2*THRESH if they are not.  (Tested using
124 *>       DSVDCH)
125 *>
126 *> Test DBDSQR on matrix A
127 *>
128 *> (11)  | A - (QU) S (VT PT) | / ( |A| max(M,N) ulp )
129 *>
130 *> (12)  | X - (QU) Z | / ( |X| max(M,k) ulp )
131 *>
132 *> (13)  | I - (QU)'(QU) | / ( M ulp )
133 *>
134 *> (14)  | I - (VT PT) (PT'VT') | / ( N ulp )
135 *>
136 *> Test DBDSDC on bidiagonal matrix B
137 *>
138 *> (15)  | B - U S1 VT | / ( |B| min(M,N) ulp ), VT = V'
139 *>
140 *> (16)  | I - U' U | / ( min(M,N) ulp )
141 *>
142 *> (17)  | I - VT VT' | / ( min(M,N) ulp )
143 *>
144 *> (18)  S1 contains min(M,N) nonnegative values in decreasing order.
145 *>       (Return 0 if true, 1/ULP if false.)
146 *>
147 *> (19)  | S1 - S2 | / ( |S1| ulp ), where S2 is computed without
148 *>                                   computing U and V.
149 *>  Test DBDSVDX on bidiagonal matrix B
150 *> 
151 *>  (20)  | B - U S1 VT | / ( |B| min(M,N) ulp ), VT = V'
152 *> 
153 *>  (21)  | I - U' U | / ( min(M,N) ulp )
154 *> 
155 *>  (22)  | I - VT VT' | / ( min(M,N) ulp )
156 *> 
157 *>  (23)  S1 contains min(M,N) nonnegative values in decreasing order.
158 *>        (Return 0 if true, 1/ULP if false.)
159 *> 
160 *>  (24)  | S1 - S2 | / ( |S1| ulp ), where S2 is computed without
161 *>                                    computing U and V.
162 *> 
163 *>  (25)  | S1 - U' B VT' | / ( |S| n ulp )    DBDSVDX('V', 'I')
164 *> 
165 *>  (26)  | I - U' U | / ( min(M,N) ulp )
166 *> 
167 *>  (27)  | I - VT VT' | / ( min(M,N) ulp )
168 *>
169 *>  (28)  S1 contains min(M,N) nonnegative values in decreasing order.
170 *>        (Return 0 if true, 1/ULP if false.)
171 *> 
172 *>  (29)  | S1 - S2 | / ( |S1| ulp ), where S2 is computed without
173 *>                                    computing U and V.
174 *> 
175 *>  (30)  | S1 - U' B VT' | / ( |S1| n ulp )   DBDSVDX('V', 'V')
176 *> 
177 *>  (31)  | I - U' U | / ( min(M,N) ulp )
178 *> 
179 *>  (32)  | I - VT VT' | / ( min(M,N) ulp )
180 *>
181 *>  (33)  S1 contains min(M,N) nonnegative values in decreasing order.
182 *>        (Return 0 if true, 1/ULP if false.)
183 *> 
184 *>  (34)  | S1 - S2 | / ( |S1| ulp ), where S2 is computed without
185 *>                                    computing U and V.
186 *> 
187 *> The possible matrix types are
188 *>
189 *> (1)  The zero matrix.
190 *> (2)  The identity matrix.
191 *>
192 *> (3)  A diagonal matrix with evenly spaced entries
193 *>      1, ..., ULP  and random signs.
194 *>      (ULP = (first number larger than 1) - 1 )
195 *> (4)  A diagonal matrix with geometrically spaced entries
196 *>      1, ..., ULP  and random signs.
197 *> (5)  A diagonal matrix with "clustered" entries 1, ULP, ..., ULP
198 *>      and random signs.
199 *>
200 *> (6)  Same as (3), but multiplied by SQRT( overflow threshold )
201 *> (7)  Same as (3), but multiplied by SQRT( underflow threshold )
202 *>
203 *> (8)  A matrix of the form  U D V, where U and V are orthogonal and
204 *>      D has evenly spaced entries 1, ..., ULP with random signs
205 *>      on the diagonal.
206 *>
207 *> (9)  A matrix of the form  U D V, where U and V are orthogonal and
208 *>      D has geometrically spaced entries 1, ..., ULP with random
209 *>      signs on the diagonal.
210 *>
211 *> (10) A matrix of the form  U D V, where U and V are orthogonal and
212 *>      D has "clustered" entries 1, ULP,..., ULP with random
213 *>      signs on the diagonal.
214 *>
215 *> (11) Same as (8), but multiplied by SQRT( overflow threshold )
216 *> (12) Same as (8), but multiplied by SQRT( underflow threshold )
217 *>
218 *> (13) Rectangular matrix with random entries chosen from (-1,1).
219 *> (14) Same as (13), but multiplied by SQRT( overflow threshold )
220 *> (15) Same as (13), but multiplied by SQRT( underflow threshold )
221 *>
222 *> Special case:
223 *> (16) A bidiagonal matrix with random entries chosen from a
224 *>      logarithmic distribution on [ulp^2,ulp^(-2)]  (I.e., each
225 *>      entry is  e^x, where x is chosen uniformly on
226 *>      [ 2 log(ulp), -2 log(ulp) ] .)  For *this* type:
227 *>      (a) DGEBRD is not called to reduce it to bidiagonal form.
228 *>      (b) the bidiagonal is  min(M,N) x min(M,N); if M<N, the
229 *>          matrix will be lower bidiagonal, otherwise upper.
230 *>      (c) only tests 5--8 and 14 are performed.
231 *>
232 *> A subset of the full set of matrix types may be selected through
233 *> the logical array DOTYPE.
234 *> \endverbatim
235 *
236 *  Arguments:
237 *  ==========
238 *
239 *> \param[in] NSIZES
240 *> \verbatim
241 *>          NSIZES is INTEGER
242 *>          The number of values of M and N contained in the vectors
243 *>          MVAL and NVAL.  The matrix sizes are used in pairs (M,N).
244 *> \endverbatim
245 *>
246 *> \param[in] MVAL
247 *> \verbatim
248 *>          MVAL is INTEGER array, dimension (NM)
249 *>          The values of the matrix row dimension M.
250 *> \endverbatim
251 *>
252 *> \param[in] NVAL
253 *> \verbatim
254 *>          NVAL is INTEGER array, dimension (NM)
255 *>          The values of the matrix column dimension N.
256 *> \endverbatim
257 *>
258 *> \param[in] NTYPES
259 *> \verbatim
260 *>          NTYPES is INTEGER
261 *>          The number of elements in DOTYPE.   If it is zero, DCHKBD
262 *>          does nothing.  It must be at least zero.  If it is MAXTYP+1
263 *>          and NSIZES is 1, then an additional type, MAXTYP+1 is
264 *>          defined, which is to use whatever matrices are in A and B.
265 *>          This is only useful if DOTYPE(1:MAXTYP) is .FALSE. and
266 *>          DOTYPE(MAXTYP+1) is .TRUE. .
267 *> \endverbatim
268 *>
269 *> \param[in] DOTYPE
270 *> \verbatim
271 *>          DOTYPE is LOGICAL array, dimension (NTYPES)
272 *>          If DOTYPE(j) is .TRUE., then for each size (m,n), a matrix
273 *>          of type j will be generated.  If NTYPES is smaller than the
274 *>          maximum number of types defined (PARAMETER MAXTYP), then
275 *>          types NTYPES+1 through MAXTYP will not be generated.  If
276 *>          NTYPES is larger than MAXTYP, DOTYPE(MAXTYP+1) through
277 *>          DOTYPE(NTYPES) will be ignored.
278 *> \endverbatim
279 *>
280 *> \param[in] NRHS
281 *> \verbatim
282 *>          NRHS is INTEGER
283 *>          The number of columns in the "right-hand side" matrices X, Y,
284 *>          and Z, used in testing DBDSQR.  If NRHS = 0, then the
285 *>          operations on the right-hand side will not be tested.
286 *>          NRHS must be at least 0.
287 *> \endverbatim
288 *>
289 *> \param[in,out] ISEED
290 *> \verbatim
291 *>          ISEED is INTEGER array, dimension (4)
292 *>          On entry ISEED specifies the seed of the random number
293 *>          generator. The array elements should be between 0 and 4095;
294 *>          if not they will be reduced mod 4096.  Also, ISEED(4) must
295 *>          be odd.  The values of ISEED are changed on exit, and can be
296 *>          used in the next call to DCHKBD to continue the same random
297 *>          number sequence.
298 *> \endverbatim
299 *>
300 *> \param[in] THRESH
301 *> \verbatim
302 *>          THRESH is DOUBLE PRECISION
303 *>          The threshold value for the test ratios.  A result is
304 *>          included in the output file if RESULT >= THRESH.  To have
305 *>          every test ratio printed, use THRESH = 0.  Note that the
306 *>          expected value of the test ratios is O(1), so THRESH should
307 *>          be a reasonably small multiple of 1, e.g., 10 or 100.
308 *> \endverbatim
309 *>
310 *> \param[out] A
311 *> \verbatim
312 *>          A is DOUBLE PRECISION array, dimension (LDA,NMAX)
313 *>          where NMAX is the maximum value of N in NVAL.
314 *> \endverbatim
315 *>
316 *> \param[in] LDA
317 *> \verbatim
318 *>          LDA is INTEGER
319 *>          The leading dimension of the array A.  LDA >= max(1,MMAX),
320 *>          where MMAX is the maximum value of M in MVAL.
321 *> \endverbatim
322 *>
323 *> \param[out] BD
324 *> \verbatim
325 *>          BD is DOUBLE PRECISION array, dimension
326 *>                      (max(min(MVAL(j),NVAL(j))))
327 *> \endverbatim
328 *>
329 *> \param[out] BE
330 *> \verbatim
331 *>          BE is DOUBLE PRECISION array, dimension
332 *>                      (max(min(MVAL(j),NVAL(j))))
333 *> \endverbatim
334 *>
335 *> \param[out] S1
336 *> \verbatim
337 *>          S1 is DOUBLE PRECISION array, dimension
338 *>                      (max(min(MVAL(j),NVAL(j))))
339 *> \endverbatim
340 *>
341 *> \param[out] S2
342 *> \verbatim
343 *>          S2 is DOUBLE PRECISION array, dimension
344 *>                      (max(min(MVAL(j),NVAL(j))))
345 *> \endverbatim
346 *>
347 *> \param[out] X
348 *> \verbatim
349 *>          X is DOUBLE PRECISION array, dimension (LDX,NRHS)
350 *> \endverbatim
351 *>
352 *> \param[in] LDX
353 *> \verbatim
354 *>          LDX is INTEGER
355 *>          The leading dimension of the arrays X, Y, and Z.
356 *>          LDX >= max(1,MMAX)
357 *> \endverbatim
358 *>
359 *> \param[out] Y
360 *> \verbatim
361 *>          Y is DOUBLE PRECISION array, dimension (LDX,NRHS)
362 *> \endverbatim
363 *>
364 *> \param[out] Z
365 *> \verbatim
366 *>          Z is DOUBLE PRECISION array, dimension (LDX,NRHS)
367 *> \endverbatim
368 *>
369 *> \param[out] Q
370 *> \verbatim
371 *>          Q is DOUBLE PRECISION array, dimension (LDQ,MMAX)
372 *> \endverbatim
373 *>
374 *> \param[in] LDQ
375 *> \verbatim
376 *>          LDQ is INTEGER
377 *>          The leading dimension of the array Q.  LDQ >= max(1,MMAX).
378 *> \endverbatim
379 *>
380 *> \param[out] PT
381 *> \verbatim
382 *>          PT is DOUBLE PRECISION array, dimension (LDPT,NMAX)
383 *> \endverbatim
384 *>
385 *> \param[in] LDPT
386 *> \verbatim
387 *>          LDPT is INTEGER
388 *>          The leading dimension of the arrays PT, U, and V.
389 *>          LDPT >= max(1, max(min(MVAL(j),NVAL(j)))).
390 *> \endverbatim
391 *>
392 *> \param[out] U
393 *> \verbatim
394 *>          U is DOUBLE PRECISION array, dimension
395 *>                      (LDPT,max(min(MVAL(j),NVAL(j))))
396 *> \endverbatim
397 *>
398 *> \param[out] VT
399 *> \verbatim
400 *>          VT is DOUBLE PRECISION array, dimension
401 *>                      (LDPT,max(min(MVAL(j),NVAL(j))))
402 *> \endverbatim
403 *>
404 *> \param[out] WORK
405 *> \verbatim
406 *>          WORK is DOUBLE PRECISION array, dimension (LWORK)
407 *> \endverbatim
408 *>
409 *> \param[in] LWORK
410 *> \verbatim
411 *>          LWORK is INTEGER
412 *>          The number of entries in WORK.  This must be at least
413 *>          3(M+N) and  M(M + max(M,N,k) + 1) + N*min(M,N)  for all
414 *>          pairs  (M,N)=(MM(j),NN(j))
415 *> \endverbatim
416 *>
417 *> \param[out] IWORK
418 *> \verbatim
419 *>          IWORK is INTEGER array, dimension at least 8*min(M,N)
420 *> \endverbatim
421 *>
422 *> \param[in] NOUT
423 *> \verbatim
424 *>          NOUT is INTEGER
425 *>          The FORTRAN unit number for printing out error messages
426 *>          (e.g., if a routine returns IINFO not equal to 0.)
427 *> \endverbatim
428 *>
429 *> \param[out] INFO
430 *> \verbatim
431 *>          INFO is INTEGER
432 *>          If 0, then everything ran OK.
433 *>           -1: NSIZES < 0
434 *>           -2: Some MM(j) < 0
435 *>           -3: Some NN(j) < 0
436 *>           -4: NTYPES < 0
437 *>           -6: NRHS  < 0
438 *>           -8: THRESH < 0
439 *>          -11: LDA < 1 or LDA < MMAX, where MMAX is max( MM(j) ).
440 *>          -17: LDB < 1 or LDB < MMAX.
441 *>          -21: LDQ < 1 or LDQ < MMAX.
442 *>          -23: LDPT< 1 or LDPT< MNMAX.
443 *>          -27: LWORK too small.
444 *>          If  DLATMR, SLATMS, DGEBRD, DORGBR, or DBDSQR,
445 *>              returns an error code, the
446 *>              absolute value of it is returned.
447 *>
448 *>-----------------------------------------------------------------------
449 *>
450 *>     Some Local Variables and Parameters:
451 *>     ---- ----- --------- --- ----------
452 *>
453 *>     ZERO, ONE       Real 0 and 1.
454 *>     MAXTYP          The number of types defined.
455 *>     NTEST           The number of tests performed, or which can
456 *>                     be performed so far, for the current matrix.
457 *>     MMAX            Largest value in NN.
458 *>     NMAX            Largest value in NN.
459 *>     MNMIN           min(MM(j), NN(j)) (the dimension of the bidiagonal
460 *>                     matrix.)
461 *>     MNMAX           The maximum value of MNMIN for j=1,...,NSIZES.
462 *>     NFAIL           The number of tests which have exceeded THRESH
463 *>     COND, IMODE     Values to be passed to the matrix generators.
464 *>     ANORM           Norm of A; passed to matrix generators.
465 *>
466 *>     OVFL, UNFL      Overflow and underflow thresholds.
467 *>     RTOVFL, RTUNFL  Square roots of the previous 2 values.
468 *>     ULP, ULPINV     Finest relative precision and its inverse.
469 *>
470 *>             The following four arrays decode JTYPE:
471 *>     KTYPE(j)        The general type (1-10) for type "j".
472 *>     KMODE(j)        The MODE value to be passed to the matrix
473 *>                     generator for type "j".
474 *>     KMAGN(j)        The order of magnitude ( O(1),
475 *>                     O(overflow^(1/2) ), O(underflow^(1/2) )
476 *> \endverbatim
477 *
478 *  Authors:
479 *  ========
480 *
481 *> \author Univ. of Tennessee 
482 *> \author Univ. of California Berkeley 
483 *> \author Univ. of Colorado Denver 
484 *> \author NAG Ltd. 
485 *
486 *> \date June 2016
487 *
488 *> \ingroup double_eig
489 *
490 *  =====================================================================
491       SUBROUTINE DCHKBD( NSIZES, MVAL, NVAL, NTYPES, DOTYPE, NRHS,
492      $                   ISEED, THRESH, A, LDA, BD, BE, S1, S2, X, LDX,
493      $                   Y, Z, Q, LDQ, PT, LDPT, U, VT, WORK, LWORK,
494      $                   IWORK, NOUT, INFO )
495 *
496 *  -- LAPACK test routine (version 3.6.1) --
497 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
498 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
499 *     June 2016
500 *
501 *     .. Scalar Arguments ..
502       INTEGER            INFO, LDA, LDPT, LDQ, LDX, LWORK, NOUT, NRHS,
503      $                   NSIZES, NTYPES
504       DOUBLE PRECISION   THRESH
505 *     ..
506 *     .. Array Arguments ..
507       LOGICAL            DOTYPE( * )
508       INTEGER            ISEED( 4 ), IWORK( * ), MVAL( * ), NVAL( * )
509       DOUBLE PRECISION   A( LDA, * ), BD( * ), BE( * ), PT( LDPT, * ),
510      $                   Q( LDQ, * ), S1( * ), S2( * ), U( LDPT, * ),
511      $                   VT( LDPT, * ), WORK( * ), X( LDX, * ),
512      $                   Y( LDX, * ), Z( LDX, * )
513 *     ..
514 *
515 * ======================================================================
516 *
517 *     .. Parameters ..
518       DOUBLE PRECISION   ZERO, ONE, TWO, HALF
519       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
520      $                   HALF = 0.5D0 )
521       INTEGER            MAXTYP
522       PARAMETER          ( MAXTYP = 16 )
523 *     ..
524 *     .. Local Scalars ..
525       LOGICAL            BADMM, BADNN, BIDIAG
526       CHARACTER          UPLO
527       CHARACTER*3        PATH
528       INTEGER            I, IINFO, IL, IMODE, ITEMP, ITYPE, IU, IWBD, 
529      $                   IWBE, IWBS, IWBZ, IWWORK, J, JCOL, JSIZE,
530      $                   JTYPE, LOG2UI, M, MINWRK, MMAX, MNMAX, MNMIN, 
531      $                   MNMIN2, MQ, MTYPES, N, NFAIL, NMAX, 
532      $                   NS1, NS2, NTEST
533       DOUBLE PRECISION   ABSTOL, AMNINV, ANORM, COND, OVFL, RTOVFL, 
534      $                   RTUNFL, TEMP1, TEMP2, TEMP3, ULP, ULPINV, 
535      $                   UNFL, VL, VU                   
536 *     ..
537 *     .. Local Arrays ..
538       INTEGER            IDUM( 1 ), IOLDSD( 4 ), ISEED2( 4 ), 
539      $                   KMAGN( MAXTYP ), KMODE( MAXTYP ), 
540      $                   KTYPE( MAXTYP )
541       DOUBLE PRECISION   DUM( 1 ), DUMMA( 1 ), RESULT( 40 )
542 *     ..
543 *     .. External Functions ..
544       DOUBLE PRECISION   DLAMCH, DLARND, DSXT1
545       EXTERNAL           DLAMCH, DLARND, DSXT1
546 *     ..
547 *     .. External Subroutines ..
548       EXTERNAL           ALASUM, DBDSDC, DBDSQR, DBDSVDX, DBDT01,  
549      $                   DBDT02, DBDT03, DBDT04, DCOPY, DGEBRD,
550      $                   DGEMM, DLABAD, DLACPY, DLAHD2, DLASET, 
551      $                   DLATMR, DLATMS, DORGBR, DORT01, XERBLA
552 *     ..
553 *     .. Intrinsic Functions ..
554       INTRINSIC          ABS, EXP, INT, LOG, MAX, MIN, SQRT
555 *     ..
556 *     .. Scalars in Common ..
557       LOGICAL            LERR, OK
558       CHARACTER*32       SRNAMT
559       INTEGER            INFOT, NUNIT
560 *     ..
561 *     .. Common blocks ..
562       COMMON             / INFOC / INFOT, NUNIT, OK, LERR
563       COMMON             / SRNAMC / SRNAMT
564 *     ..
565 *     .. Data statements ..
566       DATA            KTYPE / 1, 2, 5*4, 5*6, 3*9, 10 /
567       DATA            KMAGN / 2*1, 3*1, 2, 3, 3*1, 2, 3, 1, 2, 3, 0 /
568       DATA            KMODE / 2*0, 4, 3, 1, 4, 4, 4, 3, 1, 4, 4, 0,
569      $                0, 0, 0 /
570 *     ..
571 *     .. Executable Statements ..
572 *
573 *     Check for errors
574 *
575       INFO = 0
576 *
577       BADMM = .FALSE.
578       BADNN = .FALSE.
579       MMAX = 1
580       NMAX = 1
581       MNMAX = 1
582       MINWRK = 1
583       DO 10 J = 1, NSIZES
584          MMAX = MAX( MMAX, MVAL( J ) )
585          IF( MVAL( J ).LT.0 )
586      $      BADMM = .TRUE.
587          NMAX = MAX( NMAX, NVAL( J ) )
588          IF( NVAL( J ).LT.0 )
589      $      BADNN = .TRUE.
590          MNMAX = MAX( MNMAX, MIN( MVAL( J ), NVAL( J ) ) )
591          MINWRK = MAX( MINWRK, 3*( MVAL( J )+NVAL( J ) ),
592      $            MVAL( J )*( MVAL( J )+MAX( MVAL( J ), NVAL( J ),
593      $            NRHS )+1 )+NVAL( J )*MIN( NVAL( J ), MVAL( J ) ) )
594    10 CONTINUE
595 *
596 *     Check for errors
597 *
598       IF( NSIZES.LT.0 ) THEN
599          INFO = -1
600       ELSE IF( BADMM ) THEN
601          INFO = -2
602       ELSE IF( BADNN ) THEN
603          INFO = -3
604       ELSE IF( NTYPES.LT.0 ) THEN
605          INFO = -4
606       ELSE IF( NRHS.LT.0 ) THEN
607          INFO = -6
608       ELSE IF( LDA.LT.MMAX ) THEN
609          INFO = -11
610       ELSE IF( LDX.LT.MMAX ) THEN
611          INFO = -17
612       ELSE IF( LDQ.LT.MMAX ) THEN
613          INFO = -21
614       ELSE IF( LDPT.LT.MNMAX ) THEN
615          INFO = -23
616       ELSE IF( MINWRK.GT.LWORK ) THEN
617          INFO = -27
618       END IF
619 *
620       IF( INFO.NE.0 ) THEN
621          CALL XERBLA( 'DCHKBD', -INFO )
622          RETURN
623       END IF
624 *
625 *     Initialize constants
626 *
627       PATH( 1: 1 ) = 'Double precision'
628       PATH( 2: 3 ) = 'BD'
629       NFAIL = 0
630       NTEST = 0
631       UNFL = DLAMCH( 'Safe minimum' )
632       OVFL = DLAMCH( 'Overflow' )
633       CALL DLABAD( UNFL, OVFL )
634       ULP = DLAMCH( 'Precision' )
635       ULPINV = ONE / ULP
636       LOG2UI = INT( LOG( ULPINV ) / LOG( TWO ) )
637       RTUNFL = SQRT( UNFL )
638       RTOVFL = SQRT( OVFL )
639       INFOT = 0
640       ABSTOL = 2*UNFL
641 *
642 *     Loop over sizes, types
643 *
644       DO 300 JSIZE = 1, NSIZES
645          M = MVAL( JSIZE )
646          N = NVAL( JSIZE )
647          MNMIN = MIN( M, N )
648          AMNINV = ONE / MAX( M, N, 1 )
649 *
650          IF( NSIZES.NE.1 ) THEN
651             MTYPES = MIN( MAXTYP, NTYPES )
652          ELSE
653             MTYPES = MIN( MAXTYP+1, NTYPES )
654          END IF
655 *
656          DO 290 JTYPE = 1, MTYPES
657             IF( .NOT.DOTYPE( JTYPE ) )
658      $         GO TO 290
659 *
660             DO 20 J = 1, 4
661                IOLDSD( J ) = ISEED( J )
662    20       CONTINUE
663 *
664             DO 30 J = 1, 34
665                RESULT( J ) = -ONE
666    30       CONTINUE
667 *
668             UPLO = ' '
669 *
670 *           Compute "A"
671 *
672 *           Control parameters:
673 *
674 *           KMAGN  KMODE        KTYPE
675 *       =1  O(1)   clustered 1  zero
676 *       =2  large  clustered 2  identity
677 *       =3  small  exponential  (none)
678 *       =4         arithmetic   diagonal, (w/ eigenvalues)
679 *       =5         random       symmetric, w/ eigenvalues
680 *       =6                      nonsymmetric, w/ singular values
681 *       =7                      random diagonal
682 *       =8                      random symmetric
683 *       =9                      random nonsymmetric
684 *       =10                     random bidiagonal (log. distrib.)
685 *
686             IF( MTYPES.GT.MAXTYP )
687      $         GO TO 100
688 *
689             ITYPE = KTYPE( JTYPE )
690             IMODE = KMODE( JTYPE )
691 *
692 *           Compute norm
693 *
694             GO TO ( 40, 50, 60 )KMAGN( JTYPE )
695 *
696    40       CONTINUE
697             ANORM = ONE
698             GO TO 70
699 *
700    50       CONTINUE
701             ANORM = ( RTOVFL*ULP )*AMNINV
702             GO TO 70
703 *
704    60       CONTINUE
705             ANORM = RTUNFL*MAX( M, N )*ULPINV
706             GO TO 70
707 *
708    70       CONTINUE
709 *
710             CALL DLASET( 'Full', LDA, N, ZERO, ZERO, A, LDA )
711             IINFO = 0
712             COND = ULPINV
713 *
714             BIDIAG = .FALSE.
715             IF( ITYPE.EQ.1 ) THEN
716 *
717 *              Zero matrix
718 *
719                IINFO = 0
720 *
721             ELSE IF( ITYPE.EQ.2 ) THEN
722 *
723 *              Identity
724 *
725                DO 80 JCOL = 1, MNMIN
726                   A( JCOL, JCOL ) = ANORM
727    80          CONTINUE
728 *
729             ELSE IF( ITYPE.EQ.4 ) THEN
730 *
731 *              Diagonal Matrix, [Eigen]values Specified
732 *
733                CALL DLATMS( MNMIN, MNMIN, 'S', ISEED, 'N', WORK, IMODE,
734      $                      COND, ANORM, 0, 0, 'N', A, LDA,
735      $                      WORK( MNMIN+1 ), IINFO )
736 *
737             ELSE IF( ITYPE.EQ.5 ) THEN
738 *
739 *              Symmetric, eigenvalues specified
740 *
741                CALL DLATMS( MNMIN, MNMIN, 'S', ISEED, 'S', WORK, IMODE,
742      $                      COND, ANORM, M, N, 'N', A, LDA,
743      $                      WORK( MNMIN+1 ), IINFO )
744 *
745             ELSE IF( ITYPE.EQ.6 ) THEN
746 *
747 *              Nonsymmetric, singular values specified
748 *
749                CALL DLATMS( M, N, 'S', ISEED, 'N', WORK, IMODE, COND,
750      $                      ANORM, M, N, 'N', A, LDA, WORK( MNMIN+1 ),
751      $                      IINFO )
752 *
753             ELSE IF( ITYPE.EQ.7 ) THEN
754 *
755 *              Diagonal, random entries
756 *
757                CALL DLATMR( MNMIN, MNMIN, 'S', ISEED, 'N', WORK, 6, ONE,
758      $                      ONE, 'T', 'N', WORK( MNMIN+1 ), 1, ONE,
759      $                      WORK( 2*MNMIN+1 ), 1, ONE, 'N', IWORK, 0, 0,
760      $                      ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
761 *
762             ELSE IF( ITYPE.EQ.8 ) THEN
763 *
764 *              Symmetric, random entries
765 *
766                CALL DLATMR( MNMIN, MNMIN, 'S', ISEED, 'S', WORK, 6, ONE,
767      $                      ONE, 'T', 'N', WORK( MNMIN+1 ), 1, ONE,
768      $                      WORK( M+MNMIN+1 ), 1, ONE, 'N', IWORK, M, N,
769      $                      ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
770 *
771             ELSE IF( ITYPE.EQ.9 ) THEN
772 *
773 *              Nonsymmetric, random entries
774 *
775                CALL DLATMR( M, N, 'S', ISEED, 'N', WORK, 6, ONE, ONE,
776      $                      'T', 'N', WORK( MNMIN+1 ), 1, ONE,
777      $                      WORK( M+MNMIN+1 ), 1, ONE, 'N', IWORK, M, N,
778      $                      ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
779 *
780             ELSE IF( ITYPE.EQ.10 ) THEN
781 *
782 *              Bidiagonal, random entries
783 *
784                TEMP1 = -TWO*LOG( ULP )
785                DO 90 J = 1, MNMIN
786                   BD( J ) = EXP( TEMP1*DLARND( 2, ISEED ) )
787                   IF( J.LT.MNMIN )
788      $               BE( J ) = EXP( TEMP1*DLARND( 2, ISEED ) )
789    90          CONTINUE
790 *
791                IINFO = 0
792                BIDIAG = .TRUE.
793                IF( M.GE.N ) THEN
794                   UPLO = 'U'
795                ELSE
796                   UPLO = 'L'
797                END IF
798             ELSE
799                IINFO = 1
800             END IF
801 *
802             IF( IINFO.EQ.0 ) THEN
803 *
804 *              Generate Right-Hand Side
805 *
806                IF( BIDIAG ) THEN
807                   CALL DLATMR( MNMIN, NRHS, 'S', ISEED, 'N', WORK, 6,
808      $                         ONE, ONE, 'T', 'N', WORK( MNMIN+1 ), 1,
809      $                         ONE, WORK( 2*MNMIN+1 ), 1, ONE, 'N',
810      $                         IWORK, MNMIN, NRHS, ZERO, ONE, 'NO', Y,
811      $                         LDX, IWORK, IINFO )
812                ELSE
813                   CALL DLATMR( M, NRHS, 'S', ISEED, 'N', WORK, 6, ONE,
814      $                         ONE, 'T', 'N', WORK( M+1 ), 1, ONE,
815      $                         WORK( 2*M+1 ), 1, ONE, 'N', IWORK, M,
816      $                         NRHS, ZERO, ONE, 'NO', X, LDX, IWORK,
817      $                         IINFO )
818                END IF
819             END IF
820 *
821 *           Error Exit
822 *
823             IF( IINFO.NE.0 ) THEN
824                WRITE( NOUT, FMT = 9998 )'Generator', IINFO, M, N,
825      $            JTYPE, IOLDSD
826                INFO = ABS( IINFO )
827                RETURN
828             END IF
829 *
830   100       CONTINUE
831 *
832 *           Call DGEBRD and DORGBR to compute B, Q, and P, do tests.
833 *
834             IF( .NOT.BIDIAG ) THEN
835 *
836 *              Compute transformations to reduce A to bidiagonal form:
837 *              B := Q' * A * P.
838 *
839                CALL DLACPY( ' ', M, N, A, LDA, Q, LDQ )
840                CALL DGEBRD( M, N, Q, LDQ, BD, BE, WORK, WORK( MNMIN+1 ),
841      $                      WORK( 2*MNMIN+1 ), LWORK-2*MNMIN, IINFO )
842 *
843 *              Check error code from DGEBRD.
844 *
845                IF( IINFO.NE.0 ) THEN
846                   WRITE( NOUT, FMT = 9998 )'DGEBRD', IINFO, M, N,
847      $               JTYPE, IOLDSD
848                   INFO = ABS( IINFO )
849                   RETURN
850                END IF
851 *
852                CALL DLACPY( ' ', M, N, Q, LDQ, PT, LDPT )
853                IF( M.GE.N ) THEN
854                   UPLO = 'U'
855                ELSE
856                   UPLO = 'L'
857                END IF
858 *
859 *              Generate Q
860 *
861                MQ = M
862                IF( NRHS.LE.0 )
863      $            MQ = MNMIN
864                CALL DORGBR( 'Q', M, MQ, N, Q, LDQ, WORK,
865      $                      WORK( 2*MNMIN+1 ), LWORK-2*MNMIN, IINFO )
866 *
867 *              Check error code from DORGBR.
868 *
869                IF( IINFO.NE.0 ) THEN
870                   WRITE( NOUT, FMT = 9998 )'DORGBR(Q)', IINFO, M, N,
871      $               JTYPE, IOLDSD
872                   INFO = ABS( IINFO )
873                   RETURN
874                END IF
875 *
876 *              Generate P'
877 *
878                CALL DORGBR( 'P', MNMIN, N, M, PT, LDPT, WORK( MNMIN+1 ),
879      $                      WORK( 2*MNMIN+1 ), LWORK-2*MNMIN, IINFO )
880 *
881 *              Check error code from DORGBR.
882 *
883                IF( IINFO.NE.0 ) THEN
884                   WRITE( NOUT, FMT = 9998 )'DORGBR(P)', IINFO, M, N,
885      $               JTYPE, IOLDSD
886                   INFO = ABS( IINFO )
887                   RETURN
888                END IF
889 *
890 *              Apply Q' to an M by NRHS matrix X:  Y := Q' * X.
891 *
892                CALL DGEMM( 'Transpose', 'No transpose', M, NRHS, M, ONE,
893      $                     Q, LDQ, X, LDX, ZERO, Y, LDX )
894 *
895 *              Test 1:  Check the decomposition A := Q * B * PT
896 *                   2:  Check the orthogonality of Q
897 *                   3:  Check the orthogonality of PT
898 *
899                CALL DBDT01( M, N, 1, A, LDA, Q, LDQ, BD, BE, PT, LDPT,
900      $                      WORK, RESULT( 1 ) )
901                CALL DORT01( 'Columns', M, MQ, Q, LDQ, WORK, LWORK,
902      $                      RESULT( 2 ) )
903                CALL DORT01( 'Rows', MNMIN, N, PT, LDPT, WORK, LWORK,
904      $                      RESULT( 3 ) )
905             END IF
906 *
907 *           Use DBDSQR to form the SVD of the bidiagonal matrix B:
908 *           B := U * S1 * VT, and compute Z = U' * Y.
909 *
910             CALL DCOPY( MNMIN, BD, 1, S1, 1 )
911             IF( MNMIN.GT.0 )
912      $         CALL DCOPY( MNMIN-1, BE, 1, WORK, 1 )
913             CALL DLACPY( ' ', M, NRHS, Y, LDX, Z, LDX )
914             CALL DLASET( 'Full', MNMIN, MNMIN, ZERO, ONE, U, LDPT )
915             CALL DLASET( 'Full', MNMIN, MNMIN, ZERO, ONE, VT, LDPT )
916 *
917             CALL DBDSQR( UPLO, MNMIN, MNMIN, MNMIN, NRHS, S1, WORK, VT,
918      $                   LDPT, U, LDPT, Z, LDX, WORK( MNMIN+1 ), IINFO )
919 *
920 *           Check error code from DBDSQR.
921 *
922             IF( IINFO.NE.0 ) THEN
923                WRITE( NOUT, FMT = 9998 )'DBDSQR(vects)', IINFO, M, N,
924      $            JTYPE, IOLDSD
925                INFO = ABS( IINFO )
926                IF( IINFO.LT.0 ) THEN
927                   RETURN
928                ELSE
929                   RESULT( 4 ) = ULPINV
930                   GO TO 270
931                END IF
932             END IF
933 *
934 *           Use DBDSQR to compute only the singular values of the
935 *           bidiagonal matrix B;  U, VT, and Z should not be modified.
936 *
937             CALL DCOPY( MNMIN, BD, 1, S2, 1 )
938             IF( MNMIN.GT.0 )
939      $         CALL DCOPY( MNMIN-1, BE, 1, WORK, 1 )
940 *
941             CALL DBDSQR( UPLO, MNMIN, 0, 0, 0, S2, WORK, VT, LDPT, U,
942      $                   LDPT, Z, LDX, WORK( MNMIN+1 ), IINFO )
943 *
944 *           Check error code from DBDSQR.
945 *
946             IF( IINFO.NE.0 ) THEN
947                WRITE( NOUT, FMT = 9998 )'DBDSQR(values)', IINFO, M, N,
948      $            JTYPE, IOLDSD
949                INFO = ABS( IINFO )
950                IF( IINFO.LT.0 ) THEN
951                   RETURN
952                ELSE
953                   RESULT( 9 ) = ULPINV
954                   GO TO 270
955                END IF
956             END IF
957 *
958 *           Test 4:  Check the decomposition B := U * S1 * VT
959 *                5:  Check the computation Z := U' * Y
960 *                6:  Check the orthogonality of U
961 *                7:  Check the orthogonality of VT
962 *
963             CALL DBDT03( UPLO, MNMIN, 1, BD, BE, U, LDPT, S1, VT, LDPT,
964      $                   WORK, RESULT( 4 ) )
965             CALL DBDT02( MNMIN, NRHS, Y, LDX, Z, LDX, U, LDPT, WORK,
966      $                   RESULT( 5 ) )
967             CALL DORT01( 'Columns', MNMIN, MNMIN, U, LDPT, WORK, LWORK,
968      $                   RESULT( 6 ) )
969             CALL DORT01( 'Rows', MNMIN, MNMIN, VT, LDPT, WORK, LWORK,
970      $                   RESULT( 7 ) )
971 *
972 *           Test 8:  Check that the singular values are sorted in
973 *                    non-increasing order and are non-negative
974 *
975             RESULT( 8 ) = ZERO
976             DO 110 I = 1, MNMIN - 1
977                IF( S1( I ).LT.S1( I+1 ) )
978      $            RESULT( 8 ) = ULPINV
979                IF( S1( I ).LT.ZERO )
980      $            RESULT( 8 ) = ULPINV
981   110       CONTINUE
982             IF( MNMIN.GE.1 ) THEN
983                IF( S1( MNMIN ).LT.ZERO )
984      $            RESULT( 8 ) = ULPINV
985             END IF
986 *
987 *           Test 9:  Compare DBDSQR with and without singular vectors
988 *
989             TEMP2 = ZERO
990 *
991             DO 120 J = 1, MNMIN
992                TEMP1 = ABS( S1( J )-S2( J ) ) /
993      $                 MAX( SQRT( UNFL )*MAX( S1( 1 ), ONE ),
994      $                 ULP*MAX( ABS( S1( J ) ), ABS( S2( J ) ) ) )
995                TEMP2 = MAX( TEMP1, TEMP2 )
996   120       CONTINUE
997 *
998             RESULT( 9 ) = TEMP2
999 *
1000 *           Test 10:  Sturm sequence test of singular values
1001 *                     Go up by factors of two until it succeeds
1002 *
1003             TEMP1 = THRESH*( HALF-ULP )
1004 *
1005             DO 130 J = 0, LOG2UI
1006 *               CALL DSVDCH( MNMIN, BD, BE, S1, TEMP1, IINFO )
1007                IF( IINFO.EQ.0 )
1008      $            GO TO 140
1009                TEMP1 = TEMP1*TWO
1010   130       CONTINUE
1011 *
1012   140       CONTINUE
1013             RESULT( 10 ) = TEMP1
1014 *
1015 *           Use DBDSQR to form the decomposition A := (QU) S (VT PT)
1016 *           from the bidiagonal form A := Q B PT.
1017 *
1018             IF( .NOT.BIDIAG ) THEN
1019                CALL DCOPY( MNMIN, BD, 1, S2, 1 )
1020                IF( MNMIN.GT.0 )
1021      $            CALL DCOPY( MNMIN-1, BE, 1, WORK, 1 )
1022 *
1023                CALL DBDSQR( UPLO, MNMIN, N, M, NRHS, S2, WORK, PT, LDPT,
1024      $                      Q, LDQ, Y, LDX, WORK( MNMIN+1 ), IINFO )
1025 *
1026 *              Test 11:  Check the decomposition A := Q*U * S2 * VT*PT
1027 *                   12:  Check the computation Z := U' * Q' * X
1028 *                   13:  Check the orthogonality of Q*U
1029 *                   14:  Check the orthogonality of VT*PT
1030 *
1031                CALL DBDT01( M, N, 0, A, LDA, Q, LDQ, S2, DUMMA, PT,
1032      $                      LDPT, WORK, RESULT( 11 ) )
1033                CALL DBDT02( M, NRHS, X, LDX, Y, LDX, Q, LDQ, WORK,
1034      $                      RESULT( 12 ) )
1035                CALL DORT01( 'Columns', M, MQ, Q, LDQ, WORK, LWORK,
1036      $                      RESULT( 13 ) )
1037                CALL DORT01( 'Rows', MNMIN, N, PT, LDPT, WORK, LWORK,
1038      $                      RESULT( 14 ) )
1039             END IF
1040 *
1041 *           Use DBDSDC to form the SVD of the bidiagonal matrix B:
1042 *           B := U * S1 * VT
1043 *
1044             CALL DCOPY( MNMIN, BD, 1, S1, 1 )
1045             IF( MNMIN.GT.0 )
1046      $         CALL DCOPY( MNMIN-1, BE, 1, WORK, 1 )
1047             CALL DLASET( 'Full', MNMIN, MNMIN, ZERO, ONE, U, LDPT )
1048             CALL DLASET( 'Full', MNMIN, MNMIN, ZERO, ONE, VT, LDPT )
1049 *
1050             CALL DBDSDC( UPLO, 'I', MNMIN, S1, WORK, U, LDPT, VT, LDPT,
1051      $                   DUM, IDUM, WORK( MNMIN+1 ), IWORK, IINFO )
1052 *
1053 *           Check error code from DBDSDC.
1054 *
1055             IF( IINFO.NE.0 ) THEN
1056                WRITE( NOUT, FMT = 9998 )'DBDSDC(vects)', IINFO, M, N,
1057      $            JTYPE, IOLDSD
1058                INFO = ABS( IINFO )
1059                IF( IINFO.LT.0 ) THEN
1060                   RETURN
1061                ELSE
1062                   RESULT( 15 ) = ULPINV
1063                   GO TO 270
1064                END IF
1065             END IF
1066 *
1067 *           Use DBDSDC to compute only the singular values of the
1068 *           bidiagonal matrix B;  U and VT should not be modified.
1069 *
1070             CALL DCOPY( MNMIN, BD, 1, S2, 1 )
1071             IF( MNMIN.GT.0 )
1072      $         CALL DCOPY( MNMIN-1, BE, 1, WORK, 1 )
1073 *
1074             CALL DBDSDC( UPLO, 'N', MNMIN, S2, WORK, DUM, 1, DUM, 1,
1075      $                   DUM, IDUM, WORK( MNMIN+1 ), IWORK, IINFO )
1076 *
1077 *           Check error code from DBDSDC.
1078 *
1079             IF( IINFO.NE.0 ) THEN
1080                WRITE( NOUT, FMT = 9998 )'DBDSDC(values)', IINFO, M, N,
1081      $            JTYPE, IOLDSD
1082                INFO = ABS( IINFO )
1083                IF( IINFO.LT.0 ) THEN
1084                   RETURN
1085                ELSE
1086                   RESULT( 18 ) = ULPINV
1087                   GO TO 270
1088                END IF
1089             END IF
1090 *
1091 *           Test 15:  Check the decomposition B := U * S1 * VT
1092 *                16:  Check the orthogonality of U
1093 *                17:  Check the orthogonality of VT
1094 *
1095             CALL DBDT03( UPLO, MNMIN, 1, BD, BE, U, LDPT, S1, VT, LDPT,
1096      $                   WORK, RESULT( 15 ) )
1097             CALL DORT01( 'Columns', MNMIN, MNMIN, U, LDPT, WORK, LWORK,
1098      $                   RESULT( 16 ) )
1099             CALL DORT01( 'Rows', MNMIN, MNMIN, VT, LDPT, WORK, LWORK,
1100      $                   RESULT( 17 ) )
1101 *
1102 *           Test 18:  Check that the singular values are sorted in
1103 *                     non-increasing order and are non-negative
1104 *
1105             RESULT( 18 ) = ZERO
1106             DO 150 I = 1, MNMIN - 1
1107                IF( S1( I ).LT.S1( I+1 ) )
1108      $            RESULT( 18 ) = ULPINV
1109                IF( S1( I ).LT.ZERO )
1110      $            RESULT( 18 ) = ULPINV
1111   150       CONTINUE
1112             IF( MNMIN.GE.1 ) THEN
1113                IF( S1( MNMIN ).LT.ZERO )
1114      $            RESULT( 18 ) = ULPINV
1115             END IF
1116 *
1117 *           Test 19:  Compare DBDSQR with and without singular vectors
1118 *
1119             TEMP2 = ZERO
1120 *
1121             DO 160 J = 1, MNMIN
1122                TEMP1 = ABS( S1( J )-S2( J ) ) /
1123      $                 MAX( SQRT( UNFL )*MAX( S1( 1 ), ONE ),
1124      $                 ULP*MAX( ABS( S1( 1 ) ), ABS( S2( 1 ) ) ) )
1125                TEMP2 = MAX( TEMP1, TEMP2 )
1126   160       CONTINUE
1127 *
1128             RESULT( 19 ) = TEMP2
1129 *
1130 *
1131 *           Use DBDSVDX to compute the SVD of the bidiagonal matrix B:
1132 *           B := U * S1 * VT
1133 *
1134             IF( JTYPE.EQ.10 .OR. JTYPE.EQ.16 ) THEN
1135 *              =================================
1136 *              Matrix types temporarily disabled
1137 *              =================================
1138                RESULT( 20:34 ) = ZERO
1139                GO TO 270
1140             END IF
1141 *
1142             IWBS = 1
1143             IWBD = IWBS + MNMIN
1144             IWBE = IWBD + MNMIN
1145             IWBZ = IWBE + MNMIN
1146             IWWORK = IWBZ + 2*MNMIN*(MNMIN+1)
1147             MNMIN2 = MAX( 1,MNMIN*2 )
1148 *
1149             CALL DCOPY( MNMIN, BD, 1, WORK( IWBD ), 1 )
1150             IF( MNMIN.GT.0 )
1151      $         CALL DCOPY( MNMIN-1, BE, 1, WORK( IWBE ), 1 )
1152 *
1153             CALL DBDSVDX( UPLO, 'V', 'A', MNMIN, WORK( IWBD ),
1154      $                    WORK( IWBE ), ZERO, ZERO, 0, 0, NS1, S1, 
1155      $                    WORK( IWBZ ), MNMIN2, WORK( IWWORK ), 
1156      $                    IWORK, IINFO)
1157 *  
1158 *           Check error code from DBDSVDX.
1159 *
1160             IF( IINFO.NE.0 ) THEN
1161                WRITE( NOUT, FMT = 9998 )'DBDSVDX(vects,A)', IINFO, M, N,
1162      $            JTYPE, IOLDSD
1163                INFO = ABS( IINFO )
1164                IF( IINFO.LT.0 ) THEN
1165                   RETURN
1166                ELSE
1167                   RESULT( 20 ) = ULPINV
1168                   GO TO 270
1169                END IF
1170             END IF
1171 *
1172             J = IWBZ
1173             DO 170 I = 1, NS1
1174                CALL DCOPY( MNMIN, WORK( J ), 1, U( 1,I ), 1 )
1175                J = J + MNMIN
1176                CALL DCOPY( MNMIN, WORK( J ), 1, VT( I,1 ), LDPT )
1177                J = J + MNMIN
1178   170       CONTINUE
1179 *
1180 *           Use DBDSVDX to compute only the singular values of the
1181 *           bidiagonal matrix B;  U and VT should not be modified.
1182 *
1183             IF( JTYPE.EQ.9 ) THEN
1184 *              =================================
1185 *              Matrix types temporarily disabled
1186 *              =================================
1187                RESULT( 24 ) = ZERO
1188                GO TO 270
1189             END IF
1190 *
1191             CALL DCOPY( MNMIN, BD, 1, WORK( IWBD ), 1 )
1192             IF( MNMIN.GT.0 )
1193      $         CALL DCOPY( MNMIN-1, BE, 1, WORK( IWBE ), 1 ) 
1194 *     
1195             CALL DBDSVDX( UPLO, 'N', 'A', MNMIN, WORK( IWBD ),
1196      $                    WORK( IWBE ), ZERO, ZERO, 0, 0, NS2, S2,
1197      $                    WORK( IWBZ ), MNMIN2, WORK( IWWORK ), 
1198      $                    IWORK, IINFO )
1199 *
1200 *           Check error code from DBDSVDX.
1201 *
1202             IF( IINFO.NE.0 ) THEN
1203                WRITE( NOUT, FMT = 9998 )'DBDSVDX(values,A)', IINFO, 
1204      $            M, N, JTYPE, IOLDSD
1205                INFO = ABS( IINFO )
1206                IF( IINFO.LT.0 ) THEN
1207                   RETURN
1208                ELSE
1209                   RESULT( 24 ) = ULPINV
1210                   GO TO 270
1211                END IF
1212             END IF
1213 *
1214 *           Save S1 for tests 30-34.
1215 *
1216             CALL DCOPY( MNMIN, S1, 1, WORK( IWBS ), 1 )
1217 *
1218 *           Test 20:  Check the decomposition B := U * S1 * VT
1219 *                21:  Check the orthogonality of U
1220 *                22:  Check the orthogonality of VT
1221 *                23:  Check that the singular values are sorted in
1222 *                     non-increasing order and are non-negative
1223 *                24:  Compare DBDSVDX with and without singular vectors
1224 *
1225             CALL DBDT03( UPLO, MNMIN, 1, BD, BE, U, LDPT, S1, VT,
1226      $                   LDPT, WORK( IWBS+MNMIN ), RESULT( 20 ) )
1227             CALL DORT01( 'Columns', MNMIN, MNMIN, U, LDPT, 
1228      $                   WORK( IWBS+MNMIN ), LWORK-MNMIN, 
1229      $                   RESULT( 21 ) )
1230             CALL DORT01( 'Rows', MNMIN, MNMIN, VT, LDPT, 
1231      $                   WORK( IWBS+MNMIN ), LWORK-MNMIN, 
1232      $                   RESULT( 22) )
1233 *
1234             RESULT( 23 ) = ZERO
1235             DO 180 I = 1, MNMIN - 1
1236                IF( S1( I ).LT.S1( I+1 ) )
1237      $            RESULT( 23 ) = ULPINV
1238                IF( S1( I ).LT.ZERO )
1239      $            RESULT( 23 ) = ULPINV
1240   180       CONTINUE
1241             IF( MNMIN.GE.1 ) THEN
1242                IF( S1( MNMIN ).LT.ZERO )
1243      $            RESULT( 23 ) = ULPINV
1244             END IF
1245 *
1246             TEMP2 = ZERO
1247             DO 190 J = 1, MNMIN
1248                TEMP1 = ABS( S1( J )-S2( J ) ) /
1249      $                 MAX( SQRT( UNFL )*MAX( S1( 1 ), ONE ),
1250      $                 ULP*MAX( ABS( S1( 1 ) ), ABS( S2( 1 ) ) ) )
1251                TEMP2 = MAX( TEMP1, TEMP2 )
1252   190       CONTINUE
1253             RESULT( 24 ) = TEMP2
1254             ANORM = S1( 1 )
1255 *
1256 *           Use DBDSVDX with RANGE='I': choose random values for IL and
1257 *           IU, and ask for the IL-th through IU-th singular values
1258 *           and corresponding vectors.
1259 *
1260             DO 200 I = 1, 4
1261                ISEED2( I ) = ISEED( I )
1262   200       CONTINUE
1263             IF( MNMIN.LE.1 ) THEN
1264                IL = 1
1265                IU = MNMIN
1266             ELSE
1267                IL = 1 + INT( ( MNMIN-1 )*DLARND( 1, ISEED2 ) )
1268                IU = 1 + INT( ( MNMIN-1 )*DLARND( 1, ISEED2 ) )
1269                IF( IU.LT.IL ) THEN
1270                   ITEMP = IU
1271                   IU = IL
1272                   IL = ITEMP
1273                END IF
1274             END IF
1275 *       
1276             CALL DCOPY( MNMIN, BD, 1, WORK( IWBD ), 1 )
1277             IF( MNMIN.GT.0 )
1278      $         CALL DCOPY( MNMIN-1, BE, 1, WORK( IWBE ), 1 )
1279 *
1280             CALL DBDSVDX( UPLO, 'V', 'I', MNMIN, WORK( IWBD ),
1281      $                    WORK( IWBE ), ZERO, ZERO, IL, IU, NS1, S1, 
1282      $                    WORK( IWBZ ), MNMIN2, WORK( IWWORK ), 
1283      $                    IWORK, IINFO)
1284 *
1285 *           Check error code from DBDSVDX.
1286 *
1287             IF( IINFO.NE.0 ) THEN
1288                WRITE( NOUT, FMT = 9998 )'DBDSVDX(vects,I)', IINFO,
1289      $            M, N, JTYPE, IOLDSD
1290                INFO = ABS( IINFO )
1291                IF( IINFO.LT.0 ) THEN
1292                   RETURN
1293                ELSE
1294                   RESULT( 25 ) = ULPINV
1295                   GO TO 270
1296                END IF
1297             END IF
1298 *
1299             J = IWBZ
1300             DO 210 I = 1, NS1
1301                CALL DCOPY( MNMIN, WORK( J ), 1, U( 1,I ), 1 )
1302                J = J + MNMIN
1303                CALL DCOPY( MNMIN, WORK( J ), 1, VT( I,1 ), LDPT )
1304                J = J + MNMIN
1305   210       CONTINUE
1306 *
1307 *           Use DBDSVDX to compute only the singular values of the
1308 *           bidiagonal matrix B;  U and VT should not be modified.
1309 *
1310             CALL DCOPY( MNMIN, BD, 1, WORK( IWBD ), 1 )
1311             IF( MNMIN.GT.0 )
1312      $         CALL DCOPY( MNMIN-1, BE, 1, WORK( IWBE ), 1 )
1313 *
1314             CALL DBDSVDX( UPLO, 'N', 'I', MNMIN, WORK( IWBD ),
1315      $                    WORK( IWBE ), ZERO, ZERO, IL, IU, NS2, S2,
1316      $                    WORK( IWBZ ), MNMIN2, WORK( IWWORK ), 
1317      $                    IWORK, IINFO )
1318 *
1319 *           Check error code from DBDSVDX.
1320 *
1321             IF( IINFO.NE.0 ) THEN
1322                WRITE( NOUT, FMT = 9998 )'DBDSVDX(values,I)', IINFO,
1323      $            M, N, JTYPE, IOLDSD
1324                INFO = ABS( IINFO )
1325                IF( IINFO.LT.0 ) THEN
1326                   RETURN
1327                ELSE
1328                   RESULT( 29 ) = ULPINV
1329                   GO TO 270
1330                END IF
1331             END IF
1332 *
1333 *           Test 25:  Check S1 - U' * B * VT'
1334 *                26:  Check the orthogonality of U
1335 *                27:  Check the orthogonality of VT
1336 *                28:  Check that the singular values are sorted in
1337 *                     non-increasing order and are non-negative
1338 *                29:  Compare DBDSVDX with and without singular vectors
1339 *
1340             CALL DBDT04( UPLO, MNMIN, BD, BE, S1, NS1, U, 
1341      $                   LDPT, VT, LDPT, WORK( IWBS+MNMIN ), 
1342      $                   RESULT( 25 ) )
1343             CALL DORT01( 'Columns', MNMIN, NS1, U, LDPT, 
1344      $                   WORK( IWBS+MNMIN ), LWORK-MNMIN, 
1345      $                   RESULT( 26 ) )
1346             CALL DORT01( 'Rows', NS1, MNMIN, VT, LDPT, 
1347      $                   WORK( IWBS+MNMIN ), LWORK-MNMIN,
1348      $                   RESULT( 27 ) )
1349 *
1350             RESULT( 28 ) = ZERO
1351             DO 220 I = 1, NS1 - 1
1352                IF( S1( I ).LT.S1( I+1 ) )
1353      $            RESULT( 28 ) = ULPINV
1354                IF( S1( I ).LT.ZERO )
1355      $            RESULT( 28 ) = ULPINV
1356   220       CONTINUE
1357             IF( NS1.GE.1 ) THEN
1358                IF( S1( NS1 ).LT.ZERO )
1359      $            RESULT( 28 ) = ULPINV
1360             END IF
1361 *
1362             TEMP2 = ZERO
1363             DO 230 J = 1, NS1
1364                TEMP1 = ABS( S1( J )-S2( J ) ) /
1365      $                 MAX( SQRT( UNFL )*MAX( S1( 1 ), ONE ),
1366      $                 ULP*MAX( ABS( S1( 1 ) ), ABS( S2( 1 ) ) ) )
1367                TEMP2 = MAX( TEMP1, TEMP2 )
1368   230       CONTINUE
1369             RESULT( 29 ) = TEMP2
1370 *
1371 *           Use DBDSVDX with RANGE='V': determine the values VL and VU 
1372 *           of the IL-th and IU-th singular values and ask for all 
1373 *           singular values in this range.
1374 *
1375             CALL DCOPY( MNMIN, WORK( IWBS ), 1, S1, 1 )
1376 *
1377             IF( MNMIN.GT.0 ) THEN
1378                IF( IL.NE.1 ) THEN
1379                   VU = S1( IL ) + MAX( HALF*ABS( S1( IL )-S1( IL-1 ) ),
1380      $                 ULP*ANORM, TWO*RTUNFL )
1381                ELSE
1382                   VU = S1( 1 ) + MAX( HALF*ABS( S1( MNMIN )-S1( 1 ) ),
1383      $                 ULP*ANORM, TWO*RTUNFL )
1384                END IF
1385                IF( IU.NE.NS1 ) THEN
1386                   VL = S1( IU ) - MAX( ULP*ANORM, TWO*RTUNFL,
1387      $                 HALF*ABS( S1( IU+1 )-S1( IU ) ) )
1388                ELSE
1389                   VL = S1( NS1 ) - MAX( ULP*ANORM, TWO*RTUNFL,
1390      $                 HALF*ABS( S1( MNMIN )-S1( 1 ) ) )
1391                END IF
1392                VL = MAX( VL,ZERO )
1393                VU = MAX( VU,ZERO )
1394                IF( VL.GE.VU ) VU = MAX( VU*2, VU+VL+HALF )
1395             ELSE
1396                VL = ZERO
1397                VU = ONE
1398             END IF 
1399
1400             CALL DCOPY( MNMIN, BD, 1, WORK( IWBD ), 1 )
1401             IF( MNMIN.GT.0 )
1402      $         CALL DCOPY( MNMIN-1, BE, 1, WORK( IWBE ), 1 )
1403 *
1404             CALL DBDSVDX( UPLO, 'V', 'V', MNMIN, WORK( IWBD ),
1405      $                    WORK( IWBE ), VL, VU, 0, 0, NS1, S1, 
1406      $                    WORK( IWBZ ), MNMIN2, WORK( IWWORK ), 
1407      $                    IWORK, IINFO )
1408 *
1409 *           Check error code from DBDSVDX.
1410 *
1411             IF( IINFO.NE.0 ) THEN
1412                WRITE( NOUT, FMT = 9998 )'DBDSVDX(vects,V)', IINFO, 
1413      $            M, N, JTYPE, IOLDSD
1414                INFO = ABS( IINFO )
1415                IF( IINFO.LT.0 ) THEN
1416                   RETURN
1417                ELSE
1418                   RESULT( 30 ) = ULPINV
1419                   GO TO 270
1420                END IF
1421             END IF
1422 *
1423             J = IWBZ
1424             DO 240 I = 1, NS1
1425                CALL DCOPY( MNMIN, WORK( J ), 1, U( 1,I ), 1 )
1426                J = J + MNMIN
1427                CALL DCOPY( MNMIN, WORK( J ), 1, VT( I,1 ), LDPT )
1428                J = J + MNMIN
1429   240       CONTINUE
1430 *
1431 *           Use DBDSVDX to compute only the singular values of the
1432 *           bidiagonal matrix B;  U and VT should not be modified.
1433 *
1434             CALL DCOPY( MNMIN, BD, 1, WORK( IWBD ), 1 )
1435             IF( MNMIN.GT.0 )
1436      $         CALL DCOPY( MNMIN-1, BE, 1, WORK( IWBE ), 1 )
1437 *
1438             CALL DBDSVDX( UPLO, 'N', 'V', MNMIN, WORK( IWBD ),
1439      $                    WORK( IWBE ), VL, VU, 0, 0, NS2, S2,
1440      $                    WORK( IWBZ ), MNMIN2, WORK( IWWORK ), 
1441      $                    IWORK, IINFO )
1442 *
1443 *           Check error code from DBDSVDX.
1444 *
1445             IF( IINFO.NE.0 ) THEN
1446                WRITE( NOUT, FMT = 9998 )'DBDSVDX(values,V)', IINFO,
1447      $            M, N, JTYPE, IOLDSD
1448                INFO = ABS( IINFO )
1449                IF( IINFO.LT.0 ) THEN
1450                   RETURN
1451                ELSE
1452                   RESULT( 34 ) = ULPINV
1453                   GO TO 270
1454                END IF
1455             END IF
1456 *
1457 *           Test 30:  Check S1 - U' * B * VT'
1458 *                31:  Check the orthogonality of U
1459 *                32:  Check the orthogonality of VT
1460 *                33:  Check that the singular values are sorted in
1461 *                     non-increasing order and are non-negative
1462 *                34:  Compare DBDSVDX with and without singular vectors
1463 *
1464             CALL DBDT04( UPLO, MNMIN, BD, BE, S1, NS1, U, 
1465      $                   LDPT, VT, LDPT, WORK( IWBS+MNMIN ), 
1466      $                   RESULT( 30 ) )
1467             CALL DORT01( 'Columns', MNMIN, NS1, U, LDPT, 
1468      $                   WORK( IWBS+MNMIN ), LWORK-MNMIN,
1469      $                   RESULT( 31 ) )
1470             CALL DORT01( 'Rows', NS1, MNMIN, VT, LDPT, 
1471      $                   WORK( IWBS+MNMIN ), LWORK-MNMIN,
1472      $                   RESULT( 32 ) )
1473 *
1474             RESULT( 33 ) = ZERO
1475             DO 250 I = 1, NS1 - 1
1476                IF( S1( I ).LT.S1( I+1 ) )
1477      $            RESULT( 28 ) = ULPINV
1478                IF( S1( I ).LT.ZERO )
1479      $            RESULT( 28 ) = ULPINV
1480   250       CONTINUE
1481             IF( NS1.GE.1 ) THEN
1482                IF( S1( NS1 ).LT.ZERO )
1483      $            RESULT( 28 ) = ULPINV
1484             END IF
1485 *
1486             TEMP2 = ZERO
1487             DO 260 J = 1, NS1
1488                TEMP1 = ABS( S1( J )-S2( J ) ) /
1489      $                 MAX( SQRT( UNFL )*MAX( S1( 1 ), ONE ),
1490      $                 ULP*MAX( ABS( S1( 1 ) ), ABS( S2( 1 ) ) ) )
1491                TEMP2 = MAX( TEMP1, TEMP2 )
1492   260       CONTINUE
1493             RESULT( 34 ) = TEMP2
1494 *
1495 *           End of Loop -- Check for RESULT(j) > THRESH
1496 *
1497   270       CONTINUE
1498 *
1499             DO 280 J = 1, 34
1500                IF( RESULT( J ).GE.THRESH ) THEN
1501                   IF( NFAIL.EQ.0 )
1502      $               CALL DLAHD2( NOUT, PATH )
1503                   WRITE( NOUT, FMT = 9999 )M, N, JTYPE, IOLDSD, J,
1504      $               RESULT( J )
1505                   NFAIL = NFAIL + 1
1506                END IF
1507   280       CONTINUE
1508             IF( .NOT.BIDIAG ) THEN
1509                NTEST = NTEST + 34
1510             ELSE
1511                NTEST = NTEST + 30
1512             END IF
1513 *
1514   290    CONTINUE
1515   300 CONTINUE
1516 *
1517 *     Summary
1518 *
1519       CALL ALASUM( PATH, NOUT, NFAIL, NTEST, 0 )
1520 *
1521       RETURN
1522 *
1523 *     End of DCHKBD
1524 *
1525  9999 FORMAT( ' M=', I5, ', N=', I5, ', type ', I2, ', seed=',
1526      $      4( I4, ',' ), ' test(', I2, ')=', G11.4 )
1527  9998 FORMAT( ' DCHKBD: ', A, ' returned INFO=', I6, '.', / 9X, 'M=',
1528      $      I6, ', N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ),
1529      $      I5, ')' )
1530 *
1531       END