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