177
178
179
180
181
182
183 CHARACTER UPLO
184 INTEGER INFO, KB, LDA, LDW, N, NB
185
186
187 INTEGER IPIV( * )
188 COMPLEX*16 A( LDA, * ), W( LDW, * )
189
190
191
192
193
194 DOUBLE PRECISION ZERO, ONE
195 parameter( zero = 0.0d+0, one = 1.0d+0 )
196 DOUBLE PRECISION EIGHT, SEVTEN
197 parameter( eight = 8.0d+0, sevten = 17.0d+0 )
198 COMPLEX*16 CONE
199 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
200
201
202 INTEGER IMAX, J, JB, JJ, JMAX, JP, K, KK, KKW, KP,
203 $ KSTEP, KW
204 DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, ROWMAX
205 COMPLEX*16 D11, D21, D22, R1, T, Z
206
207
208 LOGICAL LSAME
209 INTEGER IZAMAX
211
212
214
215
216 INTRINSIC abs, dble, dimag, max, min, sqrt
217
218
219 DOUBLE PRECISION CABS1
220
221
222 cabs1( z ) = abs( dble( z ) ) + abs( dimag( z ) )
223
224
225
226 info = 0
227
228
229
230 alpha = ( one+sqrt( sevten ) ) / eight
231
232 IF(
lsame( uplo,
'U' ) )
THEN
233
234
235
236
237
238
239
240
241
242 k = n
243 10 CONTINUE
244 kw = nb + k - n
245
246
247
248 IF( ( k.LE.n-nb+1 .AND. nb.LT.n ) .OR. k.LT.1 )
249 $ GO TO 30
250
251
252
253 CALL zcopy( k, a( 1, k ), 1, w( 1, kw ), 1 )
254 IF( k.LT.n )
255 $
CALL zgemv(
'No transpose', k, n-k, -cone, a( 1, k+1 ), lda,
256 $ w( k, kw+1 ), ldw, cone, w( 1, kw ), 1 )
257
258 kstep = 1
259
260
261
262
263 absakk = cabs1( w( k, kw ) )
264
265
266
267
268 IF( k.GT.1 ) THEN
269 imax =
izamax( k-1, w( 1, kw ), 1 )
270 colmax = cabs1( w( imax, kw ) )
271 ELSE
272 colmax = zero
273 END IF
274
275 IF( max( absakk, colmax ).EQ.zero ) THEN
276
277
278
279 IF( info.EQ.0 )
280 $ info = k
281 kp = k
282 ELSE
283 IF( absakk.GE.alpha*colmax ) THEN
284
285
286
287 kp = k
288 ELSE
289
290
291
292 CALL zcopy( imax, a( 1, imax ), 1, w( 1, kw-1 ), 1 )
293 CALL zcopy( k-imax, a( imax, imax+1 ), lda,
294 $ w( imax+1, kw-1 ), 1 )
295 IF( k.LT.n )
296 $
CALL zgemv(
'No transpose', k, n-k, -cone,
297 $ a( 1, k+1 ), lda, w( imax, kw+1 ), ldw,
298 $ cone, w( 1, kw-1 ), 1 )
299
300
301
302
303 jmax = imax +
izamax( k-imax, w( imax+1, kw-1 ), 1 )
304 rowmax = cabs1( w( jmax, kw-1 ) )
305 IF( imax.GT.1 ) THEN
306 jmax =
izamax( imax-1, w( 1, kw-1 ), 1 )
307 rowmax = max( rowmax, cabs1( w( jmax, kw-1 ) ) )
308 END IF
309
310 IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
311
312
313
314 kp = k
315 ELSE IF( cabs1( w( imax, kw-1 ) ).GE.alpha*rowmax ) THEN
316
317
318
319
320 kp = imax
321
322
323
324 CALL zcopy( k, w( 1, kw-1 ), 1, w( 1, kw ), 1 )
325 ELSE
326
327
328
329
330 kp = imax
331 kstep = 2
332 END IF
333 END IF
334
335
336
337
338
339 kk = k - kstep + 1
340
341
342
343 kkw = nb + kk - n
344
345
346
347
348 IF( kp.NE.kk ) THEN
349
350
351
352
353
354
355 a( kp, kp ) = a( kk, kk )
356 CALL zcopy( kk-1-kp, a( kp+1, kk ), 1, a( kp, kp+1 ),
357 $ lda )
358 IF( kp.GT.1 )
359 $
CALL zcopy( kp-1, a( 1, kk ), 1, a( 1, kp ), 1 )
360
361
362
363
364
365
366 IF( k.LT.n )
367 $
CALL zswap( n-k, a( kk, k+1 ), lda, a( kp, k+1 ),
368 $ lda )
369 CALL zswap( n-kk+1, w( kk, kkw ), ldw, w( kp, kkw ),
370 $ ldw )
371 END IF
372
373 IF( kstep.EQ.1 ) THEN
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388 CALL zcopy( k, w( 1, kw ), 1, a( 1, k ), 1 )
389 r1 = cone / a( k, k )
390 CALL zscal( k-1, r1, a( 1, k ), 1 )
391
392 ELSE
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409 IF( k.GT.2 ) THEN
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 d21 = w( k-1, kw )
437 d11 = w( k, kw ) / d21
438 d22 = w( k-1, kw-1 ) / d21
439 t = cone / ( d11*d22-cone )
440 d21 = t / d21
441
442
443
444
445
446 DO 20 j = 1, k - 2
447 a( j, k-1 ) = d21*( d11*w( j, kw-1 )-w( j, kw ) )
448 a( j, k ) = d21*( d22*w( j, kw )-w( j, kw-1 ) )
449 20 CONTINUE
450 END IF
451
452
453
454 a( k-1, k-1 ) = w( k-1, kw-1 )
455 a( k-1, k ) = w( k-1, kw )
456 a( k, k ) = w( k, kw )
457
458 END IF
459
460 END IF
461
462
463
464 IF( kstep.EQ.1 ) THEN
465 ipiv( k ) = kp
466 ELSE
467 ipiv( k ) = -kp
468 ipiv( k-1 ) = -kp
469 END IF
470
471
472
473 k = k - kstep
474 GO TO 10
475
476 30 CONTINUE
477
478
479
480
481
482
483
484 DO 50 j = ( ( k-1 ) / nb )*nb + 1, 1, -nb
485 jb = min( nb, k-j+1 )
486
487
488
489 DO 40 jj = j, j + jb - 1
490 CALL zgemv(
'No transpose', jj-j+1, n-k, -cone,
491 $ a( j, k+1 ), lda, w( jj, kw+1 ), ldw, cone,
492 $ a( j, jj ), 1 )
493 40 CONTINUE
494
495
496
497 CALL zgemm(
'No transpose',
'Transpose', j-1, jb, n-k,
498 $ -cone, a( 1, k+1 ), lda, w( j, kw+1 ), ldw,
499 $ cone, a( 1, j ), lda )
500 50 CONTINUE
501
502
503
504
505 j = k + 1
506 60 CONTINUE
507
508
509
510
511
512 jj = j
513 jp = ipiv( j )
514 IF( jp.LT.0 ) THEN
515 jp = -jp
516
517 j = j + 1
518 END IF
519
520
521 j = j + 1
522 IF( jp.NE.jj .AND. j.LE.n )
523 $
CALL zswap( n-j+1, a( jp, j ), lda, a( jj, j ), lda )
524 IF( j.LT.n )
525 $ GO TO 60
526
527
528
529 kb = n - k
530
531 ELSE
532
533
534
535
536
537
538
539 k = 1
540 70 CONTINUE
541
542
543
544 IF( ( k.GE.nb .AND. nb.LT.n ) .OR. k.GT.n )
545 $ GO TO 90
546
547
548
549 CALL zcopy( n-k+1, a( k, k ), 1, w( k, k ), 1 )
550 CALL zgemv(
'No transpose', n-k+1, k-1, -cone, a( k, 1 ), lda,
551 $ w( k, 1 ), ldw, cone, w( k, k ), 1 )
552
553 kstep = 1
554
555
556
557
558 absakk = cabs1( w( k, k ) )
559
560
561
562
563 IF( k.LT.n ) THEN
564 imax = k +
izamax( n-k, w( k+1, k ), 1 )
565 colmax = cabs1( w( imax, k ) )
566 ELSE
567 colmax = zero
568 END IF
569
570 IF( max( absakk, colmax ).EQ.zero ) THEN
571
572
573
574 IF( info.EQ.0 )
575 $ info = k
576 kp = k
577 ELSE
578 IF( absakk.GE.alpha*colmax ) THEN
579
580
581
582 kp = k
583 ELSE
584
585
586
587 CALL zcopy( imax-k, a( imax, k ), lda, w( k, k+1 ), 1 )
588 CALL zcopy( n-imax+1, a( imax, imax ), 1, w( imax, k+1 ),
589 $ 1 )
590 CALL zgemv(
'No transpose', n-k+1, k-1, -cone, a( k, 1 ),
591 $ lda, w( imax, 1 ), ldw, cone, w( k, k+1 ),
592 $ 1 )
593
594
595
596
597 jmax = k - 1 +
izamax( imax-k, w( k, k+1 ), 1 )
598 rowmax = cabs1( w( jmax, k+1 ) )
599 IF( imax.LT.n ) THEN
600 jmax = imax +
izamax( n-imax, w( imax+1, k+1 ), 1 )
601 rowmax = max( rowmax, cabs1( w( jmax, k+1 ) ) )
602 END IF
603
604 IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
605
606
607
608 kp = k
609 ELSE IF( cabs1( w( imax, k+1 ) ).GE.alpha*rowmax ) THEN
610
611
612
613
614 kp = imax
615
616
617
618 CALL zcopy( n-k+1, w( k, k+1 ), 1, w( k, k ), 1 )
619 ELSE
620
621
622
623
624 kp = imax
625 kstep = 2
626 END IF
627 END IF
628
629
630
631
632
633 kk = k + kstep - 1
634
635
636
637
638 IF( kp.NE.kk ) THEN
639
640
641
642
643
644
645 a( kp, kp ) = a( kk, kk )
646 CALL zcopy( kp-kk-1, a( kk+1, kk ), 1, a( kp, kk+1 ),
647 $ lda )
648 IF( kp.LT.n )
649 $
CALL zcopy( n-kp, a( kp+1, kk ), 1, a( kp+1, kp ), 1 )
650
651
652
653
654
655
656 IF( k.GT.1 )
657 $
CALL zswap( k-1, a( kk, 1 ), lda, a( kp, 1 ), lda )
658 CALL zswap( kk, w( kk, 1 ), ldw, w( kp, 1 ), ldw )
659 END IF
660
661 IF( kstep.EQ.1 ) THEN
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676 CALL zcopy( n-k+1, w( k, k ), 1, a( k, k ), 1 )
677 IF( k.LT.n ) THEN
678 r1 = cone / a( k, k )
679 CALL zscal( n-k, r1, a( k+1, k ), 1 )
680 END IF
681
682 ELSE
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699 IF( k.LT.n-1 ) THEN
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726 d21 = w( k+1, k )
727 d11 = w( k+1, k+1 ) / d21
728 d22 = w( k, k ) / d21
729 t = cone / ( d11*d22-cone )
730 d21 = t / d21
731
732
733
734
735
736 DO 80 j = k + 2, n
737 a( j, k ) = d21*( d11*w( j, k )-w( j, k+1 ) )
738 a( j, k+1 ) = d21*( d22*w( j, k+1 )-w( j, k ) )
739 80 CONTINUE
740 END IF
741
742
743
744 a( k, k ) = w( k, k )
745 a( k+1, k ) = w( k+1, k )
746 a( k+1, k+1 ) = w( k+1, k+1 )
747
748 END IF
749
750 END IF
751
752
753
754 IF( kstep.EQ.1 ) THEN
755 ipiv( k ) = kp
756 ELSE
757 ipiv( k ) = -kp
758 ipiv( k+1 ) = -kp
759 END IF
760
761
762
763 k = k + kstep
764 GO TO 70
765
766 90 CONTINUE
767
768
769
770
771
772
773
774 DO 110 j = k, n, nb
775 jb = min( nb, n-j+1 )
776
777
778
779 DO 100 jj = j, j + jb - 1
780 CALL zgemv(
'No transpose', j+jb-jj, k-1, -cone,
781 $ a( jj, 1 ), lda, w( jj, 1 ), ldw, cone,
782 $ a( jj, jj ), 1 )
783 100 CONTINUE
784
785
786
787 IF( j+jb.LE.n )
788 $
CALL zgemm(
'No transpose',
'Transpose', n-j-jb+1, jb,
789 $ k-1, -cone, a( j+jb, 1 ), lda, w( j, 1 ),
790 $ ldw, cone, a( j+jb, j ), lda )
791 110 CONTINUE
792
793
794
795
796 j = k - 1
797 120 CONTINUE
798
799
800
801
802
803 jj = j
804 jp = ipiv( j )
805 IF( jp.LT.0 ) THEN
806 jp = -jp
807
808 j = j - 1
809 END IF
810
811
812 j = j - 1
813 IF( jp.NE.jj .AND. j.GE.1 )
814 $
CALL zswap( j, a( jp, 1 ), lda, a( jj, 1 ), lda )
815 IF( j.GT.1 )
816 $ GO TO 120
817
818
819
820 kb = k - 1
821
822 END IF
823 RETURN
824
825
826
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 izamax(n, zx, incx)
IZAMAX
logical function lsame(ca, cb)
LSAME
subroutine zscal(n, za, zx, incx)
ZSCAL
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP