1 *> \brief \b DCHKST2STG
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
11 * SUBROUTINE DCHKST2STG( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH,
12 * NOUNIT, A, LDA, AP, SD, SE, D1, D2, D3, D4, D5,
13 * WA1, WA2, WA3, WR, U, LDU, V, VP, TAU, Z, WORK,
14 * LWORK, IWORK, LIWORK, RESULT, INFO )
16 * .. Scalar Arguments ..
17 * INTEGER INFO, LDA, LDU, LIWORK, LWORK, NOUNIT, NSIZES,
19 * DOUBLE PRECISION THRESH
21 * .. Array Arguments ..
23 * INTEGER ISEED( 4 ), IWORK( * ), NN( * )
24 * DOUBLE PRECISION A( LDA, * ), AP( * ), D1( * ), D2( * ),
25 * $ D3( * ), D4( * ), D5( * ), RESULT( * ),
26 * $ SD( * ), SE( * ), TAU( * ), U( LDU, * ),
27 * $ V( LDU, * ), VP( * ), WA1( * ), WA2( * ),
28 * $ WA3( * ), WORK( * ), WR( * ), Z( LDU, * )
37 *> DCHKST2STG checks the symmetric eigenvalue problem routines
38 *> using the 2-stage reduction techniques. Since the generation
39 *> of Q or the vectors is not available in this release, we only
40 *> compare the eigenvalue resulting when using the 2-stage to the
41 *> one considered as reference using the standard 1-stage reduction
42 *> DSYTRD. For that, we call the standard DSYTRD and compute D1 using
43 *> DSTEQR, then we call the 2-stage DSYTRD_2STAGE with Upper and Lower
44 *> and we compute D2 and D3 using DSTEQR and then we replaced tests
45 *> 3 and 4 by tests 11 and 12. test 1 and 2 remain to verify that
46 *> the 1-stage results are OK and can be trusted.
47 *> This testing routine will converge to the DCHKST in the next
48 *> release when vectors and generation of Q will be implemented.
50 *> DSYTRD factors A as U S U' , where ' means transpose,
51 *> S is symmetric tridiagonal, and U is orthogonal.
52 *> DSYTRD can use either just the lower or just the upper triangle
53 *> of A; DCHKST2STG checks both cases.
54 *> U is represented as a product of Householder
55 *> transformations, whose vectors are stored in the first
56 *> n-1 columns of V, and whose scale factors are in TAU.
58 *> DSPTRD does the same as DSYTRD, except that A and V are stored
59 *> in "packed" format.
61 *> DORGTR constructs the matrix U from the contents of V and TAU.
63 *> DOPGTR constructs the matrix U from the contents of VP and TAU.
65 *> DSTEQR factors S as Z D1 Z' , where Z is the orthogonal
66 *> matrix of eigenvectors and D1 is a diagonal matrix with
67 *> the eigenvalues on the diagonal. D2 is the matrix of
68 *> eigenvalues computed when Z is not computed.
70 *> DSTERF computes D3, the matrix of eigenvalues, by the
71 *> PWK method, which does not yield eigenvectors.
73 *> DPTEQR factors S as Z4 D4 Z4' , for a
74 *> symmetric positive definite tridiagonal matrix.
75 *> D5 is the matrix of eigenvalues computed when Z is not
78 *> DSTEBZ computes selected eigenvalues. WA1, WA2, and
79 *> WA3 will denote eigenvalues computed to high
80 *> absolute accuracy, with different range options.
81 *> WR will denote eigenvalues computed to high relative
84 *> DSTEIN computes Y, the eigenvectors of S, given the
87 *> DSTEDC factors S as Z D1 Z' , where Z is the orthogonal
88 *> matrix of eigenvectors and D1 is a diagonal matrix with
89 *> the eigenvalues on the diagonal ('I' option). It may also
90 *> update an input orthogonal matrix, usually the output
91 *> from DSYTRD/DORGTR or DSPTRD/DOPGTR ('V' option). It may
92 *> also just compute eigenvalues ('N' option).
94 *> DSTEMR factors S as Z D1 Z' , where Z is the orthogonal
95 *> matrix of eigenvectors and D1 is a diagonal matrix with
96 *> the eigenvalues on the diagonal ('I' option). DSTEMR
97 *> uses the Relatively Robust Representation whenever possible.
99 *> When DCHKST2STG is called, a number of matrix "sizes" ("n's") and a
100 *> number of matrix "types" are specified. For each size ("n")
101 *> and each type of matrix, one matrix will be generated and used
102 *> to test the symmetric eigenroutines. For each matrix, a number
103 *> of tests will be performed:
105 *> (1) | A - V S V' | / ( |A| n ulp ) DSYTRD( UPLO='U', ... )
107 *> (2) | I - UV' | / ( n ulp ) DORGTR( UPLO='U', ... )
109 *> (3) | A - V S V' | / ( |A| n ulp ) DSYTRD( UPLO='L', ... )
110 *> replaced by | D1 - D2 | / ( |D1| ulp ) where D1 is the
111 *> eigenvalue matrix computed using S and D2 is the
112 *> eigenvalue matrix computed using S_2stage the output of
113 *> DSYTRD_2STAGE("N", "U",....). D1 and D2 are computed
114 *> via DSTEQR('N',...)
116 *> (4) | I - UV' | / ( n ulp ) DORGTR( UPLO='L', ... )
117 *> replaced by | D1 - D3 | / ( |D1| ulp ) where D1 is the
118 *> eigenvalue matrix computed using S and D3 is the
119 *> eigenvalue matrix computed using S_2stage the output of
120 *> DSYTRD_2STAGE("N", "L",....). D1 and D3 are computed
121 *> via DSTEQR('N',...)
123 *> (5-8) Same as 1-4, but for DSPTRD and DOPGTR.
125 *> (9) | S - Z D Z' | / ( |S| n ulp ) DSTEQR('V',...)
127 *> (10) | I - ZZ' | / ( n ulp ) DSTEQR('V',...)
129 *> (11) | D1 - D2 | / ( |D1| ulp ) DSTEQR('N',...)
131 *> (12) | D1 - D3 | / ( |D1| ulp ) DSTERF
133 *> (13) 0 if the true eigenvalues (computed by sturm count)
134 *> of S are within THRESH of
135 *> those in D1. 2*THRESH if they are not. (Tested using
138 *> For S positive definite,
140 *> (14) | S - Z4 D4 Z4' | / ( |S| n ulp ) DPTEQR('V',...)
142 *> (15) | I - Z4 Z4' | / ( n ulp ) DPTEQR('V',...)
144 *> (16) | D4 - D5 | / ( 100 |D4| ulp ) DPTEQR('N',...)
146 *> When S is also diagonally dominant by the factor gamma < 1,
148 *> (17) max | D4(i) - WR(i) | / ( |D4(i)| omega ) ,
150 *> omega = 2 (2n-1) ULP (1 + 8 gamma**2) / (1 - gamma)**4
151 *> DSTEBZ( 'A', 'E', ...)
153 *> (18) | WA1 - D3 | / ( |D3| ulp ) DSTEBZ( 'A', 'E', ...)
155 *> (19) ( max { min | WA2(i)-WA3(j) | } +
157 *> max { min | WA3(i)-WA2(j) | } ) / ( |D3| ulp )
159 *> DSTEBZ( 'I', 'E', ...)
161 *> (20) | S - Y WA1 Y' | / ( |S| n ulp ) DSTEBZ, SSTEIN
163 *> (21) | I - Y Y' | / ( n ulp ) DSTEBZ, SSTEIN
165 *> (22) | S - Z D Z' | / ( |S| n ulp ) DSTEDC('I')
167 *> (23) | I - ZZ' | / ( n ulp ) DSTEDC('I')
169 *> (24) | S - Z D Z' | / ( |S| n ulp ) DSTEDC('V')
171 *> (25) | I - ZZ' | / ( n ulp ) DSTEDC('V')
173 *> (26) | D1 - D2 | / ( |D1| ulp ) DSTEDC('V') and
176 *> Test 27 is disabled at the moment because DSTEMR does not
177 *> guarantee high relatvie accuracy.
179 *> (27) max | D6(i) - WR(i) | / ( |D6(i)| omega ) ,
181 *> omega = 2 (2n-1) ULP (1 + 8 gamma**2) / (1 - gamma)**4
184 *> (28) max | D6(i) - WR(i) | / ( |D6(i)| omega ) ,
186 *> omega = 2 (2n-1) ULP (1 + 8 gamma**2) / (1 - gamma)**4
189 *> Tests 29 through 34 are disable at present because DSTEMR
190 *> does not handle partial spectrum requests.
192 *> (29) | S - Z D Z' | / ( |S| n ulp ) DSTEMR('V', 'I')
194 *> (30) | I - ZZ' | / ( n ulp ) DSTEMR('V', 'I')
196 *> (31) ( max { min | WA2(i)-WA3(j) | } +
198 *> max { min | WA3(i)-WA2(j) | } ) / ( |D3| ulp )
200 *> DSTEMR('N', 'I') vs. SSTEMR('V', 'I')
202 *> (32) | S - Z D Z' | / ( |S| n ulp ) DSTEMR('V', 'V')
204 *> (33) | I - ZZ' | / ( n ulp ) DSTEMR('V', 'V')
206 *> (34) ( max { min | WA2(i)-WA3(j) | } +
208 *> max { min | WA3(i)-WA2(j) | } ) / ( |D3| ulp )
210 *> DSTEMR('N', 'V') vs. SSTEMR('V', 'V')
212 *> (35) | S - Z D Z' | / ( |S| n ulp ) DSTEMR('V', 'A')
214 *> (36) | I - ZZ' | / ( n ulp ) DSTEMR('V', 'A')
216 *> (37) ( max { min | WA2(i)-WA3(j) | } +
218 *> max { min | WA3(i)-WA2(j) | } ) / ( |D3| ulp )
220 *> DSTEMR('N', 'A') vs. SSTEMR('V', 'A')
222 *> The "sizes" are specified by an array NN(1:NSIZES); the value of
223 *> each element NN(j) specifies one size.
224 *> The "types" are specified by a logical array DOTYPE( 1:NTYPES );
225 *> if DOTYPE(j) is .TRUE., then matrix type "j" will be generated.
226 *> Currently, the list of possible types is:
228 *> (1) The zero matrix.
229 *> (2) The identity matrix.
231 *> (3) A diagonal matrix with evenly spaced entries
232 *> 1, ..., ULP and random signs.
233 *> (ULP = (first number larger than 1) - 1 )
234 *> (4) A diagonal matrix with geometrically spaced entries
235 *> 1, ..., ULP and random signs.
236 *> (5) A diagonal matrix with "clustered" entries 1, ULP, ..., ULP
239 *> (6) Same as (4), but multiplied by SQRT( overflow threshold )
240 *> (7) Same as (4), but multiplied by SQRT( underflow threshold )
242 *> (8) A matrix of the form U' D U, where U is orthogonal and
243 *> D has evenly spaced entries 1, ..., ULP with random signs
246 *> (9) A matrix of the form U' D U, where U is orthogonal and
247 *> D has geometrically spaced entries 1, ..., ULP with random
248 *> signs on the diagonal.
250 *> (10) A matrix of the form U' D U, where U is orthogonal and
251 *> D has "clustered" entries 1, ULP,..., ULP with random
252 *> signs on the diagonal.
254 *> (11) Same as (8), but multiplied by SQRT( overflow threshold )
255 *> (12) Same as (8), but multiplied by SQRT( underflow threshold )
257 *> (13) Symmetric matrix with random entries chosen from (-1,1).
258 *> (14) Same as (13), but multiplied by SQRT( overflow threshold )
259 *> (15) Same as (13), but multiplied by SQRT( underflow threshold )
260 *> (16) Same as (8), but diagonal elements are all positive.
261 *> (17) Same as (9), but diagonal elements are all positive.
262 *> (18) Same as (10), but diagonal elements are all positive.
263 *> (19) Same as (16), but multiplied by SQRT( overflow threshold )
264 *> (20) Same as (16), but multiplied by SQRT( underflow threshold )
265 *> (21) A diagonally dominant tridiagonal matrix with geometrically
266 *> spaced diagonal entries 1, ..., ULP.
275 *> The number of sizes of matrices to use. If it is zero,
276 *> DCHKST2STG does nothing. It must be at least zero.
281 *> NN is INTEGER array, dimension (NSIZES)
282 *> An array containing the sizes to be used for the matrices.
283 *> Zero values will be skipped. The values must be at least
290 *> The number of elements in DOTYPE. If it is zero, DCHKST2STG
291 *> does nothing. It must be at least zero. If it is MAXTYP+1
292 *> and NSIZES is 1, then an additional type, MAXTYP+1 is
293 *> defined, which is to use whatever matrix is in A. This
294 *> is only useful if DOTYPE(1:MAXTYP) is .FALSE. and
295 *> DOTYPE(MAXTYP+1) is .TRUE. .
300 *> DOTYPE is LOGICAL array, dimension (NTYPES)
301 *> If DOTYPE(j) is .TRUE., then for each size in NN a
302 *> matrix of that size and of type j will be generated.
303 *> If NTYPES is smaller than the maximum number of types
304 *> defined (PARAMETER MAXTYP), then types NTYPES+1 through
305 *> MAXTYP will not be generated. If NTYPES is larger
306 *> than MAXTYP, DOTYPE(MAXTYP+1) through DOTYPE(NTYPES)
310 *> \param[in,out] ISEED
312 *> ISEED is INTEGER array, dimension (4)
313 *> On entry ISEED specifies the seed of the random number
314 *> generator. The array elements should be between 0 and 4095;
315 *> if not they will be reduced mod 4096. Also, ISEED(4) must
316 *> be odd. The random number generator uses a linear
317 *> congruential sequence limited to small integers, and so
318 *> should produce machine independent random numbers. The
319 *> values of ISEED are changed on exit, and can be used in the
320 *> next call to DCHKST2STG to continue the same random number
326 *> THRESH is DOUBLE PRECISION
327 *> A test will count as "failed" if the "error", computed as
328 *> described above, exceeds THRESH. Note that the error
329 *> is scaled to be O(1), so THRESH should be a reasonably
330 *> small multiple of 1, e.g., 10 or 100. In particular,
331 *> it should not depend on the precision (single vs. double)
332 *> or the size of the matrix. It must be at least zero.
338 *> The FORTRAN unit number for printing out error messages
339 *> (e.g., if a routine returns IINFO not equal to 0.)
344 *> A is DOUBLE PRECISION array of
345 *> dimension ( LDA , max(NN) )
346 *> Used to hold the matrix whose eigenvalues are to be
347 *> computed. On exit, A contains the last matrix actually
354 *> The leading dimension of A. It must be at
355 *> least 1 and at least max( NN ).
360 *> AP is DOUBLE PRECISION array of
361 *> dimension( max(NN)*max(NN+1)/2 )
362 *> The matrix A stored in packed format.
367 *> SD is DOUBLE PRECISION array of
368 *> dimension( max(NN) )
369 *> The diagonal of the tridiagonal matrix computed by DSYTRD.
370 *> On exit, SD and SE contain the tridiagonal form of the
376 *> SE is DOUBLE PRECISION array of
377 *> dimension( max(NN) )
378 *> The off-diagonal of the tridiagonal matrix computed by
379 *> DSYTRD. On exit, SD and SE contain the tridiagonal form of
385 *> D1 is DOUBLE PRECISION array of
386 *> dimension( max(NN) )
387 *> The eigenvalues of A, as computed by DSTEQR simlutaneously
388 *> with Z. On exit, the eigenvalues in D1 correspond with the
394 *> D2 is DOUBLE PRECISION array of
395 *> dimension( max(NN) )
396 *> The eigenvalues of A, as computed by DSTEQR if Z is not
397 *> computed. On exit, the eigenvalues in D2 correspond with
403 *> D3 is DOUBLE PRECISION array of
404 *> dimension( max(NN) )
405 *> The eigenvalues of A, as computed by DSTERF. On exit, the
406 *> eigenvalues in D3 correspond with the matrix in A.
411 *> D4 is DOUBLE PRECISION array of
412 *> dimension( max(NN) )
413 *> The eigenvalues of A, as computed by DPTEQR(V).
414 *> DPTEQR factors S as Z4 D4 Z4*
415 *> On exit, the eigenvalues in D4 correspond with the matrix in A.
420 *> D5 is DOUBLE PRECISION array of
421 *> dimension( max(NN) )
422 *> The eigenvalues of A, as computed by DPTEQR(N)
423 *> when Z is not computed. On exit, the
424 *> eigenvalues in D4 correspond with the matrix in A.
429 *> WA1 is DOUBLE PRECISION array of
430 *> dimension( max(NN) )
431 *> All eigenvalues of A, computed to high
432 *> absolute accuracy, with different range options.
433 *> as computed by DSTEBZ.
438 *> WA2 is DOUBLE PRECISION array of
439 *> dimension( max(NN) )
440 *> Selected eigenvalues of A, computed to high
441 *> absolute accuracy, with different range options.
442 *> as computed by DSTEBZ.
443 *> Choose random values for IL and IU, and ask for the
444 *> IL-th through IU-th eigenvalues.
449 *> WA3 is DOUBLE PRECISION array of
450 *> dimension( max(NN) )
451 *> Selected eigenvalues of A, computed to high
452 *> absolute accuracy, with different range options.
453 *> as computed by DSTEBZ.
454 *> Determine the values VL and VU of the IL-th and IU-th
455 *> eigenvalues and ask for all eigenvalues in this range.
460 *> WR is DOUBLE PRECISION array of
461 *> dimension( max(NN) )
462 *> All eigenvalues of A, computed to high
463 *> absolute accuracy, with different options.
464 *> as computed by DSTEBZ.
469 *> U is DOUBLE PRECISION array of
470 *> dimension( LDU, max(NN) ).
471 *> The orthogonal matrix computed by DSYTRD + DORGTR.
477 *> The leading dimension of U, Z, and V. It must be at least 1
478 *> and at least max( NN ).
483 *> V is DOUBLE PRECISION array of
484 *> dimension( LDU, max(NN) ).
485 *> The Housholder vectors computed by DSYTRD in reducing A to
486 *> tridiagonal form. The vectors computed with UPLO='U' are
487 *> in the upper triangle, and the vectors computed with UPLO='L'
488 *> are in the lower triangle. (As described in DSYTRD, the
489 *> sub- and superdiagonal are not set to 1, although the
490 *> true Householder vector has a 1 in that position. The
491 *> routines that use V, such as DORGTR, set those entries to
492 *> 1 before using them, and then restore them later.)
497 *> VP is DOUBLE PRECISION array of
498 *> dimension( max(NN)*max(NN+1)/2 )
499 *> The matrix V stored in packed format.
504 *> TAU is DOUBLE PRECISION array of
505 *> dimension( max(NN) )
506 *> The Householder factors computed by DSYTRD in reducing A
507 *> to tridiagonal form.
512 *> Z is DOUBLE PRECISION array of
513 *> dimension( LDU, max(NN) ).
514 *> The orthogonal matrix of eigenvectors computed by DSTEQR,
515 *> DPTEQR, and DSTEIN.
520 *> WORK is DOUBLE PRECISION array of
521 *> dimension( LWORK )
527 *> The number of entries in WORK. This must be at least
528 *> 1 + 4 * Nmax + 2 * Nmax * lg Nmax + 3 * Nmax**2
529 *> where Nmax = max( NN(j), 2 ) and lg = log base 2.
534 *> IWORK is INTEGER array,
538 *> \param[out] LIWORK
541 *> The number of entries in IWORK. This must be at least
542 *> 6 + 6*Nmax + 5 * Nmax * lg Nmax
543 *> where Nmax = max( NN(j), 2 ) and lg = log base 2.
546 *> \param[out] RESULT
548 *> RESULT is DOUBLE PRECISION array, dimension (26)
549 *> The values computed by the tests described above.
550 *> The values are currently limited to 1/ulp, to avoid
557 *> If 0, then everything ran OK.
559 *> -2: Some NN(j) < 0
562 *> -9: LDA < 1 or LDA < NMAX, where NMAX is max( NN(j) ).
563 *> -23: LDU < 1 or LDU < NMAX.
564 *> -29: LWORK too small.
565 *> If DLATMR, SLATMS, DSYTRD, DORGTR, DSTEQR, SSTERF,
566 *> or DORMC2 returns an error code, the
567 *> absolute value of it is returned.
569 *>-----------------------------------------------------------------------
571 *> Some Local Variables and Parameters:
572 *> ---- ----- --------- --- ----------
573 *> ZERO, ONE Real 0 and 1.
574 *> MAXTYP The number of types defined.
575 *> NTEST The number of tests performed, or which can
576 *> be performed so far, for the current matrix.
577 *> NTESTT The total number of tests performed so far.
578 *> NBLOCK Blocksize as returned by ENVIR.
579 *> NMAX Largest value in NN.
580 *> NMATS The number of matrices generated so far.
581 *> NERRS The number of tests which have exceeded THRESH
583 *> COND, IMODE Values to be passed to the matrix generators.
584 *> ANORM Norm of A; passed to matrix generators.
586 *> OVFL, UNFL Overflow and underflow thresholds.
587 *> ULP, ULPINV Finest relative precision and its inverse.
588 *> RTOVFL, RTUNFL Square roots of the previous 2 values.
589 *> The following four arrays decode JTYPE:
590 *> KTYPE(j) The general type (1-10) for type "j".
591 *> KMODE(j) The MODE value to be passed to the matrix
592 *> generator for type "j".
593 *> KMAGN(j) The order of magnitude ( O(1),
594 *> O(overflow^(1/2) ), O(underflow^(1/2) )
600 *> \author Univ. of Tennessee
601 *> \author Univ. of California Berkeley
602 *> \author Univ. of Colorado Denver
605 *> \date December 2016
607 *> \ingroup double_eig
609 * =====================================================================
610 SUBROUTINE DCHKST2STG( NSIZES, NN, NTYPES, DOTYPE, ISEED, THRESH,
611 $ NOUNIT, A, LDA, AP, SD, SE, D1, D2, D3, D4, D5,
612 $ WA1, WA2, WA3, WR, U, LDU, V, VP, TAU, Z, WORK,
613 $ LWORK, IWORK, LIWORK, RESULT, INFO )
615 * -- LAPACK test routine (version 3.7.0) --
616 * -- LAPACK is a software package provided by Univ. of Tennessee, --
617 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
620 * .. Scalar Arguments ..
621 INTEGER INFO, LDA, LDU, LIWORK, LWORK, NOUNIT, NSIZES,
623 DOUBLE PRECISION THRESH
625 * .. Array Arguments ..
627 INTEGER ISEED( 4 ), IWORK( * ), NN( * )
628 DOUBLE PRECISION A( LDA, * ), AP( * ), D1( * ), D2( * ),
629 $ D3( * ), D4( * ), D5( * ), RESULT( * ),
630 $ SD( * ), SE( * ), TAU( * ), U( LDU, * ),
631 $ V( LDU, * ), VP( * ), WA1( * ), WA2( * ),
632 $ WA3( * ), WORK( * ), WR( * ), Z( LDU, * )
635 * =====================================================================
638 DOUBLE PRECISION ZERO, ONE, TWO, EIGHT, TEN, HUN
639 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
640 $ EIGHT = 8.0D0, TEN = 10.0D0, HUN = 100.0D0 )
641 DOUBLE PRECISION HALF
642 PARAMETER ( HALF = ONE / TWO )
644 PARAMETER ( MAXTYP = 21 )
646 PARAMETER ( SRANGE = .FALSE. )
648 PARAMETER ( SREL = .FALSE. )
650 * .. Local Scalars ..
651 LOGICAL BADNN, TRYRAC
652 INTEGER I, IINFO, IL, IMODE, ITEMP, ITYPE, IU, J, JC,
653 $ JR, JSIZE, JTYPE, LGN, LIWEDC, LOG2UI, LWEDC,
654 $ M, M2, M3, MTYPES, N, NAP, NBLOCK, NERRS,
655 $ NMATS, NMAX, NSPLIT, NTEST, NTESTT, LH, LW
656 DOUBLE PRECISION ABSTOL, ANINV, ANORM, COND, OVFL, RTOVFL,
657 $ RTUNFL, TEMP1, TEMP2, TEMP3, TEMP4, ULP,
658 $ ULPINV, UNFL, VL, VU
661 INTEGER IDUMMA( 1 ), IOLDSD( 4 ), ISEED2( 4 ),
662 $ KMAGN( MAXTYP ), KMODE( MAXTYP ),
664 DOUBLE PRECISION DUMMA( 1 )
666 * .. External Functions ..
668 DOUBLE PRECISION DLAMCH, DLARND, DSXT1
669 EXTERNAL ILAENV, DLAMCH, DLARND, DSXT1
671 * .. External Subroutines ..
672 EXTERNAL DCOPY, DLABAD, DLACPY, DLASET, DLASUM, DLATMR,
673 $ DLATMS, DOPGTR, DORGTR, DPTEQR, DSPT21, DSPTRD,
674 $ DSTEBZ, DSTECH, DSTEDC, DSTEMR, DSTEIN, DSTEQR,
675 $ DSTERF, DSTT21, DSTT22, DSYT21, DSYTRD, XERBLA,
678 * .. Intrinsic Functions ..
679 INTRINSIC ABS, DBLE, INT, LOG, MAX, MIN, SQRT
681 * .. Data statements ..
682 DATA KTYPE / 1, 2, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 8,
683 $ 8, 8, 9, 9, 9, 9, 9, 10 /
684 DATA KMAGN / 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 1,
685 $ 2, 3, 1, 1, 1, 2, 3, 1 /
686 DATA KMODE / 0, 0, 4, 3, 1, 4, 4, 4, 3, 1, 4, 4, 0,
687 $ 0, 0, 4, 3, 1, 4, 4, 3 /
689 * .. Executable Statements ..
699 * Important constants
705 NMAX = MAX( NMAX, NN( J ) )
710 NBLOCK = ILAENV( 1, 'DSYTRD', 'L', NMAX, -1, -1, -1 )
711 NBLOCK = MIN( NMAX, MAX( 1, NBLOCK ) )
715 IF( NSIZES.LT.0 ) THEN
717 ELSE IF( BADNN ) THEN
719 ELSE IF( NTYPES.LT.0 ) THEN
721 ELSE IF( LDA.LT.NMAX ) THEN
723 ELSE IF( LDU.LT.NMAX ) THEN
725 ELSE IF( 2*MAX( 2, NMAX )**2.GT.LWORK ) THEN
730 CALL XERBLA( 'DCHKST2STG', -INFO )
734 * Quick return if possible
736 IF( NSIZES.EQ.0 .OR. NTYPES.EQ.0 )
739 * More Important constants
741 UNFL = DLAMCH( 'Safe minimum' )
743 CALL DLABAD( UNFL, OVFL )
744 ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
746 LOG2UI = INT( LOG( ULPINV ) / LOG( TWO ) )
747 RTUNFL = SQRT( UNFL )
748 RTOVFL = SQRT( OVFL )
750 * Loop over sizes, types
753 ISEED2( I ) = ISEED( I )
758 DO 310 JSIZE = 1, NSIZES
761 LGN = INT( LOG( DBLE( N ) ) / LOG( TWO ) )
766 LWEDC = 1 + 4*N + 2*N*LGN + 4*N**2
767 LIWEDC = 6 + 6*N + 5*N*LGN
772 NAP = ( N*( N+1 ) ) / 2
773 ANINV = ONE / DBLE( MAX( 1, N ) )
775 IF( NSIZES.NE.1 ) THEN
776 MTYPES = MIN( MAXTYP, NTYPES )
778 MTYPES = MIN( MAXTYP+1, NTYPES )
781 DO 300 JTYPE = 1, MTYPES
782 IF( .NOT.DOTYPE( JTYPE ) )
788 IOLDSD( J ) = ISEED( J )
793 * Control parameters:
796 * =1 O(1) clustered 1 zero
797 * =2 large clustered 2 identity
798 * =3 small exponential (none)
799 * =4 arithmetic diagonal, (w/ eigenvalues)
800 * =5 random log symmetric, w/ eigenvalues
803 * =8 random symmetric
804 * =9 positive definite
805 * =10 diagonally dominant tridiagonal
807 IF( MTYPES.GT.MAXTYP )
810 ITYPE = KTYPE( JTYPE )
811 IMODE = KMODE( JTYPE )
815 GO TO ( 40, 50, 60 )KMAGN( JTYPE )
822 ANORM = ( RTOVFL*ULP )*ANINV
826 ANORM = RTUNFL*N*ULPINV
831 CALL DLASET( 'Full', LDA, N, ZERO, ZERO, A, LDA )
833 IF( JTYPE.LE.15 ) THEN
836 COND = ULPINV*ANINV / TEN
839 * Special Matrices -- Identity & Jordan block
843 IF( ITYPE.EQ.1 ) THEN
846 ELSE IF( ITYPE.EQ.2 ) THEN
854 ELSE IF( ITYPE.EQ.4 ) THEN
856 * Diagonal Matrix, [Eigen]values Specified
858 CALL DLATMS( N, N, 'S', ISEED, 'S', WORK, IMODE, COND,
859 $ ANORM, 0, 0, 'N', A, LDA, WORK( N+1 ),
863 ELSE IF( ITYPE.EQ.5 ) THEN
865 * Symmetric, eigenvalues specified
867 CALL DLATMS( N, N, 'S', ISEED, 'S', WORK, IMODE, COND,
868 $ ANORM, N, N, 'N', A, LDA, WORK( N+1 ),
871 ELSE IF( ITYPE.EQ.7 ) THEN
873 * Diagonal, random eigenvalues
875 CALL DLATMR( N, N, 'S', ISEED, 'S', WORK, 6, ONE, ONE,
876 $ 'T', 'N', WORK( N+1 ), 1, ONE,
877 $ WORK( 2*N+1 ), 1, ONE, 'N', IDUMMA, 0, 0,
878 $ ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
880 ELSE IF( ITYPE.EQ.8 ) THEN
882 * Symmetric, random eigenvalues
884 CALL DLATMR( N, N, 'S', ISEED, 'S', WORK, 6, ONE, ONE,
885 $ 'T', 'N', WORK( N+1 ), 1, ONE,
886 $ WORK( 2*N+1 ), 1, ONE, 'N', IDUMMA, N, N,
887 $ ZERO, ANORM, 'NO', A, LDA, IWORK, IINFO )
889 ELSE IF( ITYPE.EQ.9 ) THEN
891 * Positive definite, eigenvalues specified.
893 CALL DLATMS( N, N, 'S', ISEED, 'P', WORK, IMODE, COND,
894 $ ANORM, N, N, 'N', A, LDA, WORK( N+1 ),
897 ELSE IF( ITYPE.EQ.10 ) THEN
899 * Positive definite tridiagonal, eigenvalues specified.
901 CALL DLATMS( N, N, 'S', ISEED, 'P', WORK, IMODE, COND,
902 $ ANORM, 1, 1, 'N', A, LDA, WORK( N+1 ),
905 TEMP1 = ABS( A( I-1, I ) ) /
906 $ SQRT( ABS( A( I-1, I-1 )*A( I, I ) ) )
907 IF( TEMP1.GT.HALF ) THEN
908 A( I-1, I ) = HALF*SQRT( ABS( A( I-1, I-1 )*A( I,
910 A( I, I-1 ) = A( I-1, I )
919 IF( IINFO.NE.0 ) THEN
920 WRITE( NOUNIT, FMT = 9999 )'Generator', IINFO, N, JTYPE,
928 * Call DSYTRD and DORGTR to compute S and U from
931 CALL DLACPY( 'U', N, N, A, LDA, V, LDU )
934 CALL DSYTRD( 'U', N, V, LDU, SD, SE, TAU, WORK, LWORK,
937 IF( IINFO.NE.0 ) THEN
938 WRITE( NOUNIT, FMT = 9999 )'DSYTRD(U)', IINFO, N, JTYPE,
941 IF( IINFO.LT.0 ) THEN
949 CALL DLACPY( 'U', N, N, V, LDU, U, LDU )
952 CALL DORGTR( 'U', N, U, LDU, TAU, WORK, LWORK, IINFO )
953 IF( IINFO.NE.0 ) THEN
954 WRITE( NOUNIT, FMT = 9999 )'DORGTR(U)', IINFO, N, JTYPE,
957 IF( IINFO.LT.0 ) THEN
967 CALL DSYT21( 2, 'Upper', N, 1, A, LDA, SD, SE, U, LDU, V,
968 $ LDU, TAU, WORK, RESULT( 1 ) )
969 CALL DSYT21( 3, 'Upper', N, 1, A, LDA, SD, SE, U, LDU, V,
970 $ LDU, TAU, WORK, RESULT( 2 ) )
972 * Compute D1 the eigenvalues resulting from the tridiagonal
973 * form using the standard 1-stage algorithm and use it as a
974 * reference to compare with the 2-stage technique
976 * Compute D1 from the 1-stage and used as reference for the
979 CALL DCOPY( N, SD, 1, D1, 1 )
981 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
983 CALL DSTEQR( 'N', N, D1, WORK, WORK( N+1 ), LDU,
984 $ WORK( N+1 ), IINFO )
985 IF( IINFO.NE.0 ) THEN
986 WRITE( NOUNIT, FMT = 9999 )'DSTEQR(N)', IINFO, N, JTYPE,
989 IF( IINFO.LT.0 ) THEN
997 * 2-STAGE TRD Upper case is used to compute D2.
998 * Note to set SD and SE to zero to be sure not reusing
999 * the one from above. Compare it with D1 computed
1000 * using the 1-stage.
1002 CALL DLASET( 'Full', N, 1, ZERO, ZERO, SD, N )
1003 CALL DLASET( 'Full', N, 1, ZERO, ZERO, SE, N )
1004 CALL DLACPY( "U", N, N, A, LDA, V, LDU )
1007 CALL DSYTRD_2STAGE( 'N', "U", N, V, LDU, SD, SE, TAU,
1008 $ WORK, LH, WORK( LH+1 ), LW, IINFO )
1010 * Compute D2 from the 2-stage Upper case
1012 CALL DCOPY( N, SD, 1, D2, 1 )
1014 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1016 CALL DSTEQR( 'N', N, D2, WORK, WORK( N+1 ), LDU,
1017 $ WORK( N+1 ), IINFO )
1018 IF( IINFO.NE.0 ) THEN
1019 WRITE( NOUNIT, FMT = 9999 )'DSTEQR(N)', IINFO, N, JTYPE,
1022 IF( IINFO.LT.0 ) THEN
1025 RESULT( 3 ) = ULPINV
1030 * 2-STAGE TRD Lower case is used to compute D3.
1031 * Note to set SD and SE to zero to be sure not reusing
1032 * the one from above. Compare it with D1 computed
1033 * using the 1-stage.
1035 CALL DLASET( 'Full', N, 1, ZERO, ZERO, SD, N )
1036 CALL DLASET( 'Full', N, 1, ZERO, ZERO, SE, N )
1037 CALL DLACPY( "L", N, N, A, LDA, V, LDU )
1038 CALL DSYTRD_2STAGE( 'N', "L", N, V, LDU, SD, SE, TAU,
1039 $ WORK, LH, WORK( LH+1 ), LW, IINFO )
1041 * Compute D3 from the 2-stage Upper case
1043 CALL DCOPY( N, SD, 1, D3, 1 )
1045 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1047 CALL DSTEQR( 'N', N, D3, WORK, WORK( N+1 ), LDU,
1048 $ WORK( N+1 ), IINFO )
1049 IF( IINFO.NE.0 ) THEN
1050 WRITE( NOUNIT, FMT = 9999 )'DSTEQR(N)', IINFO, N, JTYPE,
1053 IF( IINFO.LT.0 ) THEN
1056 RESULT( 4 ) = ULPINV
1062 * Do Tests 3 and 4 which are similar to 11 and 12 but with the
1063 * D1 computed using the standard 1-stage reduction as reference
1072 TEMP1 = MAX( TEMP1, ABS( D1( J ) ), ABS( D2( J ) ) )
1073 TEMP2 = MAX( TEMP2, ABS( D1( J )-D2( J ) ) )
1074 TEMP3 = MAX( TEMP3, ABS( D1( J ) ), ABS( D3( J ) ) )
1075 TEMP4 = MAX( TEMP4, ABS( D1( J )-D3( J ) ) )
1078 RESULT( 3 ) = TEMP2 / MAX( UNFL, ULP*MAX( TEMP1, TEMP2 ) )
1079 RESULT( 4 ) = TEMP4 / MAX( UNFL, ULP*MAX( TEMP3, TEMP4 ) )
1081 * Store the upper triangle of A in AP
1087 AP( I ) = A( JR, JC )
1091 * Call DSPTRD and DOPGTR to compute S and U from AP
1093 CALL DCOPY( NAP, AP, 1, VP, 1 )
1096 CALL DSPTRD( 'U', N, VP, SD, SE, TAU, IINFO )
1098 IF( IINFO.NE.0 ) THEN
1099 WRITE( NOUNIT, FMT = 9999 )'DSPTRD(U)', IINFO, N, JTYPE,
1102 IF( IINFO.LT.0 ) THEN
1105 RESULT( 5 ) = ULPINV
1111 CALL DOPGTR( 'U', N, VP, TAU, U, LDU, WORK, IINFO )
1112 IF( IINFO.NE.0 ) THEN
1113 WRITE( NOUNIT, FMT = 9999 )'DOPGTR(U)', IINFO, N, JTYPE,
1116 IF( IINFO.LT.0 ) THEN
1119 RESULT( 6 ) = ULPINV
1126 CALL DSPT21( 2, 'Upper', N, 1, AP, SD, SE, U, LDU, VP, TAU,
1127 $ WORK, RESULT( 5 ) )
1128 CALL DSPT21( 3, 'Upper', N, 1, AP, SD, SE, U, LDU, VP, TAU,
1129 $ WORK, RESULT( 6 ) )
1131 * Store the lower triangle of A in AP
1137 AP( I ) = A( JR, JC )
1141 * Call DSPTRD and DOPGTR to compute S and U from AP
1143 CALL DCOPY( NAP, AP, 1, VP, 1 )
1146 CALL DSPTRD( 'L', N, VP, SD, SE, TAU, IINFO )
1148 IF( IINFO.NE.0 ) THEN
1149 WRITE( NOUNIT, FMT = 9999 )'DSPTRD(L)', IINFO, N, JTYPE,
1152 IF( IINFO.LT.0 ) THEN
1155 RESULT( 7 ) = ULPINV
1161 CALL DOPGTR( 'L', N, VP, TAU, U, LDU, WORK, IINFO )
1162 IF( IINFO.NE.0 ) THEN
1163 WRITE( NOUNIT, FMT = 9999 )'DOPGTR(L)', IINFO, N, JTYPE,
1166 IF( IINFO.LT.0 ) THEN
1169 RESULT( 8 ) = ULPINV
1174 CALL DSPT21( 2, 'Lower', N, 1, AP, SD, SE, U, LDU, VP, TAU,
1175 $ WORK, RESULT( 7 ) )
1176 CALL DSPT21( 3, 'Lower', N, 1, AP, SD, SE, U, LDU, VP, TAU,
1177 $ WORK, RESULT( 8 ) )
1179 * Call DSTEQR to compute D1, D2, and Z, do tests.
1183 CALL DCOPY( N, SD, 1, D1, 1 )
1185 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1186 CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDU )
1189 CALL DSTEQR( 'V', N, D1, WORK, Z, LDU, WORK( N+1 ), IINFO )
1190 IF( IINFO.NE.0 ) THEN
1191 WRITE( NOUNIT, FMT = 9999 )'DSTEQR(V)', IINFO, N, JTYPE,
1194 IF( IINFO.LT.0 ) THEN
1197 RESULT( 9 ) = ULPINV
1204 CALL DCOPY( N, SD, 1, D2, 1 )
1206 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1209 CALL DSTEQR( 'N', N, D2, WORK, WORK( N+1 ), LDU,
1210 $ WORK( N+1 ), IINFO )
1211 IF( IINFO.NE.0 ) THEN
1212 WRITE( NOUNIT, FMT = 9999 )'DSTEQR(N)', IINFO, N, JTYPE,
1215 IF( IINFO.LT.0 ) THEN
1218 RESULT( 11 ) = ULPINV
1223 * Compute D3 (using PWK method)
1225 CALL DCOPY( N, SD, 1, D3, 1 )
1227 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1230 CALL DSTERF( N, D3, WORK, IINFO )
1231 IF( IINFO.NE.0 ) THEN
1232 WRITE( NOUNIT, FMT = 9999 )'DSTERF', IINFO, N, JTYPE,
1235 IF( IINFO.LT.0 ) THEN
1238 RESULT( 12 ) = ULPINV
1245 CALL DSTT21( N, 0, SD, SE, D1, DUMMA, Z, LDU, WORK,
1248 * Do Tests 11 and 12
1256 TEMP1 = MAX( TEMP1, ABS( D1( J ) ), ABS( D2( J ) ) )
1257 TEMP2 = MAX( TEMP2, ABS( D1( J )-D2( J ) ) )
1258 TEMP3 = MAX( TEMP3, ABS( D1( J ) ), ABS( D3( J ) ) )
1259 TEMP4 = MAX( TEMP4, ABS( D1( J )-D3( J ) ) )
1262 RESULT( 11 ) = TEMP2 / MAX( UNFL, ULP*MAX( TEMP1, TEMP2 ) )
1263 RESULT( 12 ) = TEMP4 / MAX( UNFL, ULP*MAX( TEMP3, TEMP4 ) )
1265 * Do Test 13 -- Sturm Sequence Test of Eigenvalues
1266 * Go up by factors of two until it succeeds
1269 TEMP1 = THRESH*( HALF-ULP )
1271 DO 160 J = 0, LOG2UI
1272 CALL DSTECH( N, SD, SE, D1, TEMP1, WORK, IINFO )
1279 RESULT( 13 ) = TEMP1
1281 * For positive definite matrices ( JTYPE.GT.15 ) call DPTEQR
1282 * and do tests 14, 15, and 16 .
1284 IF( JTYPE.GT.15 ) THEN
1288 CALL DCOPY( N, SD, 1, D4, 1 )
1290 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1291 CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDU )
1294 CALL DPTEQR( 'V', N, D4, WORK, Z, LDU, WORK( N+1 ),
1296 IF( IINFO.NE.0 ) THEN
1297 WRITE( NOUNIT, FMT = 9999 )'DPTEQR(V)', IINFO, N,
1300 IF( IINFO.LT.0 ) THEN
1303 RESULT( 14 ) = ULPINV
1308 * Do Tests 14 and 15
1310 CALL DSTT21( N, 0, SD, SE, D4, DUMMA, Z, LDU, WORK,
1315 CALL DCOPY( N, SD, 1, D5, 1 )
1317 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1320 CALL DPTEQR( 'N', N, D5, WORK, Z, LDU, WORK( N+1 ),
1322 IF( IINFO.NE.0 ) THEN
1323 WRITE( NOUNIT, FMT = 9999 )'DPTEQR(N)', IINFO, N,
1326 IF( IINFO.LT.0 ) THEN
1329 RESULT( 16 ) = ULPINV
1339 TEMP1 = MAX( TEMP1, ABS( D4( J ) ), ABS( D5( J ) ) )
1340 TEMP2 = MAX( TEMP2, ABS( D4( J )-D5( J ) ) )
1343 RESULT( 16 ) = TEMP2 / MAX( UNFL,
1344 $ HUN*ULP*MAX( TEMP1, TEMP2 ) )
1351 * Call DSTEBZ with different options and do tests 17-18.
1353 * If S is positive definite and diagonally dominant,
1354 * ask for all eigenvalues with high relative accuracy.
1360 IF( JTYPE.EQ.21 ) THEN
1362 ABSTOL = UNFL + UNFL
1363 CALL DSTEBZ( 'A', 'E', N, VL, VU, IL, IU, ABSTOL, SD, SE,
1364 $ M, NSPLIT, WR, IWORK( 1 ), IWORK( N+1 ),
1365 $ WORK, IWORK( 2*N+1 ), IINFO )
1366 IF( IINFO.NE.0 ) THEN
1367 WRITE( NOUNIT, FMT = 9999 )'DSTEBZ(A,rel)', IINFO, N,
1370 IF( IINFO.LT.0 ) THEN
1373 RESULT( 17 ) = ULPINV
1380 TEMP2 = TWO*( TWO*N-ONE )*ULP*( ONE+EIGHT*HALF**2 ) /
1385 TEMP1 = MAX( TEMP1, ABS( D4( J )-WR( N-J+1 ) ) /
1386 $ ( ABSTOL+ABS( D4( J ) ) ) )
1389 RESULT( 17 ) = TEMP1 / TEMP2
1394 * Now ask for all eigenvalues with high absolute accuracy.
1397 ABSTOL = UNFL + UNFL
1398 CALL DSTEBZ( 'A', 'E', N, VL, VU, IL, IU, ABSTOL, SD, SE, M,
1399 $ NSPLIT, WA1, IWORK( 1 ), IWORK( N+1 ), WORK,
1400 $ IWORK( 2*N+1 ), IINFO )
1401 IF( IINFO.NE.0 ) THEN
1402 WRITE( NOUNIT, FMT = 9999 )'DSTEBZ(A)', IINFO, N, JTYPE,
1405 IF( IINFO.LT.0 ) THEN
1408 RESULT( 18 ) = ULPINV
1418 TEMP1 = MAX( TEMP1, ABS( D3( J ) ), ABS( WA1( J ) ) )
1419 TEMP2 = MAX( TEMP2, ABS( D3( J )-WA1( J ) ) )
1422 RESULT( 18 ) = TEMP2 / MAX( UNFL, ULP*MAX( TEMP1, TEMP2 ) )
1424 * Choose random values for IL and IU, and ask for the
1425 * IL-th through IU-th eigenvalues.
1432 IL = 1 + ( N-1 )*INT( DLARND( 1, ISEED2 ) )
1433 IU = 1 + ( N-1 )*INT( DLARND( 1, ISEED2 ) )
1441 CALL DSTEBZ( 'I', 'E', N, VL, VU, IL, IU, ABSTOL, SD, SE,
1442 $ M2, NSPLIT, WA2, IWORK( 1 ), IWORK( N+1 ),
1443 $ WORK, IWORK( 2*N+1 ), IINFO )
1444 IF( IINFO.NE.0 ) THEN
1445 WRITE( NOUNIT, FMT = 9999 )'DSTEBZ(I)', IINFO, N, JTYPE,
1448 IF( IINFO.LT.0 ) THEN
1451 RESULT( 19 ) = ULPINV
1456 * Determine the values VL and VU of the IL-th and IU-th
1457 * eigenvalues and ask for all eigenvalues in this range.
1461 VL = WA1( IL ) - MAX( HALF*( WA1( IL )-WA1( IL-1 ) ),
1462 $ ULP*ANORM, TWO*RTUNFL )
1464 VL = WA1( 1 ) - MAX( HALF*( WA1( N )-WA1( 1 ) ),
1465 $ ULP*ANORM, TWO*RTUNFL )
1468 VU = WA1( IU ) + MAX( HALF*( WA1( IU+1 )-WA1( IU ) ),
1469 $ ULP*ANORM, TWO*RTUNFL )
1471 VU = WA1( N ) + MAX( HALF*( WA1( N )-WA1( 1 ) ),
1472 $ ULP*ANORM, TWO*RTUNFL )
1479 CALL DSTEBZ( 'V', 'E', N, VL, VU, IL, IU, ABSTOL, SD, SE,
1480 $ M3, NSPLIT, WA3, IWORK( 1 ), IWORK( N+1 ),
1481 $ WORK, IWORK( 2*N+1 ), IINFO )
1482 IF( IINFO.NE.0 ) THEN
1483 WRITE( NOUNIT, FMT = 9999 )'DSTEBZ(V)', IINFO, N, JTYPE,
1486 IF( IINFO.LT.0 ) THEN
1489 RESULT( 19 ) = ULPINV
1494 IF( M3.EQ.0 .AND. N.NE.0 ) THEN
1495 RESULT( 19 ) = ULPINV
1501 TEMP1 = DSXT1( 1, WA2, M2, WA3, M3, ABSTOL, ULP, UNFL )
1502 TEMP2 = DSXT1( 1, WA3, M3, WA2, M2, ABSTOL, ULP, UNFL )
1504 TEMP3 = MAX( ABS( WA1( N ) ), ABS( WA1( 1 ) ) )
1509 RESULT( 19 ) = ( TEMP1+TEMP2 ) / MAX( UNFL, TEMP3*ULP )
1511 * Call DSTEIN to compute eigenvectors corresponding to
1512 * eigenvalues in WA1. (First call DSTEBZ again, to make sure
1513 * it returns these eigenvalues in the correct order.)
1516 CALL DSTEBZ( 'A', 'B', N, VL, VU, IL, IU, ABSTOL, SD, SE, M,
1517 $ NSPLIT, WA1, IWORK( 1 ), IWORK( N+1 ), WORK,
1518 $ IWORK( 2*N+1 ), IINFO )
1519 IF( IINFO.NE.0 ) THEN
1520 WRITE( NOUNIT, FMT = 9999 )'DSTEBZ(A,B)', IINFO, N,
1523 IF( IINFO.LT.0 ) THEN
1526 RESULT( 20 ) = ULPINV
1527 RESULT( 21 ) = ULPINV
1532 CALL DSTEIN( N, SD, SE, M, WA1, IWORK( 1 ), IWORK( N+1 ), Z,
1533 $ LDU, WORK, IWORK( 2*N+1 ), IWORK( 3*N+1 ),
1535 IF( IINFO.NE.0 ) THEN
1536 WRITE( NOUNIT, FMT = 9999 )'DSTEIN', IINFO, N, JTYPE,
1539 IF( IINFO.LT.0 ) THEN
1542 RESULT( 20 ) = ULPINV
1543 RESULT( 21 ) = ULPINV
1548 * Do tests 20 and 21
1550 CALL DSTT21( N, 0, SD, SE, WA1, DUMMA, Z, LDU, WORK,
1553 * Call DSTEDC(I) to compute D1 and Z, do tests.
1557 CALL DCOPY( N, SD, 1, D1, 1 )
1559 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1560 CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDU )
1563 CALL DSTEDC( 'I', N, D1, WORK, Z, LDU, WORK( N+1 ), LWEDC-N,
1564 $ IWORK, LIWEDC, IINFO )
1565 IF( IINFO.NE.0 ) THEN
1566 WRITE( NOUNIT, FMT = 9999 )'DSTEDC(I)', IINFO, N, JTYPE,
1569 IF( IINFO.LT.0 ) THEN
1572 RESULT( 22 ) = ULPINV
1577 * Do Tests 22 and 23
1579 CALL DSTT21( N, 0, SD, SE, D1, DUMMA, Z, LDU, WORK,
1582 * Call DSTEDC(V) to compute D1 and Z, do tests.
1586 CALL DCOPY( N, SD, 1, D1, 1 )
1588 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1589 CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDU )
1592 CALL DSTEDC( 'V', N, D1, WORK, Z, LDU, WORK( N+1 ), LWEDC-N,
1593 $ IWORK, LIWEDC, IINFO )
1594 IF( IINFO.NE.0 ) THEN
1595 WRITE( NOUNIT, FMT = 9999 )'DSTEDC(V)', IINFO, N, JTYPE,
1598 IF( IINFO.LT.0 ) THEN
1601 RESULT( 24 ) = ULPINV
1606 * Do Tests 24 and 25
1608 CALL DSTT21( N, 0, SD, SE, D1, DUMMA, Z, LDU, WORK,
1611 * Call DSTEDC(N) to compute D2, do tests.
1615 CALL DCOPY( N, SD, 1, D2, 1 )
1617 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1618 CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDU )
1621 CALL DSTEDC( 'N', N, D2, WORK, Z, LDU, WORK( N+1 ), LWEDC-N,
1622 $ IWORK, LIWEDC, IINFO )
1623 IF( IINFO.NE.0 ) THEN
1624 WRITE( NOUNIT, FMT = 9999 )'DSTEDC(N)', IINFO, N, JTYPE,
1627 IF( IINFO.LT.0 ) THEN
1630 RESULT( 26 ) = ULPINV
1641 TEMP1 = MAX( TEMP1, ABS( D1( J ) ), ABS( D2( J ) ) )
1642 TEMP2 = MAX( TEMP2, ABS( D1( J )-D2( J ) ) )
1645 RESULT( 26 ) = TEMP2 / MAX( UNFL, ULP*MAX( TEMP1, TEMP2 ) )
1647 * Only test DSTEMR if IEEE compliant
1649 IF( ILAENV( 10, 'DSTEMR', 'VA', 1, 0, 0, 0 ).EQ.1 .AND.
1650 $ ILAENV( 11, 'DSTEMR', 'VA', 1, 0, 0, 0 ).EQ.1 ) THEN
1652 * Call DSTEMR, do test 27 (relative eigenvalue accuracy)
1654 * If S is positive definite and diagonally dominant,
1655 * ask for all eigenvalues with high relative accuracy.
1661 IF( JTYPE.EQ.21 .AND. SREL ) THEN
1663 ABSTOL = UNFL + UNFL
1664 CALL DSTEMR( 'V', 'A', N, SD, SE, VL, VU, IL, IU,
1665 $ M, WR, Z, LDU, N, IWORK( 1 ), TRYRAC,
1666 $ WORK, LWORK, IWORK( 2*N+1 ), LWORK-2*N,
1668 IF( IINFO.NE.0 ) THEN
1669 WRITE( NOUNIT, FMT = 9999 )'DSTEMR(V,A,rel)',
1670 $ IINFO, N, JTYPE, IOLDSD
1672 IF( IINFO.LT.0 ) THEN
1675 RESULT( 27 ) = ULPINV
1682 TEMP2 = TWO*( TWO*N-ONE )*ULP*( ONE+EIGHT*HALF**2 ) /
1687 TEMP1 = MAX( TEMP1, ABS( D4( J )-WR( N-J+1 ) ) /
1688 $ ( ABSTOL+ABS( D4( J ) ) ) )
1691 RESULT( 27 ) = TEMP1 / TEMP2
1693 IL = 1 + ( N-1 )*INT( DLARND( 1, ISEED2 ) )
1694 IU = 1 + ( N-1 )*INT( DLARND( 1, ISEED2 ) )
1703 ABSTOL = UNFL + UNFL
1704 CALL DSTEMR( 'V', 'I', N, SD, SE, VL, VU, IL, IU,
1705 $ M, WR, Z, LDU, N, IWORK( 1 ), TRYRAC,
1706 $ WORK, LWORK, IWORK( 2*N+1 ),
1707 $ LWORK-2*N, IINFO )
1709 IF( IINFO.NE.0 ) THEN
1710 WRITE( NOUNIT, FMT = 9999 )'DSTEMR(V,I,rel)',
1711 $ IINFO, N, JTYPE, IOLDSD
1713 IF( IINFO.LT.0 ) THEN
1716 RESULT( 28 ) = ULPINV
1724 TEMP2 = TWO*( TWO*N-ONE )*ULP*
1725 $ ( ONE+EIGHT*HALF**2 ) / ( ONE-HALF )**4
1729 TEMP1 = MAX( TEMP1, ABS( WR( J-IL+1 )-D4( N-J+
1730 $ 1 ) ) / ( ABSTOL+ABS( WR( J-IL+1 ) ) ) )
1733 RESULT( 28 ) = TEMP1 / TEMP2
1742 * Call DSTEMR(V,I) to compute D1 and Z, do tests.
1746 CALL DCOPY( N, SD, 1, D5, 1 )
1748 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1749 CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDU )
1753 IL = 1 + ( N-1 )*INT( DLARND( 1, ISEED2 ) )
1754 IU = 1 + ( N-1 )*INT( DLARND( 1, ISEED2 ) )
1760 CALL DSTEMR( 'V', 'I', N, D5, WORK, VL, VU, IL, IU,
1761 $ M, D1, Z, LDU, N, IWORK( 1 ), TRYRAC,
1762 $ WORK( N+1 ), LWORK-N, IWORK( 2*N+1 ),
1763 $ LIWORK-2*N, IINFO )
1764 IF( IINFO.NE.0 ) THEN
1765 WRITE( NOUNIT, FMT = 9999 )'DSTEMR(V,I)', IINFO,
1768 IF( IINFO.LT.0 ) THEN
1771 RESULT( 29 ) = ULPINV
1776 * Do Tests 29 and 30
1778 CALL DSTT22( N, M, 0, SD, SE, D1, DUMMA, Z, LDU, WORK,
1781 * Call DSTEMR to compute D2, do tests.
1785 CALL DCOPY( N, SD, 1, D5, 1 )
1787 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1790 CALL DSTEMR( 'N', 'I', N, D5, WORK, VL, VU, IL, IU,
1791 $ M, D2, Z, LDU, N, IWORK( 1 ), TRYRAC,
1792 $ WORK( N+1 ), LWORK-N, IWORK( 2*N+1 ),
1793 $ LIWORK-2*N, IINFO )
1794 IF( IINFO.NE.0 ) THEN
1795 WRITE( NOUNIT, FMT = 9999 )'DSTEMR(N,I)', IINFO,
1798 IF( IINFO.LT.0 ) THEN
1801 RESULT( 31 ) = ULPINV
1811 DO 240 J = 1, IU - IL + 1
1812 TEMP1 = MAX( TEMP1, ABS( D1( J ) ),
1814 TEMP2 = MAX( TEMP2, ABS( D1( J )-D2( J ) ) )
1817 RESULT( 31 ) = TEMP2 / MAX( UNFL,
1818 $ ULP*MAX( TEMP1, TEMP2 ) )
1821 * Call DSTEMR(V,V) to compute D1 and Z, do tests.
1825 CALL DCOPY( N, SD, 1, D5, 1 )
1827 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1828 CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDU )
1834 VL = D2( IL ) - MAX( HALF*
1835 $ ( D2( IL )-D2( IL-1 ) ), ULP*ANORM,
1838 VL = D2( 1 ) - MAX( HALF*( D2( N )-D2( 1 ) ),
1839 $ ULP*ANORM, TWO*RTUNFL )
1842 VU = D2( IU ) + MAX( HALF*
1843 $ ( D2( IU+1 )-D2( IU ) ), ULP*ANORM,
1846 VU = D2( N ) + MAX( HALF*( D2( N )-D2( 1 ) ),
1847 $ ULP*ANORM, TWO*RTUNFL )
1854 CALL DSTEMR( 'V', 'V', N, D5, WORK, VL, VU, IL, IU,
1855 $ M, D1, Z, LDU, N, IWORK( 1 ), TRYRAC,
1856 $ WORK( N+1 ), LWORK-N, IWORK( 2*N+1 ),
1857 $ LIWORK-2*N, IINFO )
1858 IF( IINFO.NE.0 ) THEN
1859 WRITE( NOUNIT, FMT = 9999 )'DSTEMR(V,V)', IINFO,
1862 IF( IINFO.LT.0 ) THEN
1865 RESULT( 32 ) = ULPINV
1870 * Do Tests 32 and 33
1872 CALL DSTT22( N, M, 0, SD, SE, D1, DUMMA, Z, LDU, WORK,
1875 * Call DSTEMR to compute D2, do tests.
1879 CALL DCOPY( N, SD, 1, D5, 1 )
1881 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1884 CALL DSTEMR( 'N', 'V', N, D5, WORK, VL, VU, IL, IU,
1885 $ M, D2, Z, LDU, N, IWORK( 1 ), TRYRAC,
1886 $ WORK( N+1 ), LWORK-N, IWORK( 2*N+1 ),
1887 $ LIWORK-2*N, IINFO )
1888 IF( IINFO.NE.0 ) THEN
1889 WRITE( NOUNIT, FMT = 9999 )'DSTEMR(N,V)', IINFO,
1892 IF( IINFO.LT.0 ) THEN
1895 RESULT( 34 ) = ULPINV
1905 DO 250 J = 1, IU - IL + 1
1906 TEMP1 = MAX( TEMP1, ABS( D1( J ) ),
1908 TEMP2 = MAX( TEMP2, ABS( D1( J )-D2( J ) ) )
1911 RESULT( 34 ) = TEMP2 / MAX( UNFL,
1912 $ ULP*MAX( TEMP1, TEMP2 ) )
1923 * Call DSTEMR(V,A) to compute D1 and Z, do tests.
1927 CALL DCOPY( N, SD, 1, D5, 1 )
1929 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1933 CALL DSTEMR( 'V', 'A', N, D5, WORK, VL, VU, IL, IU,
1934 $ M, D1, Z, LDU, N, IWORK( 1 ), TRYRAC,
1935 $ WORK( N+1 ), LWORK-N, IWORK( 2*N+1 ),
1936 $ LIWORK-2*N, IINFO )
1937 IF( IINFO.NE.0 ) THEN
1938 WRITE( NOUNIT, FMT = 9999 )'DSTEMR(V,A)', IINFO, N,
1941 IF( IINFO.LT.0 ) THEN
1944 RESULT( 35 ) = ULPINV
1949 * Do Tests 35 and 36
1951 CALL DSTT22( N, M, 0, SD, SE, D1, DUMMA, Z, LDU, WORK, M,
1954 * Call DSTEMR to compute D2, do tests.
1958 CALL DCOPY( N, SD, 1, D5, 1 )
1960 $ CALL DCOPY( N-1, SE, 1, WORK, 1 )
1963 CALL DSTEMR( 'N', 'A', N, D5, WORK, VL, VU, IL, IU,
1964 $ M, D2, Z, LDU, N, IWORK( 1 ), TRYRAC,
1965 $ WORK( N+1 ), LWORK-N, IWORK( 2*N+1 ),
1966 $ LIWORK-2*N, IINFO )
1967 IF( IINFO.NE.0 ) THEN
1968 WRITE( NOUNIT, FMT = 9999 )'DSTEMR(N,A)', IINFO, N,
1971 IF( IINFO.LT.0 ) THEN
1974 RESULT( 37 ) = ULPINV
1985 TEMP1 = MAX( TEMP1, ABS( D1( J ) ), ABS( D2( J ) ) )
1986 TEMP2 = MAX( TEMP2, ABS( D1( J )-D2( J ) ) )
1989 RESULT( 37 ) = TEMP2 / MAX( UNFL,
1990 $ ULP*MAX( TEMP1, TEMP2 ) )
1994 NTESTT = NTESTT + NTEST
1996 * End of Loop -- Check for RESULT(j) > THRESH
1999 * Print out tests which fail.
2001 DO 290 JR = 1, NTEST
2002 IF( RESULT( JR ).GE.THRESH ) THEN
2004 * If this is the first test to fail,
2005 * print a header to the data file.
2007 IF( NERRS.EQ.0 ) THEN
2008 WRITE( NOUNIT, FMT = 9998 )'DST'
2009 WRITE( NOUNIT, FMT = 9997 )
2010 WRITE( NOUNIT, FMT = 9996 )
2011 WRITE( NOUNIT, FMT = 9995 )'Symmetric'
2012 WRITE( NOUNIT, FMT = 9994 )
2016 WRITE( NOUNIT, FMT = 9988 )
2019 WRITE( NOUNIT, FMT = 9990 )N, IOLDSD, JTYPE, JR,
2028 CALL DLASUM( 'DST', NOUNIT, NERRS, NTESTT )
2031 9999 FORMAT( ' DCHKST2STG: ', A, ' returned INFO=', I6, '.', / 9X,
2032 $ 'N=', I6, ', JTYPE=', I6, ', ISEED=(', 3( I5, ',' ), I5, ')' )
2034 9998 FORMAT( / 1X, A3, ' -- Real Symmetric eigenvalue problem' )
2035 9997 FORMAT( ' Matrix types (see DCHKST2STG for details): ' )
2037 9996 FORMAT( / ' Special Matrices:',
2038 $ / ' 1=Zero matrix. ',
2039 $ ' 5=Diagonal: clustered entries.',
2040 $ / ' 2=Identity matrix. ',
2041 $ ' 6=Diagonal: large, evenly spaced.',
2042 $ / ' 3=Diagonal: evenly spaced entries. ',
2043 $ ' 7=Diagonal: small, evenly spaced.',
2044 $ / ' 4=Diagonal: geometr. spaced entries.' )
2045 9995 FORMAT( ' Dense ', A, ' Matrices:',
2046 $ / ' 8=Evenly spaced eigenvals. ',
2047 $ ' 12=Small, evenly spaced eigenvals.',
2048 $ / ' 9=Geometrically spaced eigenvals. ',
2049 $ ' 13=Matrix with random O(1) entries.',
2050 $ / ' 10=Clustered eigenvalues. ',
2051 $ ' 14=Matrix with large random entries.',
2052 $ / ' 11=Large, evenly spaced eigenvals. ',
2053 $ ' 15=Matrix with small random entries.' )
2054 9994 FORMAT( ' 16=Positive definite, evenly spaced eigenvalues',
2055 $ / ' 17=Positive definite, geometrically spaced eigenvlaues',
2056 $ / ' 18=Positive definite, clustered eigenvalues',
2057 $ / ' 19=Positive definite, small evenly spaced eigenvalues',
2058 $ / ' 20=Positive definite, large evenly spaced eigenvalues',
2059 $ / ' 21=Diagonally dominant tridiagonal, geometrically',
2060 $ ' spaced eigenvalues' )
2062 9990 FORMAT( ' N=', I5, ', seed=', 4( I4, ',' ), ' type ', I2,
2063 $ ', test(', I2, ')=', G10.3 )
2065 9988 FORMAT( / 'Test performed: see DCHKST2STG for details.', / )