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 &ldquo;large&rdquo; into a
323
<p>The idea is to break a given initially &ldquo;large&rdquo; 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