00001 SUBROUTINE DLARRE( RANGE, N, VL, VU, IL, IU, D, E, E2,
00002 $ RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M,
00003 $ W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,
00004 $ WORK, IWORK, INFO )
00005 IMPLICIT NONE
00006
00007
00008
00009
00010
00011
00012
00013 CHARACTER RANGE
00014 INTEGER IL, INFO, IU, M, N, NSPLIT
00015 DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU
00016
00017
00018 INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),
00019 $ INDEXW( * )
00020 DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ),
00021 $ W( * ),WERR( * ), WGAP( * ), WORK( * )
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
00176
00177
00178
00179
00180
00181
00182
00183 DOUBLE PRECISION FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,
00184 $ MAXGROWTH, ONE, PERT, TWO, ZERO
00185 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0,
00186 $ TWO = 2.0D0, FOUR=4.0D0,
00187 $ HNDRD = 100.0D0,
00188 $ PERT = 8.0D0,
00189 $ HALF = ONE/TWO, FOURTH = ONE/FOUR, FAC= HALF,
00190 $ MAXGROWTH = 64.0D0, FUDGE = 2.0D0 )
00191 INTEGER MAXTRY, ALLRNG, INDRNG, VALRNG
00192 PARAMETER ( MAXTRY = 6, ALLRNG = 1, INDRNG = 2,
00193 $ VALRNG = 3 )
00194
00195
00196 LOGICAL FORCEB, NOREP, USEDQD
00197 INTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,
00198 $ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM,
00199 $ WBEGIN, WEND
00200 DOUBLE PRECISION AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,
00201 $ EMAX, EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL,
00202 $ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM,
00203 $ TAU, TMP, TMP1
00204
00205
00206
00207
00208 INTEGER ISEED( 4 )
00209
00210
00211 LOGICAL LSAME
00212 DOUBLE PRECISION DLAMCH
00213 EXTERNAL DLAMCH, LSAME
00214
00215
00216
00217 EXTERNAL DCOPY, DLARNV, DLARRA, DLARRB, DLARRC, DLARRD,
00218 $ DLASQ2
00219
00220
00221 INTRINSIC ABS, MAX, MIN
00222
00223
00224
00225
00226
00227 INFO = 0
00228
00229
00230
00231
00232 IF( LSAME( RANGE, 'A' ) ) THEN
00233 IRANGE = ALLRNG
00234 ELSE IF( LSAME( RANGE, 'V' ) ) THEN
00235 IRANGE = VALRNG
00236 ELSE IF( LSAME( RANGE, 'I' ) ) THEN
00237 IRANGE = INDRNG
00238 END IF
00239
00240 M = 0
00241
00242
00243 SAFMIN = DLAMCH( 'S' )
00244 EPS = DLAMCH( 'P' )
00245
00246
00247 RTL = SQRT(EPS)
00248 BSRTOL = SQRT(EPS)
00249
00250
00251 IF( N.EQ.1 ) THEN
00252 IF( (IRANGE.EQ.ALLRNG).OR.
00253 $ ((IRANGE.EQ.VALRNG).AND.(D(1).GT.VL).AND.(D(1).LE.VU)).OR.
00254 $ ((IRANGE.EQ.INDRNG).AND.(IL.EQ.1).AND.(IU.EQ.1)) ) THEN
00255 M = 1
00256 W(1) = D(1)
00257
00258 WERR(1) = ZERO
00259 WGAP(1) = ZERO
00260 IBLOCK( 1 ) = 1
00261 INDEXW( 1 ) = 1
00262 GERS(1) = D( 1 )
00263 GERS(2) = D( 1 )
00264 ENDIF
00265
00266 E(1) = ZERO
00267 RETURN
00268 END IF
00269
00270
00271
00272
00273
00274 GL = D(1)
00275 GU = D(1)
00276 EOLD = ZERO
00277 EMAX = ZERO
00278 E(N) = ZERO
00279 DO 5 I = 1,N
00280 WERR(I) = ZERO
00281 WGAP(I) = ZERO
00282 EABS = ABS( E(I) )
00283 IF( EABS .GE. EMAX ) THEN
00284 EMAX = EABS
00285 END IF
00286 TMP1 = EABS + EOLD
00287 GERS( 2*I-1) = D(I) - TMP1
00288 GL = MIN( GL, GERS( 2*I - 1))
00289 GERS( 2*I ) = D(I) + TMP1
00290 GU = MAX( GU, GERS(2*I) )
00291 EOLD = EABS
00292 5 CONTINUE
00293
00294 PIVMIN = SAFMIN * MAX( ONE, EMAX**2 )
00295
00296
00297 SPDIAM = GU - GL
00298
00299
00300 CALL DLARRA( N, D, E, E2, SPLTOL, SPDIAM,
00301 $ NSPLIT, ISPLIT, IINFO )
00302
00303
00304
00305 FORCEB = .FALSE.
00306
00307
00308
00309 USEDQD = (( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB))
00310
00311 IF( (IRANGE.EQ.ALLRNG) .AND. (.NOT. FORCEB) ) THEN
00312
00313 VL = GL
00314 VU = GU
00315 ELSE
00316
00317
00318
00319
00320
00321
00322 CALL DLARRD( RANGE, 'B', N, VL, VU, IL, IU, GERS,
00323 $ BSRTOL, D, E, E2, PIVMIN, NSPLIT, ISPLIT,
00324 $ MM, W, WERR, VL, VU, IBLOCK, INDEXW,
00325 $ WORK, IWORK, IINFO )
00326 IF( IINFO.NE.0 ) THEN
00327 INFO = -1
00328 RETURN
00329 ENDIF
00330
00331 DO 14 I = MM+1,N
00332 W( I ) = ZERO
00333 WERR( I ) = ZERO
00334 IBLOCK( I ) = 0
00335 INDEXW( I ) = 0
00336 14 CONTINUE
00337 END IF
00338
00339
00340
00341
00342 IBEGIN = 1
00343 WBEGIN = 1
00344 DO 170 JBLK = 1, NSPLIT
00345 IEND = ISPLIT( JBLK )
00346 IN = IEND - IBEGIN + 1
00347
00348
00349 IF( IN.EQ.1 ) THEN
00350 IF( (IRANGE.EQ.ALLRNG).OR.( (IRANGE.EQ.VALRNG).AND.
00351 $ ( D( IBEGIN ).GT.VL ).AND.( D( IBEGIN ).LE.VU ) )
00352 $ .OR. ( (IRANGE.EQ.INDRNG).AND.(IBLOCK(WBEGIN).EQ.JBLK))
00353 $ ) THEN
00354 M = M + 1
00355 W( M ) = D( IBEGIN )
00356 WERR(M) = ZERO
00357
00358
00359 WGAP(M) = ZERO
00360 IBLOCK( M ) = JBLK
00361 INDEXW( M ) = 1
00362 WBEGIN = WBEGIN + 1
00363 ENDIF
00364
00365 E( IEND ) = ZERO
00366 IBEGIN = IEND + 1
00367 GO TO 170
00368 END IF
00369
00370
00371
00372
00373 E( IEND ) = ZERO
00374
00375
00376 GL = D(IBEGIN)
00377 GU = D(IBEGIN)
00378 DO 15 I = IBEGIN , IEND
00379 GL = MIN( GERS( 2*I-1 ), GL )
00380 GU = MAX( GERS( 2*I ), GU )
00381 15 CONTINUE
00382 SPDIAM = GU - GL
00383
00384 IF(.NOT. ((IRANGE.EQ.ALLRNG).AND.(.NOT.FORCEB)) ) THEN
00385
00386 MB = 0
00387 DO 20 I = WBEGIN,MM
00388 IF( IBLOCK(I).EQ.JBLK ) THEN
00389 MB = MB+1
00390 ELSE
00391 GOTO 21
00392 ENDIF
00393 20 CONTINUE
00394 21 CONTINUE
00395
00396 IF( MB.EQ.0) THEN
00397
00398
00399 E( IEND ) = ZERO
00400 IBEGIN = IEND + 1
00401 GO TO 170
00402 ELSE
00403
00404
00405 USEDQD = ( (MB .GT. FAC*IN) .AND. (.NOT.FORCEB) )
00406 WEND = WBEGIN + MB - 1
00407
00408
00409
00410 SIGMA = ZERO
00411 DO 30 I = WBEGIN, WEND - 1
00412 WGAP( I ) = MAX( ZERO,
00413 $ W(I+1)-WERR(I+1) - (W(I)+WERR(I)) )
00414 30 CONTINUE
00415 WGAP( WEND ) = MAX( ZERO,
00416 $ VU - SIGMA - (W( WEND )+WERR( WEND )))
00417
00418 INDL = INDEXW(WBEGIN)
00419 INDU = INDEXW( WEND )
00420 ENDIF
00421 ENDIF
00422 IF(( (IRANGE.EQ.ALLRNG) .AND. (.NOT. FORCEB) ).OR.USEDQD) THEN
00423
00424
00425 CALL DLARRK( IN, 1, GL, GU, D(IBEGIN),
00426 $ E2(IBEGIN), PIVMIN, RTL, TMP, TMP1, IINFO )
00427 IF( IINFO.NE.0 ) THEN
00428 INFO = -1
00429 RETURN
00430 ENDIF
00431 ISLEFT = MAX(GL, TMP - TMP1
00432 $ - HNDRD * EPS* ABS(TMP - TMP1))
00433
00434 CALL DLARRK( IN, IN, GL, GU, D(IBEGIN),
00435 $ E2(IBEGIN), PIVMIN, RTL, TMP, TMP1, IINFO )
00436 IF( IINFO.NE.0 ) THEN
00437 INFO = -1
00438 RETURN
00439 ENDIF
00440 ISRGHT = MIN(GU, TMP + TMP1
00441 $ + HNDRD * EPS * ABS(TMP + TMP1))
00442
00443 SPDIAM = ISRGHT - ISLEFT
00444 ELSE
00445
00446
00447 ISLEFT = MAX(GL, W(WBEGIN) - WERR(WBEGIN)
00448 $ - HNDRD * EPS*ABS(W(WBEGIN)- WERR(WBEGIN) ))
00449 ISRGHT = MIN(GU,W(WEND) + WERR(WEND)
00450 $ + HNDRD * EPS * ABS(W(WEND)+ WERR(WEND)))
00451 ENDIF
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 IF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THEN
00463
00464 USEDQD = .TRUE.
00465
00466 INDL = 1
00467 INDU = IN
00468
00469 MB = IN
00470 WEND = WBEGIN + MB - 1
00471
00472 S1 = ISLEFT + FOURTH * SPDIAM
00473 S2 = ISRGHT - FOURTH * SPDIAM
00474 ELSE
00475
00476
00477
00478 IF( USEDQD ) THEN
00479 S1 = ISLEFT + FOURTH * SPDIAM
00480 S2 = ISRGHT - FOURTH * SPDIAM
00481 ELSE
00482 TMP = MIN(ISRGHT,VU) - MAX(ISLEFT,VL)
00483 S1 = MAX(ISLEFT,VL) + FOURTH * TMP
00484 S2 = MIN(ISRGHT,VU) - FOURTH * TMP
00485 ENDIF
00486 ENDIF
00487
00488
00489 IF(MB.GT.1) THEN
00490 CALL DLARRC( 'T', IN, S1, S2, D(IBEGIN),
00491 $ E(IBEGIN), PIVMIN, CNT, CNT1, CNT2, IINFO)
00492 ENDIF
00493
00494 IF(MB.EQ.1) THEN
00495 SIGMA = GL
00496 SGNDEF = ONE
00497 ELSEIF( CNT1 - INDL .GE. INDU - CNT2 ) THEN
00498 IF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THEN
00499 SIGMA = MAX(ISLEFT,GL)
00500 ELSEIF( USEDQD ) THEN
00501
00502
00503 SIGMA = ISLEFT
00504 ELSE
00505
00506
00507 SIGMA = MAX(ISLEFT,VL)
00508 ENDIF
00509 SGNDEF = ONE
00510 ELSE
00511 IF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THEN
00512 SIGMA = MIN(ISRGHT,GU)
00513 ELSEIF( USEDQD ) THEN
00514
00515
00516 SIGMA = ISRGHT
00517 ELSE
00518
00519
00520 SIGMA = MIN(ISRGHT,VU)
00521 ENDIF
00522 SGNDEF = -ONE
00523 ENDIF
00524
00525
00526
00527
00528
00529
00530
00531 IF( USEDQD ) THEN
00532
00533
00534 TAU = SPDIAM*EPS*N + TWO*PIVMIN
00535 ELSE
00536 IF(MB.GT.1) THEN
00537 CLWDTH = W(WEND) + WERR(WEND) - W(WBEGIN) - WERR(WBEGIN)
00538 AVGAP = ABS(CLWDTH / DBLE(WEND-WBEGIN))
00539 IF( SGNDEF.EQ.ONE ) THEN
00540 TAU = HALF*MAX(WGAP(WBEGIN),AVGAP)
00541 TAU = MAX(TAU,WERR(WBEGIN))
00542 ELSE
00543 TAU = HALF*MAX(WGAP(WEND-1),AVGAP)
00544 TAU = MAX(TAU,WERR(WEND))
00545 ENDIF
00546 ELSE
00547 TAU = WERR(WBEGIN)
00548 ENDIF
00549 ENDIF
00550
00551 DO 80 IDUM = 1, MAXTRY
00552
00553
00554
00555 DPIVOT = D( IBEGIN ) - SIGMA
00556 WORK( 1 ) = DPIVOT
00557 DMAX = ABS( WORK(1) )
00558 J = IBEGIN
00559 DO 70 I = 1, IN - 1
00560 WORK( 2*IN+I ) = ONE / WORK( I )
00561 TMP = E( J )*WORK( 2*IN+I )
00562 WORK( IN+I ) = TMP
00563 DPIVOT = ( D( J+1 )-SIGMA ) - TMP*E( J )
00564 WORK( I+1 ) = DPIVOT
00565 DMAX = MAX( DMAX, ABS(DPIVOT) )
00566 J = J + 1
00567 70 CONTINUE
00568
00569 IF( DMAX .GT. MAXGROWTH*SPDIAM ) THEN
00570 NOREP = .TRUE.
00571 ELSE
00572 NOREP = .FALSE.
00573 ENDIF
00574 IF( USEDQD .AND. .NOT.NOREP ) THEN
00575
00576
00577 DO 71 I = 1, IN
00578 TMP = SGNDEF*WORK( I )
00579 IF( TMP.LT.ZERO ) NOREP = .TRUE.
00580 71 CONTINUE
00581 ENDIF
00582 IF(NOREP) THEN
00583
00584
00585
00586 IF( IDUM.EQ.MAXTRY-1 ) THEN
00587 IF( SGNDEF.EQ.ONE ) THEN
00588
00589 SIGMA =
00590 $ GL - FUDGE*SPDIAM*EPS*N - FUDGE*TWO*PIVMIN
00591 ELSE
00592 SIGMA =
00593 $ GU + FUDGE*SPDIAM*EPS*N + FUDGE*TWO*PIVMIN
00594 END IF
00595 ELSE
00596 SIGMA = SIGMA - SGNDEF * TAU
00597 TAU = TWO * TAU
00598 END IF
00599 ELSE
00600
00601 GO TO 83
00602 END IF
00603 80 CONTINUE
00604
00605
00606 INFO = 2
00607 RETURN
00608
00609 83 CONTINUE
00610
00611
00612
00613 E( IEND ) = SIGMA
00614
00615 CALL DCOPY( IN, WORK, 1, D( IBEGIN ), 1 )
00616 CALL DCOPY( IN-1, WORK( IN+1 ), 1, E( IBEGIN ), 1 )
00617
00618
00619 IF(MB.GT.1 ) THEN
00620
00621
00622
00623
00624
00625 DO 122 I = 1, 4
00626 ISEED( I ) = 1
00627 122 CONTINUE
00628
00629 CALL DLARNV(2, ISEED, 2*IN-1, WORK(1))
00630 DO 125 I = 1,IN-1
00631 D(IBEGIN+I-1) = D(IBEGIN+I-1)*(ONE+EPS*PERT*WORK(I))
00632 E(IBEGIN+I-1) = E(IBEGIN+I-1)*(ONE+EPS*PERT*WORK(IN+I))
00633 125 CONTINUE
00634 D(IEND) = D(IEND)*(ONE+EPS*FOUR*WORK(IN))
00635
00636 ENDIF
00637
00638
00639
00640
00641
00642
00643
00644 IF ( .NOT.USEDQD ) THEN
00645
00646
00647
00648
00649
00650 DO 134 J=WBEGIN,WEND
00651 W(J) = W(J) - SIGMA
00652 WERR(J) = WERR(J) + ABS(W(J)) * EPS
00653 134 CONTINUE
00654
00655
00656 DO 135 I = IBEGIN, IEND-1
00657 WORK( I ) = D( I ) * E( I )**2
00658 135 CONTINUE
00659
00660 CALL DLARRB(IN, D(IBEGIN), WORK(IBEGIN),
00661 $ INDL, INDU, RTOL1, RTOL2, INDL-1,
00662 $ W(WBEGIN), WGAP(WBEGIN), WERR(WBEGIN),
00663 $ WORK( 2*N+1 ), IWORK, PIVMIN, SPDIAM,
00664 $ IN, IINFO )
00665 IF( IINFO .NE. 0 ) THEN
00666 INFO = -4
00667 RETURN
00668 END IF
00669
00670
00671 WGAP( WEND ) = MAX( ZERO,
00672 $ ( VU-SIGMA ) - ( W( WEND ) + WERR( WEND ) ) )
00673 DO 138 I = INDL, INDU
00674 M = M + 1
00675 IBLOCK(M) = JBLK
00676 INDEXW(M) = I
00677 138 CONTINUE
00678 ELSE
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 RTOL = LOG(DBLE(IN)) * FOUR * EPS
00691 J = IBEGIN
00692 DO 140 I = 1, IN - 1
00693 WORK( 2*I-1 ) = ABS( D( J ) )
00694 WORK( 2*I ) = E( J )*E( J )*WORK( 2*I-1 )
00695 J = J + 1
00696 140 CONTINUE
00697 WORK( 2*IN-1 ) = ABS( D( IEND ) )
00698 WORK( 2*IN ) = ZERO
00699 CALL DLASQ2( IN, WORK, IINFO )
00700 IF( IINFO .NE. 0 ) THEN
00701
00702
00703
00704 INFO = -5
00705 RETURN
00706 ELSE
00707
00708 DO 149 I = 1, IN
00709 IF( WORK( I ).LT.ZERO ) THEN
00710 INFO = -6
00711 RETURN
00712 ENDIF
00713 149 CONTINUE
00714 END IF
00715 IF( SGNDEF.GT.ZERO ) THEN
00716 DO 150 I = INDL, INDU
00717 M = M + 1
00718 W( M ) = WORK( IN-I+1 )
00719 IBLOCK( M ) = JBLK
00720 INDEXW( M ) = I
00721 150 CONTINUE
00722 ELSE
00723 DO 160 I = INDL, INDU
00724 M = M + 1
00725 W( M ) = -WORK( I )
00726 IBLOCK( M ) = JBLK
00727 INDEXW( M ) = I
00728 160 CONTINUE
00729 END IF
00730
00731 DO 165 I = M - MB + 1, M
00732
00733 WERR( I ) = RTOL * ABS( W(I) )
00734 165 CONTINUE
00735 DO 166 I = M - MB + 1, M - 1
00736
00737 WGAP( I ) = MAX( ZERO,
00738 $ W(I+1)-WERR(I+1) - (W(I)+WERR(I)) )
00739 166 CONTINUE
00740 WGAP( M ) = MAX( ZERO,
00741 $ ( VU-SIGMA ) - ( W( M ) + WERR( M ) ) )
00742 END IF
00743
00744 IBEGIN = IEND + 1
00745 WBEGIN = WEND + 1
00746 170 CONTINUE
00747
00748
00749 RETURN
00750
00751
00752
00753 END