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