1 SUBROUTINE ZLAGHE( N, K, D, A, LDA, ISEED, WORK, INFO )
2 *
3 * -- LAPACK auxiliary test routine (version 3.1) --
4 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
5 * November 2006
6 *
7 * .. Scalar Arguments ..
8 INTEGER INFO, K, LDA, N
9 * ..
10 * .. Array Arguments ..
11 INTEGER ISEED( 4 )
12 DOUBLE PRECISION D( * )
13 COMPLEX*16 A( LDA, * ), WORK( * )
14 * ..
15 *
16 * Purpose
17 * =======
18 *
19 * ZLAGHE generates a complex hermitian matrix A, by pre- and post-
20 * multiplying a real diagonal matrix D with a random unitary matrix:
21 * A = U*D*U'. The semi-bandwidth may then be reduced to k by additional
22 * unitary transformations.
23 *
24 * Arguments
25 * =========
26 *
27 * N (input) INTEGER
28 * The order of the matrix A. N >= 0.
29 *
30 * K (input) INTEGER
31 * The number of nonzero subdiagonals within the band of A.
32 * 0 <= K <= N-1.
33 *
34 * D (input) DOUBLE PRECISION array, dimension (N)
35 * The diagonal elements of the diagonal matrix D.
36 *
37 * A (output) COMPLEX*16 array, dimension (LDA,N)
38 * The generated n by n hermitian matrix A (the full matrix is
39 * stored).
40 *
41 * LDA (input) INTEGER
42 * The leading dimension of the array A. LDA >= N.
43 *
44 * ISEED (input/output) INTEGER array, dimension (4)
45 * On entry, the seed of the random number generator; the array
46 * elements must be between 0 and 4095, and ISEED(4) must be
47 * odd.
48 * On exit, the seed is updated.
49 *
50 * WORK (workspace) COMPLEX*16 array, dimension (2*N)
51 *
52 * INFO (output) INTEGER
53 * = 0: successful exit
54 * < 0: if INFO = -i, the i-th argument had an illegal value
55 *
56 * =====================================================================
57 *
58 * .. Parameters ..
59 COMPLEX*16 ZERO, ONE, HALF
60 PARAMETER ( ZERO = ( 0.0D+0, 0.0D+0 ),
61 $ ONE = ( 1.0D+0, 0.0D+0 ),
62 $ HALF = ( 0.5D+0, 0.0D+0 ) )
63 * ..
64 * .. Local Scalars ..
65 INTEGER I, J
66 DOUBLE PRECISION WN
67 COMPLEX*16 ALPHA, TAU, WA, WB
68 * ..
69 * .. External Subroutines ..
70 EXTERNAL XERBLA, ZAXPY, ZGEMV, ZGERC, ZHEMV, ZHER2,
71 $ ZLARNV, ZSCAL
72 * ..
73 * .. External Functions ..
74 DOUBLE PRECISION DZNRM2
75 COMPLEX*16 ZDOTC
76 EXTERNAL DZNRM2, ZDOTC
77 * ..
78 * .. Intrinsic Functions ..
79 INTRINSIC ABS, DBLE, DCONJG, MAX
80 * ..
81 * .. Executable Statements ..
82 *
83 * Test the input arguments
84 *
85 INFO = 0
86 IF( N.LT.0 ) THEN
87 INFO = -1
88 ELSE IF( K.LT.0 .OR. K.GT.N-1 ) THEN
89 INFO = -2
90 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
91 INFO = -5
92 END IF
93 IF( INFO.LT.0 ) THEN
94 CALL XERBLA( 'ZLAGHE', -INFO )
95 RETURN
96 END IF
97 *
98 * initialize lower triangle of A to diagonal matrix
99 *
100 DO 20 J = 1, N
101 DO 10 I = J + 1, N
102 A( I, J ) = ZERO
103 10 CONTINUE
104 20 CONTINUE
105 DO 30 I = 1, N
106 A( I, I ) = D( I )
107 30 CONTINUE
108 *
109 * Generate lower triangle of hermitian matrix
110 *
111 DO 40 I = N - 1, 1, -1
112 *
113 * generate random reflection
114 *
115 CALL ZLARNV( 3, ISEED, N-I+1, WORK )
116 WN = DZNRM2( N-I+1, WORK, 1 )
117 WA = ( WN / ABS( WORK( 1 ) ) )*WORK( 1 )
118 IF( WN.EQ.ZERO ) THEN
119 TAU = ZERO
120 ELSE
121 WB = WORK( 1 ) + WA
122 CALL ZSCAL( N-I, ONE / WB, WORK( 2 ), 1 )
123 WORK( 1 ) = ONE
124 TAU = DBLE( WB / WA )
125 END IF
126 *
127 * apply random reflection to A(i:n,i:n) from the left
128 * and the right
129 *
130 * compute y := tau * A * u
131 *
132 CALL ZHEMV( 'Lower', N-I+1, TAU, A( I, I ), LDA, WORK, 1, ZERO,
133 $ WORK( N+1 ), 1 )
134 *
135 * compute v := y - 1/2 * tau * ( y, u ) * u
136 *
137 ALPHA = -HALF*TAU*ZDOTC( N-I+1, WORK( N+1 ), 1, WORK, 1 )
138 CALL ZAXPY( N-I+1, ALPHA, WORK, 1, WORK( N+1 ), 1 )
139 *
140 * apply the transformation as a rank-2 update to A(i:n,i:n)
141 *
142 CALL ZHER2( 'Lower', N-I+1, -ONE, WORK, 1, WORK( N+1 ), 1,
143 $ A( I, I ), LDA )
144 40 CONTINUE
145 *
146 * Reduce number of subdiagonals to K
147 *
148 DO 60 I = 1, N - 1 - K
149 *
150 * generate reflection to annihilate A(k+i+1:n,i)
151 *
152 WN = DZNRM2( N-K-I+1, A( K+I, I ), 1 )
153 WA = ( WN / ABS( A( K+I, I ) ) )*A( K+I, I )
154 IF( WN.EQ.ZERO ) THEN
155 TAU = ZERO
156 ELSE
157 WB = A( K+I, I ) + WA
158 CALL ZSCAL( N-K-I, ONE / WB, A( K+I+1, I ), 1 )
159 A( K+I, I ) = ONE
160 TAU = DBLE( WB / WA )
161 END IF
162 *
163 * apply reflection to A(k+i:n,i+1:k+i-1) from the left
164 *
165 CALL ZGEMV( 'Conjugate transpose', N-K-I+1, K-1, ONE,
166 $ A( K+I, I+1 ), LDA, A( K+I, I ), 1, ZERO, WORK, 1 )
167 CALL ZGERC( N-K-I+1, K-1, -TAU, A( K+I, I ), 1, WORK, 1,
168 $ A( K+I, I+1 ), LDA )
169 *
170 * apply reflection to A(k+i:n,k+i:n) from the left and the right
171 *
172 * compute y := tau * A * u
173 *
174 CALL ZHEMV( 'Lower', N-K-I+1, TAU, A( K+I, K+I ), LDA,
175 $ A( K+I, I ), 1, ZERO, WORK, 1 )
176 *
177 * compute v := y - 1/2 * tau * ( y, u ) * u
178 *
179 ALPHA = -HALF*TAU*ZDOTC( N-K-I+1, WORK, 1, A( K+I, I ), 1 )
180 CALL ZAXPY( N-K-I+1, ALPHA, A( K+I, I ), 1, WORK, 1 )
181 *
182 * apply hermitian rank-2 update to A(k+i:n,k+i:n)
183 *
184 CALL ZHER2( 'Lower', N-K-I+1, -ONE, A( K+I, I ), 1, WORK, 1,
185 $ A( K+I, K+I ), LDA )
186 *
187 A( K+I, I ) = -WA
188 DO 50 J = K + I + 1, N
189 A( J, I ) = ZERO
190 50 CONTINUE
191 60 CONTINUE
192 *
193 * Store full hermitian matrix
194 *
195 DO 80 J = 1, N
196 DO 70 I = J + 1, N
197 A( J, I ) = DCONJG( A( I, J ) )
198 70 CONTINUE
199 80 CONTINUE
200 RETURN
201 *
202 * End of ZLAGHE
203 *
204 END
2 *
3 * -- LAPACK auxiliary test routine (version 3.1) --
4 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
5 * November 2006
6 *
7 * .. Scalar Arguments ..
8 INTEGER INFO, K, LDA, N
9 * ..
10 * .. Array Arguments ..
11 INTEGER ISEED( 4 )
12 DOUBLE PRECISION D( * )
13 COMPLEX*16 A( LDA, * ), WORK( * )
14 * ..
15 *
16 * Purpose
17 * =======
18 *
19 * ZLAGHE generates a complex hermitian matrix A, by pre- and post-
20 * multiplying a real diagonal matrix D with a random unitary matrix:
21 * A = U*D*U'. The semi-bandwidth may then be reduced to k by additional
22 * unitary transformations.
23 *
24 * Arguments
25 * =========
26 *
27 * N (input) INTEGER
28 * The order of the matrix A. N >= 0.
29 *
30 * K (input) INTEGER
31 * The number of nonzero subdiagonals within the band of A.
32 * 0 <= K <= N-1.
33 *
34 * D (input) DOUBLE PRECISION array, dimension (N)
35 * The diagonal elements of the diagonal matrix D.
36 *
37 * A (output) COMPLEX*16 array, dimension (LDA,N)
38 * The generated n by n hermitian matrix A (the full matrix is
39 * stored).
40 *
41 * LDA (input) INTEGER
42 * The leading dimension of the array A. LDA >= N.
43 *
44 * ISEED (input/output) INTEGER array, dimension (4)
45 * On entry, the seed of the random number generator; the array
46 * elements must be between 0 and 4095, and ISEED(4) must be
47 * odd.
48 * On exit, the seed is updated.
49 *
50 * WORK (workspace) COMPLEX*16 array, dimension (2*N)
51 *
52 * INFO (output) INTEGER
53 * = 0: successful exit
54 * < 0: if INFO = -i, the i-th argument had an illegal value
55 *
56 * =====================================================================
57 *
58 * .. Parameters ..
59 COMPLEX*16 ZERO, ONE, HALF
60 PARAMETER ( ZERO = ( 0.0D+0, 0.0D+0 ),
61 $ ONE = ( 1.0D+0, 0.0D+0 ),
62 $ HALF = ( 0.5D+0, 0.0D+0 ) )
63 * ..
64 * .. Local Scalars ..
65 INTEGER I, J
66 DOUBLE PRECISION WN
67 COMPLEX*16 ALPHA, TAU, WA, WB
68 * ..
69 * .. External Subroutines ..
70 EXTERNAL XERBLA, ZAXPY, ZGEMV, ZGERC, ZHEMV, ZHER2,
71 $ ZLARNV, ZSCAL
72 * ..
73 * .. External Functions ..
74 DOUBLE PRECISION DZNRM2
75 COMPLEX*16 ZDOTC
76 EXTERNAL DZNRM2, ZDOTC
77 * ..
78 * .. Intrinsic Functions ..
79 INTRINSIC ABS, DBLE, DCONJG, MAX
80 * ..
81 * .. Executable Statements ..
82 *
83 * Test the input arguments
84 *
85 INFO = 0
86 IF( N.LT.0 ) THEN
87 INFO = -1
88 ELSE IF( K.LT.0 .OR. K.GT.N-1 ) THEN
89 INFO = -2
90 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
91 INFO = -5
92 END IF
93 IF( INFO.LT.0 ) THEN
94 CALL XERBLA( 'ZLAGHE', -INFO )
95 RETURN
96 END IF
97 *
98 * initialize lower triangle of A to diagonal matrix
99 *
100 DO 20 J = 1, N
101 DO 10 I = J + 1, N
102 A( I, J ) = ZERO
103 10 CONTINUE
104 20 CONTINUE
105 DO 30 I = 1, N
106 A( I, I ) = D( I )
107 30 CONTINUE
108 *
109 * Generate lower triangle of hermitian matrix
110 *
111 DO 40 I = N - 1, 1, -1
112 *
113 * generate random reflection
114 *
115 CALL ZLARNV( 3, ISEED, N-I+1, WORK )
116 WN = DZNRM2( N-I+1, WORK, 1 )
117 WA = ( WN / ABS( WORK( 1 ) ) )*WORK( 1 )
118 IF( WN.EQ.ZERO ) THEN
119 TAU = ZERO
120 ELSE
121 WB = WORK( 1 ) + WA
122 CALL ZSCAL( N-I, ONE / WB, WORK( 2 ), 1 )
123 WORK( 1 ) = ONE
124 TAU = DBLE( WB / WA )
125 END IF
126 *
127 * apply random reflection to A(i:n,i:n) from the left
128 * and the right
129 *
130 * compute y := tau * A * u
131 *
132 CALL ZHEMV( 'Lower', N-I+1, TAU, A( I, I ), LDA, WORK, 1, ZERO,
133 $ WORK( N+1 ), 1 )
134 *
135 * compute v := y - 1/2 * tau * ( y, u ) * u
136 *
137 ALPHA = -HALF*TAU*ZDOTC( N-I+1, WORK( N+1 ), 1, WORK, 1 )
138 CALL ZAXPY( N-I+1, ALPHA, WORK, 1, WORK( N+1 ), 1 )
139 *
140 * apply the transformation as a rank-2 update to A(i:n,i:n)
141 *
142 CALL ZHER2( 'Lower', N-I+1, -ONE, WORK, 1, WORK( N+1 ), 1,
143 $ A( I, I ), LDA )
144 40 CONTINUE
145 *
146 * Reduce number of subdiagonals to K
147 *
148 DO 60 I = 1, N - 1 - K
149 *
150 * generate reflection to annihilate A(k+i+1:n,i)
151 *
152 WN = DZNRM2( N-K-I+1, A( K+I, I ), 1 )
153 WA = ( WN / ABS( A( K+I, I ) ) )*A( K+I, I )
154 IF( WN.EQ.ZERO ) THEN
155 TAU = ZERO
156 ELSE
157 WB = A( K+I, I ) + WA
158 CALL ZSCAL( N-K-I, ONE / WB, A( K+I+1, I ), 1 )
159 A( K+I, I ) = ONE
160 TAU = DBLE( WB / WA )
161 END IF
162 *
163 * apply reflection to A(k+i:n,i+1:k+i-1) from the left
164 *
165 CALL ZGEMV( 'Conjugate transpose', N-K-I+1, K-1, ONE,
166 $ A( K+I, I+1 ), LDA, A( K+I, I ), 1, ZERO, WORK, 1 )
167 CALL ZGERC( N-K-I+1, K-1, -TAU, A( K+I, I ), 1, WORK, 1,
168 $ A( K+I, I+1 ), LDA )
169 *
170 * apply reflection to A(k+i:n,k+i:n) from the left and the right
171 *
172 * compute y := tau * A * u
173 *
174 CALL ZHEMV( 'Lower', N-K-I+1, TAU, A( K+I, K+I ), LDA,
175 $ A( K+I, I ), 1, ZERO, WORK, 1 )
176 *
177 * compute v := y - 1/2 * tau * ( y, u ) * u
178 *
179 ALPHA = -HALF*TAU*ZDOTC( N-K-I+1, WORK, 1, A( K+I, I ), 1 )
180 CALL ZAXPY( N-K-I+1, ALPHA, A( K+I, I ), 1, WORK, 1 )
181 *
182 * apply hermitian rank-2 update to A(k+i:n,k+i:n)
183 *
184 CALL ZHER2( 'Lower', N-K-I+1, -ONE, A( K+I, I ), 1, WORK, 1,
185 $ A( K+I, K+I ), LDA )
186 *
187 A( K+I, I ) = -WA
188 DO 50 J = K + I + 1, N
189 A( J, I ) = ZERO
190 50 CONTINUE
191 60 CONTINUE
192 *
193 * Store full hermitian matrix
194 *
195 DO 80 J = 1, N
196 DO 70 I = J + 1, N
197 A( J, I ) = DCONJG( A( I, J ) )
198 70 CONTINUE
199 80 CONTINUE
200 RETURN
201 *
202 * End of ZLAGHE
203 *
204 END