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