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