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