3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
11 * SUBROUTINE CLATTR( 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 ..
21 * COMPLEX A( LDA, * ), B( * ), WORK( * )
30 *> CLATTR generates a triangular test matrix in 2-dimensional storage.
31 *> IMAT and UPLO uniquely specify the properties of the test matrix,
32 *> which is returned in the array A.
41 *> An integer key describing which matrix to generate for this
47 *> UPLO is CHARACTER*1
48 *> Specifies whether the matrix A will be upper or lower
50 *> = 'U': Upper triangular
51 *> = 'L': Lower triangular
56 *> TRANS is CHARACTER*1
57 *> Specifies whether the matrix or its transpose will be used.
58 *> = 'N': No transpose
60 *> = 'C': Conjugate transpose
65 *> DIAG is CHARACTER*1
66 *> Specifies whether or not the matrix A is unit triangular.
67 *> = 'N': Non-unit triangular
68 *> = 'U': Unit triangular
71 *> \param[in,out] ISEED
73 *> ISEED is INTEGER array, dimension (4)
74 *> The seed vector for the random number generator (used in
75 *> CLATMS). Modified on exit.
81 *> The order of the matrix to be generated.
86 *> A is COMPLEX array, dimension (LDA,N)
87 *> The triangular matrix A. If UPLO = 'U', the leading N x N
88 *> upper triangular part of the array A contains the upper
89 *> triangular matrix, and the strictly lower triangular part of
90 *> A is not referenced. If UPLO = 'L', the leading N x N lower
91 *> triangular part of the array A contains the lower triangular
92 *> matrix and the strictly upper triangular part of A is not
99 *> The leading dimension of the array A. LDA >= max(1,N).
104 *> B is COMPLEX array, dimension (N)
105 *> The right hand side vector, if IMAT > 10.
110 *> WORK is COMPLEX array, dimension (2*N)
115 *> RWORK is REAL array, dimension (N)
121 *> = 0: successful exit
122 *> < 0: if INFO = -i, the i-th argument had an illegal value
128 *> \author Univ. of Tennessee
129 *> \author Univ. of California Berkeley
130 *> \author Univ. of Colorado Denver
133 *> \date November 2011
135 *> \ingroup complex_lin
137 * =====================================================================
138 SUBROUTINE CLATTR( IMAT, UPLO, TRANS, DIAG, ISEED, N, A, LDA, B,
139 $ WORK, RWORK, INFO )
141 * -- LAPACK test routine (version 3.4.0) --
142 * -- LAPACK is a software package provided by Univ. of Tennessee, --
143 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
146 * .. Scalar Arguments ..
147 CHARACTER DIAG, TRANS, UPLO
148 INTEGER IMAT, INFO, LDA, N
150 * .. Array Arguments ..
153 COMPLEX A( LDA, * ), B( * ), WORK( * )
156 * =====================================================================
160 PARAMETER ( ONE = 1.0E+0, TWO = 2.0E+0, ZERO = 0.0E+0 )
162 * .. Local Scalars ..
166 INTEGER I, IY, J, JCOUNT, KL, KU, MODE
167 REAL ANORM, BIGNUM, BNORM, BSCAL, C, CNDNUM, REXP,
168 $ SFAC, SMLNUM, TEXP, TLEFT, TSCAL, ULP, UNFL, X,
170 COMPLEX PLUS1, PLUS2, RA, RB, S, STAR1
172 * .. External Functions ..
177 EXTERNAL LSAME, ICAMAX, SLAMCH, SLARND, CLARND
179 * .. External Subroutines ..
180 EXTERNAL CCOPY, CLARNV, CLATB4, CLATMS, CROT, CROTG,
181 $ CSSCAL, CSWAP, SLABAD, SLARNV
183 * .. Intrinsic Functions ..
184 INTRINSIC ABS, CMPLX, CONJG, MAX, REAL, SQRT
186 * .. Executable Statements ..
188 PATH( 1: 1 ) = 'Complex precision'
190 UNFL = SLAMCH( 'Safe minimum' )
191 ULP = SLAMCH( 'Epsilon' )*SLAMCH( 'Base' )
193 BIGNUM = ( ONE-ULP ) / SMLNUM
194 CALL SLABAD( SMLNUM, BIGNUM )
195 IF( ( IMAT.GE.7 .AND. IMAT.LE.10 ) .OR. IMAT.EQ.18 ) THEN
202 * Quick return if N.LE.0.
207 * Call CLATB4 to set parameters for CLATMS.
209 UPPER = LSAME( UPLO, 'U' )
211 CALL CLATB4( PATH, IMAT, N, N, TYPE, KL, KU, ANORM, MODE,
214 CALL CLATB4( PATH, -IMAT, N, N, TYPE, KL, KU, ANORM, MODE,
218 * IMAT <= 6: Non-unit triangular matrix
221 CALL CLATMS( N, N, DIST, ISEED, TYPE, RWORK, MODE, CNDNUM,
222 $ ANORM, KL, KU, 'No packing', A, LDA, WORK, INFO )
224 * IMAT > 6: Unit triangular matrix
225 * The diagonal is deliberately set to something other than 1.
227 * IMAT = 7: Matrix is the identity
229 ELSE IF( IMAT.EQ.7 ) THEN
246 * IMAT > 7: Non-trivial unit triangular matrix
248 * Generate a unit triangular matrix T with condition CNDNUM by
249 * forming a triangular matrix with known singular values and
250 * filling in the zero entries with Givens rotations.
252 ELSE IF( IMAT.LE.10 ) THEN
269 * Since the trace of a unit triangular matrix is 1, the product
270 * of its singular values must be 1. Let s = sqrt(CNDNUM),
271 * x = sqrt(s) - 1/sqrt(s), y = sqrt(2/(n-2))*x, and z = x**2.
272 * The following triangular matrix has singular values s, 1, 1,
284 * To fill in the zeros, we first multiply by a matrix with small
285 * condition number of the form
297 * Each element marked with a '*' is formed by taking the product
298 * of the adjacent elements marked with '+'. The '*'s can be
299 * chosen freely, and the '+'s are chosen so that the inverse of
300 * T will have elements of the same magnitude as T. If the *'s in
301 * both T and inv(T) have small magnitude, T is well conditioned.
302 * The two offdiagonals of T are stored in WORK.
304 * The product of these two matrices has the form
306 * 1 y y y y y . y y z
317 * Now we multiply by Givens rotations, using the fact that
319 * [ c s ] [ 1 w ] [ -c -s ] = [ 1 -w ]
320 * [ -s c ] [ 0 1 ] [ s -c ] [ 0 1 ]
322 * [ -c -s ] [ 1 0 ] [ c s ] = [ 1 0 ]
323 * [ s -c ] [ w 1 ] [ -s c ] [ -w 1 ]
325 * where c = w / sqrt(w**2+4) and s = 2 / sqrt(w**2+4).
327 STAR1 = 0.25*CLARND( 5, ISEED )
329 PLUS1 = SFAC*CLARND( 5, ISEED )
331 PLUS2 = STAR1 / PLUS1
337 PLUS1 = STAR1 / PLUS2
338 REXP = SLARND( 2, ISEED )
339 IF( REXP.LT.ZERO ) THEN
340 STAR1 = -SFAC**( ONE-REXP )*CLARND( 5, ISEED )
342 STAR1 = SFAC**( ONE+REXP )*CLARND( 5, ISEED )
347 X = SQRT( CNDNUM ) - 1 / SQRT( CNDNUM )
349 Y = SQRT( 2. / ( N-2 ) )*X
357 CALL CCOPY( N-3, WORK, 1, A( 2, 3 ), LDA+1 )
359 $ CALL CCOPY( N-4, WORK( N+1 ), 1, A( 2, 4 ), LDA+1 )
368 CALL CCOPY( N-3, WORK, 1, A( 3, 2 ), LDA+1 )
370 $ CALL CCOPY( N-4, WORK( N+1 ), 1, A( 4, 2 ), LDA+1 )
379 * Fill in the zeros using Givens rotations.
385 CALL CROTG( RA, RB, C, S )
387 * Multiply by [ c s; -conjg(s) c] on the left.
390 $ CALL CROT( N-J-1, A( J, J+2 ), LDA, A( J+1, J+2 ),
393 * Multiply by [-c -s; conjg(s) -c] on the right.
396 $ CALL CROT( J-1, A( 1, J+1 ), 1, A( 1, J ), 1, -C, -S )
400 A( J, J+1 ) = -A( J, J+1 )
406 CALL CROTG( RA, RB, C, S )
409 * Multiply by [ c -s; conjg(s) c] on the right.
412 $ CALL CROT( N-J-1, A( J+2, J+1 ), 1, A( J+2, J ), 1, C,
415 * Multiply by [-c s; -conjg(s) -c] on the left.
418 $ CALL CROT( J-1, A( J, 1 ), LDA, A( J+1, 1 ), LDA, -C,
423 A( J+1, J ) = -A( J+1, J )
427 * IMAT > 10: Pathological test cases. These triangular matrices
428 * are badly scaled or badly conditioned, so when used in solving a
429 * triangular system they may cause overflow in the solution vector.
431 ELSE IF( IMAT.EQ.11 ) THEN
433 * Type 11: Generate a triangular matrix with elements between
434 * -1 and 1. Give the diagonal norm 2 to make it well-conditioned.
435 * Make the right hand side large so that it requires scaling.
439 CALL CLARNV( 4, ISEED, J-1, A( 1, J ) )
440 A( J, J ) = CLARND( 5, ISEED )*TWO
445 $ CALL CLARNV( 4, ISEED, N-J, A( J+1, J ) )
446 A( J, J ) = CLARND( 5, ISEED )*TWO
450 * Set the right hand side so that the largest value is BIGNUM.
452 CALL CLARNV( 2, ISEED, N, B )
453 IY = ICAMAX( N, B, 1 )
454 BNORM = ABS( B( IY ) )
455 BSCAL = BIGNUM / MAX( ONE, BNORM )
456 CALL CSSCAL( N, BSCAL, B, 1 )
458 ELSE IF( IMAT.EQ.12 ) THEN
460 * Type 12: Make the first diagonal element in the solve small to
461 * cause immediate overflow when dividing by T(j,j).
462 * In type 12, the offdiagonal elements are small (CNORM(j) < 1).
464 CALL CLARNV( 2, ISEED, N, B )
465 TSCAL = ONE / MAX( ONE, REAL( N-1 ) )
468 CALL CLARNV( 4, ISEED, J-1, A( 1, J ) )
469 CALL CSSCAL( J-1, TSCAL, A( 1, J ), 1 )
470 A( J, J ) = CLARND( 5, ISEED )
472 A( N, N ) = SMLNUM*A( N, N )
476 CALL CLARNV( 4, ISEED, N-J, A( J+1, J ) )
477 CALL CSSCAL( N-J, TSCAL, A( J+1, J ), 1 )
479 A( J, J ) = CLARND( 5, ISEED )
481 A( 1, 1 ) = SMLNUM*A( 1, 1 )
484 ELSE IF( IMAT.EQ.13 ) THEN
486 * Type 13: Make the first diagonal element in the solve small to
487 * cause immediate overflow when dividing by T(j,j).
488 * In type 13, the offdiagonal elements are O(1) (CNORM(j) > 1).
490 CALL CLARNV( 2, ISEED, N, B )
493 CALL CLARNV( 4, ISEED, J-1, A( 1, J ) )
494 A( J, J ) = CLARND( 5, ISEED )
496 A( N, N ) = SMLNUM*A( N, N )
500 $ CALL CLARNV( 4, ISEED, N-J, A( J+1, J ) )
501 A( J, J ) = CLARND( 5, ISEED )
503 A( 1, 1 ) = SMLNUM*A( 1, 1 )
506 ELSE IF( IMAT.EQ.14 ) THEN
508 * Type 14: T is diagonal with small numbers on the diagonal to
509 * make the growth factor underflow, but a small right hand side
510 * chosen so that the solution does not overflow.
518 IF( JCOUNT.LE.2 ) THEN
519 A( J, J ) = SMLNUM*CLARND( 5, ISEED )
521 A( J, J ) = CLARND( 5, ISEED )
533 IF( JCOUNT.LE.2 ) THEN
534 A( J, J ) = SMLNUM*CLARND( 5, ISEED )
536 A( J, J ) = CLARND( 5, ISEED )
544 * Set the right hand side alternately zero and small.
550 B( I-1 ) = SMLNUM*CLARND( 5, ISEED )
554 DO 250 I = 1, N - 1, 2
556 B( I+1 ) = SMLNUM*CLARND( 5, ISEED )
560 ELSE IF( IMAT.EQ.15 ) THEN
562 * Type 15: Make the diagonal elements small to cause gradual
563 * overflow when dividing by T(j,j). To control the amount of
564 * scaling needed, the matrix is bidiagonal.
566 TEXP = ONE / MAX( ONE, REAL( N-1 ) )
568 CALL CLARNV( 4, ISEED, N, B )
575 $ A( J-1, J ) = CMPLX( -ONE, -ONE )
576 A( J, J ) = TSCAL*CLARND( 5, ISEED )
578 B( N ) = CMPLX( ONE, ONE )
585 $ A( J+1, J ) = CMPLX( -ONE, -ONE )
586 A( J, J ) = TSCAL*CLARND( 5, ISEED )
588 B( 1 ) = CMPLX( ONE, ONE )
591 ELSE IF( IMAT.EQ.16 ) THEN
593 * Type 16: One zero diagonal element.
598 CALL CLARNV( 4, ISEED, J-1, A( 1, J ) )
600 A( J, J ) = CLARND( 5, ISEED )*TWO
608 $ CALL CLARNV( 4, ISEED, N-J, A( J+1, J ) )
610 A( J, J ) = CLARND( 5, ISEED )*TWO
616 CALL CLARNV( 2, ISEED, N, B )
617 CALL CSSCAL( N, TWO, B, 1 )
619 ELSE IF( IMAT.EQ.17 ) THEN
621 * Type 17: Make the offdiagonal elements large to cause overflow
622 * when adding a column of T. In the non-transposed case, the
623 * matrix is constructed to cause overflow when adding a column in
627 TSCAL = ( ONE-ULP ) / TSCAL
636 A( 1, J ) = -TSCAL / REAL( N+1 )
638 B( J ) = TEXP*( ONE-ULP )
639 A( 1, J-1 ) = -( TSCAL / REAL( N+1 ) ) / REAL( N+2 )
641 B( J-1 ) = TEXP*REAL( N*N+N-1 )
644 B( 1 ) = ( REAL( N+1 ) / REAL( N+2 ) )*TSCAL
646 DO 350 J = 1, N - 1, 2
647 A( N, J ) = -TSCAL / REAL( N+1 )
649 B( J ) = TEXP*( ONE-ULP )
650 A( N, J+1 ) = -( TSCAL / REAL( N+1 ) ) / REAL( N+2 )
652 B( J+1 ) = TEXP*REAL( N*N+N-1 )
655 B( N ) = ( REAL( N+1 ) / REAL( N+2 ) )*TSCAL
658 ELSE IF( IMAT.EQ.18 ) THEN
660 * Type 18: Generate a unit triangular matrix with elements
661 * between -1 and 1, and make the right hand side large so that it
666 CALL CLARNV( 4, ISEED, J-1, A( 1, J ) )
672 $ CALL CLARNV( 4, ISEED, N-J, A( J+1, J ) )
677 * Set the right hand side so that the largest value is BIGNUM.
679 CALL CLARNV( 2, ISEED, N, B )
680 IY = ICAMAX( N, B, 1 )
681 BNORM = ABS( B( IY ) )
682 BSCAL = BIGNUM / MAX( ONE, BNORM )
683 CALL CSSCAL( N, BSCAL, B, 1 )
685 ELSE IF( IMAT.EQ.19 ) THEN
687 * Type 19: Generate a triangular matrix with elements between
688 * BIGNUM/(n-1) and BIGNUM so that at least one of the column
689 * norms will exceed BIGNUM.
690 * 1/3/91: CLATRS no longer can handle this case
692 TLEFT = BIGNUM / MAX( ONE, REAL( N-1 ) )
693 TSCAL = BIGNUM*( REAL( N-1 ) / MAX( ONE, REAL( N ) ) )
696 CALL CLARNV( 5, ISEED, J, A( 1, J ) )
697 CALL SLARNV( 1, ISEED, J, RWORK )
699 A( I, J ) = A( I, J )*( TLEFT+RWORK( I )*TSCAL )
704 CALL CLARNV( 5, ISEED, N-J+1, A( J, J ) )
705 CALL SLARNV( 1, ISEED, N-J+1, RWORK )
707 A( I, J ) = A( I, J )*( TLEFT+RWORK( I-J+1 )*TSCAL )
711 CALL CLARNV( 2, ISEED, N, B )
712 CALL CSSCAL( N, TWO, B, 1 )
715 * Flip the matrix if the transpose will be used.
717 IF( .NOT.LSAME( TRANS, 'N' ) ) THEN
720 CALL CSWAP( N-2*J+1, A( J, J ), LDA, A( J+1, N-J+1 ),
725 CALL CSWAP( N-2*J+1, A( J, J ), 1, A( N-J+1, J+1 ),