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