3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
11 * SUBROUTINE DLATTR( IMAT, UPLO, TRANS, DIAG, ISEED, N, A, LDA, B,
14 * .. Scalar Arguments ..
15 * CHARACTER DIAG, TRANS, UPLO
16 * INTEGER IMAT, INFO, LDA, N
18 * .. Array Arguments ..
20 * DOUBLE PRECISION A( LDA, * ), B( * ), WORK( * )
29 *> DLATTR generates a triangular test matrix.
30 *> IMAT and UPLO uniquely specify the properties of the test
31 *> matrix, which is returned in the array A.
40 *> An integer key describing which matrix to generate for this
46 *> UPLO is CHARACTER*1
47 *> Specifies whether the matrix A will be upper or lower
49 *> = 'U': Upper triangular
50 *> = 'L': Lower triangular
55 *> TRANS is CHARACTER*1
56 *> Specifies whether the matrix or its transpose will be used.
57 *> = 'N': No transpose
59 *> = 'C': Conjugate transpose (= Transpose)
64 *> DIAG is CHARACTER*1
65 *> Specifies whether or not the matrix A is unit triangular.
66 *> = 'N': Non-unit triangular
67 *> = 'U': Unit triangular
70 *> \param[in,out] ISEED
72 *> ISEED is INTEGER array, dimension (4)
73 *> The seed vector for the random number generator (used in
74 *> DLATMS). Modified on exit.
80 *> The order of the matrix to be generated.
85 *> A is DOUBLE PRECISION array, dimension (LDA,N)
86 *> The triangular matrix A. If UPLO = 'U', the leading n by n
87 *> upper triangular part of the array A contains the upper
88 *> triangular matrix, and the strictly lower triangular part of
89 *> A is not referenced. If UPLO = 'L', the leading n by n lower
90 *> triangular part of the array A contains the lower triangular
91 *> matrix, and the strictly upper triangular part of A is not
92 *> referenced. If DIAG = 'U', the diagonal elements of A are
93 *> set so that A(k,k) = k for 1 <= k <= n.
99 *> The leading dimension of the array A. LDA >= max(1,N).
104 *> B is DOUBLE PRECISION array, dimension (N)
105 *> The right hand side vector, if IMAT > 10.
110 *> WORK is DOUBLE PRECISION array, dimension (3*N)
116 *> = 0: successful exit
117 *> < 0: if INFO = -k, the k-th argument had an illegal value
123 *> \author Univ. of Tennessee
124 *> \author Univ. of California Berkeley
125 *> \author Univ. of Colorado Denver
128 *> \date November 2011
130 *> \ingroup double_lin
132 * =====================================================================
133 SUBROUTINE DLATTR( IMAT, UPLO, TRANS, DIAG, ISEED, N, A, LDA, B,
136 * -- LAPACK test routine (version 3.4.0) --
137 * -- LAPACK is a software package provided by Univ. of Tennessee, --
138 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
141 * .. Scalar Arguments ..
142 CHARACTER DIAG, TRANS, UPLO
143 INTEGER IMAT, INFO, LDA, N
145 * .. Array Arguments ..
147 DOUBLE PRECISION A( LDA, * ), B( * ), WORK( * )
150 * =====================================================================
153 DOUBLE PRECISION ONE, TWO, ZERO
154 PARAMETER ( ONE = 1.0D+0, TWO = 2.0D+0, ZERO = 0.0D+0 )
156 * .. Local Scalars ..
160 INTEGER I, IY, J, JCOUNT, KL, KU, MODE
161 DOUBLE PRECISION ANORM, BIGNUM, BNORM, BSCAL, C, CNDNUM, PLUS1,
162 $ PLUS2, RA, RB, REXP, S, SFAC, SMLNUM, STAR1,
163 $ TEXP, TLEFT, TSCAL, ULP, UNFL, X, Y, Z
165 * .. External Functions ..
168 DOUBLE PRECISION DLAMCH, DLARND
169 EXTERNAL LSAME, IDAMAX, DLAMCH, DLARND
171 * .. External Subroutines ..
172 EXTERNAL DCOPY, DLABAD, DLARNV, DLATB4, DLATMS, DROT,
173 $ DROTG, DSCAL, DSWAP
175 * .. Intrinsic Functions ..
176 INTRINSIC ABS, DBLE, MAX, SIGN, SQRT
178 * .. Executable Statements ..
180 PATH( 1: 1 ) = 'Double precision'
182 UNFL = DLAMCH( 'Safe minimum' )
183 ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
185 BIGNUM = ( ONE-ULP ) / SMLNUM
186 CALL DLABAD( SMLNUM, BIGNUM )
187 IF( ( IMAT.GE.7 .AND. IMAT.LE.10 ) .OR. IMAT.EQ.18 ) THEN
194 * Quick return if N.LE.0.
199 * Call DLATB4 to set parameters for SLATMS.
201 UPPER = LSAME( UPLO, 'U' )
203 CALL DLATB4( PATH, IMAT, N, N, TYPE, KL, KU, ANORM, MODE,
206 CALL DLATB4( PATH, -IMAT, N, N, TYPE, KL, KU, ANORM, MODE,
210 * IMAT <= 6: Non-unit triangular matrix
213 CALL DLATMS( N, N, DIST, ISEED, TYPE, B, MODE, CNDNUM, ANORM,
214 $ KL, KU, 'No packing', A, LDA, WORK, INFO )
216 * IMAT > 6: Unit triangular matrix
217 * The diagonal is deliberately set to something other than 1.
219 * IMAT = 7: Matrix is the identity
221 ELSE IF( IMAT.EQ.7 ) THEN
238 * IMAT > 7: Non-trivial unit triangular matrix
240 * Generate a unit triangular matrix T with condition CNDNUM by
241 * forming a triangular matrix with known singular values and
242 * filling in the zero entries with Givens rotations.
244 ELSE IF( IMAT.LE.10 ) THEN
261 * Since the trace of a unit triangular matrix is 1, the product
262 * of its singular values must be 1. Let s = sqrt(CNDNUM),
263 * x = sqrt(s) - 1/sqrt(s), y = sqrt(2/(n-2))*x, and z = x**2.
264 * The following triangular matrix has singular values s, 1, 1,
276 * To fill in the zeros, we first multiply by a matrix with small
277 * condition number of the form
289 * Each element marked with a '*' is formed by taking the product
290 * of the adjacent elements marked with '+'. The '*'s can be
291 * chosen freely, and the '+'s are chosen so that the inverse of
292 * T will have elements of the same magnitude as T. If the *'s in
293 * both T and inv(T) have small magnitude, T is well conditioned.
294 * The two offdiagonals of T are stored in WORK.
296 * The product of these two matrices has the form
298 * 1 y y y y y . y y z
309 * Now we multiply by Givens rotations, using the fact that
311 * [ c s ] [ 1 w ] [ -c -s ] = [ 1 -w ]
312 * [ -s c ] [ 0 1 ] [ s -c ] [ 0 1 ]
314 * [ -c -s ] [ 1 0 ] [ c s ] = [ 1 0 ]
315 * [ s -c ] [ w 1 ] [ -s c ] [ -w 1 ]
317 * where c = w / sqrt(w**2+4) and s = 2 / sqrt(w**2+4).
323 PLUS2 = STAR1 / PLUS1
329 PLUS1 = STAR1 / PLUS2
330 REXP = DLARND( 2, ISEED )
331 STAR1 = STAR1*( SFAC**REXP )
332 IF( REXP.LT.ZERO ) THEN
333 STAR1 = -SFAC**( ONE-REXP )
335 STAR1 = SFAC**( ONE+REXP )
340 X = SQRT( CNDNUM ) - 1 / SQRT( CNDNUM )
342 Y = SQRT( 2.D0 / ( N-2 ) )*X
350 CALL DCOPY( N-3, WORK, 1, A( 2, 3 ), LDA+1 )
352 $ CALL DCOPY( N-4, WORK( N+1 ), 1, A( 2, 4 ), LDA+1 )
361 CALL DCOPY( N-3, WORK, 1, A( 3, 2 ), LDA+1 )
363 $ CALL DCOPY( N-4, WORK( N+1 ), 1, A( 4, 2 ), LDA+1 )
372 * Fill in the zeros using Givens rotations.
378 CALL DROTG( RA, RB, C, S )
380 * Multiply by [ c s; -s c] on the left.
383 $ CALL DROT( N-J-1, A( J, J+2 ), LDA, A( J+1, J+2 ),
386 * Multiply by [-c -s; s -c] on the right.
389 $ CALL DROT( J-1, A( 1, J+1 ), 1, A( 1, J ), 1, -C, -S )
393 A( J, J+1 ) = -A( J, J+1 )
399 CALL DROTG( RA, RB, C, S )
401 * Multiply by [ c -s; s c] on the right.
404 $ CALL DROT( N-J-1, A( J+2, J+1 ), 1, A( J+2, J ), 1, C,
407 * Multiply by [-c s; -s -c] on the left.
410 $ CALL DROT( J-1, A( J, 1 ), LDA, A( J+1, 1 ), LDA, -C,
415 A( J+1, J ) = -A( J+1, J )
419 * IMAT > 10: Pathological test cases. These triangular matrices
420 * are badly scaled or badly conditioned, so when used in solving a
421 * triangular system they may cause overflow in the solution vector.
423 ELSE IF( IMAT.EQ.11 ) THEN
425 * Type 11: Generate a triangular matrix with elements between
426 * -1 and 1. Give the diagonal norm 2 to make it well-conditioned.
427 * Make the right hand side large so that it requires scaling.
431 CALL DLARNV( 2, ISEED, J, A( 1, J ) )
432 A( J, J ) = SIGN( TWO, A( J, J ) )
436 CALL DLARNV( 2, ISEED, N-J+1, A( J, J ) )
437 A( J, J ) = SIGN( TWO, A( J, J ) )
441 * Set the right hand side so that the largest value is BIGNUM.
443 CALL DLARNV( 2, ISEED, N, B )
444 IY = IDAMAX( N, B, 1 )
445 BNORM = ABS( B( IY ) )
446 BSCAL = BIGNUM / MAX( ONE, BNORM )
447 CALL DSCAL( N, BSCAL, B, 1 )
449 ELSE IF( IMAT.EQ.12 ) THEN
451 * Type 12: Make the first diagonal element in the solve small to
452 * cause immediate overflow when dividing by T(j,j).
453 * In type 12, the offdiagonal elements are small (CNORM(j) < 1).
455 CALL DLARNV( 2, ISEED, N, B )
456 TSCAL = ONE / MAX( ONE, DBLE( N-1 ) )
459 CALL DLARNV( 2, ISEED, J, A( 1, J ) )
460 CALL DSCAL( J-1, TSCAL, A( 1, J ), 1 )
461 A( J, J ) = SIGN( ONE, A( J, J ) )
463 A( N, N ) = SMLNUM*A( N, N )
466 CALL DLARNV( 2, ISEED, N-J+1, A( J, J ) )
468 $ CALL DSCAL( N-J, TSCAL, A( J+1, J ), 1 )
469 A( J, J ) = SIGN( ONE, A( J, J ) )
471 A( 1, 1 ) = SMLNUM*A( 1, 1 )
474 ELSE IF( IMAT.EQ.13 ) THEN
476 * Type 13: Make the first diagonal element in the solve small to
477 * cause immediate overflow when dividing by T(j,j).
478 * In type 13, the offdiagonal elements are O(1) (CNORM(j) > 1).
480 CALL DLARNV( 2, ISEED, N, B )
483 CALL DLARNV( 2, ISEED, J, A( 1, J ) )
484 A( J, J ) = SIGN( ONE, A( J, J ) )
486 A( N, N ) = SMLNUM*A( N, N )
489 CALL DLARNV( 2, ISEED, N-J+1, A( J, J ) )
490 A( J, J ) = SIGN( ONE, A( J, J ) )
492 A( 1, 1 ) = SMLNUM*A( 1, 1 )
495 ELSE IF( IMAT.EQ.14 ) THEN
497 * Type 14: T is diagonal with small numbers on the diagonal to
498 * make the growth factor underflow, but a small right hand side
499 * chosen so that the solution does not overflow.
507 IF( JCOUNT.LE.2 ) THEN
522 IF( JCOUNT.LE.2 ) THEN
533 * Set the right hand side alternately zero and small.
543 DO 250 I = 1, N - 1, 2
549 ELSE IF( IMAT.EQ.15 ) THEN
551 * Type 15: Make the diagonal elements small to cause gradual
552 * overflow when dividing by T(j,j). To control the amount of
553 * scaling needed, the matrix is bidiagonal.
555 TEXP = ONE / MAX( ONE, DBLE( N-1 ) )
557 CALL DLARNV( 2, ISEED, N, B )
580 ELSE IF( IMAT.EQ.16 ) THEN
582 * Type 16: One zero diagonal element.
587 CALL DLARNV( 2, ISEED, J, A( 1, J ) )
589 A( J, J ) = SIGN( TWO, A( J, J ) )
596 CALL DLARNV( 2, ISEED, N-J+1, A( J, J ) )
598 A( J, J ) = SIGN( TWO, A( J, J ) )
604 CALL DLARNV( 2, ISEED, N, B )
605 CALL DSCAL( N, TWO, B, 1 )
607 ELSE IF( IMAT.EQ.17 ) THEN
609 * Type 17: Make the offdiagonal elements large to cause overflow
610 * when adding a column of T. In the non-transposed case, the
611 * matrix is constructed to cause overflow when adding a column in
615 TSCAL = ( ONE-ULP ) / TSCAL
624 A( 1, J ) = -TSCAL / DBLE( N+1 )
626 B( J ) = TEXP*( ONE-ULP )
627 A( 1, J-1 ) = -( TSCAL / DBLE( N+1 ) ) / DBLE( N+2 )
629 B( J-1 ) = TEXP*DBLE( N*N+N-1 )
632 B( 1 ) = ( DBLE( N+1 ) / DBLE( N+2 ) )*TSCAL
634 DO 350 J = 1, N - 1, 2
635 A( N, J ) = -TSCAL / DBLE( N+1 )
637 B( J ) = TEXP*( ONE-ULP )
638 A( N, J+1 ) = -( TSCAL / DBLE( N+1 ) ) / DBLE( N+2 )
640 B( J+1 ) = TEXP*DBLE( N*N+N-1 )
643 B( N ) = ( DBLE( N+1 ) / DBLE( N+2 ) )*TSCAL
646 ELSE IF( IMAT.EQ.18 ) THEN
648 * Type 18: Generate a unit triangular matrix with elements
649 * between -1 and 1, and make the right hand side large so that it
654 CALL DLARNV( 2, ISEED, J-1, A( 1, J ) )
660 $ CALL DLARNV( 2, ISEED, N-J, A( J+1, J ) )
665 * Set the right hand side so that the largest value is BIGNUM.
667 CALL DLARNV( 2, ISEED, N, B )
668 IY = IDAMAX( N, B, 1 )
669 BNORM = ABS( B( IY ) )
670 BSCAL = BIGNUM / MAX( ONE, BNORM )
671 CALL DSCAL( N, BSCAL, B, 1 )
673 ELSE IF( IMAT.EQ.19 ) THEN
675 * Type 19: Generate a triangular matrix with elements between
676 * BIGNUM/(n-1) and BIGNUM so that at least one of the column
677 * norms will exceed BIGNUM.
678 * 1/3/91: DLATRS no longer can handle this case
680 TLEFT = BIGNUM / MAX( ONE, DBLE( N-1 ) )
681 TSCAL = BIGNUM*( DBLE( N-1 ) / MAX( ONE, DBLE( N ) ) )
684 CALL DLARNV( 2, ISEED, J, A( 1, J ) )
686 A( I, J ) = SIGN( TLEFT, A( I, J ) ) + TSCAL*A( I, J )
691 CALL DLARNV( 2, ISEED, N-J+1, A( J, J ) )
693 A( I, J ) = SIGN( TLEFT, A( I, J ) ) + TSCAL*A( I, J )
697 CALL DLARNV( 2, ISEED, N, B )
698 CALL DSCAL( N, TWO, B, 1 )
701 * Flip the matrix if the transpose will be used.
703 IF( .NOT.LSAME( TRANS, 'N' ) ) THEN
706 CALL DSWAP( N-2*J+1, A( J, J ), LDA, A( J+1, N-J+1 ),
711 CALL DSWAP( N-2*J+1, A( J, J ), 1, A( N-J+1, J+1 ),