Statistiques
| Révision :

root / pobysoPythonSage / src / pobyso.py @ 117

Historique | Voir | Annoter | Télécharger (46,09 ko)

1
"""
2
Actual functions to use in Sage
3
ST 2012-11-13
4

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

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

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

    
86
pobyso_max_arity = 9
87

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

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

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

    
135
def pobyso_build_function_sub_so_so(exp1So, exp2So):
136
    return(sollya_lib_build_function_sub(exp1So, exp2So))
137

    
138
def pobyso_change_var_in_function_so_so(funcSo, chvarExpSo):
139
    """
140
    Variable change in a function.
141
    """
142
    return(sollya_lib_evaluate(funcSo,chvarExpSo))
143
# End pobyso_change_var_in_function_so_so     
144

    
145
def pobyso_chebyshevform_so_so(functionSo, degreeSo, intervalSo):
146
    resultSo = sollya_lib_chebyshevform(functionSo, degreeSo, intervalSo)
147
    return(resultSo)
148
# End pobyso_chebyshevform_so_so.
149

    
150
def pobyso_clear_taylorform_sa_so(taylorFormSaSo):
151
    """
152
    This method is necessary to correctly clean up the memory from Taylor forms.
153
    These are made of a Sollya object, a Sollya object list, a Sollya object.
154
    For no clearly understood reason, sollya_lib_clear_object_list crashed 
155
    when applied to the object list.
156
    Here, we decompose it into Sage list of Sollya objects references and we
157
     clear them one by one. 
158
    """
159
    sollya_lib_clear_obj(taylorFormSaSo[0])
160
    (coefficientsErrorsListSaSo, numElementsSa, isEndEllipticSa) = \
161
        pobyso_get_list_elements_so_so(taylorFormSaSo[1])
162
    for element in coefficientsErrorsListSaSo:
163
        sollya_lib_clear_obj(element)
164
    sollya_lib_clear_obj(taylorFormSaSo[1])
165
    sollya_lib_clear_obj(taylorFormSaSo[2])
166
# End pobyso_clear_taylorform_sa_so 
167

    
168
def pobyso_cmp(rnArgSa, cteSo):
169
    """
170
    Compare the MPFR value a RealNumber with that of a Sollya constant.
171
    
172
    Get the value of the Sollya constant into a RealNumber and compare
173
    using MPFR. Could be optimized by working directly with a mpfr_t
174
    for the intermediate number. 
175
    """
176
    # Get the precision of the Sollya constant to build a Sage RealNumber 
177
    # with enough precision.to hold it.
178
    precisionOfCte = c_int(0)
179
    # From the Sollya constant, create a local Sage RealNumber.
180
    sollya_lib_get_prec_of_constant(precisionOfCte, cteSo) 
181
    #print "Precision of constant: ", precisionOfCte
182
    RRRR = RealField(precisionOfCte.value)
183
    rnLocalSa = RRRR(0)
184
    sollya_lib_get_constant(get_rn_value(rnLocalSa), cteSo)
185
    #
186
    ## Compare the Sage RealNumber version of the Sollya constant with rnArg.
187
    return(cmp_rn_value(rnArgSa, rnLocal))
188
# End pobyso_smp
189

    
190
def pobyso_compute_pos_function_abs_val_bounds_sa_sa(funcSa, lowerBoundSa, \
191
                                                     upperBoundSa):
192
    """
193
    TODO: completely rework and test.
194
    """
195
    pobyso = pobyso_name_free_variable_sa_so(funcSa.variables()[0])
196
    funcSo = pobyso_parse_string(funcSa._assume_str())
197
    rangeSo = pobyso_range_sa_so(lowerBoundSa, upperBoundSa)
198
    infnormSo = pobyso_infnorm_so_so(funcSo,rangeSo)
199
    # Sollya return the infnorm as an interval.
200
    fMaxSa = pobyso_get_interval_from_range_so_sa(infnormSo)
201
    # Get the top bound and compute the binade top limit.
202
    fMaxUpperBoundSa = fMaxSa.upper()
203
    binadeTopLimitSa = 2**ceil(fMaxUpperBoundSa.log2())
204
    # Put up together the function to use to compute the lower bound.
205
    funcAuxSo = pobyso_parse_string(str(binadeTopLimitSa) +  \
206
                                    '-(' + f._assume_str() + ')')
207
    pobyso_autoprint(funcAuxSo)
208
    # Clear the Sollya range before a new call to infnorm and issue the call.
209
    sollya_lib_clear_obj(infnormSo)
210
    infnormSo = pobyso_infnorm_so_so(funcAuxSo,rangeSo)
211
    fMinSa = pobyso_get_interval_from_range_so_sa(infnormSo)
212
    sollya_lib_clear_obj(infnormSo)
213
    fMinLowerBoundSa = binadeTopLimitSa - fMinSa.lower()
214
    # Compute the maximum of the precisions of the different bounds.
215
    maxPrecSa = max([fMinLowerBoundSa.parent().precision(), \
216
                     fMaxUpperBoundSa.parent().precision()])
217
    # Create a RealIntervalField and create an interval with the "good" bounds.
218
    RRRI = RealIntervalField(maxPrecSa)
219
    imageIntervalSa = RRRI(fMinLowerBoundSa, fMaxUpperBoundSa)
220
    # Free the unneeded Sollya objects
221
    sollya_lib_clear_obj(funcSo)
222
    sollya_lib_clear_obj(funcAuxSo)
223
    sollya_lib_clear_obj(rangeSo)
224
    return(imageIntervalSa)
225
# End pobyso_compute_pos_function_abs_val_bounds_sa_sa
226

    
227
def pobyso_constant(rnArg):
228
    """ Legacy function. See pobyso_constant_sa_so. """
229
    return(pobyso_constant_sa_so(rnArg))
230
    
231
def pobyso_constant_sa_so(rnArgSa, precisionSa=None):
232
    """
233
    Create a Sollya constant from a Sage RealNumber.
234
    """
235
    # Precision stuff
236
    if precisionSa is None:
237
        precisionSa = rnArgSa.parent().precision()
238
    currentSollyaPrecisionSo = sollya_lib_get_prec()
239
    currentSollyaPrecisionSa = \
240
        pobyso_constant_from_int(currentSollyaPrecisionSo)
241
    # Sollya constant creation takes place here.
242
    if precisionSa > currentSollyaPrecisionSa:
243
        pobyso_set_prec_sa_so(precisionSa)
244
        constantSo = sollya_lib_constant(get_rn_value(rnArgSa))
245
        pobyso_set_prec_sa_so(currentSollyaPrecision)
246
    else:
247
        constantSo = sollya_lib_constant(get_rn_value(rnArgSa))
248
    sollya_lib_clear_obj(currentSollyaPrecisionSo)
249
    return(constantSo)
250
# End pobyso_constant_sa_so
251
     
252
def pobyso_constant_0_sa_so():
253
    """
254
    Obvious.
255
    """
256
    return(pobyso_constant_from_int_sa_so(0))
257

    
258
def pobyso_constant_1():
259
    """
260
    Obvious.
261
    Legacy function. See pobyso_constant_so_so. 
262
    """
263
    return(pobyso_constant_1_sa_so())
264

    
265
def pobyso_constant_1_sa_so():
266
    """
267
    Obvious.
268
    """
269
    return(pobyso_constant_from_int_sa_so(1))
270

    
271
def pobyso_constant_from_int(anInt):
272
    """ Legacy function. See pobyso_constant_from_int_sa_so. """
273
    return(pobyso_constant_from_int_sa_so(anInt))
274

    
275
def pobyso_constant_from_int_sa_so(anInt):
276
    """
277
    Get a Sollya constant from a Sage int.
278
    """
279
    return(sollya_lib_constant_from_int(int(anInt)))
280

    
281
def pobyso_constant_from_int_so_sa(constSo):
282
    """
283
    Get a Sage int from a Sollya int constant.
284
    Usefull for precision or powers in polynomials.
285
    """
286
    constSa = c_int(0)
287
    sollya_lib_get_constant_as_int(byref(constSa), constSo)
288
    return(constSa.value)
289
# End pobyso_constant_from_int_so_sa
290

    
291
def pobyso_function_type_as_string(funcType):
292
    """ Legacy function. See pobyso_function_type_as_string_so_sa. """
293
    return(pobyso_function_type_as_string_so_sa(funcType))
294

    
295
def pobyso_function_type_as_string_so_sa(funcType):
296
    """
297
    Numeric Sollya function codes -> Sage mathematical function names.
298
    Notice that pow -> ^ (a la Sage, not a la Python).
299
    """
300
    if funcType == SOLLYA_BASE_FUNC_ABS:
301
        return "abs"
302
    elif funcType == SOLLYA_BASE_FUNC_ACOS:
303
        return "arccos"
304
    elif funcType == SOLLYA_BASE_FUNC_ACOSH:
305
        return "arccosh"
306
    elif funcType == SOLLYA_BASE_FUNC_ADD:
307
        return "+"
308
    elif funcType == SOLLYA_BASE_FUNC_ASIN:
309
        return "arcsin"
310
    elif funcType == SOLLYA_BASE_FUNC_ASINH:
311
        return "arcsinh"
312
    elif funcType == SOLLYA_BASE_FUNC_ATAN:
313
        return "arctan"
314
    elif funcType == SOLLYA_BASE_FUNC_ATANH:
315
        return "arctanh"
316
    elif funcType == SOLLYA_BASE_FUNC_CEIL:
317
        return "ceil"
318
    elif funcType == SOLLYA_BASE_FUNC_CONSTANT:
319
        return "cte"
320
    elif funcType == SOLLYA_BASE_FUNC_COS:
321
        return "cos"
322
    elif funcType == SOLLYA_BASE_FUNC_COSH:
323
        return "cosh"
324
    elif funcType == SOLLYA_BASE_FUNC_DIV:
325
        return "/"
326
    elif funcType == SOLLYA_BASE_FUNC_DOUBLE:
327
        return "double"
328
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEDOUBLE:
329
        return "doubleDouble"
330
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEEXTENDED:
331
        return "doubleDxtended"
332
    elif funcType == SOLLYA_BASE_FUNC_ERF:
333
        return "erf"
334
    elif funcType == SOLLYA_BASE_FUNC_ERFC:
335
        return "erfc"
336
    elif funcType == SOLLYA_BASE_FUNC_EXP:
337
        return "exp"
338
    elif funcType == SOLLYA_BASE_FUNC_EXP_M1:
339
        return "expm1"
340
    elif funcType == SOLLYA_BASE_FUNC_FLOOR:
341
        return "floor"
342
    elif funcType == SOLLYA_BASE_FUNC_FREE_VARIABLE:
343
        return "freeVariable"
344
    elif funcType == SOLLYA_BASE_FUNC_HALFPRECISION:
345
        return "halfPrecision"
346
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYCONSTANT:
347
        return "libraryConstant"
348
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYFUNCTION:
349
        return "libraryFunction"
350
    elif funcType == SOLLYA_BASE_FUNC_LOG:
351
        return "log"
352
    elif funcType == SOLLYA_BASE_FUNC_LOG_10:
353
        return "log10"
354
    elif funcType == SOLLYA_BASE_FUNC_LOG_1P:
355
        return "log1p"
356
    elif funcType == SOLLYA_BASE_FUNC_LOG_2:
357
        return "log2"
358
    elif funcType == SOLLYA_BASE_FUNC_MUL:
359
        return "*"
360
    elif funcType == SOLLYA_BASE_FUNC_NEARESTINT:
361
        return "round"
362
    elif funcType == SOLLYA_BASE_FUNC_NEG:
363
        return "__neg__"
364
    elif funcType == SOLLYA_BASE_FUNC_PI:
365
        return "pi"
366
    elif funcType == SOLLYA_BASE_FUNC_POW:
367
        return "^"
368
    elif funcType == SOLLYA_BASE_FUNC_PROCEDUREFUNCTION:
369
        return "procedureFunction"
370
    elif funcType == SOLLYA_BASE_FUNC_QUAD:
371
        return "quad"
372
    elif funcType == SOLLYA_BASE_FUNC_SIN:
373
        return "sin"
374
    elif funcType == SOLLYA_BASE_FUNC_SINGLE:
375
        return "single"
376
    elif funcType == SOLLYA_BASE_FUNC_SINH:
377
        return "sinh"
378
    elif funcType == SOLLYA_BASE_FUNC_SQRT:
379
        return "sqrt"
380
    elif funcType == SOLLYA_BASE_FUNC_SUB:
381
        return "-"
382
    elif funcType == SOLLYA_BASE_FUNC_TAN:
383
        return "tan"
384
    elif funcType == SOLLYA_BASE_FUNC_TANH:
385
        return "tanh"
386
    elif funcType == SOLLYA_BASE_FUNC_TRIPLEDOUBLE:
387
        return "tripleDouble"
388
    else:
389
        return None
390

    
391
def pobyso_get_constant(rnArgSa, constSo):
392
    """ Legacy function. See pobyso_get_constant_so_sa. """
393
    return(pobyso_get_constant_so_sa(rnArgSa, constSo))
394

    
395
def pobyso_get_constant_so_sa(rnArgSa, constSo):
396
    """
397
    Set the value of rnArgSo to the value of constSo in MPFR_RNDN mode.
398
    rnArg must already exist and belong to some RealField.
399
    We assume that constSo points to a Sollya constant.
400
    """
401
    return(sollya_lib_get_constant(get_rn_value(rnArgSa), constSo))
402
    
403
def pobyso_get_constant_as_rn(ctExpSo):
404
    """ 
405
    Legacy function. See pobyso_get_constant_as_rn_so_sa. 
406
    """ 
407
    return(pobyso_get_constant_as_rn_so_sa(ctExpSo))
408
    
409
def pobyso_get_constant_as_rn_so_sa(constExpSo):
410
    """
411
    Get a Sollya constant as a Sage "real number".
412
    The precision of the floating-point number returned is that of the Sollya
413
    constant.
414
    """
415
    precisionSa  = pobyso_get_prec_of_constant_so_sa(constExpSo) 
416
    RRRR = RealField(precisionSa)
417
    rnSa = RRRR(0)
418
    sollya_lib_get_constant(get_rn_value(rnSa), constExpSo)
419
    return(rnSa)
420
# End pobyso_get_constant_as_rn_so_sa
421

    
422
def pobyso_get_constant_as_rn_with_rf(ctExp, realField):
423
    """ 
424
    Legacy function. See pobyso_get_constant_as_rn_with_rf_so_sa.
425
    """
426
    return(pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField))
427
    
428
def pobyso_get_constant_as_rn_with_rf_so_sa(ctExpSo, realFieldSa = None):
429
    """
430
    Get a Sollya constant as a Sage "real number".
431
    If no real field is specified, the precision of the floating-point number 
432
    returned is that of the Sollya constant.
433
    Otherwise is is that of the real field. Hence rounding may happen.
434
    """
435
    if realFieldSa is None:
436
        sollyaPrecSa = pobyso_get_prec_of_constant_so_sa(ctExpSo)
437
        realFieldSa = RealField(sollyaPrecSa)
438
    rnSa = realFieldSa(0)
439
    sollya_lib_get_constant(get_rn_value(rnSa), ctExpSo)
440
    return(rnSa)
441
# End pobyso_get_constant_as_rn_with_rf_so_sa
442

    
443
def pobyso_get_free_variable_name():
444
    """ 
445
    Legacy function. See pobyso_get_free_variable_name_so_sa.
446
    """
447
    return(pobyso_get_free_variable_name_so_sa())
448

    
449
def pobyso_get_free_variable_name_so_sa():
450
    return(sollya_lib_get_free_variable_name())
451
    
452
def pobyso_get_function_arity(expressionSo):
453
    """ 
454
    Legacy function. See pobyso_get_function_arity_so_sa.
455
    """
456
    return(pobyso_get_function_arity_so_sa(expressionSo))
457

    
458
def pobyso_get_function_arity_so_sa(expressionSo):
459
    arity = c_int(0)
460
    sollya_lib_get_function_arity(byref(arity),expressionSo)
461
    return(int(arity.value))
462

    
463
def pobyso_get_head_function(expressionSo):
464
    """ 
465
    Legacy function. See pobyso_get_head_function_so_sa. 
466
    """
467
    return(pobyso_get_head_function_so_sa(expressionSo)) 
468

    
469
def pobyso_get_head_function_so_sa(expressionSo):
470
    functionType = c_int(0)
471
    sollya_lib_get_head_function(byref(functionType), expressionSo, None)
472
    return(int(functionType.value))
473

    
474
def pobyso_get_interval_from_range_so_sa(soRange, realIntervalFieldSa = None ):
475
    """
476
    Return the Sage interval corresponding to the Sollya range argument.
477
    If no reaIntervalField is passed as an argument, the interval bounds are not
478
    rounded: they are elements of RealIntervalField of the "right" precision
479
    to hold all the digits.
480
    """
481
    prec = c_int(0)
482
    if realIntervalFieldSa is None:
483
        retval = sollya_lib_get_prec_of_range(byref(prec), soRange, None)
484
        if retval == 0:
485
            return(None)
486
        realIntervalFieldSa = RealIntervalField(prec.value)
487
    intervalSa = realIntervalFieldSa(0,0)
488
    retval = \
489
        sollya_lib_get_interval_from_range(get_interval_value(intervalSa),\
490
                                           soRange)
491
    if retval == 0:
492
        return(None)
493
    return(intervalSa)
494
# End pobyso_get_interval_from_range_so_sa
495

    
496
def pobyso_get_list_elements(soObj):
497
    """ Legacy function. See pobyso_get_list_elements_so_so. """
498
    return(pobyso_get_list_elements_so_so(soObj))
499
 
500
def pobyso_get_list_elements_so_so(objectListSo):
501
    """
502
    Get the list elements as a Sage/Python array of Sollya objects.
503
    The other data returned are Sage/Python objects.
504
    """
505
    listAddress = POINTER(c_longlong)()
506
    numElements = c_int(0)
507
    isEndElliptic = c_int(0)
508
    listAsSageList = []
509
    result = sollya_lib_get_list_elements(byref(listAddress),\
510
                                          byref(numElements),\
511
                                          byref(isEndElliptic),\
512
                                          objectListSo)
513
    if result == 0 :
514
        return None
515
    for i in xrange(0, numElements.value, 1):
516
       listAsSageList.append(sollya_lib_copy_obj(listAddress[i]))
517
       # Clear each of the elements returned by Sollya.
518
       sollya_lib_clear_obj(listAddress[i])
519
    # Free the list itself.   
520
    sollya_lib_free(listAddress)
521
    return(listAsSageList, numElements.value, isEndElliptic.value)
522

    
523
def pobyso_get_max_prec_of_exp(soExp):
524
    """ Legacy function. See pobyso_get_max_prec_of_exp_so_sa. """
525
    return(pobyso_get_max_prec_of_exp_so_sa(soExp))
526

    
527
def pobyso_get_max_prec_of_exp_so_sa(expSo):
528
    """
529
    Get the maximum precision used for the numbers in a Sollya expression.
530
    
531
    Arguments:
532
    soExp -- a Sollya expression pointer
533
    Return value:
534
    A Python integer
535
    TODO: 
536
    - error management;
537
    - correctly deal with numerical type such as DOUBLEEXTENDED.
538
    """
539
    maxPrecision = 0
540
    minConstPrec = 0
541
    currentConstPrec = 0
542
    operator = pobyso_get_head_function_so_sa(expSo)
543
    if (operator != SOLLYA_BASE_FUNC_CONSTANT) and \
544
    (operator != SOLLYA_BASE_FUNC_FREE_VARIABLE):
545
        (arity, subexpressions) = pobyso_get_subfunctions_so_sa(expSo)
546
        for i in xrange(arity):
547
            maxPrecisionCandidate = \
548
                pobyso_get_max_prec_of_exp_so_sa(subexpressions[i])
549
            if maxPrecisionCandidate > maxPrecision:
550
                maxPrecision = maxPrecisionCandidate
551
        return(maxPrecision)
552
    elif operator == SOLLYA_BASE_FUNC_CONSTANT:
553
        #minConstPrec = pobyso_get_min_prec_of_constant_so_sa(expSo)
554
        #currentConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
555
        #print minConstPrec, " - ", currentConstPrec 
556
        return(pobyso_get_min_prec_of_constant_so_sa(expSo))
557
    
558
    elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
559
        return(0)
560
    else:
561
        print "pobyso_get_max_prec_of_exp_so_sa: unexepected operator."
562
        return(0)
563

    
564
def pobyso_get_min_prec_of_constant_so_sa(constExpSo):
565
    """
566
    Get the minimum precision necessary to represent the value of a Sollya
567
    constant.
568
    MPFR_MIN_PREC and powers of 2 are taken into account.
569
    We assume that constExpSo is a point
570
    """
571
    constExpAsRnSa = pobyso_get_constant_as_rn_so_sa(constExpSo)
572
    return(min_mpfr_size(get_rn_value(constExpAsRnSa)))
573

    
574
def pobyso_get_sage_exp_from_sollya_exp(sollyaExpSo, realField = RR):
575
    """ Legacy function. See pobyso_get_sage_exp_from_sollya_exp_so_sa. """
576
    return(pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, \
577
                                                     realField = RR))
578

    
579
def pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, realFieldSa = RR):
580
    """
581
    Get a Sage expression from a Sollya expression. 
582
    Currently only tested with polynomials with floating-point coefficients.
583
    Notice that, in the returned polynomial, the exponents are RealNumbers.
584
    """
585
    #pobyso_autoprint(sollyaExp)
586
    operatorSa = pobyso_get_head_function_so_sa(sollyaExpSo)
587
    sollyaLibFreeVariableName = sollya_lib_get_free_variable_name()
588
    # Constants and the free variable are special cases.
589
    # All other operator are dealt with in the same way.
590
    if (operatorSa != SOLLYA_BASE_FUNC_CONSTANT) and \
591
       (operatorSa != SOLLYA_BASE_FUNC_FREE_VARIABLE):
592
        (aritySa, subexpressionsSa) = pobyso_get_subfunctions_so_sa(sollyaExpSo)
593
        if aritySa == 1:
594
            sageExpSa = eval(pobyso_function_type_as_string_so_sa(operatorSa) + \
595
            "(" + pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], \
596
            realFieldSa) + ")")
597
        elif aritySa == 2:
598
            # We do not get through the preprocessor.
599
            # The "^" operator is then a special case.
600
            if operatorSa == SOLLYA_BASE_FUNC_POW:
601
                operatorAsStringSa = "**"
602
            else:
603
                operatorAsStringSa = \
604
                    pobyso_function_type_as_string_so_sa(operatorSa)
605
            sageExpSa = \
606
              eval("pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], realFieldSa)"\
607
              + " " + operatorAsStringSa + " " + \
608
                   "pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[1], realFieldSa)")
609
        # We do not know yet how to deal with arity >= 3 
610
        # (is there any in Sollya anyway?).
611
        else:
612
            sageExpSa = eval('None')
613
        return(sageExpSa)
614
    elif operatorSa == SOLLYA_BASE_FUNC_CONSTANT:
615
        #print "This is a constant"
616
        return pobyso_get_constant_as_rn_with_rf_so_sa(sollyaExpSo, realFieldSa)
617
    elif operatorSa == SOLLYA_BASE_FUNC_FREE_VARIABLE:
618
        #print "This is free variable"
619
        return(eval(sollyaLibFreeVariableName))
620
    else:
621
        print "Unexpected"
622
        return eval('None')
623
# End pobyso_get_sage_poly_from_sollya_poly
624

    
625
def pobyso_get_poly_sa_so(polySo, realFieldSa=None):
626
    """
627
    Create a Sollya polynomial from a Sage polynomial.
628
    """
629
    pass
630
# pobyso_get_poly_sa_so
631

    
632
def pobyso_get_poly_so_sa(polySo, realFieldSa=None):
633
    """
634
    Convert a Sollya polynomial into a Sage polynomial.
635
    We assume that the polynomial is in canonical form.
636
    If no realField is given, a RealField corresponding to the maximum precision 
637
    of the coefficients is internally computed.
638
    It is not returned but can be easily retrieved from the polynomial itself.
639
    Main steps:
640
    - (optional) compute the RealField of the coefficients;
641
    - convert the Sollya expression into a Sage expression;
642
    - convert the Sage expression into a Sage polynomial
643
    TODO: the canonical thing for the polynomial.
644
    """    
645
    if realFieldSa is None:
646
        expressionPrecSa = pobyso_get_max_prec_of_exp_so_sa(polySo)
647
        realFieldSa = RealField(expressionPrecSa)
648
    #print "Sollya expression before...",
649
    #pobyso_autoprint(polySo)
650

    
651
    expressionSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, \
652
                                                             realFieldSa)
653
    #print "...Sollya expression after.",
654
    #pobyso_autoprint(polySo)
655
    polyVariableSa = expressionSa.variables()[0]
656
    polyRingSa = realFieldSa[str(polyVariableSa)]
657
    #print polyRingSa
658
    # Do not use the polynomial(expressionSa, ring=polyRingSa) form!
659
    polynomialSa = polyRingSa(expressionSa)
660
    return(polynomialSa)
661
# End pobyso_get_sage_poly_from_sollya_poly
662

    
663
def pobyso_get_subfunctions(expressionSo):
664
    """ Legacy function. See pobyso_get_subfunctions_so_sa. """
665
    return(pobyso_get_subfunctions_so_sa(expressionSo)) 
666

    
667
def pobyso_get_subfunctions_so_sa(expressionSo):
668
    """
669
    Get the subfunctions of an expression.
670
    Return the number of subfunctions and the list of subfunctions addresses.
671
    S.T.: Could not figure out another way than that ugly list of declarations
672
    to recover the addresses of the subfunctions.
673
    We limit ourselves to arity 8 functions. 
674
    """
675
    subf0 = c_int(0)
676
    subf1 = c_int(0)
677
    subf2 = c_int(0)
678
    subf3 = c_int(0)
679
    subf4 = c_int(0)
680
    subf5 = c_int(0)
681
    subf6 = c_int(0)
682
    subf7 = c_int(0)
683
    subf8 = c_int(0)
684
    arity = c_int(0)
685
    nullPtr = POINTER(c_int)()
686
    sollya_lib_get_subfunctions(expressionSo, byref(arity), \
687
      byref(subf0), byref(subf1), byref(subf2), byref(subf3), \
688
      byref(subf4), byref(subf5),\
689
      byref(subf6), byref(subf7), byref(subf8), nullPtr, None) 
690
#    byref(cast(subfunctions[0], POINTER(c_int))), \
691
#    byref(cast(subfunctions[0], POINTER(c_int))), \
692
#    byref(cast(subfunctions[2], POINTER(c_int))), \
693
#    byref(cast(subfunctions[3], POINTER(c_int))), \
694
#    byref(cast(subfunctions[4], POINTER(c_int))), \
695
#    byref(cast(subfunctions[5], POINTER(c_int))), \
696
#    byref(cast(subfunctions[6], POINTER(c_int))), \
697
#    byref(cast(subfunctions[7], POINTER(c_int))), \
698
#    byref(cast(subfunctions[8], POINTER(c_int))), nullPtr)
699
    subfunctions = [subf0, subf1, subf2, subf3, subf4, subf5, subf6, subf7, \
700
                    subf8]
701
    subs = []
702
    if arity.value > pobyso_max_arity:
703
        return(0,[])
704
    for i in xrange(arity.value):
705
        subs.append(int(subfunctions[i].value))
706
        #print subs[i]
707
    return(int(arity.value), subs)
708
    
709
def pobyso_get_prec():
710
    """ Legacy function. See pobyso_get_prec_so_sa(). """
711
    return(pobyso_get_prec_so_sa())
712

    
713
def pobyso_get_prec_so():
714
    """
715
    Get the current default precision in Sollya.
716
    The return value is a Sollya object.
717
    Usefull when modifying the precision back and forth by avoiding
718
    extra conversions.
719
    """
720
    return(sollya_lib_get_prec(None))
721
    
722
def pobyso_get_prec_so_sa():
723
    """
724
    Get the current default precision in Sollya.
725
    The return value is Sage/Python int.
726
    """
727
    precSo = sollya_lib_get_prec(None)
728
    precSa = c_int(0)
729
    sollya_lib_get_constant_as_int(byref(precSa), precSo)
730
    sollya_lib_clear_obj(precSo)
731
    return(int(precSa.value))
732
# End pobyso_get_prec_so_sa.
733

    
734
def pobyso_get_prec_of_constant(ctExpSo):
735
    """ Legacy function. See pobyso_get_prec_of_constant_so_sa. """
736
    return(pobyso_get_prec_of_constant_so_sa(ctExpSo))
737

    
738
def pobyso_get_prec_of_constant_so_sa(ctExpSo):
739
    prec = c_int(0)
740
    retc = sollya_lib_get_prec_of_constant(byref(prec), ctExpSo, None)
741
    if retc == 0:
742
        return(None)
743
    return(int(prec.value))
744

    
745
def pobyso_get_prec_of_range_so_sa(rangeSo):
746
    prec = c_int(0)
747
    retc = sollya_lib_get_prec_of_range(byref(prec), rangeSo, None)
748
    if retc == 0:
749
        return(None)
750
    return(int(prec.value))
751

    
752
def pobyso_infnorm_so_so(func, interval, file = None, intervalList = None):
753
    print "Do not use this function. User pobyso_supnorm_so_so instead."
754
    return(None)
755

    
756
def pobyso_interval_to_range_sa_so(intervalSa, precisionSa=None):
757
    if precisionSa is None:
758
        precisionSa = intervalSa.parent().precision()
759
    intervalSo = pobyso_bounds_to_range_sa_so(intervalSa.lower(),\
760
                                              intervalSa.upper(),\
761
                                              precisionSa)
762
    return(intervalSo)
763
# End pobyso_interval_to_range_sa_so
764

    
765
def pobyso_lib_init():
766
    sollya_lib_init(None)
767

    
768
def pobyso_lib_close():
769
    sollya_lib_close(None)
770
    
771
def pobyso_name_free_variable(freeVariableNameSa):
772
    """ Legacy function. See pobyso_name_free_variable_sa_so. """
773
    pobyso_name_free_variable_sa_so(freeVariableNameSa)
774

    
775
def pobyso_name_free_variable_sa_so(freeVariableNameSa):
776
    """
777
    Set the free variable name in Sollya from a Sage string.
778
    """
779
    sollya_lib_name_free_variable(freeVariableNameSa)
780

    
781
def pobyso_parse_string(string):
782
    """ Legacy function. See pobyso_parse_string_sa_so. """
783
    return(pobyso_parse_string_sa_so(string))
784
 
785
def pobyso_parse_string_sa_so(string):
786
    """
787
    Get the Sollya expression computed from a Sage string.
788
    """
789
    return(sollya_lib_parse_string(string))
790

    
791
def pobyso_range(rnLowerBound, rnUpperBound):
792
    """ Legacy function. See pobyso_range_sa_so. """
793
    return(pobyso_range_sa_so(rnLowerBound, rnUpperBound)) 
794

    
795

    
796
def pobyso_range_to_interval_so_sa(rangeSo, realIntervalFieldSa = None):
797
    """
798
    Get a Sage interval from a Sollya range.
799
    If no realIntervalField is given as a parameter, the Sage interval
800
    precision is that of the Sollya range.
801
    Otherwise, the precision is that of the realIntervalField. In this case
802
    rounding may happen.
803
    """
804
    if realIntervalFieldSa is None:
805
        precSa = pobyso_get_prec_of_range_so_sa(rangeSo)
806
        realIntervalFieldSa = RealIntervalField(precSa)
807
    intervalSa = \
808
        pobyso_get_interval_from_range_so_sa(rangeSo, realIntervalFieldSa) 
809
    return(intervalSa)
810

    
811
def pobyso_remez_canonical_sa_sa(func, \
812
                                 degree, \
813
                                 lowerBound, \
814
                                 upperBound, \
815
                                 weight = None, \
816
                                 quality = None):
817
    """
818
    All arguments are Sage/Python.
819
    The functions (func and weight) must be passed as expressions or strings.
820
    Otherwise the function fails. 
821
    The return value is a Sage polynomial.
822
    """
823
    var('zorglub')    # Dummy variable name for type check only. Type of 
824
    # zorglub is "symbolic expression".
825
    polySo = pobyso_remez_canonical_sa_so(func, \
826
                                 degree, \
827
                                 lowerBound, \
828
                                 upperBound, \
829
                                 weight, \
830
                                 quality)
831
    # String test
832
    if parent(func) == parent("string"):
833
        functionSa = eval(func)
834
    # Expression test.
835
    elif type(func) == type(zorglub):
836
        functionSa = func
837
    else:
838
        return None
839
    #
840
    maxPrecision = 0
841
    if polySo is None:
842
        return(None)
843
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
844
    RRRRSa = RealField(maxPrecision)
845
    polynomialRingSa = RRRRSa[functionSa.variables()[0]]
846
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, RRRRSa)
847
    polySa = polynomial(expSa, polynomialRingSa)
848
    sollya_lib_clear_obj(polySo)
849
    return(polySa)
850
# End pobyso_remez_canonical_sa_sa
851
    
852
def pobyso_remez_canonical(func, \
853
                           degree, \
854
                           lowerBound, \
855
                           upperBound, \
856
                           weight = "1", \
857
                           quality = None):
858
    """ Legacy function. See pobyso_remez_canonical_sa_so. """
859
    return(pobyso_remez_canonical_sa_so(func, \
860
                                        degree, \
861
                                        lowerBound, \
862
                                        upperBound, \
863
                                        weight, \
864
                                        quality))
865
def pobyso_remez_canonical_sa_so(func, \
866
                                 degree, \
867
                                 lowerBound, \
868
                                 upperBound, \
869
                                 weight = None, \
870
                                 quality = None):
871
    """
872
    All arguments are Sage/Python.
873
    The functions (func and weight) must be passed as expressions or strings.
874
    Otherwise the function fails. 
875
    The return value is a pointer to a Sollya function.
876
    """
877
    var('zorglub')    # Dummy variable name for type check only. Type of
878
    # zorglub is "symbolic expression".
879
    currentVariableNameSa = None
880
    # The func argument can be of different types (string, 
881
    # symbolic expression...)
882
    if parent(func) == parent("string"):
883
        localFuncSa = eval(func)
884
        if len(localFuncSa.variables()) > 0:
885
            currentVariableNameSa = localFuncSa.variables()[0]
886
            sollya_lib_name_free_variable(str(currentVariableNameSa))
887
            functionSo = sollya_lib_parse_string(localFuncSa._assume_str())
888
    # Expression test.
889
    elif type(func) == type(zorglub):
890
        # Until we are able to translate Sage expressions into Sollya 
891
        # expressions : parse the string version.
892
        if len(func.variables()) > 0:
893
            currentVariableNameSa = func.variables()[0]
894
            sollya_lib_name_free_variable(str(currentVariableNameSa))
895
            functionSo = sollya_lib_parse_string(func._assume_str())
896
    else:
897
        return(None)
898
    if weight is None: # No weight given -> 1.
899
        weightSo = pobyso_constant_1_sa_so()
900
    elif parent(weight) == parent("string"): # Weight given as string: parse it.
901
        weightSo = sollya_lib_parse_string(func)
902
    elif type(weight) == type(zorglub): # Weight given as symbolice expression.
903
        functionSo = sollya_lib_parse_string_sa_so(weight._assume_str())
904
    else:
905
        return(None)
906
    degreeSo = pobyso_constant_from_int(degree)
907
    rangeSo = pobyso_bounds_to_range_sa_so(lowerBound, upperBound)
908
    if not quality is None:
909
        qualitySo= pobyso_constant_sa_so(quality)
910
    else:
911
        qualitySo = None
912
        
913
    remezPolySo = sollya_lib_remez(functionSo, \
914
                                   degreeSo, \
915
                                   rangeSo, \
916
                                   weightSo, \
917
                                   qualitySo, \
918
                                   None)
919
    sollya_lib_clear_obj(functionSo)
920
    sollya_lib_clear_obj(degreeSo)
921
    sollya_lib_clear_obj(rangeSo)
922
    sollya_lib_clear_obj(weightSo)
923
    if not qualitySo is None:
924
        sollya_lib_clear_obj(qualitySo)
925
    return(remezPolySo)
926
# End pobyso_remez_canonical_sa_so
927

    
928
def pobyso_remez_canonical_so_so(funcSo, \
929
                                 degreeSo, \
930
                                 rangeSo, \
931
                                 weightSo = pobyso_constant_1_sa_so(),\
932
                                 qualitySo = None):
933
    """
934
    All arguments are pointers to Sollya objects.
935
    The return value is a pointer to a Sollya function.
936
    """
937
    if not sollya_lib_obj_is_function(funcSo):
938
        return(None)
939
    return(sollya_lib_remez(funcSo, degreeSo, rangeSo, weightSo, qualitySo, None))
940
    
941
def pobyso_set_canonical_off():
942
    sollya_lib_set_canonical(sollya_lib_off())
943

    
944
def pobyso_set_canonical_on():
945
    sollya_lib_set_canonical(sollya_lib_on())
946

    
947
def pobyso_set_prec(p):
948
    """ Legacy function. See pobyso_set_prec_sa_so. """
949
    pobyso_set_prec_sa_so(p)
950

    
951
def pobyso_set_prec_sa_so(p):
952
    a = c_int(p)
953
    precSo = c_void_p(sollya_lib_constant_from_int(a))
954
    sollya_lib_set_prec(precSo, None)
955

    
956
def pobyso_set_prec_so_so(newPrecSo):
957
    sollya_lib_set_prec(newPrecSo, None)
958

    
959
def pobyso_supnorm_so_so(polySo, funcSo, intervalSo, errorTypeSo = None,\
960
                         accuracySo = None):
961
    """
962
    Computes the supnorm of the approximation error between the given 
963
    polynomial and function.
964
    errorTypeSo defaults to "absolute".
965
    accuracySo defaults to 2^(-40).
966
    """
967
    if errorTypeSo is None:
968
        errorTypeSo = sollya_lib_absolute(None)
969
        errorTypeIsNone = True
970
    else:
971
        errorTypeIsNone = False
972
    #
973
    if accuracySo is None:
974
        # Notice the **!
975
        accuracySo = pobyso_constant_sa_so(RR(2**(-40)))
976
        accuracyIsNone = True
977
    else:
978
        accuracyIsNone = False
979
    pobyso_autoprint(accuracySo)
980
    resultSo = \
981
        sollya_lib_supnorm(polySo, funcSo, intervalSo, errorTypeSo, \
982
                              accuracySo)
983
    if errorTypeIsNone:
984
        sollya_lib_clear_obj(errorTypeSo)
985
    if accuracyIsNone:
986
        sollya_lib_clear_obj(accuracySo)
987
    return resultSo
988
# End pobyso_supnorm_so_so
989

    
990
def pobyso_taylor_expansion_with_change_var_so_so(functionSo, degreeSo, \
991
                                                  rangeSo, \
992
                                                  errorTypeSo=None, \
993
                                                  sollyaPrecSo=None):
994
    """
995
    Compute the Taylor expansion with the variable change
996
    x -> (x-intervalCenter) included.
997
    """
998
    # No global change of the working precision.
999
    if not sollyaPrecSo is None:
1000
        initialPrecSo = sollya_lib_get_prec(None)
1001
        sollya_lib_set_prec(sollyaPrecSo)
1002
    #
1003
    # Error type stuff: default to absolute.
1004
    if errorTypeSo is None:
1005
        errorTypeIsNone = True
1006
        errorTypeSo = sollya_lib_absolute(None)
1007
    else:
1008
        errorTypeIsNone = False
1009
    intervalCenterSo = sollya_lib_mid(rangeSo)
1010
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, \
1011
                                         intervalCenterSo, \
1012
                                         rangeSo, errorTypeSo, None)
1013
    # taylorFormListSaSo is a Python list of Sollya objects references that 
1014
    # are copies of the elements of taylorFormSo.
1015
    # pobyso_get_list_elements_so_so clears taylorFormSo.
1016
    (taylorFormListSo, numElements, isEndElliptic) = \
1017
        pobyso_get_list_elements_so_so(taylorFormSo)
1018
    polySo = taylorFormListSo[0]
1019
    errorRangeSo = taylorFormListSo[2]
1020
    maxErrorSo = sollya_lib_sup(errorRangeSo)
1021
    changeVarExpSo = sollya_lib_build_function_sub(\
1022
                       sollya_lib_build_function_free_variable(),\
1023
                       sollya_lib_copy_obj(intervalCenterSo))
1024
    polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpSo) 
1025
    sollya_lib_clear_obj(changeVarExpSo)
1026
    # If changed, reset the Sollya working precision.
1027
    if not sollyaPrecSo is None:
1028
        sollya_lib_set_prec(initialPrecSo)
1029
        sollya_lib_clear_obj(initialPrecSo)
1030
    if errorTypeIsNone:
1031
        sollya_lib_clear_obj(errorTypeSo)
1032
    sollya_lib_clear_obj(taylorFormSo)
1033
    # Do not clear maxErrorSo.
1034
    return((polyVarChangedSo, intervalCenterSo, maxErrorSo))
1035
# end pobyso_taylor_expansion_with_change_var_so_so
1036

    
1037
def pobyso_taylor_expansion_no_change_var_so_so(functionSo, degreeSo, rangeSo,
1038
                                                errorTypeSo=None, 
1039
                                                sollyaPrecSo=None):
1040
    """
1041
    Compute the Taylor expansion without the variable change
1042
    x -> x-intervalCenter.
1043
    """
1044
    # No global change of the working precision.
1045
    if not sollyaPrecSo is None:
1046
        initialPrecSo = sollya_lib_get_prec(None)
1047
        sollya_lib_set_prec(sollyaPrecSo)
1048
    # Error type stuff: default to absolute.
1049
    if errorTypeSo is None:
1050
        errorTypeIsNone = True
1051
        errorTypeSo = sollya_lib_absolute(None)
1052
    else:
1053
        errorTypeIsNone = False
1054
    intervalCenterSo = sollya_lib_mid(rangeSo, None)
1055
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo,
1056
                                         intervalCenterSo,
1057
                                         rangeSo, errorTypeSo, None)
1058
    # taylorFormListSaSo is a Python list of Sollya objects references that 
1059
    # are copies of the elements of taylorFormSo.
1060
    # pobyso_get_list_elements_so_so clears taylorFormSo.
1061
    (taylorFormListSaSo, numElementsSa, isEndEllipticSa) = \
1062
        pobyso_get_list_elements_so_so(taylorFormSo)
1063
    sollya_lib_clear_obj(taylorFormSo)
1064
    polySo = sollya_lib_copy_obj(taylorFormListSaSo[0])
1065
    #polySo = taylorFormListSaSo[0]
1066
    #errorRangeSo = sollya_lib_copy_obj(taylorFormListSaSo[2])
1067
    errorRangeSo = taylorFormListSaSo[2]
1068
    # No copy_obj needed here: a new object is created.
1069
    maxErrorSo = sollya_lib_sup(errorRangeSo)
1070
    # If changed, reset the Sollya working precision.
1071
    if not sollyaPrecSo is None:
1072
        sollya_lib_set_prec(initialPrecSo)
1073
        sollya_lib_clear_obj(initialPrecSo)
1074
    if errorTypeIsNone:
1075
        sollya_lib_clear_obj(errorTypeSo)
1076
    pobyso_clear_taylorform_sa_so(taylorFormListSaSo)
1077
    return((polySo, intervalCenterSo, maxErrorSo))
1078
# end pobyso_taylor_expansion_no_change_var_so_so
1079

    
1080
def pobyso_taylor(function, degree, point):
1081
    """ Legacy function. See pobysoTaylor_so_so. """
1082
    return(pobyso_taylor_so_so(function, degree, point))
1083

    
1084
def pobyso_taylor_so_so(functionSo, degreeSo, pointSo):
1085
    return(sollya_lib_taylor(functionSo, degreeSo, pointSo))
1086
    
1087
def pobyso_taylorform(function, degree, point = None, 
1088
                      interval = None, errorType=None):
1089
    """ Legacy function. See pobyso_taylorform_sa_sa;"""
1090
    
1091
def pobyso_taylorform_sa_sa(functionSa, \
1092
                            degreeSa, \
1093
                            pointSa, \
1094
                            intervalSa=None, \
1095
                            errorTypeSa=None, \
1096
                            precisionSa=None):
1097
    """
1098
    Compute the Taylor form of 'degreeSa' for 'functionSa' at 'pointSa' 
1099
    for 'intervalSa' with 'errorTypeSa' (a string) using 'precisionSa'. 
1100
    point: must be a Real or a Real interval.
1101
    return the Taylor form as an array
1102
    TODO: take care of the interval and of the point when it is an interval;
1103
          when errorType is not None;
1104
          take care of the other elements of the Taylor form (coefficients 
1105
          errors and delta.
1106
    """
1107
    # Absolute as the default error.
1108
    if errorTypeSa is None:
1109
        errorTypeSo = sollya_lib_absolute()
1110
    elif errorTypeSa == "relative":
1111
        errorTypeSo = sollya_lib_relative()
1112
    elif errortypeSa == "absolute":
1113
        errorTypeSo = sollya_lib_absolute()
1114
    else:
1115
        # No clean up needed.
1116
        return None
1117
    # Global precision stuff
1118
    precisionChangedSa = False
1119
    currentSollyaPrecSo = pobyso_get_prec_so()
1120
    currentSollyaPrecSa = pobyso_constant_from_int_so_sa(currentSollyaPrecSo)
1121
    if not precisionSa is None:
1122
        if precisionSa > currentSollyaPrecSa:
1123
            pobyso_set_prec_sa_so(precisionSa)
1124
            precisionChangedSa = True
1125
            
1126
    if len(functionSa.variables()) > 0:
1127
        varSa = functionSa.variables()[0]
1128
        pobyso_name_free_variable_sa_so(str(varSa))
1129
    # In any case (point or interval) the parent of pointSa has a precision
1130
    # method.
1131
    pointPrecSa = pointSa.parent().precision()
1132
    if precisionSa > pointPrecSa:
1133
        pointPrecSa = precisionSa
1134
    # In any case (point or interval) pointSa has a base_ring() method.
1135
    pointBaseRingString = str(pointSa.base_ring())
1136
    if re.search('Interval', pointBaseRingString) is None: # Point
1137
        pointSo = pobyso_constant_sa_so(pointSa, pointPrecSa)
1138
    else: # Interval.
1139
        pointSo = pobyso_interval_to_range_sa_so(pointSa, pointPrecSa)
1140
    # Sollyafy the function.
1141
    functionSo = pobyso_parse_string_sa_so(functionSa._assume_str())
1142
    if sollya_lib_obj_is_error(functionSo):
1143
        print "pobyso_tailorform: function string can't be parsed!"
1144
        return None
1145
    # Sollyafy the degree
1146
    degreeSo = sollya_lib_constant_from_int(int(degreeSa))
1147
    # Sollyafy the point
1148
    # Call Sollya
1149
    taylorFormSo = \
1150
        sollya_lib_taylorform(functionSo, degreeSo, pointSo, errorTypeSo,\
1151
                                         None)
1152
    sollya_lib_clear_obj(functionSo)
1153
    sollya_lib_clear_obj(degreeSo)
1154
    sollya_lib_clear_obj(pointSo)
1155
    sollya_lib_clear_obj(errorTypeSo)
1156
    (tfsAsList, numElements, isEndElliptic) = \
1157
            pobyso_get_list_elements_so_so(taylorFormSo)
1158
    polySo = tfsAsList[0]
1159
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
1160
    polyRealField = RealField(maxPrecision)
1161
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, polyRealField)
1162
    if precisionChangedSa:
1163
        sollya_lib_set_prec(currentSollyaPrecSo)
1164
        sollya_lib_clear_obj(currentSollyaPrecSo)
1165
    polynomialRing = polyRealField[str(varSa)]
1166
    polySa = polynomial(expSa, polynomialRing)
1167
    taylorFormSa = [polySa]
1168
    # Final clean-up.
1169
    sollya_lib_clear_obj(taylorFormSo)
1170
    return(taylorFormSa)
1171
# End pobyso_taylor_form_sa_sa
1172

    
1173
def pobyso_taylorform_so_so(functionSo, degreeSo, pointSo, intervalSo=None, \
1174
                            errorTypeSo=None):
1175
    createdErrorType = False
1176
    if errorTypeSo is None:
1177
        errorTypeSo = sollya_lib_absolute()
1178
        createdErrorType = True
1179
    else:
1180
        #TODO: deal with the other case.
1181
        pass
1182
    if intervalSo is None:
1183
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
1184
                                         errorTypeSo, None)
1185
    else:
1186
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
1187
                                         intervalSo, errorTypeSo, None)
1188
    if createdErrorType:
1189
        sollya_lib_clear_obj(errorTypeSo)
1190
    return(resultSo)
1191
        
1192

    
1193
def pobyso_univar_polynomial_print_reverse(polySa):
1194
    """ Legacy function. See pobyso_univar_polynomial_print_reverse_sa_sa. """
1195
    return(pobyso_univar_polynomial_print_reverse_sa_sa(polySa))
1196

    
1197
def pobyso_univar_polynomial_print_reverse_sa_sa(polySa):
1198
    """
1199
    Return the string representation of a univariate polynomial with
1200
    monomials ordered in the x^0..x^n order of the monomials.
1201
    Remember: Sage
1202
    """
1203
    polynomialRing = polySa.base_ring()
1204
    # A very expensive solution:
1205
    # -create a fake multivariate polynomial field with only one variable,
1206
    #   specifying a negative lexicographical order;
1207
    mpolynomialRing = PolynomialRing(polynomialRing.base(), \
1208
                                     polynomialRing.variable_name(), \
1209
                                     1, order='neglex')
1210
    # - convert the univariate argument polynomial into a multivariate
1211
    #   version;
1212
    p = mpolynomialRing(polySa)
1213
    # - return the string representation of the converted form.
1214
    # There is no simple str() method defined for p's class.
1215
    return(p.__str__())
1216
#
1217
print pobyso_get_prec()  
1218
pobyso_set_prec(165)
1219
print pobyso_get_prec()  
1220
a=100
1221
print type(a)
1222
id(a)
1223
print "Max arity: ", pobyso_max_arity
1224
print "Function tripleDouble (43) as a string: ", pobyso_function_type_as_string(43)
1225
print "Function None (44) as a string: ", pobyso_function_type_as_string(44)
1226
print "...Pobyso check done"