182
183
184
185
186
187
188 CHARACTER UPLO
189 INTEGER INFO, KB, LDA, LDW, N, NB
190
191
192 INTEGER IPIV( * )
193 COMPLEX*16 A( LDA, * ), W( LDW, * )
194
195
196
197
198
199 DOUBLE PRECISION ZERO, ONE
200 parameter( zero = 0.0d+0, one = 1.0d+0 )
201 DOUBLE PRECISION EIGHT, SEVTEN
202 parameter( eight = 8.0d+0, sevten = 17.0d+0 )
203 COMPLEX*16 CONE, CZERO
204 parameter( cone = ( 1.0d+0, 0.0d+0 ),
205 $ czero = ( 0.0d+0, 0.0d+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 DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, ROWMAX, DTEMP, SFMIN
212 COMPLEX*16 D11, D12, D21, D22, R1, T, Z
213
214
215 LOGICAL LSAME
216 INTEGER IZAMAX
217 DOUBLE PRECISION DLAMCH
219
220
222
223
224 INTRINSIC abs, max, min, sqrt, dimag, dble
225
226
227 DOUBLE PRECISION CABS1
228
229
230 cabs1( z ) = abs( dble( z ) ) + abs( dimag( 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 zcopy( k, a( 1, k ), 1, w( 1, kw ), 1 )
270 IF( k.LT.n )
271 $
CALL zgemv(
'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 =
izamax( 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 zcopy( 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 zcopy( imax, a( 1, imax ), 1, w( 1, kw-1 ),
327 $ 1 )
328 CALL zcopy( k-imax, a( imax, imax+1 ), lda,
329 $ w( imax+1, kw-1 ), 1 )
330
331 IF( k.LT.n )
332 $
CALL zgemv(
'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 +
izamax( 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 =
izamax( imax-1, w( 1, kw-1 ), 1 )
350 dtemp = cabs1( w( itemp, kw-1 ) )
351 IF( dtemp.GT.rowmax ) THEN
352 rowmax = dtemp
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 zcopy( 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 zcopy( 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 zcopy( k-p, a( p+1, k ), 1, a( p, p+1 ), lda )
420 CALL zcopy( p, a( 1, k ), 1, a( 1, p ), 1 )
421
422
423
424
425 CALL zswap( n-k+1, a( k, k ), lda, a( p, k ), lda )
426 CALL zswap( 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 zcopy( k-1-kp, a( kp+1, kk ), 1, a( kp, kp+1 ),
438 $ lda )
439 CALL zcopy( kp, a( 1, kk ), 1, a( 1, kp ), 1 )
440
441
442
443
444 CALL zswap( n-kk+1, a( kk, kk ), lda, a( kp, kk ),
445 $ lda )
446 CALL zswap( 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 zcopy( 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 zscal( 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 zgemmtr(
'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 zswap( 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 zswap( 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 zcopy( n-k+1, a( k, k ), 1, w( k, k ), 1 )
584 IF( k.GT.1 )
585 $
CALL zgemv(
'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 +
izamax( 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 zcopy( 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 zcopy( imax-k, a( imax, k ), lda, w( k, k+1 ),
641 $ 1)
642 CALL zcopy( n-imax+1, a( imax, imax ), 1,
643 $ w( imax, k+1 ), 1 )
644 IF( k.GT.1 )
645 $
CALL zgemv(
'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 +
izamax( 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 +
izamax( n-imax, w( imax+1, k+1 ),
662 $ 1)
663 dtemp = cabs1( w( itemp, k+1 ) )
664 IF( dtemp.GT.rowmax ) THEN
665 rowmax = dtemp
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 zcopy( 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 zcopy( 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 zcopy( p-k, a( k, k ), 1, a( p, k ), lda )
731 CALL zcopy( n-p+1, a( p, k ), 1, a( p, p ), 1 )
732
733
734
735
736 CALL zswap( k, a( k, 1 ), lda, a( p, 1 ), lda )
737 CALL zswap( 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 zcopy( kp-k-1, a( k+1, kk ), 1, a( kp, k+1 ),
748 $ lda )
749 CALL zcopy( n-kp+1, a( kp, kk ), 1, a( kp, kp ), 1 )
750
751
752
753 CALL zswap( kk, a( kk, 1 ), lda, a( kp, 1 ), lda )
754 CALL zswap( 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 zcopy( 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 zscal( 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 zgemmtr(
'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 zswap( j, a( jp2, 1 ), lda, a( jj, 1 ), lda )
858 jj = j + 1
859 IF( jp1.NE.jj .AND. kstep.EQ.2 )
860 $
CALL zswap( 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 zcopy(n, zx, incx, zy, incy)
ZCOPY
subroutine zgemmtr(uplo, transa, transb, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMMTR
subroutine zgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
ZGEMV
integer function izamax(n, zx, incx)
IZAMAX
double precision function dlamch(cmach)
DLAMCH
logical function lsame(ca, cb)
LSAME
subroutine zscal(n, za, zx, incx)
ZSCAL
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP