2
3
4
5
6
7
8 INTEGER INFO, K, LDA, N
9
10
11 INTEGER ISEED( 4 )
12 DOUBLE PRECISION D( * )
13 COMPLEX*16 A( LDA, * ), WORK( * )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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
65 INTEGER I, II, J, JJ
66 DOUBLE PRECISION WN
67 COMPLEX*16 ALPHA, TAU, WA, WB, DOTC
68
69
70 EXTERNAL xerbla, zaxpy, zgemv, zgerc, zlacgv,
zlarnv,
72
73
74 DOUBLE PRECISION DZNRM2
75 EXTERNAL dznrm2
76
77
78 INTRINSIC abs, dble,
max
79
80
81
82
83
84 info = 0
85 IF( n.LT.0 ) THEN
86 info = -1
87 ELSE IF( k.LT.0 .OR. k.GT.n-1 ) THEN
88 info = -2
89 ELSE IF( lda.LT.
max( 1, n ) )
THEN
90 info = -5
91 END IF
92 IF( info.LT.0 ) THEN
93 CALL xerbla( 'ZLAGSY', -info )
94 RETURN
95 END IF
96
97
98
99 DO 20 j = 1, n
100 DO 10 i = j + 1, n
101 a( i, j ) = zero
102 10 CONTINUE
103 20 CONTINUE
104 DO 30 i = 1, n
105 a( i, i ) = d( i )
106 30 CONTINUE
107
108
109
110 DO 60 i = n - 1, 1, -1
111
112
113
114 CALL zlarnv( 3, iseed, n-i+1, work )
115 wn = dznrm2( n-i+1, work, 1 )
116 wa = ( wn / abs( work( 1 ) ) )*work( 1 )
117 IF( wn.EQ.zero ) THEN
118 tau = zero
119 ELSE
120 wb = work( 1 ) + wa
121 CALL zscal( n-i, one / wb, work( 2 ), 1 )
122 work( 1 ) = one
123 tau = dble( wb / wa )
124 END IF
125
126
127
128
129
130
131 CALL zlacgv( n-i+1, work, 1 )
132 CALL zsymv(
'Lower', n-i+1, tau, a( i, i ), lda, work, 1, zero,
133 $ work( n+1 ), 1 )
134 CALL zlacgv( n-i+1, work, 1 )
135
136
137
138 CALL zzdotc( n-i+1, dotc, work, 1, work( n+1 ), 1 )
139 alpha = -half*tau*dotc
140 CALL zaxpy( n-i+1, alpha, work, 1, work( n+1 ), 1 )
141
142
143
144
145
146
147 DO 50 jj = i, n
148 DO 40 ii = jj, n
149 a( ii, jj ) = a( ii, jj ) -
150 $ work( ii-i+1 )*work( n+jj-i+1 ) -
151 $ work( n+ii-i+1 )*work( jj-i+1 )
152 40 CONTINUE
153 50 CONTINUE
154 60 CONTINUE
155
156
157
158 DO 100 i = 1, n - 1 - k
159
160
161
162 wn = dznrm2( n-k-i+1, a( k+i, i ), 1 )
163 wa = ( wn / abs( a( k+i, i ) ) )*a( k+i, i )
164 IF( wn.EQ.zero ) THEN
165 tau = zero
166 ELSE
167 wb = a( k+i, i ) + wa
168 CALL zscal( n-k-i, one / wb, a( k+i+1, i ), 1 )
169 a( k+i, i ) = one
170 tau = dble( wb / wa )
171 END IF
172
173
174
175 CALL zgemv( 'Conjugate transpose', n-k-i+1, k-1, one,
176 $ a( k+i, i+1 ), lda, a( k+i, i ), 1, zero, work, 1 )
177 CALL zgerc( n-k-i+1, k-1, -tau, a( k+i, i ), 1, work, 1,
178 $ a( k+i, i+1 ), lda )
179
180
181
182
183
184 CALL zlacgv( n-k-i+1, a( k+i, i ), 1 )
185 CALL zsymv(
'Lower', n-k-i+1, tau, a( k+i, k+i ), lda,
186 $ a( k+i, i ), 1, zero, work, 1 )
187 CALL zlacgv( n-k-i+1, a( k+i, i ), 1 )
188
189
190
191 CALL zzdotc( n-k-i+1, dotc, a( k+i, i ), 1, work, 1 )
192 alpha = -half*tau*dotc
193 CALL zaxpy( n-k-i+1, alpha, a( k+i, i ), 1, work, 1 )
194
195
196
197
198
199
200 DO 80 jj = k + i, n
201 DO 70 ii = jj, n
202 a( ii, jj ) = a( ii, jj ) - a( ii, i )*work( jj-k-i+1 ) -
203 $ work( ii-k-i+1 )*a( jj, i )
204 70 CONTINUE
205 80 CONTINUE
206
207 a( k+i, i ) = -wa
208 DO 90 j = k + i + 1, n
209 a( j, i ) = zero
210 90 CONTINUE
211 100 CONTINUE
212
213
214
215 DO 120 j = 1, n
216 DO 110 i = j + 1, n
217 a( j, i ) = a( i, j )
218 110 CONTINUE
219 120 CONTINUE
220 RETURN
221
222
223
subroutine zlarnv(idist, iseed, n, x)
subroutine zsymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
subroutine zzdotc(n, dotc, x, incx, y, incy)