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