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