Statistiques
| Révision :

root / pobysoPythonSage / src / pobyso.py @ 284

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

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

897 118 storres
    INPUT:
898 118 storres
    - objectListSo: a Sollya list of Sollya objects.
899 118 storres

900 118 storres
    OUTPUT:
901 118 storres
    - a Sage/Python tuple made of:
902 118 storres
      - a Sage/Python list of Sollya objects,
903 118 storres
      - a Sage/Python int holding the number of elements,
904 118 storres
      - a Sage/Python int stating (!= 0) that the list is end-elliptic.
905 118 storres
    NOTE::
906 118 storres
        We recover the addresses of the Sollya object from the list of pointers
907 118 storres
        returned by sollya_lib_get_list_elements. The list itself is freed.
908 118 storres
    TODO::
909 118 storres
        Figure out what to do with numElements since the number of elements
910 118 storres
        can easily be recovered from the list itself.
911 118 storres
        Ditto for isEndElliptic.
912 51 storres
    """
913 5 storres
    listAddress = POINTER(c_longlong)()
914 5 storres
    numElements = c_int(0)
915 5 storres
    isEndElliptic = c_int(0)
916 117 storres
    listAsSageList = []
917 5 storres
    result = sollya_lib_get_list_elements(byref(listAddress),\
918 54 storres
                                          byref(numElements),\
919 54 storres
                                          byref(isEndElliptic),\
920 117 storres
                                          objectListSo)
921 5 storres
    if result == 0 :
922 5 storres
        return None
923 5 storres
    for i in xrange(0, numElements.value, 1):
924 118 storres
       #listAsSageList.append(sollya_lib_copy_obj(listAddress[i]))
925 118 storres
       listAsSageList.append(listAddress[i])
926 117 storres
       # Clear each of the elements returned by Sollya.
927 118 storres
       #sollya_lib_clear_obj(listAddress[i])
928 117 storres
    # Free the list itself.
929 117 storres
    sollya_lib_free(listAddress)
930 209 storres
    return (listAsSageList, numElements.value, isEndElliptic.value)
931 5 storres
932 38 storres
def pobyso_get_max_prec_of_exp(soExp):
933 38 storres
    """ Legacy function. See pobyso_get_max_prec_of_exp_so_sa. """
934 209 storres
    return pobyso_get_max_prec_of_exp_so_sa(soExp)
935 5 storres
936 85 storres
def pobyso_get_max_prec_of_exp_so_sa(expSo):
937 38 storres
    """
938 38 storres
    Get the maximum precision used for the numbers in a Sollya expression.
939 52 storres

940 52 storres
    Arguments:
941 52 storres
    soExp -- a Sollya expression pointer
942 52 storres
    Return value:
943 52 storres
    A Python integer
944 38 storres
    TODO:
945 38 storres
    - error management;
946 38 storres
    - correctly deal with numerical type such as DOUBLEEXTENDED.
947 38 storres
    """
948 226 storres
    if expSo is None:
949 226 storres
        print inspect.stack()[0][3], ": expSo is None."
950 226 storres
        return 0
951 5 storres
    maxPrecision = 0
952 52 storres
    minConstPrec = 0
953 52 storres
    currentConstPrec = 0
954 226 storres
    #pobyso_autoprint(expSo)
955 85 storres
    operator = pobyso_get_head_function_so_sa(expSo)
956 5 storres
    if (operator != SOLLYA_BASE_FUNC_CONSTANT) and \
957 5 storres
    (operator != SOLLYA_BASE_FUNC_FREE_VARIABLE):
958 85 storres
        (arity, subexpressions) = pobyso_get_subfunctions_so_sa(expSo)
959 5 storres
        for i in xrange(arity):
960 5 storres
            maxPrecisionCandidate = \
961 38 storres
                pobyso_get_max_prec_of_exp_so_sa(subexpressions[i])
962 5 storres
            if maxPrecisionCandidate > maxPrecision:
963 5 storres
                maxPrecision = maxPrecisionCandidate
964 209 storres
        return maxPrecision
965 5 storres
    elif operator == SOLLYA_BASE_FUNC_CONSTANT:
966 85 storres
        #minConstPrec = pobyso_get_min_prec_of_constant_so_sa(expSo)
967 52 storres
        #currentConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
968 52 storres
        #print minConstPrec, " - ", currentConstPrec
969 209 storres
        return pobyso_get_min_prec_of_constant_so_sa(expSo)
970 52 storres
971 5 storres
    elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
972 209 storres
        return 0
973 5 storres
    else:
974 38 storres
        print "pobyso_get_max_prec_of_exp_so_sa: unexepected operator."
975 209 storres
        return 0
976 5 storres
977 85 storres
def pobyso_get_min_prec_of_constant_so_sa(constExpSo):
978 52 storres
    """
979 52 storres
    Get the minimum precision necessary to represent the value of a Sollya
980 52 storres
    constant.
981 52 storres
    MPFR_MIN_PREC and powers of 2 are taken into account.
982 209 storres
    We assume that constExpSo is a pointer to a Sollay constant expression.
983 52 storres
    """
984 85 storres
    constExpAsRnSa = pobyso_get_constant_as_rn_so_sa(constExpSo)
985 85 storres
    return(min_mpfr_size(get_rn_value(constExpAsRnSa)))
986 52 storres
987 200 storres
def pobyso_get_poly_so_sa(polySo, realFieldSa=None):
988 200 storres
    """
989 200 storres
    Convert a Sollya polynomial into a Sage polynomial.
990 209 storres
    Legacy function. Use pobyso_float_poly_so_sa() instead.
991 200 storres
    """
992 213 storres
    return pobyso_float_poly_so_sa(polySo,realFieldSa)
993 200 storres
# End pobyso_get_poly_so_sa
994 200 storres
995 200 storres
def pobyso_get_prec():
996 200 storres
    """ Legacy function. See pobyso_get_prec_so_sa(). """
997 209 storres
    return pobyso_get_prec_so_sa()
998 200 storres
999 200 storres
def pobyso_get_prec_so():
1000 200 storres
    """
1001 200 storres
    Get the current default precision in Sollya.
1002 200 storres
    The return value is a Sollya object.
1003 200 storres
    Usefull when modifying the precision back and forth by avoiding
1004 200 storres
    extra conversions.
1005 200 storres
    """
1006 209 storres
    return sollya_lib_get_prec(None)
1007 200 storres
1008 200 storres
def pobyso_get_prec_so_sa():
1009 200 storres
    """
1010 200 storres
    Get the current default precision in Sollya.
1011 200 storres
    The return value is Sage/Python int.
1012 200 storres
    """
1013 227 storres
    precSo = sollya_lib_get_prec()
1014 227 storres
    precSa = pobyso_constant_from_int_so_sa(precSo)
1015 200 storres
    sollya_lib_clear_obj(precSo)
1016 227 storres
    return precSa
1017 200 storres
# End pobyso_get_prec_so_sa.
1018 200 storres
1019 209 storres
def pobyso_get_prec_so_so_sa():
1020 209 storres
    """
1021 209 storres
    Return the current precision both as a Sollya object and a
1022 209 storres
    Sage integer as hybrid tuple.
1023 209 storres
    To avoid multiple calls for precision manipulations.
1024 209 storres
    """
1025 227 storres
    precSo = sollya_lib_get_prec()
1026 227 storres
    precSa = pobyso_constant_from_int_so_sa(precSo)
1027 227 storres
    return (precSo, int(precSa))
1028 200 storres
1029 200 storres
def pobyso_get_prec_of_constant(ctExpSo):
1030 200 storres
    """ Legacy function. See pobyso_get_prec_of_constant_so_sa. """
1031 209 storres
    return pobyso_get_prec_of_constant_so_sa(ctExpSo)
1032 200 storres
1033 200 storres
def pobyso_get_prec_of_constant_so_sa(ctExpSo):
1034 200 storres
    """
1035 200 storres
    Tries to find a precision to represent ctExpSo without rounding.
1036 200 storres
    If not possible, returns None.
1037 200 storres
    """
1038 218 storres
    #print "Entering pobyso_get_prec_of_constant_so_sa..."
1039 200 storres
    prec = c_int(0)
1040 200 storres
    retc = sollya_lib_get_prec_of_constant(byref(prec), ctExpSo, None)
1041 200 storres
    if retc == 0:
1042 218 storres
        #print "pobyso_get_prec_of_constant_so_sa failed."
1043 209 storres
        return None
1044 218 storres
    #print "...exiting pobyso_get_prec_of_constant_so_sa."
1045 209 storres
    return int(prec.value)
1046 200 storres
1047 200 storres
def pobyso_get_prec_of_range_so_sa(rangeSo):
1048 200 storres
    """
1049 200 storres
    Returns the number of bits elements of a range are coded with.
1050 200 storres
    """
1051 200 storres
    prec = c_int(0)
1052 200 storres
    retc = sollya_lib_get_prec_of_range(byref(prec), rangeSo, None)
1053 200 storres
    if retc == 0:
1054 200 storres
        return(None)
1055 209 storres
    return int(prec.value)
1056 200 storres
# End pobyso_get_prec_of_range_so_sa()
1057 200 storres
1058 85 storres
def pobyso_get_sage_exp_from_sollya_exp(sollyaExpSo, realField = RR):
1059 38 storres
    """ Legacy function. See pobyso_get_sage_exp_from_sollya_exp_so_sa. """
1060 209 storres
    return pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo,
1061 209 storres
                                                     realField = RR)
1062 38 storres
1063 85 storres
def pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, realFieldSa = RR):
1064 5 storres
    """
1065 38 storres
    Get a Sage expression from a Sollya expression.
1066 38 storres
    Currently only tested with polynomials with floating-point coefficients.
1067 5 storres
    Notice that, in the returned polynomial, the exponents are RealNumbers.
1068 5 storres
    """
1069 5 storres
    #pobyso_autoprint(sollyaExp)
1070 85 storres
    operatorSa = pobyso_get_head_function_so_sa(sollyaExpSo)
1071 83 storres
    sollyaLibFreeVariableName = sollya_lib_get_free_variable_name()
1072 213 storres
    ## Get rid of the "_"'s in "_x_", if any.
1073 213 storres
    sollyaLibFreeVariableName = re.sub('_', '', sollyaLibFreeVariableName)
1074 5 storres
    # Constants and the free variable are special cases.
1075 5 storres
    # All other operator are dealt with in the same way.
1076 85 storres
    if (operatorSa != SOLLYA_BASE_FUNC_CONSTANT) and \
1077 85 storres
       (operatorSa != SOLLYA_BASE_FUNC_FREE_VARIABLE):
1078 85 storres
        (aritySa, subexpressionsSa) = pobyso_get_subfunctions_so_sa(sollyaExpSo)
1079 85 storres
        if aritySa == 1:
1080 85 storres
            sageExpSa = eval(pobyso_function_type_as_string_so_sa(operatorSa) + \
1081 85 storres
            "(" + pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], \
1082 85 storres
            realFieldSa) + ")")
1083 85 storres
        elif aritySa == 2:
1084 63 storres
            # We do not get through the preprocessor.
1085 63 storres
            # The "^" operator is then a special case.
1086 85 storres
            if operatorSa == SOLLYA_BASE_FUNC_POW:
1087 85 storres
                operatorAsStringSa = "**"
1088 5 storres
            else:
1089 85 storres
                operatorAsStringSa = \
1090 85 storres
                    pobyso_function_type_as_string_so_sa(operatorSa)
1091 85 storres
            sageExpSa = \
1092 85 storres
              eval("pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], realFieldSa)"\
1093 85 storres
              + " " + operatorAsStringSa + " " + \
1094 85 storres
                   "pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[1], realFieldSa)")
1095 63 storres
        # We do not know yet how to deal with arity >= 3
1096 63 storres
        # (is there any in Sollya anyway?).
1097 5 storres
        else:
1098 85 storres
            sageExpSa = eval('None')
1099 209 storres
        return sageExpSa
1100 85 storres
    elif operatorSa == SOLLYA_BASE_FUNC_CONSTANT:
1101 5 storres
        #print "This is a constant"
1102 85 storres
        return pobyso_get_constant_as_rn_with_rf_so_sa(sollyaExpSo, realFieldSa)
1103 85 storres
    elif operatorSa == SOLLYA_BASE_FUNC_FREE_VARIABLE:
1104 218 storres
        #print "This is the free variable"
1105 209 storres
        return eval(sollyaLibFreeVariableName)
1106 5 storres
    else:
1107 5 storres
        print "Unexpected"
1108 5 storres
        return eval('None')
1109 185 storres
# End pobyso_get_sage_exp_from_sollya_exp_so_sa
1110 73 storres
1111 185 storres
1112 38 storres
def pobyso_get_subfunctions(expressionSo):
1113 38 storres
    """ Legacy function. See pobyso_get_subfunctions_so_sa. """
1114 209 storres
    return pobyso_get_subfunctions_so_sa(expressionSo)
1115 200 storres
# End pobyso_get_subfunctions.
1116 200 storres
1117 38 storres
def pobyso_get_subfunctions_so_sa(expressionSo):
1118 38 storres
    """
1119 38 storres
    Get the subfunctions of an expression.
1120 38 storres
    Return the number of subfunctions and the list of subfunctions addresses.
1121 55 storres
    S.T.: Could not figure out another way than that ugly list of declarations
1122 83 storres
    to recover the addresses of the subfunctions.
1123 83 storres
    We limit ourselves to arity 8 functions.
1124 38 storres
    """
1125 5 storres
    subf0 = c_int(0)
1126 5 storres
    subf1 = c_int(0)
1127 5 storres
    subf2 = c_int(0)
1128 5 storres
    subf3 = c_int(0)
1129 5 storres
    subf4 = c_int(0)
1130 5 storres
    subf5 = c_int(0)
1131 5 storres
    subf6 = c_int(0)
1132 5 storres
    subf7 = c_int(0)
1133 5 storres
    subf8 = c_int(0)
1134 5 storres
    arity = c_int(0)
1135 5 storres
    nullPtr = POINTER(c_int)()
1136 38 storres
    sollya_lib_get_subfunctions(expressionSo, byref(arity), \
1137 83 storres
      byref(subf0), byref(subf1), byref(subf2), byref(subf3), \
1138 83 storres
      byref(subf4), byref(subf5),\
1139 83 storres
      byref(subf6), byref(subf7), byref(subf8), nullPtr, None)
1140 83 storres
#    byref(cast(subfunctions[0], POINTER(c_int))), \
1141 83 storres
#    byref(cast(subfunctions[0], POINTER(c_int))), \
1142 83 storres
#    byref(cast(subfunctions[2], POINTER(c_int))), \
1143 83 storres
#    byref(cast(subfunctions[3], POINTER(c_int))), \
1144 83 storres
#    byref(cast(subfunctions[4], POINTER(c_int))), \
1145 83 storres
#    byref(cast(subfunctions[5], POINTER(c_int))), \
1146 83 storres
#    byref(cast(subfunctions[6], POINTER(c_int))), \
1147 83 storres
#    byref(cast(subfunctions[7], POINTER(c_int))), \
1148 5 storres
#    byref(cast(subfunctions[8], POINTER(c_int))), nullPtr)
1149 83 storres
    subfunctions = [subf0, subf1, subf2, subf3, subf4, subf5, subf6, subf7, \
1150 83 storres
                    subf8]
1151 5 storres
    subs = []
1152 5 storres
    if arity.value > pobyso_max_arity:
1153 38 storres
        return(0,[])
1154 5 storres
    for i in xrange(arity.value):
1155 5 storres
        subs.append(int(subfunctions[i].value))
1156 5 storres
        #print subs[i]
1157 209 storres
    return (int(arity.value), subs)
1158 200 storres
# End pobyso_get_subfunctions_so_sa
1159 5 storres
1160 155 storres
def pobyso_guess_degree_sa_sa(functionSa, intervalSa, approxErrorSa,
1161 155 storres
                              weightSa=None, degreeBoundSa=None):
1162 155 storres
    """
1163 155 storres
    Sa_sa variant of the solly_guessdegree function.
1164 155 storres
    Return 0 if something goes wrong.
1165 155 storres
    """
1166 159 storres
    functionAsStringSa = functionSa._assume_str().replace('_SAGE_VAR_', '')
1167 154 storres
    functionSo = pobyso_parse_string_sa_so(functionAsStringSa)
1168 155 storres
    if pobyso_is_error_so_sa(functionSo):
1169 155 storres
        sollya_lib_clear_obj(functionSo)
1170 155 storres
        return 0
1171 154 storres
    rangeSo = pobyso_interval_to_range_sa_so(intervalSa)
1172 155 storres
    # The approximation error is expected to be a floating point number.
1173 155 storres
    if pobyso_is_floating_point_number_sa_sa(approxErrorSa):
1174 155 storres
        approxErrorSo = pobyso_constant_sa_so(approxErrorSa)
1175 155 storres
    else:
1176 155 storres
        approxErrorSo = pobyso_constant_sa_so(RR(approxErrorSa))
1177 154 storres
    if not weightSa is None:
1178 159 storres
        weightAsStringSa = weightSa._assume_str().replace('_SAGE_VAR_', '')
1179 154 storres
        weightSo = pobyso_parse_string_sa_so(weightAsStringSa)
1180 166 storres
        if pobyso_is_error_so_sa(weightSo):
1181 155 storres
            sollya_lib_clear_obj(functionSo)
1182 155 storres
            sollya_lib_clear_obj(rangeSo)
1183 155 storres
            sollya_lib_clear_obj(approxErrorSo)
1184 155 storres
            sollya_lib_clear_obj(weightSo)
1185 155 storres
            return 0
1186 154 storres
    else:
1187 154 storres
        weightSo = None
1188 154 storres
    if not degreeBoundSa is None:
1189 154 storres
        degreeBoundSo = pobyso_constant_from_int_sa_so(degreeBoundSa)
1190 154 storres
    else:
1191 154 storres
        degreeBoundSo = None
1192 154 storres
    guessedDegreeSa = pobyso_guess_degree_so_sa(functionSo,
1193 162 storres
                                                rangeSo,
1194 162 storres
                                                approxErrorSo,
1195 162 storres
                                                weightSo,
1196 162 storres
                                                degreeBoundSo)
1197 154 storres
    sollya_lib_clear_obj(functionSo)
1198 154 storres
    sollya_lib_clear_obj(rangeSo)
1199 155 storres
    sollya_lib_clear_obj(approxErrorSo)
1200 154 storres
    if not weightSo is None:
1201 154 storres
        sollya_lib_clear_obj(weightSo)
1202 154 storres
    if not degreeBoundSo is None:
1203 154 storres
        sollya_lib_clear_obj(degreeBoundSo)
1204 154 storres
    return guessedDegreeSa
1205 154 storres
# End poyso_guess_degree_sa_sa
1206 154 storres
1207 153 storres
def pobyso_guess_degree_so_sa(functionSo, rangeSo, errorSo, weightSo=None, \
1208 154 storres
                              degreeBoundSo=None):
1209 154 storres
    """
1210 154 storres
    Thin wrapper around the guessdegree function.
1211 154 storres
    Nevertheless, some precision control stuff has been appended.
1212 154 storres
    """
1213 154 storres
    # Deal with Sollya internal precision issues: if it is too small,
1214 154 storres
    # compared with the error, increases it to about twice -log2(error).
1215 154 storres
    errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(errorSo)
1216 154 storres
    log2ErrorSa = errorSa.log2()
1217 154 storres
    if log2ErrorSa < 0:
1218 154 storres
        neededPrecisionSa = int(2 * int(-log2ErrorSa) / 64) * 64
1219 154 storres
    else:
1220 154 storres
        neededPrecisionSa = int(2 * int(log2ErrorSa) / 64) * 64
1221 154 storres
    #print "Needed precision:", neededPrecisionSa
1222 226 storres
    sollyaPrecisionHasChanged = False
1223 226 storres
    (initialPrecSo, initialPrecSa) = pobyso_get_prec_so_so_sa()
1224 226 storres
    if neededPrecisionSa > initialPrecSa:
1225 226 storres
        if neededPrecisionSa <= 2:
1226 226 storres
            print inspect.stack()[0][3], ": precision change <= 2 requested."
1227 154 storres
        pobyso_set_prec_sa_so(neededPrecisionSa)
1228 226 storres
        sollyaPrecisionHasChanged = True
1229 166 storres
    #print "Guessing degree..."
1230 153 storres
    # weightSo and degreeBoundsSo are optional arguments.
1231 162 storres
    # As declared, sollya_lib_guessdegree must take 5 arguments.
1232 153 storres
    if weightSo is None:
1233 162 storres
        degreeRangeSo = sollya_lib_guessdegree(functionSo, rangeSo, errorSo,
1234 162 storres
                                               0, 0, None)
1235 154 storres
    elif degreeBoundSo is None:
1236 153 storres
        degreeRangeSo =  sollya_lib_guessdegree(functionSo, rangeSo, \
1237 162 storres
                                                errorSo, weightSo, 0, None)
1238 153 storres
    else:
1239 153 storres
        degreeRangeSo =  sollya_lib_guessdegree(functionSo, rangeSo, errorSo, \
1240 154 storres
                                                weightSo, degreeBoundSo, None)
1241 166 storres
    #print "...degree guess done."
1242 154 storres
    # Restore internal precision, if applicable.
1243 226 storres
    if sollyaPrecisionHasChanged:
1244 226 storres
        pobyso_set_prec_so_so(initialPrecSo)
1245 226 storres
        sollya_lib_clear_obj(initialPrecSo)
1246 154 storres
    degreeIntervalSa = pobyso_range_to_interval_so_sa(degreeRangeSo)
1247 154 storres
    sollya_lib_clear_obj(degreeRangeSo)
1248 154 storres
    # When ok, both bounds match.
1249 154 storres
    # When the degree bound is too low, the upper bound is the degree
1250 154 storres
    # for which the error can be honored.
1251 154 storres
    # When it really goes wrong, the upper bound is infinity.
1252 154 storres
    if degreeIntervalSa.lower() == degreeIntervalSa.upper():
1253 154 storres
        return int(degreeIntervalSa.lower())
1254 154 storres
    else:
1255 154 storres
        if degreeIntervalSa.upper().is_infinity():
1256 154 storres
            return None
1257 154 storres
        else:
1258 154 storres
            return int(degreeIntervalSa.upper())
1259 154 storres
    # End pobyso_guess_degree_so_sa
1260 153 storres
1261 215 storres
def pobyso_inf_so_so(intervalSo):
1262 215 storres
    """
1263 215 storres
    Very thin wrapper around sollya_lib_inf().
1264 215 storres
    """
1265 215 storres
    return sollya_lib_inf(intervalSo)
1266 215 storres
# End pobyso_inf_so_so.
1267 282 storres
#
1268 282 storres
def pobyso_infnorm_sa_sa(funcSa, intervalSa):
1269 282 storres
    """
1270 282 storres
    An infnorm call with Sage arguments.
1271 282 storres
    We only take into account the 2 first arguments (the function and
1272 282 storres
    the interval (a range). Managing the other arguments (the file for
1273 282 storres
    the proof and the exclusion intervals list) will be performed later
1274 282 storres
    Changes will be needed in sollya_lib.py file too.
1275 282 storres
    """
1276 282 storres
    # Check that funcSa is a function.
1277 282 storres
    if not \
1278 282 storres
     sage.symbolic.callable.is_CallableSymbolicExpressionRing(parent(funcSa)):
1279 282 storres
        return None
1280 282 storres
    # Check that intervalSa is an interval.
1281 282 storres
    try:
1282 282 storres
        intervalSa.upper()
1283 282 storres
    except AttributeError:
1284 282 storres
        return None
1285 282 storres
    # Convert the Sage function into a Sollya function.
1286 282 storres
    funcAsStringSa = funcSa._assume_str().replace('_SAGE_VAR_', '')
1287 282 storres
    funcSo = pobyso_parse_string_sa_so(funcAsStringSa)
1288 282 storres
    if not pobyso_obj_is_function_so_sa(funcSo):
1289 282 storres
        sollya_lib_clear_obj(funcSo)
1290 282 storres
        return None
1291 282 storres
    # Convert the Sage interval into a Sollya range.
1292 282 storres
    rangeSo = pobyso_interval_to_range_sa_so(intervalSa)
1293 282 storres
    retValSo = sollya_lib_infnorm(funcSo, rangeSo, None)
1294 282 storres
    sollya_lib_clear_obj(funcSo)
1295 282 storres
    sollya_lib_clear_obj(rangeSo)
1296 282 storres
    if pobyso_is_error_so_sa(retValSo):
1297 282 storres
        sollya_lib_clear_obj(retValSo)
1298 282 storres
        return None
1299 282 storres
    retValSa = pobyso_range_to_interval_so_sa(retValSo)
1300 282 storres
    sollya_lib_clear_obj(retValSo)
1301 282 storres
    return retValSa
1302 282 storres
# End pobyso_infnorm_so_so.
1303 282 storres
#
1304 282 storres
def pobyso_infnorm_so_so(funcSo, rangeSo):
1305 282 storres
    """
1306 282 storres
    Very thin wrapper around sollya_lib_infnorm().
1307 282 storres
    We only take into account the 2 first arguments (the function and
1308 282 storres
    the interval (a range). Managing the other arguments (the file for
1309 282 storres
    the proof and the exclusion intervals list) will be performed later
1310 282 storres
    Changes will be needed in sollya_lib.py file too.
1311 215 storres

1312 282 storres
    As per Sollya manual, this function should not be used anymore and
1313 282 storres
    supnorm should be called instead. Nevertheless, supnorm breaks
1314 282 storres
    sometimes whereas infnorm still returns a satisfactory answer.
1315 282 storres
    """
1316 282 storres
    return sollya_lib_infnorm(funcSo, rangeSo, None)
1317 282 storres
# End pobyso_infnorm_so_so.
1318 53 storres
1319 84 storres
def pobyso_interval_to_range_sa_so(intervalSa, precisionSa=None):
1320 84 storres
    if precisionSa is None:
1321 84 storres
        precisionSa = intervalSa.parent().precision()
1322 84 storres
    intervalSo = pobyso_bounds_to_range_sa_so(intervalSa.lower(),\
1323 84 storres
                                              intervalSa.upper(),\
1324 84 storres
                                              precisionSa)
1325 209 storres
    return intervalSo
1326 84 storres
# End pobyso_interval_to_range_sa_so
1327 84 storres
1328 155 storres
def pobyso_is_error_so_sa(objSo):
1329 155 storres
    """
1330 155 storres
    Thin wrapper around the sollya_lib_obj_is_error() function.
1331 155 storres
    """
1332 155 storres
    if sollya_lib_obj_is_error(objSo) != 0:
1333 155 storres
        return True
1334 155 storres
    else:
1335 155 storres
        return False
1336 155 storres
# End pobyso_is_error-so_sa
1337 155 storres
1338 155 storres
def pobyso_is_floating_point_number_sa_sa(numberSa):
1339 155 storres
    """
1340 209 storres
    Check whether a Sage number is floating point.
1341 209 storres
    Exception stuff added because numbers other than
1342 209 storres
    floating-point ones do not have the is_real() attribute.
1343 155 storres
    """
1344 209 storres
    try:
1345 209 storres
        return numberSa.is_real()
1346 209 storres
    except AttributeError:
1347 209 storres
        return False
1348 209 storres
# End pobyso_is_floating_piont_number_sa_sa
1349 155 storres
1350 226 storres
def pobyso_is_range_so_sa(rangeCandidateSo):
1351 226 storres
    """
1352 226 storres
    Thin wrapper over sollya_lib_is_range.
1353 226 storres
    """
1354 226 storres
    return sollya_lib_obj_is_range(rangeCandidateSo) != 0
1355 226 storres
1356 226 storres
# End pobyso_is_range_so_sa
1357 226 storres
1358 226 storres
1359 37 storres
def pobyso_lib_init():
1360 37 storres
    sollya_lib_init(None)
1361 116 storres
1362 116 storres
def pobyso_lib_close():
1363 116 storres
    sollya_lib_close(None)
1364 237 storres
1365 85 storres
def pobyso_name_free_variable(freeVariableNameSa):
1366 38 storres
    """ Legacy function. See pobyso_name_free_variable_sa_so. """
1367 85 storres
    pobyso_name_free_variable_sa_so(freeVariableNameSa)
1368 38 storres
1369 85 storres
def pobyso_name_free_variable_sa_so(freeVariableNameSa):
1370 83 storres
    """
1371 83 storres
    Set the free variable name in Sollya from a Sage string.
1372 83 storres
    """
1373 85 storres
    sollya_lib_name_free_variable(freeVariableNameSa)
1374 37 storres
1375 281 storres
def pobyso_obj_is_function_so_sa(objSo):
1376 281 storres
    """
1377 281 storres
    Check if an object is a function.
1378 281 storres
    """
1379 281 storres
    if sollya_lib_obj_is_function(objSo) != 0:
1380 281 storres
        return True
1381 281 storres
    else:
1382 281 storres
        return False
1383 281 storres
# End pobyso_obj_is_function_so_sa
1384 281 storres
1385 281 storres
def pobyso_obj_is_range_so_sa(objSo):
1386 281 storres
    """
1387 281 storres
    Check if an object is a function.
1388 281 storres
    """
1389 281 storres
    if sollya_lib_obj_is_range(objSo) != 0:
1390 281 storres
        return True
1391 281 storres
    else:
1392 281 storres
        return False
1393 281 storres
# End pobyso_obj_is_range_so_sa
1394 281 storres
1395 281 storres
def pobyso_obj_is_string_so_sa(objSo):
1396 281 storres
    """
1397 281 storres
    Check if an object is a function.
1398 281 storres
    """
1399 281 storres
    if sollya_lib_obj_is_string(objSo) != 0:
1400 281 storres
        return True
1401 281 storres
    else:
1402 281 storres
        return False
1403 281 storres
# End pobyso_obj_is_string_so_sa
1404 281 storres
1405 5 storres
def pobyso_parse_string(string):
1406 38 storres
    """ Legacy function. See pobyso_parse_string_sa_so. """
1407 209 storres
    return pobyso_parse_string_sa_so(string)
1408 38 storres
1409 38 storres
def pobyso_parse_string_sa_so(string):
1410 83 storres
    """
1411 155 storres
    Get the Sollya expression computed from a Sage string or
1412 155 storres
    a Sollya error object if parsing failed.
1413 83 storres
    """
1414 209 storres
    return sollya_lib_parse_string(string)
1415 5 storres
1416 200 storres
def pobyso_precision_so_sa(ctExpSo):
1417 209 storres
    """
1418 209 storres
    Computes the necessary precision to represent a number.
1419 209 storres
    If x is not zero, it can be uniquely written as x = m · 2e
1420 209 storres
    where m is an odd integer and e is an integer.
1421 209 storres
    precision(x) returns the number of bits necessary to write m
1422 209 storres
    in binary (i.e. ceil(log2(m))).
1423 209 storres
    """
1424 209 storres
    #TODO: take care of the special case: 0, @NaN@, @Inf@
1425 200 storres
    precisionSo = sollya_lib_precision(ctExpSo)
1426 200 storres
    precisionSa = pobyso_constant_from_int_so_sa(precisionSo)
1427 200 storres
    sollya_lib_clear_obj(precisionSo)
1428 200 storres
    return precisionSa
1429 200 storres
# End pobyso_precision_so_sa
1430 215 storres
1431 217 storres
def pobyso_polynomial_coefficients_progressive_round_so_so(polySo,
1432 217 storres
                                                           funcSo,
1433 217 storres
                                                           icSo,
1434 217 storres
                                                           intervalSo,
1435 217 storres
                                                           itpSo,
1436 217 storres
                                                           ftpSo,
1437 217 storres
                                                           maxPrecSo,
1438 219 storres
                                                           maxErrSo,
1439 219 storres
                                                           debug=False):
1440 219 storres
    if debug:
1441 219 storres
        print "Input arguments:"
1442 219 storres
        pobyso_autoprint(polySo)
1443 219 storres
        pobyso_autoprint(funcSo)
1444 219 storres
        pobyso_autoprint(icSo)
1445 219 storres
        pobyso_autoprint(intervalSo)
1446 219 storres
        pobyso_autoprint(itpSo)
1447 219 storres
        pobyso_autoprint(ftpSo)
1448 219 storres
        pobyso_autoprint(maxPrecSo)
1449 219 storres
        pobyso_autoprint(maxErrSo)
1450 219 storres
        print "________________"
1451 200 storres
1452 217 storres
    ## Higher order function see:
1453 217 storres
    #  http://effbot.org/pyfaq/how-do-you-make-a-higher-order-function-in-python.htm
1454 217 storres
    def precision_decay_ratio_function(degreeSa):
1455 217 storres
        def outer(x):
1456 217 storres
            def inner(x):
1457 217 storres
                we = 3/8
1458 217 storres
                wq = 2/8
1459 217 storres
                a  = 2.2
1460 217 storres
                b  = 2
1461 217 storres
                return we*(exp(x/a)-1) +  wq*((b*x)**2) + (1-we-wq)*x
1462 217 storres
            return  inner(x)/inner(degreeSa)
1463 217 storres
        return outer
1464 217 storres
1465 217 storres
    #
1466 217 storres
    degreeSa        = pobyso_polynomial_degree_so_sa(polySo)
1467 217 storres
    ratio           = precision_decay_ratio_function(degreeSa)
1468 217 storres
    itpSa           = pobyso_constant_from_int_so_sa(itpSo)
1469 217 storres
    ftpSa           = pobyso_constant_from_int_so_sa(ftpSo)
1470 217 storres
    maxPrecSa       = pobyso_constant_from_int_so_sa(maxPrecSo)
1471 217 storres
    maxErrSa        = pobyso_get_constant_as_rn_so_sa(maxErrSo)
1472 219 storres
    if debug:
1473 219 storres
        print "degreeSa:", degreeSa
1474 219 storres
        print "ratio:", ratio
1475 219 storres
        print "itpsSa:", itpSa
1476 219 storres
        print "ftpSa:", ftpSa
1477 219 storres
        print "maxPrecSa:", maxPrecSa
1478 219 storres
        print "maxErrSa:", maxErrSa
1479 217 storres
    lastResPolySo   = None
1480 218 storres
    lastInfNormSo   = None
1481 219 storres
    #print "About to enter the while loop..."
1482 217 storres
    while True:
1483 218 storres
        resPolySo   = pobyso_constant_0_sa_so()
1484 217 storres
        pDeltaSa    = ftpSa - itpSa
1485 217 storres
        for indexSa in reversed(xrange(0,degreeSa+1)):
1486 218 storres
            #print "Index:", indexSa
1487 217 storres
            indexSo = pobyso_constant_from_int_sa_so(indexSa)
1488 217 storres
            #pobyso_autoprint(indexSo)
1489 217 storres
            #print ratio(indexSa)
1490 217 storres
            ctpSa = floor(ftpSa - (pDeltaSa * ratio(indexSa)))
1491 217 storres
            ctpSo = pobyso_constant_from_int_sa_so(ctpSa)
1492 219 storres
            if debug:
1493 219 storres
                print "Index:", indexSa, " - Target precision:",
1494 219 storres
                pobyso_autoprint(ctpSo)
1495 217 storres
            cmonSo  = \
1496 217 storres
                sollya_lib_build_function_mul(sollya_lib_coeff(polySo, indexSo),
1497 217 storres
                                      sollya_lib_build_function_pow( \
1498 217 storres
                                          sollya_lib_build_function_free_variable(), \
1499 217 storres
                                          indexSo))
1500 217 storres
            #pobyso_autoprint(cmonSo)
1501 217 storres
            cmonrSo = pobyso_round_coefficients_single_so_so(cmonSo, ctpSo)
1502 217 storres
            sollya_lib_clear_obj(cmonSo)
1503 217 storres
            #pobyso_autoprint(cmonrSo)
1504 217 storres
            resPolySo = sollya_lib_build_function_add(resPolySo,
1505 217 storres
                                                      cmonrSo)
1506 218 storres
            #pobyso_autoprint(resPolySo)
1507 217 storres
        # End for index
1508 217 storres
        freeVarSo     = sollya_lib_build_function_free_variable()
1509 217 storres
        changeVarSo   = sollya_lib_sub(freeVarSo, icSo)
1510 217 storres
        resPolyCvSo   = sollya_lib_evaluate(resPolySo, changeVarSo)
1511 218 storres
        errFuncSo = sollya_lib_build_function_sub(sollya_lib_copy_obj(funcSo),
1512 218 storres
                                                  resPolyCvSo)
1513 218 storres
        infNormSo = sollya_lib_dirtyinfnorm(errFuncSo, intervalSo)
1514 217 storres
        cerrSa    = pobyso_get_constant_as_rn_so_sa(infNormSo)
1515 219 storres
        if debug:
1516 219 storres
            print "Infnorm (Sollya):",
1517 219 storres
            pobyso_autoprint(infNormSo)
1518 218 storres
        sollya_lib_clear_obj(errFuncSo)
1519 218 storres
        #print "Infnorm  (Sage):", cerrSa
1520 217 storres
        if (cerrSa > maxErrSa):
1521 219 storres
            if debug:
1522 219 storres
                print "Error is too large."
1523 218 storres
            if lastResPolySo is None:
1524 219 storres
                if debug:
1525 219 storres
                    print "Enlarging prec."
1526 217 storres
                ntpSa = floor(ftpSa + ftpSa/50)
1527 217 storres
                ## Can't enlarge (numerical)
1528 217 storres
                if ntpSa == ftpSa:
1529 217 storres
                    sollya_lib_clear_obj(resPolySo)
1530 217 storres
                    return None
1531 217 storres
                ## Can't enlarge (not enough precision left)
1532 217 storres
                if ntpSa > maxPrecSa:
1533 217 storres
                    sollya_lib_clear_obj(resPolySo)
1534 217 storres
                    return None
1535 217 storres
                ftpSa = ntpSa
1536 217 storres
                continue
1537 217 storres
            ## One enlargement took place.
1538 217 storres
            else:
1539 219 storres
                if debug:
1540 219 storres
                    print "Exit with the last before last polynomial."
1541 222 storres
                    print "Precision of highest degree monomial:", itpSa
1542 222 storres
                    print "Precision of constant term          :", ftpSa
1543 217 storres
                sollya_lib_clear_obj(resPolySo)
1544 218 storres
                sollya_lib_clear_obj(infNormSo)
1545 218 storres
                return (lastResPolySo, lastInfNormSo)
1546 218 storres
        # cerrSa <= maxErrSa: scrap more bits, possibly.
1547 217 storres
        else:
1548 219 storres
            if debug:
1549 219 storres
                print "Error is too small"
1550 219 storres
            if cerrSa <= (maxErrSa/2):
1551 219 storres
                if debug:
1552 219 storres
                    print "Shrinking prec."
1553 218 storres
                ntpSa = floor(ftpSa - ftpSa/50)
1554 218 storres
                ## Can't shrink (numerical)
1555 218 storres
                if ntpSa == ftpSa:
1556 218 storres
                    if not lastResPolySo is None:
1557 218 storres
                        sollya_lib_clear_obj(lastResPolySo)
1558 218 storres
                    if not lastInfNormSo is None:
1559 218 storres
                        sollya_lib_clear_obj(lastInfNormSo)
1560 222 storres
                    if debug:
1561 222 storres
                        print "Exit because can't shrink anymore (numerically)."
1562 222 storres
                        print "Precision of highest degree monomial:", itpSa
1563 222 storres
                        print "Precision of constant term          :", ftpSa
1564 218 storres
                    return (resPolySo, infNormSo)
1565 218 storres
                ## Can't shrink (not enough precision left)
1566 218 storres
                if ntpSa <= itpSa:
1567 218 storres
                    if not lastResPolySo is None:
1568 218 storres
                        sollya_lib_clear_obj(lastResPolySo)
1569 218 storres
                    if not lastInfNormSo is None:
1570 218 storres
                        sollya_lib_clear_obj(lastInfNormSo)
1571 222 storres
                        print "Exit because can't shrink anymore (no bits left)."
1572 222 storres
                        print "Precision of highest degree monomial:", itpSa
1573 222 storres
                        print "Precision of constant term          :", ftpSa
1574 218 storres
                    return (resPolySo, infNormSo)
1575 218 storres
                ftpSa = ntpSa
1576 217 storres
                if not lastResPolySo is None:
1577 217 storres
                    sollya_lib_clear_obj(lastResPolySo)
1578 218 storres
                if not lastInfNormSo is None:
1579 218 storres
                    sollya_lib_clear_obj(lastInfNormSo)
1580 218 storres
                lastResPolySo = resPolySo
1581 218 storres
                lastInfNormSo = infNormSo
1582 218 storres
                continue
1583 218 storres
            else: # Error is not that small, just return
1584 217 storres
                if not lastResPolySo is None:
1585 217 storres
                    sollya_lib_clear_obj(lastResPolySo)
1586 218 storres
                if not lastInfNormSo is None:
1587 218 storres
                    sollya_lib_clear_obj(lastInfNormSo)
1588 222 storres
                if debug:
1589 222 storres
                    print "Exit normally."
1590 222 storres
                    print "Precision of highest degree monomial:", itpSa
1591 222 storres
                    print "Precision of constant term          :", ftpSa
1592 218 storres
                return (resPolySo, infNormSo)
1593 217 storres
    # End wile True
1594 215 storres
    return None
1595 217 storres
# End pobyso_polynomial_coefficients_progressive_truncate_so_so.
1596 217 storres
1597 217 storres
def pobyso_polynomial_degree_so_sa(polySo):
1598 217 storres
    """
1599 217 storres
    Return the degree of a Sollya polynomial as a Sage int.
1600 217 storres
    """
1601 217 storres
    degreeSo = sollya_lib_degree(polySo)
1602 217 storres
    return pobyso_constant_from_int_so_sa(degreeSo)
1603 217 storres
# End pobyso_polynomial_degree_so_sa
1604 217 storres
1605 217 storres
def pobyso_polynomial_degree_so_so(polySo):
1606 217 storres
    """
1607 217 storres
    Thin wrapper around lib_sollya_degree().
1608 217 storres
    """
1609 217 storres
    return sollya_lib_degree(polySo)
1610 217 storres
# End pobyso_polynomial_degree_so_so
1611 217 storres
1612 5 storres
def pobyso_range(rnLowerBound, rnUpperBound):
1613 38 storres
    """ Legacy function. See pobyso_range_sa_so. """
1614 209 storres
    return pobyso_range_sa_so(rnLowerBound, rnUpperBound)
1615 38 storres
1616 226 storres
def pobyso_range_from_bounds_sa_so(rnLowerBound, rnUpperBound, precSa = None):
1617 226 storres
    """
1618 226 storres
    Create a Sollya range from 2 Sage real numbers as bounds
1619 226 storres
    """
1620 226 storres
    # TODO check precision stuff.
1621 226 storres
    sollyaPrecChanged = False
1622 226 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = \
1623 226 storres
        pobyso_get_prec_so_so_sa()
1624 226 storres
    if precSa is None:
1625 226 storres
        precSa = max(rnLowerBound.parent().prec(), rnUpperBound.parent().prec())
1626 226 storres
    if precSa > initialSollyaPrecSa:
1627 226 storres
        if precSa <= 2:
1628 226 storres
            print inspect.stack()[0][3], ": precision change <= 2 requested."
1629 226 storres
        pobyso_set_prec_sa_so(precSa)
1630 226 storres
        sollyaPrecChanged = True
1631 226 storres
    rangeSo = sollya_lib_range_from_bounds(get_rn_value(rnLowerBound),
1632 226 storres
                                           get_rn_value(rnUpperBound))
1633 226 storres
    if sollyaPrecChanged:
1634 226 storres
        pobyso_set_prec_so_so(initialSollyaPrecSo)
1635 234 storres
        sollya_lib_clear_obj(initialSollyaPrecSo)
1636 226 storres
    return rangeSo
1637 226 storres
# End pobyso_range_from_bounds_sa_so
1638 5 storres
1639 261 storres
def pobyso_range_list_so_sa(listSo):
1640 261 storres
    """
1641 261 storres
    Return a Sollya list of ranges as a Sage list of
1642 261 storres
    floating-point intervals.
1643 261 storres
    """
1644 261 storres
    listSa   = []
1645 261 storres
    ## The function returns none if the list is empty or an error has happened.
1646 261 storres
    retVal = pobyso_get_list_elements_so_so(listSo)
1647 261 storres
    if retVal is None:
1648 261 storres
        return listSa
1649 261 storres
    ## Just in case the interface is changed and an empty list is returned
1650 261 storres
    #  instead of None.
1651 261 storres
    elif len(retVal) == 0:
1652 261 storres
        return listSa
1653 261 storres
    else:
1654 261 storres
        ## Remember pobyso_get_list_elements_so_so returns more information
1655 261 storres
        #  than just the elements of the list (# elements, is_elliptic)
1656 261 storres
        listSaSo, numElements, isEndElliptic = retVal
1657 261 storres
    ## Return an empty list.
1658 261 storres
    if numElements == 0:
1659 261 storres
        return listSa
1660 261 storres
    ## Search first for the maximum precision of the elements
1661 261 storres
    maxPrecSa = 0
1662 261 storres
    for rangeSo in listSaSo:
1663 261 storres
        #pobyso_autoprint(floatSo)
1664 261 storres
        curPrecSa =  pobyso_get_prec_of_range_so_sa(rangeSo)
1665 261 storres
        if curPrecSa > maxPrecSa:
1666 261 storres
            maxPrecSa = curPrecSa
1667 261 storres
    ##
1668 261 storres
    intervalField = RealIntervalField(maxPrecSa)
1669 261 storres
    ##
1670 261 storres
    for rangeSo in listSaSo:
1671 261 storres
        listSa.append(pobyso_range_to_interval_so_sa(rangeSo, intervalField))
1672 261 storres
    return listSa
1673 261 storres
# End pobyso_range_list_so_sa
1674 261 storres
1675 226 storres
def pobyso_range_max_abs_so_so(rangeSo):
1676 226 storres
    """
1677 226 storres
    Return, as Sollya constant, the maximum absolute value of a Sollay range.
1678 226 storres
    """
1679 226 storres
    lowerBoundSo = sollya_lib_inf(rangeSo)
1680 226 storres
    upperBoundSo = sollya_lib_sup(rangeSo)
1681 226 storres
    #
1682 226 storres
    lowerBoundSo = sollya_lib_build_function_abs(lowerBoundSo)
1683 226 storres
    upperBoundSo = sollya_lib_build_function_abs(upperBoundSo)
1684 226 storres
    #pobyso_autoprint(lowerBoundSo)
1685 226 storres
    #pobyso_autoprint(upperBoundSo)
1686 226 storres
    #
1687 226 storres
    maxAbsSo = sollya_lib_max(lowerBoundSo, upperBoundSo, None)
1688 226 storres
    #sollya_lib_clear_obj(lowerBoundSo)
1689 226 storres
    #sollya_lib_clear_obj(upperBoundSo)
1690 226 storres
    return maxAbsSo
1691 226 storres
# End pobyso_range_max_abs_so_so
1692 226 storres
1693 85 storres
def pobyso_range_to_interval_so_sa(rangeSo, realIntervalFieldSa = None):
1694 83 storres
    """
1695 83 storres
    Get a Sage interval from a Sollya range.
1696 83 storres
    If no realIntervalField is given as a parameter, the Sage interval
1697 83 storres
    precision is that of the Sollya range.
1698 85 storres
    Otherwise, the precision is that of the realIntervalField. In this case
1699 85 storres
    rounding may happen.
1700 83 storres
    """
1701 85 storres
    if realIntervalFieldSa is None:
1702 56 storres
        precSa = pobyso_get_prec_of_range_so_sa(rangeSo)
1703 85 storres
        realIntervalFieldSa = RealIntervalField(precSa)
1704 56 storres
    intervalSa = \
1705 85 storres
        pobyso_get_interval_from_range_so_sa(rangeSo, realIntervalFieldSa)
1706 209 storres
    return intervalSa
1707 209 storres
# End pobyso_range_to_interval_so_sa
1708 240 storres
#
1709 240 storres
def pobyso_relative_so_so():
1710 240 storres
    """
1711 240 storres
    Very thin wrapper around the sollya_lib_relative function.
1712 240 storres
    """
1713 240 storres
    return sollya_lib_relative()
1714 240 storres
# End pobyso_relative_so_so
1715 240 storres
#
1716 209 storres
def pobyso_rat_poly_sa_so(polySa, precSa = None):
1717 209 storres
    """
1718 209 storres
    Create a Sollya polynomial from a Sage rational polynomial.
1719 272 storres
    We first convert the rational polynomial into a floating-point
1720 272 storres
    polynomial.
1721 209 storres
    """
1722 209 storres
    ## TODO: filter arguments.
1723 209 storres
    ## Precision. If no precision is given, use the current precision
1724 209 storres
    #  of Sollya.
1725 209 storres
    if precSa is None:
1726 209 storres
        precSa =  pobyso_get_prec_so_sa()
1727 209 storres
    #print "Precision:",  precSa
1728 209 storres
    RRR = RealField(precSa)
1729 209 storres
    ## Create a Sage polynomial in the "right" precision.
1730 209 storres
    P_RRR = RRR[polySa.variables()[0]]
1731 209 storres
    polyFloatSa = P_RRR(polySa)
1732 213 storres
    ## Make sure no precision is provided: pobyso_float_poly_sa_so will
1733 272 storres
    #  recover it all by itself and will not make any extra conversion.
1734 209 storres
    return pobyso_float_poly_sa_so(polyFloatSa)
1735 209 storres
1736 209 storres
# End pobyso_rat_poly_sa_so
1737 209 storres
1738 52 storres
def pobyso_remez_canonical_sa_sa(func, \
1739 52 storres
                                 degree, \
1740 52 storres
                                 lowerBound, \
1741 52 storres
                                 upperBound, \
1742 52 storres
                                 weight = None, \
1743 52 storres
                                 quality = None):
1744 52 storres
    """
1745 52 storres
    All arguments are Sage/Python.
1746 52 storres
    The functions (func and weight) must be passed as expressions or strings.
1747 52 storres
    Otherwise the function fails.
1748 83 storres
    The return value is a Sage polynomial.
1749 52 storres
    """
1750 83 storres
    var('zorglub')    # Dummy variable name for type check only. Type of
1751 83 storres
    # zorglub is "symbolic expression".
1752 52 storres
    polySo = pobyso_remez_canonical_sa_so(func, \
1753 52 storres
                                 degree, \
1754 52 storres
                                 lowerBound, \
1755 52 storres
                                 upperBound, \
1756 85 storres
                                 weight, \
1757 85 storres
                                 quality)
1758 83 storres
    # String test
1759 52 storres
    if parent(func) == parent("string"):
1760 52 storres
        functionSa = eval(func)
1761 52 storres
    # Expression test.
1762 52 storres
    elif type(func) == type(zorglub):
1763 52 storres
        functionSa = func
1764 83 storres
    else:
1765 83 storres
        return None
1766 83 storres
    #
1767 52 storres
    maxPrecision = 0
1768 52 storres
    if polySo is None:
1769 52 storres
        return(None)
1770 52 storres
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
1771 85 storres
    RRRRSa = RealField(maxPrecision)
1772 85 storres
    polynomialRingSa = RRRRSa[functionSa.variables()[0]]
1773 85 storres
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, RRRRSa)
1774 85 storres
    polySa = polynomial(expSa, polynomialRingSa)
1775 83 storres
    sollya_lib_clear_obj(polySo)
1776 52 storres
    return(polySa)
1777 85 storres
# End pobyso_remez_canonical_sa_sa
1778 52 storres
1779 38 storres
def pobyso_remez_canonical(func, \
1780 5 storres
                           degree, \
1781 5 storres
                           lowerBound, \
1782 5 storres
                           upperBound, \
1783 38 storres
                           weight = "1", \
1784 5 storres
                           quality = None):
1785 38 storres
    """ Legacy function. See pobyso_remez_canonical_sa_so. """
1786 51 storres
    return(pobyso_remez_canonical_sa_so(func, \
1787 51 storres
                                        degree, \
1788 51 storres
                                        lowerBound, \
1789 51 storres
                                        upperBound, \
1790 51 storres
                                        weight, \
1791 51 storres
                                        quality))
1792 200 storres
# End pobyso_remez_canonical.
1793 200 storres
1794 38 storres
def pobyso_remez_canonical_sa_so(func, \
1795 38 storres
                                 degree, \
1796 38 storres
                                 lowerBound, \
1797 38 storres
                                 upperBound, \
1798 52 storres
                                 weight = None, \
1799 38 storres
                                 quality = None):
1800 38 storres
    """
1801 38 storres
    All arguments are Sage/Python.
1802 51 storres
    The functions (func and weight) must be passed as expressions or strings.
1803 51 storres
    Otherwise the function fails.
1804 38 storres
    The return value is a pointer to a Sollya function.
1805 234 storres
    lowerBound and upperBound mus be reals.
1806 38 storres
    """
1807 83 storres
    var('zorglub')    # Dummy variable name for type check only. Type of
1808 83 storres
    # zorglub is "symbolic expression".
1809 85 storres
    currentVariableNameSa = None
1810 52 storres
    # The func argument can be of different types (string,
1811 52 storres
    # symbolic expression...)
1812 38 storres
    if parent(func) == parent("string"):
1813 234 storres
        localFuncSa = sage_eval(func,globals())
1814 85 storres
        if len(localFuncSa.variables()) > 0:
1815 85 storres
            currentVariableNameSa = localFuncSa.variables()[0]
1816 85 storres
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1817 159 storres
            functionSo = \
1818 159 storres
              sollya_lib_parse_string(localFuncSa._assume_str().replace('_SAGE_VAR_', ''))
1819 51 storres
    # Expression test.
1820 52 storres
    elif type(func) == type(zorglub):
1821 52 storres
        # Until we are able to translate Sage expressions into Sollya
1822 52 storres
        # expressions : parse the string version.
1823 85 storres
        if len(func.variables()) > 0:
1824 85 storres
            currentVariableNameSa = func.variables()[0]
1825 85 storres
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1826 159 storres
            functionSo = \
1827 159 storres
              sollya_lib_parse_string(func._assume_str().replace('_SAGE_VAR_', ''))
1828 38 storres
    else:
1829 38 storres
        return(None)
1830 85 storres
    if weight is None: # No weight given -> 1.
1831 52 storres
        weightSo = pobyso_constant_1_sa_so()
1832 85 storres
    elif parent(weight) == parent("string"): # Weight given as string: parse it.
1833 51 storres
        weightSo = sollya_lib_parse_string(func)
1834 85 storres
    elif type(weight) == type(zorglub): # Weight given as symbolice expression.
1835 159 storres
        functionSo = \
1836 159 storres
          sollya_lib_parse_string_sa_so(weight._assume_str().replace('_SAGE_VAR_', ''))
1837 51 storres
    else:
1838 51 storres
        return(None)
1839 5 storres
    degreeSo = pobyso_constant_from_int(degree)
1840 85 storres
    rangeSo = pobyso_bounds_to_range_sa_so(lowerBound, upperBound)
1841 38 storres
    if not quality is None:
1842 38 storres
        qualitySo= pobyso_constant_sa_so(quality)
1843 52 storres
    else:
1844 52 storres
        qualitySo = None
1845 83 storres
1846 83 storres
    remezPolySo = sollya_lib_remez(functionSo, \
1847 83 storres
                                   degreeSo, \
1848 83 storres
                                   rangeSo, \
1849 83 storres
                                   weightSo, \
1850 83 storres
                                   qualitySo, \
1851 83 storres
                                   None)
1852 83 storres
    sollya_lib_clear_obj(functionSo)
1853 83 storres
    sollya_lib_clear_obj(degreeSo)
1854 83 storres
    sollya_lib_clear_obj(rangeSo)
1855 83 storres
    sollya_lib_clear_obj(weightSo)
1856 83 storres
    if not qualitySo is None:
1857 85 storres
        sollya_lib_clear_obj(qualitySo)
1858 83 storres
    return(remezPolySo)
1859 83 storres
# End pobyso_remez_canonical_sa_so
1860 83 storres
1861 38 storres
def pobyso_remez_canonical_so_so(funcSo, \
1862 38 storres
                                 degreeSo, \
1863 38 storres
                                 rangeSo, \
1864 52 storres
                                 weightSo = pobyso_constant_1_sa_so(),\
1865 38 storres
                                 qualitySo = None):
1866 38 storres
    """
1867 38 storres
    All arguments are pointers to Sollya objects.
1868 38 storres
    The return value is a pointer to a Sollya function.
1869 38 storres
    """
1870 38 storres
    if not sollya_lib_obj_is_function(funcSo):
1871 38 storres
        return(None)
1872 38 storres
    return(sollya_lib_remez(funcSo, degreeSo, rangeSo, weightSo, qualitySo, None))
1873 200 storres
# End pobyso_remez_canonical_so_so.
1874 200 storres
1875 237 storres
def pobyso_remez_exponents_list_sa_so(func,     \
1876 237 storres
                                 exponentsList, \
1877 237 storres
                                 lowerBound,    \
1878 237 storres
                                 upperBound,    \
1879 237 storres
                                 weight = None, \
1880 237 storres
                                 quality = None):
1881 237 storres
    """
1882 237 storres
    All arguments are Sage/Python.
1883 237 storres
    The functions (func and weight) must be passed as expressions or strings.
1884 237 storres
    Otherwise the function fails.
1885 237 storres
    The return value is a pointer to a Sollya function.
1886 237 storres
    lowerBound and upperBound mus be reals.
1887 237 storres
    """
1888 237 storres
    var('zorglub')    # Dummy variable name for type check only. Type of
1889 237 storres
    # zorglub is "symbolic expression".
1890 237 storres
    currentVariableNameSa = None
1891 237 storres
    # The func argument can be of different types (string,
1892 237 storres
    # symbolic expression...)
1893 237 storres
    if parent(func) == parent("string"):
1894 237 storres
        localFuncSa = sage_eval(func,globals())
1895 237 storres
        if len(localFuncSa.variables()) > 0:
1896 237 storres
            currentVariableNameSa = localFuncSa.variables()[0]
1897 237 storres
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1898 237 storres
            functionSo = \
1899 237 storres
              sollya_lib_parse_string(localFuncSa._assume_str().replace('_SAGE_VAR_', ''))
1900 237 storres
    # Expression test.
1901 237 storres
    elif type(func) == type(zorglub):
1902 237 storres
        # Until we are able to translate Sage expressions into Sollya
1903 237 storres
        # expressions : parse the string version.
1904 237 storres
        if len(func.variables()) > 0:
1905 237 storres
            currentVariableNameSa = func.variables()[0]
1906 237 storres
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1907 237 storres
            functionSo = \
1908 237 storres
              sollya_lib_parse_string(func._assume_str().replace('_SAGE_VAR_', ''))
1909 237 storres
    else:
1910 237 storres
        return(None)
1911 237 storres
    ## Deal with the weight, much in the same way as with the function.
1912 237 storres
    if weight is None: # No weight given -> 1.
1913 237 storres
        weightSo = pobyso_constant_1_sa_so()
1914 237 storres
    elif parent(weight) == parent("string"): # Weight given as string: parse it.
1915 237 storres
        weightSo = sollya_lib_parse_string(func)
1916 237 storres
    elif type(weight) == type(zorglub): # Weight given as symbolice expression.
1917 237 storres
        functionSo = \
1918 237 storres
          sollya_lib_parse_string(weight._assume_str().replace('_SAGE_VAR_', '',100))
1919 237 storres
    else:
1920 237 storres
        return(None)
1921 237 storres
    rangeSo = pobyso_bounds_to_range_sa_so(lowerBound, upperBound)
1922 237 storres
    if not quality is None:
1923 237 storres
        qualitySo= pobyso_constant_sa_so(quality)
1924 237 storres
    else:
1925 237 storres
        qualitySo = None
1926 237 storres
    #
1927 237 storres
    ## Tranform the Sage list of exponents into a Sollya list.
1928 237 storres
    exponentsListSo = pobyso_build_list_of_ints_sa_so(*exponentsList)
1929 278 storres
    remezPolySo = sollya_lib_remez(functionSo,      \
1930 237 storres
                                   exponentsListSo, \
1931 278 storres
                                   rangeSo,         \
1932 278 storres
                                   weightSo,        \
1933 278 storres
                                   qualitySo,       \
1934 237 storres
                                   None)
1935 237 storres
    sollya_lib_clear_obj(functionSo)
1936 237 storres
    sollya_lib_clear_obj(exponentsListSo)
1937 237 storres
    sollya_lib_clear_obj(rangeSo)
1938 237 storres
    sollya_lib_clear_obj(weightSo)
1939 237 storres
    if not qualitySo is None:
1940 237 storres
        sollya_lib_clear_obj(qualitySo)
1941 237 storres
    return(remezPolySo)
1942 237 storres
# End pobyso_remez_exponentsList_sa_so
1943 240 storres
#
1944 240 storres
def pobyso_round_coefficients_so_so(polySo, truncFormatListSo):
1945 240 storres
    """
1946 240 storres
    A wrapper around the "classical" sollya_lib_roundcoefficients: a Sollya
1947 240 storres
    polynomial and a Sollya list are given as arguments.
1948 240 storres
    """
1949 240 storres
    return sollya_lib_roundcoefficients(polySo, truncFormatListSo)
1950 237 storres
1951 224 storres
def pobyso_round_coefficients_progressive_so_so(polySo,
1952 224 storres
                                                funcSo,
1953 224 storres
                                                precSo,
1954 224 storres
                                                intervalSo,
1955 224 storres
                                                icSo,
1956 224 storres
                                                currentApproxErrorSo,
1957 224 storres
                                                approxAccurSo,
1958 224 storres
                                                debug=False):
1959 272 storres
    """
1960 272 storres
    From an input approximation polynomial, compute an output one with
1961 272 storres
    smaller coefficients and yet yields a sufficient approximation accuracy.
1962 272 storres
    """
1963 223 storres
    if debug:
1964 223 storres
        print "Input arguments:"
1965 228 storres
        print "Polynomial: ", ; pobyso_autoprint(polySo)
1966 228 storres
        print "Function: ", ; pobyso_autoprint(funcSo)
1967 228 storres
        print "Internal precision: ", ; pobyso_autoprint(precSo)
1968 228 storres
        print "Interval: ", ; pobyso_autoprint(intervalSo)
1969 228 storres
        print "Current approximation error: ", ; pobyso_autoprint(currentApproxErrorSo)
1970 228 storres
        print "Requested approxiation error: ", ; pobyso_autoprint(approxAccurSo)
1971 223 storres
        print "________________"
1972 223 storres
    approxAccurSa        = pobyso_get_constant_as_rn_so_sa(approxAccurSo)
1973 223 storres
    currentApproxErrorSa = pobyso_get_constant_as_rn_so_sa(currentApproxErrorSo)
1974 223 storres
    ## If the current approximation error is too close to the target, there is
1975 223 storres
    #  no possible gain.
1976 223 storres
    if currentApproxErrorSa >= approxAccurSa / 2:
1977 232 storres
        #### Do not return the initial argument but copies: caller may free
1978 272 storres
        #    the former as inutile after call.
1979 232 storres
        return (sollya_lib_copy_obj(polySo),
1980 232 storres
                sollya_lib_copy_obj(currentApproxErrorSo))
1981 278 storres
    #
1982 278 storres
    ## Try to round the coefficients.
1983 223 storres
    degreeSa             = pobyso_polynomial_degree_so_sa(polySo)
1984 223 storres
    intervalSa           = pobyso_range_to_interval_so_sa(intervalSo)
1985 223 storres
1986 223 storres
    if debug:
1987 228 storres
        print "degreeSa              :", degreeSa
1988 228 storres
        print "intervalSa            :", intervalSa.str(style='brackets')
1989 223 storres
        print "currentApproxErrorSa  :", currentApproxErrorSa
1990 228 storres
        print "approxAccurSa         :", approxAccurSa
1991 223 storres
    radiusSa = intervalSa.absolute_diameter() / 2
1992 223 storres
    if debug:
1993 224 storres
        print "log2(radius):", RR(radiusSa).log2()
1994 224 storres
    iterIndex = 0
1995 272 storres
    ## Build the "shaved" polynomial.
1996 224 storres
    while True:
1997 272 storres
        ### Start with a 0 value expression.
1998 224 storres
        resPolySo = pobyso_constant_0_sa_so()
1999 224 storres
        roundedPolyApproxAccurSa = approxAccurSa / 2
2000 224 storres
        currentRadiusPowerSa = 1
2001 224 storres
        for degree in xrange(0,degreeSa + 1):
2002 224 storres
            #### At round 0, use the agressive formula. At round 1, run the
2003 224 storres
            #    proved formula.
2004 224 storres
            if iterIndex == 0:
2005 224 storres
                roundingPowerSa = \
2006 224 storres
                    floor(((currentRadiusPowerSa/roundedPolyApproxAccurSa)*(degree+1)).log2())
2007 224 storres
            else:
2008 224 storres
                roundingPowerSa = \
2009 224 storres
                    floor(((currentRadiusPowerSa/roundedPolyApproxAccurSa)*(degreeSa+1)).log2())
2010 272 storres
            ## Under extreme conditions the above formulas can evaluate under 2,
2011 272 storres
            #   which is the minimal precision of an MPFR number.
2012 228 storres
            if roundingPowerSa < 2:
2013 228 storres
                roundingPowerSa = 2
2014 224 storres
            if debug:
2015 224 storres
                print "roundedPolyApproxAccurSa", roundedPolyApproxAccurSa
2016 224 storres
                print "currentRadiusPowerSa", currentRadiusPowerSa
2017 224 storres
                print "Current rounding exponent:", roundingPowerSa
2018 224 storres
            currentRadiusPowerSa *= radiusSa
2019 224 storres
            index1So = pobyso_constant_from_int_sa_so(degree)
2020 224 storres
            index2So = pobyso_constant_from_int_sa_so(degree)
2021 224 storres
            ### Create a monomial with:
2022 224 storres
            #   - the coefficient in the initial monomial at the current degrree;
2023 224 storres
            #   - the current exponent;
2024 224 storres
            #   - the free variable.
2025 224 storres
            cmonSo  = \
2026 224 storres
                sollya_lib_build_function_mul(sollya_lib_coeff(polySo, index1So),
2027 224 storres
                                              sollya_lib_build_function_pow( \
2028 224 storres
                                                sollya_lib_build_function_free_variable(), \
2029 224 storres
                                                index2So))
2030 224 storres
            roundingPowerSo = pobyso_constant_from_int_sa_so(roundingPowerSa)
2031 224 storres
            cmonrSo = pobyso_round_coefficients_single_so_so(cmonSo, roundingPowerSo)
2032 224 storres
            sollya_lib_clear_obj(cmonSo)
2033 224 storres
            ### Add to the result polynomial.
2034 224 storres
            resPolySo = sollya_lib_build_function_add(resPolySo,
2035 224 storres
                                                      cmonrSo)
2036 224 storres
        # End for.
2037 224 storres
        ### Check the new polynomial.
2038 224 storres
        freeVarSo     = sollya_lib_build_function_free_variable()
2039 224 storres
        changeVarSo   = sollya_lib_sub(freeVarSo, icSo)
2040 224 storres
        resPolyCvSo   = sollya_lib_evaluate(resPolySo, changeVarSo)
2041 224 storres
        errFuncSo     = sollya_lib_build_function_sub(sollya_lib_copy_obj(funcSo),
2042 224 storres
                                                      resPolyCvSo)
2043 224 storres
        infNormSo = sollya_lib_dirtyinfnorm(errFuncSo, intervalSo)
2044 224 storres
        ### This also clears resPolyCvSo.
2045 224 storres
        sollya_lib_clear_obj(errFuncSo)
2046 224 storres
        cerrSa    = pobyso_get_constant_as_rn_so_sa(infNormSo)
2047 223 storres
        if debug:
2048 224 storres
            print "Error of the new polynomial:", cerrSa
2049 224 storres
        ### If at round 1, return the initial polynomial error. This should
2050 224 storres
        #   never happen since the rounding algorithm is proved. But some
2051 224 storres
        #   circumstances may break it (e.g. internal precision of tools).
2052 224 storres
        if cerrSa > approxAccurSa:
2053 278 storres
            if iterIndex == 0: # Round 0 is agressive rounding, got round 1 (proved rounding)
2054 224 storres
                sollya_lib_clear_obj(resPolySo)
2055 224 storres
                sollya_lib_clear_obj(infNormSo)
2056 278 storres
                iterIndex += 1
2057 278 storres
                continue
2058 278 storres
            else: # Round 1 and beyond : just return the oroginal polynomial.
2059 278 storres
                sollya_lib_clear_obj(resPolySo)
2060 278 storres
                sollya_lib_clear_obj(infNormSo)
2061 232 storres
                #### Do not return the arguments but copies: the caller may free
2062 232 storres
                #    free the former as inutile after call.
2063 232 storres
                return (sollya_lib_copy_obj(polySo),
2064 232 storres
                        sollya_lib_copy_obj(currentApproxErrorSo))
2065 224 storres
        ### If get here it is because cerrSa <= approxAccurSa
2066 224 storres
        ### Approximation error of the new polynomial is acceptable.
2067 224 storres
        return (resPolySo, infNormSo)
2068 224 storres
    # End while True
2069 224 storres
# End pobyso_round_coefficients_progressive_so_so
2070 223 storres
2071 240 storres
def pobyso_round_coefficients_single_so_so(polySo, commonPrecSo):
2072 215 storres
    """
2073 215 storres
    Create a rounded coefficients polynomial from polynomial argument to
2074 215 storres
    the number of bits in size argument.
2075 215 storres
    All coefficients are set to the same precision.
2076 215 storres
    """
2077 215 storres
    ## TODO: check arguments.
2078 240 storres
    endEllipListSo = pobyso_build_end_elliptic_list_so_so(commonPrecSo)
2079 215 storres
    polySo = sollya_lib_roundcoefficients(polySo, endEllipListSo, None)
2080 217 storres
    sollya_lib_clear_obj(endEllipListSo)
2081 215 storres
    #sollya_lib_clear_obj(endEllipListSo)
2082 215 storres
    return polySo
2083 215 storres
2084 215 storres
# End pobyso_round_coefficients_single_so_so
2085 215 storres
2086 5 storres
def pobyso_set_canonical_off():
2087 5 storres
    sollya_lib_set_canonical(sollya_lib_off())
2088 5 storres
2089 5 storres
def pobyso_set_canonical_on():
2090 5 storres
    sollya_lib_set_canonical(sollya_lib_on())
2091 5 storres
2092 5 storres
def pobyso_set_prec(p):
2093 38 storres
    """ Legacy function. See pobyso_set_prec_sa_so. """
2094 85 storres
    pobyso_set_prec_sa_so(p)
2095 38 storres
2096 38 storres
def pobyso_set_prec_sa_so(p):
2097 227 storres
    #a = c_int(p)
2098 226 storres
    #precSo = c_void_p(sollya_lib_constant_from_int(a))
2099 227 storres
    #precSo = sollya_lib_constant_from_int(a)
2100 227 storres
    precSo = pobyso_constant_from_int_sa_so(p)
2101 226 storres
    sollya_lib_set_prec(precSo)
2102 226 storres
    sollya_lib_clear_obj(precSo)
2103 215 storres
# End pobyso_set_prec_sa_so.
2104 5 storres
2105 85 storres
def pobyso_set_prec_so_so(newPrecSo):
2106 226 storres
    sollya_lib_set_prec(newPrecSo)
2107 215 storres
# End pobyso_set_prec_so_so.
2108 242 storres
#
2109 284 storres
def pobyso_supnorm_sa_sa(polySa,
2110 284 storres
                         funcSa,
2111 284 storres
                         intervalSa,
2112 284 storres
                         errorTypeSa=SOLLYA_ABSOLUTE,
2113 284 storres
                         accuracySa=RR(2^-40)):
2114 281 storres
    """
2115 284 storres
    An supnorm call with Sage arguments.
2116 281 storres
    """
2117 284 storres
    # Check that polySa is a univariate polynomial. We only check here at
2118 284 storres
    # expression level, not at polynomial ring level
2119 284 storres
    ## Make sure it is not a multivariate polynomial. The number of variables
2120 284 storres
    #  can be zero in the case of a constant.
2121 284 storres
    try:
2122 284 storres
        if len(polySa.free_variables()) > 1 :
2123 284 storres
            print "Invalid number of free variables in polySa:", polySa,
2124 284 storres
            " -", polySa.free_variables()
2125 284 storres
            return None
2126 284 storres
    except AttributeError:
2127 284 storres
        print "polySa is not a SymbolicExpression."
2128 284 storres
        return None
2129 284 storres
    ## Make sure it is a polynomial.
2130 284 storres
    if not polySa.is_polynomial(polySa.default_variable()):
2131 284 storres
        print "polySa is not a polynomila expression."
2132 284 storres
        return None
2133 284 storres
    # Check that funcSa is a function.
2134 284 storres
    if not \
2135 284 storres
     sage.symbolic.callable.is_CallableSymbolicExpressionRing(parent(funcSa)):
2136 284 storres
        return None
2137 284 storres
    # Check that intervalSa is an interval.
2138 284 storres
    try:
2139 284 storres
        intervalSa.upper()
2140 284 storres
    except AttributeError:
2141 284 storres
        print "intervalSa is not an interval."
2142 284 storres
        return None
2143 284 storres
    # Convert the Sage polynomial into a Sollya polynomial.
2144 284 storres
    polyAsStringSa = polySa._assume_str().replace('_SAGE_VAR_', '')
2145 284 storres
    polySo = pobyso_parse_string_sa_so(polyAsStringSa)
2146 284 storres
    if not pobyso_obj_is_function_so_sa(polySo):
2147 284 storres
        sollya_lib_clear_obj(polySo)
2148 284 storres
        print "The Sollya object created from the polynomial is not a function."
2149 284 storres
        return None
2150 284 storres
    #pobyso_autoprint(polySo)
2151 284 storres
    # Convert the Sage function into a Sollya function.
2152 284 storres
    funcAsStringSa = funcSa._assume_str().replace('_SAGE_VAR_', '')
2153 284 storres
    funcSo = pobyso_parse_string_sa_so(funcAsStringSa)
2154 284 storres
    if not pobyso_obj_is_function_so_sa(funcSo):
2155 284 storres
        sollya_lib_clear_obj(polySo)
2156 284 storres
        sollya_lib_clear_obj(funcSo)
2157 284 storres
        print "The Sollya object created from the function is not a function."
2158 284 storres
        return None
2159 284 storres
    #pobyso_autoprint(funcSo)
2160 284 storres
    # Convert the Sage interval into a Sollya range.
2161 284 storres
    rangeSo = pobyso_interval_to_range_sa_so(intervalSa)
2162 284 storres
    if not pobyso_is_range_so_sa(rangeSo):
2163 284 storres
        sollya_lib_clear_obj(polySo)
2164 284 storres
        sollya_lib_clear_obj(funcSo)
2165 284 storres
        sollya_lib_clear_obj(rangeSo)
2166 284 storres
        print "The Sollya object created from the interval is not a range."
2167 284 storres
        return None
2168 284 storres
    #pobyso_autoprint(rangeSo)
2169 284 storres
    # Check the error type. We do not check the returned object since we
2170 284 storres
    # trust our code and Sollya on this one.
2171 284 storres
    if errorTypeSa != SOLLYA_ABSOLUTE and errorTypeSa != SOLLYA_RELATIVE:
2172 284 storres
        sollya_lib_clear_obj(polySo)
2173 284 storres
        sollya_lib_clear_obj(funcSo)
2174 284 storres
        sollya_lib_clear_obj(rangeSo)
2175 284 storres
        return None
2176 284 storres
    if errorTypeSa == SOLLYA_ABSOLUTE:
2177 284 storres
        errorTypeSo = pobyso_absolute_so_so()
2178 284 storres
    else:
2179 284 storres
        errorTypeSo = pobyso_relative_so_so()
2180 284 storres
    #pobyso_autoprint(errorTypeSo)
2181 284 storres
    # Check if accuracySa is an element of a RealField. If not, try to
2182 284 storres
    # convert it.
2183 284 storres
    try:
2184 284 storres
        accuracySa.ulp()
2185 284 storres
    except AttributeError:
2186 284 storres
        try:
2187 284 storres
            accuracySa = RR(accuracySa)
2188 284 storres
        except TypeError:
2189 284 storres
            accuracySa = RR(str(accuracySa))
2190 284 storres
    # Create the Sollya object
2191 284 storres
    accuracySo = pobyso_constant_sa_so(accuracySa)
2192 284 storres
    #pobyso_autoprint(accuracySo)
2193 284 storres
    if pobyso_is_error_so_sa(accuracySo):
2194 284 storres
        sollya_lib_clear_obj(polySo)
2195 284 storres
        sollya_lib_clear_obj(funcSo)
2196 284 storres
        sollya_lib_clear_obj(rangeSo)
2197 284 storres
        sollya_lib_clear_obj(errorTypeSo)
2198 284 storres
        sollya_lib_clear_obj(accuracySo)
2199 284 storres
        return None
2200 284 storres
    retValSo = sollya_lib_supnorm(polySo,
2201 284 storres
                                  funcSo,
2202 284 storres
                                  rangeSo,
2203 284 storres
                                  errorTypeSo,
2204 284 storres
                                  accuracySo,
2205 284 storres
                                  None)
2206 284 storres
    sollya_lib_clear_obj(polySo)
2207 284 storres
    sollya_lib_clear_obj(funcSo)
2208 284 storres
    sollya_lib_clear_obj(rangeSo)
2209 284 storres
    sollya_lib_clear_obj(errorTypeSo)
2210 284 storres
    sollya_lib_clear_obj(accuracySo)
2211 284 storres
    if pobyso_is_error_so_sa(retValSo):
2212 284 storres
        sollya_lib_clear_obj(retValSo)
2213 284 storres
        return None
2214 284 storres
    #pobyso_autoprint(retValSo)
2215 284 storres
    retValSa = pobyso_range_to_interval_so_sa(retValSo)
2216 284 storres
    sollya_lib_clear_obj(retValSo)
2217 284 storres
    return retValSa
2218 281 storres
# End pobyso_supnorm_sa_sa
2219 281 storres
2220 242 storres
def pobyso_supnorm_so_sa(polySo, funcSo, intervalSo, errorTypeSo = None,\
2221 242 storres
                         accuracySo = None, realFieldSa = None):
2222 242 storres
    """
2223 281 storres
    Computes the supremum norm from Sollya input arguments and returns a
2224 242 storres
    Sage floating-point number whose precision is set by the only Sage argument.
2225 215 storres

2226 242 storres
    The returned value is the maximum of the absolute values of the range
2227 242 storres
    elements  returned by the Sollya supnorm functions
2228 242 storres
    """
2229 242 storres
    supNormRangeSo = pobyso_supnorm_so_so(polySo,
2230 242 storres
                                          funcSo,
2231 242 storres
                                          intervalSo,
2232 242 storres
                                          errorTypeSo,
2233 242 storres
                                          accuracySo)
2234 242 storres
    supNormSo = pobyso_range_max_abs_so_so(supNormRangeSo)
2235 242 storres
    sollya_lib_clear_obj(supNormRangeSo)
2236 242 storres
    #pobyso_autoprint(supNormSo)
2237 242 storres
    supNormSa = pobyso_get_constant_as_rn_with_rf_so_sa(supNormSo, realFieldSa)
2238 242 storres
    sollya_lib_clear_obj(supNormSo)
2239 242 storres
    return supNormSa
2240 242 storres
# End pobyso_supnorm_so_sa.
2241 242 storres
#
2242 85 storres
def pobyso_supnorm_so_so(polySo, funcSo, intervalSo, errorTypeSo = None,\
2243 85 storres
                         accuracySo = None):
2244 58 storres
    """
2245 85 storres
    Computes the supnorm of the approximation error between the given
2246 242 storres
    polynomial and function. Attention: returns a range!
2247 85 storres
    errorTypeSo defaults to "absolute".
2248 85 storres
    accuracySo defaults to 2^(-40).
2249 85 storres
    """
2250 85 storres
    if errorTypeSo is None:
2251 85 storres
        errorTypeSo = sollya_lib_absolute(None)
2252 85 storres
        errorTypeIsNone = True
2253 85 storres
    else:
2254 85 storres
        errorTypeIsNone = False
2255 85 storres
    #
2256 85 storres
    if accuracySo is None:
2257 237 storres
        # Notice the **: we are in Pythonland here!
2258 85 storres
        accuracySo = pobyso_constant_sa_so(RR(2**(-40)))
2259 85 storres
        accuracyIsNone = True
2260 85 storres
    else:
2261 85 storres
        accuracyIsNone = False
2262 238 storres
    #pobyso_autoprint(accuracySo)
2263 85 storres
    resultSo = \
2264 85 storres
        sollya_lib_supnorm(polySo, funcSo, intervalSo, errorTypeSo, \
2265 85 storres
                              accuracySo)
2266 85 storres
    if errorTypeIsNone:
2267 85 storres
        sollya_lib_clear_obj(errorTypeSo)
2268 85 storres
    if accuracyIsNone:
2269 85 storres
        sollya_lib_clear_obj(accuracySo)
2270 85 storres
    return resultSo
2271 85 storres
# End pobyso_supnorm_so_so
2272 242 storres
#
2273 162 storres
def pobyso_taylor_expansion_no_change_var_so_so(functionSo,
2274 162 storres
                                                degreeSo,
2275 162 storres
                                                rangeSo,
2276 162 storres
                                                errorTypeSo=None,
2277 162 storres
                                                sollyaPrecSo=None):
2278 85 storres
    """
2279 162 storres
    Compute the Taylor expansion without the variable change
2280 162 storres
    x -> x-intervalCenter.
2281 272 storres
    If errorTypeSo is None, absolute is used.
2282 272 storres
    If sollyaPrecSo is None, Sollya internal precision is not changed.
2283 58 storres
    """
2284 226 storres
    # Change internal Sollya precision, if needed.
2285 227 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = pobyso_get_prec_so_so_sa()
2286 226 storres
    sollyaPrecChanged = False
2287 226 storres
    if sollyaPrecSo is None:
2288 226 storres
        pass
2289 226 storres
    else:
2290 58 storres
        sollya_lib_set_prec(sollyaPrecSo)
2291 226 storres
        sollyaPrecChanged = True
2292 85 storres
    # Error type stuff: default to absolute.
2293 85 storres
    if errorTypeSo is None:
2294 85 storres
        errorTypeIsNone = True
2295 85 storres
        errorTypeSo = sollya_lib_absolute(None)
2296 85 storres
    else:
2297 85 storres
        errorTypeIsNone = False
2298 162 storres
    intervalCenterSo = sollya_lib_mid(rangeSo, None)
2299 162 storres
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo,
2300 162 storres
                                         intervalCenterSo,
2301 58 storres
                                         rangeSo, errorTypeSo, None)
2302 272 storres
    # Object taylorFormListSaSo is a Python list of Sollya objects references
2303 272 storres
    #  that are copies of the elements of taylorFormSo.
2304 117 storres
    # pobyso_get_list_elements_so_so clears taylorFormSo.
2305 162 storres
    (taylorFormListSaSo, numElementsSa, isEndEllipticSa) = \
2306 58 storres
        pobyso_get_list_elements_so_so(taylorFormSo)
2307 272 storres
    ## Copy needed here since polySo will be returned and taylorFormListSaSo
2308 272 storres
    #  will be cleared.
2309 162 storres
    polySo = sollya_lib_copy_obj(taylorFormListSaSo[0])
2310 162 storres
    #print "Num elements:", numElementsSa
2311 162 storres
    sollya_lib_clear_obj(taylorFormSo)
2312 181 storres
    # No copy_obj needed here: a new objects are created.
2313 272 storres
    maxErrorSo    = sollya_lib_sup(taylorFormListSaSo[2])
2314 272 storres
    minErrorSo    = sollya_lib_inf(taylorFormListSaSo[2])
2315 272 storres
    # List taylorFormListSaSo is not needed anymore.
2316 280 storres
    pobyso_clear_list_elements_sa_so(taylorFormListSaSo)
2317 181 storres
    absMaxErrorSo = sollya_lib_abs(maxErrorSo)
2318 181 storres
    absMinErrorSo = sollya_lib_abs(minErrorSo)
2319 181 storres
    sollya_lib_clear_obj(maxErrorSo)
2320 181 storres
    sollya_lib_clear_obj(minErrorSo)
2321 181 storres
    absMaxErrorSa = pobyso_get_constant_as_rn_so_sa(absMaxErrorSo)
2322 181 storres
    absMinErrorSa = pobyso_get_constant_as_rn_so_sa(absMinErrorSo)
2323 272 storres
    #
2324 272 storres
    if errorTypeIsNone:
2325 272 storres
        sollya_lib_clear_obj(errorTypeSo)
2326 272 storres
    ## If changed, reset the Sollya working precision.
2327 226 storres
    if sollyaPrecChanged:
2328 226 storres
        sollya_lib_set_prec(initialSollyaPrecSo)
2329 226 storres
    sollya_lib_clear_obj(initialSollyaPrecSo)
2330 272 storres
    ## According to what error is the largest, return the errors.
2331 181 storres
    if absMaxErrorSa > absMinErrorSa:
2332 181 storres
        sollya_lib_clear_obj(absMinErrorSo)
2333 227 storres
        return (polySo, intervalCenterSo, absMaxErrorSo)
2334 181 storres
    else:
2335 181 storres
        sollya_lib_clear_obj(absMaxErrorSo)
2336 227 storres
        return (polySo, intervalCenterSo, absMinErrorSo)
2337 162 storres
# end pobyso_taylor_expansion_no_change_var_so_so
2338 58 storres
2339 162 storres
def pobyso_taylor_expansion_with_change_var_so_so(functionSo, degreeSo, \
2340 162 storres
                                                  rangeSo, \
2341 162 storres
                                                  errorTypeSo=None, \
2342 162 storres
                                                  sollyaPrecSo=None):
2343 58 storres
    """
2344 162 storres
    Compute the Taylor expansion with the variable change
2345 162 storres
    x -> (x-intervalCenter) included.
2346 58 storres
    """
2347 226 storres
    # Change Sollya internal precision, if need.
2348 226 storres
    sollyaPrecChanged = False
2349 271 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = pobyso_get_prec_so_so_sa()
2350 226 storres
    if sollyaPrecSo is None:
2351 226 storres
        pass
2352 226 storres
    else:
2353 56 storres
        sollya_lib_set_prec(sollyaPrecSo)
2354 226 storres
        sollyaPrecChanged = True
2355 162 storres
    #
2356 85 storres
    # Error type stuff: default to absolute.
2357 85 storres
    if errorTypeSo is None:
2358 85 storres
        errorTypeIsNone = True
2359 85 storres
        errorTypeSo = sollya_lib_absolute(None)
2360 85 storres
    else:
2361 85 storres
        errorTypeIsNone = False
2362 162 storres
    intervalCenterSo = sollya_lib_mid(rangeSo)
2363 162 storres
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, \
2364 162 storres
                                         intervalCenterSo, \
2365 56 storres
                                         rangeSo, errorTypeSo, None)
2366 272 storres
    # Object taylorFormListSaSo is a Python list of Sollya objects references
2367 272 storres
    # that are copies of the elements of taylorFormSo.
2368 116 storres
    # pobyso_get_list_elements_so_so clears taylorFormSo.
2369 272 storres
    (taylorFormListSaSo, numElements, isEndElliptic) = \
2370 56 storres
        pobyso_get_list_elements_so_so(taylorFormSo)
2371 272 storres
    sollya_lib_clear_obj(taylorFormSo)
2372 272 storres
    polySo = taylorFormListSaSo[0]
2373 272 storres
    ## Maximum error computation with taylorFormListSaSo[2], a range
2374 272 storres
    #  holding the actual error. Bounds can be negative.
2375 272 storres
    maxErrorSo    = sollya_lib_sup(taylorFormListSaSo[2])
2376 272 storres
    minErrorSo    = sollya_lib_inf(taylorFormListSaSo[2])
2377 181 storres
    absMaxErrorSo = sollya_lib_abs(maxErrorSo)
2378 181 storres
    absMinErrorSo = sollya_lib_abs(minErrorSo)
2379 181 storres
    sollya_lib_clear_obj(maxErrorSo)
2380 181 storres
    sollya_lib_clear_obj(minErrorSo)
2381 181 storres
    absMaxErrorSa = pobyso_get_constant_as_rn_so_sa(absMaxErrorSo)
2382 181 storres
    absMinErrorSa = pobyso_get_constant_as_rn_so_sa(absMinErrorSo)
2383 162 storres
    changeVarExpSo = sollya_lib_build_function_sub(\
2384 162 storres
                       sollya_lib_build_function_free_variable(),\
2385 162 storres
                       sollya_lib_copy_obj(intervalCenterSo))
2386 181 storres
    polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpSo)
2387 272 storres
    # List taylorFormListSaSo is not needed anymore.
2388 280 storres
    pobyso_clear_list_elements_sa_so(taylorFormListSaSo)
2389 162 storres
    sollya_lib_clear_obj(changeVarExpSo)
2390 56 storres
    # If changed, reset the Sollya working precision.
2391 226 storres
    if sollyaPrecChanged:
2392 226 storres
        sollya_lib_set_prec(initialSollyaPrecSo)
2393 226 storres
    sollya_lib_clear_obj(initialSollyaPrecSo)
2394 85 storres
    if errorTypeIsNone:
2395 85 storres
        sollya_lib_clear_obj(errorTypeSo)
2396 162 storres
    # Do not clear maxErrorSo.
2397 181 storres
    if absMaxErrorSa > absMinErrorSa:
2398 181 storres
        sollya_lib_clear_obj(absMinErrorSo)
2399 181 storres
        return((polyVarChangedSo, intervalCenterSo, absMaxErrorSo))
2400 181 storres
    else:
2401 181 storres
        sollya_lib_clear_obj(absMaxErrorSo)
2402 181 storres
        return((polyVarChangedSo, intervalCenterSo, absMinErrorSo))
2403 162 storres
# end pobyso_taylor_expansion_with_change_var_so_so
2404 56 storres
2405 5 storres
def pobyso_taylor(function, degree, point):
2406 38 storres
    """ Legacy function. See pobysoTaylor_so_so. """
2407 38 storres
    return(pobyso_taylor_so_so(function, degree, point))
2408 38 storres
2409 56 storres
def pobyso_taylor_so_so(functionSo, degreeSo, pointSo):
2410 56 storres
    return(sollya_lib_taylor(functionSo, degreeSo, pointSo))
2411 5 storres
2412 85 storres
def pobyso_taylorform(function, degree, point = None,
2413 85 storres
                      interval = None, errorType=None):
2414 85 storres
    """ Legacy function. See pobyso_taylorform_sa_sa;"""
2415 38 storres
2416 38 storres
def pobyso_taylorform_sa_sa(functionSa, \
2417 84 storres
                            degreeSa, \
2418 84 storres
                            pointSa, \
2419 84 storres
                            intervalSa=None, \
2420 84 storres
                            errorTypeSa=None, \
2421 84 storres
                            precisionSa=None):
2422 37 storres
    """
2423 85 storres
    Compute the Taylor form of 'degreeSa' for 'functionSa' at 'pointSa'
2424 85 storres
    for 'intervalSa' with 'errorTypeSa' (a string) using 'precisionSa'.
2425 37 storres
    point: must be a Real or a Real interval.
2426 37 storres
    return the Taylor form as an array
2427 83 storres
    TODO: take care of the interval and of the point when it is an interval;
2428 38 storres
          when errorType is not None;
2429 83 storres
          take care of the other elements of the Taylor form (coefficients
2430 83 storres
          errors and delta.
2431 37 storres
    """
2432 37 storres
    # Absolute as the default error.
2433 84 storres
    if errorTypeSa is None:
2434 37 storres
        errorTypeSo = sollya_lib_absolute()
2435 84 storres
    elif errorTypeSa == "relative":
2436 84 storres
        errorTypeSo = sollya_lib_relative()
2437 84 storres
    elif errortypeSa == "absolute":
2438 84 storres
        errorTypeSo = sollya_lib_absolute()
2439 37 storres
    else:
2440 84 storres
        # No clean up needed.
2441 84 storres
        return None
2442 84 storres
    # Global precision stuff
2443 226 storres
    sollyaPrecisionChangedSa = False
2444 226 storres
    (initialSollyaPrecSo, initialSollyaPrecSa) = pobyso_get_prec_so_so_sa()
2445 226 storres
    if precisionSa is None:
2446 226 storres
        precSa = initialSollyaPrecSa
2447 226 storres
    else:
2448 226 storres
        if precSa > initialSollyaPrecSa:
2449 226 storres
            if precSa <= 2:
2450 226 storres
                print inspect.stack()[0][3], ":precision change <= 2 requested."
2451 226 storres
            pobyso_set_prec_sa_so(precSa)
2452 226 storres
            sollyaPrecisionChangedSa = True
2453 226 storres
    #
2454 85 storres
    if len(functionSa.variables()) > 0:
2455 85 storres
        varSa = functionSa.variables()[0]
2456 85 storres
        pobyso_name_free_variable_sa_so(str(varSa))
2457 84 storres
    # In any case (point or interval) the parent of pointSa has a precision
2458 84 storres
    # method.
2459 84 storres
    pointPrecSa = pointSa.parent().precision()
2460 226 storres
    if precSa > pointPrecSa:
2461 226 storres
        pointPrecSa = precSa
2462 84 storres
    # In any case (point or interval) pointSa has a base_ring() method.
2463 84 storres
    pointBaseRingString = str(pointSa.base_ring())
2464 84 storres
    if re.search('Interval', pointBaseRingString) is None: # Point
2465 84 storres
        pointSo = pobyso_constant_sa_so(pointSa, pointPrecSa)
2466 84 storres
    else: # Interval.
2467 84 storres
        pointSo = pobyso_interval_to_range_sa_so(pointSa, pointPrecSa)
2468 37 storres
    # Sollyafy the function.
2469 159 storres
    functionSo = pobyso_parse_string_sa_so(functionSa._assume_str().replace('_SAGE_VAR_', ''))
2470 37 storres
    if sollya_lib_obj_is_error(functionSo):
2471 37 storres
        print "pobyso_tailorform: function string can't be parsed!"
2472 37 storres
        return None
2473 37 storres
    # Sollyafy the degree
2474 84 storres
    degreeSo = sollya_lib_constant_from_int(int(degreeSa))
2475 37 storres
    # Sollyafy the point
2476 37 storres
    # Call Sollya
2477 83 storres
    taylorFormSo = \
2478 83 storres
        sollya_lib_taylorform(functionSo, degreeSo, pointSo, errorTypeSo,\
2479 37 storres
                                         None)
2480 85 storres
    sollya_lib_clear_obj(functionSo)
2481 85 storres
    sollya_lib_clear_obj(degreeSo)
2482 85 storres
    sollya_lib_clear_obj(pointSo)
2483 85 storres
    sollya_lib_clear_obj(errorTypeSo)
2484 38 storres
    (tfsAsList, numElements, isEndElliptic) = \
2485 38 storres
            pobyso_get_list_elements_so_so(taylorFormSo)
2486 37 storres
    polySo = tfsAsList[0]
2487 38 storres
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
2488 37 storres
    polyRealField = RealField(maxPrecision)
2489 38 storres
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, polyRealField)
2490 226 storres
    if sollyaPrecisionChangedSa:
2491 226 storres
        sollya_lib_set_prec(initialSollyaPrecSo)
2492 226 storres
    sollya_lib_clear_obj(initialSollyaPrecSo)
2493 37 storres
    polynomialRing = polyRealField[str(varSa)]
2494 37 storres
    polySa = polynomial(expSa, polynomialRing)
2495 37 storres
    taylorFormSa = [polySa]
2496 85 storres
    # Final clean-up.
2497 85 storres
    sollya_lib_clear_obj(taylorFormSo)
2498 51 storres
    return(taylorFormSa)
2499 51 storres
# End pobyso_taylor_form_sa_sa
2500 54 storres
2501 54 storres
def pobyso_taylorform_so_so(functionSo, degreeSo, pointSo, intervalSo=None, \
2502 54 storres
                            errorTypeSo=None):
2503 54 storres
    createdErrorType = False
2504 51 storres
    if errorTypeSo is None:
2505 51 storres
        errorTypeSo = sollya_lib_absolute()
2506 54 storres
        createdErrorType = True
2507 51 storres
    else:
2508 51 storres
        #TODO: deal with the other case.
2509 51 storres
        pass
2510 51 storres
    if intervalSo is None:
2511 54 storres
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
2512 54 storres
                                         errorTypeSo, None)
2513 51 storres
    else:
2514 54 storres
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
2515 54 storres
                                         intervalSo, errorTypeSo, None)
2516 54 storres
    if createdErrorType:
2517 54 storres
        sollya_lib_clear_obj(errorTypeSo)
2518 215 storres
    return resultSo
2519 51 storres
2520 37 storres
2521 37 storres
def pobyso_univar_polynomial_print_reverse(polySa):
2522 51 storres
    """ Legacy function. See pobyso_univar_polynomial_print_reverse_sa_sa. """
2523 51 storres
    return(pobyso_univar_polynomial_print_reverse_sa_sa(polySa))
2524 38 storres
2525 51 storres
def pobyso_univar_polynomial_print_reverse_sa_sa(polySa):
2526 37 storres
    """
2527 37 storres
    Return the string representation of a univariate polynomial with
2528 38 storres
    monomials ordered in the x^0..x^n order of the monomials.
2529 37 storres
    Remember: Sage
2530 37 storres
    """
2531 37 storres
    polynomialRing = polySa.base_ring()
2532 37 storres
    # A very expensive solution:
2533 37 storres
    # -create a fake multivariate polynomial field with only one variable,
2534 37 storres
    #   specifying a negative lexicographical order;
2535 37 storres
    mpolynomialRing = PolynomialRing(polynomialRing.base(), \
2536 37 storres
                                     polynomialRing.variable_name(), \
2537 37 storres
                                     1, order='neglex')
2538 37 storres
    # - convert the univariate argument polynomial into a multivariate
2539 37 storres
    #   version;
2540 37 storres
    p = mpolynomialRing(polySa)
2541 37 storres
    # - return the string representation of the converted form.
2542 37 storres
    # There is no simple str() method defined for p's class.
2543 37 storres
    return(p.__str__())
2544 5 storres
#
2545 230 storres
#print pobyso_get_prec()
2546 5 storres
pobyso_set_prec(165)
2547 230 storres
#print pobyso_get_prec()
2548 230 storres
#a=100
2549 230 storres
#print type(a)
2550 230 storres
#id(a)
2551 230 storres
#print "Max arity: ", pobyso_max_arity
2552 230 storres
#print "Function tripleDouble (43) as a string: ", pobyso_function_type_as_string(43)
2553 230 storres
#print "Function None (44) as a string: ", pobyso_function_type_as_string(44)
2554 246 storres
sys.stderr.write("\t...Pobyso check done.\n")