00001 SUBROUTINE SLATPS( 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 AP( * ), CNORM( * ), X( * )
00016
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 REAL ZERO, HALF, ONE
00168 PARAMETER ( ZERO = 0.0E+0, HALF = 0.5E+0, ONE = 1.0E+0 )
00169
00170
00171 LOGICAL NOTRAN, NOUNIT, UPPER
00172 INTEGER I, IMAX, IP, J, JFIRST, JINC, JLAST, JLEN
00173 REAL BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,
00174 $ TMAX, TSCAL, USCAL, XBND, XJ, XMAX
00175
00176
00177 LOGICAL LSAME
00178 INTEGER ISAMAX
00179 REAL SASUM, SDOT, SLAMCH
00180 EXTERNAL LSAME, ISAMAX, SASUM, SDOT, SLAMCH
00181
00182
00183 EXTERNAL SAXPY, SSCAL, STPSV, XERBLA
00184
00185
00186 INTRINSIC ABS, MAX, MIN
00187
00188
00189
00190 INFO = 0
00191 UPPER = LSAME( UPLO, 'U' )
00192 NOTRAN = LSAME( TRANS, 'N' )
00193 NOUNIT = LSAME( DIAG, 'N' )
00194
00195
00196
00197 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00198 INFO = -1
00199 ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
00200 $ LSAME( TRANS, 'C' ) ) THEN
00201 INFO = -2
00202 ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
00203 INFO = -3
00204 ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.
00205 $ LSAME( NORMIN, 'N' ) ) THEN
00206 INFO = -4
00207 ELSE IF( N.LT.0 ) THEN
00208 INFO = -5
00209 END IF
00210 IF( INFO.NE.0 ) THEN
00211 CALL XERBLA( 'SLATPS', -INFO )
00212 RETURN
00213 END IF
00214
00215
00216
00217 IF( N.EQ.0 )
00218 $ RETURN
00219
00220
00221
00222 SMLNUM = SLAMCH( 'Safe minimum' ) / SLAMCH( 'Precision' )
00223 BIGNUM = ONE / SMLNUM
00224 SCALE = ONE
00225
00226 IF( LSAME( NORMIN, 'N' ) ) THEN
00227
00228
00229
00230 IF( UPPER ) THEN
00231
00232
00233
00234 IP = 1
00235 DO 10 J = 1, N
00236 CNORM( J ) = SASUM( J-1, AP( IP ), 1 )
00237 IP = IP + J
00238 10 CONTINUE
00239 ELSE
00240
00241
00242
00243 IP = 1
00244 DO 20 J = 1, N - 1
00245 CNORM( J ) = SASUM( N-J, AP( IP+1 ), 1 )
00246 IP = IP + N - J + 1
00247 20 CONTINUE
00248 CNORM( N ) = ZERO
00249 END IF
00250 END IF
00251
00252
00253
00254
00255 IMAX = ISAMAX( N, CNORM, 1 )
00256 TMAX = CNORM( IMAX )
00257 IF( TMAX.LE.BIGNUM ) THEN
00258 TSCAL = ONE
00259 ELSE
00260 TSCAL = ONE / ( SMLNUM*TMAX )
00261 CALL SSCAL( N, TSCAL, CNORM, 1 )
00262 END IF
00263
00264
00265
00266
00267 J = ISAMAX( N, X, 1 )
00268 XMAX = ABS( X( J ) )
00269 XBND = XMAX
00270 IF( NOTRAN ) THEN
00271
00272
00273
00274 IF( UPPER ) THEN
00275 JFIRST = N
00276 JLAST = 1
00277 JINC = -1
00278 ELSE
00279 JFIRST = 1
00280 JLAST = N
00281 JINC = 1
00282 END IF
00283
00284 IF( TSCAL.NE.ONE ) THEN
00285 GROW = ZERO
00286 GO TO 50
00287 END IF
00288
00289 IF( NOUNIT ) THEN
00290
00291
00292
00293
00294
00295
00296 GROW = ONE / MAX( XBND, SMLNUM )
00297 XBND = GROW
00298 IP = JFIRST*( JFIRST+1 ) / 2
00299 JLEN = N
00300 DO 30 J = JFIRST, JLAST, JINC
00301
00302
00303
00304 IF( GROW.LE.SMLNUM )
00305 $ GO TO 50
00306
00307
00308
00309 TJJ = ABS( AP( IP ) )
00310 XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )
00311 IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN
00312
00313
00314
00315 GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )
00316 ELSE
00317
00318
00319
00320 GROW = ZERO
00321 END IF
00322 IP = IP + JINC*JLEN
00323 JLEN = JLEN - 1
00324 30 CONTINUE
00325 GROW = XBND
00326 ELSE
00327
00328
00329
00330
00331
00332 GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
00333 DO 40 J = JFIRST, JLAST, JINC
00334
00335
00336
00337 IF( GROW.LE.SMLNUM )
00338 $ GO TO 50
00339
00340
00341
00342 GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )
00343 40 CONTINUE
00344 END IF
00345 50 CONTINUE
00346
00347 ELSE
00348
00349
00350
00351 IF( UPPER ) THEN
00352 JFIRST = 1
00353 JLAST = N
00354 JINC = 1
00355 ELSE
00356 JFIRST = N
00357 JLAST = 1
00358 JINC = -1
00359 END IF
00360
00361 IF( TSCAL.NE.ONE ) THEN
00362 GROW = ZERO
00363 GO TO 80
00364 END IF
00365
00366 IF( NOUNIT ) THEN
00367
00368
00369
00370
00371
00372
00373 GROW = ONE / MAX( XBND, SMLNUM )
00374 XBND = GROW
00375 IP = JFIRST*( JFIRST+1 ) / 2
00376 JLEN = 1
00377 DO 60 J = JFIRST, JLAST, JINC
00378
00379
00380
00381 IF( GROW.LE.SMLNUM )
00382 $ GO TO 80
00383
00384
00385
00386 XJ = ONE + CNORM( J )
00387 GROW = MIN( GROW, XBND / XJ )
00388
00389
00390
00391 TJJ = ABS( AP( IP ) )
00392 IF( XJ.GT.TJJ )
00393 $ XBND = XBND*( TJJ / XJ )
00394 JLEN = JLEN + 1
00395 IP = IP + JINC*JLEN
00396 60 CONTINUE
00397 GROW = MIN( GROW, XBND )
00398 ELSE
00399
00400
00401
00402
00403
00404 GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )
00405 DO 70 J = JFIRST, JLAST, JINC
00406
00407
00408
00409 IF( GROW.LE.SMLNUM )
00410 $ GO TO 80
00411
00412
00413
00414 XJ = ONE + CNORM( J )
00415 GROW = GROW / XJ
00416 70 CONTINUE
00417 END IF
00418 80 CONTINUE
00419 END IF
00420
00421 IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN
00422
00423
00424
00425
00426 CALL STPSV( UPLO, TRANS, DIAG, N, AP, X, 1 )
00427 ELSE
00428
00429
00430
00431 IF( XMAX.GT.BIGNUM ) THEN
00432
00433
00434
00435
00436 SCALE = BIGNUM / XMAX
00437 CALL SSCAL( N, SCALE, X, 1 )
00438 XMAX = BIGNUM
00439 END IF
00440
00441 IF( NOTRAN ) THEN
00442
00443
00444
00445 IP = JFIRST*( JFIRST+1 ) / 2
00446 DO 100 J = JFIRST, JLAST, JINC
00447
00448
00449
00450 XJ = ABS( X( J ) )
00451 IF( NOUNIT ) THEN
00452 TJJS = AP( IP )*TSCAL
00453 ELSE
00454 TJJS = TSCAL
00455 IF( TSCAL.EQ.ONE )
00456 $ GO TO 95
00457 END IF
00458 TJJ = ABS( TJJS )
00459 IF( TJJ.GT.SMLNUM ) THEN
00460
00461
00462
00463 IF( TJJ.LT.ONE ) THEN
00464 IF( XJ.GT.TJJ*BIGNUM ) THEN
00465
00466
00467
00468 REC = ONE / XJ
00469 CALL SSCAL( N, REC, X, 1 )
00470 SCALE = SCALE*REC
00471 XMAX = XMAX*REC
00472 END IF
00473 END IF
00474 X( J ) = X( J ) / TJJS
00475 XJ = ABS( X( J ) )
00476 ELSE IF( TJJ.GT.ZERO ) THEN
00477
00478
00479
00480 IF( XJ.GT.TJJ*BIGNUM ) THEN
00481
00482
00483
00484
00485 REC = ( TJJ*BIGNUM ) / XJ
00486 IF( CNORM( J ).GT.ONE ) THEN
00487
00488
00489
00490
00491 REC = REC / CNORM( J )
00492 END IF
00493 CALL SSCAL( N, REC, X, 1 )
00494 SCALE = SCALE*REC
00495 XMAX = XMAX*REC
00496 END IF
00497 X( J ) = X( J ) / TJJS
00498 XJ = ABS( X( J ) )
00499 ELSE
00500
00501
00502
00503
00504 DO 90 I = 1, N
00505 X( I ) = ZERO
00506 90 CONTINUE
00507 X( J ) = ONE
00508 XJ = ONE
00509 SCALE = ZERO
00510 XMAX = ZERO
00511 END IF
00512 95 CONTINUE
00513
00514
00515
00516
00517 IF( XJ.GT.ONE ) THEN
00518 REC = ONE / XJ
00519 IF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN
00520
00521
00522
00523 REC = REC*HALF
00524 CALL SSCAL( N, REC, X, 1 )
00525 SCALE = SCALE*REC
00526 END IF
00527 ELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN
00528
00529
00530
00531 CALL SSCAL( N, HALF, X, 1 )
00532 SCALE = SCALE*HALF
00533 END IF
00534
00535 IF( UPPER ) THEN
00536 IF( J.GT.1 ) THEN
00537
00538
00539
00540
00541 CALL SAXPY( J-1, -X( J )*TSCAL, AP( IP-J+1 ), 1, X,
00542 $ 1 )
00543 I = ISAMAX( J-1, X, 1 )
00544 XMAX = ABS( X( I ) )
00545 END IF
00546 IP = IP - J
00547 ELSE
00548 IF( J.LT.N ) THEN
00549
00550
00551
00552
00553 CALL SAXPY( N-J, -X( J )*TSCAL, AP( IP+1 ), 1,
00554 $ X( J+1 ), 1 )
00555 I = J + ISAMAX( N-J, X( J+1 ), 1 )
00556 XMAX = ABS( X( I ) )
00557 END IF
00558 IP = IP + N - J + 1
00559 END IF
00560 100 CONTINUE
00561
00562 ELSE
00563
00564
00565
00566 IP = JFIRST*( JFIRST+1 ) / 2
00567 JLEN = 1
00568 DO 140 J = JFIRST, JLAST, JINC
00569
00570
00571
00572
00573 XJ = ABS( X( J ) )
00574 USCAL = TSCAL
00575 REC = ONE / MAX( XMAX, ONE )
00576 IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN
00577
00578
00579
00580 REC = REC*HALF
00581 IF( NOUNIT ) THEN
00582 TJJS = AP( IP )*TSCAL
00583 ELSE
00584 TJJS = TSCAL
00585 END IF
00586 TJJ = ABS( TJJS )
00587 IF( TJJ.GT.ONE ) THEN
00588
00589
00590
00591 REC = MIN( ONE, REC*TJJ )
00592 USCAL = USCAL / TJJS
00593 END IF
00594 IF( REC.LT.ONE ) THEN
00595 CALL SSCAL( N, REC, X, 1 )
00596 SCALE = SCALE*REC
00597 XMAX = XMAX*REC
00598 END IF
00599 END IF
00600
00601 SUMJ = ZERO
00602 IF( USCAL.EQ.ONE ) THEN
00603
00604
00605
00606
00607 IF( UPPER ) THEN
00608 SUMJ = SDOT( J-1, AP( IP-J+1 ), 1, X, 1 )
00609 ELSE IF( J.LT.N ) THEN
00610 SUMJ = SDOT( N-J, AP( IP+1 ), 1, X( J+1 ), 1 )
00611 END IF
00612 ELSE
00613
00614
00615
00616 IF( UPPER ) THEN
00617 DO 110 I = 1, J - 1
00618 SUMJ = SUMJ + ( AP( IP-J+I )*USCAL )*X( I )
00619 110 CONTINUE
00620 ELSE IF( J.LT.N ) THEN
00621 DO 120 I = 1, N - J
00622 SUMJ = SUMJ + ( AP( IP+I )*USCAL )*X( J+I )
00623 120 CONTINUE
00624 END IF
00625 END IF
00626
00627 IF( USCAL.EQ.TSCAL ) THEN
00628
00629
00630
00631
00632 X( J ) = X( J ) - SUMJ
00633 XJ = ABS( X( J ) )
00634 IF( NOUNIT ) THEN
00635
00636
00637
00638 TJJS = AP( IP )*TSCAL
00639 ELSE
00640 TJJS = TSCAL
00641 IF( TSCAL.EQ.ONE )
00642 $ GO TO 135
00643 END IF
00644 TJJ = ABS( TJJS )
00645 IF( TJJ.GT.SMLNUM ) THEN
00646
00647
00648
00649 IF( TJJ.LT.ONE ) THEN
00650 IF( XJ.GT.TJJ*BIGNUM ) THEN
00651
00652
00653
00654 REC = ONE / XJ
00655 CALL SSCAL( N, REC, X, 1 )
00656 SCALE = SCALE*REC
00657 XMAX = XMAX*REC
00658 END IF
00659 END IF
00660 X( J ) = X( J ) / TJJS
00661 ELSE IF( TJJ.GT.ZERO ) THEN
00662
00663
00664
00665 IF( XJ.GT.TJJ*BIGNUM ) THEN
00666
00667
00668
00669 REC = ( TJJ*BIGNUM ) / XJ
00670 CALL SSCAL( N, REC, X, 1 )
00671 SCALE = SCALE*REC
00672 XMAX = XMAX*REC
00673 END IF
00674 X( J ) = X( J ) / TJJS
00675 ELSE
00676
00677
00678
00679
00680 DO 130 I = 1, N
00681 X( I ) = ZERO
00682 130 CONTINUE
00683 X( J ) = ONE
00684 SCALE = ZERO
00685 XMAX = ZERO
00686 END IF
00687 135 CONTINUE
00688 ELSE
00689
00690
00691
00692
00693 X( J ) = X( J ) / TJJS - SUMJ
00694 END IF
00695 XMAX = MAX( XMAX, ABS( X( J ) ) )
00696 JLEN = JLEN + 1
00697 IP = IP + JINC*JLEN
00698 140 CONTINUE
00699 END IF
00700 SCALE = SCALE / TSCAL
00701 END IF
00702
00703
00704
00705 IF( TSCAL.NE.ONE ) THEN
00706 CALL SSCAL( N, ONE / TSCAL, CNORM, 1 )
00707 END IF
00708
00709 RETURN
00710
00711
00712
00713 END