132
133
134
135
136
137 IMPLICIT NONE
138
139
140 CHARACTER UPLO
141 INTEGER N, LDA, LWORK, INFO
142
143
144 INTEGER IPIV( * )
145 REAL A( LDA, * ), WORK( * )
146
147
148
149
150 REAL ZERO, ONE
151 parameter( zero = 0.0e+0, one = 1.0e+0 )
152
153
154 LOGICAL LQUERY, UPPER
155 INTEGER J, LWKOPT
156 INTEGER NB, MJ, NJ, K1, K2, J1, J2, J3, JB
157 REAL ALPHA
158
159
160 LOGICAL LSAME
161 INTEGER ILAENV
162 REAL SROUNDUP_LWORK
164
165
168
169
170 INTRINSIC max
171
172
173
174
175
176 nb =
ilaenv( 1,
'SSYTRF_AA', uplo, n, -1, -1, -1 )
177
178
179
180 info = 0
181 upper =
lsame( uplo,
'U' )
182 lquery = ( lwork.EQ.-1 )
183 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
184 info = -1
185 ELSE IF( n.LT.0 ) THEN
186 info = -2
187 ELSE IF( lda.LT.max( 1, n ) ) THEN
188 info = -4
189 ELSE IF( lwork.LT.max( 1, 2*n ) .AND. .NOT.lquery ) THEN
190 info = -7
191 END IF
192
193 IF( info.EQ.0 ) THEN
194 lwkopt = (nb+1)*n
196 END IF
197
198 IF( info.NE.0 ) THEN
199 CALL xerbla(
'SSYTRF_AA', -info )
200 RETURN
201 ELSE IF( lquery ) THEN
202 RETURN
203 END IF
204
205
206
207 IF ( n.EQ.0 ) THEN
208 RETURN
209 ENDIF
210 ipiv( 1 ) = 1
211 IF ( n.EQ.1 ) THEN
212 RETURN
213 END IF
214
215
216
217 IF( lwork.LT.((1+nb)*n) ) THEN
218 nb = ( lwork-n ) / n
219 END IF
220
221 IF( upper ) THEN
222
223
224
225
226
227
228
229 CALL scopy( n, a( 1, 1 ), lda, work( 1 ), 1 )
230
231
232
233
234
235 j = 0
236 10 CONTINUE
237 IF( j.GE.n )
238 $ GO TO 20
239
240
241
242
243
244
245
246
247 j1 = j + 1
248 jb = min( n-j1+1, nb )
249 k1 = max(1, j)-j
250
251
252
254 $ a( max(1, j), j+1 ), lda,
255 $ ipiv( j+1 ), work, n, work( n*nb+1 ) )
256
257
258
259 DO j2 = j+2, min(n, j+jb+1)
260 ipiv( j2 ) = ipiv( j2 ) + j
261 IF( (j2.NE.ipiv(j2)) .AND. ((j1-k1).GT.2) ) THEN
262 CALL sswap( j1-k1-2, a( 1, j2 ), 1,
263 $ a( 1, ipiv(j2) ), 1 )
264 END IF
265 END DO
266 j = j + jb
267
268
269
270
271
272 IF( j.LT.n ) THEN
273
274
275
276 IF( j1.GT.1 .OR. jb.GT.1 ) THEN
277
278
279
280 alpha = a( j, j+1 )
281 a( j, j+1 ) = one
282 CALL scopy( n-j, a( j-1, j+1 ), lda,
283 $ work( (j+1-j1+1)+jb*n ), 1 )
284 CALL sscal( n-j, alpha, work( (j+1-j1+1)+jb*n ), 1 )
285
286
287
288
289
290 IF( j1.GT.1 ) THEN
291
292
293
294 k2 = 1
295 ELSE
296
297
298
299 k2 = 0
300
301
302
303 jb = jb - 1
304 END IF
305
306 DO j2 = j+1, n, nb
307 nj = min( nb, n-j2+1 )
308
309
310
311 j3 = j2
312 DO mj = nj-1, 1, -1
313 CALL sgemv(
'No transpose', mj, jb+1,
314 $ -one, work( j3-j1+1+k1*n ), n,
315 $ a( j1-k2, j3 ), 1,
316 $ one, a( j3, j3 ), lda )
317 j3 = j3 + 1
318 END DO
319
320
321
322 CALL sgemm(
'Transpose',
'Transpose',
323 $ nj, n-j3+1, jb+1,
324 $ -one, a( j1-k2, j2 ), lda,
325 $ work( j3-j1+1+k1*n ), n,
326 $ one, a( j2, j3 ), lda )
327 END DO
328
329
330
331 a( j, j+1 ) = alpha
332 END IF
333
334
335
336 CALL scopy( n-j, a( j+1, j+1 ), lda, work( 1 ), 1 )
337 END IF
338 GO TO 10
339 ELSE
340
341
342
343
344
345
346
347
348 CALL scopy( n, a( 1, 1 ), 1, work( 1 ), 1 )
349
350
351
352
353
354 j = 0
355 11 CONTINUE
356 IF( j.GE.n )
357 $ GO TO 20
358
359
360
361
362
363
364
365
366 j1 = j+1
367 jb = min( n-j1+1, nb )
368 k1 = max(1, j)-j
369
370
371
373 $ a( j+1, max(1, j) ), lda,
374 $ ipiv( j+1 ), work, n, work( n*nb+1 ) )
375
376
377
378 DO j2 = j+2, min(n, j+jb+1)
379 ipiv( j2 ) = ipiv( j2 ) + j
380 IF( (j2.NE.ipiv(j2)) .AND. ((j1-k1).GT.2) ) THEN
381 CALL sswap( j1-k1-2, a( j2, 1 ), lda,
382 $ a( ipiv(j2), 1 ), lda )
383 END IF
384 END DO
385 j = j + jb
386
387
388
389
390
391 IF( j.LT.n ) THEN
392
393
394
395 IF( j1.GT.1 .OR. jb.GT.1 ) THEN
396
397
398
399 alpha = a( j+1, j )
400 a( j+1, j ) = one
401 CALL scopy( n-j, a( j+1, j-1 ), 1,
402 $ work( (j+1-j1+1)+jb*n ), 1 )
403 CALL sscal( n-j, alpha, work( (j+1-j1+1)+jb*n ), 1 )
404
405
406
407
408
409 IF( j1.GT.1 ) THEN
410
411
412
413 k2 = 1
414 ELSE
415
416
417
418 k2 = 0
419
420
421
422 jb = jb - 1
423 END IF
424
425 DO j2 = j+1, n, nb
426 nj = min( nb, n-j2+1 )
427
428
429
430 j3 = j2
431 DO mj = nj-1, 1, -1
432 CALL sgemv(
'No transpose', mj, jb+1,
433 $ -one, work( j3-j1+1+k1*n ), n,
434 $ a( j3, j1-k2 ), lda,
435 $ one, a( j3, j3 ), 1 )
436 j3 = j3 + 1
437 END DO
438
439
440
441 CALL sgemm(
'No transpose',
'Transpose',
442 $ n-j3+1, nj, jb+1,
443 $ -one, work( j3-j1+1+k1*n ), n,
444 $ a( j2, j1-k2 ), lda,
445 $ one, a( j3, j2 ), lda )
446 END DO
447
448
449
450 a( j+1, j ) = alpha
451 END IF
452
453
454
455 CALL scopy( n-j, a( j+1, j+1 ), 1, work( 1 ), 1 )
456 END IF
457 GO TO 11
458 END IF
459
460 20 CONTINUE
462 RETURN
463
464
465
subroutine xerbla(srname, info)
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine sgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
SGEMV
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
subroutine slasyf_aa(uplo, j1, m, nb, a, lda, ipiv, h, ldh, work)
SLASYF_AA
logical function lsame(ca, cb)
LSAME
real function sroundup_lwork(lwork)
SROUNDUP_LWORK
subroutine sscal(n, sa, sx, incx)
SSCAL
subroutine sswap(n, sx, incx, sy, incy)
SSWAP