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