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