Statistiques
| Révision :

root / pobysoPythonSage / src / pobyso.py @ 215

Historique | Voir | Annoter | Télécharger (62,13 ko)

1
"""
2
@file pobyso.py
3
Actual functions to use in Sage
4
ST 2012-11-13
5

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

9
pobyso functions come in five flavors: 
10
- the _so_so (arguments and returned objects are pointers to Sollya objects, 
11
  includes the void function and the no arguments function that return a 
12
  pointer to a Sollya object);
13
- the _so_sa (argument are pointers to Sollya objects, returned objects are
14
  Sage/Python objects or, more generally, information is transfered from the
15
  Sollya world to Sage/Python world; e.g. functions without arguments that
16
  return a Sage/Python object);
17
- the _sa_so (arguments are Sage/Python objects, returned objects are 
18
  pointers to Sollya objects);
19
- the sa_sa (arguments and returned objects are all Sage/Python objects);
20
- a catch all flavor, without any suffix, (e. g. functions that have no argument 
21
  nor return value).
22
This classification is not always very strict. Conversion functions from Sollya
23
to Sage/Python are sometimes decorated with Sage/Python arguments to set
24
the precision. These functions remain in the so_sa category.
25
NOTES:
26
Reported errors in Eclipse come from the calls to
27
the Sollya library
28

29
ToDo (among other things): 
30
 -memory management.
31
"""
32
from ctypes import *
33
import re
34
from sage.symbolic.expression_conversions import polynomial
35
from sage.symbolic.expression_conversions import PolynomialConverter
36
"""
37
Create the equivalent to an enum for the Sollya function types.
38
"""
39
(SOLLYA_BASE_FUNC_ABS,
40
SOLLYA_BASE_FUNC_ACOS,
41
    SOLLYA_BASE_FUNC_ACOSH,
42
    SOLLYA_BASE_FUNC_ADD,
43
    SOLLYA_BASE_FUNC_ASIN,
44
    SOLLYA_BASE_FUNC_ASINH,
45
    SOLLYA_BASE_FUNC_ATAN,
46
    SOLLYA_BASE_FUNC_ATANH,
47
    SOLLYA_BASE_FUNC_CEIL,
48
    SOLLYA_BASE_FUNC_CONSTANT,
49
    SOLLYA_BASE_FUNC_COS,
50
    SOLLYA_BASE_FUNC_COSH,
51
    SOLLYA_BASE_FUNC_DIV,
52
    SOLLYA_BASE_FUNC_DOUBLE,
53
    SOLLYA_BASE_FUNC_DOUBLEDOUBLE,
54
    SOLLYA_BASE_FUNC_DOUBLEEXTENDED,
55
    SOLLYA_BASE_FUNC_ERF,
56
    SOLLYA_BASE_FUNC_ERFC,
57
    SOLLYA_BASE_FUNC_EXP,
58
    SOLLYA_BASE_FUNC_EXP_M1,
59
    SOLLYA_BASE_FUNC_FLOOR,
60
    SOLLYA_BASE_FUNC_FREE_VARIABLE,
61
    SOLLYA_BASE_FUNC_HALFPRECISION,
62
    SOLLYA_BASE_FUNC_LIBRARYCONSTANT,
63
    SOLLYA_BASE_FUNC_LIBRARYFUNCTION,
64
    SOLLYA_BASE_FUNC_LOG,
65
    SOLLYA_BASE_FUNC_LOG_10,
66
    SOLLYA_BASE_FUNC_LOG_1P,
67
    SOLLYA_BASE_FUNC_LOG_2,
68
    SOLLYA_BASE_FUNC_MUL,
69
    SOLLYA_BASE_FUNC_NEARESTINT,
70
    SOLLYA_BASE_FUNC_NEG,
71
    SOLLYA_BASE_FUNC_PI,
72
    SOLLYA_BASE_FUNC_POW,
73
    SOLLYA_BASE_FUNC_PROCEDUREFUNCTION,
74
    SOLLYA_BASE_FUNC_QUAD,
75
    SOLLYA_BASE_FUNC_SIN,
76
    SOLLYA_BASE_FUNC_SINGLE,
77
    SOLLYA_BASE_FUNC_SINH,
78
    SOLLYA_BASE_FUNC_SQRT,
79
    SOLLYA_BASE_FUNC_SUB,
80
    SOLLYA_BASE_FUNC_TAN,
81
    SOLLYA_BASE_FUNC_TANH,
82
SOLLYA_BASE_FUNC_TRIPLEDOUBLE) = map(int,xrange(44))
83
print "\nSuperficial pobyso check..."    
84
print "First constant - SOLLYA_BASE_FUNC_ABS: ", SOLLYA_BASE_FUNC_ABS
85
print "Last constant  - SOLLYA_BASE_FUNC_TRIPLEDOUBLE: ", SOLLYA_BASE_FUNC_TRIPLEDOUBLE
86

    
87
pobyso_max_arity = 9
88

    
89
def pobyso_absolute_so_so():
90
    return(sollya_lib_absolute(None))
91

    
92
def pobyso_autoprint(arg):
93
    sollya_lib_autoprint(arg,None)
94

    
95
def pobyso_autoprint_so_so(arg):
96
    sollya_lib_autoprint(arg,None)
97
    
98
def pobyso_bounds_to_range_sa_so(rnLowerBoundSa, rnUpperBoundSa, \
99
                                 precisionSa=None):
100
    """
101
    Return a Sollya range from to 2 RealField Sage elements.
102
    The Sollya range element has a sufficient precision to hold all
103
    the digits of the widest of the Sage bounds.
104
    """
105
    # Sanity check.
106
    if rnLowerBoundSa > rnUpperBoundSa:
107
        return None
108
    # Precision stuff.
109
    if precisionSa is None:
110
        # Check for the largest precision.
111
        lbPrecSa = rnLowerBoundSa.parent().precision()
112
        ubPrecSa = rnLowerBoundSa.parent().precision()
113
        maxPrecSa = max(lbPrecSa, ubPrecSa)
114
    else:
115
        maxPrecSa = precisionSa
116
    # From Sage to Sollya bounds.
117
#    lowerBoundSo = sollya_lib_constant(get_rn_value(rnLowerBoundSa),
118
#                                       maxPrecSa)
119
    lowerBoundSo = pobyso_constant_sa_so(rnLowerBoundSa,
120
                                         maxPrecSa)
121
    upperBoundSo = pobyso_constant_sa_so(rnUpperBoundSa,
122
                                       maxPrecSa)
123
    
124
    # From Sollya bounds to range.
125
    rangeSo = sollya_lib_range(lowerBoundSo, upperBoundSo)
126
    # Back to original precision.
127
    # Clean up
128
    sollya_lib_clear_obj(lowerBoundSo)
129
    sollya_lib_clear_obj(upperBoundSo)
130
    return rangeSo
131
# End pobyso_bounds_to_range_sa_so
132

    
133
def pobyso_build_end_elliptic_list_so_so(*args):
134
    """
135
    From argumrny Sollya objects, create a Sollya end elliptic list.
136
    Elements of the list are "eaten" (should not be cleared individualy, 
137
    are cleared when the list is cleared).
138
    """
139
    if len(args) == 0:
140
        ## Called with an empty list produced "error".
141
        return sollya_lib_build_end_elliptic_list(None)
142
    index = 0
143
    ## One can not append elements to an elliptic list, prepend only is 
144
    #  permitted.
145
    for argument in reversed(args):
146
        if index == 0:
147
            listSo = sollya_lib_build_end_elliptic_list(argument, None)
148
        else:
149
            listSo = sollya_lib_prepend(argument, listSo)
150
        index += 1
151
    return listSo
152
        
153
# End pobyso_build_end_elliptic_list_so_so
154

    
155
def pobyso_build_function_sub_so_so(exp1So, exp2So):
156
    return(sollya_lib_build_function_sub(exp1So, exp2So))
157

    
158
def pobyso_change_var_in_function_so_so(funcSo, chvarExpSo):
159
    """
160
    Variable change in a function.
161
    """
162
    return(sollya_lib_evaluate(funcSo,chvarExpSo))
163
# End pobyso_change_var_in_function_so_so     
164

    
165
def pobyso_chebyshevform_so_so(functionSo, degreeSo, intervalSo):
166
    resultSo = sollya_lib_chebyshevform(functionSo, degreeSo, intervalSo)
167
    return(resultSo)
168
# End pobyso_chebyshevform_so_so.
169

    
170
def pobyso_clear_taylorform_sa_so(taylorFormSaSo):
171
    """
172
    This method is necessary to correctly clean up the memory from Taylor forms.
173
    These are made of a Sollya object, a Sollya object list, a Sollya object.
174
    For no clearly understood reason, sollya_lib_clear_object_list crashed 
175
    when applied to the object list.
176
    Here, we decompose it into Sage list of Sollya objects references and we
177
     clear them one by one. 
178
    """
179
    sollya_lib_clear_obj(taylorFormSaSo[0])
180
    (coefficientsErrorsListSaSo, numElementsSa, isEndEllipticSa) = \
181
        pobyso_get_list_elements_so_so(taylorFormSaSo[1])
182
    for element in coefficientsErrorsListSaSo:
183
        sollya_lib_clear_obj(element)
184
    sollya_lib_clear_obj(taylorFormSaSo[1])
185
    sollya_lib_clear_obj(taylorFormSaSo[2])
186
# End pobyso_clear_taylorform_sa_so 
187

    
188
def pobyso_cmp(rnArgSa, cteSo):
189
    """
190
    Compare the MPFR value a RealNumber with that of a Sollya constant.
191
    
192
    Get the value of the Sollya constant into a RealNumber and compare
193
    using MPFR. Could be optimized by working directly with a mpfr_t
194
    for the intermediate number. 
195
    """
196
    # Get the precision of the Sollya constant to build a Sage RealNumber 
197
    # with enough precision.to hold it.
198
    precisionOfCte = c_int(0)
199
    # From the Sollya constant, create a local Sage RealNumber.
200
    sollya_lib_get_prec_of_constant(precisionOfCte, cteSo) 
201
    #print "Precision of constant: ", precisionOfCte
202
    RRRR = RealField(precisionOfCte.value)
203
    rnLocalSa = RRRR(0)
204
    sollya_lib_get_constant(get_rn_value(rnLocalSa), cteSo)
205
    #
206
    ## Compare the Sage RealNumber version of the Sollya constant with rnArg.
207
    return(cmp_rn_value(rnArgSa, rnLocal))
208
# End pobyso_smp
209

    
210
def pobyso_compute_pos_function_abs_val_bounds_sa_sa(funcSa, lowerBoundSa, \
211
                                                     upperBoundSa):
212
    """
213
    TODO: completely rework and test.
214
    """
215
    pobyso = pobyso_name_free_variable_sa_so(funcSa.variables()[0])
216
    funcSo = pobyso_parse_string(funcSa._assume_str().replace('_SAGE_VAR_', ''))
217
    rangeSo = pobyso_range_sa_so(lowerBoundSa, upperBoundSa)
218
    infnormSo = pobyso_infnorm_so_so(funcSo,rangeSo)
219
    # Sollya return the infnorm as an interval.
220
    fMaxSa = pobyso_get_interval_from_range_so_sa(infnormSo)
221
    # Get the top bound and compute the binade top limit.
222
    fMaxUpperBoundSa = fMaxSa.upper()
223
    binadeTopLimitSa = 2**ceil(fMaxUpperBoundSa.log2())
224
    # Put up together the function to use to compute the lower bound.
225
    funcAuxSo = pobyso_parse_string(str(binadeTopLimitSa) +  \
226
                                    '-(' + f._assume_str().replace('_SAGE_VAR_', '') + ')')
227
    pobyso_autoprint(funcAuxSo)
228
    # Clear the Sollya range before a new call to infnorm and issue the call.
229
    sollya_lib_clear_obj(infnormSo)
230
    infnormSo = pobyso_infnorm_so_so(funcAuxSo,rangeSo)
231
    fMinSa = pobyso_get_interval_from_range_so_sa(infnormSo)
232
    sollya_lib_clear_obj(infnormSo)
233
    fMinLowerBoundSa = binadeTopLimitSa - fMinSa.lower()
234
    # Compute the maximum of the precisions of the different bounds.
235
    maxPrecSa = max([fMinLowerBoundSa.parent().precision(), \
236
                     fMaxUpperBoundSa.parent().precision()])
237
    # Create a RealIntervalField and create an interval with the "good" bounds.
238
    RRRI = RealIntervalField(maxPrecSa)
239
    imageIntervalSa = RRRI(fMinLowerBoundSa, fMaxUpperBoundSa)
240
    # Free the unneeded Sollya objects
241
    sollya_lib_clear_obj(funcSo)
242
    sollya_lib_clear_obj(funcAuxSo)
243
    sollya_lib_clear_obj(rangeSo)
244
    return(imageIntervalSa)
245
# End pobyso_compute_pos_function_abs_val_bounds_sa_sa
246

    
247
def pobyso_compute_precision_decay_ratio_function_sa_so():
248
    """
249
    Compute the precision decay ratio function for polynomial 
250
    coefficient progressive trucation.
251
    """
252
    functionText = """
253
    proc(deg, a, b, we, wq) 
254
    {
255
      k = we * (exp(x/a)-1) + wq * (b*x)^2 + (1-we-wq) * x;
256
      return k/k(d);
257
    };
258
    """
259
    return pobyso_parse_string_sa_so(functionText)
260
# End  pobyso_compute_precision_decay_ratio_function.
261

    
262

    
263
def pobyso_constant(rnArg):
264
    """ Legacy function. See pobyso_constant_sa_so. """
265
    return(pobyso_constant_sa_so(rnArg))
266
    
267
def pobyso_constant_sa_so(rnArgSa, precisionSa=None):
268
    """
269
    Create a Sollya constant from a Sage RealNumber.
270
    The sollya_lib_constant() function creates a constant
271
    with the same precision as the source.
272
    """
273
    ## Precision stuff. If one wants to change precisions,
274
    #  everything takes place in Sage. That only makes
275
    #  sense if one wants to reduce the precision.
276
    if not precisionSa is None:
277
        RRR = RealField(precisionSa)
278
        rnArgSa = RRR(rnArgSa)
279
    #print rnArgSa, rnArgSa.precision()
280
    # Sollya constant creation takes place here.
281
    return sollya_lib_constant(get_rn_value(rnArgSa))
282
# End pobyso_constant_sa_so
283
     
284
def pobyso_constant_0_sa_so():
285
    """
286
    Obvious.
287
    """
288
    return pobyso_constant_from_int_sa_so(0)
289

    
290
def pobyso_constant_1():
291
    """
292
    Obvious.
293
    Legacy function. See pobyso_constant_so_so. 
294
    """
295
    return pobyso_constant_1_sa_so()
296

    
297
def pobyso_constant_1_sa_so():
298
    """
299
    Obvious.
300
    """
301
    return(pobyso_constant_from_int_sa_so(1))
302

    
303
def pobyso_constant_from_int(anInt):
304
    """ Legacy function. See pobyso_constant_from_int_sa_so. """
305
    return pobyso_constant_from_int_sa_so(anInt)
306

    
307
def pobyso_constant_from_int_sa_so(anInt):
308
    """
309
    Get a Sollya constant from a Sage int.
310
    """
311
    return sollya_lib_constant_from_int64(long(anInt))
312

    
313
def pobyso_constant_from_int_so_sa(constSo):
314
    """
315
    Get a Sage int from a Sollya int constant.
316
    Usefull for precision or powers in polynomials.
317
    """
318
    constSa = c_long(0)
319
    sollya_lib_get_constant_as_int64(byref(constSa), constSo)
320
    return constSa.value
321
# End pobyso_constant_from_int_so_sa
322

    
323
def pobyso_constant_from_mpq_sa_so(rationalSa):
324
    """
325
    Make a Sollya constant from Sage rational.
326
    The Sollya constant is an unevaluated expression.
327
    Hence no precision argument is needed.
328
    It is better to leave this way since Sollya has its own
329
    optimized evaluation mecanism that tries very hard to
330
    return exact values or at least faithful ones.
331
    """
332
    ratExprSo = \
333
        sollya_lib_constant_from_mpq(sgmp_get_rational_value(rationalSa))
334
    return ratExprSo
335
# End pobyso_constant_from_mpq_sa_so.
336

    
337
def pobyso_constant_sollya_prec_sa_so(rnArgSa):
338
    """
339
    Create a Sollya constant from a Sage RealNumber at the
340
    current precision in Sollya.
341
    """
342
    currentSollyaPrecSa = pobyso_get_prec_so_sa()
343
    return pobyso_constant_sa_so(rnArgSa, currentSollyaPrecSa)
344
# End pobyso_constant_sollya_prec_sa_so
345

    
346
def pobyso_end_elliptic_list_so_sa_so(objectsListSo, intCountSa):
347
    """
348
    Create a Sollya end elliptic list made of the objectListSo[0] to
349
     objectsListSo[intCountSa-1] objects.
350
    """     
351
    return sollya_lib_end_elliptic_list(objectSo, int(intCountSa))
352

    
353
def pobyso_error_so():
354
    return sollya_lib_error(None)
355
# End pobyso_error().
356

    
357
def pobyso_evaluate_so_so(funcSo, argumentSo):
358
    """
359
    Evaluates funcSo for arguemntSo through sollya_lib_evaluate().
360
    """
361
    return sollya_lib_evaluate(funcSo, argumentSo)
362
# End pobyso_evaluate_so_so.
363

    
364
def pobyso_float_poly_sa_so(polySa, precSa = None):
365
    """
366
    Create a Sollya polynomial from a Sage RealField polynomial.
367
    """
368
    ## TODO: filter arguments.
369
    ## Precision. If a precision is given, convert the polynomial
370
    #  into the right polynomial field. If not convert it straight
371
    #  to Sollya.
372
    if not precSa is None:
373
        RRR = RealField(precSa)
374
        ## Create a Sage polynomial in the "right" precision.
375
        P_RRR = RRR[polySa.variables()[0]]
376
        polyFloatSa = P_RRR(polySa)
377
    else:
378
        polyFloatSa = polySa
379
        precSa = polySa.parent().base_ring().precision()
380
    ## Get exponents and coefficients.
381
    exponentsSa = polyFloatSa.exponents()
382
    coefficientsSa = polyFloatSa.coefficients()
383
    ## Build the polynomial.
384
    polySo = None
385
    for coefficientSa, exponentSa in zip(coefficientsSa, exponentsSa):
386
        #print coefficientSa.n(prec=precSa), exponentSa
387
        coefficientSo = \
388
            pobyso_constant_sa_so(coefficientSa)
389
        #pobyso_autoprint(coefficientSo)
390
        exponentSo = \
391
            pobyso_constant_from_int_sa_so(exponentSa)
392
        #pobyso_autoprint(exponentSo)
393
        monomialSo = sollya_lib_build_function_pow(
394
                       sollya_lib_build_function_free_variable(),
395
                       exponentSo)
396
        if polySo is None:
397
            polySo = sollya_lib_build_function_mul(coefficientSo,
398
                                                   monomialSo)
399
        else:
400
            polyTermSo = sollya_lib_build_function_mul(coefficientSo,
401
                                                       monomialSo)
402
            polySo = sollya_lib_build_function_add(polySo, polyTermSo)
403
    return polySo
404
# End pobyso_float_poly_sa_so    
405

    
406
def pobyso_float_poly_so_sa(polySo, realFieldSa=None):
407
    """
408
    Convert a Sollya polynomial into a Sage floating-point polynomial.
409
    We assume that the polynomial is in canonical form.
410
    If no realField is given, a RealField corresponding to the maximum 
411
    precision of the coefficients is internally computed.
412
    The real field is not returned but can be easily retrieved from 
413
    the polynomial itself.
414
    ALGORITHM:
415
    - (optional) compute the RealField of the coefficients;
416
    - convert the Sollya expression into a Sage expression;
417
    - convert the Sage expression into a Sage polynomial
418
    TODO: the canonical thing for the polynomial.
419
    """    
420
    if realFieldSa is None:
421
        expressionPrecSa = pobyso_get_max_prec_of_exp_so_sa(polySo)
422
        print "Maximum precision of Sollya polynomial coefficients:", expressionPrecSa
423
        realFieldSa      = RealField(expressionPrecSa)
424
    #print "Sollya expression before...",
425
    #pobyso_autoprint(polySo)
426

    
427
    expressionSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo,
428
                                                             realFieldSa)
429
    #print "...Sollya expression after.",
430
    #pobyso_autoprint(polySo)
431
    polyVariableSa = expressionSa.variables()[0]
432
    polyRingSa     = realFieldSa[str(polyVariableSa)]
433
    #print polyRingSa
434
    # Do not use the polynomial(expressionSa, ring=polyRingSa) form!
435
    polynomialSa = polyRingSa(expressionSa)
436
    polyCoeffsListSa = polynomialSa.coefficients()
437
    #for coeff in polyCoeffsListSa:
438
    #    print coeff.abs().n()
439
    return polynomialSa
440
# End pobyso_float_poly_so_sa
441

    
442
def pobyso_free_variable():
443
    """
444
    Ultra thin wrapper around the sollya_lib_function_build_free_variable function.
445
    """
446
    return sollya_lib_build_function_free_variable()
447
    
448
def pobyso_function_type_as_string(funcType):
449
    """ Legacy function. See pobyso_function_type_as_string_so_sa. """
450
    return(pobyso_function_type_as_string_so_sa(funcType))
451

    
452
def pobyso_function_type_as_string_so_sa(funcType):
453
    """
454
    Numeric Sollya function codes -> Sage mathematical function names.
455
    Notice that pow -> ^ (a la Sage, not a la Python).
456
    """
457
    if funcType == SOLLYA_BASE_FUNC_ABS:
458
        return "abs"
459
    elif funcType == SOLLYA_BASE_FUNC_ACOS:
460
        return "arccos"
461
    elif funcType == SOLLYA_BASE_FUNC_ACOSH:
462
        return "arccosh"
463
    elif funcType == SOLLYA_BASE_FUNC_ADD:
464
        return "+"
465
    elif funcType == SOLLYA_BASE_FUNC_ASIN:
466
        return "arcsin"
467
    elif funcType == SOLLYA_BASE_FUNC_ASINH:
468
        return "arcsinh"
469
    elif funcType == SOLLYA_BASE_FUNC_ATAN:
470
        return "arctan"
471
    elif funcType == SOLLYA_BASE_FUNC_ATANH:
472
        return "arctanh"
473
    elif funcType == SOLLYA_BASE_FUNC_CEIL:
474
        return "ceil"
475
    elif funcType == SOLLYA_BASE_FUNC_CONSTANT:
476
        return "cte"
477
    elif funcType == SOLLYA_BASE_FUNC_COS:
478
        return "cos"
479
    elif funcType == SOLLYA_BASE_FUNC_COSH:
480
        return "cosh"
481
    elif funcType == SOLLYA_BASE_FUNC_DIV:
482
        return "/"
483
    elif funcType == SOLLYA_BASE_FUNC_DOUBLE:
484
        return "double"
485
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEDOUBLE:
486
        return "doubleDouble"
487
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEEXTENDED:
488
        return "doubleDxtended"
489
    elif funcType == SOLLYA_BASE_FUNC_ERF:
490
        return "erf"
491
    elif funcType == SOLLYA_BASE_FUNC_ERFC:
492
        return "erfc"
493
    elif funcType == SOLLYA_BASE_FUNC_EXP:
494
        return "exp"
495
    elif funcType == SOLLYA_BASE_FUNC_EXP_M1:
496
        return "expm1"
497
    elif funcType == SOLLYA_BASE_FUNC_FLOOR:
498
        return "floor"
499
    elif funcType == SOLLYA_BASE_FUNC_FREE_VARIABLE:
500
        return "freeVariable"
501
    elif funcType == SOLLYA_BASE_FUNC_HALFPRECISION:
502
        return "halfPrecision"
503
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYCONSTANT:
504
        return "libraryConstant"
505
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYFUNCTION:
506
        return "libraryFunction"
507
    elif funcType == SOLLYA_BASE_FUNC_LOG:
508
        return "log"
509
    elif funcType == SOLLYA_BASE_FUNC_LOG_10:
510
        return "log10"
511
    elif funcType == SOLLYA_BASE_FUNC_LOG_1P:
512
        return "log1p"
513
    elif funcType == SOLLYA_BASE_FUNC_LOG_2:
514
        return "log2"
515
    elif funcType == SOLLYA_BASE_FUNC_MUL:
516
        return "*"
517
    elif funcType == SOLLYA_BASE_FUNC_NEARESTINT:
518
        return "round"
519
    elif funcType == SOLLYA_BASE_FUNC_NEG:
520
        return "__neg__"
521
    elif funcType == SOLLYA_BASE_FUNC_PI:
522
        return "pi"
523
    elif funcType == SOLLYA_BASE_FUNC_POW:
524
        return "^"
525
    elif funcType == SOLLYA_BASE_FUNC_PROCEDUREFUNCTION:
526
        return "procedureFunction"
527
    elif funcType == SOLLYA_BASE_FUNC_QUAD:
528
        return "quad"
529
    elif funcType == SOLLYA_BASE_FUNC_SIN:
530
        return "sin"
531
    elif funcType == SOLLYA_BASE_FUNC_SINGLE:
532
        return "single"
533
    elif funcType == SOLLYA_BASE_FUNC_SINH:
534
        return "sinh"
535
    elif funcType == SOLLYA_BASE_FUNC_SQRT:
536
        return "sqrt"
537
    elif funcType == SOLLYA_BASE_FUNC_SUB:
538
        return "-"
539
    elif funcType == SOLLYA_BASE_FUNC_TAN:
540
        return "tan"
541
    elif funcType == SOLLYA_BASE_FUNC_TANH:
542
        return "tanh"
543
    elif funcType == SOLLYA_BASE_FUNC_TRIPLEDOUBLE:
544
        return "tripleDouble"
545
    else:
546
        return None
547

    
548
def pobyso_get_constant(rnArgSa, constSo):
549
    """ Legacy function. See pobyso_get_constant_so_sa. """
550
    return pobyso_get_constant_so_sa(rnArgSa, constSo)
551
# End pobyso_get_constant
552

    
553
def pobyso_get_constant_so_sa(rnArgSa, constSo):
554
    """
555
    Set the value of rnArgSo to the value of constSo in MPFR_RNDN mode.
556
    rnArg must already exist and belong to some RealField.
557
    We assume that constSo points to a Sollya constant.
558
    """
559
    outcome = sollya_lib_get_constant(get_rn_value(rnArgSa), constSo)
560
    if outcome == 0: # Failure because constSo is not a constant expression.
561
        return None
562
    else:
563
        return outcome
564
# End  pobyso_get_constant_so_sa
565
   
566
def pobyso_get_constant_as_rn(ctExpSo):
567
    """ 
568
    Legacy function. See pobyso_get_constant_as_rn_so_sa. 
569
    """ 
570
    return(pobyso_get_constant_as_rn_so_sa(ctExpSo))
571
    
572
def pobyso_get_constant_as_rn_so_sa(constExpSo):
573
    """
574
    Get a Sollya constant as a Sage "real number".
575
    The precision of the floating-point number returned is that of the Sollya
576
    constant.
577
    """
578
    precisionSa  = pobyso_get_prec_of_constant_so_sa(constExpSo)
579
    ## If the expression can not be exactly converted, None is returned.
580
    #  In this case opt for the Sollya current expression.
581
    if precisionSa is None:
582
        precisionSa = pobyso_get_prec_so_sa()
583
    RRRR = RealField(precisionSa)
584
    rnSa = RRRR(0)
585
    outcome = sollya_lib_get_constant(get_rn_value(rnSa), constExpSo)
586
    if outcome == 0:
587
        return None
588
    else:
589
        return rnSa
590
# End pobyso_get_constant_as_rn_so_sa
591

    
592
def pobyso_get_constant_as_rn_with_rf(ctExp, realField):
593
    """ 
594
    Legacy function. See pobyso_get_constant_as_rn_with_rf_so_sa.
595
    """
596
    return pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField)
597
# End pobyso_get_constant_as_rn_with_rf
598
    
599
def pobyso_get_constant_as_rn_with_rf_so_sa(ctExpSo, realFieldSa = None):
600
    """
601
    Get a Sollya constant as a Sage "real number".
602
    If no real field is specified, the precision of the floating-point number 
603
    returned is that of the Sollya constant.
604
    Otherwise is is that of the real field. Hence rounding may happen.
605
    """
606
    if realFieldSa is None:
607
        return pobyso_get_constant_as_rn_so_sa(ctExpSo)
608
    rnSa = realFieldSa(0)
609
    outcome = sollya_lib_get_constant(get_rn_value(rnSa), ctExpSo)
610
    if outcome == 0:
611
        return None
612
    else:
613
        return rnSa
614
# End pobyso_get_constant_as_rn_with_rf_so_sa
615

    
616
def pobyso_get_free_variable_name():
617
    """ 
618
    Legacy function. See pobyso_get_free_variable_name_so_sa.
619
    """
620
    return(pobyso_get_free_variable_name_so_sa())
621

    
622
def pobyso_get_free_variable_name_so_sa():
623
    return sollya_lib_get_free_variable_name()
624
    
625
def pobyso_get_function_arity(expressionSo):
626
    """ 
627
    Legacy function. See pobyso_get_function_arity_so_sa.
628
    """
629
    return(pobyso_get_function_arity_so_sa(expressionSo))
630

    
631
def pobyso_get_function_arity_so_sa(expressionSo):
632
    arity = c_int(0)
633
    sollya_lib_get_function_arity(byref(arity),expressionSo)
634
    return int(arity.value)
635

    
636
def pobyso_get_head_function(expressionSo):
637
    """ 
638
    Legacy function. See pobyso_get_head_function_so_sa. 
639
    """
640
    return(pobyso_get_head_function_so_sa(expressionSo)) 
641

    
642
def pobyso_get_head_function_so_sa(expressionSo):
643
    functionType = c_int(0)
644
    sollya_lib_get_head_function(byref(functionType), expressionSo, None)
645
    return int(functionType.value)
646

    
647
def pobyso_get_interval_from_range_so_sa(soRange, realIntervalFieldSa = None ):
648
    """
649
    Return the Sage interval corresponding to the Sollya range argument.
650
    If no reaIntervalField is passed as an argument, the interval bounds are not
651
    rounded: they are elements of RealIntervalField of the "right" precision
652
    to hold all the digits.
653
    """
654
    prec = c_int(0)
655
    if realIntervalFieldSa is None:
656
        retval = sollya_lib_get_prec_of_range(byref(prec), soRange, None)
657
        if retval == 0:
658
            return None
659
        realIntervalFieldSa = RealIntervalField(prec.value)
660
    intervalSa = realIntervalFieldSa(0,0)
661
    retval = \
662
        sollya_lib_get_interval_from_range(get_interval_value(intervalSa),\
663
                                           soRange)
664
    if retval == 0:
665
        return None
666
    return intervalSa
667
# End pobyso_get_interval_from_range_so_sa
668

    
669
def pobyso_get_list_elements(soObj):
670
    """ Legacy function. See pobyso_get_list_elements_so_so. """
671
    return pobyso_get_list_elements_so_so(soObj)
672
 
673
def pobyso_get_list_elements_so_so(objectListSo):
674
    """
675
    Get the Sollya list elements as a Sage/Python array of Sollya objects.
676
    
677
    INPUT:
678
    - objectListSo: a Sollya list of Sollya objects.
679
    
680
    OUTPUT:
681
    - a Sage/Python tuple made of:
682
      - a Sage/Python list of Sollya objects,
683
      - a Sage/Python int holding the number of elements,
684
      - a Sage/Python int stating (!= 0) that the list is end-elliptic.
685
    NOTE::
686
        We recover the addresses of the Sollya object from the list of pointers
687
        returned by sollya_lib_get_list_elements. The list itself is freed.
688
    TODO::
689
        Figure out what to do with numElements since the number of elements
690
        can easily be recovered from the list itself. 
691
        Ditto for isEndElliptic.
692
    """
693
    listAddress = POINTER(c_longlong)()
694
    numElements = c_int(0)
695
    isEndElliptic = c_int(0)
696
    listAsSageList = []
697
    result = sollya_lib_get_list_elements(byref(listAddress),\
698
                                          byref(numElements),\
699
                                          byref(isEndElliptic),\
700
                                          objectListSo)
701
    if result == 0 :
702
        return None
703
    for i in xrange(0, numElements.value, 1):
704
       #listAsSageList.append(sollya_lib_copy_obj(listAddress[i]))
705
       listAsSageList.append(listAddress[i])
706
       # Clear each of the elements returned by Sollya.
707
       #sollya_lib_clear_obj(listAddress[i])
708
    # Free the list itself.   
709
    sollya_lib_free(listAddress)
710
    return (listAsSageList, numElements.value, isEndElliptic.value)
711

    
712
def pobyso_get_max_prec_of_exp(soExp):
713
    """ Legacy function. See pobyso_get_max_prec_of_exp_so_sa. """
714
    return pobyso_get_max_prec_of_exp_so_sa(soExp)
715

    
716
def pobyso_get_max_prec_of_exp_so_sa(expSo):
717
    """
718
    Get the maximum precision used for the numbers in a Sollya expression.
719
    
720
    Arguments:
721
    soExp -- a Sollya expression pointer
722
    Return value:
723
    A Python integer
724
    TODO: 
725
    - error management;
726
    - correctly deal with numerical type such as DOUBLEEXTENDED.
727
    """
728
    maxPrecision = 0
729
    minConstPrec = 0
730
    currentConstPrec = 0
731
    operator = pobyso_get_head_function_so_sa(expSo)
732
    if (operator != SOLLYA_BASE_FUNC_CONSTANT) and \
733
    (operator != SOLLYA_BASE_FUNC_FREE_VARIABLE):
734
        (arity, subexpressions) = pobyso_get_subfunctions_so_sa(expSo)
735
        for i in xrange(arity):
736
            maxPrecisionCandidate = \
737
                pobyso_get_max_prec_of_exp_so_sa(subexpressions[i])
738
            if maxPrecisionCandidate > maxPrecision:
739
                maxPrecision = maxPrecisionCandidate
740
        return maxPrecision
741
    elif operator == SOLLYA_BASE_FUNC_CONSTANT:
742
        #minConstPrec = pobyso_get_min_prec_of_constant_so_sa(expSo)
743
        #currentConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
744
        #print minConstPrec, " - ", currentConstPrec 
745
        return pobyso_get_min_prec_of_constant_so_sa(expSo)
746
    
747
    elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
748
        return 0
749
    else:
750
        print "pobyso_get_max_prec_of_exp_so_sa: unexepected operator."
751
        return 0
752

    
753
def pobyso_get_min_prec_of_constant_so_sa(constExpSo):
754
    """
755
    Get the minimum precision necessary to represent the value of a Sollya
756
    constant.
757
    MPFR_MIN_PREC and powers of 2 are taken into account.
758
    We assume that constExpSo is a pointer to a Sollay constant expression.
759
    """
760
    constExpAsRnSa = pobyso_get_constant_as_rn_so_sa(constExpSo)
761
    return(min_mpfr_size(get_rn_value(constExpAsRnSa)))
762

    
763
def pobyso_get_poly_so_sa(polySo, realFieldSa=None):
764
    """
765
    Convert a Sollya polynomial into a Sage polynomial.
766
    Legacy function. Use pobyso_float_poly_so_sa() instead.
767
    """    
768
    return pobyso_float_poly_so_sa(polySo,realFieldSa)
769
# End pobyso_get_poly_so_sa
770

    
771
def pobyso_get_prec():
772
    """ Legacy function. See pobyso_get_prec_so_sa(). """
773
    return pobyso_get_prec_so_sa()
774

    
775
def pobyso_get_prec_so():
776
    """
777
    Get the current default precision in Sollya.
778
    The return value is a Sollya object.
779
    Usefull when modifying the precision back and forth by avoiding
780
    extra conversions.
781
    """
782
    return sollya_lib_get_prec(None)
783
    
784
def pobyso_get_prec_so_sa():
785
    """
786
    Get the current default precision in Sollya.
787
    The return value is Sage/Python int.
788
    """
789
    precSo = sollya_lib_get_prec(None)
790
    precSa = c_int(0)
791
    sollya_lib_get_constant_as_int(byref(precSa), precSo)
792
    sollya_lib_clear_obj(precSo)
793
    return int(precSa.value)
794
# End pobyso_get_prec_so_sa.
795

    
796
def pobyso_get_prec_so_so_sa():
797
    """
798
    Return the current precision both as a Sollya object and a
799
    Sage integer as hybrid tuple.
800
    To avoid multiple calls for precision manipulations. 
801
    """
802
    precSo = sollya_lib_get_prec(None)
803
    precSa = c_int(0)
804
    sollya_lib_get_constant_as_int(byref(precSa), precSo)
805
    return (precSo, precSa)
806
    
807
def pobyso_get_prec_of_constant(ctExpSo):
808
    """ Legacy function. See pobyso_get_prec_of_constant_so_sa. """
809
    return pobyso_get_prec_of_constant_so_sa(ctExpSo)
810

    
811
def pobyso_get_prec_of_constant_so_sa(ctExpSo):
812
    """
813
    Tries to find a precision to represent ctExpSo without rounding.
814
    If not possible, returns None.
815
    """
816
    prec = c_int(0)
817
    retc = sollya_lib_get_prec_of_constant(byref(prec), ctExpSo, None)
818
    if retc == 0:
819
        return None
820
    return int(prec.value)
821

    
822
def pobyso_get_prec_of_range_so_sa(rangeSo):
823
    """
824
    Returns the number of bits elements of a range are coded with.
825
    """
826
    prec = c_int(0)
827
    retc = sollya_lib_get_prec_of_range(byref(prec), rangeSo, None)
828
    if retc == 0:
829
        return(None)
830
    return int(prec.value)
831
# End pobyso_get_prec_of_range_so_sa()
832

    
833
def pobyso_get_sage_exp_from_sollya_exp(sollyaExpSo, realField = RR):
834
    """ Legacy function. See pobyso_get_sage_exp_from_sollya_exp_so_sa. """
835
    return pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, 
836
                                                     realField = RR)
837

    
838
def pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, realFieldSa = RR):
839
    """
840
    Get a Sage expression from a Sollya expression. 
841
    Currently only tested with polynomials with floating-point coefficients.
842
    Notice that, in the returned polynomial, the exponents are RealNumbers.
843
    """
844
    #pobyso_autoprint(sollyaExp)
845
    operatorSa = pobyso_get_head_function_so_sa(sollyaExpSo)
846
    sollyaLibFreeVariableName = sollya_lib_get_free_variable_name()
847
    ## Get rid of the "_"'s in "_x_", if any.
848
    sollyaLibFreeVariableName = re.sub('_', '', sollyaLibFreeVariableName)
849
    # Constants and the free variable are special cases.
850
    # All other operator are dealt with in the same way.
851
    if (operatorSa != SOLLYA_BASE_FUNC_CONSTANT) and \
852
       (operatorSa != SOLLYA_BASE_FUNC_FREE_VARIABLE):
853
        (aritySa, subexpressionsSa) = pobyso_get_subfunctions_so_sa(sollyaExpSo)
854
        if aritySa == 1:
855
            sageExpSa = eval(pobyso_function_type_as_string_so_sa(operatorSa) + \
856
            "(" + pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], \
857
            realFieldSa) + ")")
858
        elif aritySa == 2:
859
            # We do not get through the preprocessor.
860
            # The "^" operator is then a special case.
861
            if operatorSa == SOLLYA_BASE_FUNC_POW:
862
                operatorAsStringSa = "**"
863
            else:
864
                operatorAsStringSa = \
865
                    pobyso_function_type_as_string_so_sa(operatorSa)
866
            sageExpSa = \
867
              eval("pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], realFieldSa)"\
868
              + " " + operatorAsStringSa + " " + \
869
                   "pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[1], realFieldSa)")
870
        # We do not know yet how to deal with arity >= 3 
871
        # (is there any in Sollya anyway?).
872
        else:
873
            sageExpSa = eval('None')
874
        return sageExpSa
875
    elif operatorSa == SOLLYA_BASE_FUNC_CONSTANT:
876
        #print "This is a constant"
877
        return pobyso_get_constant_as_rn_with_rf_so_sa(sollyaExpSo, realFieldSa)
878
    elif operatorSa == SOLLYA_BASE_FUNC_FREE_VARIABLE:
879
        #print "This is free variable"
880
        return eval(sollyaLibFreeVariableName)
881
    else:
882
        print "Unexpected"
883
        return eval('None')
884
# End pobyso_get_sage_exp_from_sollya_exp_so_sa
885

    
886

    
887
def pobyso_get_subfunctions(expressionSo):
888
    """ Legacy function. See pobyso_get_subfunctions_so_sa. """
889
    return pobyso_get_subfunctions_so_sa(expressionSo) 
890
# End pobyso_get_subfunctions.
891
 
892
def pobyso_get_subfunctions_so_sa(expressionSo):
893
    """
894
    Get the subfunctions of an expression.
895
    Return the number of subfunctions and the list of subfunctions addresses.
896
    S.T.: Could not figure out another way than that ugly list of declarations
897
    to recover the addresses of the subfunctions.
898
    We limit ourselves to arity 8 functions. 
899
    """
900
    subf0 = c_int(0)
901
    subf1 = c_int(0)
902
    subf2 = c_int(0)
903
    subf3 = c_int(0)
904
    subf4 = c_int(0)
905
    subf5 = c_int(0)
906
    subf6 = c_int(0)
907
    subf7 = c_int(0)
908
    subf8 = c_int(0)
909
    arity = c_int(0)
910
    nullPtr = POINTER(c_int)()
911
    sollya_lib_get_subfunctions(expressionSo, byref(arity), \
912
      byref(subf0), byref(subf1), byref(subf2), byref(subf3), \
913
      byref(subf4), byref(subf5),\
914
      byref(subf6), byref(subf7), byref(subf8), nullPtr, None) 
915
#    byref(cast(subfunctions[0], POINTER(c_int))), \
916
#    byref(cast(subfunctions[0], POINTER(c_int))), \
917
#    byref(cast(subfunctions[2], POINTER(c_int))), \
918
#    byref(cast(subfunctions[3], POINTER(c_int))), \
919
#    byref(cast(subfunctions[4], POINTER(c_int))), \
920
#    byref(cast(subfunctions[5], POINTER(c_int))), \
921
#    byref(cast(subfunctions[6], POINTER(c_int))), \
922
#    byref(cast(subfunctions[7], POINTER(c_int))), \
923
#    byref(cast(subfunctions[8], POINTER(c_int))), nullPtr)
924
    subfunctions = [subf0, subf1, subf2, subf3, subf4, subf5, subf6, subf7, \
925
                    subf8]
926
    subs = []
927
    if arity.value > pobyso_max_arity:
928
        return(0,[])
929
    for i in xrange(arity.value):
930
        subs.append(int(subfunctions[i].value))
931
        #print subs[i]
932
    return (int(arity.value), subs)
933
# End pobyso_get_subfunctions_so_sa
934
    
935
def pobyso_guess_degree_sa_sa(functionSa, intervalSa, approxErrorSa, 
936
                              weightSa=None, degreeBoundSa=None):
937
    """
938
    Sa_sa variant of the solly_guessdegree function.
939
    Return 0 if something goes wrong.
940
    """
941
    functionAsStringSa = functionSa._assume_str().replace('_SAGE_VAR_', '')
942
    functionSo = pobyso_parse_string_sa_so(functionAsStringSa)
943
    if pobyso_is_error_so_sa(functionSo):
944
        sollya_lib_clear_obj(functionSo)
945
        return 0
946
    rangeSo = pobyso_interval_to_range_sa_so(intervalSa)
947
    # The approximation error is expected to be a floating point number.
948
    if pobyso_is_floating_point_number_sa_sa(approxErrorSa):
949
        approxErrorSo = pobyso_constant_sa_so(approxErrorSa)
950
    else:
951
        approxErrorSo = pobyso_constant_sa_so(RR(approxErrorSa))
952
    if not weightSa is None:
953
        weightAsStringSa = weightSa._assume_str().replace('_SAGE_VAR_', '')
954
        weightSo = pobyso_parse_string_sa_so(weightAsStringSa)
955
        if pobyso_is_error_so_sa(weightSo):
956
            sollya_lib_clear_obj(functionSo)
957
            sollya_lib_clear_obj(rangeSo)
958
            sollya_lib_clear_obj(approxErrorSo)   
959
            sollya_lib_clear_obj(weightSo)
960
            return 0   
961
    else:
962
        weightSo = None
963
    if not degreeBoundSa is None:
964
        degreeBoundSo = pobyso_constant_from_int_sa_so(degreeBoundSa)
965
    else:
966
        degreeBoundSo = None
967
    guessedDegreeSa = pobyso_guess_degree_so_sa(functionSo,
968
                                                rangeSo,
969
                                                approxErrorSo,
970
                                                weightSo,
971
                                                degreeBoundSo)
972
    sollya_lib_clear_obj(functionSo)
973
    sollya_lib_clear_obj(rangeSo)
974
    sollya_lib_clear_obj(approxErrorSo)
975
    if not weightSo is None:
976
        sollya_lib_clear_obj(weightSo)
977
    if not degreeBoundSo is None:
978
        sollya_lib_clear_obj(degreeBoundSo)
979
    return guessedDegreeSa
980
# End poyso_guess_degree_sa_sa
981

    
982
def pobyso_guess_degree_so_sa(functionSo, rangeSo, errorSo, weightSo=None, \
983
                              degreeBoundSo=None):
984
    """
985
    Thin wrapper around the guessdegree function.
986
    Nevertheless, some precision control stuff has been appended.
987
    """
988
    # Deal with Sollya internal precision issues: if it is too small, 
989
    # compared with the error, increases it to about twice -log2(error).
990
    errorSa = pobyso_get_constant_as_rn_with_rf_so_sa(errorSo)
991
    log2ErrorSa = errorSa.log2()
992
    if log2ErrorSa < 0:
993
        neededPrecisionSa = int(2 * int(-log2ErrorSa) / 64) * 64
994
    else:
995
        neededPrecisionSa = int(2 * int(log2ErrorSa) / 64) * 64
996
    #print "Needed precision:", neededPrecisionSa
997
    currentPrecSa = pobyso_get_prec_so_sa()
998
    if neededPrecisionSa > currentPrecSa:
999
        currentPrecSo = pobyso_get_prec_so()
1000
        pobyso_set_prec_sa_so(neededPrecisionSa)
1001
    #print "Guessing degree..."
1002
    # weightSo and degreeBoundsSo are optional arguments.
1003
    # As declared, sollya_lib_guessdegree must take 5 arguments.
1004
    if weightSo is None:
1005
        degreeRangeSo = sollya_lib_guessdegree(functionSo, rangeSo, errorSo, 
1006
                                               0, 0, None)
1007
    elif degreeBoundSo is None:
1008
        degreeRangeSo =  sollya_lib_guessdegree(functionSo, rangeSo, \
1009
                                                errorSo, weightSo, 0, None)
1010
    else:
1011
        degreeRangeSo =  sollya_lib_guessdegree(functionSo, rangeSo, errorSo, \
1012
                                                weightSo, degreeBoundSo, None)
1013
    #print "...degree guess done."
1014
    # Restore internal precision, if applicable.
1015
    if neededPrecisionSa > currentPrecSa:
1016
        pobyso_set_prec_so_so(currentPrecSo)
1017
        sollya_lib_clear_obj(currentPrecSo)
1018
    degreeIntervalSa = pobyso_range_to_interval_so_sa(degreeRangeSo)
1019
    sollya_lib_clear_obj(degreeRangeSo)
1020
    # When ok, both bounds match.
1021
    # When the degree bound is too low, the upper bound is the degree
1022
    # for which the error can be honored.
1023
    # When it really goes wrong, the upper bound is infinity. 
1024
    if degreeIntervalSa.lower() == degreeIntervalSa.upper():
1025
        return int(degreeIntervalSa.lower())
1026
    else:
1027
        if degreeIntervalSa.upper().is_infinity():
1028
            return None
1029
        else:
1030
            return int(degreeIntervalSa.upper())
1031
    # End pobyso_guess_degree_so_sa
1032

    
1033
def pobyso_inf_so_so(intervalSo):
1034
    """
1035
    Very thin wrapper around sollya_lib_inf().
1036
    """
1037
    return sollya_lib_inf(intervalSo)
1038
# End pobyso_inf_so_so.
1039
    
1040
def pobyso_infnorm_so_so(func, interval, file = None, intervalList = None):
1041
    print "Do not use this function. User pobyso_supnorm_so_so instead."
1042
    return None
1043

    
1044
def pobyso_interval_to_range_sa_so(intervalSa, precisionSa=None):
1045
    if precisionSa is None:
1046
        precisionSa = intervalSa.parent().precision()
1047
    intervalSo = pobyso_bounds_to_range_sa_so(intervalSa.lower(),\
1048
                                              intervalSa.upper(),\
1049
                                              precisionSa)
1050
    return intervalSo
1051
# End pobyso_interval_to_range_sa_so
1052

    
1053
def pobyso_is_error_so_sa(objSo):
1054
    """
1055
    Thin wrapper around the sollya_lib_obj_is_error() function.
1056
    """
1057
    if sollya_lib_obj_is_error(objSo) != 0:
1058
        return True
1059
    else:
1060
        return False
1061
# End pobyso_is_error-so_sa
1062

    
1063
def pobyso_is_floating_point_number_sa_sa(numberSa):
1064
    """
1065
    Check whether a Sage number is floating point.
1066
    Exception stuff added because numbers other than
1067
    floating-point ones do not have the is_real() attribute.
1068
    """
1069
    try:
1070
        return numberSa.is_real()
1071
    except AttributeError:
1072
        return False
1073
# End pobyso_is_floating_piont_number_sa_sa
1074

    
1075
def pobyso_lib_init():
1076
    sollya_lib_init(None)
1077

    
1078
def pobyso_lib_close():
1079
    sollya_lib_close(None)
1080
    
1081
def pobyso_name_free_variable(freeVariableNameSa):
1082
    """ Legacy function. See pobyso_name_free_variable_sa_so. """
1083
    pobyso_name_free_variable_sa_so(freeVariableNameSa)
1084

    
1085
def pobyso_name_free_variable_sa_so(freeVariableNameSa):
1086
    """
1087
    Set the free variable name in Sollya from a Sage string.
1088
    """
1089
    sollya_lib_name_free_variable(freeVariableNameSa)
1090

    
1091
def pobyso_parse_string(string):
1092
    """ Legacy function. See pobyso_parse_string_sa_so. """
1093
    return pobyso_parse_string_sa_so(string)
1094
 
1095
def pobyso_parse_string_sa_so(string):
1096
    """
1097
    Get the Sollya expression computed from a Sage string or
1098
    a Sollya error object if parsing failed.
1099
    """
1100
    return sollya_lib_parse_string(string)
1101

    
1102
def pobyso_precision_so_sa(ctExpSo):
1103
    """
1104
    Computes the necessary precision to represent a number.
1105
    If x is not zero, it can be uniquely written as x = m · 2e 
1106
    where m is an odd integer and e is an integer. 
1107
    precision(x) returns the number of bits necessary to write m 
1108
    in binary (i.e. ceil(log2(m))).
1109
    """
1110
    #TODO: take care of the special case: 0, @NaN@, @Inf@
1111
    precisionSo = sollya_lib_precision(ctExpSo)
1112
    precisionSa = pobyso_constant_from_int_so_sa(precisionSo)
1113
    sollya_lib_clear_obj(precisionSo)
1114
    return precisionSa
1115
# End pobyso_precision_so_sa
1116

    
1117
def pobyso_polynomial_coefficients_progressive_truncate_so_so(polySo,
1118
                                                              funcSo,
1119
                                                              icSo,
1120
                                                              intervalSo,
1121
                                                              itpSo,
1122
                                                              ftpSo,
1123
                                                              maxPrecSo,
1124
                                                              maxErrSo):
1125
    print "Input arguments:"
1126
    pobyso_autoprint(polySo)
1127
    pobyso_autoprint(funcSo)
1128
    pobyso_autoprint(icSo)
1129
    pobyso_autoprint(intervalSo)
1130
    pobyso_autoprint(itpSo)
1131
    pobyso_autoprint(ftpSo)
1132
    pobyso_autoprint(maxPrecSo)
1133
    pobyso_autoprint(maxErrSo)
1134
    print "________________"
1135
    
1136
    precDecayFuncSo = \
1137
        pobyso_parse_string("3/8*(exp(x/2.2)-1) + 2/8*(2*x)^2 + (1-3/8-2/8)*x")
1138
    pobyso_autoprint(precDecayFuncSo)
1139
    return None
1140
    
1141
def pobyso_range(rnLowerBound, rnUpperBound):
1142
    """ Legacy function. See pobyso_range_sa_so. """
1143
    return pobyso_range_sa_so(rnLowerBound, rnUpperBound) 
1144

    
1145

    
1146
def pobyso_range_to_interval_so_sa(rangeSo, realIntervalFieldSa = None):
1147
    """
1148
    Get a Sage interval from a Sollya range.
1149
    If no realIntervalField is given as a parameter, the Sage interval
1150
    precision is that of the Sollya range.
1151
    Otherwise, the precision is that of the realIntervalField. In this case
1152
    rounding may happen.
1153
    """
1154
    if realIntervalFieldSa is None:
1155
        precSa = pobyso_get_prec_of_range_so_sa(rangeSo)
1156
        realIntervalFieldSa = RealIntervalField(precSa)
1157
    intervalSa = \
1158
        pobyso_get_interval_from_range_so_sa(rangeSo, realIntervalFieldSa) 
1159
    return intervalSa
1160
# End pobyso_range_to_interval_so_sa
1161

    
1162
def pobyso_rat_poly_sa_so(polySa, precSa = None):
1163
    """
1164
    Create a Sollya polynomial from a Sage rational polynomial.
1165
    """
1166
    ## TODO: filter arguments.
1167
    ## Precision. If no precision is given, use the current precision
1168
    #  of Sollya.
1169
    if precSa is None:
1170
        precSa =  pobyso_get_prec_so_sa()
1171
    #print "Precision:",  precSa
1172
    RRR = RealField(precSa)
1173
    ## Create a Sage polynomial in the "right" precision.
1174
    P_RRR = RRR[polySa.variables()[0]]
1175
    polyFloatSa = P_RRR(polySa)
1176
    ## Make sure no precision is provided: pobyso_float_poly_sa_so will
1177
    #  recover it all by itself and not make an extra conversion.
1178
    return pobyso_float_poly_sa_so(polyFloatSa)
1179
    
1180
# End pobyso_rat_poly_sa_so    
1181
    
1182
def pobyso_remez_canonical_sa_sa(func, \
1183
                                 degree, \
1184
                                 lowerBound, \
1185
                                 upperBound, \
1186
                                 weight = None, \
1187
                                 quality = None):
1188
    """
1189
    All arguments are Sage/Python.
1190
    The functions (func and weight) must be passed as expressions or strings.
1191
    Otherwise the function fails. 
1192
    The return value is a Sage polynomial.
1193
    """
1194
    var('zorglub')    # Dummy variable name for type check only. Type of 
1195
    # zorglub is "symbolic expression".
1196
    polySo = pobyso_remez_canonical_sa_so(func, \
1197
                                 degree, \
1198
                                 lowerBound, \
1199
                                 upperBound, \
1200
                                 weight, \
1201
                                 quality)
1202
    # String test
1203
    if parent(func) == parent("string"):
1204
        functionSa = eval(func)
1205
    # Expression test.
1206
    elif type(func) == type(zorglub):
1207
        functionSa = func
1208
    else:
1209
        return None
1210
    #
1211
    maxPrecision = 0
1212
    if polySo is None:
1213
        return(None)
1214
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
1215
    RRRRSa = RealField(maxPrecision)
1216
    polynomialRingSa = RRRRSa[functionSa.variables()[0]]
1217
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, RRRRSa)
1218
    polySa = polynomial(expSa, polynomialRingSa)
1219
    sollya_lib_clear_obj(polySo)
1220
    return(polySa)
1221
# End pobyso_remez_canonical_sa_sa
1222
    
1223
def pobyso_remez_canonical(func, \
1224
                           degree, \
1225
                           lowerBound, \
1226
                           upperBound, \
1227
                           weight = "1", \
1228
                           quality = None):
1229
    """ Legacy function. See pobyso_remez_canonical_sa_so. """
1230
    return(pobyso_remez_canonical_sa_so(func, \
1231
                                        degree, \
1232
                                        lowerBound, \
1233
                                        upperBound, \
1234
                                        weight, \
1235
                                        quality))
1236
# End pobyso_remez_canonical.
1237

    
1238
def pobyso_remez_canonical_sa_so(func, \
1239
                                 degree, \
1240
                                 lowerBound, \
1241
                                 upperBound, \
1242
                                 weight = None, \
1243
                                 quality = None):
1244
    """
1245
    All arguments are Sage/Python.
1246
    The functions (func and weight) must be passed as expressions or strings.
1247
    Otherwise the function fails. 
1248
    The return value is a pointer to a Sollya function.
1249
    """
1250
    var('zorglub')    # Dummy variable name for type check only. Type of
1251
    # zorglub is "symbolic expression".
1252
    currentVariableNameSa = None
1253
    # The func argument can be of different types (string, 
1254
    # symbolic expression...)
1255
    if parent(func) == parent("string"):
1256
        localFuncSa = eval(func)
1257
        if len(localFuncSa.variables()) > 0:
1258
            currentVariableNameSa = localFuncSa.variables()[0]
1259
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1260
            functionSo = \
1261
              sollya_lib_parse_string(localFuncSa._assume_str().replace('_SAGE_VAR_', ''))
1262
    # Expression test.
1263
    elif type(func) == type(zorglub):
1264
        # Until we are able to translate Sage expressions into Sollya 
1265
        # expressions : parse the string version.
1266
        if len(func.variables()) > 0:
1267
            currentVariableNameSa = func.variables()[0]
1268
            sollya_lib_name_free_variable(str(currentVariableNameSa))
1269
            functionSo = \
1270
              sollya_lib_parse_string(func._assume_str().replace('_SAGE_VAR_', ''))
1271
    else:
1272
        return(None)
1273
    if weight is None: # No weight given -> 1.
1274
        weightSo = pobyso_constant_1_sa_so()
1275
    elif parent(weight) == parent("string"): # Weight given as string: parse it.
1276
        weightSo = sollya_lib_parse_string(func)
1277
    elif type(weight) == type(zorglub): # Weight given as symbolice expression.
1278
        functionSo = \
1279
          sollya_lib_parse_string_sa_so(weight._assume_str().replace('_SAGE_VAR_', ''))
1280
    else:
1281
        return(None)
1282
    degreeSo = pobyso_constant_from_int(degree)
1283
    rangeSo = pobyso_bounds_to_range_sa_so(lowerBound, upperBound)
1284
    if not quality is None:
1285
        qualitySo= pobyso_constant_sa_so(quality)
1286
    else:
1287
        qualitySo = None
1288
        
1289
    remezPolySo = sollya_lib_remez(functionSo, \
1290
                                   degreeSo, \
1291
                                   rangeSo, \
1292
                                   weightSo, \
1293
                                   qualitySo, \
1294
                                   None)
1295
    sollya_lib_clear_obj(functionSo)
1296
    sollya_lib_clear_obj(degreeSo)
1297
    sollya_lib_clear_obj(rangeSo)
1298
    sollya_lib_clear_obj(weightSo)
1299
    if not qualitySo is None:
1300
        sollya_lib_clear_obj(qualitySo)
1301
    return(remezPolySo)
1302
# End pobyso_remez_canonical_sa_so
1303

    
1304
def pobyso_remez_canonical_so_so(funcSo, \
1305
                                 degreeSo, \
1306
                                 rangeSo, \
1307
                                 weightSo = pobyso_constant_1_sa_so(),\
1308
                                 qualitySo = None):
1309
    """
1310
    All arguments are pointers to Sollya objects.
1311
    The return value is a pointer to a Sollya function.
1312
    """
1313
    if not sollya_lib_obj_is_function(funcSo):
1314
        return(None)
1315
    return(sollya_lib_remez(funcSo, degreeSo, rangeSo, weightSo, qualitySo, None))
1316
# End pobyso_remez_canonical_so_so.
1317

    
1318
def pobyso_round_coefficients_single_so_so(polySo, precSo):
1319
    """
1320
    Create a rounded coefficients polynomial from polynomial argument to
1321
    the number of bits in size argument.
1322
    All coefficients are set to the same precision.
1323
    """
1324
    ## TODO: check arguments.
1325
    endEllipListSo = pobyso_build_end_elliptic_list_so_so(precSo)
1326
    polySo = sollya_lib_roundcoefficients(polySo, endEllipListSo, None)
1327
    #sollya_lib_clear_obj(endEllipListSo)
1328
    return polySo
1329
    
1330
# End pobyso_round_coefficients_single_so_so
1331

    
1332
def pobyso_set_canonical_off():
1333
    sollya_lib_set_canonical(sollya_lib_off())
1334

    
1335
def pobyso_set_canonical_on():
1336
    sollya_lib_set_canonical(sollya_lib_on())
1337

    
1338
def pobyso_set_prec(p):
1339
    """ Legacy function. See pobyso_set_prec_sa_so. """
1340
    pobyso_set_prec_sa_so(p)
1341

    
1342
def pobyso_set_prec_sa_so(p):
1343
    a = c_int(p)
1344
    precSo = c_void_p(sollya_lib_constant_from_int(a))
1345
    sollya_lib_set_prec(precSo, None)
1346
# End pobyso_set_prec_sa_so.
1347

    
1348
def pobyso_set_prec_so_so(newPrecSo):
1349
    sollya_lib_set_prec(newPrecSo, None)
1350
# End pobyso_set_prec_so_so.
1351

    
1352
def pobyso_inf_so_so(intervalSo):
1353
    """
1354
    Very thin wrapper around sollya_lib_inf().
1355
    """
1356
    return sollya_lib_inf(intervalSo)
1357
# End pobyso_inf_so_so.
1358
    
1359
def pobyso_supnorm_so_so(polySo, funcSo, intervalSo, errorTypeSo = None,\
1360
                         accuracySo = None):
1361
    """
1362
    Computes the supnorm of the approximation error between the given 
1363
    polynomial and function.
1364
    errorTypeSo defaults to "absolute".
1365
    accuracySo defaults to 2^(-40).
1366
    """
1367
    if errorTypeSo is None:
1368
        errorTypeSo = sollya_lib_absolute(None)
1369
        errorTypeIsNone = True
1370
    else:
1371
        errorTypeIsNone = False
1372
    #
1373
    if accuracySo is None:
1374
        # Notice the **!
1375
        accuracySo = pobyso_constant_sa_so(RR(2**(-40)))
1376
        accuracyIsNone = True
1377
    else:
1378
        accuracyIsNone = False
1379
    pobyso_autoprint(accuracySo)
1380
    resultSo = \
1381
        sollya_lib_supnorm(polySo, funcSo, intervalSo, errorTypeSo, \
1382
                              accuracySo)
1383
    if errorTypeIsNone:
1384
        sollya_lib_clear_obj(errorTypeSo)
1385
    if accuracyIsNone:
1386
        sollya_lib_clear_obj(accuracySo)
1387
    return resultSo
1388
# End pobyso_supnorm_so_so
1389

    
1390
def pobyso_taylor_expansion_no_change_var_so_so(functionSo, 
1391
                                                degreeSo, 
1392
                                                rangeSo,
1393
                                                errorTypeSo=None, 
1394
                                                sollyaPrecSo=None):
1395
    """
1396
    Compute the Taylor expansion without the variable change
1397
    x -> x-intervalCenter.
1398
    """
1399
    # No global change of the working precision.
1400
    if not sollyaPrecSo is None:
1401
        initialPrecSo = sollya_lib_get_prec(None)
1402
        sollya_lib_set_prec(sollyaPrecSo)
1403
    # Error type stuff: default to absolute.
1404
    if errorTypeSo is None:
1405
        errorTypeIsNone = True
1406
        errorTypeSo = sollya_lib_absolute(None)
1407
    else:
1408
        errorTypeIsNone = False
1409
    intervalCenterSo = sollya_lib_mid(rangeSo, None)
1410
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo,
1411
                                         intervalCenterSo,
1412
                                         rangeSo, errorTypeSo, None)
1413
    # taylorFormListSaSo is a Python list of Sollya objects references that 
1414
    # are copies of the elements of taylorFormSo.
1415
    # pobyso_get_list_elements_so_so clears taylorFormSo.
1416
    (taylorFormListSaSo, numElementsSa, isEndEllipticSa) = \
1417
        pobyso_get_list_elements_so_so(taylorFormSo)
1418
    polySo = sollya_lib_copy_obj(taylorFormListSaSo[0])
1419
    #print "Num elements:", numElementsSa
1420
    sollya_lib_clear_obj(taylorFormSo)
1421
    #polySo = taylorFormListSaSo[0]
1422
    #errorRangeSo = sollya_lib_copy_obj(taylorFormListSaSo[2])
1423
    errorRangeSo = taylorFormListSaSo[2]
1424
    # No copy_obj needed here: a new objects are created.
1425
    maxErrorSo    = sollya_lib_sup(errorRangeSo)
1426
    minErrorSo    = sollya_lib_inf(errorRangeSo)
1427
    absMaxErrorSo = sollya_lib_abs(maxErrorSo)
1428
    absMinErrorSo = sollya_lib_abs(minErrorSo)
1429
    sollya_lib_clear_obj(maxErrorSo)
1430
    sollya_lib_clear_obj(minErrorSo)
1431
    absMaxErrorSa = pobyso_get_constant_as_rn_so_sa(absMaxErrorSo)
1432
    absMinErrorSa = pobyso_get_constant_as_rn_so_sa(absMinErrorSo)
1433
    # If changed, reset the Sollya working precision.
1434
    if not sollyaPrecSo is None:
1435
        sollya_lib_set_prec(initialPrecSo)
1436
        sollya_lib_clear_obj(initialPrecSo)
1437
    if errorTypeIsNone:
1438
        sollya_lib_clear_obj(errorTypeSo)
1439
    pobyso_clear_taylorform_sa_so(taylorFormListSaSo)
1440
    if absMaxErrorSa > absMinErrorSa:
1441
        sollya_lib_clear_obj(absMinErrorSo)
1442
        return((polySo, intervalCenterSo, absMaxErrorSo))
1443
    else:
1444
        sollya_lib_clear_obj(absMaxErrorSo)
1445
        return((polySo, intervalCenterSo, absMinErrorSo))
1446
# end pobyso_taylor_expansion_no_change_var_so_so
1447

    
1448
def pobyso_taylor_expansion_with_change_var_so_so(functionSo, degreeSo, \
1449
                                                  rangeSo, \
1450
                                                  errorTypeSo=None, \
1451
                                                  sollyaPrecSo=None):
1452
    """
1453
    Compute the Taylor expansion with the variable change
1454
    x -> (x-intervalCenter) included.
1455
    """
1456
    # No global change of the working precision.
1457
    if not sollyaPrecSo is None:
1458
        initialPrecSo = sollya_lib_get_prec(None)
1459
        sollya_lib_set_prec(sollyaPrecSo)
1460
    #
1461
    # Error type stuff: default to absolute.
1462
    if errorTypeSo is None:
1463
        errorTypeIsNone = True
1464
        errorTypeSo = sollya_lib_absolute(None)
1465
    else:
1466
        errorTypeIsNone = False
1467
    intervalCenterSo = sollya_lib_mid(rangeSo)
1468
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, \
1469
                                         intervalCenterSo, \
1470
                                         rangeSo, errorTypeSo, None)
1471
    # taylorFormListSaSo is a Python list of Sollya objects references that 
1472
    # are copies of the elements of taylorFormSo.
1473
    # pobyso_get_list_elements_so_so clears taylorFormSo.
1474
    (taylorFormListSo, numElements, isEndElliptic) = \
1475
        pobyso_get_list_elements_so_so(taylorFormSo)
1476
    polySo = taylorFormListSo[0]
1477
    errorRangeSo = taylorFormListSo[2]
1478
    maxErrorSo    = sollya_lib_sup(errorRangeSo)
1479
    minErrorSo    = sollya_lib_inf(errorRangeSo)
1480
    absMaxErrorSo = sollya_lib_abs(maxErrorSo)
1481
    absMinErrorSo = sollya_lib_abs(minErrorSo)
1482
    sollya_lib_clear_obj(maxErrorSo)
1483
    sollya_lib_clear_obj(minErrorSo)
1484
    absMaxErrorSa = pobyso_get_constant_as_rn_so_sa(absMaxErrorSo)
1485
    absMinErrorSa = pobyso_get_constant_as_rn_so_sa(absMinErrorSo)
1486
    changeVarExpSo = sollya_lib_build_function_sub(\
1487
                       sollya_lib_build_function_free_variable(),\
1488
                       sollya_lib_copy_obj(intervalCenterSo))
1489
    polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpSo)
1490
    sollya_lib_clear_obj(polySo) 
1491
    sollya_lib_clear_obj(changeVarExpSo)
1492
    # If changed, reset the Sollya working precision.
1493
    if not sollyaPrecSo is None:
1494
        sollya_lib_set_prec(initialPrecSo)
1495
        sollya_lib_clear_obj(initialPrecSo)
1496
    if errorTypeIsNone:
1497
        sollya_lib_clear_obj(errorTypeSo)
1498
    sollya_lib_clear_obj(taylorFormSo)
1499
    # Do not clear maxErrorSo.
1500
    if absMaxErrorSa > absMinErrorSa:
1501
        sollya_lib_clear_obj(absMinErrorSo)
1502
        return((polyVarChangedSo, intervalCenterSo, absMaxErrorSo))
1503
    else:
1504
        sollya_lib_clear_obj(absMaxErrorSo)
1505
        return((polyVarChangedSo, intervalCenterSo, absMinErrorSo))
1506
# end pobyso_taylor_expansion_with_change_var_so_so
1507

    
1508
def pobyso_taylor(function, degree, point):
1509
    """ Legacy function. See pobysoTaylor_so_so. """
1510
    return(pobyso_taylor_so_so(function, degree, point))
1511

    
1512
def pobyso_taylor_so_so(functionSo, degreeSo, pointSo):
1513
    return(sollya_lib_taylor(functionSo, degreeSo, pointSo))
1514
    
1515
def pobyso_taylorform(function, degree, point = None, 
1516
                      interval = None, errorType=None):
1517
    """ Legacy function. See pobyso_taylorform_sa_sa;"""
1518
    
1519
def pobyso_taylorform_sa_sa(functionSa, \
1520
                            degreeSa, \
1521
                            pointSa, \
1522
                            intervalSa=None, \
1523
                            errorTypeSa=None, \
1524
                            precisionSa=None):
1525
    """
1526
    Compute the Taylor form of 'degreeSa' for 'functionSa' at 'pointSa' 
1527
    for 'intervalSa' with 'errorTypeSa' (a string) using 'precisionSa'. 
1528
    point: must be a Real or a Real interval.
1529
    return the Taylor form as an array
1530
    TODO: take care of the interval and of the point when it is an interval;
1531
          when errorType is not None;
1532
          take care of the other elements of the Taylor form (coefficients 
1533
          errors and delta.
1534
    """
1535
    # Absolute as the default error.
1536
    if errorTypeSa is None:
1537
        errorTypeSo = sollya_lib_absolute()
1538
    elif errorTypeSa == "relative":
1539
        errorTypeSo = sollya_lib_relative()
1540
    elif errortypeSa == "absolute":
1541
        errorTypeSo = sollya_lib_absolute()
1542
    else:
1543
        # No clean up needed.
1544
        return None
1545
    # Global precision stuff
1546
    precisionChangedSa = False
1547
    currentSollyaPrecSo = pobyso_get_prec_so()
1548
    currentSollyaPrecSa = pobyso_constant_from_int_so_sa(currentSollyaPrecSo)
1549
    if not precisionSa is None:
1550
        if precisionSa > currentSollyaPrecSa:
1551
            pobyso_set_prec_sa_so(precisionSa)
1552
            precisionChangedSa = True
1553
            
1554
    if len(functionSa.variables()) > 0:
1555
        varSa = functionSa.variables()[0]
1556
        pobyso_name_free_variable_sa_so(str(varSa))
1557
    # In any case (point or interval) the parent of pointSa has a precision
1558
    # method.
1559
    pointPrecSa = pointSa.parent().precision()
1560
    if precisionSa > pointPrecSa:
1561
        pointPrecSa = precisionSa
1562
    # In any case (point or interval) pointSa has a base_ring() method.
1563
    pointBaseRingString = str(pointSa.base_ring())
1564
    if re.search('Interval', pointBaseRingString) is None: # Point
1565
        pointSo = pobyso_constant_sa_so(pointSa, pointPrecSa)
1566
    else: # Interval.
1567
        pointSo = pobyso_interval_to_range_sa_so(pointSa, pointPrecSa)
1568
    # Sollyafy the function.
1569
    functionSo = pobyso_parse_string_sa_so(functionSa._assume_str().replace('_SAGE_VAR_', ''))
1570
    if sollya_lib_obj_is_error(functionSo):
1571
        print "pobyso_tailorform: function string can't be parsed!"
1572
        return None
1573
    # Sollyafy the degree
1574
    degreeSo = sollya_lib_constant_from_int(int(degreeSa))
1575
    # Sollyafy the point
1576
    # Call Sollya
1577
    taylorFormSo = \
1578
        sollya_lib_taylorform(functionSo, degreeSo, pointSo, errorTypeSo,\
1579
                                         None)
1580
    sollya_lib_clear_obj(functionSo)
1581
    sollya_lib_clear_obj(degreeSo)
1582
    sollya_lib_clear_obj(pointSo)
1583
    sollya_lib_clear_obj(errorTypeSo)
1584
    (tfsAsList, numElements, isEndElliptic) = \
1585
            pobyso_get_list_elements_so_so(taylorFormSo)
1586
    polySo = tfsAsList[0]
1587
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
1588
    polyRealField = RealField(maxPrecision)
1589
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, polyRealField)
1590
    if precisionChangedSa:
1591
        sollya_lib_set_prec(currentSollyaPrecSo)
1592
        sollya_lib_clear_obj(currentSollyaPrecSo)
1593
    polynomialRing = polyRealField[str(varSa)]
1594
    polySa = polynomial(expSa, polynomialRing)
1595
    taylorFormSa = [polySa]
1596
    # Final clean-up.
1597
    sollya_lib_clear_obj(taylorFormSo)
1598
    return(taylorFormSa)
1599
# End pobyso_taylor_form_sa_sa
1600

    
1601
def pobyso_taylorform_so_so(functionSo, degreeSo, pointSo, intervalSo=None, \
1602
                            errorTypeSo=None):
1603
    createdErrorType = False
1604
    if errorTypeSo is None:
1605
        errorTypeSo = sollya_lib_absolute()
1606
        createdErrorType = True
1607
    else:
1608
        #TODO: deal with the other case.
1609
        pass
1610
    if intervalSo is None:
1611
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
1612
                                         errorTypeSo, None)
1613
    else:
1614
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
1615
                                         intervalSo, errorTypeSo, None)
1616
    if createdErrorType:
1617
        sollya_lib_clear_obj(errorTypeSo)
1618
    return resultSo
1619
        
1620

    
1621
def pobyso_univar_polynomial_print_reverse(polySa):
1622
    """ Legacy function. See pobyso_univar_polynomial_print_reverse_sa_sa. """
1623
    return(pobyso_univar_polynomial_print_reverse_sa_sa(polySa))
1624

    
1625
def pobyso_univar_polynomial_print_reverse_sa_sa(polySa):
1626
    """
1627
    Return the string representation of a univariate polynomial with
1628
    monomials ordered in the x^0..x^n order of the monomials.
1629
    Remember: Sage
1630
    """
1631
    polynomialRing = polySa.base_ring()
1632
    # A very expensive solution:
1633
    # -create a fake multivariate polynomial field with only one variable,
1634
    #   specifying a negative lexicographical order;
1635
    mpolynomialRing = PolynomialRing(polynomialRing.base(), \
1636
                                     polynomialRing.variable_name(), \
1637
                                     1, order='neglex')
1638
    # - convert the univariate argument polynomial into a multivariate
1639
    #   version;
1640
    p = mpolynomialRing(polySa)
1641
    # - return the string representation of the converted form.
1642
    # There is no simple str() method defined for p's class.
1643
    return(p.__str__())
1644
#
1645
print pobyso_get_prec()  
1646
pobyso_set_prec(165)
1647
print pobyso_get_prec()  
1648
a=100
1649
print type(a)
1650
id(a)
1651
print "Max arity: ", pobyso_max_arity
1652
print "Function tripleDouble (43) as a string: ", pobyso_function_type_as_string(43)
1653
print "Function None (44) as a string: ", pobyso_function_type_as_string(44)
1654
print "...Pobyso check done"