158
159
160
161
162
163 IMPLICIT NONE
164
165
166 CHARACTER UPLO
167 INTEGER N, LDA, LTB, LWORK, INFO
168
169
170 INTEGER IPIV( * ), IPIV2( * )
171 COMPLEX*16 A( LDA, * ), TB( * ), WORK( * )
172
173
174
175
176 COMPLEX*16 ZERO, ONE
177 parameter( zero = ( 0.0e+0, 0.0e+0 ),
178 $ one = ( 1.0e+0, 0.0e+0 ) )
179
180
181 LOGICAL UPPER, TQUERY, WQUERY
182 INTEGER I, J, K, I1, I2, TD
183 INTEGER LWKOPT, LDTB, NB, KB, JB, NT, IINFO
184 COMPLEX*16 PIV
185
186
187 LOGICAL LSAME
188 INTEGER ILAENV
190
191
195
196
197 INTRINSIC dconjg, min, max
198
199
200
201
202
203 info = 0
204 upper =
lsame( uplo,
'U' )
205 wquery = ( lwork.EQ.-1 )
206 tquery = ( ltb.EQ.-1 )
207 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
208 info = -1
209 ELSE IF( n.LT.0 ) THEN
210 info = -2
211 ELSE IF( lda.LT.max( 1, n ) ) THEN
212 info = -4
213 ELSE IF( ltb.LT.max( 1, 4*n ) .AND. .NOT.tquery ) THEN
214 info = -6
215 ELSE IF( lwork.LT.max( 1, n ) .AND. .NOT.wquery ) THEN
216 info = -10
217 END IF
218
219 IF( info.NE.0 ) THEN
220 CALL xerbla(
'ZHETRF_AA_2STAGE', -info )
221 RETURN
222 END IF
223
224
225
226 nb =
ilaenv( 1,
'ZHETRF_AA_2STAGE', uplo, n, -1, -1, -1 )
227 IF( info.EQ.0 ) THEN
228 IF( tquery ) THEN
229 tb( 1 ) = max( 1, (3*nb+1)*n )
230 END IF
231 IF( wquery ) THEN
232 work( 1 ) = max( 1, n*nb )
233 END IF
234 END IF
235 IF( tquery .OR. wquery ) THEN
236 RETURN
237 END IF
238
239
240
241 IF( n.EQ.0 ) THEN
242 RETURN
243 ENDIF
244
245
246
247 ldtb = ltb/n
248 IF( ldtb .LT. 3*nb+1 ) THEN
249 nb = (ldtb-1)/3
250 END IF
251 IF( lwork .LT. nb*n ) THEN
252 nb = lwork/n
253 END IF
254
255
256
257 nt = (n+nb-1)/nb
258 td = 2*nb
259 kb = min(nb, n)
260
261
262
263 DO j = 1, kb
264 ipiv( j ) = j
265 END DO
266
267
268
269 tb( 1 ) = nb
270
271 IF( upper ) THEN
272
273
274
275
276
277 DO j = 0, nt-1
278
279
280
281 kb = min(nb, n-j*nb)
282 DO i = 1, j-1
283 IF( i.EQ.1 ) THEN
284
285 IF( i .EQ. (j-1) ) THEN
286 jb = nb+kb
287 ELSE
288 jb = 2*nb
289 END IF
290 CALL zgemm(
'NoTranspose',
'NoTranspose',
291 $ nb, kb, jb,
292 $ one, tb( td+1 + (i*nb)*ldtb ), ldtb-1,
293 $ a( (i-1)*nb+1, j*nb+1 ), lda,
294 $ zero, work( i*nb+1 ), n )
295 ELSE
296
297 IF( i .EQ. (j-1) ) THEN
298 jb = 2*nb+kb
299 ELSE
300 jb = 3*nb
301 END IF
302 CALL zgemm(
'NoTranspose',
'NoTranspose',
303 $ nb, kb, jb,
304 $ one, tb( td+nb+1 + ((i-1)*nb)*ldtb ),
305 $ ldtb-1,
306 $ a( (i-2)*nb+1, j*nb+1 ), lda,
307 $ zero, work( i*nb+1 ), n )
308 END IF
309 END DO
310
311
312
313 CALL zlacpy(
'Upper', kb, kb, a( j*nb+1, j*nb+1 ), lda,
314 $ tb( td+1 + (j*nb)*ldtb ), ldtb-1 )
315 IF( j.GT.1 ) THEN
316
317 CALL zgemm(
'Conjugate transpose',
'NoTranspose',
318 $ kb, kb, (j-1)*nb,
319 $ -one, a( 1, j*nb+1 ), lda,
320 $ work( nb+1 ), n,
321 $ one, tb( td+1 + (j*nb)*ldtb ), ldtb-1 )
322
323 CALL zgemm(
'Conjugate transpose',
'NoTranspose',
324 $ kb, nb, kb,
325 $ one, a( (j-1)*nb+1, j*nb+1 ), lda,
326 $ tb( td+nb+1 + ((j-1)*nb)*ldtb ), ldtb-1,
327 $ zero, work( 1 ), n )
328 CALL zgemm(
'NoTranspose',
'NoTranspose',
329 $ kb, kb, nb,
330 $ -one, work( 1 ), n,
331 $ a( (j-2)*nb+1, j*nb+1 ), lda,
332 $ one, tb( td+1 + (j*nb)*ldtb ), ldtb-1 )
333 END IF
334 IF( j.GT.0 ) THEN
335 CALL zhegst( 1,
'Upper', kb,
336 $ tb( td+1 + (j*nb)*ldtb ), ldtb-1,
337 $ a( (j-1)*nb+1, j*nb+1 ), lda, iinfo )
338 END IF
339
340
341
342 DO i = 1, kb
343 tb( td+1 + (j*nb+i-1)*ldtb )
344 $ = real( tb( td+1 + (j*nb+i-1)*ldtb ) )
345 DO k = i+1, kb
346 tb( td+(k-i)+1 + (j*nb+i-1)*ldtb )
347 $ = dconjg( tb( td-(k-(i+1)) + (j*nb+k-1)*ldtb ) )
348 END DO
349 END DO
350
351 IF( j.LT.nt-1 ) THEN
352 IF( j.GT.0 ) THEN
353
354
355
356 IF( j.EQ.1 ) THEN
357 CALL zgemm(
'NoTranspose',
'NoTranspose',
358 $ kb, kb, kb,
359 $ one, tb( td+1 + (j*nb)*ldtb ), ldtb-1,
360 $ a( (j-1)*nb+1, j*nb+1 ), lda,
361 $ zero, work( j*nb+1 ), n )
362 ELSE
363 CALL zgemm(
'NoTranspose',
'NoTranspose',
364 $ kb, kb, nb+kb,
365 $ one, tb( td+nb+1 + ((j-1)*nb)*ldtb ),
366 $ ldtb-1,
367 $ a( (j-2)*nb+1, j*nb+1 ), lda,
368 $ zero, work( j*nb+1 ), n )
369 END IF
370
371
372
373 CALL zgemm(
'Conjugate transpose',
'NoTranspose',
374 $ nb, n-(j+1)*nb, j*nb,
375 $ -one, work( nb+1 ), n,
376 $ a( 1, (j+1)*nb+1 ), lda,
377 $ one, a( j*nb+1, (j+1)*nb+1 ), lda )
378 END IF
379
380
381
382 DO k = 1, nb
383 CALL zcopy( n-(j+1)*nb,
384 $ a( j*nb+k, (j+1)*nb+1 ), lda,
385 $ work( 1+(k-1)*n ), 1 )
386 END DO
387
388
389
390 CALL zgetrf( n-(j+1)*nb, nb,
391 $ work, n,
392 $ ipiv( (j+1)*nb+1 ), iinfo )
393
394
395
396
397
398
399 DO k = 1, nb
400
401
402
403 CALL zcopy( n-k-(j+1)*nb,
404 $ work( k+1+(k-1)*n ), 1,
405 $ a( j*nb+k, (j+1)*nb+k+1 ), lda )
406
407
408
409 CALL zlacgv( k, work( 1+(k-1)*n ), 1 )
410 END DO
411
412
413
414 kb = min(nb, n-(j+1)*nb)
415 CALL zlaset(
'Full', kb, nb, zero, zero,
416 $ tb( td+nb+1 + (j*nb)*ldtb) , ldtb-1 )
417 CALL zlacpy(
'Upper', kb, nb,
418 $ work, n,
419 $ tb( td+nb+1 + (j*nb)*ldtb ), ldtb-1 )
420 IF( j.GT.0 ) THEN
421 CALL ztrsm(
'R',
'U',
'N',
'U', kb, nb, one,
422 $ a( (j-1)*nb+1, j*nb+1 ), lda,
423 $ tb( td+nb+1 + (j*nb)*ldtb ), ldtb-1 )
424 END IF
425
426
427
428
429 DO k = 1, nb
430 DO i = 1, kb
431 tb( td-nb+k-i+1 + (j*nb+nb+i-1)*ldtb )
432 $ = dconjg( tb( td+nb+i-k+1 + (j*nb+k-1)*ldtb ) )
433 END DO
434 END DO
435 CALL zlaset(
'Lower', kb, nb, zero, one,
436 $ a( j*nb+1, (j+1)*nb+1), lda )
437
438
439
440 DO k = 1, kb
441
442 ipiv( (j+1)*nb+k ) = ipiv( (j+1)*nb+k ) + (j+1)*nb
443
444 i1 = (j+1)*nb+k
445 i2 = ipiv( (j+1)*nb+k )
446 IF( i1.NE.i2 ) THEN
447
448 CALL zswap( k-1, a( (j+1)*nb+1, i1 ), 1,
449 $ a( (j+1)*nb+1, i2 ), 1 )
450
451 IF( i2.GT.(i1+1) ) THEN
452 CALL zswap( i2-i1-1, a( i1, i1+1 ), lda,
453 $ a( i1+1, i2 ), 1 )
454 CALL zlacgv( i2-i1-1, a( i1+1, i2 ), 1 )
455 END IF
456 CALL zlacgv( i2-i1, a( i1, i1+1 ), lda )
457
458 IF( i2.LT.n )
459 $
CALL zswap( n-i2, a( i1, i2+1 ), lda,
460 $ a( i2, i2+1 ), lda )
461
462 piv = a( i1, i1 )
463 a( i1, i1 ) = a( i2, i2 )
464 a( i2, i2 ) = piv
465
466 IF( j.GT.0 ) THEN
467 CALL zswap( j*nb, a( 1, i1 ), 1,
468 $ a( 1, i2 ), 1 )
469 END IF
470 ENDIF
471 END DO
472 END IF
473 END DO
474 ELSE
475
476
477
478
479
480 DO j = 0, nt-1
481
482
483
484 kb = min(nb, n-j*nb)
485 DO i = 1, j-1
486 IF( i.EQ.1 ) THEN
487
488 IF( i .EQ. (j-1) ) THEN
489 jb = nb+kb
490 ELSE
491 jb = 2*nb
492 END IF
493 CALL zgemm(
'NoTranspose',
'Conjugate transpose',
494 $ nb, kb, jb,
495 $ one, tb( td+1 + (i*nb)*ldtb ), ldtb-1,
496 $ a( j*nb+1, (i-1)*nb+1 ), lda,
497 $ zero, work( i*nb+1 ), n )
498 ELSE
499
500 IF( i .EQ. (j-1) ) THEN
501 jb = 2*nb+kb
502 ELSE
503 jb = 3*nb
504 END IF
505 CALL zgemm(
'NoTranspose',
'Conjugate transpose',
506 $ nb, kb, jb,
507 $ one, tb( td+nb+1 + ((i-1)*nb)*ldtb ),
508 $ ldtb-1,
509 $ a( j*nb+1, (i-2)*nb+1 ), lda,
510 $ zero, work( i*nb+1 ), n )
511 END IF
512 END DO
513
514
515
516 CALL zlacpy(
'Lower', kb, kb, a( j*nb+1, j*nb+1 ), lda,
517 $ tb( td+1 + (j*nb)*ldtb ), ldtb-1 )
518 IF( j.GT.1 ) THEN
519
520 CALL zgemm(
'NoTranspose',
'NoTranspose',
521 $ kb, kb, (j-1)*nb,
522 $ -one, a( j*nb+1, 1 ), lda,
523 $ work( nb+1 ), n,
524 $ one, tb( td+1 + (j*nb)*ldtb ), ldtb-1 )
525
526 CALL zgemm(
'NoTranspose',
'NoTranspose',
527 $ kb, nb, kb,
528 $ one, a( j*nb+1, (j-1)*nb+1 ), lda,
529 $ tb( td+nb+1 + ((j-1)*nb)*ldtb ), ldtb-1,
530 $ zero, work( 1 ), n )
531 CALL zgemm(
'NoTranspose',
'Conjugate transpose',
532 $ kb, kb, nb,
533 $ -one, work( 1 ), n,
534 $ a( j*nb+1, (j-2)*nb+1 ), lda,
535 $ one, tb( td+1 + (j*nb)*ldtb ), ldtb-1 )
536 END IF
537 IF( j.GT.0 ) THEN
538 CALL zhegst( 1,
'Lower', kb,
539 $ tb( td+1 + (j*nb)*ldtb ), ldtb-1,
540 $ a( j*nb+1, (j-1)*nb+1 ), lda, iinfo )
541 END IF
542
543
544
545 DO i = 1, kb
546 tb( td+1 + (j*nb+i-1)*ldtb )
547 $ = real( tb( td+1 + (j*nb+i-1)*ldtb ) )
548 DO k = i+1, kb
549 tb( td-(k-(i+1)) + (j*nb+k-1)*ldtb )
550 $ = dconjg( tb( td+(k-i)+1 + (j*nb+i-1)*ldtb ) )
551 END DO
552 END DO
553
554 IF( j.LT.nt-1 ) THEN
555 IF( j.GT.0 ) THEN
556
557
558
559 IF( j.EQ.1 ) THEN
560 CALL zgemm(
'NoTranspose',
561 $ 'Conjugate transpose',
562 $ kb, kb, kb,
563 $ one, tb( td+1 + (j*nb)*ldtb ), ldtb-1,
564 $ a( j*nb+1, (j-1)*nb+1 ), lda,
565 $ zero, work( j*nb+1 ), n )
566 ELSE
567 CALL zgemm(
'NoTranspose',
568 $ 'Conjugate transpose',
569 $ kb, kb, nb+kb,
570 $ one, tb( td+nb+1 + ((j-1)*nb)*ldtb ),
571 $ ldtb-1,
572 $ a( j*nb+1, (j-2)*nb+1 ), lda,
573 $ zero, work( j*nb+1 ), n )
574 END IF
575
576
577
578 CALL zgemm(
'NoTranspose',
'NoTranspose',
579 $ n-(j+1)*nb, nb, j*nb,
580 $ -one, a( (j+1)*nb+1, 1 ), lda,
581 $ work( nb+1 ), n,
582 $ one, a( (j+1)*nb+1, j*nb+1 ), lda )
583 END IF
584
585
586
587 CALL zgetrf( n-(j+1)*nb, nb,
588 $ a( (j+1)*nb+1, j*nb+1 ), lda,
589 $ ipiv( (j+1)*nb+1 ), iinfo )
590
591
592
593
594
595
596 kb = min(nb, n-(j+1)*nb)
597 CALL zlaset(
'Full', kb, nb, zero, zero,
598 $ tb( td+nb+1 + (j*nb)*ldtb) , ldtb-1 )
599 CALL zlacpy(
'Upper', kb, nb,
600 $ a( (j+1)*nb+1, j*nb+1 ), lda,
601 $ tb( td+nb+1 + (j*nb)*ldtb ), ldtb-1 )
602 IF( j.GT.0 ) THEN
603 CALL ztrsm(
'R',
'L',
'C',
'U', kb, nb, one,
604 $ a( j*nb+1, (j-1)*nb+1 ), lda,
605 $ tb( td+nb+1 + (j*nb)*ldtb ), ldtb-1 )
606 END IF
607
608
609
610
611 DO k = 1, nb
612 DO i = 1, kb
613 tb( td-nb+k-i+1 + (j*nb+nb+i-1)*ldtb )
614 $ = dconjg( tb( td+nb+i-k+1 + (j*nb+k-1)*ldtb ) )
615 END DO
616 END DO
617 CALL zlaset(
'Upper', kb, nb, zero, one,
618 $ a( (j+1)*nb+1, j*nb+1), lda )
619
620
621
622 DO k = 1, kb
623
624 ipiv( (j+1)*nb+k ) = ipiv( (j+1)*nb+k ) + (j+1)*nb
625
626 i1 = (j+1)*nb+k
627 i2 = ipiv( (j+1)*nb+k )
628 IF( i1.NE.i2 ) THEN
629
630 CALL zswap( k-1, a( i1, (j+1)*nb+1 ), lda,
631 $ a( i2, (j+1)*nb+1 ), lda )
632
633 IF( i2.GT.(i1+1) ) THEN
634 CALL zswap( i2-i1-1, a( i1+1, i1 ), 1,
635 $ a( i2, i1+1 ), lda )
636 CALL zlacgv( i2-i1-1, a( i2, i1+1 ), lda )
637 END IF
638 CALL zlacgv( i2-i1, a( i1+1, i1 ), 1 )
639
640 IF( i2.LT.n )
641 $
CALL zswap( n-i2, a( i2+1, i1 ), 1,
642 $ a( i2+1, i2 ), 1 )
643
644 piv = a( i1, i1 )
645 a( i1, i1 ) = a( i2, i2 )
646 a( i2, i2 ) = piv
647
648 IF( j.GT.0 ) THEN
649 CALL zswap( j*nb, a( i1, 1 ), lda,
650 $ a( i2, 1 ), lda )
651 END IF
652 ENDIF
653 END DO
654
655
656
657
658
659 END IF
660 END DO
661 END IF
662
663
664 CALL zgbtrf( n, n, nb, nb, tb, ldtb, ipiv2, info )
665
666 RETURN
667
668
669
subroutine xerbla(srname, info)
subroutine zcopy(n, zx, incx, zy, incy)
ZCOPY
subroutine zgbtrf(m, n, kl, ku, ab, ldab, ipiv, info)
ZGBTRF
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
subroutine zgetrf(m, n, a, lda, ipiv, info)
ZGETRF
subroutine zhegst(itype, uplo, n, a, lda, b, ldb, info)
ZHEGST
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
subroutine zlacgv(n, x, incx)
ZLACGV conjugates a complex vector.
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
logical function lsame(ca, cb)
LSAME
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
subroutine ztrsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
ZTRSM