00001 SUBROUTINE CLATPS( UPLO, TRANS, DIAG, NORMIN, N, AP, X, SCALE,
00002 $ CNORM, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 CHARACTER DIAG, NORMIN, TRANS, UPLO
00011 INTEGER INFO, N
00012 REAL SCALE
00013
00014
00015 REAL CNORM( * )
00016 COMPLEX AP( * ), X( * )
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 REAL ZERO, HALF, ONE, TWO
00170 PARAMETER ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0,
00171 $ TWO = 2.0E+0 )
00172
00173
00174 LOGICAL NOTRAN, NOUNIT, UPPER
00175 INTEGER I, IMAX, IP, J, JFIRST, JINC, JLAST, JLEN
00176 REAL BIGNUM, GROW, REC, SMLNUM, TJJ, TMAX, TSCAL,
00177 $ XBND, XJ, XMAX
00178 COMPLEX CSUMJ, TJJS, USCAL, ZDUM
00179
00180
00181 LOGICAL LSAME
00182 INTEGER ICAMAX, ISAMAX
00183 REAL SCASUM, SLAMCH
00184 COMPLEX CDOTC, CDOTU, CLADIV
00185 EXTERNAL LSAME, ICAMAX, ISAMAX, SCASUM, SLAMCH, CDOTC,
00186 $ CDOTU, CLADIV
00187
00188
00189 EXTERNAL CAXPY, CSSCAL, CTPSV, SLABAD, SSCAL, XERBLA
00190
00191
00192 INTRINSIC ABS, AIMAG, CMPLX, CONJG, MAX, MIN, REAL
00193
00194
00195 REAL CABS1, CABS2
00196
00197
00198 CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
00199 CABS2( ZDUM ) = ABS( REAL( ZDUM ) / 2. ) +
00200 $ ABS( AIMAG( ZDUM ) / 2. )
00201
00202
00203
00204 INFO = 0
00205 UPPER = LSAME( UPLO, 'U' )
00206 NOTRAN = LSAME( TRANS, 'N' )
00207 NOUNIT = LSAME( DIAG, 'N' )
00208
00209
00210
00211 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00212 INFO = -1
00213 ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
00214 $ LSAME( TRANS, 'C' ) ) THEN
00215 INFO = -2
00216 ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
00217 INFO = -3
00218 ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
00219 $ LSAME( NORMIN, 'N' ) ) THEN
00220 INFO = -4
00221 ELSE IF( N.LT.0 ) THEN
00222 INFO = -5
00223 END IF
00224 IF( INFO.NE.0 ) THEN
00225 CALL XERBLA( 'CLATPS', -INFO )
00226 RETURN
00227 END IF
00228
00229
00230
00231 IF( N.EQ.0 )
00232 $ RETURN
00233
00234
00235
00236 SMLNUM = SLAMCH( 'Safe minimum' )
00237 BIGNUM = ONE / SMLNUM
00238 CALL SLABAD( SMLNUM, BIGNUM )
00239 SMLNUM = SMLNUM / SLAMCH( 'Precision' )
00240 BIGNUM = ONE / SMLNUM
00241 SCALE = ONE
00242
00243 IF( LSAME( NORMIN, 'N' ) ) THEN
00244
00245
00246
00247 IF( UPPER ) THEN
00248
00249
00250
00251 IP = 1
00252 DO 10 J = 1, N
00253 CNORM( J ) = SCASUM( J-1, AP( IP ), 1 )
00254 IP = IP + J
00255 10 CONTINUE
00256 ELSE
00257
00258
00259
00260 IP = 1
00261 DO 20 J = 1, N - 1
00262 CNORM( J ) = SCASUM( N-J, AP( IP+1 ), 1 )
00263 IP = IP + N - J + 1
00264 20 CONTINUE
00265 CNORM( N ) = ZERO
00266 END IF
00267 END IF
00268
00269
00270
00271
00272 IMAX = ISAMAX( N, CNORM, 1 )
00273 TMAX = CNORM( IMAX )
00274 IF( TMAX.LE.BIGNUM*HALF ) THEN
00275 TSCAL = ONE
00276 ELSE
00277 TSCAL = HALF / ( SMLNUM*TMAX )
00278 CALL SSCAL( N, TSCAL, CNORM, 1 )
00279 END IF
00280
00281
00282
00283
00284 XMAX = ZERO
00285 DO 30 J = 1, N
00286 XMAX = MAX( XMAX, CABS2( X( J ) ) )
00287 30 CONTINUE
00288 XBND = XMAX
00289 IF( NOTRAN ) THEN
00290
00291
00292
00293 IF( UPPER ) THEN
00294 JFIRST = N
00295 JLAST = 1
00296 JINC = -1
00297 ELSE
00298 JFIRST = 1
00299 JLAST = N
00300 JINC = 1
00301 END IF
00302
00303 IF( TSCAL.NE.ONE ) THEN
00304 GROW = ZERO
00305 GO TO 60
00306 END IF
00307
00308 IF( NOUNIT ) THEN
00309
00310
00311
00312
00313
00314
00315 GROW = HALF / MAX( XBND, SMLNUM )
00316 XBND = GROW
00317 IP = JFIRST*( JFIRST+1 ) / 2
00318 JLEN = N
00319 DO 40 J = JFIRST, JLAST, JINC
00320
00321
00322
00323 IF( GROW.LE.SMLNUM )
00324 $ GO TO 60
00325
00326 TJJS = AP( IP )
00327 TJJ = CABS1( TJJS )
00328
00329 IF( TJJ.GE.SMLNUM ) THEN
00330
00331
00332
00333 XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
00334 ELSE
00335
00336
00337
00338 XBND = ZERO
00339 END IF
00340
00341 IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
00342
00343
00344
00345 GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
00346 ELSE
00347
00348
00349
00350 GROW = ZERO
00351 END IF
00352 IP = IP + JINC*JLEN
00353 JLEN = JLEN - 1
00354 40 CONTINUE
00355 GROW = XBND
00356 ELSE
00357
00358
00359
00360
00361
00362 GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
00363 DO 50 J = JFIRST, JLAST, JINC
00364
00365
00366
00367 IF( GROW.LE.SMLNUM )
00368 $ GO TO 60
00369
00370
00371
00372 GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
00373 50 CONTINUE
00374 END IF
00375 60 CONTINUE
00376
00377 ELSE
00378
00379
00380
00381 IF( UPPER ) THEN
00382 JFIRST = 1
00383 JLAST = N
00384 JINC = 1
00385 ELSE
00386 JFIRST = N
00387 JLAST = 1
00388 JINC = -1
00389 END IF
00390
00391 IF( TSCAL.NE.ONE ) THEN
00392 GROW = ZERO
00393 GO TO 90
00394 END IF
00395
00396 IF( NOUNIT ) THEN
00397
00398
00399
00400
00401
00402
00403 GROW = HALF / MAX( XBND, SMLNUM )
00404 XBND = GROW
00405 IP = JFIRST*( JFIRST+1 ) / 2
00406 JLEN = 1
00407 DO 70 J = JFIRST, JLAST, JINC
00408
00409
00410
00411 IF( GROW.LE.SMLNUM )
00412 $ GO TO 90
00413
00414
00415
00416 XJ = ONE + CNORM( J )
00417 GROW = MIN( GROW, XBND / XJ )
00418
00419 TJJS = AP( IP )
00420 TJJ = CABS1( TJJS )
00421
00422 IF( TJJ.GE.SMLNUM ) THEN
00423
00424
00425
00426 IF( XJ.GT.TJJ )
00427 $ XBND = XBND*( TJJ / XJ )
00428 ELSE
00429
00430
00431
00432 XBND = ZERO
00433 END IF
00434 JLEN = JLEN + 1
00435 IP = IP + JINC*JLEN
00436 70 CONTINUE
00437 GROW = MIN( GROW, XBND )
00438 ELSE
00439
00440
00441
00442
00443
00444 GROW = MIN( ONE, HALF / MAX( XBND, SMLNUM ) )
00445 DO 80 J = JFIRST, JLAST, JINC
00446
00447
00448
00449 IF( GROW.LE.SMLNUM )
00450 $ GO TO 90
00451
00452
00453
00454 XJ = ONE + CNORM( J )
00455 GROW = GROW / XJ
00456 80 CONTINUE
00457 END IF
00458 90 CONTINUE
00459 END IF
00460
00461 IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
00462
00463
00464
00465
00466 CALL CTPSV( UPLO, TRANS, DIAG, N, AP, X, 1 )
00467 ELSE
00468
00469
00470
00471 IF( XMAX.GT.BIGNUM*HALF ) THEN
00472
00473
00474
00475
00476 SCALE = ( BIGNUM*HALF ) / XMAX
00477 CALL CSSCAL( N, SCALE, X, 1 )
00478 XMAX = BIGNUM
00479 ELSE
00480 XMAX = XMAX*TWO
00481 END IF
00482
00483 IF( NOTRAN ) THEN
00484
00485
00486
00487 IP = JFIRST*( JFIRST+1 ) / 2
00488 DO 110 J = JFIRST, JLAST, JINC
00489
00490
00491
00492 XJ = CABS1( X( J ) )
00493 IF( NOUNIT ) THEN
00494 TJJS = AP( IP )*TSCAL
00495 ELSE
00496 TJJS = TSCAL
00497 IF( TSCAL.EQ.ONE )
00498 $ GO TO 105
00499 END IF
00500 TJJ = CABS1( TJJS )
00501 IF( TJJ.GT.SMLNUM ) THEN
00502
00503
00504
00505 IF( TJJ.LT.ONE ) THEN
00506 IF( XJ.GT.TJJ*BIGNUM ) THEN
00507
00508
00509
00510 REC = ONE / XJ
00511 CALL CSSCAL( N, REC, X, 1 )
00512 SCALE = SCALE*REC
00513 XMAX = XMAX*REC
00514 END IF
00515 END IF
00516 X( J ) = CLADIV( X( J ), TJJS )
00517 XJ = CABS1( X( J ) )
00518 ELSE IF( TJJ.GT.ZERO ) THEN
00519
00520
00521
00522 IF( XJ.GT.TJJ*BIGNUM ) THEN
00523
00524
00525
00526
00527 REC = ( TJJ*BIGNUM ) / XJ
00528 IF( CNORM( J ).GT.ONE ) THEN
00529
00530
00531
00532
00533 REC = REC / CNORM( J )
00534 END IF
00535 CALL CSSCAL( N, REC, X, 1 )
00536 SCALE = SCALE*REC
00537 XMAX = XMAX*REC
00538 END IF
00539 X( J ) = CLADIV( X( J ), TJJS )
00540 XJ = CABS1( X( J ) )
00541 ELSE
00542
00543
00544
00545
00546 DO 100 I = 1, N
00547 X( I ) = ZERO
00548 100 CONTINUE
00549 X( J ) = ONE
00550 XJ = ONE
00551 SCALE = ZERO
00552 XMAX = ZERO
00553 END IF
00554 105 CONTINUE
00555
00556
00557
00558
00559 IF( XJ.GT.ONE ) THEN
00560 REC = ONE / XJ
00561 IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
00562
00563
00564
00565 REC = REC*HALF
00566 CALL CSSCAL( N, REC, X, 1 )
00567 SCALE = SCALE*REC
00568 END IF
00569 ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
00570
00571
00572
00573 CALL CSSCAL( N, HALF, X, 1 )
00574 SCALE = SCALE*HALF
00575 END IF
00576
00577 IF( UPPER ) THEN
00578 IF( J.GT.1 ) THEN
00579
00580
00581
00582
00583 CALL CAXPY( J-1, -X( J )*TSCAL, AP( IP-J+1 ), 1, X,
00584 $ 1 )
00585 I = ICAMAX( J-1, X, 1 )
00586 XMAX = CABS1( X( I ) )
00587 END IF
00588 IP = IP - J
00589 ELSE
00590 IF( J.LT.N ) THEN
00591
00592
00593
00594
00595 CALL CAXPY( N-J, -X( J )*TSCAL, AP( IP+1 ), 1,
00596 $ X( J+1 ), 1 )
00597 I = J + ICAMAX( N-J, X( J+1 ), 1 )
00598 XMAX = CABS1( X( I ) )
00599 END IF
00600 IP = IP + N - J + 1
00601 END IF
00602 110 CONTINUE
00603
00604 ELSE IF( LSAME( TRANS, 'T' ) ) THEN
00605
00606
00607
00608 IP = JFIRST*( JFIRST+1 ) / 2
00609 JLEN = 1
00610 DO 150 J = JFIRST, JLAST, JINC
00611
00612
00613
00614
00615 XJ = CABS1( X( J ) )
00616 USCAL = TSCAL
00617 REC = ONE / MAX( XMAX, ONE )
00618 IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
00619
00620
00621
00622 REC = REC*HALF
00623 IF( NOUNIT ) THEN
00624 TJJS = AP( IP )*TSCAL
00625 ELSE
00626 TJJS = TSCAL
00627 END IF
00628 TJJ = CABS1( TJJS )
00629 IF( TJJ.GT.ONE ) THEN
00630
00631
00632
00633 REC = MIN( ONE, REC*TJJ )
00634 USCAL = CLADIV( USCAL, TJJS )
00635 END IF
00636 IF( REC.LT.ONE ) THEN
00637 CALL CSSCAL( N, REC, X, 1 )
00638 SCALE = SCALE*REC
00639 XMAX = XMAX*REC
00640 END IF
00641 END IF
00642
00643 CSUMJ = ZERO
00644 IF( USCAL.EQ.CMPLX( ONE ) ) THEN
00645
00646
00647
00648
00649 IF( UPPER ) THEN
00650 CSUMJ = CDOTU( J-1, AP( IP-J+1 ), 1, X, 1 )
00651 ELSE IF( J.LT.N ) THEN
00652 CSUMJ = CDOTU( N-J, AP( IP+1 ), 1, X( J+1 ), 1 )
00653 END IF
00654 ELSE
00655
00656
00657
00658 IF( UPPER ) THEN
00659 DO 120 I = 1, J - 1
00660 CSUMJ = CSUMJ + ( AP( IP-J+I )*USCAL )*X( I )
00661 120 CONTINUE
00662 ELSE IF( J.LT.N ) THEN
00663 DO 130 I = 1, N - J
00664 CSUMJ = CSUMJ + ( AP( IP+I )*USCAL )*X( J+I )
00665 130 CONTINUE
00666 END IF
00667 END IF
00668
00669 IF( USCAL.EQ.CMPLX( TSCAL ) ) THEN
00670
00671
00672
00673
00674 X( J ) = X( J ) - CSUMJ
00675 XJ = CABS1( X( J ) )
00676 IF( NOUNIT ) THEN
00677
00678
00679
00680 TJJS = AP( IP )*TSCAL
00681 ELSE
00682 TJJS = TSCAL
00683 IF( TSCAL.EQ.ONE )
00684 $ GO TO 145
00685 END IF
00686 TJJ = CABS1( TJJS )
00687 IF( TJJ.GT.SMLNUM ) THEN
00688
00689
00690
00691 IF( TJJ.LT.ONE ) THEN
00692 IF( XJ.GT.TJJ*BIGNUM ) THEN
00693
00694
00695
00696 REC = ONE / XJ
00697 CALL CSSCAL( N, REC, X, 1 )
00698 SCALE = SCALE*REC
00699 XMAX = XMAX*REC
00700 END IF
00701 END IF
00702 X( J ) = CLADIV( X( J ), TJJS )
00703 ELSE IF( TJJ.GT.ZERO ) THEN
00704
00705
00706
00707 IF( XJ.GT.TJJ*BIGNUM ) THEN
00708
00709
00710
00711 REC = ( TJJ*BIGNUM ) / XJ
00712 CALL CSSCAL( N, REC, X, 1 )
00713 SCALE = SCALE*REC
00714 XMAX = XMAX*REC
00715 END IF
00716 X( J ) = CLADIV( X( J ), TJJS )
00717 ELSE
00718
00719
00720
00721
00722 DO 140 I = 1, N
00723 X( I ) = ZERO
00724 140 CONTINUE
00725 X( J ) = ONE
00726 SCALE = ZERO
00727 XMAX = ZERO
00728 END IF
00729 145 CONTINUE
00730 ELSE
00731
00732
00733
00734
00735 X( J ) = CLADIV( X( J ), TJJS ) - CSUMJ
00736 END IF
00737 XMAX = MAX( XMAX, CABS1( X( J ) ) )
00738 JLEN = JLEN + 1
00739 IP = IP + JINC*JLEN
00740 150 CONTINUE
00741
00742 ELSE
00743
00744
00745
00746 IP = JFIRST*( JFIRST+1 ) / 2
00747 JLEN = 1
00748 DO 190 J = JFIRST, JLAST, JINC
00749
00750
00751
00752
00753 XJ = CABS1( X( J ) )
00754 USCAL = TSCAL
00755 REC = ONE / MAX( XMAX, ONE )
00756 IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
00757
00758
00759
00760 REC = REC*HALF
00761 IF( NOUNIT ) THEN
00762 TJJS = CONJG( AP( IP ) )*TSCAL
00763 ELSE
00764 TJJS = TSCAL
00765 END IF
00766 TJJ = CABS1( TJJS )
00767 IF( TJJ.GT.ONE ) THEN
00768
00769
00770
00771 REC = MIN( ONE, REC*TJJ )
00772 USCAL = CLADIV( USCAL, TJJS )
00773 END IF
00774 IF( REC.LT.ONE ) THEN
00775 CALL CSSCAL( N, REC, X, 1 )
00776 SCALE = SCALE*REC
00777 XMAX = XMAX*REC
00778 END IF
00779 END IF
00780
00781 CSUMJ = ZERO
00782 IF( USCAL.EQ.CMPLX( ONE ) ) THEN
00783
00784
00785
00786
00787 IF( UPPER ) THEN
00788 CSUMJ = CDOTC( J-1, AP( IP-J+1 ), 1, X, 1 )
00789 ELSE IF( J.LT.N ) THEN
00790 CSUMJ = CDOTC( N-J, AP( IP+1 ), 1, X( J+1 ), 1 )
00791 END IF
00792 ELSE
00793
00794
00795
00796 IF( UPPER ) THEN
00797 DO 160 I = 1, J - 1
00798 CSUMJ = CSUMJ + ( CONJG( AP( IP-J+I ) )*USCAL )*
00799 $ X( I )
00800 160 CONTINUE
00801 ELSE IF( J.LT.N ) THEN
00802 DO 170 I = 1, N - J
00803 CSUMJ = CSUMJ + ( CONJG( AP( IP+I ) )*USCAL )*
00804 $ X( J+I )
00805 170 CONTINUE
00806 END IF
00807 END IF
00808
00809 IF( USCAL.EQ.CMPLX( TSCAL ) ) THEN
00810
00811
00812
00813
00814 X( J ) = X( J ) - CSUMJ
00815 XJ = CABS1( X( J ) )
00816 IF( NOUNIT ) THEN
00817
00818
00819
00820 TJJS = CONJG( AP( IP ) )*TSCAL
00821 ELSE
00822 TJJS = TSCAL
00823 IF( TSCAL.EQ.ONE )
00824 $ GO TO 185
00825 END IF
00826 TJJ = CABS1( TJJS )
00827 IF( TJJ.GT.SMLNUM ) THEN
00828
00829
00830
00831 IF( TJJ.LT.ONE ) THEN
00832 IF( XJ.GT.TJJ*BIGNUM ) THEN
00833
00834
00835
00836 REC = ONE / XJ
00837 CALL CSSCAL( N, REC, X, 1 )
00838 SCALE = SCALE*REC
00839 XMAX = XMAX*REC
00840 END IF
00841 END IF
00842 X( J ) = CLADIV( X( J ), TJJS )
00843 ELSE IF( TJJ.GT.ZERO ) THEN
00844
00845
00846
00847 IF( XJ.GT.TJJ*BIGNUM ) THEN
00848
00849
00850
00851 REC = ( TJJ*BIGNUM ) / XJ
00852 CALL CSSCAL( N, REC, X, 1 )
00853 SCALE = SCALE*REC
00854 XMAX = XMAX*REC
00855 END IF
00856 X( J ) = CLADIV( X( J ), TJJS )
00857 ELSE
00858
00859
00860
00861
00862 DO 180 I = 1, N
00863 X( I ) = ZERO
00864 180 CONTINUE
00865 X( J ) = ONE
00866 SCALE = ZERO
00867 XMAX = ZERO
00868 END IF
00869 185 CONTINUE
00870 ELSE
00871
00872
00873
00874
00875 X( J ) = CLADIV( X( J ), TJJS ) - CSUMJ
00876 END IF
00877 XMAX = MAX( XMAX, CABS1( X( J ) ) )
00878 JLEN = JLEN + 1
00879 IP = IP + JINC*JLEN
00880 190 CONTINUE
00881 END IF
00882 SCALE = SCALE / TSCAL
00883 END IF
00884
00885
00886
00887 IF( TSCAL.NE.ONE ) THEN
00888 CALL SSCAL( N, ONE / TSCAL, CNORM, 1 )
00889 END IF
00890
00891 RETURN
00892
00893
00894
00895 END