182
183
184
185
186
187
188 CHARACTER UPLO
189 INTEGER INFO, KB, LDA, LDW, N, NB
190
191
192 INTEGER IPIV( * )
193 COMPLEX A( LDA, * ), W( LDW, * )
194
195
196
197
198
199 REAL ZERO, ONE
200 parameter( zero = 0.0e+0, one = 1.0e+0 )
201 COMPLEX CONE
202 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
203 REAL EIGHT, SEVTEN
204 parameter( eight = 8.0e+0, sevten = 17.0e+0 )
205
206
207 LOGICAL DONE
208 INTEGER IMAX, ITEMP, II, J, JB, JJ, JMAX, JP1, JP2, K,
209 $ KK, KKW, KP, KSTEP, KW, P
210 REAL ABSAKK, ALPHA, COLMAX, STEMP, R1, ROWMAX, T,
211 $ SFMIN
212 COMPLEX D11, D21, D22, Z
213
214
215 LOGICAL LSAME
216 INTEGER ICAMAX
217 REAL SLAMCH
219
220
223
224
225 INTRINSIC abs, conjg, aimag, max, min, real, sqrt
226
227
228 REAL CABS1
229
230
231 cabs1( z ) = abs( real( z ) ) + abs( aimag( z ) )
232
233
234
235 info = 0
236
237
238
239 alpha = ( one+sqrt( sevten ) ) / eight
240
241
242
244
245 IF(
lsame( uplo,
'U' ) )
THEN
246
247
248
249
250
251
252
253 k = n
254 10 CONTINUE
255
256
257
258 kw = nb + k - n
259
260
261
262 IF( ( k.LE.n-nb+1 .AND. nb.LT.n ) .OR. k.LT.1 )
263 $ GO TO 30
264
265 kstep = 1
266 p = k
267
268
269
270 IF( k.GT.1 )
271 $
CALL ccopy( k-1, a( 1, k ), 1, w( 1, kw ), 1 )
272 w( k, kw ) = real( a( k, k ) )
273 IF( k.LT.n ) THEN
274 CALL cgemv(
'No transpose', k, n-k, -cone, a( 1, k+1 ),
275 $ lda,
276 $ w( k, kw+1 ), ldw, cone, w( 1, kw ), 1 )
277 w( k, kw ) = real( w( k, kw ) )
278 END IF
279
280
281
282
283 absakk = abs( real( w( k, kw ) ) )
284
285
286
287
288
289 IF( k.GT.1 ) THEN
290 imax =
icamax( k-1, w( 1, kw ), 1 )
291 colmax = cabs1( w( imax, kw ) )
292 ELSE
293 colmax = zero
294 END IF
295
296 IF( max( absakk, colmax ).EQ.zero ) THEN
297
298
299
300 IF( info.EQ.0 )
301 $ info = k
302 kp = k
303 a( k, k ) = real( w( k, kw ) )
304 IF( k.GT.1 )
305 $
CALL ccopy( k-1, w( 1, kw ), 1, a( 1, k ), 1 )
306 ELSE
307
308
309
310
311
312
313
314
315 IF( .NOT.( absakk.LT.alpha*colmax ) ) THEN
316
317
318
319 kp = k
320
321 ELSE
322
323
324
325 done = .false.
326
327 12 CONTINUE
328
329
330
331
332
333
334 IF( imax.GT.1 )
335 $
CALL ccopy( imax-1, a( 1, imax ), 1, w( 1,
336 $ kw-1 ),
337 $ 1 )
338 w( imax, kw-1 ) = real( a( imax, imax ) )
339
340 CALL ccopy( k-imax, a( imax, imax+1 ), lda,
341 $ w( imax+1, kw-1 ), 1 )
342 CALL clacgv( k-imax, w( imax+1, kw-1 ), 1 )
343
344 IF( k.LT.n ) THEN
345 CALL cgemv(
'No transpose', k, n-k, -cone,
346 $ a( 1, k+1 ), lda, w( imax, kw+1 ), ldw,
347 $ cone, w( 1, kw-1 ), 1 )
348 w( imax, kw-1 ) = real( w( imax, kw-1 ) )
349 END IF
350
351
352
353
354
355 IF( imax.NE.k ) THEN
356 jmax = imax +
icamax( k-imax, w( imax+1, kw-1 ),
357 $ 1 )
358 rowmax = cabs1( w( jmax, kw-1 ) )
359 ELSE
360 rowmax = zero
361 END IF
362
363 IF( imax.GT.1 ) THEN
364 itemp =
icamax( imax-1, w( 1, kw-1 ), 1 )
365 stemp = cabs1( w( itemp, kw-1 ) )
366 IF( stemp.GT.rowmax ) THEN
367 rowmax = stemp
368 jmax = itemp
369 END IF
370 END IF
371
372
373
374
375
376
377 IF( .NOT.( abs( real( w( imax,kw-1 ) ) )
378 $ .LT.alpha*rowmax ) ) THEN
379
380
381
382
383 kp = imax
384
385
386
387 CALL ccopy( k, w( 1, kw-1 ), 1, w( 1, kw ), 1 )
388
389 done = .true.
390
391
392
393
394
395 ELSE IF( ( p.EQ.jmax ) .OR. ( rowmax.LE.colmax ) )
396 $ THEN
397
398
399
400
401 kp = imax
402 kstep = 2
403 done = .true.
404
405
406 ELSE
407
408
409
410 p = imax
411 colmax = rowmax
412 imax = jmax
413
414
415
416 CALL ccopy( k, w( 1, kw-1 ), 1, w( 1, kw ), 1 )
417
418 END IF
419
420
421
422
423 IF( .NOT.done ) GOTO 12
424
425 END IF
426
427
428
429
430
431
432
433 kk = k - kstep + 1
434
435
436
437 kkw = nb + kk - n
438
439
440
441
442 IF( ( kstep.EQ.2 ) .AND. ( p.NE.k ) ) THEN
443
444
445
446
447
448
449 a( p, p ) = real( a( k, k ) )
450 CALL ccopy( k-1-p, a( p+1, k ), 1, a( p, p+1 ),
451 $ lda )
452 CALL clacgv( k-1-p, a( p, p+1 ), lda )
453 IF( p.GT.1 )
454 $
CALL ccopy( p-1, a( 1, k ), 1, a( 1, p ), 1 )
455
456
457
458
459
460
461 IF( k.LT.n )
462 $
CALL cswap( n-k, a( k, k+1 ), lda, a( p, k+1 ),
463 $ lda )
464 CALL cswap( n-kk+1, w( k, kkw ), ldw, w( p, kkw ),
465 $ ldw )
466 END IF
467
468
469
470
471 IF( kp.NE.kk ) THEN
472
473
474
475
476
477
478 a( kp, kp ) = real( a( kk, kk ) )
479 CALL ccopy( kk-1-kp, a( kp+1, kk ), 1, a( kp, kp+1 ),
480 $ lda )
481 CALL clacgv( kk-1-kp, a( kp, kp+1 ), lda )
482 IF( kp.GT.1 )
483 $
CALL ccopy( kp-1, a( 1, kk ), 1, a( 1, kp ), 1 )
484
485
486
487
488
489
490 IF( k.LT.n )
491 $
CALL cswap( n-k, a( kk, k+1 ), lda, a( kp, k+1 ),
492 $ lda )
493 CALL cswap( n-kk+1, w( kk, kkw ), ldw, w( kp, kkw ),
494 $ ldw )
495 END IF
496
497 IF( kstep.EQ.1 ) THEN
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 CALL ccopy( k, w( 1, kw ), 1, a( 1, k ), 1 )
516 IF( k.GT.1 ) THEN
517
518
519
520
521
522
523
524 t = real( a( k, k ) )
525 IF( abs( t ).GE.sfmin ) THEN
526 r1 = one / t
527 CALL csscal( k-1, r1, a( 1, k ), 1 )
528 ELSE
529 DO 14 ii = 1, k-1
530 a( ii, k ) = a( ii, k ) / t
531 14 CONTINUE
532 END IF
533
534
535
536 CALL clacgv( k-1, w( 1, kw ), 1 )
537 END IF
538
539 ELSE
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556 IF( k.GT.2 ) THEN
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603 d21 = w( k-1, kw )
604 d11 = w( k, kw ) / conjg( d21 )
605 d22 = w( k-1, kw-1 ) / d21
606 t = one / ( real( d11*d22 )-one )
607
608
609
610
611
612 DO 20 j = 1, k - 2
613 a( j, k-1 ) = t*( ( d11*w( j, kw-1 )-w( j, kw ) ) /
614 $ d21 )
615 a( j, k ) = t*( ( d22*w( j, kw )-w( j, kw-1 ) ) /
616 $ conjg( d21 ) )
617 20 CONTINUE
618 END IF
619
620
621
622 a( k-1, k-1 ) = w( k-1, kw-1 )
623 a( k-1, k ) = w( k-1, kw )
624 a( k, k ) = w( k, kw )
625
626
627
628 CALL clacgv( k-1, w( 1, kw ), 1 )
629 CALL clacgv( k-2, w( 1, kw-1 ), 1 )
630
631 END IF
632
633 END IF
634
635
636
637 IF( kstep.EQ.1 ) THEN
638 ipiv( k ) = kp
639 ELSE
640 ipiv( k ) = -p
641 ipiv( k-1 ) = -kp
642 END IF
643
644
645
646 k = k - kstep
647 GO TO 10
648
649 30 CONTINUE
650
651
652
653
654
655
656
657
658 DO 50 j = ( ( k-1 ) / nb )*nb + 1, 1, -nb
659 jb = min( nb, k-j+1 )
660
661
662
663 DO 40 jj = j, j + jb - 1
664 a( jj, jj ) = real( a( jj, jj ) )
665 CALL cgemv(
'No transpose', jj-j+1, n-k, -cone,
666 $ a( j, k+1 ), lda, w( jj, kw+1 ), ldw, cone,
667 $ a( j, jj ), 1 )
668 a( jj, jj ) = real( a( jj, jj ) )
669 40 CONTINUE
670
671
672
673 IF( j.GE.2 )
674 $
CALL cgemm(
'No transpose',
'Transpose', j-1, jb, n-k,
675 $ -cone, a( 1, k+1 ), lda, w( j, kw+1 ), ldw,
676 $ cone, a( 1, j ), lda )
677 50 CONTINUE
678
679
680
681
682 j = k + 1
683 60 CONTINUE
684
685
686
687
688 kstep = 1
689 jp1 = 1
690
691 jj = j
692 jp2 = ipiv( j )
693 IF( jp2.LT.0 ) THEN
694 jp2 = -jp2
695
696 j = j + 1
697 jp1 = -ipiv( j )
698 kstep = 2
699 END IF
700
701
702 j = j + 1
703 IF( jp2.NE.jj .AND. j.LE.n )
704 $
CALL cswap( n-j+1, a( jp2, j ), lda, a( jj, j ), lda )
705 jj = jj + 1
706 IF( kstep.EQ.2 .AND. jp1.NE.jj .AND. j.LE.n )
707 $
CALL cswap( n-j+1, a( jp1, j ), lda, a( jj, j ), lda )
708 IF( j.LT.n )
709 $ GO TO 60
710
711
712
713 kb = n - k
714
715 ELSE
716
717
718
719
720
721
722
723 k = 1
724 70 CONTINUE
725
726
727
728 IF( ( k.GE.nb .AND. nb.LT.n ) .OR. k.GT.n )
729 $ GO TO 90
730
731 kstep = 1
732 p = k
733
734
735
736 w( k, k ) = real( a( k, k ) )
737 IF( k.LT.n )
738 $
CALL ccopy( n-k, a( k+1, k ), 1, w( k+1, k ), 1 )
739 IF( k.GT.1 ) THEN
740 CALL cgemv(
'No transpose', n-k+1, k-1, -cone, a( k, 1 ),
741 $ lda, w( k, 1 ), ldw, cone, w( k, k ), 1 )
742 w( k, k ) = real( w( k, k ) )
743 END IF
744
745
746
747
748 absakk = abs( real( w( k, k ) ) )
749
750
751
752
753
754 IF( k.LT.n ) THEN
755 imax = k +
icamax( n-k, w( k+1, k ), 1 )
756 colmax = cabs1( w( imax, k ) )
757 ELSE
758 colmax = zero
759 END IF
760
761 IF( max( absakk, colmax ).EQ.zero ) THEN
762
763
764
765 IF( info.EQ.0 )
766 $ info = k
767 kp = k
768 a( k, k ) = real( w( k, k ) )
769 IF( k.LT.n )
770 $
CALL ccopy( n-k, w( k+1, k ), 1, a( k+1, k ), 1 )
771 ELSE
772
773
774
775
776
777
778
779
780
781 IF( .NOT.( absakk.LT.alpha*colmax ) ) THEN
782
783
784
785 kp = k
786
787 ELSE
788
789 done = .false.
790
791
792
793 72 CONTINUE
794
795
796
797
798
799
800 CALL ccopy( imax-k, a( imax, k ), lda, w( k, k+1 ),
801 $ 1)
802 CALL clacgv( imax-k, w( k, k+1 ), 1 )
803 w( imax, k+1 ) = real( a( imax, imax ) )
804
805 IF( imax.LT.n )
806 $
CALL ccopy( n-imax, a( imax+1, imax ), 1,
807 $ w( imax+1, k+1 ), 1 )
808
809 IF( k.GT.1 ) THEN
810 CALL cgemv(
'No transpose', n-k+1, k-1, -cone,
811 $ a( k, 1 ), lda, w( imax, 1 ), ldw,
812 $ cone, w( k, k+1 ), 1 )
813 w( imax, k+1 ) = real( w( imax, k+1 ) )
814 END IF
815
816
817
818
819
820 IF( imax.NE.k ) THEN
821 jmax = k - 1 +
icamax( imax-k, w( k, k+1 ), 1 )
822 rowmax = cabs1( w( jmax, k+1 ) )
823 ELSE
824 rowmax = zero
825 END IF
826
827 IF( imax.LT.n ) THEN
828 itemp = imax +
icamax( n-imax, w( imax+1, k+1 ),
829 $ 1)
830 stemp = cabs1( w( itemp, k+1 ) )
831 IF( stemp.GT.rowmax ) THEN
832 rowmax = stemp
833 jmax = itemp
834 END IF
835 END IF
836
837
838
839
840
841
842 IF( .NOT.( abs( real( w( imax,k+1 ) ) )
843 $ .LT.alpha*rowmax ) ) THEN
844
845
846
847
848 kp = imax
849
850
851
852 CALL ccopy( n-k+1, w( k, k+1 ), 1, w( k, k ),
853 $ 1 )
854
855 done = .true.
856
857
858
859
860
861 ELSE IF( ( p.EQ.jmax ) .OR. ( rowmax.LE.colmax ) )
862 $ THEN
863
864
865
866
867 kp = imax
868 kstep = 2
869 done = .true.
870
871
872 ELSE
873
874
875
876 p = imax
877 colmax = rowmax
878 imax = jmax
879
880
881
882 CALL ccopy( n-k+1, w( k, k+1 ), 1, w( k, k ),
883 $ 1 )
884
885 END IF
886
887
888
889
890 IF( .NOT.done ) GOTO 72
891
892 END IF
893
894
895
896
897
898
899
900 kk = k + kstep - 1
901
902
903
904
905 IF( ( kstep.EQ.2 ) .AND. ( p.NE.k ) ) THEN
906
907
908
909
910
911
912 a( p, p ) = real( a( k, k ) )
913 CALL ccopy( p-k-1, a( k+1, k ), 1, a( p, k+1 ), lda )
914 CALL clacgv( p-k-1, a( p, k+1 ), lda )
915 IF( p.LT.n )
916 $
CALL ccopy( n-p, a( p+1, k ), 1, a( p+1, p ), 1 )
917
918
919
920
921
922
923 IF( k.GT.1 )
924 $
CALL cswap( k-1, a( k, 1 ), lda, a( p, 1 ), lda )
925 CALL cswap( kk, w( k, 1 ), ldw, w( p, 1 ), ldw )
926 END IF
927
928
929
930
931 IF( kp.NE.kk ) THEN
932
933
934
935
936
937
938 a( kp, kp ) = real( a( kk, kk ) )
939 CALL ccopy( kp-kk-1, a( kk+1, kk ), 1, a( kp, kk+1 ),
940 $ lda )
941 CALL clacgv( kp-kk-1, a( kp, kk+1 ), lda )
942 IF( kp.LT.n )
943 $
CALL ccopy( n-kp, a( kp+1, kk ), 1, a( kp+1, kp ),
944 $ 1 )
945
946
947
948
949
950
951 IF( k.GT.1 )
952 $
CALL cswap( k-1, a( kk, 1 ), lda, a( kp, 1 ), lda )
953 CALL cswap( kk, w( kk, 1 ), ldw, w( kp, 1 ), ldw )
954 END IF
955
956 IF( kstep.EQ.1 ) THEN
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974 CALL ccopy( n-k+1, w( k, k ), 1, a( k, k ), 1 )
975 IF( k.LT.n ) THEN
976
977
978
979
980
981
982
983 t = real( a( k, k ) )
984 IF( abs( t ).GE.sfmin ) THEN
985 r1 = one / t
986 CALL csscal( n-k, r1, a( k+1, k ), 1 )
987 ELSE
988 DO 74 ii = k + 1, n
989 a( ii, k ) = a( ii, k ) / t
990 74 CONTINUE
991 END IF
992
993
994
995 CALL clacgv( n-k, w( k+1, k ), 1 )
996 END IF
997
998 ELSE
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 IF( k.LT.n-1 ) THEN
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062 d21 = w( k+1, k )
1063 d11 = w( k+1, k+1 ) / d21
1064 d22 = w( k, k ) / conjg( d21 )
1065 t = one / ( real( d11*d22 )-one )
1066
1067
1068
1069
1070
1071 DO 80 j = k + 2, n
1072 a( j, k ) = t*( ( d11*w( j, k )-w( j, k+1 ) ) /
1073 $ conjg( d21 ) )
1074 a( j, k+1 ) = t*( ( d22*w( j, k+1 )-w( j, k ) ) /
1075 $ d21 )
1076 80 CONTINUE
1077 END IF
1078
1079
1080
1081 a( k, k ) = w( k, k )
1082 a( k+1, k ) = w( k+1, k )
1083 a( k+1, k+1 ) = w( k+1, k+1 )
1084
1085
1086
1087 CALL clacgv( n-k, w( k+1, k ), 1 )
1088 CALL clacgv( n-k-1, w( k+2, k+1 ), 1 )
1089
1090 END IF
1091
1092 END IF
1093
1094
1095
1096 IF( kstep.EQ.1 ) THEN
1097 ipiv( k ) = kp
1098 ELSE
1099 ipiv( k ) = -p
1100 ipiv( k+1 ) = -kp
1101 END IF
1102
1103
1104
1105 k = k + kstep
1106 GO TO 70
1107
1108 90 CONTINUE
1109
1110
1111
1112
1113
1114
1115
1116
1117 DO 110 j = k, n, nb
1118 jb = min( nb, n-j+1 )
1119
1120
1121
1122 DO 100 jj = j, j + jb - 1
1123 a( jj, jj ) = real( a( jj, jj ) )
1124 CALL cgemv(
'No transpose', j+jb-jj, k-1, -cone,
1125 $ a( jj, 1 ), lda, w( jj, 1 ), ldw, cone,
1126 $ a( jj, jj ), 1 )
1127 a( jj, jj ) = real( a( jj, jj ) )
1128 100 CONTINUE
1129
1130
1131
1132 IF( j+jb.LE.n )
1133 $
CALL cgemm(
'No transpose',
'Transpose', n-j-jb+1, jb,
1134 $ k-1, -cone, a( j+jb, 1 ), lda, w( j, 1 ),
1135 $ ldw, cone, a( j+jb, j ), lda )
1136 110 CONTINUE
1137
1138
1139
1140
1141 j = k - 1
1142 120 CONTINUE
1143
1144
1145
1146
1147 kstep = 1
1148 jp1 = 1
1149
1150 jj = j
1151 jp2 = ipiv( j )
1152 IF( jp2.LT.0 ) THEN
1153 jp2 = -jp2
1154
1155 j = j - 1
1156 jp1 = -ipiv( j )
1157 kstep = 2
1158 END IF
1159
1160
1161 j = j - 1
1162 IF( jp2.NE.jj .AND. j.GE.1 )
1163 $
CALL cswap( j, a( jp2, 1 ), lda, a( jj, 1 ), lda )
1164 jj = jj -1
1165 IF( kstep.EQ.2 .AND. jp1.NE.jj .AND. j.GE.1 )
1166 $
CALL cswap( j, a( jp1, 1 ), lda, a( jj, 1 ), lda )
1167 IF( j.GT.1 )
1168 $ GO TO 120
1169
1170
1171
1172 kb = k - 1
1173
1174 END IF
1175 RETURN
1176
1177
1178
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
subroutine clacgv(n, x, incx)
CLACGV conjugates a complex vector.
real function slamch(cmach)
SLAMCH
logical function lsame(ca, cb)
LSAME
subroutine csscal(n, sa, cx, incx)
CSSCAL
subroutine cswap(n, cx, incx, cy, incy)
CSWAP