101
102
103
104
105
106
107 INTEGER INFO, K, LDA, N
108
109
110 INTEGER ISEED( 4 )
111 REAL A( LDA, * ), D( * ), WORK( * )
112
113
114
115
116
117 REAL ZERO, ONE, HALF
118 parameter( zero = 0.0e+0, one = 1.0e+0, half = 0.5e+0 )
119
120
121 INTEGER I, J
122 REAL ALPHA, TAU, WA, WB, WN
123
124
127
128
129 REAL SDOT, SNRM2
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(
'SLAGSY', -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 slarnv( 3, iseed, n-i+1, work )
170 wn =
snrm2( 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 sscal( 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 ssymv(
'Lower', n-i+1, tau, a( i, i ), lda, work, 1, zero,
187 $ work( n+1 ), 1 )
188
189
190
191 alpha = -half*tau*
sdot( n-i+1, work( n+1 ), 1, work, 1 )
192 CALL saxpy( n-i+1, alpha, work, 1, work( n+1 ), 1 )
193
194
195
196 CALL ssyr2(
'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 =
snrm2( 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 sscal( 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 sgemv(
'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 sger( 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 ssymv(
'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*
sdot( n-k-i+1, work, 1, a( k+i, i ), 1 )
234 CALL saxpy( n-k-i+1, alpha, a( k+i, i ), 1, work, 1 )
235
236
237
238 CALL ssyr2(
'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 saxpy(n, sa, sx, incx, sy, incy)
SAXPY
real function sdot(n, sx, incx, sy, incy)
SDOT
subroutine sgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
SGEMV
subroutine sger(m, n, alpha, x, incx, y, incy, a, lda)
SGER
subroutine ssymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
SSYMV
subroutine ssyr2(uplo, n, alpha, x, incx, y, incy, a, lda)
SSYR2
subroutine slarnv(idist, iseed, n, x)
SLARNV returns a vector of random numbers from a uniform or normal distribution.
real(wp) function snrm2(n, x, incx)
SNRM2
subroutine sscal(n, sa, sx, incx)
SSCAL