229
  230
  231
  232
  233
  234
  235      CHARACTER          DIAG, NORMIN, TRANS, UPLO
  236      INTEGER            INFO, N
  237      REAL               SCALE
  238
  239
  240      REAL               CNORM( * )
  241      COMPLEX            AP( * ), X( * )
  242
  243
  244
  245
  246
  247      REAL               ZERO, HALF, ONE, TWO
  248      parameter( zero = 0.0e+0, half = 0.5e+0, one = 1.0e+0,
  249     $                   two = 2.0e+0 )
  250
  251
  252      LOGICAL            NOTRAN, NOUNIT, UPPER
  253      INTEGER            I, IMAX, IP, J, JFIRST, JINC, JLAST, JLEN
  254      REAL               BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
  255     $                   XBND, XJ, XMAX
  256      COMPLEX            CSUMJ, TJJS, USCAL, ZDUM
  257
  258
  259      LOGICAL            LSAME
  260      INTEGER            ICAMAX, ISAMAX
  261      REAL               SCASUM, SLAMCH
  262      COMPLEX            CDOTC, CDOTU, CLADIV
  266
  267
  269
  270
  271      INTRINSIC          abs, aimag, cmplx, conjg, max, min, real
  272
  273
  274      REAL               CABS1, CABS2
  275
  276
  277      cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
  278      cabs2( zdum ) = abs( real( zdum ) / 2. ) +
  279     $                abs( aimag( zdum ) / 2. )
  280
  281
  282
  283      info = 0
  284      upper = 
lsame( uplo, 
'U' )
 
  285      notran = 
lsame( trans, 
'N' )
 
  286      nounit = 
lsame( diag, 
'N' )
 
  287
  288
  289
  290      IF( .NOT.upper .AND. .NOT.
lsame( uplo, 
'L' ) ) 
THEN 
  291         info = -1
  292      ELSE IF( .NOT.notran .AND. .NOT.
lsame( trans, 
'T' ) .AND. .NOT.
 
  293     $         
lsame( trans, 
'C' ) ) 
THEN 
  294         info = -2
  295      ELSE IF( .NOT.nounit .AND. .NOT.
lsame( diag, 
'U' ) ) 
THEN 
  296         info = -3
  297      ELSE IF( .NOT.
lsame( normin, 
'Y' ) .AND. .NOT.
 
  298     $         
lsame( normin, 
'N' ) ) 
THEN 
  299         info = -4
  300      ELSE IF( n.LT.0 ) THEN
  301         info = -5
  302      END IF
  303      IF( info.NE.0 ) THEN
  304         CALL xerbla( 
'CLATPS', -info )
 
  305         RETURN
  306      END IF
  307
  308
  309
  310      IF( n.EQ.0 )
  311     $   RETURN
  312
  313
  314
  315      smlnum = 
slamch( 
'Safe minimum' )
 
  316      bignum = one / smlnum
  317      smlnum = smlnum / 
slamch( 
'Precision' )
 
  318      bignum = one / smlnum
  319      scale = one
  320
  321      IF( 
lsame( normin, 
'N' ) ) 
THEN 
  322
  323
  324
  325         IF( upper ) THEN
  326
  327
  328
  329            ip = 1
  330            DO 10 j = 1, n
  331               cnorm( j ) = 
scasum( j-1, ap( ip ), 1 )
 
  332               ip = ip + j
  333   10       CONTINUE
  334         ELSE
  335
  336
  337
  338            ip = 1
  339            DO 20 j = 1, n - 1
  340               cnorm( j ) = 
scasum( n-j, ap( ip+1 ), 1 )
 
  341               ip = ip + n - j + 1
  342   20       CONTINUE
  343            cnorm( n ) = zero
  344         END IF
  345      END IF
  346
  347
  348
  349
  350      imax = 
isamax( n, cnorm, 1 )
 
  351      tmax = cnorm( imax )
  352      IF( tmax.LE.bignum*half ) THEN
  353         tscal = one
  354      ELSE
  355         tscal = half / ( smlnum*tmax )
  356         CALL sscal( n, tscal, cnorm, 1 )
 
  357      END IF
  358
  359
  360
  361
  362      xmax = zero
  363      DO 30 j = 1, n
  364         xmax = max( xmax, cabs2( x( j ) ) )
  365   30 CONTINUE
  366      xbnd = xmax
  367      IF( notran ) THEN
  368
  369
  370
  371         IF( upper ) THEN
  372            jfirst = n
  373            jlast = 1
  374            jinc = -1
  375         ELSE
  376            jfirst = 1
  377            jlast = n
  378            jinc = 1
  379         END IF
  380
  381         IF( tscal.NE.one ) THEN
  382            grow = zero
  383            GO TO 60
  384         END IF
  385
  386         IF( nounit ) THEN
  387
  388
  389
  390
  391
  392
  393            grow = half / max( xbnd, smlnum )
  394            xbnd = grow
  395            ip = jfirst*( jfirst+1 ) / 2
  396            jlen = n
  397            DO 40 j = jfirst, jlast, jinc
  398
  399
  400
  401               IF( grow.LE.smlnum )
  402     $            GO TO 60
  403
  404               tjjs = ap( ip )
  405               tjj = cabs1( tjjs )
  406
  407               IF( tjj.GE.smlnum ) THEN
  408
  409
  410
  411                  xbnd = min( xbnd, min( one, tjj )*grow )
  412               ELSE
  413
  414
  415
  416                  xbnd = zero
  417               END IF
  418
  419               IF( tjj+cnorm( j ).GE.smlnum ) THEN
  420
  421
  422
  423                  grow = grow*( tjj / ( tjj+cnorm( j ) ) )
  424               ELSE
  425
  426
  427
  428                  grow = zero
  429               END IF
  430               ip = ip + jinc*jlen
  431               jlen = jlen - 1
  432   40       CONTINUE
  433            grow = xbnd
  434         ELSE
  435
  436
  437
  438
  439
  440            grow = min( one, half / max( xbnd, smlnum ) )
  441            DO 50 j = jfirst, jlast, jinc
  442
  443
  444
  445               IF( grow.LE.smlnum )
  446     $            GO TO 60
  447
  448
  449
  450               grow = grow*( one / ( one+cnorm( j ) ) )
  451   50       CONTINUE
  452         END IF
  453   60    CONTINUE
  454
  455      ELSE
  456
  457
  458
  459         IF( upper ) THEN
  460            jfirst = 1
  461            jlast = n
  462            jinc = 1
  463         ELSE
  464            jfirst = n
  465            jlast = 1
  466            jinc = -1
  467         END IF
  468
  469         IF( tscal.NE.one ) THEN
  470            grow = zero
  471            GO TO 90
  472         END IF
  473
  474         IF( nounit ) THEN
  475
  476
  477
  478
  479
  480
  481            grow = half / max( xbnd, smlnum )
  482            xbnd = grow
  483            ip = jfirst*( jfirst+1 ) / 2
  484            jlen = 1
  485            DO 70 j = jfirst, jlast, jinc
  486
  487
  488
  489               IF( grow.LE.smlnum )
  490     $            GO TO 90
  491
  492
  493
  494               xj = one + cnorm( j )
  495               grow = min( grow, xbnd / xj )
  496
  497               tjjs = ap( ip )
  498               tjj = cabs1( tjjs )
  499
  500               IF( tjj.GE.smlnum ) THEN
  501
  502
  503
  504                  IF( xj.GT.tjj )
  505     $               xbnd = xbnd*( tjj / xj )
  506               ELSE
  507
  508
  509
  510                  xbnd = zero
  511               END IF
  512               jlen = jlen + 1
  513               ip = ip + jinc*jlen
  514   70       CONTINUE
  515            grow = min( grow, xbnd )
  516         ELSE
  517
  518
  519
  520
  521
  522            grow = min( one, half / max( xbnd, smlnum ) )
  523            DO 80 j = jfirst, jlast, jinc
  524
  525
  526
  527               IF( grow.LE.smlnum )
  528     $            GO TO 90
  529
  530
  531
  532               xj = one + cnorm( j )
  533               grow = grow / xj
  534   80       CONTINUE
  535         END IF
  536   90    CONTINUE
  537      END IF
  538
  539      IF( ( grow*tscal ).GT.smlnum ) THEN
  540
  541
  542
  543
  544         CALL ctpsv( uplo, trans, diag, n, ap, x, 1 )
 
  545      ELSE
  546
  547
  548
  549         IF( xmax.GT.bignum*half ) THEN
  550
  551
  552
  553
  554            scale = ( bignum*half ) / xmax
  555            CALL csscal( n, scale, x, 1 )
 
  556            xmax = bignum
  557         ELSE
  558            xmax = xmax*two
  559         END IF
  560
  561         IF( notran ) THEN
  562
  563
  564
  565            ip = jfirst*( jfirst+1 ) / 2
  566            DO 110 j = jfirst, jlast, jinc
  567
  568
  569
  570               xj = cabs1( x( j ) )
  571               IF( nounit ) THEN
  572                  tjjs = ap( ip )*tscal
  573               ELSE
  574                  tjjs = tscal
  575                  IF( tscal.EQ.one )
  576     $               GO TO 105
  577               END IF
  578                  tjj = cabs1( tjjs )
  579                  IF( tjj.GT.smlnum ) THEN
  580
  581
  582
  583                     IF( tjj.LT.one ) THEN
  584                        IF( xj.GT.tjj*bignum ) THEN
  585
  586
  587
  588                           rec = one / xj
  589                           CALL csscal( n, rec, x, 1 )
 
  590                           scale = scale*rec
  591                           xmax = xmax*rec
  592                        END IF
  593                     END IF
  594                     x( j ) = 
cladiv( x( j ), tjjs )
 
  595                     xj = cabs1( x( j ) )
  596                  ELSE IF( tjj.GT.zero ) THEN
  597
  598
  599
  600                     IF( xj.GT.tjj*bignum ) THEN
  601
  602
  603
  604
  605                        rec = ( tjj*bignum ) / xj
  606                        IF( cnorm( j ).GT.one ) THEN
  607
  608
  609
  610
  611                           rec = rec / cnorm( j )
  612                        END IF
  613                        CALL csscal( n, rec, x, 1 )
 
  614                        scale = scale*rec
  615                        xmax = xmax*rec
  616                     END IF
  617                     x( j ) = 
cladiv( x( j ), tjjs )
 
  618                     xj = cabs1( x( j ) )
  619                  ELSE
  620
  621
  622
  623
  624                     DO 100 i = 1, n
  625                        x( i ) = zero
  626  100                CONTINUE
  627                     x( j ) = one
  628                     xj = one
  629                     scale = zero
  630                     xmax = zero
  631                  END IF
  632  105          CONTINUE
  633
  634
  635
  636
  637               IF( xj.GT.one ) THEN
  638                  rec = one / xj
  639                  IF( cnorm( j ).GT.( bignum-xmax )*rec ) THEN
  640
  641
  642
  643                     rec = rec*half
  644                     CALL csscal( n, rec, x, 1 )
 
  645                     scale = scale*rec
  646                  END IF
  647               ELSE IF( xj*cnorm( j ).GT.( bignum-xmax ) ) THEN
  648
  649
  650
  651                  CALL csscal( n, half, x, 1 )
 
  652                  scale = scale*half
  653               END IF
  654
  655               IF( upper ) THEN
  656                  IF( j.GT.1 ) THEN
  657
  658
  659
  660
  661                     CALL caxpy( j-1, -x( j )*tscal, ap( ip-j+1 ), 1,
 
  662     $                           x,
  663     $                           1 )
  665                     xmax = cabs1( x( i ) )
  666                  END IF
  667                  ip = ip - j
  668               ELSE
  669                  IF( j.LT.n ) THEN
  670
  671
  672
  673
  674                     CALL caxpy( n-j, -x( j )*tscal, ap( ip+1 ), 1,
 
  675     $                           x( j+1 ), 1 )
  676                     i = j + 
icamax( n-j, x( j+1 ), 1 )
 
  677                     xmax = cabs1( x( i ) )
  678                  END IF
  679                  ip = ip + n - j + 1
  680               END IF
  681  110       CONTINUE
  682
  683         ELSE IF( 
lsame( trans, 
'T' ) ) 
THEN 
  684
  685
  686
  687            ip = jfirst*( jfirst+1 ) / 2
  688            jlen = 1
  689            DO 150 j = jfirst, jlast, jinc
  690
  691
  692
  693
  694               xj = cabs1( x( j ) )
  695               uscal = tscal
  696               rec = one / max( xmax, one )
  697               IF( cnorm( j ).GT.( bignum-xj )*rec ) THEN
  698
  699
  700
  701                  rec = rec*half
  702                  IF( nounit ) THEN
  703                     tjjs = ap( ip )*tscal
  704                  ELSE
  705                     tjjs = tscal
  706                  END IF
  707                     tjj = cabs1( tjjs )
  708                     IF( tjj.GT.one ) THEN
  709
  710
  711
  712                        rec = min( one, rec*tjj )
  713                        uscal = 
cladiv( uscal, tjjs )
 
  714                     END IF
  715                  IF( rec.LT.one ) THEN
  716                     CALL csscal( n, rec, x, 1 )
 
  717                     scale = scale*rec
  718                     xmax = xmax*rec
  719                  END IF
  720               END IF
  721
  722               csumj = zero
  723               IF( uscal.EQ.cmplx( one ) ) THEN
  724
  725
  726
  727
  728                  IF( upper ) THEN
  729                     csumj = 
cdotu( j-1, ap( ip-j+1 ), 1, x, 1 )
 
  730                  ELSE IF( j.LT.n ) THEN
  731                     csumj = 
cdotu( n-j, ap( ip+1 ), 1, x( j+1 ), 1 )
 
  732                  END IF
  733               ELSE
  734
  735
  736
  737                  IF( upper ) THEN
  738                     DO 120 i = 1, j - 1
  739                        csumj = csumj + ( ap( ip-j+i )*uscal )*x( i )
  740  120                CONTINUE
  741                  ELSE IF( j.LT.n ) THEN
  742                     DO 130 i = 1, n - j
  743                        csumj = csumj + ( ap( ip+i )*uscal )*x( j+i )
  744  130                CONTINUE
  745                  END IF
  746               END IF
  747
  748               IF( uscal.EQ.cmplx( tscal ) ) THEN
  749
  750
  751
  752
  753                  x( j ) = x( j ) - csumj
  754                  xj = cabs1( x( j ) )
  755                  IF( nounit ) THEN
  756
  757
  758
  759                     tjjs = ap( ip )*tscal
  760                  ELSE
  761                     tjjs = tscal
  762                     IF( tscal.EQ.one )
  763     $                  GO TO 145
  764                  END IF
  765                     tjj = cabs1( tjjs )
  766                     IF( tjj.GT.smlnum ) THEN
  767
  768
  769
  770                        IF( tjj.LT.one ) THEN
  771                           IF( xj.GT.tjj*bignum ) THEN
  772
  773
  774
  775                              rec = one / xj
  776                              CALL csscal( n, rec, x, 1 )
 
  777                              scale = scale*rec
  778                              xmax = xmax*rec
  779                           END IF
  780                        END IF
  781                        x( j ) = 
cladiv( x( j ), tjjs )
 
  782                     ELSE IF( tjj.GT.zero ) THEN
  783
  784
  785
  786                        IF( xj.GT.tjj*bignum ) THEN
  787
  788
  789
  790                           rec = ( tjj*bignum ) / xj
  791                           CALL csscal( n, rec, x, 1 )
 
  792                           scale = scale*rec
  793                           xmax = xmax*rec
  794                        END IF
  795                        x( j ) = 
cladiv( x( j ), tjjs )
 
  796                     ELSE
  797
  798
  799
  800
  801                        DO 140 i = 1, n
  802                           x( i ) = zero
  803  140                   CONTINUE
  804                        x( j ) = one
  805                        scale = zero
  806                        xmax = zero
  807                     END IF
  808  145             CONTINUE
  809               ELSE
  810
  811
  812
  813
  814                  x( j ) = 
cladiv( x( j ), tjjs ) - csumj
 
  815               END IF
  816               xmax = max( xmax, cabs1( x( j ) ) )
  817               jlen = jlen + 1
  818               ip = ip + jinc*jlen
  819  150       CONTINUE
  820
  821         ELSE
  822
  823
  824
  825            ip = jfirst*( jfirst+1 ) / 2
  826            jlen = 1
  827            DO 190 j = jfirst, jlast, jinc
  828
  829
  830
  831
  832               xj = cabs1( x( j ) )
  833               uscal = tscal
  834               rec = one / max( xmax, one )
  835               IF( cnorm( j ).GT.( bignum-xj )*rec ) THEN
  836
  837
  838
  839                  rec = rec*half
  840                  IF( nounit ) THEN
  841                     tjjs = conjg( ap( ip ) )*tscal
  842                  ELSE
  843                     tjjs = tscal
  844                  END IF
  845                     tjj = cabs1( tjjs )
  846                     IF( tjj.GT.one ) THEN
  847
  848
  849
  850                        rec = min( one, rec*tjj )
  851                        uscal = 
cladiv( uscal, tjjs )
 
  852                     END IF
  853                  IF( rec.LT.one ) THEN
  854                     CALL csscal( n, rec, x, 1 )
 
  855                     scale = scale*rec
  856                     xmax = xmax*rec
  857                  END IF
  858               END IF
  859
  860               csumj = zero
  861               IF( uscal.EQ.cmplx( one ) ) THEN
  862
  863
  864
  865
  866                  IF( upper ) THEN
  867                     csumj = 
cdotc( j-1, ap( ip-j+1 ), 1, x, 1 )
 
  868                  ELSE IF( j.LT.n ) THEN
  869                     csumj = 
cdotc( n-j, ap( ip+1 ), 1, x( j+1 ), 1 )
 
  870                  END IF
  871               ELSE
  872
  873
  874
  875                  IF( upper ) THEN
  876                     DO 160 i = 1, j - 1
  877                        csumj = csumj + ( conjg( ap( ip-j+i ) )*uscal )*
  878     $                          x( i )
  879  160                CONTINUE
  880                  ELSE IF( j.LT.n ) THEN
  881                     DO 170 i = 1, n - j
  882                        csumj = csumj + ( conjg( ap( ip+i ) )*uscal )*
  883     $                          x( j+i )
  884  170                CONTINUE
  885                  END IF
  886               END IF
  887
  888               IF( uscal.EQ.cmplx( tscal ) ) THEN
  889
  890
  891
  892
  893                  x( j ) = x( j ) - csumj
  894                  xj = cabs1( x( j ) )
  895                  IF( nounit ) THEN
  896
  897
  898
  899                     tjjs = conjg( ap( ip ) )*tscal
  900                  ELSE
  901                     tjjs = tscal
  902                     IF( tscal.EQ.one )
  903     $                  GO TO 185
  904                  END IF
  905                     tjj = cabs1( tjjs )
  906                     IF( tjj.GT.smlnum ) THEN
  907
  908
  909
  910                        IF( tjj.LT.one ) THEN
  911                           IF( xj.GT.tjj*bignum ) THEN
  912
  913
  914
  915                              rec = one / xj
  916                              CALL csscal( n, rec, x, 1 )
 
  917                              scale = scale*rec
  918                              xmax = xmax*rec
  919                           END IF
  920                        END IF
  921                        x( j ) = 
cladiv( x( j ), tjjs )
 
  922                     ELSE IF( tjj.GT.zero ) THEN
  923
  924
  925
  926                        IF( xj.GT.tjj*bignum ) THEN
  927
  928
  929
  930                           rec = ( tjj*bignum ) / xj
  931                           CALL csscal( n, rec, x, 1 )
 
  932                           scale = scale*rec
  933                           xmax = xmax*rec
  934                        END IF
  935                        x( j ) = 
cladiv( x( j ), tjjs )
 
  936                     ELSE
  937
  938
  939
  940
  941                        DO 180 i = 1, n
  942                           x( i ) = zero
  943  180                   CONTINUE
  944                        x( j ) = one
  945                        scale = zero
  946                        xmax = zero
  947                     END IF
  948  185             CONTINUE
  949               ELSE
  950
  951
  952
  953
  954                  x( j ) = 
cladiv( x( j ), tjjs ) - csumj
 
  955               END IF
  956               xmax = max( xmax, cabs1( x( j ) ) )
  957               jlen = jlen + 1
  958               ip = ip + jinc*jlen
  959  190       CONTINUE
  960         END IF
  961         scale = scale / tscal
  962      END IF
  963
  964
  965
  966      IF( tscal.NE.one ) THEN
  967         CALL sscal( n, one / tscal, cnorm, 1 )
 
  968      END IF
  969
  970      RETURN
  971
  972
  973
subroutine xerbla(srname, info)
real function scasum(n, cx, incx)
SCASUM
subroutine caxpy(n, ca, cx, incx, cy, incy)
CAXPY
complex function cdotu(n, cx, incx, cy, incy)
CDOTU
complex function cdotc(n, cx, incx, cy, incy)
CDOTC
integer function isamax(n, sx, incx)
ISAMAX
integer function icamax(n, cx, incx)
ICAMAX
complex function cladiv(x, y)
CLADIV performs complex division in real arithmetic, avoiding unnecessary overflow.
real function slamch(cmach)
SLAMCH
logical function lsame(ca, cb)
LSAME
subroutine csscal(n, sa, cx, incx)
CSSCAL
subroutine sscal(n, sa, sx, incx)
SSCAL
subroutine ctpsv(uplo, trans, diag, n, ap, x, incx)
CTPSV