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