Révision 101
pobysoPythonSage/src/sageSLZ/sageSLZ.sage (revision 101) | ||
---|---|---|
36 | 36 |
absoluteErrorTypeSo) |
37 | 37 |
maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
38 | 38 |
while maxErrorSa > approxPrecSa: |
39 |
#print "++Approximation error:", maxErrorSa |
|
39 | 40 |
sollya_lib_clear_obj(maxErrorSo) |
40 | 41 |
sollya_lib_clear_obj(polySo) |
41 | 42 |
sollya_lib_clear_obj(intervalCenterSo) |
42 |
shrinkFactorSa = RRR('5.0')/(maxErrorSa/approxPrecSa).log2().abs()
|
|
43 |
shrinkFactorSa = RRR('5')/(maxErrorSa/approxPrecSa).log2().abs() |
|
43 | 44 |
#shrinkFactorSa = 1.5/(maxErrorSa/approxPrecSa) |
44 | 45 |
#errorRatioSa = approxPrecSa/maxErrorSa |
45 | 46 |
#print "Error ratio: ", errorRatioSa |
46 |
|
|
47 | 47 |
if shrinkFactorSa > intervalShrinkConstFactorSa: |
48 | 48 |
actualShrinkFactorSa = intervalShrinkConstFactorSa |
49 | 49 |
#print "Fixed" |
... | ... | |
51 | 51 |
actualShrinkFactorSa = shrinkFactorSa |
52 | 52 |
#print "Computed",shrinkFactorSa,maxErrorSa |
53 | 53 |
#print shrinkFactorSa, maxErrorSa |
54 |
#print "Shrink factor", actualShrinkFactorSa |
|
54 | 55 |
currentUpperBoundSa = currentLowerBoundSa + \ |
55 | 56 |
(currentUpperBoundSa - currentLowerBoundSa) * \ |
56 | 57 |
actualShrinkFactorSa |
57 | 58 |
#print "Current upper bound:", currentUpperBoundSa |
58 | 59 |
sollya_lib_clear_obj(currentRangeSo) |
59 | 60 |
sollya_lib_clear_obj(polySo) |
60 |
if currentUpperBoundSa <= currentLowerBoundSa: |
|
61 |
if currentUpperBoundSa <= currentLowerBoundSa or \ |
|
62 |
currentUpperBoundSa == currentLowerBoundSa.nextabove(): |
|
61 | 63 |
sollya_lib_clear_obj(absoluteErrorTypeSo) |
62 | 64 |
print "Can't find an interval." |
63 | 65 |
print "Use either or both a higher polynomial degree or a higher", |
... | ... | |
210 | 212 |
- the corresponding approximation error. |
211 | 213 |
TODO: fix endless looping for some parameters sets. |
212 | 214 |
""" |
215 |
# Set Sollya to the necessary internal precision. |
|
213 | 216 |
currentSollyaPrecSo = pobyso_get_prec_so() |
214 | 217 |
currentSollyaPrecSa = pobyso_constant_from_int_so_sa(currentSollyaPrecSo) |
215 | 218 |
if internalSollyaPrecSa > currentSollyaPrecSa: |
216 | 219 |
pobyso_set_prec_sa_so(internalSollyaPrecSa) |
220 |
# |
|
217 | 221 |
x = functionSa.variables()[0] # Actual variable name can be anything. |
222 |
# Scaled function: [1=,2] -> [1,2]. |
|
218 | 223 |
(fff, scaledLowerBoundSa, scaledUpperBoundSa, \ |
219 | 224 |
scaledLowerBoundImageSa, scaledUpperBoundImageSa) = \ |
220 | 225 |
slz_compute_scaled_function(functionSa, \ |
... | ... | |
236 | 241 |
scaledLowerBoundSa, scaledUpperBoundSa, |
237 | 242 |
approxPrecSa, internalSollyaPrecSa) |
238 | 243 |
if polySo is None: |
239 |
print "Aborting" |
|
244 |
print "slz_get_intervals_and_polynomials: Aborting and returning None!" |
|
245 |
if internalSollyaPrecSa != currentSollyaPrecSa: |
|
246 |
pobyso_set_prec_sa_so(currentSollyaPrecSa) |
|
240 | 247 |
return None |
241 |
# Change variable stuff |
|
242 |
changeVarExpressionSo = sollya_lib_build_function_sub( |
|
243 |
sollya_lib_build_function_free_variable(), |
|
244 |
sollya_lib_copy_obj(intervalCenterSo)) |
|
245 |
polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpressionSo) |
|
246 |
resultArray.append((polySo, polyVarChangedSo, boundsSo, intervalCenterSo,\ |
|
247 |
maxErrorSo)) |
|
248 | 248 |
realIntervalField = RealIntervalField(max(lowerBoundSa.parent().precision(), |
249 | 249 |
upperBoundSa.parent().precision())) |
250 | 250 |
boundsSa = pobyso_range_to_interval_so_sa(boundsSo, realIntervalField) |
251 |
errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
|
252 |
#print "First approximation error:", errorSa |
|
253 |
# If the error and interval are OK a the first try, just return. |
|
254 |
if boundsSa.endpoints()[1] >= scaledUpperBoundSa: |
|
255 |
# Change variable stuff in Sollya x -> x0-x. |
|
256 |
changeVarExpressionSo = sollya_lib_build_function_sub( \ |
|
257 |
sollya_lib_build_function_free_variable(), \ |
|
258 |
sollya_lib_copy_obj(intervalCenterSo)) |
|
259 |
polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpressionSo) |
|
260 |
resultArray.append((polySo, polyVarChangedSo, boundsSo, \ |
|
261 |
intervalCenterSo, maxErrorSo)) |
|
262 |
if internalSollyaPrecSa != currentSollyaPrecSa: |
|
263 |
pobyso_set_prec_sa_so(currentSollyaPrecSa) |
|
264 |
sollya_lib_clear_obj(functionSo) |
|
265 |
sollya_lib_clear_obj(degreeSo) |
|
266 |
sollya_lib_clear_obj(scaledBoundsSo) |
|
267 |
#print "Approximation error:", errorSa |
|
268 |
return resultArray |
|
251 | 269 |
# Compute the next upper bound. |
252 |
# If the error of approximation is more than half of the target, |
|
253 |
# use the same interval. |
|
254 |
# If it is less, increase it a bit. |
|
255 |
errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
|
270 |
# The following ratio is always >= 1 |
|
256 | 271 |
currentErrorRatio = approxPrecSa / errorSa |
272 |
# Starting point for the next upper bound. |
|
257 | 273 |
currentScaledUpperBoundSa = boundsSa.endpoints()[1] |
258 |
if currentErrorRatio < 2 : |
|
274 |
boundsWidthSa = boundsSa.endpoints()[1] - boundsSa.endpoints()[0] |
|
275 |
# Compute the increment. |
|
276 |
if currentErrorRatio > RR('1000'): # ]1.5, infinity[ |
|
259 | 277 |
currentScaledUpperBoundSa += \ |
260 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0])
|
|
261 |
else: |
|
278 |
currentErrorRatio * boundsWidthSa * 2
|
|
279 |
else: # [1, 1.5]
|
|
262 | 280 |
currentScaledUpperBoundSa += \ |
263 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) \
|
|
264 |
* currentErrorRatio.log2() * 2
|
|
281 |
(RR('1.0') + currentErrorRatio.log() / 500) * boundsWidthSa
|
|
282 |
# Take into account the original interval upper bound.
|
|
265 | 283 |
if currentScaledUpperBoundSa > scaledUpperBoundSa: |
266 | 284 |
currentScaledUpperBoundSa = scaledUpperBoundSa |
267 | 285 |
# Compute the other expansions. |
... | ... | |
273 | 291 |
currentScaledUpperBoundSa, |
274 | 292 |
approxPrecSa, |
275 | 293 |
internalSollyaPrecSa) |
276 |
# Change variable stuff |
|
277 |
changeVarExpressionSo = sollya_lib_build_function_sub( |
|
278 |
sollya_lib_build_function_free_variable(), |
|
279 |
sollya_lib_copy_obj(intervalCenterSo)) |
|
280 |
polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpressionSo) |
|
281 |
resultArray.append((polySo, polyVarChangedSo, boundsSo, \ |
|
282 |
intervalCenterSo, maxErrorSo)) |
|
294 |
errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
|
295 |
if errorSa < approxPrecSa: |
|
296 |
# Change variable stuff |
|
297 |
#print "Approximation error:", errorSa |
|
298 |
changeVarExpressionSo = sollya_lib_build_function_sub( |
|
299 |
sollya_lib_build_function_free_variable(), |
|
300 |
sollya_lib_copy_obj(intervalCenterSo)) |
|
301 |
polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpressionSo) |
|
302 |
resultArray.append((polySo, polyVarChangedSo, boundsSo, \ |
|
303 |
intervalCenterSo, maxErrorSo)) |
|
283 | 304 |
boundsSa = pobyso_range_to_interval_so_sa(boundsSo, realIntervalField) |
284 | 305 |
# Compute the next upper bound. |
285 |
# If the error of approximation is more than half of the target, |
|
286 |
# use the same interval. |
|
287 |
# If it is less, increase it a bit. |
|
288 |
errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
|
306 |
# The following ratio is always >= 1 |
|
289 | 307 |
currentErrorRatio = approxPrecSa / errorSa |
290 |
if currentErrorRatio < RR('1.5') : |
|
291 |
currentScaledUpperBoundSa = \ |
|
292 |
boundsSa.endpoints()[1] + \ |
|
293 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) |
|
294 |
elif currentErrorRatio < 2: |
|
295 |
currentScaledUpperBoundSa = \ |
|
296 |
boundsSa.endpoints()[1] + \ |
|
297 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) \ |
|
298 |
* currentErrorRatio.log2() |
|
299 |
else: |
|
300 |
currentScaledUpperBoundSa = \ |
|
301 |
boundsSa.endpoints()[1] + \ |
|
302 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) \ |
|
303 |
* currentErrorRatio.log2() * 2 |
|
308 |
# Starting point for the next upper bound. |
|
309 |
currentScaledUpperBoundSa = boundsSa.endpoints()[1] |
|
310 |
boundsWidthSa = boundsSa.endpoints()[1] - boundsSa.endpoints()[0] |
|
311 |
# Compute the increment. |
|
312 |
if currentErrorRatio > RR('1000'): # ]1.5, infinity[ |
|
313 |
currentScaledUpperBoundSa += \ |
|
314 |
currentErrorRatio * boundsWidthSa * 2 |
|
315 |
else: # [1, 1.5] |
|
316 |
currentScaledUpperBoundSa += \ |
|
317 |
(RR('1.0') + currentErrorRatio.log()/500) * boundsWidthSa |
|
318 |
#print "currentErrorRatio:", currentErrorRatio |
|
319 |
#print "currentScaledUpperBoundSa", currentScaledUpperBoundSa |
|
304 | 320 |
# Test for insufficient precision. |
305 | 321 |
if currentScaledUpperBoundSa == scaledLowerBoundSa: |
306 | 322 |
print "Can't shrink the interval anymore!" |
307 | 323 |
print "You should consider increasing the Sollya internal precision" |
308 | 324 |
print "or the polynomial degree." |
309 | 325 |
print "Giving up!" |
326 |
if internalSollyaPrecSa != currentSollyaPrecSa: |
|
327 |
pobyso_set_prec_sa_so(currentSollyaPrecSa) |
|
310 | 328 |
sollya_lib_clear_obj(functionSo) |
311 | 329 |
sollya_lib_clear_obj(degreeSo) |
312 | 330 |
sollya_lib_clear_obj(scaledBoundsSo) |
Formats disponibles : Unified diff