101
102
103
104
105
106
107 INTEGER INFO, K, LDA, N
108
109
110 INTEGER ISEED( 4 )
111 DOUBLE PRECISION A( LDA, * ), D( * ), WORK( * )
112
113
114
115
116
117 DOUBLE PRECISION ZERO, ONE, HALF
118 parameter( zero = 0.0d+0, one = 1.0d+0, half = 0.5d+0 )
119
120
121 INTEGER I, J
122 DOUBLE PRECISION ALPHA, TAU, WA, WB, WN
123
124
127
128
129 DOUBLE PRECISION DDOT, DNRM2
131
132
133 INTRINSIC max, sign
134
135
136
137
138
139 info = 0
140 IF( n.LT.0 ) THEN
141 info = -1
142 ELSE IF( k.LT.0 .OR. k.GT.n-1 ) THEN
143 info = -2
144 ELSE IF( lda.LT.max( 1, n ) ) THEN
145 info = -5
146 END IF
147 IF( info.LT.0 ) THEN
148 CALL xerbla(
'DLAGSY', -info )
149 RETURN
150 END IF
151
152
153
154 DO 20 j = 1, n
155 DO 10 i = j + 1, n
156 a( i, j ) = zero
157 10 CONTINUE
158 20 CONTINUE
159 DO 30 i = 1, n
160 a( i, i ) = d( i )
161 30 CONTINUE
162
163
164
165 DO 40 i = n - 1, 1, -1
166
167
168
169 CALL dlarnv( 3, iseed, n-i+1, work )
170 wn =
dnrm2( n-i+1, work, 1 )
171 wa = sign( wn, work( 1 ) )
172 IF( wn.EQ.zero ) THEN
173 tau = zero
174 ELSE
175 wb = work( 1 ) + wa
176 CALL dscal( n-i, one / wb, work( 2 ), 1 )
177 work( 1 ) = one
178 tau = wb / wa
179 END IF
180
181
182
183
184
185
186 CALL dsymv(
'Lower', n-i+1, tau, a( i, i ), lda, work, 1, zero,
187 $ work( n+1 ), 1 )
188
189
190
191 alpha = -half*tau*
ddot( n-i+1, work( n+1 ), 1, work, 1 )
192 CALL daxpy( n-i+1, alpha, work, 1, work( n+1 ), 1 )
193
194
195
196 CALL dsyr2(
'Lower', n-i+1, -one, work, 1, work( n+1 ), 1,
197 $ a( i, i ), lda )
198 40 CONTINUE
199
200
201
202 DO 60 i = 1, n - 1 - k
203
204
205
206 wn =
dnrm2( n-k-i+1, a( k+i, i ), 1 )
207 wa = sign( wn, a( k+i, i ) )
208 IF( wn.EQ.zero ) THEN
209 tau = zero
210 ELSE
211 wb = a( k+i, i ) + wa
212 CALL dscal( n-k-i, one / wb, a( k+i+1, i ), 1 )
213 a( k+i, i ) = one
214 tau = wb / wa
215 END IF
216
217
218
219 CALL dgemv(
'Transpose', n-k-i+1, k-1, one, a( k+i, i+1 ), lda,
220 $ a( k+i, i ), 1, zero, work, 1 )
221 CALL dger( n-k-i+1, k-1, -tau, a( k+i, i ), 1, work, 1,
222 $ a( k+i, i+1 ), lda )
223
224
225
226
227
228 CALL dsymv(
'Lower', n-k-i+1, tau, a( k+i, k+i ), lda,
229 $ a( k+i, i ), 1, zero, work, 1 )
230
231
232
233 alpha = -half*tau*
ddot( n-k-i+1, work, 1, a( k+i, i ), 1 )
234 CALL daxpy( n-k-i+1, alpha, a( k+i, i ), 1, work, 1 )
235
236
237
238 CALL dsyr2(
'Lower', n-k-i+1, -one, a( k+i, i ), 1, work, 1,
239 $ a( k+i, k+i ), lda )
240
241 a( k+i, i ) = -wa
242 DO 50 j = k + i + 1, n
243 a( j, i ) = zero
244 50 CONTINUE
245 60 CONTINUE
246
247
248
249 DO 80 j = 1, n
250 DO 70 i = j + 1, n
251 a( j, i ) = a( i, j )
252 70 CONTINUE
253 80 CONTINUE
254 RETURN
255
256
257
subroutine xerbla(srname, info)
subroutine daxpy(n, da, dx, incx, dy, incy)
DAXPY
double precision function ddot(n, dx, incx, dy, incy)
DDOT
subroutine dgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
DGEMV
subroutine dger(m, n, alpha, x, incx, y, incy, a, lda)
DGER
subroutine dsymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
DSYMV
subroutine dsyr2(uplo, n, alpha, x, incx, y, incy, a, lda)
DSYR2
subroutine dlarnv(idist, iseed, n, x)
DLARNV returns a vector of random numbers from a uniform or normal distribution.
real(wp) function dnrm2(n, x, incx)
DNRM2
subroutine dscal(n, da, dx, incx)
DSCAL