Statistiques
| Révision :

root / pobysoPythonSage / src / pobyso.py @ 281

Historique | Voir | Annoter | Télécharger (92,33 ko)

1 5 storres
"""
2 209 storres
@file pobyso.py
3 5 storres
Actual functions to use in Sage
4 256 storres
@author S.T.
5 256 storres
@date 2012-11-13
6 5 storres

7 5 storres
Command line syntax:
8 5 storres
  use from Sage (via the "load" or the "attach" commands)
9 5 storres

10 38 storres
pobyso functions come in five flavors:
11 57 storres
- the _so_so (arguments and returned objects are pointers to Sollya objects,
12 57 storres
  includes the void function and the no arguments function that return a
13 57 storres
  pointer to a Sollya object);
14 38 storres
- the _so_sa (argument are pointers to Sollya objects, returned objects are
15 57 storres
  Sage/Python objects or, more generally, information is transfered from the
16 57 storres
  Sollya world to Sage/Python world; e.g. functions without arguments that
17 57 storres
  return a Sage/Python object);
18 38 storres
- the _sa_so (arguments are Sage/Python objects, returned objects are
19 38 storres
  pointers to Sollya objects);
20 38 storres
- the sa_sa (arguments and returned objects are all Sage/Python objects);
21 257 storres
- a catch all flavor, without any suffix, (e. g. functions that have no
22 257 storres
  argument nor return value).
23 257 storres

24 57 storres
This classification is not always very strict. Conversion functions from Sollya
25 57 storres
to Sage/Python are sometimes decorated with Sage/Python arguments to set
26 57 storres
the precision. These functions remain in the so_sa category.
27 258 storres

28 258 storres
@note
29 259 storres
Reported errors in Eclipse come from the calls to the Sollya library
30 5 storres

31 10 storres
ToDo (among other things):
32 10 storres
 -memory management.
33 5 storres
"""
34 5 storres
from ctypes import *
35 37 storres
import re
36 37 storres
from sage.symbolic.expression_conversions import polynomial
37 59 storres
from sage.symbolic.expression_conversions import PolynomialConverter
38 38 storres
"""
39 38 storres
Create the equivalent to an enum for the Sollya function types.
40 38 storres
"""
41 5 storres
(SOLLYA_BASE_FUNC_ABS,
42 5 storres
SOLLYA_BASE_FUNC_ACOS,
43 5 storres
    SOLLYA_BASE_FUNC_ACOSH,
44 5 storres
    SOLLYA_BASE_FUNC_ADD,
45 5 storres
    SOLLYA_BASE_FUNC_ASIN,
46 5 storres
    SOLLYA_BASE_FUNC_ASINH,
47 5 storres
    SOLLYA_BASE_FUNC_ATAN,
48 5 storres
    SOLLYA_BASE_FUNC_ATANH,
49 5 storres
    SOLLYA_BASE_FUNC_CEIL,
50 5 storres
    SOLLYA_BASE_FUNC_CONSTANT,
51 5 storres
    SOLLYA_BASE_FUNC_COS,
52 5 storres
    SOLLYA_BASE_FUNC_COSH,
53 5 storres
    SOLLYA_BASE_FUNC_DIV,
54 5 storres
    SOLLYA_BASE_FUNC_DOUBLE,
55 5 storres
    SOLLYA_BASE_FUNC_DOUBLEDOUBLE,
56 5 storres
    SOLLYA_BASE_FUNC_DOUBLEEXTENDED,
57 5 storres
    SOLLYA_BASE_FUNC_ERF,
58 5 storres
    SOLLYA_BASE_FUNC_ERFC,
59 5 storres
    SOLLYA_BASE_FUNC_EXP,
60 5 storres
    SOLLYA_BASE_FUNC_EXP_M1,
61 5 storres
    SOLLYA_BASE_FUNC_FLOOR,
62 5 storres
    SOLLYA_BASE_FUNC_FREE_VARIABLE,
63 5 storres
    SOLLYA_BASE_FUNC_HALFPRECISION,
64 5 storres
    SOLLYA_BASE_FUNC_LIBRARYCONSTANT,
65 5 storres
    SOLLYA_BASE_FUNC_LIBRARYFUNCTION,
66 5 storres
    SOLLYA_BASE_FUNC_LOG,
67 5 storres
    SOLLYA_BASE_FUNC_LOG_10,
68 5 storres
    SOLLYA_BASE_FUNC_LOG_1P,
69 5 storres
    SOLLYA_BASE_FUNC_LOG_2,
70 5 storres
    SOLLYA_BASE_FUNC_MUL,
71 5 storres
    SOLLYA_BASE_FUNC_NEARESTINT,
72 5 storres
    SOLLYA_BASE_FUNC_NEG,
73 5 storres
    SOLLYA_BASE_FUNC_PI,
74 5 storres
    SOLLYA_BASE_FUNC_POW,
75 5 storres
    SOLLYA_BASE_FUNC_PROCEDUREFUNCTION,
76 5 storres
    SOLLYA_BASE_FUNC_QUAD,
77 5 storres
    SOLLYA_BASE_FUNC_SIN,
78 5 storres
    SOLLYA_BASE_FUNC_SINGLE,
79 5 storres
    SOLLYA_BASE_FUNC_SINH,
80 5 storres
    SOLLYA_BASE_FUNC_SQRT,
81 5 storres
    SOLLYA_BASE_FUNC_SUB,
82 5 storres
    SOLLYA_BASE_FUNC_TAN,
83 5 storres
    SOLLYA_BASE_FUNC_TANH,
84 5 storres
SOLLYA_BASE_FUNC_TRIPLEDOUBLE) = map(int,xrange(44))
85 246 storres
sys.stderr.write("Superficial pobyso check...\n")
86 230 storres
#print "First constant - SOLLYA_BASE_FUNC_ABS: ", SOLLYA_BASE_FUNC_ABS
87 230 storres
#print "Last constant  - SOLLYA_BASE_FUNC_TRIPLEDOUBLE: ", SOLLYA_BASE_FUNC_TRIPLEDOUBLE
88 5 storres
89 5 storres
pobyso_max_arity = 9
90 5 storres
91 85 storres
def pobyso_absolute_so_so():
92 259 storres
    """
93 259 storres
    Create an "absolute" Sollya object.
94 259 storres
    """
95 85 storres
    return(sollya_lib_absolute(None))
96 85 storres
97 5 storres
def pobyso_autoprint(arg):
98 218 storres
    sollya_lib_autoprint(arg, None)
99 5 storres
100 38 storres
def pobyso_autoprint_so_so(arg):
101 38 storres
    sollya_lib_autoprint(arg,None)
102 54 storres
103 84 storres
def pobyso_bounds_to_range_sa_so(rnLowerBoundSa, rnUpperBoundSa, \
104 84 storres
                                 precisionSa=None):
105 84 storres
    """
106 84 storres
    Return a Sollya range from to 2 RealField Sage elements.
107 84 storres
    The Sollya range element has a sufficient precision to hold all
108 162 storres
    the digits of the widest of the Sage bounds.
109 84 storres
    """
110 84 storres
    # Sanity check.
111 84 storres
    if rnLowerBoundSa > rnUpperBoundSa:
112 84 storres
        return None
113 115 storres
    # Precision stuff.
114 85 storres
    if precisionSa is None:
115 84 storres
        # Check for the largest precision.
116 84 storres
        lbPrecSa = rnLowerBoundSa.parent().precision()
117 84 storres
        ubPrecSa = rnLowerBoundSa.parent().precision()
118 84 storres
        maxPrecSa = max(lbPrecSa, ubPrecSa)
119 84 storres
    else:
120 84 storres
        maxPrecSa = precisionSa
121 115 storres
    # From Sage to Sollya bounds.
122 162 storres
#    lowerBoundSo = sollya_lib_constant(get_rn_value(rnLowerBoundSa),
123 162 storres
#                                       maxPrecSa)
124 162 storres
    lowerBoundSo = pobyso_constant_sa_so(rnLowerBoundSa,
125 162 storres
                                         maxPrecSa)
126 162 storres
    upperBoundSo = pobyso_constant_sa_so(rnUpperBoundSa,
127 154 storres
                                       maxPrecSa)
128 162 storres
129 115 storres
    # From Sollya bounds to range.
130 84 storres
    rangeSo = sollya_lib_range(lowerBoundSo, upperBoundSo)
131 84 storres
    # Back to original precision.
132 84 storres
    # Clean up
133 84 storres
    sollya_lib_clear_obj(lowerBoundSo)
134 84 storres
    sollya_lib_clear_obj(upperBoundSo)
135 154 storres
    return rangeSo
136 84 storres
# End pobyso_bounds_to_range_sa_so
137 84 storres
138 215 storres
def pobyso_build_end_elliptic_list_so_so(*args):
139 215 storres
    """
140 237 storres
    From Sollya argument objects, create a Sollya end elliptic list.
141 237 storres
    Elements of the list are "eaten" (should not be cleared individually,
142 215 storres
    are cleared when the list is cleared).
143 215 storres
    """
144 215 storres
    if len(args) == 0:
145 280 storres
        ## When called with an empty list, sollya_lib_build_end_elliptic_list,
146 280 storres
        #  produces "error".
147 280 storres
        return sollya_lib_build_list(None)
148 215 storres
    index = 0
149 215 storres
    ## One can not append elements to an elliptic list, prepend only is
150 215 storres
    #  permitted.
151 215 storres
    for argument in reversed(args):
152 215 storres
        if index == 0:
153 215 storres
            listSo = sollya_lib_build_end_elliptic_list(argument, None)
154 215 storres
        else:
155 215 storres
            listSo = sollya_lib_prepend(argument, listSo)
156 215 storres
        index += 1
157 215 storres
    return listSo
158 215 storres
159 215 storres
# End pobyso_build_end_elliptic_list_so_so
160 215 storres
161 54 storres
def pobyso_build_function_sub_so_so(exp1So, exp2So):
162 237 storres
    return sollya_lib_build_function_sub(exp1So, exp2So)
163 54 storres
164 237 storres
def pobyso_build_list_of_ints_sa_so(*args):
165 237 storres
    """
166 237 storres
    Build a Sollya list from Sage integral arguments.
167 237 storres
    """
168 237 storres
    if len(args) == 0:
169 237 storres
        return pobyso_build_list_so_so()
170 237 storres
    ## Make a Sage list of integral constants.
171 237 storres
    intsList = []
172 237 storres
    for intElem in args:
173 237 storres
        intsList.append(pobyso_constant_from_int_sa_so(intElem))
174 237 storres
    return pobyso_build_list_so_so(*intsList)
175 237 storres
176 237 storres
def pobyso_build_list_so_so(*args):
177 237 storres
    """
178 237 storres
    Make a Sollya list out of Sollya objects passed as arguments.
179 237 storres
    If one wants to call it with a list argument, should prepend a "*"
180 237 storres
    before the list variable name.
181 237 storres
    Elements of the list are "eaten" (should not be cleared individually,
182 237 storres
    are cleared when the list is cleared).
183 237 storres
    """
184 237 storres
    if len(args) == 0:
185 237 storres
        ## Called with an empty list produced "error".
186 237 storres
        return sollya_lib_build_list(None)
187 237 storres
    index = 0
188 237 storres
    ## Append the Sollya elements one by one.
189 237 storres
    for elementSo in args:
190 237 storres
        if index == 0:
191 237 storres
            listSo = sollya_lib_build_list(elementSo, None)
192 237 storres
        else:
193 237 storres
            listSo = sollya_lib_append(listSo, elementSo)
194 237 storres
        index += 1
195 237 storres
    return listSo
196 237 storres
# End pobyso_build list_so_so
197 237 storres
198 237 storres
199 85 storres
def pobyso_change_var_in_function_so_so(funcSo, chvarExpSo):
200 54 storres
    """
201 85 storres
    Variable change in a function.
202 85 storres
    """
203 85 storres
    return(sollya_lib_evaluate(funcSo,chvarExpSo))
204 85 storres
# End pobyso_change_var_in_function_so_so
205 85 storres
206 85 storres
def pobyso_chebyshevform_so_so(functionSo, degreeSo, intervalSo):
207 85 storres
    resultSo = sollya_lib_chebyshevform(functionSo, degreeSo, intervalSo)
208 85 storres
    return(resultSo)
209 85 storres
# End pobyso_chebyshevform_so_so.
210 85 storres
211 280 storres
def pobyso_clear_full_list_elements_sa_so(objectListSaSo):
212 280 storres
    """
213 280 storres
    Clear the elements of list created by the
214 280 storres
    pobyso_get_list_elements_so_so function.
215 280 storres
    objectListSaSo is as follows:
216 280 storres
    - objectListSaSo[0]: a list of Sollya objects;
217 280 storres
    - objectListSaSo[1]: the number of elements of the previous list;
218 280 storres
    - objectListSaSo[2]: an integer that if != 0 states that the list is
219 280 storres
                         end-elliptic
220 280 storres
    The objects to clear are the elements of the objectListSaSo[0] list.
221 280 storres
    """
222 280 storres
    for index in xrange(0, objectListSaSo[1]):
223 280 storres
        sollya_lib_clear_obj(objectListSaSo[0][index])
224 280 storres
# End pobyso_clear_full_list_elements_sa_so
225 280 storres
226 280 storres
def pobyso_clear_list_elements_sa_so(objectListSaSo):
227 280 storres
    """
228 280 storres
    Clear the elements of list of references to Sollya objects
229 280 storres
    """
230 280 storres
    for index in xrange(0, len(objectListSaSo)):
231 280 storres
        sollya_lib_clear_obj(objectListSaSo[index])
232 280 storres
# End pobyso_clear_list_elements_sa_so
233 280 storres
234 237 storres
def pobyso_clear_obj(objSo):
235 237 storres
    """
236 237 storres
    Free a Sollya object's memory.
237 237 storres
    Very thin wrapper around sollya_lib_clear_obj().
238 237 storres
    """
239 237 storres
    sollya_lib_clear_obj(objSo)
240 237 storres
# End pobyso_clear_obj.
241 237 storres
242 117 storres
def pobyso_clear_taylorform_sa_so(taylorFormSaSo):
243 117 storres
    """
244 280 storres
    This method is rapper around pobyso_clear_list_elements_sa_so.
245 280 storres
    It is a legacy method left here since it may be used in existing code
246 280 storres
    where Taylor forms are used as Sage lists obtained by converting
247 280 storres
    Sollya Taylor forms (a list made of:
248 280 storres
    - a polynomial;
249 280 storres
    - a list of intervals enclosing the errors accumulated when computing
250 280 storres
      the polynomial coefficients;
251 280 storres
    - a bound on the approximation error between the polynomial and the
252 280 storres
      function.)
253 280 storres
    A Taylor form directly obtained from pobyso_taylorform_so_so is cleared
254 280 storres
    by sollya_lib_clear_obj.
255 117 storres
    """
256 280 storres
    pobyso_clear_list_elements_sa_so(taylorFormSaSo)
257 117 storres
# End pobyso_clear_taylorform_sa_so
258 117 storres
259 85 storres
def pobyso_cmp(rnArgSa, cteSo):
260 85 storres
    """
261 237 storres
    Deprecated, use pobyso_cmp_sa_so_sa instead.
262 237 storres
    """
263 237 storres
    print "Deprecated, use pobyso_cmp_sa_so_sa instead."
264 237 storres
    return pobyso_cmp_sa_so_sa(rnArgSa, cteSo)
265 237 storres
# End  pobyso_cmp
266 237 storres
267 237 storres
def pobyso_cmp_sa_so_sa(rnArgSa, cteSo):
268 237 storres
    """
269 54 storres
    Compare the MPFR value a RealNumber with that of a Sollya constant.
270 54 storres

271 54 storres
    Get the value of the Sollya constant into a RealNumber and compare
272 54 storres
    using MPFR. Could be optimized by working directly with a mpfr_t
273 54 storres
    for the intermediate number.
274 54 storres
    """
275 115 storres
    # Get the precision of the Sollya constant to build a Sage RealNumber
276 115 storres
    # with enough precision.to hold it.
277 5 storres
    precisionOfCte = c_int(0)
278 5 storres
    # From the Sollya constant, create a local Sage RealNumber.
279 85 storres
    sollya_lib_get_prec_of_constant(precisionOfCte, cteSo)
280 5 storres
    #print "Precision of constant: ", precisionOfCte
281 5 storres
    RRRR = RealField(precisionOfCte.value)
282 85 storres
    rnLocalSa = RRRR(0)
283 85 storres
    sollya_lib_get_constant(get_rn_value(rnLocalSa), cteSo)
284 115 storres
    #
285 237 storres
    ## Compare the Sage RealNumber version of the Sollya constant with rnArg
286 237 storres
    #  through a direct comparison of underlying MPFR numbers.
287 237 storres
    return cmp_rn_value(rnArgSa, rnLocal)
288 237 storres
# End pobyso_smp_sa_so_sa
289 5 storres
290 54 storres
def pobyso_compute_pos_function_abs_val_bounds_sa_sa(funcSa, lowerBoundSa, \
291 54 storres
                                                     upperBoundSa):
292 54 storres
    """
293 85 storres
    TODO: completely rework and test.
294 54 storres
    """
295 85 storres
    pobyso = pobyso_name_free_variable_sa_so(funcSa.variables()[0])
296 159 storres
    funcSo = pobyso_parse_string(funcSa._assume_str().replace('_SAGE_VAR_', ''))
297 54 storres
    rangeSo = pobyso_range_sa_so(lowerBoundSa, upperBoundSa)
298 54 storres
    infnormSo = pobyso_infnorm_so_so(funcSo,rangeSo)
299 83 storres
    # Sollya return the infnorm as an interval.
300 54 storres
    fMaxSa = pobyso_get_interval_from_range_so_sa(infnormSo)
301 54 storres
    # Get the top bound and compute the binade top limit.
302 54 storres
    fMaxUpperBoundSa = fMaxSa.upper()
303 54 storres
    binadeTopLimitSa = 2**ceil(fMaxUpperBoundSa.log2())
304 54 storres
    # Put up together the function to use to compute the lower bound.
305 54 storres
    funcAuxSo = pobyso_parse_string(str(binadeTopLimitSa) +  \
306 159 storres
                                    '-(' + f._assume_str().replace('_SAGE_VAR_', '') + ')')
307 54 storres
    pobyso_autoprint(funcAuxSo)
308 83 storres
    # Clear the Sollya range before a new call to infnorm and issue the call.
309 54 storres
    sollya_lib_clear_obj(infnormSo)
310 54 storres
    infnormSo = pobyso_infnorm_so_so(funcAuxSo,rangeSo)
311 54 storres
    fMinSa = pobyso_get_interval_from_range_so_sa(infnormSo)
312 54 storres
    sollya_lib_clear_obj(infnormSo)
313 85 storres
    fMinLowerBoundSa = binadeTopLimitSa - fMinSa.lower()
314 54 storres
    # Compute the maximum of the precisions of the different bounds.
315 54 storres
    maxPrecSa = max([fMinLowerBoundSa.parent().precision(), \
316 54 storres
                     fMaxUpperBoundSa.parent().precision()])
317 54 storres
    # Create a RealIntervalField and create an interval with the "good" bounds.
318 54 storres
    RRRI = RealIntervalField(maxPrecSa)
319 54 storres
    imageIntervalSa = RRRI(fMinLowerBoundSa, fMaxUpperBoundSa)
320 83 storres
    # Free the unneeded Sollya objects
321 54 storres
    sollya_lib_clear_obj(funcSo)
322 54 storres
    sollya_lib_clear_obj(funcAuxSo)
323 54 storres
    sollya_lib_clear_obj(rangeSo)
324 54 storres
    return(imageIntervalSa)
325 83 storres
# End pobyso_compute_pos_function_abs_val_bounds_sa_sa
326 54 storres
327 215 storres
def pobyso_compute_precision_decay_ratio_function_sa_so():
328 215 storres
    """
329 215 storres
    Compute the precision decay ratio function for polynomial
330 215 storres
    coefficient progressive trucation.
331 215 storres
    """
332 215 storres
    functionText = """
333 215 storres
    proc(deg, a, b, we, wq)
334 215 storres
    {
335 215 storres
      k = we * (exp(x/a)-1) + wq * (b*x)^2 + (1-we-wq) * x;
336 215 storres
      return k/k(d);
337 215 storres
    };
338 215 storres
    """
339 215 storres
    return pobyso_parse_string_sa_so(functionText)
340 215 storres
# End  pobyso_compute_precision_decay_ratio_function.
341 215 storres
342 215 storres
343 5 storres
def pobyso_constant(rnArg):
344 38 storres
    """ Legacy function. See pobyso_constant_sa_so. """
345 38 storres
    return(pobyso_constant_sa_so(rnArg))
346 5 storres
347 84 storres
def pobyso_constant_sa_so(rnArgSa, precisionSa=None):
348 52 storres
    """
349 115 storres
    Create a Sollya constant from a Sage RealNumber.
350 209 storres
    The sollya_lib_constant() function creates a constant
351 209 storres
    with the same precision as the source.
352 52 storres
    """
353 209 storres
    ## Precision stuff. If one wants to change precisions,
354 209 storres
    #  everything takes place in Sage. That only makes
355 209 storres
    #  sense if one wants to reduce the precision.
356 226 storres
    # TODO: revisit precision stuff with new technique.
357 209 storres
    if not precisionSa is None:
358 209 storres
        RRR = RealField(precisionSa)
359 209 storres
        rnArgSa = RRR(rnArgSa)
360 209 storres
    #print rnArgSa, rnArgSa.precision()
361 115 storres
    # Sollya constant creation takes place here.
362 209 storres
    return sollya_lib_constant(get_rn_value(rnArgSa))
363 115 storres
# End pobyso_constant_sa_so
364 115 storres
365 55 storres
def pobyso_constant_0_sa_so():
366 115 storres
    """
367 115 storres
    Obvious.
368 115 storres
    """
369 215 storres
    return pobyso_constant_from_int_sa_so(0)
370 55 storres
371 5 storres
def pobyso_constant_1():
372 115 storres
    """
373 115 storres
    Obvious.
374 115 storres
    Legacy function. See pobyso_constant_so_so.
375 115 storres
    """
376 215 storres
    return pobyso_constant_1_sa_so()
377 5 storres
378 52 storres
def pobyso_constant_1_sa_so():
379 115 storres
    """
380 115 storres
    Obvious.
381 115 storres
    """
382 38 storres
    return(pobyso_constant_from_int_sa_so(1))
383 38 storres
384 5 storres
def pobyso_constant_from_int(anInt):
385 38 storres
    """ Legacy function. See pobyso_constant_from_int_sa_so. """
386 215 storres
    return pobyso_constant_from_int_sa_so(anInt)
387 38 storres
388 38 storres
def pobyso_constant_from_int_sa_so(anInt):
389 115 storres
    """
390 115 storres
    Get a Sollya constant from a Sage int.
391 115 storres
    """
392 215 storres
    return sollya_lib_constant_from_int64(long(anInt))
393 5 storres
394 84 storres
def pobyso_constant_from_int_so_sa(constSo):
395 84 storres
    """
396 117 storres
    Get a Sage int from a Sollya int constant.
397 115 storres
    Usefull for precision or powers in polynomials.
398 84 storres
    """
399 200 storres
    constSa = c_long(0)
400 200 storres
    sollya_lib_get_constant_as_int64(byref(constSa), constSo)
401 215 storres
    return constSa.value
402 84 storres
# End pobyso_constant_from_int_so_sa
403 84 storres
404 209 storres
def pobyso_constant_from_mpq_sa_so(rationalSa):
405 200 storres
    """
406 200 storres
    Make a Sollya constant from Sage rational.
407 209 storres
    The Sollya constant is an unevaluated expression.
408 209 storres
    Hence no precision argument is needed.
409 209 storres
    It is better to leave this way since Sollya has its own
410 209 storres
    optimized evaluation mecanism that tries very hard to
411 209 storres
    return exact values or at least faithful ones.
412 200 storres
    """
413 200 storres
    ratExprSo = \
414 200 storres
        sollya_lib_constant_from_mpq(sgmp_get_rational_value(rationalSa))
415 209 storres
    return ratExprSo
416 200 storres
# End pobyso_constant_from_mpq_sa_so.
417 200 storres
418 209 storres
def pobyso_constant_sollya_prec_sa_so(rnArgSa):
419 209 storres
    """
420 209 storres
    Create a Sollya constant from a Sage RealNumber at the
421 209 storres
    current precision in Sollya.
422 209 storres
    """
423 209 storres
    currentSollyaPrecSa = pobyso_get_prec_so_sa()
424 209 storres
    return pobyso_constant_sa_so(rnArgSa, currentSollyaPrecSa)
425 209 storres
# End pobyso_constant_sollya_prec_sa_so
426 215 storres
427 215 storres
def pobyso_end_elliptic_list_so_sa_so(objectsListSo, intCountSa):
428 215 storres
    """
429 215 storres
    Create a Sollya end elliptic list made of the objectListSo[0] to
430 215 storres
     objectsListSo[intCountSa-1] objects.
431 215 storres
    """
432 215 storres
    return sollya_lib_end_elliptic_list(objectSo, int(intCountSa))
433 215 storres
434 155 storres
def pobyso_error_so():
435 155 storres
    return sollya_lib_error(None)
436 155 storres
# End pobyso_error().
437 155 storres
438 262 storres
def pobyso_evaluate_so_sa(funcSo, argumentSo):
439 262 storres
    """
440 262 storres
    Evaluates funcSo for arguemntSo through sollya_lib_evaluate() and return
441 262 storres
    the result as a Sage object
442 262 storres
    """
443 262 storres
    evalSo = sollya_lib_evaluate(funcSo, argumentSo)
444 262 storres
    if pobyso_is_error_so_sa(evalSo):
445 262 storres
        return None
446 262 storres
    if pobyso_is_range_so_sa(evalSo):
447 262 storres
        retVal = pobyso_range_to_interval_so_sa(evalSo)
448 262 storres
    else:
449 262 storres
        retVal = pobyso_get_constant_as_rn(evalSo)
450 262 storres
    sollya_lib_clear_obj(evalSo)
451 262 storres
    return retVal
452 262 storres
# End pobyso_evaluate_so_sa.
453 262 storres
454 215 storres
def pobyso_evaluate_so_so(funcSo, argumentSo):
455 215 storres
    """
456 215 storres
    Evaluates funcSo for arguemntSo through sollya_lib_evaluate().
457 215 storres
    """
458 215 storres
    return sollya_lib_evaluate(funcSo, argumentSo)
459 215 storres
# End pobyso_evaluate_so_so.
460 240 storres
#
461 240 storres
def pobyso_diff_so_so(funcSo):
462 240 storres
    """
463 240 storres
    Very thin wrapper around sollya_lib_diff.
464 240 storres
    """
465 240 storres
    ## TODO: add a check to make sure funcSo is a functional expression.
466 240 storres
    return sollya_lib_diff(funcSo)
467 237 storres
468 234 storres
def pobyso_dirty_find_zeros_so_so(funcSo, rangeSo):
469 234 storres
    """
470 234 storres
    Thin wrapper over sollya_lib_dirtyfindzeros()
471 234 storres
    """
472 234 storres
    return sollya_lib_dirtyfindzeros(funcSo, rangeSo)
473 234 storres
# End pobys_dirty_find_zeros
474 215 storres
475 237 storres
def pobyso_dirty_inf_norm_so_so(funcSo, rangeSo, preSo=None):
476 237 storres
    """
477 237 storres
    Thin wrapper around sollya_dirtyinfnorm().
478 237 storres
    """
479 237 storres
    # TODO: manage the precision change.
480 237 storres
481 237 storres
    return sollya_lib_dirtyinfnorm(funcSo, rangeSo)
482 237 storres
# End pobyso_dirty_inf_norm_so_so
483 237 storres
484 261 storres
def pobyso_find_zeros_so_so(funcSo, rangeSo):
485 261 storres
    """
486 261 storres
    Thin wrapper over sollya_lib_findzeros()
487 261 storres
    """
488 261 storres
    return sollya_lib_findzeros(funcSo, rangeSo)
489 261 storres
# End pobys_find_zeros
490 261 storres
491 234 storres
def pobyso_float_list_so_sa(listSo):
492 234 storres
    """
493 240 storres
    Return a Sollya list of floating-point numbers as a Sage list of
494 234 storres
    floating-point numbers.
495 240 storres
    TODO: add a test to make sure that each element of the list is a constant.
496 234 storres
    """
497 234 storres
    listSa   = []
498 239 storres
    ## The function returns none if the list is empty or an error has happened.
499 239 storres
    retVal = pobyso_get_list_elements_so_so(listSo)
500 239 storres
    if retVal is None:
501 239 storres
        return listSa
502 240 storres
    ## Just in case the interface is changed and an empty list is returned
503 240 storres
    #  instead of None.
504 239 storres
    elif len(retVal) == 0:
505 239 storres
        return listSa
506 239 storres
    else:
507 239 storres
        ## Remember pobyso_get_list_elements_so_so returns more information
508 240 storres
        #  than just the elements of the list (# elements, is_elliptic)
509 239 storres
        listSaSo, numElements, isEndElliptic = retVal
510 240 storres
    ## Return an empty list.
511 239 storres
    if numElements == 0:
512 239 storres
        return listSa
513 234 storres
    ## Search first for the maximum precision of the elements
514 234 storres
    maxPrecSa = 0
515 234 storres
    for floatSo in listSaSo:
516 240 storres
        #pobyso_autoprint(floatSo)
517 234 storres
        curPrecSa =  pobyso_get_prec_of_constant_so_sa(floatSo)
518 234 storres
        if curPrecSa > maxPrecSa:
519 234 storres
            maxPrecSa = curPrecSa
520 234 storres
    ##
521 234 storres
    RF = RealField(maxPrecSa)
522 234 storres
    ##
523 234 storres
    for floatSo in listSaSo:
524 234 storres
        listSa.append(pobyso_get_constant_as_rn_with_rf_so_sa(floatSo))
525 234 storres
    return listSa
526 234 storres
# End pobyso_float_list_so_sa
527 234 storres
528 209 storres
def pobyso_float_poly_sa_so(polySa, precSa = None):
529 209 storres
    """
530 209 storres
    Create a Sollya polynomial from a Sage RealField polynomial.
531 209 storres
    """
532 209 storres
    ## TODO: filter arguments.
533 209 storres
    ## Precision. If a precision is given, convert the polynomial
534 209 storres
    #  into the right polynomial field. If not convert it straight
535 209 storres
    #  to Sollya.
536 218 storres
    sollyaPrecChanged = False
537 226 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = pobyso_get_prec_so_so_sa()
538 218 storres
    if precSa is None:
539 209 storres
        precSa = polySa.parent().base_ring().precision()
540 226 storres
    if (precSa > initialSollyaPrecSa):
541 228 storres
        assert precSa >= 2, "Precision change <2 requested"
542 226 storres
        if precSa <= 2:
543 226 storres
            print inspect.stack()[0][3], ": precision change <= 2 requested"
544 218 storres
        precSo = pobyso_constant_from_int(precSa)
545 218 storres
        pobyso_set_prec_so_so(precSo)
546 218 storres
        sollya_lib_clear_obj(precSo)
547 272 storres
        sollyaPrecChanged = True
548 272 storres
    ## Free variable stuff.
549 272 storres
    freeVariableNameChanged = False
550 272 storres
    polyFreeVariableNameSa = \
551 272 storres
        str(polySa.variables()[0])
552 272 storres
    currentFreeVariableNameSa = pobyso_get_free_variable_name_so_sa()
553 272 storres
    if polyFreeVariableNameSa != currentFreeVariableNameSa:
554 272 storres
        #print "Free variable names do not match.", polyFreeVariableNameSa
555 272 storres
        sollya_lib_name_free_variable(polyFreeVariableNameSa)
556 272 storres
        freeVariableNameChanged = True
557 209 storres
    ## Get exponents and coefficients.
558 218 storres
    exponentsSa     = polySa.exponents()
559 218 storres
    coefficientsSa  = polySa.coefficients()
560 209 storres
    ## Build the polynomial.
561 209 storres
    polySo = None
562 213 storres
    for coefficientSa, exponentSa in zip(coefficientsSa, exponentsSa):
563 209 storres
        #print coefficientSa.n(prec=precSa), exponentSa
564 209 storres
        coefficientSo = \
565 209 storres
            pobyso_constant_sa_so(coefficientSa)
566 209 storres
        #pobyso_autoprint(coefficientSo)
567 209 storres
        exponentSo = \
568 209 storres
            pobyso_constant_from_int_sa_so(exponentSa)
569 209 storres
        #pobyso_autoprint(exponentSo)
570 209 storres
        monomialSo = sollya_lib_build_function_pow(
571 209 storres
                       sollya_lib_build_function_free_variable(),
572 209 storres
                       exponentSo)
573 218 storres
        polyTermSo = sollya_lib_build_function_mul(coefficientSo,
574 218 storres
                                                       monomialSo)
575 209 storres
        if polySo is None:
576 218 storres
            polySo = polyTermSo
577 209 storres
        else:
578 209 storres
            polySo = sollya_lib_build_function_add(polySo, polyTermSo)
579 218 storres
    if sollyaPrecChanged:
580 226 storres
        pobyso_set_prec_so_so(initialSollyaPrecSo)
581 272 storres
    sollya_lib_clear_obj(initialSollyaPrecSo)
582 272 storres
    ## Do not set back the free variable name in Sollya to its initial value:
583 272 storres
    #  it will change it back, in the Sollya polynomial, to what it was in the
584 272 storres
    #  first place.
585 209 storres
    return polySo
586 209 storres
# End pobyso_float_poly_sa_so
587 209 storres
588 209 storres
def pobyso_float_poly_so_sa(polySo, realFieldSa=None):
589 209 storres
    """
590 209 storres
    Convert a Sollya polynomial into a Sage floating-point polynomial.
591 209 storres
    If no realField is given, a RealField corresponding to the maximum
592 209 storres
    precision of the coefficients is internally computed.
593 209 storres
    The real field is not returned but can be easily retrieved from
594 209 storres
    the polynomial itself.
595 209 storres
    ALGORITHM:
596 209 storres
    - (optional) compute the RealField of the coefficients;
597 209 storres
    - convert the Sollya expression into a Sage expression;
598 209 storres
    - convert the Sage expression into a Sage polynomial
599 209 storres
    """
600 209 storres
    if realFieldSa is None:
601 209 storres
        expressionPrecSa = pobyso_get_max_prec_of_exp_so_sa(polySo)
602 218 storres
        #print "Maximum precision of Sollya polynomial coefficients:", expressionPrecSa
603 226 storres
        if expressionPrecSa < 2 or expressionPrecSa > 2147483391:
604 226 storres
            print "Maximum degree of expression:", expressionPrecSa
605 209 storres
        realFieldSa      = RealField(expressionPrecSa)
606 209 storres
    #print "Sollya expression before...",
607 209 storres
    #pobyso_autoprint(polySo)
608 209 storres
609 209 storres
    expressionSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo,
610 209 storres
                                                             realFieldSa)
611 218 storres
    #print "...Sollya expression after."
612 209 storres
    #pobyso_autoprint(polySo)
613 209 storres
    polyVariableSa = expressionSa.variables()[0]
614 209 storres
    polyRingSa     = realFieldSa[str(polyVariableSa)]
615 209 storres
    #print polyRingSa
616 209 storres
    # Do not use the polynomial(expressionSa, ring=polyRingSa) form!
617 209 storres
    polynomialSa = polyRingSa(expressionSa)
618 215 storres
    polyCoeffsListSa = polynomialSa.coefficients()
619 215 storres
    #for coeff in polyCoeffsListSa:
620 215 storres
    #    print coeff.abs().n()
621 209 storres
    return polynomialSa
622 209 storres
# End pobyso_float_poly_so_sa
623 209 storres
624 215 storres
def pobyso_free_variable():
625 215 storres
    """
626 215 storres
    Ultra thin wrapper around the sollya_lib_function_build_free_variable function.
627 215 storres
    """
628 215 storres
    return sollya_lib_build_function_free_variable()
629 209 storres
630 5 storres
def pobyso_function_type_as_string(funcType):
631 38 storres
    """ Legacy function. See pobyso_function_type_as_string_so_sa. """
632 38 storres
    return(pobyso_function_type_as_string_so_sa(funcType))
633 38 storres
634 38 storres
def pobyso_function_type_as_string_so_sa(funcType):
635 38 storres
    """
636 38 storres
    Numeric Sollya function codes -> Sage mathematical function names.
637 38 storres
    Notice that pow -> ^ (a la Sage, not a la Python).
638 38 storres
    """
639 5 storres
    if funcType == SOLLYA_BASE_FUNC_ABS:
640 5 storres
        return "abs"
641 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ACOS:
642 5 storres
        return "arccos"
643 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ACOSH:
644 5 storres
        return "arccosh"
645 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ADD:
646 5 storres
        return "+"
647 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ASIN:
648 5 storres
        return "arcsin"
649 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ASINH:
650 5 storres
        return "arcsinh"
651 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ATAN:
652 5 storres
        return "arctan"
653 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ATANH:
654 5 storres
        return "arctanh"
655 5 storres
    elif funcType == SOLLYA_BASE_FUNC_CEIL:
656 5 storres
        return "ceil"
657 5 storres
    elif funcType == SOLLYA_BASE_FUNC_CONSTANT:
658 5 storres
        return "cte"
659 5 storres
    elif funcType == SOLLYA_BASE_FUNC_COS:
660 5 storres
        return "cos"
661 5 storres
    elif funcType == SOLLYA_BASE_FUNC_COSH:
662 5 storres
        return "cosh"
663 5 storres
    elif funcType == SOLLYA_BASE_FUNC_DIV:
664 5 storres
        return "/"
665 5 storres
    elif funcType == SOLLYA_BASE_FUNC_DOUBLE:
666 5 storres
        return "double"
667 5 storres
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEDOUBLE:
668 5 storres
        return "doubleDouble"
669 5 storres
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEEXTENDED:
670 5 storres
        return "doubleDxtended"
671 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ERF:
672 5 storres
        return "erf"
673 5 storres
    elif funcType == SOLLYA_BASE_FUNC_ERFC:
674 5 storres
        return "erfc"
675 5 storres
    elif funcType == SOLLYA_BASE_FUNC_EXP:
676 5 storres
        return "exp"
677 5 storres
    elif funcType == SOLLYA_BASE_FUNC_EXP_M1:
678 5 storres
        return "expm1"
679 5 storres
    elif funcType == SOLLYA_BASE_FUNC_FLOOR:
680 5 storres
        return "floor"
681 5 storres
    elif funcType == SOLLYA_BASE_FUNC_FREE_VARIABLE:
682 5 storres
        return "freeVariable"
683 5 storres
    elif funcType == SOLLYA_BASE_FUNC_HALFPRECISION:
684 5 storres
        return "halfPrecision"
685 5 storres
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYCONSTANT:
686 5 storres
        return "libraryConstant"
687 5 storres
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYFUNCTION:
688 5 storres
        return "libraryFunction"
689 5 storres
    elif funcType == SOLLYA_BASE_FUNC_LOG:
690 5 storres
        return "log"
691 5 storres
    elif funcType == SOLLYA_BASE_FUNC_LOG_10:
692 5 storres
        return "log10"
693 5 storres
    elif funcType == SOLLYA_BASE_FUNC_LOG_1P:
694 5 storres
        return "log1p"
695 5 storres
    elif funcType == SOLLYA_BASE_FUNC_LOG_2:
696 5 storres
        return "log2"
697 5 storres
    elif funcType == SOLLYA_BASE_FUNC_MUL:
698 5 storres
        return "*"
699 5 storres
    elif funcType == SOLLYA_BASE_FUNC_NEARESTINT:
700 5 storres
        return "round"
701 5 storres
    elif funcType == SOLLYA_BASE_FUNC_NEG:
702 5 storres
        return "__neg__"
703 5 storres
    elif funcType == SOLLYA_BASE_FUNC_PI:
704 5 storres
        return "pi"
705 5 storres
    elif funcType == SOLLYA_BASE_FUNC_POW:
706 5 storres
        return "^"
707 5 storres
    elif funcType == SOLLYA_BASE_FUNC_PROCEDUREFUNCTION:
708 5 storres
        return "procedureFunction"
709 5 storres
    elif funcType == SOLLYA_BASE_FUNC_QUAD:
710 5 storres
        return "quad"
711 5 storres
    elif funcType == SOLLYA_BASE_FUNC_SIN:
712 5 storres
        return "sin"
713 5 storres
    elif funcType == SOLLYA_BASE_FUNC_SINGLE:
714 5 storres
        return "single"
715 5 storres
    elif funcType == SOLLYA_BASE_FUNC_SINH:
716 5 storres
        return "sinh"
717 5 storres
    elif funcType == SOLLYA_BASE_FUNC_SQRT:
718 5 storres
        return "sqrt"
719 5 storres
    elif funcType == SOLLYA_BASE_FUNC_SUB:
720 5 storres
        return "-"
721 5 storres
    elif funcType == SOLLYA_BASE_FUNC_TAN:
722 5 storres
        return "tan"
723 5 storres
    elif funcType == SOLLYA_BASE_FUNC_TANH:
724 5 storres
        return "tanh"
725 5 storres
    elif funcType == SOLLYA_BASE_FUNC_TRIPLEDOUBLE:
726 5 storres
        return "tripleDouble"
727 5 storres
    else:
728 5 storres
        return None
729 5 storres
730 85 storres
def pobyso_get_constant(rnArgSa, constSo):
731 38 storres
    """ Legacy function. See pobyso_get_constant_so_sa. """
732 209 storres
    return pobyso_get_constant_so_sa(rnArgSa, constSo)
733 209 storres
# End pobyso_get_constant
734 38 storres
735 84 storres
def pobyso_get_constant_so_sa(rnArgSa, constSo):
736 52 storres
    """
737 85 storres
    Set the value of rnArgSo to the value of constSo in MPFR_RNDN mode.
738 52 storres
    rnArg must already exist and belong to some RealField.
739 85 storres
    We assume that constSo points to a Sollya constant.
740 52 storres
    """
741 209 storres
    outcome = sollya_lib_get_constant(get_rn_value(rnArgSa), constSo)
742 209 storres
    if outcome == 0: # Failure because constSo is not a constant expression.
743 209 storres
        return None
744 209 storres
    else:
745 209 storres
        return outcome
746 209 storres
# End  pobyso_get_constant_so_sa
747 209 storres
748 57 storres
def pobyso_get_constant_as_rn(ctExpSo):
749 83 storres
    """
750 83 storres
    Legacy function. See pobyso_get_constant_as_rn_so_sa.
751 83 storres
    """
752 57 storres
    return(pobyso_get_constant_as_rn_so_sa(ctExpSo))
753 38 storres
754 56 storres
def pobyso_get_constant_as_rn_so_sa(constExpSo):
755 83 storres
    """
756 83 storres
    Get a Sollya constant as a Sage "real number".
757 83 storres
    The precision of the floating-point number returned is that of the Sollya
758 83 storres
    constant.
759 83 storres
    """
760 218 storres
    #print "Before computing precision of variable..."
761 218 storres
    #pobyso_autoprint(constExpSo)
762 209 storres
    precisionSa  = pobyso_get_prec_of_constant_so_sa(constExpSo)
763 218 storres
    #print "precisionSa:", precisionSa
764 209 storres
    ## If the expression can not be exactly converted, None is returned.
765 209 storres
    #  In this case opt for the Sollya current expression.
766 209 storres
    if precisionSa is None:
767 209 storres
        precisionSa = pobyso_get_prec_so_sa()
768 56 storres
    RRRR = RealField(precisionSa)
769 56 storres
    rnSa = RRRR(0)
770 209 storres
    outcome = sollya_lib_get_constant(get_rn_value(rnSa), constExpSo)
771 209 storres
    if outcome == 0:
772 209 storres
        return None
773 209 storres
    else:
774 209 storres
        return rnSa
775 83 storres
# End pobyso_get_constant_as_rn_so_sa
776 38 storres
777 38 storres
def pobyso_get_constant_as_rn_with_rf(ctExp, realField):
778 83 storres
    """
779 83 storres
    Legacy function. See pobyso_get_constant_as_rn_with_rf_so_sa.
780 83 storres
    """
781 209 storres
    return pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField)
782 209 storres
# End pobyso_get_constant_as_rn_with_rf
783 5 storres
784 56 storres
def pobyso_get_constant_as_rn_with_rf_so_sa(ctExpSo, realFieldSa = None):
785 83 storres
    """
786 83 storres
    Get a Sollya constant as a Sage "real number".
787 83 storres
    If no real field is specified, the precision of the floating-point number
788 85 storres
    returned is that of the Sollya constant.
789 83 storres
    Otherwise is is that of the real field. Hence rounding may happen.
790 83 storres
    """
791 56 storres
    if realFieldSa is None:
792 209 storres
        return pobyso_get_constant_as_rn_so_sa(ctExpSo)
793 56 storres
    rnSa = realFieldSa(0)
794 209 storres
    outcome = sollya_lib_get_constant(get_rn_value(rnSa), ctExpSo)
795 209 storres
    if outcome == 0:
796 209 storres
        return None
797 209 storres
    else:
798 209 storres
        return rnSa
799 83 storres
# End pobyso_get_constant_as_rn_with_rf_so_sa
800 38 storres
801 5 storres
def pobyso_get_free_variable_name():
802 83 storres
    """
803 83 storres
    Legacy function. See pobyso_get_free_variable_name_so_sa.
804 83 storres
    """
805 38 storres
    return(pobyso_get_free_variable_name_so_sa())
806 38 storres
807 38 storres
def pobyso_get_free_variable_name_so_sa():
808 209 storres
    return sollya_lib_get_free_variable_name()
809 5 storres
810 38 storres
def pobyso_get_function_arity(expressionSo):
811 83 storres
    """
812 83 storres
    Legacy function. See pobyso_get_function_arity_so_sa.
813 83 storres
    """
814 38 storres
    return(pobyso_get_function_arity_so_sa(expressionSo))
815 38 storres
816 38 storres
def pobyso_get_function_arity_so_sa(expressionSo):
817 5 storres
    arity = c_int(0)
818 38 storres
    sollya_lib_get_function_arity(byref(arity),expressionSo)
819 209 storres
    return int(arity.value)
820 5 storres
821 38 storres
def pobyso_get_head_function(expressionSo):
822 83 storres
    """
823 83 storres
    Legacy function. See pobyso_get_head_function_so_sa.
824 83 storres
    """
825 38 storres
    return(pobyso_get_head_function_so_sa(expressionSo))
826 38 storres
827 38 storres
def pobyso_get_head_function_so_sa(expressionSo):
828 5 storres
    functionType = c_int(0)
829 218 storres
    sollya_lib_get_head_function(byref(functionType), expressionSo)
830 209 storres
    return int(functionType.value)
831 5 storres
832 56 storres
def pobyso_get_interval_from_range_so_sa(soRange, realIntervalFieldSa = None ):
833 53 storres
    """
834 53 storres
    Return the Sage interval corresponding to the Sollya range argument.
835 83 storres
    If no reaIntervalField is passed as an argument, the interval bounds are not
836 56 storres
    rounded: they are elements of RealIntervalField of the "right" precision
837 56 storres
    to hold all the digits.
838 53 storres
    """
839 53 storres
    prec = c_int(0)
840 56 storres
    if realIntervalFieldSa is None:
841 56 storres
        retval = sollya_lib_get_prec_of_range(byref(prec), soRange, None)
842 56 storres
        if retval == 0:
843 209 storres
            return None
844 56 storres
        realIntervalFieldSa = RealIntervalField(prec.value)
845 56 storres
    intervalSa = realIntervalFieldSa(0,0)
846 53 storres
    retval = \
847 53 storres
        sollya_lib_get_interval_from_range(get_interval_value(intervalSa),\
848 53 storres
                                           soRange)
849 53 storres
    if retval == 0:
850 209 storres
        return None
851 209 storres
    return intervalSa
852 56 storres
# End pobyso_get_interval_from_range_so_sa
853 56 storres
854 5 storres
def pobyso_get_list_elements(soObj):
855 38 storres
    """ Legacy function. See pobyso_get_list_elements_so_so. """
856 209 storres
    return pobyso_get_list_elements_so_so(soObj)
857 38 storres
858 117 storres
def pobyso_get_list_elements_so_so(objectListSo):
859 51 storres
    """
860 118 storres
    Get the Sollya list elements as a Sage/Python array of Sollya objects.
861 118 storres

862 118 storres
    INPUT:
863 118 storres
    - objectListSo: a Sollya list of Sollya objects.
864 118 storres

865 118 storres
    OUTPUT:
866 118 storres
    - a Sage/Python tuple made of:
867 118 storres
      - a Sage/Python list of Sollya objects,
868 118 storres
      - a Sage/Python int holding the number of elements,
869 118 storres
      - a Sage/Python int stating (!= 0) that the list is end-elliptic.
870 118 storres
    NOTE::
871 118 storres
        We recover the addresses of the Sollya object from the list of pointers
872 118 storres
        returned by sollya_lib_get_list_elements. The list itself is freed.
873 118 storres
    TODO::
874 118 storres
        Figure out what to do with numElements since the number of elements
875 118 storres
        can easily be recovered from the list itself.
876 118 storres
        Ditto for isEndElliptic.
877 51 storres
    """
878 5 storres
    listAddress = POINTER(c_longlong)()
879 5 storres
    numElements = c_int(0)
880 5 storres
    isEndElliptic = c_int(0)
881 117 storres
    listAsSageList = []
882 5 storres
    result = sollya_lib_get_list_elements(byref(listAddress),\
883 54 storres
                                          byref(numElements),\
884 54 storres
                                          byref(isEndElliptic),\
885 117 storres
                                          objectListSo)
886 5 storres
    if result == 0 :
887 5 storres
        return None
888 5 storres
    for i in xrange(0, numElements.value, 1):
889 118 storres
       #listAsSageList.append(sollya_lib_copy_obj(listAddress[i]))
890 118 storres
       listAsSageList.append(listAddress[i])
891 117 storres
       # Clear each of the elements returned by Sollya.
892 118 storres
       #sollya_lib_clear_obj(listAddress[i])
893 117 storres
    # Free the list itself.
894 117 storres
    sollya_lib_free(listAddress)
895 209 storres
    return (listAsSageList, numElements.value, isEndElliptic.value)
896 5 storres
897 38 storres
def pobyso_get_max_prec_of_exp(soExp):
898 38 storres
    """ Legacy function. See pobyso_get_max_prec_of_exp_so_sa. """
899 209 storres
    return pobyso_get_max_prec_of_exp_so_sa(soExp)
900 5 storres
901 85 storres
def pobyso_get_max_prec_of_exp_so_sa(expSo):
902 38 storres
    """
903 38 storres
    Get the maximum precision used for the numbers in a Sollya expression.
904 52 storres

905 52 storres
    Arguments:
906 52 storres
    soExp -- a Sollya expression pointer
907 52 storres
    Return value:
908 52 storres
    A Python integer
909 38 storres
    TODO:
910 38 storres
    - error management;
911 38 storres
    - correctly deal with numerical type such as DOUBLEEXTENDED.
912 38 storres
    """
913 226 storres
    if expSo is None:
914 226 storres
        print inspect.stack()[0][3], ": expSo is None."
915 226 storres
        return 0
916 5 storres
    maxPrecision = 0
917 52 storres
    minConstPrec = 0
918 52 storres
    currentConstPrec = 0
919 226 storres
    #pobyso_autoprint(expSo)
920 85 storres
    operator = pobyso_get_head_function_so_sa(expSo)
921 5 storres
    if (operator != SOLLYA_BASE_FUNC_CONSTANT) and \
922 5 storres
    (operator != SOLLYA_BASE_FUNC_FREE_VARIABLE):
923 85 storres
        (arity, subexpressions) = pobyso_get_subfunctions_so_sa(expSo)
924 5 storres
        for i in xrange(arity):
925 5 storres
            maxPrecisionCandidate = \
926 38 storres
                pobyso_get_max_prec_of_exp_so_sa(subexpressions[i])
927 5 storres
            if maxPrecisionCandidate > maxPrecision:
928 5 storres
                maxPrecision = maxPrecisionCandidate
929 209 storres
        return maxPrecision
930 5 storres
    elif operator == SOLLYA_BASE_FUNC_CONSTANT:
931 85 storres
        #minConstPrec = pobyso_get_min_prec_of_constant_so_sa(expSo)
932 52 storres
        #currentConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
933 52 storres
        #print minConstPrec, " - ", currentConstPrec
934 209 storres
        return pobyso_get_min_prec_of_constant_so_sa(expSo)
935 52 storres
936 5 storres
    elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
937 209 storres
        return 0
938 5 storres
    else:
939 38 storres
        print "pobyso_get_max_prec_of_exp_so_sa: unexepected operator."
940 209 storres
        return 0
941 5 storres
942 85 storres
def pobyso_get_min_prec_of_constant_so_sa(constExpSo):
943 52 storres
    """
944 52 storres
    Get the minimum precision necessary to represent the value of a Sollya
945 52 storres
    constant.
946 52 storres
    MPFR_MIN_PREC and powers of 2 are taken into account.
947 209 storres
    We assume that constExpSo is a pointer to a Sollay constant expression.
948 52 storres
    """
949 85 storres
    constExpAsRnSa = pobyso_get_constant_as_rn_so_sa(constExpSo)
950 85 storres
    return(min_mpfr_size(get_rn_value(constExpAsRnSa)))
951 52 storres
952 200 storres
def pobyso_get_poly_so_sa(polySo, realFieldSa=None):
953 200 storres
    """
954 200 storres
    Convert a Sollya polynomial into a Sage polynomial.
955 209 storres
    Legacy function. Use pobyso_float_poly_so_sa() instead.
956 200 storres
    """
957 213 storres
    return pobyso_float_poly_so_sa(polySo,realFieldSa)
958 200 storres
# End pobyso_get_poly_so_sa
959 200 storres
960 200 storres
def pobyso_get_prec():
961 200 storres
    """ Legacy function. See pobyso_get_prec_so_sa(). """
962 209 storres
    return pobyso_get_prec_so_sa()
963 200 storres
964 200 storres
def pobyso_get_prec_so():
965 200 storres
    """
966 200 storres
    Get the current default precision in Sollya.
967 200 storres
    The return value is a Sollya object.
968 200 storres
    Usefull when modifying the precision back and forth by avoiding
969 200 storres
    extra conversions.
970 200 storres
    """
971 209 storres
    return sollya_lib_get_prec(None)
972 200 storres
973 200 storres
def pobyso_get_prec_so_sa():
974 200 storres
    """
975 200 storres
    Get the current default precision in Sollya.
976 200 storres
    The return value is Sage/Python int.
977 200 storres
    """
978 227 storres
    precSo = sollya_lib_get_prec()
979 227 storres
    precSa = pobyso_constant_from_int_so_sa(precSo)
980 200 storres
    sollya_lib_clear_obj(precSo)
981 227 storres
    return precSa
982 200 storres
# End pobyso_get_prec_so_sa.
983 200 storres
984 209 storres
def pobyso_get_prec_so_so_sa():
985 209 storres
    """
986 209 storres
    Return the current precision both as a Sollya object and a
987 209 storres
    Sage integer as hybrid tuple.
988 209 storres
    To avoid multiple calls for precision manipulations.
989 209 storres
    """
990 227 storres
    precSo = sollya_lib_get_prec()
991 227 storres
    precSa = pobyso_constant_from_int_so_sa(precSo)
992 227 storres
    return (precSo, int(precSa))
993 200 storres
994 200 storres
def pobyso_get_prec_of_constant(ctExpSo):
995 200 storres
    """ Legacy function. See pobyso_get_prec_of_constant_so_sa. """
996 209 storres
    return pobyso_get_prec_of_constant_so_sa(ctExpSo)
997 200 storres
998 200 storres
def pobyso_get_prec_of_constant_so_sa(ctExpSo):
999 200 storres
    """
1000 200 storres
    Tries to find a precision to represent ctExpSo without rounding.
1001 200 storres
    If not possible, returns None.
1002 200 storres
    """
1003 218 storres
    #print "Entering pobyso_get_prec_of_constant_so_sa..."
1004 200 storres
    prec = c_int(0)
1005 200 storres
    retc = sollya_lib_get_prec_of_constant(byref(prec), ctExpSo, None)
1006 200 storres
    if retc == 0:
1007 218 storres
        #print "pobyso_get_prec_of_constant_so_sa failed."
1008 209 storres
        return None
1009 218 storres
    #print "...exiting pobyso_get_prec_of_constant_so_sa."
1010 209 storres
    return int(prec.value)
1011 200 storres
1012 200 storres
def pobyso_get_prec_of_range_so_sa(rangeSo):
1013 200 storres
    """
1014 200 storres
    Returns the number of bits elements of a range are coded with.
1015 200 storres
    """
1016 200 storres
    prec = c_int(0)
1017 200 storres
    retc = sollya_lib_get_prec_of_range(byref(prec), rangeSo, None)
1018 200 storres
    if retc == 0:
1019 200 storres
        return(None)
1020 209 storres
    return int(prec.value)
1021 200 storres
# End pobyso_get_prec_of_range_so_sa()
1022 200 storres
1023 85 storres
def pobyso_get_sage_exp_from_sollya_exp(sollyaExpSo, realField = RR):
1024 38 storres
    """ Legacy function. See pobyso_get_sage_exp_from_sollya_exp_so_sa. """
1025 209 storres
    return pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo,
1026 209 storres
                                                     realField = RR)
1027 38 storres
1028 85 storres
def pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, realFieldSa = RR):
1029 5 storres
    """
1030 38 storres
    Get a Sage expression from a Sollya expression.
1031 38 storres
    Currently only tested with polynomials with floating-point coefficients.
1032 5 storres
    Notice that, in the returned polynomial, the exponents are RealNumbers.
1033 5 storres
    """
1034 5 storres
    #pobyso_autoprint(sollyaExp)
1035 85 storres
    operatorSa = pobyso_get_head_function_so_sa(sollyaExpSo)
1036 83 storres
    sollyaLibFreeVariableName = sollya_lib_get_free_variable_name()
1037 213 storres
    ## Get rid of the "_"'s in "_x_", if any.
1038 213 storres
    sollyaLibFreeVariableName = re.sub('_', '', sollyaLibFreeVariableName)
1039 5 storres
    # Constants and the free variable are special cases.
1040 5 storres
    # All other operator are dealt with in the same way.
1041 85 storres
    if (operatorSa != SOLLYA_BASE_FUNC_CONSTANT) and \
1042 85 storres
       (operatorSa != SOLLYA_BASE_FUNC_FREE_VARIABLE):
1043 85 storres
        (aritySa, subexpressionsSa) = pobyso_get_subfunctions_so_sa(sollyaExpSo)
1044 85 storres
        if aritySa == 1:
1045 85 storres
            sageExpSa = eval(pobyso_function_type_as_string_so_sa(operatorSa) + \
1046 85 storres
            "(" + pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], \
1047 85 storres
            realFieldSa) + ")")
1048 85 storres
        elif aritySa == 2:
1049 63 storres
            # We do not get through the preprocessor.
1050 63 storres
            # The "^" operator is then a special case.
1051 85 storres
            if operatorSa == SOLLYA_BASE_FUNC_POW:
1052 85 storres
                operatorAsStringSa = "**"
1053 5 storres
            else:
1054 85 storres
                operatorAsStringSa = \
1055 85 storres
                    pobyso_function_type_as_string_so_sa(operatorSa)
1056 85 storres
            sageExpSa = \
1057 85 storres
              eval("pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], realFieldSa)"\
1058 85 storres
              + " " + operatorAsStringSa + " " + \
1059 85 storres
                   "pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[1], realFieldSa)")
1060 63 storres
        # We do not know yet how to deal with arity >= 3
1061 63 storres
        # (is there any in Sollya anyway?).
1062 5 storres
        else:
1063 85 storres
            sageExpSa = eval('None')
1064 209 storres
        return sageExpSa
1065 85 storres
    elif operatorSa == SOLLYA_BASE_FUNC_CONSTANT:
1066 5 storres
        #print "This is a constant"
1067 85 storres
        return pobyso_get_constant_as_rn_with_rf_so_sa(sollyaExpSo, realFieldSa)
1068 85 storres
    elif operatorSa == SOLLYA_BASE_FUNC_FREE_VARIABLE:
1069 218 storres
        #print "This is the free variable"
1070 209 storres
        return eval(sollyaLibFreeVariableName)
1071 5 storres
    else:
1072 5 storres
        print "Unexpected"
1073 5 storres
        return eval('None')
1074 185 storres
# End pobyso_get_sage_exp_from_sollya_exp_so_sa
1075 73 storres
1076 185 storres
1077 38 storres
def pobyso_get_subfunctions(expressionSo):
1078 38 storres
    """ Legacy function. See pobyso_get_subfunctions_so_sa. """
1079 209 storres
    return pobyso_get_subfunctions_so_sa(expressionSo)
1080 200 storres
# End pobyso_get_subfunctions.
1081 200 storres
1082 38 storres
def pobyso_get_subfunctions_so_sa(expressionSo):
1083 38 storres
    """
1084 38 storres
    Get the subfunctions of an expression.
1085 38 storres
    Return the number of subfunctions and the list of subfunctions addresses.
1086 55 storres
    S.T.: Could not figure out another way than that ugly list of declarations
1087 83 storres
    to recover the addresses of the subfunctions.
1088 83 storres
    We limit ourselves to arity 8 functions.
1089 38 storres
    """
1090 5 storres
    subf0 = c_int(0)
1091 5 storres
    subf1 = c_int(0)
1092 5 storres
    subf2 = c_int(0)
1093 5 storres
    subf3 = c_int(0)
1094 5 storres
    subf4 = c_int(0)
1095 5 storres
    subf5 = c_int(0)
1096 5 storres
    subf6 = c_int(0)
1097 5 storres
    subf7 = c_int(0)
1098 5 storres
    subf8 = c_int(0)
1099 5 storres
    arity = c_int(0)
1100 5 storres
    nullPtr = POINTER(c_int)()
1101 38 storres
    sollya_lib_get_subfunctions(expressionSo, byref(arity), \
1102 83 storres
      byref(subf0), byref(subf1), byref(subf2), byref(subf3), \
1103 83 storres
      byref(subf4), byref(subf5),\
1104 83 storres
      byref(subf6), byref(subf7), byref(subf8), nullPtr, None)
1105 83 storres
#    byref(cast(subfunctions[0], POINTER(c_int))), \
1106 83 storres
#    byref(cast(subfunctions[0], POINTER(c_int))), \
1107 83 storres
#    byref(cast(subfunctions[2], POINTER(c_int))), \
1108 83 storres
#    byref(cast(subfunctions[3], POINTER(c_int))), \
1109 83 storres
#    byref(cast(subfunctions[4], POINTER(c_int))), \
1110 83 storres
#    byref(cast(subfunctions[5], POINTER(c_int))), \
1111 83 storres
#    byref(cast(subfunctions[6], POINTER(c_int))), \
1112 83 storres
#    byref(cast(subfunctions[7], POINTER(c_int))), \
1113 5 storres
#    byref(cast(subfunctions[8], POINTER(c_int))), nullPtr)
1114 83 storres
    subfunctions = [subf0, subf1, subf2, subf3, subf4, subf5, subf6, subf7, \
1115 83 storres
                    subf8]
1116 5 storres
    subs = []
1117 5 storres
    if arity.value > pobyso_max_arity:
1118 38 storres
        return(0,[])
1119 5 storres
    for i in xrange(arity.value):
1120 5 storres
        subs.append(int(subfunctions[i].value))
1121 5 storres
        #print subs[i]
1122 209 storres
    return (int(arity.value), subs)
1123 200 storres
# End pobyso_get_subfunctions_so_sa
1124 5 storres
1125 155 storres
def pobyso_guess_degree_sa_sa(functionSa, intervalSa, approxErrorSa,
1126 155 storres
                              weightSa=None, degreeBoundSa=None):
1127 155 storres
    """
1128 155 storres
    Sa_sa variant of the solly_guessdegree function.
1129 155 storres
    Return 0 if something goes wrong.
1130 155 storres
    """
1131 159 storres
    functionAsStringSa = functionSa._assume_str().replace('_SAGE_VAR_', '')
1132 154 storres
    functionSo = pobyso_parse_string_sa_so(functionAsStringSa)
1133 155 storres
    if pobyso_is_error_so_sa(functionSo):
1134 155 storres
        sollya_lib_clear_obj(functionSo)
1135 155 storres
        return 0
1136 154 storres
    rangeSo = pobyso_interval_to_range_sa_so(intervalSa)
1137 155 storres
    # The approximation error is expected to be a floating point number.
1138 155 storres
    if pobyso_is_floating_point_number_sa_sa(approxErrorSa):
1139 155 storres
        approxErrorSo = pobyso_constant_sa_so(approxErrorSa)
1140 155 storres
    else:
1141 155 storres
        approxErrorSo = pobyso_constant_sa_so(RR(approxErrorSa))
1142 154 storres
    if not weightSa is None:
1143 159 storres
        weightAsStringSa = weightSa._assume_str().replace('_SAGE_VAR_', '')
1144 154 storres
        weightSo = pobyso_parse_string_sa_so(weightAsStringSa)
1145 166 storres
        if pobyso_is_error_so_sa(weightSo):
1146 155 storres
            sollya_lib_clear_obj(functionSo)
1147 155 storres
            sollya_lib_clear_obj(rangeSo)
1148 155 storres
            sollya_lib_clear_obj(approxErrorSo)
1149 155 storres
            sollya_lib_clear_obj(weightSo)
1150 155 storres
            return 0
1151 154 storres
    else:
1152 154 storres
        weightSo = None
1153 154 storres
    if not degreeBoundSa is None:
1154 154 storres
        degreeBoundSo = pobyso_constant_from_int_sa_so(degreeBoundSa)
1155 154 storres
    else:
1156 154 storres
        degreeBoundSo = None
1157 154 storres
    guessedDegreeSa = pobyso_guess_degree_so_sa(functionSo,
1158 162 storres
                                                rangeSo,
1159 162 storres
                                                approxErrorSo,
1160 162 storres
                                                weightSo,
1161 162 storres
                                                degreeBoundSo)
1162 154 storres
    sollya_lib_clear_obj(functionSo)
1163 154 storres
    sollya_lib_clear_obj(rangeSo)
1164 155 storres
    sollya_lib_clear_obj(approxErrorSo)
1165 154 storres
    if not weightSo is None:
1166 154 storres
        sollya_lib_clear_obj(weightSo)
1167 154 storres
    if not degreeBoundSo is None:
1168 154 storres
        sollya_lib_clear_obj(degreeBoundSo)
1169 154 storres
    return guessedDegreeSa
1170 154 storres
# End poyso_guess_degree_sa_sa
1171 154 storres
1172 153 storres
def pobyso_guess_degree_so_sa(functionSo, rangeSo, errorSo, weightSo=None, \
1173 154 storres
                              degreeBoundSo=None):
1174 154 storres
    """
1175 154 storres
    Thin wrapper around the guessdegree function.
1176 154 storres
    Nevertheless, some precision control stuff has been appended.
1177 154 storres
    """
1178 154 storres
    # Deal with Sollya internal precision issues: if it is too small,
1179 154 storres
    # compared with the error, increases it to about twice -log2(error).
1180 154 storres
    errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(errorSo)
1181 154 storres
    log2ErrorSa = errorSa.log2()
1182 154 storres
    if log2ErrorSa < 0:
1183 154 storres
        neededPrecisionSa = int(2 * int(-log2ErrorSa) / 64) * 64
1184 154 storres
    else:
1185 154 storres
        neededPrecisionSa = int(2 * int(log2ErrorSa) / 64) * 64
1186 154 storres
    #print "Needed precision:", neededPrecisionSa
1187 226 storres
    sollyaPrecisionHasChanged = False
1188 226 storres
    (initialPrecSo, initialPrecSa) = pobyso_get_prec_so_so_sa()
1189 226 storres
    if neededPrecisionSa > initialPrecSa:
1190 226 storres
        if neededPrecisionSa <= 2:
1191 226 storres
            print inspect.stack()[0][3], ": precision change <= 2 requested."
1192 154 storres
        pobyso_set_prec_sa_so(neededPrecisionSa)
1193 226 storres
        sollyaPrecisionHasChanged = True
1194 166 storres
    #print "Guessing degree..."
1195 153 storres
    # weightSo and degreeBoundsSo are optional arguments.
1196 162 storres
    # As declared, sollya_lib_guessdegree must take 5 arguments.
1197 153 storres
    if weightSo is None:
1198 162 storres
        degreeRangeSo = sollya_lib_guessdegree(functionSo, rangeSo, errorSo,
1199 162 storres
                                               0, 0, None)
1200 154 storres
    elif degreeBoundSo is None:
1201 153 storres
        degreeRangeSo =  sollya_lib_guessdegree(functionSo, rangeSo, \
1202 162 storres
                                                errorSo, weightSo, 0, None)
1203 153 storres
    else:
1204 153 storres
        degreeRangeSo =  sollya_lib_guessdegree(functionSo, rangeSo, errorSo, \
1205 154 storres
                                                weightSo, degreeBoundSo, None)
1206 166 storres
    #print "...degree guess done."
1207 154 storres
    # Restore internal precision, if applicable.
1208 226 storres
    if sollyaPrecisionHasChanged:
1209 226 storres
        pobyso_set_prec_so_so(initialPrecSo)
1210 226 storres
        sollya_lib_clear_obj(initialPrecSo)
1211 154 storres
    degreeIntervalSa = pobyso_range_to_interval_so_sa(degreeRangeSo)
1212 154 storres
    sollya_lib_clear_obj(degreeRangeSo)
1213 154 storres
    # When ok, both bounds match.
1214 154 storres
    # When the degree bound is too low, the upper bound is the degree
1215 154 storres
    # for which the error can be honored.
1216 154 storres
    # When it really goes wrong, the upper bound is infinity.
1217 154 storres
    if degreeIntervalSa.lower() == degreeIntervalSa.upper():
1218 154 storres
        return int(degreeIntervalSa.lower())
1219 154 storres
    else:
1220 154 storres
        if degreeIntervalSa.upper().is_infinity():
1221 154 storres
            return None
1222 154 storres
        else:
1223 154 storres
            return int(degreeIntervalSa.upper())
1224 154 storres
    # End pobyso_guess_degree_so_sa
1225 153 storres
1226 215 storres
def pobyso_inf_so_so(intervalSo):
1227 215 storres
    """
1228 215 storres
    Very thin wrapper around sollya_lib_inf().
1229 215 storres
    """
1230 215 storres
    return sollya_lib_inf(intervalSo)
1231 215 storres
# End pobyso_inf_so_so.
1232 215 storres
1233 53 storres
def pobyso_infnorm_so_so(func, interval, file = None, intervalList = None):
1234 54 storres
    print "Do not use this function. User pobyso_supnorm_so_so instead."
1235 209 storres
    return None
1236 53 storres
1237 84 storres
def pobyso_interval_to_range_sa_so(intervalSa, precisionSa=None):
1238 84 storres
    if precisionSa is None:
1239 84 storres
        precisionSa = intervalSa.parent().precision()
1240 84 storres
    intervalSo = pobyso_bounds_to_range_sa_so(intervalSa.lower(),\
1241 84 storres
                                              intervalSa.upper(),\
1242 84 storres
                                              precisionSa)
1243 209 storres
    return intervalSo
1244 84 storres
# End pobyso_interval_to_range_sa_so
1245 84 storres
1246 155 storres
def pobyso_is_error_so_sa(objSo):
1247 155 storres
    """
1248 155 storres
    Thin wrapper around the sollya_lib_obj_is_error() function.
1249 155 storres
    """
1250 155 storres
    if sollya_lib_obj_is_error(objSo) != 0:
1251 155 storres
        return True
1252 155 storres
    else:
1253 155 storres
        return False
1254 155 storres
# End pobyso_is_error-so_sa
1255 155 storres
1256 155 storres
def pobyso_is_floating_point_number_sa_sa(numberSa):
1257 155 storres
    """
1258 209 storres
    Check whether a Sage number is floating point.
1259 209 storres
    Exception stuff added because numbers other than
1260 209 storres
    floating-point ones do not have the is_real() attribute.
1261 155 storres
    """
1262 209 storres
    try:
1263 209 storres
        return numberSa.is_real()
1264 209 storres
    except AttributeError:
1265 209 storres
        return False
1266 209 storres
# End pobyso_is_floating_piont_number_sa_sa
1267 155 storres
1268 226 storres
def pobyso_is_range_so_sa(rangeCandidateSo):
1269 226 storres
    """
1270 226 storres
    Thin wrapper over sollya_lib_is_range.
1271 226 storres
    """
1272 226 storres
    return sollya_lib_obj_is_range(rangeCandidateSo) != 0
1273 226 storres
1274 226 storres
# End pobyso_is_range_so_sa
1275 226 storres
1276 226 storres
1277 37 storres
def pobyso_lib_init():
1278 37 storres
    sollya_lib_init(None)
1279 116 storres
1280 116 storres
def pobyso_lib_close():
1281 116 storres
    sollya_lib_close(None)
1282 237 storres
1283 85 storres
def pobyso_name_free_variable(freeVariableNameSa):
1284 38 storres
    """ Legacy function. See pobyso_name_free_variable_sa_so. """
1285 85 storres
    pobyso_name_free_variable_sa_so(freeVariableNameSa)
1286 38 storres
1287 85 storres
def pobyso_name_free_variable_sa_so(freeVariableNameSa):
1288 83 storres
    """
1289 83 storres
    Set the free variable name in Sollya from a Sage string.
1290 83 storres
    """
1291 85 storres
    sollya_lib_name_free_variable(freeVariableNameSa)
1292 37 storres
1293 281 storres
def pobyso_obj_is_function_so_sa(objSo):
1294 281 storres
    """
1295 281 storres
    Check if an object is a function.
1296 281 storres
    """
1297 281 storres
    if sollya_lib_obj_is_function(objSo) != 0:
1298 281 storres
        return True
1299 281 storres
    else:
1300 281 storres
        return False
1301 281 storres
# End pobyso_obj_is_function_so_sa
1302 281 storres
1303 281 storres
def pobyso_obj_is_range_so_sa(objSo):
1304 281 storres
    """
1305 281 storres
    Check if an object is a function.
1306 281 storres
    """
1307 281 storres
    if sollya_lib_obj_is_range(objSo) != 0:
1308 281 storres
        return True
1309 281 storres
    else:
1310 281 storres
        return False
1311 281 storres
# End pobyso_obj_is_range_so_sa
1312 281 storres
1313 281 storres
def pobyso_obj_is_string_so_sa(objSo):
1314 281 storres
    """
1315 281 storres
    Check if an object is a function.
1316 281 storres
    """
1317 281 storres
    if sollya_lib_obj_is_string(objSo) != 0:
1318 281 storres
        return True
1319 281 storres
    else:
1320 281 storres
        return False
1321 281 storres
# End pobyso_obj_is_string_so_sa
1322 281 storres
1323 5 storres
def pobyso_parse_string(string):
1324 38 storres
    """ Legacy function. See pobyso_parse_string_sa_so. """
1325 209 storres
    return pobyso_parse_string_sa_so(string)
1326 38 storres
1327 38 storres
def pobyso_parse_string_sa_so(string):
1328 83 storres
    """
1329 155 storres
    Get the Sollya expression computed from a Sage string or
1330 155 storres
    a Sollya error object if parsing failed.
1331 83 storres
    """
1332 209 storres
    return sollya_lib_parse_string(string)
1333 5 storres
1334 200 storres
def pobyso_precision_so_sa(ctExpSo):
1335 209 storres
    """
1336 209 storres
    Computes the necessary precision to represent a number.
1337 209 storres
    If x is not zero, it can be uniquely written as x = m · 2e
1338 209 storres
    where m is an odd integer and e is an integer.
1339 209 storres
    precision(x) returns the number of bits necessary to write m
1340 209 storres
    in binary (i.e. ceil(log2(m))).
1341 209 storres
    """
1342 209 storres
    #TODO: take care of the special case: 0, @NaN@, @Inf@
1343 200 storres
    precisionSo = sollya_lib_precision(ctExpSo)
1344 200 storres
    precisionSa = pobyso_constant_from_int_so_sa(precisionSo)
1345 200 storres
    sollya_lib_clear_obj(precisionSo)
1346 200 storres
    return precisionSa
1347 200 storres
# End pobyso_precision_so_sa
1348 215 storres
1349 217 storres
def pobyso_polynomial_coefficients_progressive_round_so_so(polySo,
1350 217 storres
                                                           funcSo,
1351 217 storres
                                                           icSo,
1352 217 storres
                                                           intervalSo,
1353 217 storres
                                                           itpSo,
1354 217 storres
                                                           ftpSo,
1355 217 storres
                                                           maxPrecSo,
1356 219 storres
                                                           maxErrSo,
1357 219 storres
                                                           debug=False):
1358 219 storres
    if debug:
1359 219 storres
        print "Input arguments:"
1360 219 storres
        pobyso_autoprint(polySo)
1361 219 storres
        pobyso_autoprint(funcSo)
1362 219 storres
        pobyso_autoprint(icSo)
1363 219 storres
        pobyso_autoprint(intervalSo)
1364 219 storres
        pobyso_autoprint(itpSo)
1365 219 storres
        pobyso_autoprint(ftpSo)
1366 219 storres
        pobyso_autoprint(maxPrecSo)
1367 219 storres
        pobyso_autoprint(maxErrSo)
1368 219 storres
        print "________________"
1369 200 storres
1370 217 storres
    ## Higher order function see:
1371 217 storres
    #  http://effbot.org/pyfaq/how-do-you-make-a-higher-order-function-in-python.htm
1372 217 storres
    def precision_decay_ratio_function(degreeSa):
1373 217 storres
        def outer(x):
1374 217 storres
            def inner(x):
1375 217 storres
                we = 3/8
1376 217 storres
                wq = 2/8
1377 217 storres
                a  = 2.2
1378 217 storres
                b  = 2
1379 217 storres
                return we*(exp(x/a)-1) +  wq*((b*x)**2) + (1-we-wq)*x
1380 217 storres
            return  inner(x)/inner(degreeSa)
1381 217 storres
        return outer
1382 217 storres
1383 217 storres
    #
1384 217 storres
    degreeSa        = pobyso_polynomial_degree_so_sa(polySo)
1385 217 storres
    ratio           = precision_decay_ratio_function(degreeSa)
1386 217 storres
    itpSa           = pobyso_constant_from_int_so_sa(itpSo)
1387 217 storres
    ftpSa           = pobyso_constant_from_int_so_sa(ftpSo)
1388 217 storres
    maxPrecSa       = pobyso_constant_from_int_so_sa(maxPrecSo)
1389 217 storres
    maxErrSa        = pobyso_get_constant_as_rn_so_sa(maxErrSo)
1390 219 storres
    if debug:
1391 219 storres
        print "degreeSa:", degreeSa
1392 219 storres
        print "ratio:", ratio
1393 219 storres
        print "itpsSa:", itpSa
1394 219 storres
        print "ftpSa:", ftpSa
1395 219 storres
        print "maxPrecSa:", maxPrecSa
1396 219 storres
        print "maxErrSa:", maxErrSa
1397 217 storres
    lastResPolySo   = None
1398 218 storres
    lastInfNormSo   = None
1399 219 storres
    #print "About to enter the while loop..."
1400 217 storres
    while True:
1401 218 storres
        resPolySo   = pobyso_constant_0_sa_so()
1402 217 storres
        pDeltaSa    = ftpSa - itpSa
1403 217 storres
        for indexSa in reversed(xrange(0,degreeSa+1)):
1404 218 storres
            #print "Index:", indexSa
1405 217 storres
            indexSo = pobyso_constant_from_int_sa_so(indexSa)
1406 217 storres
            #pobyso_autoprint(indexSo)
1407 217 storres
            #print ratio(indexSa)
1408 217 storres
            ctpSa = floor(ftpSa - (pDeltaSa * ratio(indexSa)))
1409 217 storres
            ctpSo = pobyso_constant_from_int_sa_so(ctpSa)
1410 219 storres
            if debug:
1411 219 storres
                print "Index:", indexSa, " - Target precision:",
1412 219 storres
                pobyso_autoprint(ctpSo)
1413 217 storres
            cmonSo  = \
1414 217 storres
                sollya_lib_build_function_mul(sollya_lib_coeff(polySo, indexSo),
1415 217 storres
                                      sollya_lib_build_function_pow( \
1416 217 storres
                                          sollya_lib_build_function_free_variable(), \
1417 217 storres
                                          indexSo))
1418 217 storres
            #pobyso_autoprint(cmonSo)
1419 217 storres
            cmonrSo = pobyso_round_coefficients_single_so_so(cmonSo, ctpSo)
1420 217 storres
            sollya_lib_clear_obj(cmonSo)
1421 217 storres
            #pobyso_autoprint(cmonrSo)
1422 217 storres
            resPolySo = sollya_lib_build_function_add(resPolySo,
1423 217 storres
                                                      cmonrSo)
1424 218 storres
            #pobyso_autoprint(resPolySo)
1425 217 storres
        # End for index
1426 217 storres
        freeVarSo     = sollya_lib_build_function_free_variable()
1427 217 storres
        changeVarSo   = sollya_lib_sub(freeVarSo, icSo)
1428 217 storres
        resPolyCvSo   = sollya_lib_evaluate(resPolySo, changeVarSo)
1429 218 storres
        errFuncSo = sollya_lib_build_function_sub(sollya_lib_copy_obj(funcSo),
1430 218 storres
                                                  resPolyCvSo)
1431 218 storres
        infNormSo = sollya_lib_dirtyinfnorm(errFuncSo, intervalSo)
1432 217 storres
        cerrSa    = pobyso_get_constant_as_rn_so_sa(infNormSo)
1433 219 storres
        if debug:
1434 219 storres
            print "Infnorm (Sollya):",
1435 219 storres
            pobyso_autoprint(infNormSo)
1436 218 storres
        sollya_lib_clear_obj(errFuncSo)
1437 218 storres
        #print "Infnorm  (Sage):", cerrSa
1438 217 storres
        if (cerrSa > maxErrSa):
1439 219 storres
            if debug:
1440 219 storres
                print "Error is too large."
1441 218 storres
            if lastResPolySo is None:
1442 219 storres
                if debug:
1443 219 storres
                    print "Enlarging prec."
1444 217 storres
                ntpSa = floor(ftpSa + ftpSa/50)
1445 217 storres
                ## Can't enlarge (numerical)
1446 217 storres
                if ntpSa == ftpSa:
1447 217 storres
                    sollya_lib_clear_obj(resPolySo)
1448 217 storres
                    return None
1449 217 storres
                ## Can't enlarge (not enough precision left)
1450 217 storres
                if ntpSa > maxPrecSa:
1451 217 storres
                    sollya_lib_clear_obj(resPolySo)
1452 217 storres
                    return None
1453 217 storres
                ftpSa = ntpSa
1454 217 storres
                continue
1455 217 storres
            ## One enlargement took place.
1456 217 storres
            else:
1457 219 storres
                if debug:
1458 219 storres
                    print "Exit with the last before last polynomial."
1459 222 storres
                    print "Precision of highest degree monomial:", itpSa
1460 222 storres
                    print "Precision of constant term          :", ftpSa
1461 217 storres
                sollya_lib_clear_obj(resPolySo)
1462 218 storres
                sollya_lib_clear_obj(infNormSo)
1463 218 storres
                return (lastResPolySo, lastInfNormSo)
1464 218 storres
        # cerrSa <= maxErrSa: scrap more bits, possibly.
1465 217 storres
        else:
1466 219 storres
            if debug:
1467 219 storres
                print "Error is too small"
1468 219 storres
            if cerrSa <= (maxErrSa/2):
1469 219 storres
                if debug:
1470 219 storres
                    print "Shrinking prec."
1471 218 storres
                ntpSa = floor(ftpSa - ftpSa/50)
1472 218 storres
                ## Can't shrink (numerical)
1473 218 storres
                if ntpSa == ftpSa:
1474 218 storres
                    if not lastResPolySo is None:
1475 218 storres
                        sollya_lib_clear_obj(lastResPolySo)
1476 218 storres
                    if not lastInfNormSo is None:
1477 218 storres
                        sollya_lib_clear_obj(lastInfNormSo)
1478 222 storres
                    if debug:
1479 222 storres
                        print "Exit because can't shrink anymore (numerically)."
1480 222 storres
                        print "Precision of highest degree monomial:", itpSa
1481 222 storres
                        print "Precision of constant term          :", ftpSa
1482 218 storres
                    return (resPolySo, infNormSo)
1483 218 storres
                ## Can't shrink (not enough precision left)
1484 218 storres
                if ntpSa <= itpSa:
1485 218 storres
                    if not lastResPolySo is None:
1486 218 storres
                        sollya_lib_clear_obj(lastResPolySo)
1487 218 storres
                    if not lastInfNormSo is None:
1488 218 storres
                        sollya_lib_clear_obj(lastInfNormSo)
1489 222 storres
                        print "Exit because can't shrink anymore (no bits left)."
1490 222 storres
                        print "Precision of highest degree monomial:", itpSa
1491 222 storres
                        print "Precision of constant term          :", ftpSa
1492 218 storres
                    return (resPolySo, infNormSo)
1493 218 storres
                ftpSa = ntpSa
1494 217 storres
                if not lastResPolySo is None:
1495 217 storres
                    sollya_lib_clear_obj(lastResPolySo)
1496 218 storres
                if not lastInfNormSo is None:
1497 218 storres
                    sollya_lib_clear_obj(lastInfNormSo)
1498 218 storres
                lastResPolySo = resPolySo
1499 218 storres
                lastInfNormSo = infNormSo
1500 218 storres
                continue
1501 218 storres
            else: # Error is not that small, just return
1502 217 storres
                if not lastResPolySo is None:
1503 217 storres
                    sollya_lib_clear_obj(lastResPolySo)
1504 218 storres
                if not lastInfNormSo is None:
1505 218 storres
                    sollya_lib_clear_obj(lastInfNormSo)
1506 222 storres
                if debug:
1507 222 storres
                    print "Exit normally."
1508 222 storres
                    print "Precision of highest degree monomial:", itpSa
1509 222 storres
                    print "Precision of constant term          :", ftpSa
1510 218 storres
                return (resPolySo, infNormSo)
1511 217 storres
    # End wile True
1512 215 storres
    return None
1513 217 storres
# End pobyso_polynomial_coefficients_progressive_truncate_so_so.
1514 217 storres
1515 217 storres
def pobyso_polynomial_degree_so_sa(polySo):
1516 217 storres
    """
1517 217 storres
    Return the degree of a Sollya polynomial as a Sage int.
1518 217 storres
    """
1519 217 storres
    degreeSo = sollya_lib_degree(polySo)
1520 217 storres
    return pobyso_constant_from_int_so_sa(degreeSo)
1521 217 storres
# End pobyso_polynomial_degree_so_sa
1522 217 storres
1523 217 storres
def pobyso_polynomial_degree_so_so(polySo):
1524 217 storres
    """
1525 217 storres
    Thin wrapper around lib_sollya_degree().
1526 217 storres
    """
1527 217 storres
    return sollya_lib_degree(polySo)
1528 217 storres
# End pobyso_polynomial_degree_so_so
1529 217 storres
1530 5 storres
def pobyso_range(rnLowerBound, rnUpperBound):
1531 38 storres
    """ Legacy function. See pobyso_range_sa_so. """
1532 209 storres
    return pobyso_range_sa_so(rnLowerBound, rnUpperBound)
1533 38 storres
1534 226 storres
def pobyso_range_from_bounds_sa_so(rnLowerBound, rnUpperBound, precSa = None):
1535 226 storres
    """
1536 226 storres
    Create a Sollya range from 2 Sage real numbers as bounds
1537 226 storres
    """
1538 226 storres
    # TODO check precision stuff.
1539 226 storres
    sollyaPrecChanged = False
1540 226 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = \
1541 226 storres
        pobyso_get_prec_so_so_sa()
1542 226 storres
    if precSa is None:
1543 226 storres
        precSa = max(rnLowerBound.parent().prec(), rnUpperBound.parent().prec())
1544 226 storres
    if precSa > initialSollyaPrecSa:
1545 226 storres
        if precSa <= 2:
1546 226 storres
            print inspect.stack()[0][3], ": precision change <= 2 requested."
1547 226 storres
        pobyso_set_prec_sa_so(precSa)
1548 226 storres
        sollyaPrecChanged = True
1549 226 storres
    rangeSo = sollya_lib_range_from_bounds(get_rn_value(rnLowerBound),
1550 226 storres
                                           get_rn_value(rnUpperBound))
1551 226 storres
    if sollyaPrecChanged:
1552 226 storres
        pobyso_set_prec_so_so(initialSollyaPrecSo)
1553 234 storres
        sollya_lib_clear_obj(initialSollyaPrecSo)
1554 226 storres
    return rangeSo
1555 226 storres
# End pobyso_range_from_bounds_sa_so
1556 5 storres
1557 261 storres
def pobyso_range_list_so_sa(listSo):
1558 261 storres
    """
1559 261 storres
    Return a Sollya list of ranges as a Sage list of
1560 261 storres
    floating-point intervals.
1561 261 storres
    """
1562 261 storres
    listSa   = []
1563 261 storres
    ## The function returns none if the list is empty or an error has happened.
1564 261 storres
    retVal = pobyso_get_list_elements_so_so(listSo)
1565 261 storres
    if retVal is None:
1566 261 storres
        return listSa
1567 261 storres
    ## Just in case the interface is changed and an empty list is returned
1568 261 storres
    #  instead of None.
1569 261 storres
    elif len(retVal) == 0:
1570 261 storres
        return listSa
1571 261 storres
    else:
1572 261 storres
        ## Remember pobyso_get_list_elements_so_so returns more information
1573 261 storres
        #  than just the elements of the list (# elements, is_elliptic)
1574 261 storres
        listSaSo, numElements, isEndElliptic = retVal
1575 261 storres
    ## Return an empty list.
1576 261 storres
    if numElements == 0:
1577 261 storres
        return listSa
1578 261 storres
    ## Search first for the maximum precision of the elements
1579 261 storres
    maxPrecSa = 0
1580 261 storres
    for rangeSo in listSaSo:
1581 261 storres
        #pobyso_autoprint(floatSo)
1582 261 storres
        curPrecSa =  pobyso_get_prec_of_range_so_sa(rangeSo)
1583 261 storres
        if curPrecSa > maxPrecSa:
1584 261 storres
            maxPrecSa = curPrecSa
1585 261 storres
    ##
1586 261 storres
    intervalField = RealIntervalField(maxPrecSa)
1587 261 storres
    ##
1588 261 storres
    for rangeSo in listSaSo:
1589 261 storres
        listSa.append(pobyso_range_to_interval_so_sa(rangeSo, intervalField))
1590 261 storres
    return listSa
1591 261 storres
# End pobyso_range_list_so_sa
1592 261 storres
1593 226 storres
def pobyso_range_max_abs_so_so(rangeSo):
1594 226 storres
    """
1595 226 storres
    Return, as Sollya constant, the maximum absolute value of a Sollay range.
1596 226 storres
    """
1597 226 storres
    lowerBoundSo = sollya_lib_inf(rangeSo)
1598 226 storres
    upperBoundSo = sollya_lib_sup(rangeSo)
1599 226 storres
    #
1600 226 storres
    lowerBoundSo = sollya_lib_build_function_abs(lowerBoundSo)
1601 226 storres
    upperBoundSo = sollya_lib_build_function_abs(upperBoundSo)
1602 226 storres
    #pobyso_autoprint(lowerBoundSo)
1603 226 storres
    #pobyso_autoprint(upperBoundSo)
1604 226 storres
    #
1605 226 storres
    maxAbsSo = sollya_lib_max(lowerBoundSo, upperBoundSo, None)
1606 226 storres
    #sollya_lib_clear_obj(lowerBoundSo)
1607 226 storres
    #sollya_lib_clear_obj(upperBoundSo)
1608 226 storres
    return maxAbsSo
1609 226 storres
# End pobyso_range_max_abs_so_so
1610 226 storres
1611 85 storres
def pobyso_range_to_interval_so_sa(rangeSo, realIntervalFieldSa = None):
1612 83 storres
    """
1613 83 storres
    Get a Sage interval from a Sollya range.
1614 83 storres
    If no realIntervalField is given as a parameter, the Sage interval
1615 83 storres
    precision is that of the Sollya range.
1616 85 storres
    Otherwise, the precision is that of the realIntervalField. In this case
1617 85 storres
    rounding may happen.
1618 83 storres
    """
1619 85 storres
    if realIntervalFieldSa is None:
1620 56 storres
        precSa = pobyso_get_prec_of_range_so_sa(rangeSo)
1621 85 storres
        realIntervalFieldSa = RealIntervalField(precSa)
1622 56 storres
    intervalSa = \
1623 85 storres
        pobyso_get_interval_from_range_so_sa(rangeSo, realIntervalFieldSa)
1624 209 storres
    return intervalSa
1625 209 storres
# End pobyso_range_to_interval_so_sa
1626 240 storres
#
1627 240 storres
def pobyso_relative_so_so():
1628 240 storres
    """
1629 240 storres
    Very thin wrapper around the sollya_lib_relative function.
1630 240 storres
    """
1631 240 storres
    return sollya_lib_relative()
1632 240 storres
# End pobyso_relative_so_so
1633 240 storres
#
1634 209 storres
def pobyso_rat_poly_sa_so(polySa, precSa = None):
1635 209 storres
    """
1636 209 storres
    Create a Sollya polynomial from a Sage rational polynomial.
1637 272 storres
    We first convert the rational polynomial into a floating-point
1638 272 storres
    polynomial.
1639 209 storres
    """
1640 209 storres
    ## TODO: filter arguments.
1641 209 storres
    ## Precision. If no precision is given, use the current precision
1642 209 storres
    #  of Sollya.
1643 209 storres
    if precSa is None:
1644 209 storres
        precSa =  pobyso_get_prec_so_sa()
1645 209 storres
    #print "Precision:",  precSa
1646 209 storres
    RRR = RealField(precSa)
1647 209 storres
    ## Create a Sage polynomial in the "right" precision.
1648 209 storres
    P_RRR = RRR[polySa.variables()[0]]
1649 209 storres
    polyFloatSa = P_RRR(polySa)
1650 213 storres
    ## Make sure no precision is provided: pobyso_float_poly_sa_so will
1651 272 storres
    #  recover it all by itself and will not make any extra conversion.
1652 209 storres
    return pobyso_float_poly_sa_so(polyFloatSa)
1653 209 storres
1654 209 storres
# End pobyso_rat_poly_sa_so
1655 209 storres
1656 52 storres
def pobyso_remez_canonical_sa_sa(func, \
1657 52 storres
                                 degree, \
1658 52 storres
                                 lowerBound, \
1659 52 storres
                                 upperBound, \
1660 52 storres
                                 weight = None, \
1661 52 storres
                                 quality = None):
1662 52 storres
    """
1663 52 storres
    All arguments are Sage/Python.
1664 52 storres
    The functions (func and weight) must be passed as expressions or strings.
1665 52 storres
    Otherwise the function fails.
1666 83 storres
    The return value is a Sage polynomial.
1667 52 storres
    """
1668 83 storres
    var('zorglub')    # Dummy variable name for type check only. Type of
1669 83 storres
    # zorglub is "symbolic expression".
1670 52 storres
    polySo = pobyso_remez_canonical_sa_so(func, \
1671 52 storres
                                 degree, \
1672 52 storres
                                 lowerBound, \
1673 52 storres
                                 upperBound, \
1674 85 storres
                                 weight, \
1675 85 storres
                                 quality)
1676 83 storres
    # String test
1677 52 storres
    if parent(func) == parent("string"):
1678 52 storres
        functionSa = eval(func)
1679 52 storres
    # Expression test.
1680 52 storres
    elif type(func) == type(zorglub):
1681 52 storres
        functionSa = func
1682 83 storres
    else:
1683 83 storres
        return None
1684 83 storres
    #
1685 52 storres
    maxPrecision = 0
1686 52 storres
    if polySo is None:
1687 52 storres
        return(None)
1688 52 storres
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
1689 85 storres
    RRRRSa = RealField(maxPrecision)
1690 85 storres
    polynomialRingSa = RRRRSa[functionSa.variables()[0]]
1691 85 storres
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, RRRRSa)
1692 85 storres
    polySa = polynomial(expSa, polynomialRingSa)
1693 83 storres
    sollya_lib_clear_obj(polySo)
1694 52 storres
    return(polySa)
1695 85 storres
# End pobyso_remez_canonical_sa_sa
1696 52 storres
1697 38 storres
def pobyso_remez_canonical(func, \
1698 5 storres
                           degree, \
1699 5 storres
                           lowerBound, \
1700 5 storres
                           upperBound, \
1701 38 storres
                           weight = "1", \
1702 5 storres
                           quality = None):
1703 38 storres
    """ Legacy function. See pobyso_remez_canonical_sa_so. """
1704 51 storres
    return(pobyso_remez_canonical_sa_so(func, \
1705 51 storres
                                        degree, \
1706 51 storres
                                        lowerBound, \
1707 51 storres
                                        upperBound, \
1708 51 storres
                                        weight, \
1709 51 storres
                                        quality))
1710 200 storres
# End pobyso_remez_canonical.
1711 200 storres
1712 38 storres
def pobyso_remez_canonical_sa_so(func, \
1713 38 storres
                                 degree, \
1714 38 storres
                                 lowerBound, \
1715 38 storres
                                 upperBound, \
1716 52 storres
                                 weight = None, \
1717 38 storres
                                 quality = None):
1718 38 storres
    """
1719 38 storres
    All arguments are Sage/Python.
1720 51 storres
    The functions (func and weight) must be passed as expressions or strings.
1721 51 storres
    Otherwise the function fails.
1722 38 storres
    The return value is a pointer to a Sollya function.
1723 234 storres
    lowerBound and upperBound mus be reals.
1724 38 storres
    """
1725 83 storres
    var('zorglub')    # Dummy variable name for type check only. Type of
1726 83 storres
    # zorglub is "symbolic expression".
1727 85 storres
    currentVariableNameSa = None
1728 52 storres
    # The func argument can be of different types (string,
1729 52 storres
    # symbolic expression...)
1730 38 storres
    if parent(func) == parent("string"):
1731 234 storres
        localFuncSa = sage_eval(func,globals())
1732 85 storres
        if len(localFuncSa.variables()) > 0:
1733 85 storres
            currentVariableNameSa = localFuncSa.variables()[0]
1734 85 storres
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1735 159 storres
            functionSo = \
1736 159 storres
              sollya_lib_parse_string(localFuncSa._assume_str().replace('_SAGE_VAR_', ''))
1737 51 storres
    # Expression test.
1738 52 storres
    elif type(func) == type(zorglub):
1739 52 storres
        # Until we are able to translate Sage expressions into Sollya
1740 52 storres
        # expressions : parse the string version.
1741 85 storres
        if len(func.variables()) > 0:
1742 85 storres
            currentVariableNameSa = func.variables()[0]
1743 85 storres
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1744 159 storres
            functionSo = \
1745 159 storres
              sollya_lib_parse_string(func._assume_str().replace('_SAGE_VAR_', ''))
1746 38 storres
    else:
1747 38 storres
        return(None)
1748 85 storres
    if weight is None: # No weight given -> 1.
1749 52 storres
        weightSo = pobyso_constant_1_sa_so()
1750 85 storres
    elif parent(weight) == parent("string"): # Weight given as string: parse it.
1751 51 storres
        weightSo = sollya_lib_parse_string(func)
1752 85 storres
    elif type(weight) == type(zorglub): # Weight given as symbolice expression.
1753 159 storres
        functionSo = \
1754 159 storres
          sollya_lib_parse_string_sa_so(weight._assume_str().replace('_SAGE_VAR_', ''))
1755 51 storres
    else:
1756 51 storres
        return(None)
1757 5 storres
    degreeSo = pobyso_constant_from_int(degree)
1758 85 storres
    rangeSo = pobyso_bounds_to_range_sa_so(lowerBound, upperBound)
1759 38 storres
    if not quality is None:
1760 38 storres
        qualitySo= pobyso_constant_sa_so(quality)
1761 52 storres
    else:
1762 52 storres
        qualitySo = None
1763 83 storres
1764 83 storres
    remezPolySo = sollya_lib_remez(functionSo, \
1765 83 storres
                                   degreeSo, \
1766 83 storres
                                   rangeSo, \
1767 83 storres
                                   weightSo, \
1768 83 storres
                                   qualitySo, \
1769 83 storres
                                   None)
1770 83 storres
    sollya_lib_clear_obj(functionSo)
1771 83 storres
    sollya_lib_clear_obj(degreeSo)
1772 83 storres
    sollya_lib_clear_obj(rangeSo)
1773 83 storres
    sollya_lib_clear_obj(weightSo)
1774 83 storres
    if not qualitySo is None:
1775 85 storres
        sollya_lib_clear_obj(qualitySo)
1776 83 storres
    return(remezPolySo)
1777 83 storres
# End pobyso_remez_canonical_sa_so
1778 83 storres
1779 38 storres
def pobyso_remez_canonical_so_so(funcSo, \
1780 38 storres
                                 degreeSo, \
1781 38 storres
                                 rangeSo, \
1782 52 storres
                                 weightSo = pobyso_constant_1_sa_so(),\
1783 38 storres
                                 qualitySo = None):
1784 38 storres
    """
1785 38 storres
    All arguments are pointers to Sollya objects.
1786 38 storres
    The return value is a pointer to a Sollya function.
1787 38 storres
    """
1788 38 storres
    if not sollya_lib_obj_is_function(funcSo):
1789 38 storres
        return(None)
1790 38 storres
    return(sollya_lib_remez(funcSo, degreeSo, rangeSo, weightSo, qualitySo, None))
1791 200 storres
# End pobyso_remez_canonical_so_so.
1792 200 storres
1793 237 storres
def pobyso_remez_exponents_list_sa_so(func,     \
1794 237 storres
                                 exponentsList, \
1795 237 storres
                                 lowerBound,    \
1796 237 storres
                                 upperBound,    \
1797 237 storres
                                 weight = None, \
1798 237 storres
                                 quality = None):
1799 237 storres
    """
1800 237 storres
    All arguments are Sage/Python.
1801 237 storres
    The functions (func and weight) must be passed as expressions or strings.
1802 237 storres
    Otherwise the function fails.
1803 237 storres
    The return value is a pointer to a Sollya function.
1804 237 storres
    lowerBound and upperBound mus be reals.
1805 237 storres
    """
1806 237 storres
    var('zorglub')    # Dummy variable name for type check only. Type of
1807 237 storres
    # zorglub is "symbolic expression".
1808 237 storres
    currentVariableNameSa = None
1809 237 storres
    # The func argument can be of different types (string,
1810 237 storres
    # symbolic expression...)
1811 237 storres
    if parent(func) == parent("string"):
1812 237 storres
        localFuncSa = sage_eval(func,globals())
1813 237 storres
        if len(localFuncSa.variables()) > 0:
1814 237 storres
            currentVariableNameSa = localFuncSa.variables()[0]
1815 237 storres
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1816 237 storres
            functionSo = \
1817 237 storres
              sollya_lib_parse_string(localFuncSa._assume_str().replace('_SAGE_VAR_', ''))
1818 237 storres
    # Expression test.
1819 237 storres
    elif type(func) == type(zorglub):
1820 237 storres
        # Until we are able to translate Sage expressions into Sollya
1821 237 storres
        # expressions : parse the string version.
1822 237 storres
        if len(func.variables()) > 0:
1823 237 storres
            currentVariableNameSa = func.variables()[0]
1824 237 storres
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1825 237 storres
            functionSo = \
1826 237 storres
              sollya_lib_parse_string(func._assume_str().replace('_SAGE_VAR_', ''))
1827 237 storres
    else:
1828 237 storres
        return(None)
1829 237 storres
    ## Deal with the weight, much in the same way as with the function.
1830 237 storres
    if weight is None: # No weight given -> 1.
1831 237 storres
        weightSo = pobyso_constant_1_sa_so()
1832 237 storres
    elif parent(weight) == parent("string"): # Weight given as string: parse it.
1833 237 storres
        weightSo = sollya_lib_parse_string(func)
1834 237 storres
    elif type(weight) == type(zorglub): # Weight given as symbolice expression.
1835 237 storres
        functionSo = \
1836 237 storres
          sollya_lib_parse_string(weight._assume_str().replace('_SAGE_VAR_', '',100))
1837 237 storres
    else:
1838 237 storres
        return(None)
1839 237 storres
    rangeSo = pobyso_bounds_to_range_sa_so(lowerBound, upperBound)
1840 237 storres
    if not quality is None:
1841 237 storres
        qualitySo= pobyso_constant_sa_so(quality)
1842 237 storres
    else:
1843 237 storres
        qualitySo = None
1844 237 storres
    #
1845 237 storres
    ## Tranform the Sage list of exponents into a Sollya list.
1846 237 storres
    exponentsListSo = pobyso_build_list_of_ints_sa_so(*exponentsList)
1847 278 storres
    remezPolySo = sollya_lib_remez(functionSo,      \
1848 237 storres
                                   exponentsListSo, \
1849 278 storres
                                   rangeSo,         \
1850 278 storres
                                   weightSo,        \
1851 278 storres
                                   qualitySo,       \
1852 237 storres
                                   None)
1853 237 storres
    sollya_lib_clear_obj(functionSo)
1854 237 storres
    sollya_lib_clear_obj(exponentsListSo)
1855 237 storres
    sollya_lib_clear_obj(rangeSo)
1856 237 storres
    sollya_lib_clear_obj(weightSo)
1857 237 storres
    if not qualitySo is None:
1858 237 storres
        sollya_lib_clear_obj(qualitySo)
1859 237 storres
    return(remezPolySo)
1860 237 storres
# End pobyso_remez_exponentsList_sa_so
1861 240 storres
#
1862 240 storres
def pobyso_round_coefficients_so_so(polySo, truncFormatListSo):
1863 240 storres
    """
1864 240 storres
    A wrapper around the "classical" sollya_lib_roundcoefficients: a Sollya
1865 240 storres
    polynomial and a Sollya list are given as arguments.
1866 240 storres
    """
1867 240 storres
    return sollya_lib_roundcoefficients(polySo, truncFormatListSo)
1868 237 storres
1869 224 storres
def pobyso_round_coefficients_progressive_so_so(polySo,
1870 224 storres
                                                funcSo,
1871 224 storres
                                                precSo,
1872 224 storres
                                                intervalSo,
1873 224 storres
                                                icSo,
1874 224 storres
                                                currentApproxErrorSo,
1875 224 storres
                                                approxAccurSo,
1876 224 storres
                                                debug=False):
1877 272 storres
    """
1878 272 storres
    From an input approximation polynomial, compute an output one with
1879 272 storres
    smaller coefficients and yet yields a sufficient approximation accuracy.
1880 272 storres
    """
1881 223 storres
    if debug:
1882 223 storres
        print "Input arguments:"
1883 228 storres
        print "Polynomial: ", ; pobyso_autoprint(polySo)
1884 228 storres
        print "Function: ", ; pobyso_autoprint(funcSo)
1885 228 storres
        print "Internal precision: ", ; pobyso_autoprint(precSo)
1886 228 storres
        print "Interval: ", ; pobyso_autoprint(intervalSo)
1887 228 storres
        print "Current approximation error: ", ; pobyso_autoprint(currentApproxErrorSo)
1888 228 storres
        print "Requested approxiation error: ", ; pobyso_autoprint(approxAccurSo)
1889 223 storres
        print "________________"
1890 223 storres
    approxAccurSa        = pobyso_get_constant_as_rn_so_sa(approxAccurSo)
1891 223 storres
    currentApproxErrorSa = pobyso_get_constant_as_rn_so_sa(currentApproxErrorSo)
1892 223 storres
    ## If the current approximation error is too close to the target, there is
1893 223 storres
    #  no possible gain.
1894 223 storres
    if currentApproxErrorSa >= approxAccurSa / 2:
1895 232 storres
        #### Do not return the initial argument but copies: caller may free
1896 272 storres
        #    the former as inutile after call.
1897 232 storres
        return (sollya_lib_copy_obj(polySo),
1898 232 storres
                sollya_lib_copy_obj(currentApproxErrorSo))
1899 278 storres
    #
1900 278 storres
    ## Try to round the coefficients.
1901 223 storres
    degreeSa             = pobyso_polynomial_degree_so_sa(polySo)
1902 223 storres
    intervalSa           = pobyso_range_to_interval_so_sa(intervalSo)
1903 223 storres
1904 223 storres
    if debug:
1905 228 storres
        print "degreeSa              :", degreeSa
1906 228 storres
        print "intervalSa            :", intervalSa.str(style='brackets')
1907 223 storres
        print "currentApproxErrorSa  :", currentApproxErrorSa
1908 228 storres
        print "approxAccurSa         :", approxAccurSa
1909 223 storres
    radiusSa = intervalSa.absolute_diameter() / 2
1910 223 storres
    if debug:
1911 224 storres
        print "log2(radius):", RR(radiusSa).log2()
1912 224 storres
    iterIndex = 0
1913 272 storres
    ## Build the "shaved" polynomial.
1914 224 storres
    while True:
1915 272 storres
        ### Start with a 0 value expression.
1916 224 storres
        resPolySo = pobyso_constant_0_sa_so()
1917 224 storres
        roundedPolyApproxAccurSa = approxAccurSa / 2
1918 224 storres
        currentRadiusPowerSa = 1
1919 224 storres
        for degree in xrange(0,degreeSa + 1):
1920 224 storres
            #### At round 0, use the agressive formula. At round 1, run the
1921 224 storres
            #    proved formula.
1922 224 storres
            if iterIndex == 0:
1923 224 storres
                roundingPowerSa = \
1924 224 storres
                    floor(((currentRadiusPowerSa/roundedPolyApproxAccurSa)*(degree+1)).log2())
1925 224 storres
            else:
1926 224 storres
                roundingPowerSa = \
1927 224 storres
                    floor(((currentRadiusPowerSa/roundedPolyApproxAccurSa)*(degreeSa+1)).log2())
1928 272 storres
            ## Under extreme conditions the above formulas can evaluate under 2,
1929 272 storres
            #   which is the minimal precision of an MPFR number.
1930 228 storres
            if roundingPowerSa < 2:
1931 228 storres
                roundingPowerSa = 2
1932 224 storres
            if debug:
1933 224 storres
                print "roundedPolyApproxAccurSa", roundedPolyApproxAccurSa
1934 224 storres
                print "currentRadiusPowerSa", currentRadiusPowerSa
1935 224 storres
                print "Current rounding exponent:", roundingPowerSa
1936 224 storres
            currentRadiusPowerSa *= radiusSa
1937 224 storres
            index1So = pobyso_constant_from_int_sa_so(degree)
1938 224 storres
            index2So = pobyso_constant_from_int_sa_so(degree)
1939 224 storres
            ### Create a monomial with:
1940 224 storres
            #   - the coefficient in the initial monomial at the current degrree;
1941 224 storres
            #   - the current exponent;
1942 224 storres
            #   - the free variable.
1943 224 storres
            cmonSo  = \
1944 224 storres
                sollya_lib_build_function_mul(sollya_lib_coeff(polySo, index1So),
1945 224 storres
                                              sollya_lib_build_function_pow( \
1946 224 storres
                                                sollya_lib_build_function_free_variable(), \
1947 224 storres
                                                index2So))
1948 224 storres
            roundingPowerSo = pobyso_constant_from_int_sa_so(roundingPowerSa)
1949 224 storres
            cmonrSo = pobyso_round_coefficients_single_so_so(cmonSo, roundingPowerSo)
1950 224 storres
            sollya_lib_clear_obj(cmonSo)
1951 224 storres
            ### Add to the result polynomial.
1952 224 storres
            resPolySo = sollya_lib_build_function_add(resPolySo,
1953 224 storres
                                                      cmonrSo)
1954 224 storres
        # End for.
1955 224 storres
        ### Check the new polynomial.
1956 224 storres
        freeVarSo     = sollya_lib_build_function_free_variable()
1957 224 storres
        changeVarSo   = sollya_lib_sub(freeVarSo, icSo)
1958 224 storres
        resPolyCvSo   = sollya_lib_evaluate(resPolySo, changeVarSo)
1959 224 storres
        errFuncSo     = sollya_lib_build_function_sub(sollya_lib_copy_obj(funcSo),
1960 224 storres
                                                      resPolyCvSo)
1961 224 storres
        infNormSo = sollya_lib_dirtyinfnorm(errFuncSo, intervalSo)
1962 224 storres
        ### This also clears resPolyCvSo.
1963 224 storres
        sollya_lib_clear_obj(errFuncSo)
1964 224 storres
        cerrSa    = pobyso_get_constant_as_rn_so_sa(infNormSo)
1965 223 storres
        if debug:
1966 224 storres
            print "Error of the new polynomial:", cerrSa
1967 224 storres
        ### If at round 1, return the initial polynomial error. This should
1968 224 storres
        #   never happen since the rounding algorithm is proved. But some
1969 224 storres
        #   circumstances may break it (e.g. internal precision of tools).
1970 224 storres
        if cerrSa > approxAccurSa:
1971 278 storres
            if iterIndex == 0: # Round 0 is agressive rounding, got round 1 (proved rounding)
1972 224 storres
                sollya_lib_clear_obj(resPolySo)
1973 224 storres
                sollya_lib_clear_obj(infNormSo)
1974 278 storres
                iterIndex += 1
1975 278 storres
                continue
1976 278 storres
            else: # Round 1 and beyond : just return the oroginal polynomial.
1977 278 storres
                sollya_lib_clear_obj(resPolySo)
1978 278 storres
                sollya_lib_clear_obj(infNormSo)
1979 232 storres
                #### Do not return the arguments but copies: the caller may free
1980 232 storres
                #    free the former as inutile after call.
1981 232 storres
                return (sollya_lib_copy_obj(polySo),
1982 232 storres
                        sollya_lib_copy_obj(currentApproxErrorSo))
1983 224 storres
        ### If get here it is because cerrSa <= approxAccurSa
1984 224 storres
        ### Approximation error of the new polynomial is acceptable.
1985 224 storres
        return (resPolySo, infNormSo)
1986 224 storres
    # End while True
1987 224 storres
# End pobyso_round_coefficients_progressive_so_so
1988 223 storres
1989 240 storres
def pobyso_round_coefficients_single_so_so(polySo, commonPrecSo):
1990 215 storres
    """
1991 215 storres
    Create a rounded coefficients polynomial from polynomial argument to
1992 215 storres
    the number of bits in size argument.
1993 215 storres
    All coefficients are set to the same precision.
1994 215 storres
    """
1995 215 storres
    ## TODO: check arguments.
1996 240 storres
    endEllipListSo = pobyso_build_end_elliptic_list_so_so(commonPrecSo)
1997 215 storres
    polySo = sollya_lib_roundcoefficients(polySo, endEllipListSo, None)
1998 217 storres
    sollya_lib_clear_obj(endEllipListSo)
1999 215 storres
    #sollya_lib_clear_obj(endEllipListSo)
2000 215 storres
    return polySo
2001 215 storres
2002 215 storres
# End pobyso_round_coefficients_single_so_so
2003 215 storres
2004 5 storres
def pobyso_set_canonical_off():
2005 5 storres
    sollya_lib_set_canonical(sollya_lib_off())
2006 5 storres
2007 5 storres
def pobyso_set_canonical_on():
2008 5 storres
    sollya_lib_set_canonical(sollya_lib_on())
2009 5 storres
2010 5 storres
def pobyso_set_prec(p):
2011 38 storres
    """ Legacy function. See pobyso_set_prec_sa_so. """
2012 85 storres
    pobyso_set_prec_sa_so(p)
2013 38 storres
2014 38 storres
def pobyso_set_prec_sa_so(p):
2015 227 storres
    #a = c_int(p)
2016 226 storres
    #precSo = c_void_p(sollya_lib_constant_from_int(a))
2017 227 storres
    #precSo = sollya_lib_constant_from_int(a)
2018 227 storres
    precSo = pobyso_constant_from_int_sa_so(p)
2019 226 storres
    sollya_lib_set_prec(precSo)
2020 226 storres
    sollya_lib_clear_obj(precSo)
2021 215 storres
# End pobyso_set_prec_sa_so.
2022 5 storres
2023 85 storres
def pobyso_set_prec_so_so(newPrecSo):
2024 226 storres
    sollya_lib_set_prec(newPrecSo)
2025 215 storres
# End pobyso_set_prec_so_so.
2026 54 storres
2027 281 storres
def pobyso_inf_so_so(rangeSo):
2028 215 storres
    """
2029 215 storres
    Very thin wrapper around sollya_lib_inf().
2030 215 storres
    """
2031 281 storres
    return sollya_lib_inf(rangeSo)
2032 215 storres
# End pobyso_inf_so_so.
2033 242 storres
#
2034 281 storres
def pobyso_infnorm_sa_sa(funcSa, interevalSa):
2035 281 storres
    """
2036 281 storres
    Very thin wrapper around sollya_lib_infnorm().
2037 281 storres
    We only take into account the 2 first arguments (the function and
2038 281 storres
    the interval (a range). Managing the other arguments (the file for
2039 281 storres
    the proof and the exclusion intervals list) will be performed later
2040 281 storres
    Changes will be needed in sollya_lib.py file too.
2041 281 storres
    """
2042 281 storres
    return sollya_lib_infnorm(funcSo, rangeSo, None)
2043 281 storres
# End pobyso_infnorm_so_so.
2044 281 storres
#
2045 281 storres
def pobyso_infnorm_so_so(funcSo, rangeSo):
2046 281 storres
    """
2047 281 storres
    Very thin wrapper around sollya_lib_infnorm().
2048 281 storres
    We only take into account the 2 first arguments (the function and
2049 281 storres
    the interval (a range). Managing the other arguments (the file for
2050 281 storres
    the proof and the exclusion intervals list) will be performed later
2051 281 storres
    Changes will be needed in sollya_lib.py file too.
2052 281 storres
    """
2053 281 storres
    return sollya_lib_infnorm(funcSo, rangeSo, None)
2054 281 storres
# End pobyso_infnorm_so_so.
2055 281 storres
#
2056 281 storres
def pobyso_supnorm_sa_sa(poly):
2057 281 storres
    """
2058 281 storres
    Computes the supremum norm from Sage input arguments and returns a
2059 281 storres
    Sage floating-point number whose precision is set by the realFieldSa
2060 281 storres
    argument.
2061 281 storres
    TODO: complete this stub!
2062 281 storres
    """
2063 281 storres
    print("This function does nothing!")
2064 281 storres
    return None
2065 281 storres
# End pobyso_supnorm_sa_sa
2066 281 storres
2067 242 storres
def pobyso_supnorm_so_sa(polySo, funcSo, intervalSo, errorTypeSo = None,\
2068 242 storres
                         accuracySo = None, realFieldSa = None):
2069 242 storres
    """
2070 281 storres
    Computes the supremum norm from Sollya input arguments and returns a
2071 242 storres
    Sage floating-point number whose precision is set by the only Sage argument.
2072 215 storres

2073 242 storres
    The returned value is the maximum of the absolute values of the range
2074 242 storres
    elements  returned by the Sollya supnorm functions
2075 242 storres
    """
2076 242 storres
    supNormRangeSo = pobyso_supnorm_so_so(polySo,
2077 242 storres
                                          funcSo,
2078 242 storres
                                          intervalSo,
2079 242 storres
                                          errorTypeSo,
2080 242 storres
                                          accuracySo)
2081 242 storres
    supNormSo = pobyso_range_max_abs_so_so(supNormRangeSo)
2082 242 storres
    sollya_lib_clear_obj(supNormRangeSo)
2083 242 storres
    #pobyso_autoprint(supNormSo)
2084 242 storres
    supNormSa = pobyso_get_constant_as_rn_with_rf_so_sa(supNormSo, realFieldSa)
2085 242 storres
    sollya_lib_clear_obj(supNormSo)
2086 242 storres
    return supNormSa
2087 242 storres
# End pobyso_supnorm_so_sa.
2088 242 storres
#
2089 85 storres
def pobyso_supnorm_so_so(polySo, funcSo, intervalSo, errorTypeSo = None,\
2090 85 storres
                         accuracySo = None):
2091 58 storres
    """
2092 85 storres
    Computes the supnorm of the approximation error between the given
2093 242 storres
    polynomial and function. Attention: returns a range!
2094 85 storres
    errorTypeSo defaults to "absolute".
2095 85 storres
    accuracySo defaults to 2^(-40).
2096 85 storres
    """
2097 85 storres
    if errorTypeSo is None:
2098 85 storres
        errorTypeSo = sollya_lib_absolute(None)
2099 85 storres
        errorTypeIsNone = True
2100 85 storres
    else:
2101 85 storres
        errorTypeIsNone = False
2102 85 storres
    #
2103 85 storres
    if accuracySo is None:
2104 237 storres
        # Notice the **: we are in Pythonland here!
2105 85 storres
        accuracySo = pobyso_constant_sa_so(RR(2**(-40)))
2106 85 storres
        accuracyIsNone = True
2107 85 storres
    else:
2108 85 storres
        accuracyIsNone = False
2109 238 storres
    #pobyso_autoprint(accuracySo)
2110 85 storres
    resultSo = \
2111 85 storres
        sollya_lib_supnorm(polySo, funcSo, intervalSo, errorTypeSo, \
2112 85 storres
                              accuracySo)
2113 85 storres
    if errorTypeIsNone:
2114 85 storres
        sollya_lib_clear_obj(errorTypeSo)
2115 85 storres
    if accuracyIsNone:
2116 85 storres
        sollya_lib_clear_obj(accuracySo)
2117 85 storres
    return resultSo
2118 85 storres
# End pobyso_supnorm_so_so
2119 242 storres
#
2120 162 storres
def pobyso_taylor_expansion_no_change_var_so_so(functionSo,
2121 162 storres
                                                degreeSo,
2122 162 storres
                                                rangeSo,
2123 162 storres
                                                errorTypeSo=None,
2124 162 storres
                                                sollyaPrecSo=None):
2125 85 storres
    """
2126 162 storres
    Compute the Taylor expansion without the variable change
2127 162 storres
    x -> x-intervalCenter.
2128 272 storres
    If errorTypeSo is None, absolute is used.
2129 272 storres
    If sollyaPrecSo is None, Sollya internal precision is not changed.
2130 58 storres
    """
2131 226 storres
    # Change internal Sollya precision, if needed.
2132 227 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = pobyso_get_prec_so_so_sa()
2133 226 storres
    sollyaPrecChanged = False
2134 226 storres
    if sollyaPrecSo is None:
2135 226 storres
        pass
2136 226 storres
    else:
2137 58 storres
        sollya_lib_set_prec(sollyaPrecSo)
2138 226 storres
        sollyaPrecChanged = True
2139 85 storres
    # Error type stuff: default to absolute.
2140 85 storres
    if errorTypeSo is None:
2141 85 storres
        errorTypeIsNone = True
2142 85 storres
        errorTypeSo = sollya_lib_absolute(None)
2143 85 storres
    else:
2144 85 storres
        errorTypeIsNone = False
2145 162 storres
    intervalCenterSo = sollya_lib_mid(rangeSo, None)
2146 162 storres
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo,
2147 162 storres
                                         intervalCenterSo,
2148 58 storres
                                         rangeSo, errorTypeSo, None)
2149 272 storres
    # Object taylorFormListSaSo is a Python list of Sollya objects references
2150 272 storres
    #  that are copies of the elements of taylorFormSo.
2151 117 storres
    # pobyso_get_list_elements_so_so clears taylorFormSo.
2152 162 storres
    (taylorFormListSaSo, numElementsSa, isEndEllipticSa) = \
2153 58 storres
        pobyso_get_list_elements_so_so(taylorFormSo)
2154 272 storres
    ## Copy needed here since polySo will be returned and taylorFormListSaSo
2155 272 storres
    #  will be cleared.
2156 162 storres
    polySo = sollya_lib_copy_obj(taylorFormListSaSo[0])
2157 162 storres
    #print "Num elements:", numElementsSa
2158 162 storres
    sollya_lib_clear_obj(taylorFormSo)
2159 181 storres
    # No copy_obj needed here: a new objects are created.
2160 272 storres
    maxErrorSo    = sollya_lib_sup(taylorFormListSaSo[2])
2161 272 storres
    minErrorSo    = sollya_lib_inf(taylorFormListSaSo[2])
2162 272 storres
    # List taylorFormListSaSo is not needed anymore.
2163 280 storres
    pobyso_clear_list_elements_sa_so(taylorFormListSaSo)
2164 181 storres
    absMaxErrorSo = sollya_lib_abs(maxErrorSo)
2165 181 storres
    absMinErrorSo = sollya_lib_abs(minErrorSo)
2166 181 storres
    sollya_lib_clear_obj(maxErrorSo)
2167 181 storres
    sollya_lib_clear_obj(minErrorSo)
2168 181 storres
    absMaxErrorSa = pobyso_get_constant_as_rn_so_sa(absMaxErrorSo)
2169 181 storres
    absMinErrorSa = pobyso_get_constant_as_rn_so_sa(absMinErrorSo)
2170 272 storres
    #
2171 272 storres
    if errorTypeIsNone:
2172 272 storres
        sollya_lib_clear_obj(errorTypeSo)
2173 272 storres
    ## If changed, reset the Sollya working precision.
2174 226 storres
    if sollyaPrecChanged:
2175 226 storres
        sollya_lib_set_prec(initialSollyaPrecSo)
2176 226 storres
    sollya_lib_clear_obj(initialSollyaPrecSo)
2177 272 storres
    ## According to what error is the largest, return the errors.
2178 181 storres
    if absMaxErrorSa > absMinErrorSa:
2179 181 storres
        sollya_lib_clear_obj(absMinErrorSo)
2180 227 storres
        return (polySo, intervalCenterSo, absMaxErrorSo)
2181 181 storres
    else:
2182 181 storres
        sollya_lib_clear_obj(absMaxErrorSo)
2183 227 storres
        return (polySo, intervalCenterSo, absMinErrorSo)
2184 162 storres
# end pobyso_taylor_expansion_no_change_var_so_so
2185 58 storres
2186 162 storres
def pobyso_taylor_expansion_with_change_var_so_so(functionSo, degreeSo, \
2187 162 storres
                                                  rangeSo, \
2188 162 storres
                                                  errorTypeSo=None, \
2189 162 storres
                                                  sollyaPrecSo=None):
2190 58 storres
    """
2191 162 storres
    Compute the Taylor expansion with the variable change
2192 162 storres
    x -> (x-intervalCenter) included.
2193 58 storres
    """
2194 226 storres
    # Change Sollya internal precision, if need.
2195 226 storres
    sollyaPrecChanged = False
2196 271 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = pobyso_get_prec_so_so_sa()
2197 226 storres
    if sollyaPrecSo is None:
2198 226 storres
        pass
2199 226 storres
    else:
2200 56 storres
        sollya_lib_set_prec(sollyaPrecSo)
2201 226 storres
        sollyaPrecChanged = True
2202 162 storres
    #
2203 85 storres
    # Error type stuff: default to absolute.
2204 85 storres
    if errorTypeSo is None:
2205 85 storres
        errorTypeIsNone = True
2206 85 storres
        errorTypeSo = sollya_lib_absolute(None)
2207 85 storres
    else:
2208 85 storres
        errorTypeIsNone = False
2209 162 storres
    intervalCenterSo = sollya_lib_mid(rangeSo)
2210 162 storres
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, \
2211 162 storres
                                         intervalCenterSo, \
2212 56 storres
                                         rangeSo, errorTypeSo, None)
2213 272 storres
    # Object taylorFormListSaSo is a Python list of Sollya objects references
2214 272 storres
    # that are copies of the elements of taylorFormSo.
2215 116 storres
    # pobyso_get_list_elements_so_so clears taylorFormSo.
2216 272 storres
    (taylorFormListSaSo, numElements, isEndElliptic) = \
2217 56 storres
        pobyso_get_list_elements_so_so(taylorFormSo)
2218 272 storres
    sollya_lib_clear_obj(taylorFormSo)
2219 272 storres
    polySo = taylorFormListSaSo[0]
2220 272 storres
    ## Maximum error computation with taylorFormListSaSo[2], a range
2221 272 storres
    #  holding the actual error. Bounds can be negative.
2222 272 storres
    maxErrorSo    = sollya_lib_sup(taylorFormListSaSo[2])
2223 272 storres
    minErrorSo    = sollya_lib_inf(taylorFormListSaSo[2])
2224 181 storres
    absMaxErrorSo = sollya_lib_abs(maxErrorSo)
2225 181 storres
    absMinErrorSo = sollya_lib_abs(minErrorSo)
2226 181 storres
    sollya_lib_clear_obj(maxErrorSo)
2227 181 storres
    sollya_lib_clear_obj(minErrorSo)
2228 181 storres
    absMaxErrorSa = pobyso_get_constant_as_rn_so_sa(absMaxErrorSo)
2229 181 storres
    absMinErrorSa = pobyso_get_constant_as_rn_so_sa(absMinErrorSo)
2230 162 storres
    changeVarExpSo = sollya_lib_build_function_sub(\
2231 162 storres
                       sollya_lib_build_function_free_variable(),\
2232 162 storres
                       sollya_lib_copy_obj(intervalCenterSo))
2233 181 storres
    polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpSo)
2234 272 storres
    # List taylorFormListSaSo is not needed anymore.
2235 280 storres
    pobyso_clear_list_elements_sa_so(taylorFormListSaSo)
2236 162 storres
    sollya_lib_clear_obj(changeVarExpSo)
2237 56 storres
    # If changed, reset the Sollya working precision.
2238 226 storres
    if sollyaPrecChanged:
2239 226 storres
        sollya_lib_set_prec(initialSollyaPrecSo)
2240 226 storres
    sollya_lib_clear_obj(initialSollyaPrecSo)
2241 85 storres
    if errorTypeIsNone:
2242 85 storres
        sollya_lib_clear_obj(errorTypeSo)
2243 162 storres
    # Do not clear maxErrorSo.
2244 181 storres
    if absMaxErrorSa > absMinErrorSa:
2245 181 storres
        sollya_lib_clear_obj(absMinErrorSo)
2246 181 storres
        return((polyVarChangedSo, intervalCenterSo, absMaxErrorSo))
2247 181 storres
    else:
2248 181 storres
        sollya_lib_clear_obj(absMaxErrorSo)
2249 181 storres
        return((polyVarChangedSo, intervalCenterSo, absMinErrorSo))
2250 162 storres
# end pobyso_taylor_expansion_with_change_var_so_so
2251 56 storres
2252 5 storres
def pobyso_taylor(function, degree, point):
2253 38 storres
    """ Legacy function. See pobysoTaylor_so_so. """
2254 38 storres
    return(pobyso_taylor_so_so(function, degree, point))
2255 38 storres
2256 56 storres
def pobyso_taylor_so_so(functionSo, degreeSo, pointSo):
2257 56 storres
    return(sollya_lib_taylor(functionSo, degreeSo, pointSo))
2258 5 storres
2259 85 storres
def pobyso_taylorform(function, degree, point = None,
2260 85 storres
                      interval = None, errorType=None):
2261 85 storres
    """ Legacy function. See pobyso_taylorform_sa_sa;"""
2262 38 storres
2263 38 storres
def pobyso_taylorform_sa_sa(functionSa, \
2264 84 storres
                            degreeSa, \
2265 84 storres
                            pointSa, \
2266 84 storres
                            intervalSa=None, \
2267 84 storres
                            errorTypeSa=None, \
2268 84 storres
                            precisionSa=None):
2269 37 storres
    """
2270 85 storres
    Compute the Taylor form of 'degreeSa' for 'functionSa' at 'pointSa'
2271 85 storres
    for 'intervalSa' with 'errorTypeSa' (a string) using 'precisionSa'.
2272 37 storres
    point: must be a Real or a Real interval.
2273 37 storres
    return the Taylor form as an array
2274 83 storres
    TODO: take care of the interval and of the point when it is an interval;
2275 38 storres
          when errorType is not None;
2276 83 storres
          take care of the other elements of the Taylor form (coefficients
2277 83 storres
          errors and delta.
2278 37 storres
    """
2279 37 storres
    # Absolute as the default error.
2280 84 storres
    if errorTypeSa is None:
2281 37 storres
        errorTypeSo = sollya_lib_absolute()
2282 84 storres
    elif errorTypeSa == "relative":
2283 84 storres
        errorTypeSo = sollya_lib_relative()
2284 84 storres
    elif errortypeSa == "absolute":
2285 84 storres
        errorTypeSo = sollya_lib_absolute()
2286 37 storres
    else:
2287 84 storres
        # No clean up needed.
2288 84 storres
        return None
2289 84 storres
    # Global precision stuff
2290 226 storres
    sollyaPrecisionChangedSa = False
2291 226 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = pobyso_get_prec_so_so_sa()
2292 226 storres
    if precisionSa is None:
2293 226 storres
        precSa = initialSollyaPrecSa
2294 226 storres
    else:
2295 226 storres
        if precSa > initialSollyaPrecSa:
2296 226 storres
            if precSa <= 2:
2297 226 storres
                print inspect.stack()[0][3], ":precision change <= 2 requested."
2298 226 storres
            pobyso_set_prec_sa_so(precSa)
2299 226 storres
            sollyaPrecisionChangedSa = True
2300 226 storres
    #
2301 85 storres
    if len(functionSa.variables()) > 0:
2302 85 storres
        varSa = functionSa.variables()[0]
2303 85 storres
        pobyso_name_free_variable_sa_so(str(varSa))
2304 84 storres
    # In any case (point or interval) the parent of pointSa has a precision
2305 84 storres
    # method.
2306 84 storres
    pointPrecSa = pointSa.parent().precision()
2307 226 storres
    if precSa > pointPrecSa:
2308 226 storres
        pointPrecSa = precSa
2309 84 storres
    # In any case (point or interval) pointSa has a base_ring() method.
2310 84 storres
    pointBaseRingString = str(pointSa.base_ring())
2311 84 storres
    if re.search('Interval', pointBaseRingString) is None: # Point
2312 84 storres
        pointSo = pobyso_constant_sa_so(pointSa, pointPrecSa)
2313 84 storres
    else: # Interval.
2314 84 storres
        pointSo = pobyso_interval_to_range_sa_so(pointSa, pointPrecSa)
2315 37 storres
    # Sollyafy the function.
2316 159 storres
    functionSo = pobyso_parse_string_sa_so(functionSa._assume_str().replace('_SAGE_VAR_', ''))
2317 37 storres
    if sollya_lib_obj_is_error(functionSo):
2318 37 storres
        print "pobyso_tailorform: function string can't be parsed!"
2319 37 storres
        return None
2320 37 storres
    # Sollyafy the degree
2321 84 storres
    degreeSo = sollya_lib_constant_from_int(int(degreeSa))
2322 37 storres
    # Sollyafy the point
2323 37 storres
    # Call Sollya
2324 83 storres
    taylorFormSo = \
2325 83 storres
        sollya_lib_taylorform(functionSo, degreeSo, pointSo, errorTypeSo,\
2326 37 storres
                                         None)
2327 85 storres
    sollya_lib_clear_obj(functionSo)
2328 85 storres
    sollya_lib_clear_obj(degreeSo)
2329 85 storres
    sollya_lib_clear_obj(pointSo)
2330 85 storres
    sollya_lib_clear_obj(errorTypeSo)
2331 38 storres
    (tfsAsList, numElements, isEndElliptic) = \
2332 38 storres
            pobyso_get_list_elements_so_so(taylorFormSo)
2333 37 storres
    polySo = tfsAsList[0]
2334 38 storres
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
2335 37 storres
    polyRealField = RealField(maxPrecision)
2336 38 storres
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, polyRealField)
2337 226 storres
    if sollyaPrecisionChangedSa:
2338 226 storres
        sollya_lib_set_prec(initialSollyaPrecSo)
2339 226 storres
    sollya_lib_clear_obj(initialSollyaPrecSo)
2340 37 storres
    polynomialRing = polyRealField[str(varSa)]
2341 37 storres
    polySa = polynomial(expSa, polynomialRing)
2342 37 storres
    taylorFormSa = [polySa]
2343 85 storres
    # Final clean-up.
2344 85 storres
    sollya_lib_clear_obj(taylorFormSo)
2345 51 storres
    return(taylorFormSa)
2346 51 storres
# End pobyso_taylor_form_sa_sa
2347 54 storres
2348 54 storres
def pobyso_taylorform_so_so(functionSo, degreeSo, pointSo, intervalSo=None, \
2349 54 storres
                            errorTypeSo=None):
2350 54 storres
    createdErrorType = False
2351 51 storres
    if errorTypeSo is None:
2352 51 storres
        errorTypeSo = sollya_lib_absolute()
2353 54 storres
        createdErrorType = True
2354 51 storres
    else:
2355 51 storres
        #TODO: deal with the other case.
2356 51 storres
        pass
2357 51 storres
    if intervalSo is None:
2358 54 storres
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
2359 54 storres
                                         errorTypeSo, None)
2360 51 storres
    else:
2361 54 storres
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
2362 54 storres
                                         intervalSo, errorTypeSo, None)
2363 54 storres
    if createdErrorType:
2364 54 storres
        sollya_lib_clear_obj(errorTypeSo)
2365 215 storres
    return resultSo
2366 51 storres
2367 37 storres
2368 37 storres
def pobyso_univar_polynomial_print_reverse(polySa):
2369 51 storres
    """ Legacy function. See pobyso_univar_polynomial_print_reverse_sa_sa. """
2370 51 storres
    return(pobyso_univar_polynomial_print_reverse_sa_sa(polySa))
2371 38 storres
2372 51 storres
def pobyso_univar_polynomial_print_reverse_sa_sa(polySa):
2373 37 storres
    """
2374 37 storres
    Return the string representation of a univariate polynomial with
2375 38 storres
    monomials ordered in the x^0..x^n order of the monomials.
2376 37 storres
    Remember: Sage
2377 37 storres
    """
2378 37 storres
    polynomialRing = polySa.base_ring()
2379 37 storres
    # A very expensive solution:
2380 37 storres
    # -create a fake multivariate polynomial field with only one variable,
2381 37 storres
    #   specifying a negative lexicographical order;
2382 37 storres
    mpolynomialRing = PolynomialRing(polynomialRing.base(), \
2383 37 storres
                                     polynomialRing.variable_name(), \
2384 37 storres
                                     1, order='neglex')
2385 37 storres
    # - convert the univariate argument polynomial into a multivariate
2386 37 storres
    #   version;
2387 37 storres
    p = mpolynomialRing(polySa)
2388 37 storres
    # - return the string representation of the converted form.
2389 37 storres
    # There is no simple str() method defined for p's class.
2390 37 storres
    return(p.__str__())
2391 5 storres
#
2392 230 storres
#print pobyso_get_prec()
2393 5 storres
pobyso_set_prec(165)
2394 230 storres
#print pobyso_get_prec()
2395 230 storres
#a=100
2396 230 storres
#print type(a)
2397 230 storres
#id(a)
2398 230 storres
#print "Max arity: ", pobyso_max_arity
2399 230 storres
#print "Function tripleDouble (43) as a string: ", pobyso_function_type_as_string(43)
2400 230 storres
#print "Function None (44) as a string: ", pobyso_function_type_as_string(44)
2401 246 storres
sys.stderr.write("\t...Pobyso check done.\n")