Révision 81
pobysoPythonSage/src/pobyso.py (revision 81) | ||
---|---|---|
522 | 522 |
#pobyso_autoprint(polySo) |
523 | 523 |
polyVariableSa = expressionSa.variables()[0] |
524 | 524 |
polyRingSa = realFieldSa[str(polyVariableSa)] |
525 |
print polyRingSa |
|
525 |
#print polyRingSa
|
|
526 | 526 |
# Do not use the polynomial(expressionSa, ring=polyRingSa) form! |
527 | 527 |
polynomialSa = polyRingSa(expressionSa) |
528 | 528 |
return(polynomialSa) |
pobysoPythonSage/src/sageSLZ/sageSLZ-Notes.html (revision 81) | ||
---|---|---|
306 | 306 |
<h2>The approximation interval problem</h2> |
307 | 307 |
|
308 | 308 |
<p>When Sollya computes an approximation polynomial for a given function, |
309 |
degree and range, it also returns the approximation error (and the center of |
|
310 |
the interval as well).</p> |
|
309 |
degree and range, it also returns the approximation error (refered to, in the sequel, |
|
310 |
as the |
|
311 |
<span class="langElem">computedError</span> and the center of |
|
312 |
the interval as well). |
|
313 |
</p> |
|
311 | 314 |
|
312 |
<p>Very often we want to solve a slightly different problem: for a given |
|
313 |
function, degree, lower bound and approximation error, computed the |
|
315 |
<p>Very often, we want to solve a slightly different problem: for a given |
|
316 |
function, degree, lower bound and approximation error (referred to, in the |
|
317 |
sequel, as the |
|
318 |
<span class="langElem">targetError</span> ), compute the |
|
314 | 319 |
approximation polynomial and the upper bound of the interval comprised between |
315 |
it and the upper bound for which the approximation error stands.</p> |
|
320 |
it and the lower bound for which the approximation error stands. |
|
321 |
</p> |
|
316 | 322 |
|
317 |
<p>Very often the idea is to break a given “large” into a
|
|
323 |
<p>The idea is to break a given initially “large” interval into a
|
|
318 | 324 |
collection of smaller intervals because for the given function-degree-error the |
319 | 325 |
initial interval is too large.</p> |
320 | 326 |
|
321 |
<p>The naive approach is to:</p> |
|
327 |
<p>The most naive approach is to:</p>
|
|
322 | 328 |
<ol> |
323 |
<li>give it a try with the initial data;</li> |
|
329 |
<li>give it a try with the initial data (a very probably too high upper bound |
|
330 |
for the given <span class="langElem">targetError</span>);</li> |
|
324 | 331 |
<li>when you get a too large error, reduce (e. g. divide by 2) the interval by |
325 | 332 |
lowering the upper bound until the computed error matches the target |
326 | 333 |
error;</li> |
... | ... | |
330 | 337 |
</ol> |
331 | 338 |
|
332 | 339 |
<p>In step 2 you may have to compute several polynomials until the computed |
333 |
error is below or equal to the expected error. You must not decrease the |
|
334 |
interval width too agressively. There is no point in getting a too small approximation error since it multiplies the number of interval (and |
|
340 |
error is below or equal to the expected error. But you must not decrease the |
|
341 |
interval width too agressively: there is no point in getting a too small |
|
342 |
approximation error since it multiplies the number of interval (and |
|
335 | 343 |
lengthens the subsequent manipulations that are made on each sub-interval).</p> |
336 | 344 |
|
337 | 345 |
<p>In step 3 you probably inutily compute polynomials for too large intervals |
338 | 346 |
and you could know it from the previous computations.</p> |
339 | 347 |
|
340 | 348 |
<p>The whole idea is to reduce the number of polynomial computations and get the |
341 |
maximum width (compatible with the expected approwimaiton error).</p>
|
|
349 |
maximum width (compatible with the target error).</p>
|
|
342 | 350 |
|
343 | 351 |
<p>This process has different aspects:</p> |
344 | 352 |
<ol> |
... | ... | |
347 | 355 |
<li>reuse the computation already done in previous steps.</li> |
348 | 356 |
</ol> |
349 | 357 |
|
350 |
<p>For point 1, can something be done with the derivative at the upper bound or |
|
351 |
at the center point of the interval (also given by Sollya).</p> |
|
358 |
<p>We use two strategies.</p> |
|
359 |
<p>The first is in the inner function that computes the first approximation |
|
360 |
polynomial. If the upper bound is too high, we shrink the interval by a non |
|
361 |
linear (and complex) factor computed from the ratio beetwen the obtained |
|
362 |
error and the target error.<br>The whole idea is not to end up with a too |
|
363 |
small interval.</p> |
|
364 |
<p>This only takes into account aspect 1</p>. |
|
365 |
<p>The second strategy is in the outer function. In this function the |
|
366 |
computed intervals returned by the inner function give all correct |
|
367 |
approximation errors. The computation of next upper bound will take into |
|
368 |
account the value of the previous interval and that of the previous |
|
369 |
computed error.</p> |
|
370 |
<p>If the errors ratio is lower than 2, we try the same interval length |
|
371 |
as given by the previous computation. If larger we increase the next |
|
372 |
interval but by a small margin (log2(errorsRatio).</p> |
|
352 | 373 |
|
353 |
<p>For point 2, can some type of data structure keep the informations (which |
|
354 |
ones ?) and allow for an efficient reuse.</p> |
|
355 |
|
|
356 |
<p>Adjacent question: is it possible, given a the result of a previous |
|
357 |
computation, to forecast the effect on the approximation precision of a degree |
|
358 |
in(de)crease?</p> |
|
374 |
<p>In this case, aspects 1 and 2 are considered </p> |
|
375 |
|
|
376 |
<p>For the moment, we do not resort to more complex forcasting techniques |
|
377 |
(using the derivative of the function?). This could be an option if the |
|
378 |
present strategies did not output enough performance. </p> |
|
359 | 379 |
</body> |
360 | 380 |
</html> |
pobysoPythonSage/src/sageSLZ/sagePolynomialOperations.sage (revision 81) | ||
---|---|---|
107 | 107 |
return(expressionAsString) |
108 | 108 |
# End spo_expression_as_string. |
109 | 109 |
|
110 |
def spo_norm(poly, degree): |
|
111 |
""" |
|
112 |
Behaves more or less (no infinity defined) as the norm for the |
|
113 |
univariate polynomials. |
|
114 |
Quoting the Sage documentation: |
|
115 |
Definition: For integer p, the p-norm of a polynomial is the pth root of |
|
116 |
the sum of the pth powers of the absolute values of the coefficients of |
|
117 |
the polynomial. |
|
118 |
""" |
|
119 |
# TODO: check the arguments. |
|
120 |
norm = 0 |
|
121 |
for coefficient in poly.coefficients(): |
|
122 |
norm += (coefficient^degree).abs() |
|
123 |
return pow(norm, 1/degree) |
|
124 |
# end spo_norm |
|
125 |
|
|
110 | 126 |
def spo_polynomial_to_matrix(p, pRing, alpha, N, columnsWidth=0): |
111 | 127 |
""" |
112 | 128 |
From a (bivariate) polynomial and some other parameters build a matrix |
... | ... | |
316 | 332 |
# End for pPower loop |
317 | 333 |
return protoMatrixRows |
318 | 334 |
# End spo_polynomial_to_matrix |
335 |
|
|
336 |
print "sagePolynomialOperations loaded..." |
pobysoPythonSage/src/sageSLZ/sageSLZ.sage (revision 81) | ||
---|---|---|
12 | 12 |
are returned. |
13 | 13 |
""" |
14 | 14 |
RRR = lowerBoundSa.parent() |
15 |
#goldenRatioSa = RRR(5.sqrt() / 2 - 1/2) |
|
16 |
#intervalShrinkConstFactorSa = goldenRatioSa |
|
17 | 15 |
intervalShrinkConstFactorSa = RRR('0.5') |
18 | 16 |
absoluteErrorTypeSo = pobyso_absolute_so_so() |
19 | 17 |
currentRangeSo = pobyso_bounds_to_range_sa_so(lowerBoundSa, upperBoundSa) |
... | ... | |
29 | 27 |
maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
30 | 28 |
while maxErrorSa > approxPrecSa: |
31 | 29 |
sollya_lib_clear_obj(maxErrorSo) |
32 |
errorRatioSa = 1/(maxErrorSa/approxPrecSa).log2() |
|
30 |
sollya_lib_clear_obj(polySo) |
|
31 |
sollya_lib_clear_obj(intervalCenterSo) |
|
32 |
shrinkFactorSa = RRR('5.0')/(maxErrorSa/approxPrecSa).log2().abs() |
|
33 |
#shrinkFactorSa = 1.5/(maxErrorSa/approxPrecSa) |
|
34 |
#errorRatioSa = approxPrecSa/maxErrorSa |
|
33 | 35 |
#print "Error ratio: ", errorRatioSa |
34 |
if errorRatioSa > intervalShrinkConstFactorSa: |
|
35 |
currentUpperBoundSa = currentLowerBoundSa + \
|
|
36 |
(currentUpperBoundSa - currentLowerBoundSa) * \
|
|
37 |
intervalShrinkConstFactorSa
|
|
36 |
|
|
37 |
if shrinkFactorSa > intervalShrinkConstFactorSa:
|
|
38 |
actualShrinkFactorSa = intervalShrinkConstFactorSa
|
|
39 |
#print "Fixed"
|
|
38 | 40 |
else: |
39 |
currentUpperBoundSa = currentLowerBoundSa + \ |
|
41 |
actualShrinkFactorSa = shrinkFactorSa |
|
42 |
#print "Computed",shrinkFactorSa,maxErrorSa |
|
43 |
#print shrinkFactorSa, maxErrorSa |
|
44 |
currentUpperBoundSa = currentLowerBoundSa + \ |
|
40 | 45 |
(currentUpperBoundSa - currentLowerBoundSa) * \ |
41 |
intervalShrinkConstFactorSa |
|
42 |
currentUpperBoundSa = currentLowerBoundSa + \ |
|
43 |
(currentUpperBoundSa - currentLowerBoundSa) * \ |
|
44 |
errorRatioSa |
|
46 |
actualShrinkFactorSa |
|
45 | 47 |
#print "Current upper bound:", currentUpperBoundSa |
46 | 48 |
sollya_lib_clear_obj(currentRangeSo) |
47 | 49 |
sollya_lib_clear_obj(polySo) |
... | ... | |
55 | 57 |
maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
56 | 58 |
sollya_lib_clear_obj(absoluteErrorTypeSo) |
57 | 59 |
return((polySo, currentRangeSo, intervalCenterSo, maxErrorSo)) |
58 |
# End slz_compute_polynomial_and_interval
|
|
60 |
# End slz_compute_polynomial_and_interval |
|
59 | 61 |
|
60 | 62 |
def slz_compute_scaled_function(functionSa, \ |
61 | 63 |
lowerBoundSa, \ |
... | ... | |
111 | 113 |
polynomialRing = QQ[str(polyOfFloat.variables()[0])] |
112 | 114 |
return(polynomialRing(polyOfFloat)) |
113 | 115 |
# End slz_float_poly_of_float_to_rat_poly_of_rat |
114 |
|
|
116 |
|
|
115 | 117 |
def slz_get_intervals_and_polynomials(functionSa, degreeSa, |
116 | 118 |
lowerBoundSa, |
117 | 119 |
upperBoundSa, floatingPointPrecSa, |
... | ... | |
166 | 168 |
realIntervalField = RealIntervalField(max(lowerBoundSa.parent().precision(), |
167 | 169 |
upperBoundSa.parent().precision())) |
168 | 170 |
boundsSa = pobyso_range_to_interval_so_sa(boundsSo, realIntervalField) |
171 |
# Compute the next upper bound. |
|
172 |
# If the error of approximation is more than half of the target, |
|
173 |
# use the same interval. |
|
174 |
# If it is less, increase it a bit. |
|
175 |
errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
|
176 |
currentErrorRatio = approxPrecSa / errorSa |
|
177 |
currentScaledUpperBoundSa = boundsSa.endpoints()[1] |
|
178 |
if currentErrorRatio < 2 : |
|
179 |
currentScaledUpperBoundSa += \ |
|
180 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) |
|
181 |
else: |
|
182 |
currentScaledUpperBoundSa += \ |
|
183 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) \ |
|
184 |
* currentErrorRatio.log2() * 2 |
|
185 |
if currentScaledUpperBoundSa > scaledUpperBoundSa: |
|
186 |
currentScaledUpperBoundSa = scaledUpperBoundSa |
|
169 | 187 |
# Compute the other expansions. |
170 | 188 |
while boundsSa.endpoints()[1] < scaledUpperBoundSa: |
171 | 189 |
currentScaledLowerBoundSa = boundsSa.endpoints()[1] |
172 | 190 |
(polySo, boundsSo, intervalCenterSo, maxErrorSo) = \ |
173 | 191 |
slz_compute_polynomial_and_interval(functionSo, degreeSo, |
174 | 192 |
currentScaledLowerBoundSa, |
175 |
scaledUpperBoundSa, approxPrecSa, |
|
193 |
currentScaledUpperBoundSa, |
|
194 |
approxPrecSa, |
|
176 | 195 |
internalSollyaPrecSa) |
177 | 196 |
# Change variable stuff |
178 | 197 |
changeVarExpressionSo = sollya_lib_build_function_sub( |
... | ... | |
182 | 201 |
resultArray.append((polySo, polyVarChangedSo, boundsSo, \ |
183 | 202 |
intervalCenterSo, maxErrorSo)) |
184 | 203 |
boundsSa = pobyso_range_to_interval_so_sa(boundsSo, realIntervalField) |
204 |
# Compute the next upper bound. |
|
205 |
# If the error of approximation is more than half of the target, |
|
206 |
# use the same interval. |
|
207 |
# If it is less, increase it a bit. |
|
208 |
errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
|
209 |
currentErrorRatio = approxPrecSa / errorSa |
|
210 |
if currentErrorRatio < RR('1.5') : |
|
211 |
currentScaledUpperBoundSa = \ |
|
212 |
boundsSa.endpoints()[1] + \ |
|
213 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) |
|
214 |
elif currentErrorRatio < 2: |
|
215 |
currentScaledUpperBoundSa = \ |
|
216 |
boundsSa.endpoints()[1] + \ |
|
217 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) \ |
|
218 |
* currentErrorRatio.log2() |
|
219 |
else: |
|
220 |
currentScaledUpperBoundSa = \ |
|
221 |
boundsSa.endpoints()[1] + \ |
|
222 |
(boundsSa.endpoints()[1] - boundsSa.endpoints()[0]) \ |
|
223 |
* currentErrorRatio.log2() * 2 |
|
224 |
if currentScaledUpperBoundSa > scaledUpperBoundSa: |
|
225 |
currentScaledUpperBoundSa = scaledUpperBoundSa |
|
185 | 226 |
sollya_lib_clear_obj(functionSo) |
186 | 227 |
sollya_lib_clear_obj(degreeSo) |
187 | 228 |
sollya_lib_clear_obj(scaledBoundsSo) |
188 | 229 |
return(resultArray) |
189 |
# End slz_get_intervals_and_polynomials
|
|
230 |
# End slz_get_intervals_and_polynomials |
|
190 | 231 |
|
232 |
|
|
191 | 233 |
def slz_interval_scaling_expression(boundsInterval, expVar): |
192 | 234 |
""" |
193 | 235 |
Compute the scaling expression to map an interval that span only |
pobysoPythonSage/src/sageSLZ/sageRationalOperations.sage (revision 81) | ||
---|---|---|
96 | 96 |
"has no \"numerator()\" member." |
97 | 97 |
return([]) |
98 | 98 |
return(numeratorsList) |
99 |
# End sro_numerators |
|
99 |
# End sro_numerators |
|
100 |
|
|
101 |
print "sageRationalOperations loaded..." |
Formats disponibles : Unified diff