00001 SUBROUTINE SLARRF( N, D, L, LD, CLSTRT, CLEND,
00002 $ W, WGAP, WERR,
00003 $ SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA,
00004 $ DPLUS, LPLUS, WORK, INFO )
00005
00006
00007
00008
00009
00010
00011
00012 INTEGER CLSTRT, CLEND, INFO, N
00013 REAL CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM
00014
00015
00016 REAL D( * ), DPLUS( * ), L( * ), LD( * ),
00017 $ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * )
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 REAL FOUR, MAXGROWTH1, MAXGROWTH2, ONE, QUART, TWO,
00107 $ ZERO
00108 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
00109 $ FOUR = 4.0E0, QUART = 0.25E0,
00110 $ MAXGROWTH1 = 8.E0,
00111 $ MAXGROWTH2 = 8.E0 )
00112
00113
00114 LOGICAL DORRR1, FORCER, NOFAIL, SAWNAN1, SAWNAN2, TRYRRR1
00115 INTEGER I, INDX, KTRY, KTRYMAX, SLEFT, SRIGHT, SHIFT
00116 PARAMETER ( KTRYMAX = 1, SLEFT = 1, SRIGHT = 2 )
00117 REAL AVGAP, BESTSHIFT, CLWDTH, EPS, FACT, FAIL,
00118 $ FAIL2, GROWTHBOUND, LDELTA, LDMAX, LSIGMA,
00119 $ MAX1, MAX2, MINGAP, OLDP, PROD, RDELTA, RDMAX,
00120 $ RRR1, RRR2, RSIGMA, S, SMLGROWTH, TMP, ZNM2
00121
00122
00123 LOGICAL SISNAN
00124 REAL SLAMCH
00125 EXTERNAL SISNAN, SLAMCH
00126
00127
00128 EXTERNAL SCOPY
00129
00130
00131 INTRINSIC ABS
00132
00133
00134
00135 INFO = 0
00136 FACT = REAL(2**KTRYMAX)
00137 EPS = SLAMCH( 'Precision' )
00138 SHIFT = 0
00139 FORCER = .FALSE.
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 NOFAIL = .TRUE.
00155
00156
00157
00158 CLWDTH = ABS(W(CLEND)-W(CLSTRT)) + WERR(CLEND) + WERR(CLSTRT)
00159 AVGAP = CLWDTH / REAL(CLEND-CLSTRT)
00160 MINGAP = MIN(CLGAPL, CLGAPR)
00161
00162 LSIGMA = MIN(W( CLSTRT ),W( CLEND )) - WERR( CLSTRT )
00163 RSIGMA = MAX(W( CLSTRT ),W( CLEND )) + WERR( CLEND )
00164
00165
00166 LSIGMA = LSIGMA - ABS(LSIGMA)* TWO * EPS
00167 RSIGMA = RSIGMA + ABS(RSIGMA)* TWO * EPS
00168
00169
00170 LDMAX = QUART * MINGAP + TWO * PIVMIN
00171 RDMAX = QUART * MINGAP + TWO * PIVMIN
00172
00173 LDELTA = MAX(AVGAP,WGAP( CLSTRT ))/FACT
00174 RDELTA = MAX(AVGAP,WGAP( CLEND-1 ))/FACT
00175
00176
00177
00178 S = SLAMCH( 'S' )
00179 SMLGROWTH = ONE / S
00180 FAIL = REAL(N-1)*MINGAP/(SPDIAM*EPS)
00181 FAIL2 = REAL(N-1)*MINGAP/(SPDIAM*SQRT(EPS))
00182 BESTSHIFT = LSIGMA
00183
00184
00185 KTRY = 0
00186 GROWTHBOUND = MAXGROWTH1*SPDIAM
00187
00188 5 CONTINUE
00189 SAWNAN1 = .FALSE.
00190 SAWNAN2 = .FALSE.
00191
00192 LDELTA = MIN(LDMAX,LDELTA)
00193 RDELTA = MIN(RDMAX,RDELTA)
00194
00195
00196
00197
00198
00199 S = -LSIGMA
00200 DPLUS( 1 ) = D( 1 ) + S
00201 IF(ABS(DPLUS(1)).LT.PIVMIN) THEN
00202 DPLUS(1) = -PIVMIN
00203
00204
00205 SAWNAN1 = .TRUE.
00206 ENDIF
00207 MAX1 = ABS( DPLUS( 1 ) )
00208 DO 6 I = 1, N - 1
00209 LPLUS( I ) = LD( I ) / DPLUS( I )
00210 S = S*LPLUS( I )*L( I ) - LSIGMA
00211 DPLUS( I+1 ) = D( I+1 ) + S
00212 IF(ABS(DPLUS(I+1)).LT.PIVMIN) THEN
00213 DPLUS(I+1) = -PIVMIN
00214
00215
00216 SAWNAN1 = .TRUE.
00217 ENDIF
00218 MAX1 = MAX( MAX1,ABS(DPLUS(I+1)) )
00219 6 CONTINUE
00220 SAWNAN1 = SAWNAN1 .OR. SISNAN( MAX1 )
00221
00222 IF( FORCER .OR.
00223 $ (MAX1.LE.GROWTHBOUND .AND. .NOT.SAWNAN1 ) ) THEN
00224 SIGMA = LSIGMA
00225 SHIFT = SLEFT
00226 GOTO 100
00227 ENDIF
00228
00229
00230 S = -RSIGMA
00231 WORK( 1 ) = D( 1 ) + S
00232 IF(ABS(WORK(1)).LT.PIVMIN) THEN
00233 WORK(1) = -PIVMIN
00234
00235
00236 SAWNAN2 = .TRUE.
00237 ENDIF
00238 MAX2 = ABS( WORK( 1 ) )
00239 DO 7 I = 1, N - 1
00240 WORK( N+I ) = LD( I ) / WORK( I )
00241 S = S*WORK( N+I )*L( I ) - RSIGMA
00242 WORK( I+1 ) = D( I+1 ) + S
00243 IF(ABS(WORK(I+1)).LT.PIVMIN) THEN
00244 WORK(I+1) = -PIVMIN
00245
00246
00247 SAWNAN2 = .TRUE.
00248 ENDIF
00249 MAX2 = MAX( MAX2,ABS(WORK(I+1)) )
00250 7 CONTINUE
00251 SAWNAN2 = SAWNAN2 .OR. SISNAN( MAX2 )
00252
00253 IF( FORCER .OR.
00254 $ (MAX2.LE.GROWTHBOUND .AND. .NOT.SAWNAN2 ) ) THEN
00255 SIGMA = RSIGMA
00256 SHIFT = SRIGHT
00257 GOTO 100
00258 ENDIF
00259
00260
00261
00262 IF(SAWNAN1.AND.SAWNAN2) THEN
00263
00264 GOTO 50
00265 ELSE
00266 IF( .NOT.SAWNAN1 ) THEN
00267 INDX = 1
00268 IF(MAX1.LE.SMLGROWTH) THEN
00269 SMLGROWTH = MAX1
00270 BESTSHIFT = LSIGMA
00271 ENDIF
00272 ENDIF
00273 IF( .NOT.SAWNAN2 ) THEN
00274 IF(SAWNAN1 .OR. MAX2.LE.MAX1) INDX = 2
00275 IF(MAX2.LE.SMLGROWTH) THEN
00276 SMLGROWTH = MAX2
00277 BESTSHIFT = RSIGMA
00278 ENDIF
00279 ENDIF
00280 ENDIF
00281
00282
00283
00284
00285
00286
00287 IF((CLWDTH.LT.MINGAP/REAL(128)) .AND.
00288 $ (MIN(MAX1,MAX2).LT.FAIL2)
00289 $ .AND.(.NOT.SAWNAN1).AND.(.NOT.SAWNAN2)) THEN
00290 DORRR1 = .TRUE.
00291 ELSE
00292 DORRR1 = .FALSE.
00293 ENDIF
00294 TRYRRR1 = .TRUE.
00295 IF( TRYRRR1 .AND. DORRR1 ) THEN
00296 IF(INDX.EQ.1) THEN
00297 TMP = ABS( DPLUS( N ) )
00298 ZNM2 = ONE
00299 PROD = ONE
00300 OLDP = ONE
00301 DO 15 I = N-1, 1, -1
00302 IF( PROD .LE. EPS ) THEN
00303 PROD =
00304 $ ((DPLUS(I+1)*WORK(N+I+1))/(DPLUS(I)*WORK(N+I)))*OLDP
00305 ELSE
00306 PROD = PROD*ABS(WORK(N+I))
00307 END IF
00308 OLDP = PROD
00309 ZNM2 = ZNM2 + PROD**2
00310 TMP = MAX( TMP, ABS( DPLUS( I ) * PROD ))
00311 15 CONTINUE
00312 RRR1 = TMP/( SPDIAM * SQRT( ZNM2 ) )
00313 IF (RRR1.LE.MAXGROWTH2) THEN
00314 SIGMA = LSIGMA
00315 SHIFT = SLEFT
00316 GOTO 100
00317 ENDIF
00318 ELSE IF(INDX.EQ.2) THEN
00319 TMP = ABS( WORK( N ) )
00320 ZNM2 = ONE
00321 PROD = ONE
00322 OLDP = ONE
00323 DO 16 I = N-1, 1, -1
00324 IF( PROD .LE. EPS ) THEN
00325 PROD = ((WORK(I+1)*LPLUS(I+1))/(WORK(I)*LPLUS(I)))*OLDP
00326 ELSE
00327 PROD = PROD*ABS(LPLUS(I))
00328 END IF
00329 OLDP = PROD
00330 ZNM2 = ZNM2 + PROD**2
00331 TMP = MAX( TMP, ABS( WORK( I ) * PROD ))
00332 16 CONTINUE
00333 RRR2 = TMP/( SPDIAM * SQRT( ZNM2 ) )
00334 IF (RRR2.LE.MAXGROWTH2) THEN
00335 SIGMA = RSIGMA
00336 SHIFT = SRIGHT
00337 GOTO 100
00338 ENDIF
00339 END IF
00340 ENDIF
00341
00342 50 CONTINUE
00343
00344 IF (KTRY.LT.KTRYMAX) THEN
00345
00346
00347 LSIGMA = MAX( LSIGMA - LDELTA,
00348 $ LSIGMA - LDMAX)
00349 RSIGMA = MIN( RSIGMA + RDELTA,
00350 $ RSIGMA + RDMAX )
00351 LDELTA = TWO * LDELTA
00352 RDELTA = TWO * RDELTA
00353 KTRY = KTRY + 1
00354 GOTO 5
00355 ELSE
00356
00357
00358 IF((SMLGROWTH.LT.FAIL).OR.NOFAIL) THEN
00359 LSIGMA = BESTSHIFT
00360 RSIGMA = BESTSHIFT
00361 FORCER = .TRUE.
00362 GOTO 5
00363 ELSE
00364 INFO = 1
00365 RETURN
00366 ENDIF
00367 END IF
00368
00369 100 CONTINUE
00370 IF (SHIFT.EQ.SLEFT) THEN
00371 ELSEIF (SHIFT.EQ.SRIGHT) THEN
00372
00373 CALL SCOPY( N, WORK, 1, DPLUS, 1 )
00374 CALL SCOPY( N-1, WORK(N+1), 1, LPLUS, 1 )
00375 ENDIF
00376
00377 RETURN
00378
00379
00380
00381 END