00001 SUBROUTINE SSTEBZ( RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D, E,
00002 $ M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK,
00003 $ INFO )
00004
00005
00006
00007
00008
00009
00010
00011
00012 CHARACTER ORDER, RANGE
00013 INTEGER IL, INFO, IU, M, N, NSPLIT
00014 REAL ABSTOL, VL, VU
00015
00016
00017 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * )
00018 REAL D( * ), E( * ), W( * ), WORK( * )
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
00175 REAL ZERO, ONE, TWO, HALF
00176 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
00177 $ HALF = 1.0E0 / TWO )
00178 REAL FUDGE, RELFAC
00179 PARAMETER ( FUDGE = 2.1E0, RELFAC = 2.0E0 )
00180
00181
00182 LOGICAL NCNVRG, TOOFEW
00183 INTEGER IB, IBEGIN, IDISCL, IDISCU, IE, IEND, IINFO,
00184 $ IM, IN, IOFF, IORDER, IOUT, IRANGE, ITMAX,
00185 $ ITMP1, IW, IWOFF, J, JB, JDISC, JE, NB, NWL,
00186 $ NWU
00187 REAL ATOLI, BNORM, GL, GU, PIVMIN, RTOLI, SAFEMN,
00188 $ TMP1, TMP2, TNORM, ULP, WKILL, WL, WLU, WU, WUL
00189
00190
00191 INTEGER IDUMMA( 1 )
00192
00193
00194 LOGICAL LSAME
00195 INTEGER ILAENV
00196 REAL SLAMCH
00197 EXTERNAL LSAME, ILAENV, SLAMCH
00198
00199
00200 EXTERNAL SLAEBZ, XERBLA
00201
00202
00203 INTRINSIC ABS, INT, LOG, MAX, MIN, SQRT
00204
00205
00206
00207 INFO = 0
00208
00209
00210
00211 IF( LSAME( RANGE, 'A' ) ) THEN
00212 IRANGE = 1
00213 ELSE IF( LSAME( RANGE, 'V' ) ) THEN
00214 IRANGE = 2
00215 ELSE IF( LSAME( RANGE, 'I' ) ) THEN
00216 IRANGE = 3
00217 ELSE
00218 IRANGE = 0
00219 END IF
00220
00221
00222
00223 IF( LSAME( ORDER, 'B' ) ) THEN
00224 IORDER = 2
00225 ELSE IF( LSAME( ORDER, 'E' ) ) THEN
00226 IORDER = 1
00227 ELSE
00228 IORDER = 0
00229 END IF
00230
00231
00232
00233 IF( IRANGE.LE.0 ) THEN
00234 INFO = -1
00235 ELSE IF( IORDER.LE.0 ) THEN
00236 INFO = -2
00237 ELSE IF( N.LT.0 ) THEN
00238 INFO = -3
00239 ELSE IF( IRANGE.EQ.2 ) THEN
00240 IF( VL.GE.VU ) INFO = -5
00241 ELSE IF( IRANGE.EQ.3 .AND. ( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) )
00242 $ THEN
00243 INFO = -6
00244 ELSE IF( IRANGE.EQ.3 .AND. ( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) )
00245 $ THEN
00246 INFO = -7
00247 END IF
00248
00249 IF( INFO.NE.0 ) THEN
00250 CALL XERBLA( 'SSTEBZ', -INFO )
00251 RETURN
00252 END IF
00253
00254
00255
00256 INFO = 0
00257 NCNVRG = .FALSE.
00258 TOOFEW = .FALSE.
00259
00260
00261
00262 M = 0
00263 IF( N.EQ.0 )
00264 $ RETURN
00265
00266
00267
00268 IF( IRANGE.EQ.3 .AND. IL.EQ.1 .AND. IU.EQ.N )
00269 $ IRANGE = 1
00270
00271
00272
00273
00274
00275 SAFEMN = SLAMCH( 'S' )
00276 ULP = SLAMCH( 'P' )
00277 RTOLI = ULP*RELFAC
00278 NB = ILAENV( 1, 'SSTEBZ', ' ', N, -1, -1, -1 )
00279 IF( NB.LE.1 )
00280 $ NB = 0
00281
00282
00283
00284 IF( N.EQ.1 ) THEN
00285 NSPLIT = 1
00286 ISPLIT( 1 ) = 1
00287 IF( IRANGE.EQ.2 .AND. ( VL.GE.D( 1 ) .OR. VU.LT.D( 1 ) ) ) THEN
00288 M = 0
00289 ELSE
00290 W( 1 ) = D( 1 )
00291 IBLOCK( 1 ) = 1
00292 M = 1
00293 END IF
00294 RETURN
00295 END IF
00296
00297
00298
00299 NSPLIT = 1
00300 WORK( N ) = ZERO
00301 PIVMIN = ONE
00302
00303
00304 DO 10 J = 2, N
00305 TMP1 = E( J-1 )**2
00306 IF( ABS( D( J )*D( J-1 ) )*ULP**2+SAFEMN.GT.TMP1 ) THEN
00307 ISPLIT( NSPLIT ) = J - 1
00308 NSPLIT = NSPLIT + 1
00309 WORK( J-1 ) = ZERO
00310 ELSE
00311 WORK( J-1 ) = TMP1
00312 PIVMIN = MAX( PIVMIN, TMP1 )
00313 END IF
00314 10 CONTINUE
00315 ISPLIT( NSPLIT ) = N
00316 PIVMIN = PIVMIN*SAFEMN
00317
00318
00319
00320 IF( IRANGE.EQ.3 ) THEN
00321
00322
00323
00324
00325
00326
00327
00328 GU = D( 1 )
00329 GL = D( 1 )
00330 TMP1 = ZERO
00331
00332 DO 20 J = 1, N - 1
00333 TMP2 = SQRT( WORK( J ) )
00334 GU = MAX( GU, D( J )+TMP1+TMP2 )
00335 GL = MIN( GL, D( J )-TMP1-TMP2 )
00336 TMP1 = TMP2
00337 20 CONTINUE
00338
00339 GU = MAX( GU, D( N )+TMP1 )
00340 GL = MIN( GL, D( N )-TMP1 )
00341 TNORM = MAX( ABS( GL ), ABS( GU ) )
00342 GL = GL - FUDGE*TNORM*ULP*N - FUDGE*TWO*PIVMIN
00343 GU = GU + FUDGE*TNORM*ULP*N + FUDGE*PIVMIN
00344
00345
00346
00347 ITMAX = INT( ( LOG( TNORM+PIVMIN )-LOG( PIVMIN ) ) /
00348 $ LOG( TWO ) ) + 2
00349 IF( ABSTOL.LE.ZERO ) THEN
00350 ATOLI = ULP*TNORM
00351 ELSE
00352 ATOLI = ABSTOL
00353 END IF
00354
00355 WORK( N+1 ) = GL
00356 WORK( N+2 ) = GL
00357 WORK( N+3 ) = GU
00358 WORK( N+4 ) = GU
00359 WORK( N+5 ) = GL
00360 WORK( N+6 ) = GU
00361 IWORK( 1 ) = -1
00362 IWORK( 2 ) = -1
00363 IWORK( 3 ) = N + 1
00364 IWORK( 4 ) = N + 1
00365 IWORK( 5 ) = IL - 1
00366 IWORK( 6 ) = IU
00367
00368 CALL SLAEBZ( 3, ITMAX, N, 2, 2, NB, ATOLI, RTOLI, PIVMIN, D, E,
00369 $ WORK, IWORK( 5 ), WORK( N+1 ), WORK( N+5 ), IOUT,
00370 $ IWORK, W, IBLOCK, IINFO )
00371
00372 IF( IWORK( 6 ).EQ.IU ) THEN
00373 WL = WORK( N+1 )
00374 WLU = WORK( N+3 )
00375 NWL = IWORK( 1 )
00376 WU = WORK( N+4 )
00377 WUL = WORK( N+2 )
00378 NWU = IWORK( 4 )
00379 ELSE
00380 WL = WORK( N+2 )
00381 WLU = WORK( N+4 )
00382 NWL = IWORK( 2 )
00383 WU = WORK( N+3 )
00384 WUL = WORK( N+1 )
00385 NWU = IWORK( 3 )
00386 END IF
00387
00388 IF( NWL.LT.0 .OR. NWL.GE.N .OR. NWU.LT.1 .OR. NWU.GT.N ) THEN
00389 INFO = 4
00390 RETURN
00391 END IF
00392 ELSE
00393
00394
00395
00396 TNORM = MAX( ABS( D( 1 ) )+ABS( E( 1 ) ),
00397 $ ABS( D( N ) )+ABS( E( N-1 ) ) )
00398
00399 DO 30 J = 2, N - 1
00400 TNORM = MAX( TNORM, ABS( D( J ) )+ABS( E( J-1 ) )+
00401 $ ABS( E( J ) ) )
00402 30 CONTINUE
00403
00404 IF( ABSTOL.LE.ZERO ) THEN
00405 ATOLI = ULP*TNORM
00406 ELSE
00407 ATOLI = ABSTOL
00408 END IF
00409
00410 IF( IRANGE.EQ.2 ) THEN
00411 WL = VL
00412 WU = VU
00413 ELSE
00414 WL = ZERO
00415 WU = ZERO
00416 END IF
00417 END IF
00418
00419
00420
00421
00422
00423 M = 0
00424 IEND = 0
00425 INFO = 0
00426 NWL = 0
00427 NWU = 0
00428
00429 DO 70 JB = 1, NSPLIT
00430 IOFF = IEND
00431 IBEGIN = IOFF + 1
00432 IEND = ISPLIT( JB )
00433 IN = IEND - IOFF
00434
00435 IF( IN.EQ.1 ) THEN
00436
00437
00438
00439 IF( IRANGE.EQ.1 .OR. WL.GE.D( IBEGIN )-PIVMIN )
00440 $ NWL = NWL + 1
00441 IF( IRANGE.EQ.1 .OR. WU.GE.D( IBEGIN )-PIVMIN )
00442 $ NWU = NWU + 1
00443 IF( IRANGE.EQ.1 .OR. ( WL.LT.D( IBEGIN )-PIVMIN .AND. WU.GE.
00444 $ D( IBEGIN )-PIVMIN ) ) THEN
00445 M = M + 1
00446 W( M ) = D( IBEGIN )
00447 IBLOCK( M ) = JB
00448 END IF
00449 ELSE
00450
00451
00452
00453
00454
00455
00456 GU = D( IBEGIN )
00457 GL = D( IBEGIN )
00458 TMP1 = ZERO
00459
00460 DO 40 J = IBEGIN, IEND - 1
00461 TMP2 = ABS( E( J ) )
00462 GU = MAX( GU, D( J )+TMP1+TMP2 )
00463 GL = MIN( GL, D( J )-TMP1-TMP2 )
00464 TMP1 = TMP2
00465 40 CONTINUE
00466
00467 GU = MAX( GU, D( IEND )+TMP1 )
00468 GL = MIN( GL, D( IEND )-TMP1 )
00469 BNORM = MAX( ABS( GL ), ABS( GU ) )
00470 GL = GL - FUDGE*BNORM*ULP*IN - FUDGE*PIVMIN
00471 GU = GU + FUDGE*BNORM*ULP*IN + FUDGE*PIVMIN
00472
00473
00474
00475 IF( ABSTOL.LE.ZERO ) THEN
00476 ATOLI = ULP*MAX( ABS( GL ), ABS( GU ) )
00477 ELSE
00478 ATOLI = ABSTOL
00479 END IF
00480
00481 IF( IRANGE.GT.1 ) THEN
00482 IF( GU.LT.WL ) THEN
00483 NWL = NWL + IN
00484 NWU = NWU + IN
00485 GO TO 70
00486 END IF
00487 GL = MAX( GL, WL )
00488 GU = MIN( GU, WU )
00489 IF( GL.GE.GU )
00490 $ GO TO 70
00491 END IF
00492
00493
00494
00495 WORK( N+1 ) = GL
00496 WORK( N+IN+1 ) = GU
00497 CALL SLAEBZ( 1, 0, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,
00498 $ D( IBEGIN ), E( IBEGIN ), WORK( IBEGIN ),
00499 $ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IM,
00500 $ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )
00501
00502 NWL = NWL + IWORK( 1 )
00503 NWU = NWU + IWORK( IN+1 )
00504 IWOFF = M - IWORK( 1 )
00505
00506
00507
00508 ITMAX = INT( ( LOG( GU-GL+PIVMIN )-LOG( PIVMIN ) ) /
00509 $ LOG( TWO ) ) + 2
00510 CALL SLAEBZ( 2, ITMAX, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,
00511 $ D( IBEGIN ), E( IBEGIN ), WORK( IBEGIN ),
00512 $ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IOUT,
00513 $ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )
00514
00515
00516
00517
00518 DO 60 J = 1, IOUT
00519 TMP1 = HALF*( WORK( J+N )+WORK( J+IN+N ) )
00520
00521
00522
00523 IF( J.GT.IOUT-IINFO ) THEN
00524 NCNVRG = .TRUE.
00525 IB = -JB
00526 ELSE
00527 IB = JB
00528 END IF
00529 DO 50 JE = IWORK( J ) + 1 + IWOFF,
00530 $ IWORK( J+IN ) + IWOFF
00531 W( JE ) = TMP1
00532 IBLOCK( JE ) = IB
00533 50 CONTINUE
00534 60 CONTINUE
00535
00536 M = M + IM
00537 END IF
00538 70 CONTINUE
00539
00540
00541
00542
00543 IF( IRANGE.EQ.3 ) THEN
00544 IM = 0
00545 IDISCL = IL - 1 - NWL
00546 IDISCU = NWU - IU
00547
00548 IF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THEN
00549 DO 80 JE = 1, M
00550 IF( W( JE ).LE.WLU .AND. IDISCL.GT.0 ) THEN
00551 IDISCL = IDISCL - 1
00552 ELSE IF( W( JE ).GE.WUL .AND. IDISCU.GT.0 ) THEN
00553 IDISCU = IDISCU - 1
00554 ELSE
00555 IM = IM + 1
00556 W( IM ) = W( JE )
00557 IBLOCK( IM ) = IBLOCK( JE )
00558 END IF
00559 80 CONTINUE
00560 M = IM
00561 END IF
00562 IF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THEN
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 IF( IDISCL.GT.0 ) THEN
00575 WKILL = WU
00576 DO 100 JDISC = 1, IDISCL
00577 IW = 0
00578 DO 90 JE = 1, M
00579 IF( IBLOCK( JE ).NE.0 .AND.
00580 $ ( W( JE ).LT.WKILL .OR. IW.EQ.0 ) ) THEN
00581 IW = JE
00582 WKILL = W( JE )
00583 END IF
00584 90 CONTINUE
00585 IBLOCK( IW ) = 0
00586 100 CONTINUE
00587 END IF
00588 IF( IDISCU.GT.0 ) THEN
00589
00590 WKILL = WL
00591 DO 120 JDISC = 1, IDISCU
00592 IW = 0
00593 DO 110 JE = 1, M
00594 IF( IBLOCK( JE ).NE.0 .AND.
00595 $ ( W( JE ).GT.WKILL .OR. IW.EQ.0 ) ) THEN
00596 IW = JE
00597 WKILL = W( JE )
00598 END IF
00599 110 CONTINUE
00600 IBLOCK( IW ) = 0
00601 120 CONTINUE
00602 END IF
00603 IM = 0
00604 DO 130 JE = 1, M
00605 IF( IBLOCK( JE ).NE.0 ) THEN
00606 IM = IM + 1
00607 W( IM ) = W( JE )
00608 IBLOCK( IM ) = IBLOCK( JE )
00609 END IF
00610 130 CONTINUE
00611 M = IM
00612 END IF
00613 IF( IDISCL.LT.0 .OR. IDISCU.LT.0 ) THEN
00614 TOOFEW = .TRUE.
00615 END IF
00616 END IF
00617
00618
00619
00620
00621
00622 IF( IORDER.EQ.1 .AND. NSPLIT.GT.1 ) THEN
00623 DO 150 JE = 1, M - 1
00624 IE = 0
00625 TMP1 = W( JE )
00626 DO 140 J = JE + 1, M
00627 IF( W( J ).LT.TMP1 ) THEN
00628 IE = J
00629 TMP1 = W( J )
00630 END IF
00631 140 CONTINUE
00632
00633 IF( IE.NE.0 ) THEN
00634 ITMP1 = IBLOCK( IE )
00635 W( IE ) = W( JE )
00636 IBLOCK( IE ) = IBLOCK( JE )
00637 W( JE ) = TMP1
00638 IBLOCK( JE ) = ITMP1
00639 END IF
00640 150 CONTINUE
00641 END IF
00642
00643 INFO = 0
00644 IF( NCNVRG )
00645 $ INFO = INFO + 1
00646 IF( TOOFEW )
00647 $ INFO = INFO + 2
00648 RETURN
00649
00650
00651
00652 END