176
177
178
179
180
181
182 CHARACTER UPLO
183 INTEGER INFO, KB, LDA, LDW, N, NB
184
185
186 INTEGER IPIV( * )
187 COMPLEX 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 COMPLEX CONE
198 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
199
200
201 INTEGER IMAX, J, JJ, JMAX, JP, K, KK, KKW, KP,
202 $ KSTEP, KW
203 REAL ABSAKK, ALPHA, COLMAX, ROWMAX
204 COMPLEX D11, D21, D22, R1, T, Z
205
206
207 LOGICAL LSAME
208 INTEGER ICAMAX
210
211
213
214
215 INTRINSIC abs, aimag, max, min, real, sqrt
216
217
218 REAL CABS1
219
220
221 cabs1( z ) = abs( real( z ) ) + abs( aimag( z ) )
222
223
224
225 info = 0
226
227
228
229 alpha = ( one+sqrt( sevten ) ) / eight
230
231 IF(
lsame( uplo,
'U' ) )
THEN
232
233
234
235
236
237
238
239
240
241 k = n
242 10 CONTINUE
243 kw = nb + k - n
244
245
246
247 IF( ( k.LE.n-nb+1 .AND. nb.LT.n ) .OR. k.LT.1 )
248 $ GO TO 30
249
250
251
252 CALL ccopy( k, a( 1, k ), 1, w( 1, kw ), 1 )
253 IF( k.LT.n )
254 $
CALL cgemv(
'No transpose', k, n-k, -cone, a( 1, k+1 ),
255 $ 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 CALL cgemmtr(
'Upper',
'No transpose',
'Transpose', k, n-k,
484 $ -cone, a( 1, k+1 ), lda, w( 1, kw+1 ), ldw,
485 $ cone, a( 1, 1 ), lda )
486
487
488
489
490 j = k + 1
491 60 CONTINUE
492
493
494
495
496
497 jj = j
498 jp = ipiv( j )
499 IF( jp.LT.0 ) THEN
500 jp = -jp
501
502 j = j + 1
503 END IF
504
505
506 j = j + 1
507 IF( jp.NE.jj .AND. j.LE.n )
508 $
CALL cswap( n-j+1, a( jp, j ), lda, a( jj, j ), lda )
509 IF( j.LT.n )
510 $ GO TO 60
511
512
513
514 kb = n - k
515
516 ELSE
517
518
519
520
521
522
523
524 k = 1
525 70 CONTINUE
526
527
528
529 IF( ( k.GE.nb .AND. nb.LT.n ) .OR. k.GT.n )
530 $ GO TO 90
531
532
533
534 CALL ccopy( n-k+1, a( k, k ), 1, w( k, k ), 1 )
535 CALL cgemv(
'No transpose', n-k+1, k-1, -cone, a( k, 1 ),
536 $ lda,
537 $ w( k, 1 ), ldw, cone, w( k, k ), 1 )
538
539 kstep = 1
540
541
542
543
544 absakk = cabs1( w( k, k ) )
545
546
547
548
549
550 IF( k.LT.n ) THEN
551 imax = k +
icamax( n-k, w( k+1, k ), 1 )
552 colmax = cabs1( w( imax, k ) )
553 ELSE
554 colmax = zero
555 END IF
556
557 IF( max( absakk, colmax ).EQ.zero ) THEN
558
559
560
561 IF( info.EQ.0 )
562 $ info = k
563 kp = k
564 ELSE
565 IF( absakk.GE.alpha*colmax ) THEN
566
567
568
569 kp = k
570 ELSE
571
572
573
574 CALL ccopy( imax-k, a( imax, k ), lda, w( k, k+1 ),
575 $ 1 )
576 CALL ccopy( n-imax+1, a( imax, imax ), 1, w( imax,
577 $ k+1 ),
578 $ 1 )
579 CALL cgemv(
'No transpose', n-k+1, k-1, -cone, a( k,
580 $ 1 ),
581 $ lda, w( imax, 1 ), ldw, cone, w( k, k+1 ),
582 $ 1 )
583
584
585
586
587 jmax = k - 1 +
icamax( imax-k, w( k, k+1 ), 1 )
588 rowmax = cabs1( w( jmax, k+1 ) )
589 IF( imax.LT.n ) THEN
590 jmax = imax +
icamax( n-imax, w( imax+1, k+1 ), 1 )
591 rowmax = max( rowmax, cabs1( w( jmax, k+1 ) ) )
592 END IF
593
594 IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
595
596
597
598 kp = k
599 ELSE IF( cabs1( w( imax, k+1 ) ).GE.alpha*rowmax ) THEN
600
601
602
603
604 kp = imax
605
606
607
608 CALL ccopy( n-k+1, w( k, k+1 ), 1, w( k, k ), 1 )
609 ELSE
610
611
612
613
614 kp = imax
615 kstep = 2
616 END IF
617 END IF
618
619
620
621
622
623 kk = k + kstep - 1
624
625
626
627
628 IF( kp.NE.kk ) THEN
629
630
631
632
633
634
635 a( kp, kp ) = a( kk, kk )
636 CALL ccopy( kp-kk-1, a( kk+1, kk ), 1, a( kp, kk+1 ),
637 $ lda )
638 IF( kp.LT.n )
639 $
CALL ccopy( n-kp, a( kp+1, kk ), 1, a( kp+1, kp ),
640 $ 1 )
641
642
643
644
645
646
647 IF( k.GT.1 )
648 $
CALL cswap( k-1, a( kk, 1 ), lda, a( kp, 1 ), lda )
649 CALL cswap( kk, w( kk, 1 ), ldw, w( kp, 1 ), ldw )
650 END IF
651
652 IF( kstep.EQ.1 ) THEN
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667 CALL ccopy( n-k+1, w( k, k ), 1, a( k, k ), 1 )
668 IF( k.LT.n ) THEN
669 r1 = cone / a( k, k )
670 CALL cscal( n-k, r1, a( k+1, k ), 1 )
671 END IF
672
673 ELSE
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690 IF( k.LT.n-1 ) THEN
691
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 d21 = w( k+1, k )
718 d11 = w( k+1, k+1 ) / d21
719 d22 = w( k, k ) / d21
720 t = cone / ( d11*d22-cone )
721 d21 = t / d21
722
723
724
725
726
727 DO 80 j = k + 2, n
728 a( j, k ) = d21*( d11*w( j, k )-w( j, k+1 ) )
729 a( j, k+1 ) = d21*( d22*w( j, k+1 )-w( j, k ) )
730 80 CONTINUE
731 END IF
732
733
734
735 a( k, k ) = w( k, k )
736 a( k+1, k ) = w( k+1, k )
737 a( k+1, k+1 ) = w( k+1, k+1 )
738
739 END IF
740
741 END IF
742
743
744
745 IF( kstep.EQ.1 ) THEN
746 ipiv( k ) = kp
747 ELSE
748 ipiv( k ) = -kp
749 ipiv( k+1 ) = -kp
750 END IF
751
752
753
754 k = k + kstep
755 GO TO 70
756
757 90 CONTINUE
758
759
760
761
762
763 CALL cgemmtr(
'Lower',
'No transpose',
'Transpose', n-k+1,
764 $ k-1, -cone, a( k, 1 ), lda, w( k, 1 ), ldw,
765 $ cone, a( k, k ), lda )
766
767
768
769
770 j = k - 1
771 120 CONTINUE
772
773
774
775
776
777 jj = j
778 jp = ipiv( j )
779 IF( jp.LT.0 ) THEN
780 jp = -jp
781
782 j = j - 1
783 END IF
784
785
786 j = j - 1
787 IF( jp.NE.jj .AND. j.GE.1 )
788 $
CALL cswap( j, a( jp, 1 ), lda, a( jj, 1 ), lda )
789 IF( j.GT.1 )
790 $ GO TO 120
791
792
793
794 kb = k - 1
795
796 END IF
797 RETURN
798
799
800
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
logical function lsame(ca, cb)
LSAME
subroutine cscal(n, ca, cx, incx)
CSCAL
subroutine cswap(n, cx, incx, cy, incy)
CSWAP