zlattr.f
来自「famous linear algebra library (LAPACK) p」· F 代码 · 共 659 行 · 第 1/2 页
F
659 行
*
* Multiply by [ c -s; conjg(s) c] on the right.
*
IF( N.GT.J+1 )
$ CALL ZROT( N-J-1, A( J+2, J+1 ), 1, A( J+2, J ), 1, C,
$ -S )
*
* Multiply by [-c s; -conjg(s) -c] on the left.
*
IF( J.GT.1 )
$ CALL ZROT( J-1, A( J, 1 ), LDA, A( J+1, 1 ), LDA, -C,
$ S )
*
* Negate A(J+1,J).
*
A( J+1, J ) = -A( J+1, J )
130 CONTINUE
END IF
*
* IMAT > 10: Pathological test cases. These triangular matrices
* are badly scaled or badly conditioned, so when used in solving a
* triangular system they may cause overflow in the solution vector.
*
ELSE IF( IMAT.EQ.11 ) THEN
*
* Type 11: Generate a triangular matrix with elements between
* -1 and 1. Give the diagonal norm 2 to make it well-conditioned.
* Make the right hand side large so that it requires scaling.
*
IF( UPPER ) THEN
DO 140 J = 1, N
CALL ZLARNV( 4, ISEED, J-1, A( 1, J ) )
A( J, J ) = ZLARND( 5, ISEED )*TWO
140 CONTINUE
ELSE
DO 150 J = 1, N
IF( J.LT.N )
$ CALL ZLARNV( 4, ISEED, N-J, A( J+1, J ) )
A( J, J ) = ZLARND( 5, ISEED )*TWO
150 CONTINUE
END IF
*
* Set the right hand side so that the largest value is BIGNUM.
*
CALL ZLARNV( 2, ISEED, N, B )
IY = IZAMAX( N, B, 1 )
BNORM = ABS( B( IY ) )
BSCAL = BIGNUM / MAX( ONE, BNORM )
CALL ZDSCAL( N, BSCAL, B, 1 )
*
ELSE IF( IMAT.EQ.12 ) THEN
*
* Type 12: Make the first diagonal element in the solve small to
* cause immediate overflow when dividing by T(j,j).
* In type 12, the offdiagonal elements are small (CNORM(j) < 1).
*
CALL ZLARNV( 2, ISEED, N, B )
TSCAL = ONE / MAX( ONE, DBLE( N-1 ) )
IF( UPPER ) THEN
DO 160 J = 1, N
CALL ZLARNV( 4, ISEED, J-1, A( 1, J ) )
CALL ZDSCAL( J-1, TSCAL, A( 1, J ), 1 )
A( J, J ) = ZLARND( 5, ISEED )
160 CONTINUE
A( N, N ) = SMLNUM*A( N, N )
ELSE
DO 170 J = 1, N
IF( J.LT.N ) THEN
CALL ZLARNV( 4, ISEED, N-J, A( J+1, J ) )
CALL ZDSCAL( N-J, TSCAL, A( J+1, J ), 1 )
END IF
A( J, J ) = ZLARND( 5, ISEED )
170 CONTINUE
A( 1, 1 ) = SMLNUM*A( 1, 1 )
END IF
*
ELSE IF( IMAT.EQ.13 ) THEN
*
* Type 13: Make the first diagonal element in the solve small to
* cause immediate overflow when dividing by T(j,j).
* In type 13, the offdiagonal elements are O(1) (CNORM(j) > 1).
*
CALL ZLARNV( 2, ISEED, N, B )
IF( UPPER ) THEN
DO 180 J = 1, N
CALL ZLARNV( 4, ISEED, J-1, A( 1, J ) )
A( J, J ) = ZLARND( 5, ISEED )
180 CONTINUE
A( N, N ) = SMLNUM*A( N, N )
ELSE
DO 190 J = 1, N
IF( J.LT.N )
$ CALL ZLARNV( 4, ISEED, N-J, A( J+1, J ) )
A( J, J ) = ZLARND( 5, ISEED )
190 CONTINUE
A( 1, 1 ) = SMLNUM*A( 1, 1 )
END IF
*
ELSE IF( IMAT.EQ.14 ) THEN
*
* Type 14: T is diagonal with small numbers on the diagonal to
* make the growth factor underflow, but a small right hand side
* chosen so that the solution does not overflow.
*
IF( UPPER ) THEN
JCOUNT = 1
DO 210 J = N, 1, -1
DO 200 I = 1, J - 1
A( I, J ) = ZERO
200 CONTINUE
IF( JCOUNT.LE.2 ) THEN
A( J, J ) = SMLNUM*ZLARND( 5, ISEED )
ELSE
A( J, J ) = ZLARND( 5, ISEED )
END IF
JCOUNT = JCOUNT + 1
IF( JCOUNT.GT.4 )
$ JCOUNT = 1
210 CONTINUE
ELSE
JCOUNT = 1
DO 230 J = 1, N
DO 220 I = J + 1, N
A( I, J ) = ZERO
220 CONTINUE
IF( JCOUNT.LE.2 ) THEN
A( J, J ) = SMLNUM*ZLARND( 5, ISEED )
ELSE
A( J, J ) = ZLARND( 5, ISEED )
END IF
JCOUNT = JCOUNT + 1
IF( JCOUNT.GT.4 )
$ JCOUNT = 1
230 CONTINUE
END IF
*
* Set the right hand side alternately zero and small.
*
IF( UPPER ) THEN
B( 1 ) = ZERO
DO 240 I = N, 2, -2
B( I ) = ZERO
B( I-1 ) = SMLNUM*ZLARND( 5, ISEED )
240 CONTINUE
ELSE
B( N ) = ZERO
DO 250 I = 1, N - 1, 2
B( I ) = ZERO
B( I+1 ) = SMLNUM*ZLARND( 5, ISEED )
250 CONTINUE
END IF
*
ELSE IF( IMAT.EQ.15 ) THEN
*
* Type 15: Make the diagonal elements small to cause gradual
* overflow when dividing by T(j,j). To control the amount of
* scaling needed, the matrix is bidiagonal.
*
TEXP = ONE / MAX( ONE, DBLE( N-1 ) )
TSCAL = SMLNUM**TEXP
CALL ZLARNV( 4, ISEED, N, B )
IF( UPPER ) THEN
DO 270 J = 1, N
DO 260 I = 1, J - 2
A( I, J ) = 0.D0
260 CONTINUE
IF( J.GT.1 )
$ A( J-1, J ) = DCMPLX( -ONE, -ONE )
A( J, J ) = TSCAL*ZLARND( 5, ISEED )
270 CONTINUE
B( N ) = DCMPLX( ONE, ONE )
ELSE
DO 290 J = 1, N
DO 280 I = J + 2, N
A( I, J ) = 0.D0
280 CONTINUE
IF( J.LT.N )
$ A( J+1, J ) = DCMPLX( -ONE, -ONE )
A( J, J ) = TSCAL*ZLARND( 5, ISEED )
290 CONTINUE
B( 1 ) = DCMPLX( ONE, ONE )
END IF
*
ELSE IF( IMAT.EQ.16 ) THEN
*
* Type 16: One zero diagonal element.
*
IY = N / 2 + 1
IF( UPPER ) THEN
DO 300 J = 1, N
CALL ZLARNV( 4, ISEED, J-1, A( 1, J ) )
IF( J.NE.IY ) THEN
A( J, J ) = ZLARND( 5, ISEED )*TWO
ELSE
A( J, J ) = ZERO
END IF
300 CONTINUE
ELSE
DO 310 J = 1, N
IF( J.LT.N )
$ CALL ZLARNV( 4, ISEED, N-J, A( J+1, J ) )
IF( J.NE.IY ) THEN
A( J, J ) = ZLARND( 5, ISEED )*TWO
ELSE
A( J, J ) = ZERO
END IF
310 CONTINUE
END IF
CALL ZLARNV( 2, ISEED, N, B )
CALL ZDSCAL( N, TWO, B, 1 )
*
ELSE IF( IMAT.EQ.17 ) THEN
*
* Type 17: Make the offdiagonal elements large to cause overflow
* when adding a column of T. In the non-transposed case, the
* matrix is constructed to cause overflow when adding a column in
* every other step.
*
TSCAL = UNFL / ULP
TSCAL = ( ONE-ULP ) / TSCAL
DO 330 J = 1, N
DO 320 I = 1, N
A( I, J ) = 0.D0
320 CONTINUE
330 CONTINUE
TEXP = ONE
IF( UPPER ) THEN
DO 340 J = N, 2, -2
A( 1, J ) = -TSCAL / DBLE( N+1 )
A( J, J ) = ONE
B( J ) = TEXP*( ONE-ULP )
A( 1, J-1 ) = -( TSCAL / DBLE( N+1 ) ) / DBLE( N+2 )
A( J-1, J-1 ) = ONE
B( J-1 ) = TEXP*DBLE( N*N+N-1 )
TEXP = TEXP*2.D0
340 CONTINUE
B( 1 ) = ( DBLE( N+1 ) / DBLE( N+2 ) )*TSCAL
ELSE
DO 350 J = 1, N - 1, 2
A( N, J ) = -TSCAL / DBLE( N+1 )
A( J, J ) = ONE
B( J ) = TEXP*( ONE-ULP )
A( N, J+1 ) = -( TSCAL / DBLE( N+1 ) ) / DBLE( N+2 )
A( J+1, J+1 ) = ONE
B( J+1 ) = TEXP*DBLE( N*N+N-1 )
TEXP = TEXP*2.D0
350 CONTINUE
B( N ) = ( DBLE( N+1 ) / DBLE( N+2 ) )*TSCAL
END IF
*
ELSE IF( IMAT.EQ.18 ) THEN
*
* Type 18: Generate a unit triangular matrix with elements
* between -1 and 1, and make the right hand side large so that it
* requires scaling.
*
IF( UPPER ) THEN
DO 360 J = 1, N
CALL ZLARNV( 4, ISEED, J-1, A( 1, J ) )
A( J, J ) = ZERO
360 CONTINUE
ELSE
DO 370 J = 1, N
IF( J.LT.N )
$ CALL ZLARNV( 4, ISEED, N-J, A( J+1, J ) )
A( J, J ) = ZERO
370 CONTINUE
END IF
*
* Set the right hand side so that the largest value is BIGNUM.
*
CALL ZLARNV( 2, ISEED, N, B )
IY = IZAMAX( N, B, 1 )
BNORM = ABS( B( IY ) )
BSCAL = BIGNUM / MAX( ONE, BNORM )
CALL ZDSCAL( N, BSCAL, B, 1 )
*
ELSE IF( IMAT.EQ.19 ) THEN
*
* Type 19: Generate a triangular matrix with elements between
* BIGNUM/(n-1) and BIGNUM so that at least one of the column
* norms will exceed BIGNUM.
* 1/3/91: ZLATRS no longer can handle this case
*
TLEFT = BIGNUM / MAX( ONE, DBLE( N-1 ) )
TSCAL = BIGNUM*( DBLE( N-1 ) / MAX( ONE, DBLE( N ) ) )
IF( UPPER ) THEN
DO 390 J = 1, N
CALL ZLARNV( 5, ISEED, J, A( 1, J ) )
CALL DLARNV( 1, ISEED, J, RWORK )
DO 380 I = 1, J
A( I, J ) = A( I, J )*( TLEFT+RWORK( I )*TSCAL )
380 CONTINUE
390 CONTINUE
ELSE
DO 410 J = 1, N
CALL ZLARNV( 5, ISEED, N-J+1, A( J, J ) )
CALL DLARNV( 1, ISEED, N-J+1, RWORK )
DO 400 I = J, N
A( I, J ) = A( I, J )*( TLEFT+RWORK( I-J+1 )*TSCAL )
400 CONTINUE
410 CONTINUE
END IF
CALL ZLARNV( 2, ISEED, N, B )
CALL ZDSCAL( N, TWO, B, 1 )
END IF
*
* Flip the matrix if the transpose will be used.
*
IF( .NOT.LSAME( TRANS, 'N' ) ) THEN
IF( UPPER ) THEN
DO 420 J = 1, N / 2
CALL ZSWAP( N-2*J+1, A( J, J ), LDA, A( J+1, N-J+1 ),
$ -1 )
420 CONTINUE
ELSE
DO 430 J = 1, N / 2
CALL ZSWAP( N-2*J+1, A( J, J ), 1, A( N-J+1, J+1 ),
$ -LDA )
430 CONTINUE
END IF
END IF
*
RETURN
*
* End of ZLATTR
*
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?