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