Statistiques
| Révision :

root / pobysoPythonSage / src / pobyso.py @ 114

Historique | Voir | Annoter | Télécharger (44,23 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
    if precisionSa is None:
108
        # Check for the largest precision.
109
        lbPrecSa = rnLowerBoundSa.parent().precision()
110
        ubPrecSa = rnLowerBoundSa.parent().precision()
111
        maxPrecSa = max(lbPrecSa, ubPrecSa)
112
    else:
113
        maxPrecSa = precisionSa
114
    sollyaCurrentPrecSo = pobyso_get_prec_so()
115
    sollyaCurrentPrecSa = pobyso_constant_from_int_so_sa(sollyaCurrentPrecSo)
116
    # Change the current Sollya precision only if necessary.
117
    if maxPrecSa > sollyaCurrentPrecSa:
118
        pobyso_set_prec_sa_so(maxPrecSa)
119
    lowerBoundSo = sollya_lib_constant(get_rn_value(rnLowerBoundSa))
120
    upperBoundSo = sollya_lib_constant(get_rn_value(rnUpperBoundSa))
121
    rangeSo = sollya_lib_range(lowerBoundSo, upperBoundSo)
122
    # Back to original precision.
123
    if maxPrecSa > sollyaCurrentPrecSa:
124
        sollya_lib_set_prec(sollyaCurrentPrecSo)
125
    # Clean up
126
    sollya_lib_clear_obj(sollyaCurrentPrecSo)
127
    sollya_lib_clear_obj(lowerBoundSo)
128
    sollya_lib_clear_obj(upperBoundSo)
129
    return(rangeSo)
130
# End pobyso_bounds_to_range_sa_so
131

    
132
def pobyso_build_function_sub_so_so(exp1So, exp2So):
133
    return(sollya_lib_build_function_sub(exp1So, exp2So))
134

    
135
def pobyso_change_var_in_function_so_so(funcSo, chvarExpSo):
136
    """
137
    Variable change in a function.
138
    """
139
    return(sollya_lib_evaluate(funcSo,chvarExpSo))
140
# End pobyso_change_var_in_function_so_so     
141

    
142
def pobyso_chebyshevform_so_so(functionSo, degreeSo, intervalSo):
143
    resultSo = sollya_lib_chebyshevform(functionSo, degreeSo, intervalSo)
144
    return(resultSo)
145
# End pobyso_chebyshevform_so_so.
146

    
147
def pobyso_cmp(rnArgSa, cteSo):
148
    """
149
    Compare the MPFR value a RealNumber with that of a Sollya constant.
150
    
151
    Get the value of the Sollya constant into a RealNumber and compare
152
    using MPFR. Could be optimized by working directly with a mpfr_t
153
    for the intermediate number. 
154
    """
155
    precisionOfCte = c_int(0)
156
    # From the Sollya constant, create a local Sage RealNumber.
157
    sollya_lib_get_prec_of_constant(precisionOfCte, cteSo) 
158
    #print "Precision of constant: ", precisionOfCte
159
    RRRR = RealField(precisionOfCte.value)
160
    rnLocalSa = RRRR(0)
161
    sollya_lib_get_constant(get_rn_value(rnLocalSa), cteSo)
162
    # Compare the local Sage RealNumber with rnArg.
163
    return(cmp_rn_value(rnArgSa, rnLocal))
164
# End pobyso_smp
165

    
166
def pobyso_compute_pos_function_abs_val_bounds_sa_sa(funcSa, lowerBoundSa, \
167
                                                     upperBoundSa):
168
    """
169
    TODO: completely rework and test.
170
    """
171
    pobyso = pobyso_name_free_variable_sa_so(funcSa.variables()[0])
172
    funcSo = pobyso_parse_string(funcSa._assume_str())
173
    rangeSo = pobyso_range_sa_so(lowerBoundSa, upperBoundSa)
174
    infnormSo = pobyso_infnorm_so_so(funcSo,rangeSo)
175
    # Sollya return the infnorm as an interval.
176
    fMaxSa = pobyso_get_interval_from_range_so_sa(infnormSo)
177
    # Get the top bound and compute the binade top limit.
178
    fMaxUpperBoundSa = fMaxSa.upper()
179
    binadeTopLimitSa = 2**ceil(fMaxUpperBoundSa.log2())
180
    # Put up together the function to use to compute the lower bound.
181
    funcAuxSo = pobyso_parse_string(str(binadeTopLimitSa) +  \
182
                                    '-(' + f._assume_str() + ')')
183
    pobyso_autoprint(funcAuxSo)
184
    # Clear the Sollya range before a new call to infnorm and issue the call.
185
    sollya_lib_clear_obj(infnormSo)
186
    infnormSo = pobyso_infnorm_so_so(funcAuxSo,rangeSo)
187
    fMinSa = pobyso_get_interval_from_range_so_sa(infnormSo)
188
    sollya_lib_clear_obj(infnormSo)
189
    fMinLowerBoundSa = binadeTopLimitSa - fMinSa.lower()
190
    # Compute the maximum of the precisions of the different bounds.
191
    maxPrecSa = max([fMinLowerBoundSa.parent().precision(), \
192
                     fMaxUpperBoundSa.parent().precision()])
193
    # Create a RealIntervalField and create an interval with the "good" bounds.
194
    RRRI = RealIntervalField(maxPrecSa)
195
    imageIntervalSa = RRRI(fMinLowerBoundSa, fMaxUpperBoundSa)
196
    # Free the unneeded Sollya objects
197
    sollya_lib_clear_obj(funcSo)
198
    sollya_lib_clear_obj(funcAuxSo)
199
    sollya_lib_clear_obj(rangeSo)
200
    return(imageIntervalSa)
201
# End pobyso_compute_pos_function_abs_val_bounds_sa_sa
202

    
203
def pobyso_constant(rnArg):
204
    """ Legacy function. See pobyso_constant_sa_so. """
205
    return(pobyso_constant_sa_so(rnArg))
206
    
207
def pobyso_constant_sa_so(rnArgSa, precisionSa=None):
208
    """
209
    Create a Sollya constant from a RealNumber.
210
    """
211
    # Precision stuff
212
    if precisionSa is None:
213
        precisionSa = rnArgSa.parent().precision()
214
    currentSollyaPrecisionSo = sollya_lib_get_prec()
215
    currentSollyaPrecisionSa = \
216
        pobyso_constant_from_int(currentSollyaPrecisionSo)
217
    if precisionSa > currentSollyaPrecisionSa:
218
        pobyso_set_prec_sa_so(precisionSa)
219
        constantSo = sollya_lib_constant(get_rn_value(rnArgSa))
220
        pobyso_set_prec_sa_so(currentSollyaPrecision)
221
    else:
222
        constantSo = sollya_lib_constant(get_rn_value(rnArgSa))
223
    sollya_lib_clear_obj(currentSollyaPrecisionSo)
224
    return(constantSo)
225
    
226
def pobyso_constant_0_sa_so():
227
    return(pobyso_constant_from_int_sa_so(0))
228

    
229
def pobyso_constant_1():
230
    """ Legacy function. See pobyso_constant_so_so. """
231
    return(pobyso_constant_1_sa_so())
232

    
233
def pobyso_constant_1_sa_so():
234
    return(pobyso_constant_from_int_sa_so(1))
235

    
236
def pobyso_constant_from_int(anInt):
237
    """ Legacy function. See pobyso_constant_from_int_sa_so. """
238
    return(pobyso_constant_from_int_sa_so(anInt))
239

    
240
def pobyso_constant_from_int_sa_so(anInt):
241
    return(sollya_lib_constant_from_int(int(anInt)))
242

    
243
def pobyso_constant_from_int_so_sa(constSo):
244
    """
245
    Get a Sollya constant as an int.
246
    Use full for precision or powers in polynomials.
247
    """
248
    constSa = c_int(0)
249
    sollya_lib_get_constant_as_int(byref(constSa), constSo)
250
    return(constSa.value)
251
# End pobyso_constant_from_int_so_sa
252

    
253
def pobyso_function_type_as_string(funcType):
254
    """ Legacy function. See pobyso_function_type_as_string_so_sa. """
255
    return(pobyso_function_type_as_string_so_sa(funcType))
256

    
257
def pobyso_function_type_as_string_so_sa(funcType):
258
    """
259
    Numeric Sollya function codes -> Sage mathematical function names.
260
    Notice that pow -> ^ (a la Sage, not a la Python).
261
    """
262
    if funcType == SOLLYA_BASE_FUNC_ABS:
263
        return "abs"
264
    elif funcType == SOLLYA_BASE_FUNC_ACOS:
265
        return "arccos"
266
    elif funcType == SOLLYA_BASE_FUNC_ACOSH:
267
        return "arccosh"
268
    elif funcType == SOLLYA_BASE_FUNC_ADD:
269
        return "+"
270
    elif funcType == SOLLYA_BASE_FUNC_ASIN:
271
        return "arcsin"
272
    elif funcType == SOLLYA_BASE_FUNC_ASINH:
273
        return "arcsinh"
274
    elif funcType == SOLLYA_BASE_FUNC_ATAN:
275
        return "arctan"
276
    elif funcType == SOLLYA_BASE_FUNC_ATANH:
277
        return "arctanh"
278
    elif funcType == SOLLYA_BASE_FUNC_CEIL:
279
        return "ceil"
280
    elif funcType == SOLLYA_BASE_FUNC_CONSTANT:
281
        return "cte"
282
    elif funcType == SOLLYA_BASE_FUNC_COS:
283
        return "cos"
284
    elif funcType == SOLLYA_BASE_FUNC_COSH:
285
        return "cosh"
286
    elif funcType == SOLLYA_BASE_FUNC_DIV:
287
        return "/"
288
    elif funcType == SOLLYA_BASE_FUNC_DOUBLE:
289
        return "double"
290
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEDOUBLE:
291
        return "doubleDouble"
292
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEEXTENDED:
293
        return "doubleDxtended"
294
    elif funcType == SOLLYA_BASE_FUNC_ERF:
295
        return "erf"
296
    elif funcType == SOLLYA_BASE_FUNC_ERFC:
297
        return "erfc"
298
    elif funcType == SOLLYA_BASE_FUNC_EXP:
299
        return "exp"
300
    elif funcType == SOLLYA_BASE_FUNC_EXP_M1:
301
        return "expm1"
302
    elif funcType == SOLLYA_BASE_FUNC_FLOOR:
303
        return "floor"
304
    elif funcType == SOLLYA_BASE_FUNC_FREE_VARIABLE:
305
        return "freeVariable"
306
    elif funcType == SOLLYA_BASE_FUNC_HALFPRECISION:
307
        return "halfPrecision"
308
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYCONSTANT:
309
        return "libraryConstant"
310
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYFUNCTION:
311
        return "libraryFunction"
312
    elif funcType == SOLLYA_BASE_FUNC_LOG:
313
        return "log"
314
    elif funcType == SOLLYA_BASE_FUNC_LOG_10:
315
        return "log10"
316
    elif funcType == SOLLYA_BASE_FUNC_LOG_1P:
317
        return "log1p"
318
    elif funcType == SOLLYA_BASE_FUNC_LOG_2:
319
        return "log2"
320
    elif funcType == SOLLYA_BASE_FUNC_MUL:
321
        return "*"
322
    elif funcType == SOLLYA_BASE_FUNC_NEARESTINT:
323
        return "round"
324
    elif funcType == SOLLYA_BASE_FUNC_NEG:
325
        return "__neg__"
326
    elif funcType == SOLLYA_BASE_FUNC_PI:
327
        return "pi"
328
    elif funcType == SOLLYA_BASE_FUNC_POW:
329
        return "^"
330
    elif funcType == SOLLYA_BASE_FUNC_PROCEDUREFUNCTION:
331
        return "procedureFunction"
332
    elif funcType == SOLLYA_BASE_FUNC_QUAD:
333
        return "quad"
334
    elif funcType == SOLLYA_BASE_FUNC_SIN:
335
        return "sin"
336
    elif funcType == SOLLYA_BASE_FUNC_SINGLE:
337
        return "single"
338
    elif funcType == SOLLYA_BASE_FUNC_SINH:
339
        return "sinh"
340
    elif funcType == SOLLYA_BASE_FUNC_SQRT:
341
        return "sqrt"
342
    elif funcType == SOLLYA_BASE_FUNC_SUB:
343
        return "-"
344
    elif funcType == SOLLYA_BASE_FUNC_TAN:
345
        return "tan"
346
    elif funcType == SOLLYA_BASE_FUNC_TANH:
347
        return "tanh"
348
    elif funcType == SOLLYA_BASE_FUNC_TRIPLEDOUBLE:
349
        return "tripleDouble"
350
    else:
351
        return None
352

    
353
def pobyso_get_constant(rnArgSa, constSo):
354
    """ Legacy function. See pobyso_get_constant_so_sa. """
355
    return(pobyso_get_constant_so_sa(rnArgSa, constSo))
356

    
357
def pobyso_get_constant_so_sa(rnArgSa, constSo):
358
    """
359
    Set the value of rnArgSo to the value of constSo in MPFR_RNDN mode.
360
    rnArg must already exist and belong to some RealField.
361
    We assume that constSo points to a Sollya constant.
362
    """
363
    return(sollya_lib_get_constant(get_rn_value(rnArgSa), constSo))
364
    
365
def pobyso_get_constant_as_rn(ctExpSo):
366
    """ 
367
    Legacy function. See pobyso_get_constant_as_rn_so_sa. 
368
    """ 
369
    return(pobyso_get_constant_as_rn_so_sa(ctExpSo))
370
    
371
def pobyso_get_constant_as_rn_so_sa(constExpSo):
372
    """
373
    Get a Sollya constant as a Sage "real number".
374
    The precision of the floating-point number returned is that of the Sollya
375
    constant.
376
    """
377
    precisionSa  = pobyso_get_prec_of_constant_so_sa(constExpSo) 
378
    RRRR = RealField(precisionSa)
379
    rnSa = RRRR(0)
380
    sollya_lib_get_constant(get_rn_value(rnSa), constExpSo)
381
    return(rnSa)
382
# End pobyso_get_constant_as_rn_so_sa
383

    
384
def pobyso_get_constant_as_rn_with_rf(ctExp, realField):
385
    """ 
386
    Legacy function. See pobyso_get_constant_as_rn_with_rf_so_sa.
387
    """
388
    return(pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField))
389
    
390
def pobyso_get_constant_as_rn_with_rf_so_sa(ctExpSo, realFieldSa = None):
391
    """
392
    Get a Sollya constant as a Sage "real number".
393
    If no real field is specified, the precision of the floating-point number 
394
    returned is that of the Sollya constant.
395
    Otherwise is is that of the real field. Hence rounding may happen.
396
    """
397
    if realFieldSa is None:
398
        sollyaPrecSa = pobyso_get_prec_of_constant_so_sa(ctExpSo)
399
        realFieldSa = RealField(sollyaPrecSa)
400
    rnSa = realFieldSa(0)
401
    sollya_lib_get_constant(get_rn_value(rnSa), ctExpSo)
402
    return(rnSa)
403
# End pobyso_get_constant_as_rn_with_rf_so_sa
404

    
405
def pobyso_get_free_variable_name():
406
    """ 
407
    Legacy function. See pobyso_get_free_variable_name_so_sa.
408
    """
409
    return(pobyso_get_free_variable_name_so_sa())
410

    
411
def pobyso_get_free_variable_name_so_sa():
412
    return(sollya_lib_get_free_variable_name())
413
    
414
def pobyso_get_function_arity(expressionSo):
415
    """ 
416
    Legacy function. See pobyso_get_function_arity_so_sa.
417
    """
418
    return(pobyso_get_function_arity_so_sa(expressionSo))
419

    
420
def pobyso_get_function_arity_so_sa(expressionSo):
421
    arity = c_int(0)
422
    sollya_lib_get_function_arity(byref(arity),expressionSo)
423
    return(int(arity.value))
424

    
425
def pobyso_get_head_function(expressionSo):
426
    """ 
427
    Legacy function. See pobyso_get_head_function_so_sa. 
428
    """
429
    return(pobyso_get_head_function_so_sa(expressionSo)) 
430

    
431
def pobyso_get_head_function_so_sa(expressionSo):
432
    functionType = c_int(0)
433
    sollya_lib_get_head_function(byref(functionType), expressionSo, None)
434
    return(int(functionType.value))
435

    
436
def pobyso_get_interval_from_range_so_sa(soRange, realIntervalFieldSa = None ):
437
    """
438
    Return the Sage interval corresponding to the Sollya range argument.
439
    If no reaIntervalField is passed as an argument, the interval bounds are not
440
    rounded: they are elements of RealIntervalField of the "right" precision
441
    to hold all the digits.
442
    """
443
    prec = c_int(0)
444
    if realIntervalFieldSa is None:
445
        retval = sollya_lib_get_prec_of_range(byref(prec), soRange, None)
446
        if retval == 0:
447
            return(None)
448
        realIntervalFieldSa = RealIntervalField(prec.value)
449
    intervalSa = realIntervalFieldSa(0,0)
450
    retval = \
451
        sollya_lib_get_interval_from_range(get_interval_value(intervalSa),\
452
                                           soRange)
453
    if retval == 0:
454
        return(None)
455
    return(intervalSa)
456
# End pobyso_get_interval_from_range_so_sa
457

    
458
def pobyso_get_list_elements(soObj):
459
    """ Legacy function. See pobyso_get_list_elements_so_so. """
460
    return(pobyso_get_list_elements_so_so(soObj))
461
 
462
def pobyso_get_list_elements_so_so(objSo):
463
    """
464
    Get the list elements as a Sage/Python array of Sollya objects.
465
    The other data returned are Sage/Python objects.
466
    """
467
    listAddress = POINTER(c_longlong)()
468
    numElements = c_int(0)
469
    isEndElliptic = c_int(0)
470
    listAsList = []
471
    result = sollya_lib_get_list_elements(byref(listAddress),\
472
                                          byref(numElements),\
473
                                          byref(isEndElliptic),\
474
                                          objSo)
475
    if result == 0 :
476
        return None
477
    for i in xrange(0, numElements.value, 1):
478
       listAsList.append(sollya_lib_copy_obj(listAddress[i]))
479
    return(listAsList, numElements.value, isEndElliptic.value)
480

    
481
def pobyso_get_max_prec_of_exp(soExp):
482
    """ Legacy function. See pobyso_get_max_prec_of_exp_so_sa. """
483
    return(pobyso_get_max_prec_of_exp_so_sa(soExp))
484

    
485
def pobyso_get_max_prec_of_exp_so_sa(expSo):
486
    """
487
    Get the maximum precision used for the numbers in a Sollya expression.
488
    
489
    Arguments:
490
    soExp -- a Sollya expression pointer
491
    Return value:
492
    A Python integer
493
    TODO: 
494
    - error management;
495
    - correctly deal with numerical type such as DOUBLEEXTENDED.
496
    """
497
    maxPrecision = 0
498
    minConstPrec = 0
499
    currentConstPrec = 0
500
    operator = pobyso_get_head_function_so_sa(expSo)
501
    if (operator != SOLLYA_BASE_FUNC_CONSTANT) and \
502
    (operator != SOLLYA_BASE_FUNC_FREE_VARIABLE):
503
        (arity, subexpressions) = pobyso_get_subfunctions_so_sa(expSo)
504
        for i in xrange(arity):
505
            maxPrecisionCandidate = \
506
                pobyso_get_max_prec_of_exp_so_sa(subexpressions[i])
507
            if maxPrecisionCandidate > maxPrecision:
508
                maxPrecision = maxPrecisionCandidate
509
        return(maxPrecision)
510
    elif operator == SOLLYA_BASE_FUNC_CONSTANT:
511
        #minConstPrec = pobyso_get_min_prec_of_constant_so_sa(expSo)
512
        #currentConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
513
        #print minConstPrec, " - ", currentConstPrec 
514
        return(pobyso_get_min_prec_of_constant_so_sa(expSo))
515
    
516
    elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
517
        return(0)
518
    else:
519
        print "pobyso_get_max_prec_of_exp_so_sa: unexepected operator."
520
        return(0)
521

    
522
def pobyso_get_min_prec_of_constant_so_sa(constExpSo):
523
    """
524
    Get the minimum precision necessary to represent the value of a Sollya
525
    constant.
526
    MPFR_MIN_PREC and powers of 2 are taken into account.
527
    We assume that constExpSo is a point
528
    """
529
    constExpAsRnSa = pobyso_get_constant_as_rn_so_sa(constExpSo)
530
    return(min_mpfr_size(get_rn_value(constExpAsRnSa)))
531

    
532
def pobyso_get_sage_exp_from_sollya_exp(sollyaExpSo, realField = RR):
533
    """ Legacy function. See pobyso_get_sage_exp_from_sollya_exp_so_sa. """
534
    return(pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, \
535
                                                     realField = RR))
536

    
537
def pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, realFieldSa = RR):
538
    """
539
    Get a Sage expression from a Sollya expression. 
540
    Currently only tested with polynomials with floating-point coefficients.
541
    Notice that, in the returned polynomial, the exponents are RealNumbers.
542
    """
543
    #pobyso_autoprint(sollyaExp)
544
    operatorSa = pobyso_get_head_function_so_sa(sollyaExpSo)
545
    sollyaLibFreeVariableName = sollya_lib_get_free_variable_name()
546
    # Constants and the free variable are special cases.
547
    # All other operator are dealt with in the same way.
548
    if (operatorSa != SOLLYA_BASE_FUNC_CONSTANT) and \
549
       (operatorSa != SOLLYA_BASE_FUNC_FREE_VARIABLE):
550
        (aritySa, subexpressionsSa) = pobyso_get_subfunctions_so_sa(sollyaExpSo)
551
        if aritySa == 1:
552
            sageExpSa = eval(pobyso_function_type_as_string_so_sa(operatorSa) + \
553
            "(" + pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], \
554
            realFieldSa) + ")")
555
        elif aritySa == 2:
556
            # We do not get through the preprocessor.
557
            # The "^" operator is then a special case.
558
            if operatorSa == SOLLYA_BASE_FUNC_POW:
559
                operatorAsStringSa = "**"
560
            else:
561
                operatorAsStringSa = \
562
                    pobyso_function_type_as_string_so_sa(operatorSa)
563
            sageExpSa = \
564
              eval("pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], realFieldSa)"\
565
              + " " + operatorAsStringSa + " " + \
566
                   "pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[1], realFieldSa)")
567
        # We do not know yet how to deal with arity >= 3 
568
        # (is there any in Sollya anyway?).
569
        else:
570
            sageExpSa = eval('None')
571
        return(sageExpSa)
572
    elif operatorSa == SOLLYA_BASE_FUNC_CONSTANT:
573
        #print "This is a constant"
574
        return pobyso_get_constant_as_rn_with_rf_so_sa(sollyaExpSo, realFieldSa)
575
    elif operatorSa == SOLLYA_BASE_FUNC_FREE_VARIABLE:
576
        #print "This is free variable"
577
        return(eval(sollyaLibFreeVariableName))
578
    else:
579
        print "Unexpected"
580
        return eval('None')
581
# End pobyso_get_sage_poly_from_sollya_poly
582

    
583
def pobyso_get_poly_sa_so(polySo, realFieldSa=None):
584
    """
585
    Create a Sollya polynomial from a Sage polynomial.
586
    """
587
    pass
588
# pobyso_get_poly_sa_so
589

    
590
def pobyso_get_poly_so_sa(polySo, realFieldSa=None):
591
    """
592
    Convert a Sollya polynomial into a Sage polynomial.
593
    We assume that the polynomial is in canonical form.
594
    If no realField is given, a RealField corresponding to the maximum precision 
595
    of the coefficients is internally computed.
596
    It is not returned but can be easily retrieved from the polynomial itself.
597
    Main steps:
598
    - (optional) compute the RealField of the coefficients;
599
    - convert the Sollya expression into a Sage expression;
600
    - convert the Sage expression into a Sage polynomial
601
    TODO: the canonical thing for the polynomial.
602
    """    
603
    if realFieldSa is None:
604
        expressionPrecSa = pobyso_get_max_prec_of_exp_so_sa(polySo)
605
        realFieldSa = RealField(expressionPrecSa)
606
    #print "Sollya expression before...",
607
    #pobyso_autoprint(polySo)
608

    
609
    expressionSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, \
610
                                                             realFieldSa)
611
    #print "...Sollya expression after.",
612
    #pobyso_autoprint(polySo)
613
    polyVariableSa = expressionSa.variables()[0]
614
    polyRingSa = realFieldSa[str(polyVariableSa)]
615
    #print polyRingSa
616
    # Do not use the polynomial(expressionSa, ring=polyRingSa) form!
617
    polynomialSa = polyRingSa(expressionSa)
618
    return(polynomialSa)
619
# End pobyso_get_sage_poly_from_sollya_poly
620

    
621
def pobyso_get_subfunctions(expressionSo):
622
    """ Legacy function. See pobyso_get_subfunctions_so_sa. """
623
    return(pobyso_get_subfunctions_so_sa(expressionSo)) 
624

    
625
def pobyso_get_subfunctions_so_sa(expressionSo):
626
    """
627
    Get the subfunctions of an expression.
628
    Return the number of subfunctions and the list of subfunctions addresses.
629
    S.T.: Could not figure out another way than that ugly list of declarations
630
    to recover the addresses of the subfunctions.
631
    We limit ourselves to arity 8 functions. 
632
    """
633
    subf0 = c_int(0)
634
    subf1 = c_int(0)
635
    subf2 = c_int(0)
636
    subf3 = c_int(0)
637
    subf4 = c_int(0)
638
    subf5 = c_int(0)
639
    subf6 = c_int(0)
640
    subf7 = c_int(0)
641
    subf8 = c_int(0)
642
    arity = c_int(0)
643
    nullPtr = POINTER(c_int)()
644
    sollya_lib_get_subfunctions(expressionSo, byref(arity), \
645
      byref(subf0), byref(subf1), byref(subf2), byref(subf3), \
646
      byref(subf4), byref(subf5),\
647
      byref(subf6), byref(subf7), byref(subf8), nullPtr, None) 
648
#    byref(cast(subfunctions[0], POINTER(c_int))), \
649
#    byref(cast(subfunctions[0], POINTER(c_int))), \
650
#    byref(cast(subfunctions[2], POINTER(c_int))), \
651
#    byref(cast(subfunctions[3], POINTER(c_int))), \
652
#    byref(cast(subfunctions[4], POINTER(c_int))), \
653
#    byref(cast(subfunctions[5], POINTER(c_int))), \
654
#    byref(cast(subfunctions[6], POINTER(c_int))), \
655
#    byref(cast(subfunctions[7], POINTER(c_int))), \
656
#    byref(cast(subfunctions[8], POINTER(c_int))), nullPtr)
657
    subfunctions = [subf0, subf1, subf2, subf3, subf4, subf5, subf6, subf7, \
658
                    subf8]
659
    subs = []
660
    if arity.value > pobyso_max_arity:
661
        return(0,[])
662
    for i in xrange(arity.value):
663
        subs.append(int(subfunctions[i].value))
664
        #print subs[i]
665
    return(int(arity.value), subs)
666
    
667
def pobyso_get_prec():
668
    """ Legacy function. See pobyso_get_prec_so_sa(). """
669
    return(pobyso_get_prec_so_sa())
670

    
671
def pobyso_get_prec_so():
672
    """
673
    Get the current default precision in Sollya.
674
    The return value is a Sollya object.
675
    Usefull when modifying the precision back and forth by avoiding
676
    extra conversions.
677
    """
678
    return(sollya_lib_get_prec(None))
679
    
680
def pobyso_get_prec_so_sa():
681
    """
682
    Get the current default precision in Sollya.
683
    The return value is Sage/Python int.
684
    """
685
    precSo = sollya_lib_get_prec(None)
686
    precSa = c_int(0)
687
    sollya_lib_get_constant_as_int(byref(precSa), precSo)
688
    sollya_lib_clear_obj(precSo)
689
    return(int(precSa.value))
690
# End pobyso_get_prec_so_sa.
691

    
692
def pobyso_get_prec_of_constant(ctExpSo):
693
    """ Legacy function. See pobyso_get_prec_of_constant_so_sa. """
694
    return(pobyso_get_prec_of_constant_so_sa(ctExpSo))
695

    
696
def pobyso_get_prec_of_constant_so_sa(ctExpSo):
697
    prec = c_int(0)
698
    retc = sollya_lib_get_prec_of_constant(byref(prec), ctExpSo, None)
699
    if retc == 0:
700
        return(None)
701
    return(int(prec.value))
702

    
703
def pobyso_get_prec_of_range_so_sa(rangeSo):
704
    prec = c_int(0)
705
    retc = sollya_lib_get_prec_of_range(byref(prec), rangeSo, None)
706
    if retc == 0:
707
        return(None)
708
    return(int(prec.value))
709

    
710
def pobyso_infnorm_so_so(func, interval, file = None, intervalList = None):
711
    print "Do not use this function. User pobyso_supnorm_so_so instead."
712
    return(None)
713

    
714
def pobyso_interval_to_range_sa_so(intervalSa, precisionSa=None):
715
    if precisionSa is None:
716
        precisionSa = intervalSa.parent().precision()
717
    intervalSo = pobyso_bounds_to_range_sa_so(intervalSa.lower(),\
718
                                              intervalSa.upper(),\
719
                                              precisionSa)
720
    return(intervalSo)
721
# End pobyso_interval_to_range_sa_so
722

    
723
def pobyso_lib_init():
724
    sollya_lib_init(None)
725
    
726
def pobyso_name_free_variable(freeVariableNameSa):
727
    """ Legacy function. See pobyso_name_free_variable_sa_so. """
728
    pobyso_name_free_variable_sa_so(freeVariableNameSa)
729

    
730
def pobyso_name_free_variable_sa_so(freeVariableNameSa):
731
    """
732
    Set the free variable name in Sollya from a Sage string.
733
    """
734
    sollya_lib_name_free_variable(freeVariableNameSa)
735

    
736
def pobyso_parse_string(string):
737
    """ Legacy function. See pobyso_parse_string_sa_so. """
738
    return(pobyso_parse_string_sa_so(string))
739
 
740
def pobyso_parse_string_sa_so(string):
741
    """
742
    Get the Sollya expression computed from a Sage string.
743
    """
744
    return(sollya_lib_parse_string(string))
745

    
746
def pobyso_range(rnLowerBound, rnUpperBound):
747
    """ Legacy function. See pobyso_range_sa_so. """
748
    return(pobyso_range_sa_so(rnLowerBound, rnUpperBound)) 
749

    
750

    
751
def pobyso_range_to_interval_so_sa(rangeSo, realIntervalFieldSa = None):
752
    """
753
    Get a Sage interval from a Sollya range.
754
    If no realIntervalField is given as a parameter, the Sage interval
755
    precision is that of the Sollya range.
756
    Otherwise, the precision is that of the realIntervalField. In this case
757
    rounding may happen.
758
    """
759
    if realIntervalFieldSa is None:
760
        precSa = pobyso_get_prec_of_range_so_sa(rangeSo)
761
        realIntervalFieldSa = RealIntervalField(precSa)
762
    intervalSa = \
763
        pobyso_get_interval_from_range_so_sa(rangeSo, realIntervalFieldSa) 
764
    return(intervalSa)
765

    
766
def pobyso_remez_canonical_sa_sa(func, \
767
                                 degree, \
768
                                 lowerBound, \
769
                                 upperBound, \
770
                                 weight = None, \
771
                                 quality = None):
772
    """
773
    All arguments are Sage/Python.
774
    The functions (func and weight) must be passed as expressions or strings.
775
    Otherwise the function fails. 
776
    The return value is a Sage polynomial.
777
    """
778
    var('zorglub')    # Dummy variable name for type check only. Type of 
779
    # zorglub is "symbolic expression".
780
    polySo = pobyso_remez_canonical_sa_so(func, \
781
                                 degree, \
782
                                 lowerBound, \
783
                                 upperBound, \
784
                                 weight, \
785
                                 quality)
786
    # String test
787
    if parent(func) == parent("string"):
788
        functionSa = eval(func)
789
    # Expression test.
790
    elif type(func) == type(zorglub):
791
        functionSa = func
792
    else:
793
        return None
794
    #
795
    maxPrecision = 0
796
    if polySo is None:
797
        return(None)
798
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
799
    RRRRSa = RealField(maxPrecision)
800
    polynomialRingSa = RRRRSa[functionSa.variables()[0]]
801
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, RRRRSa)
802
    polySa = polynomial(expSa, polynomialRingSa)
803
    sollya_lib_clear_obj(polySo)
804
    return(polySa)
805
# End pobyso_remez_canonical_sa_sa
806
    
807
def pobyso_remez_canonical(func, \
808
                           degree, \
809
                           lowerBound, \
810
                           upperBound, \
811
                           weight = "1", \
812
                           quality = None):
813
    """ Legacy function. See pobyso_remez_canonical_sa_so. """
814
    return(pobyso_remez_canonical_sa_so(func, \
815
                                        degree, \
816
                                        lowerBound, \
817
                                        upperBound, \
818
                                        weight, \
819
                                        quality))
820
def pobyso_remez_canonical_sa_so(func, \
821
                                 degree, \
822
                                 lowerBound, \
823
                                 upperBound, \
824
                                 weight = None, \
825
                                 quality = None):
826
    """
827
    All arguments are Sage/Python.
828
    The functions (func and weight) must be passed as expressions or strings.
829
    Otherwise the function fails. 
830
    The return value is a pointer to a Sollya function.
831
    """
832
    var('zorglub')    # Dummy variable name for type check only. Type of
833
    # zorglub is "symbolic expression".
834
    currentVariableNameSa = None
835
    # The func argument can be of different types (string, 
836
    # symbolic expression...)
837
    if parent(func) == parent("string"):
838
        localFuncSa = eval(func)
839
        if len(localFuncSa.variables()) > 0:
840
            currentVariableNameSa = localFuncSa.variables()[0]
841
            sollya_lib_name_free_variable(str(currentVariableNameSa))
842
            functionSo = sollya_lib_parse_string(localFuncSa._assume_str())
843
    # Expression test.
844
    elif type(func) == type(zorglub):
845
        # Until we are able to translate Sage expressions into Sollya 
846
        # expressions : parse the string version.
847
        if len(func.variables()) > 0:
848
            currentVariableNameSa = func.variables()[0]
849
            sollya_lib_name_free_variable(str(currentVariableNameSa))
850
            functionSo = sollya_lib_parse_string(func._assume_str())
851
    else:
852
        return(None)
853
    if weight is None: # No weight given -> 1.
854
        weightSo = pobyso_constant_1_sa_so()
855
    elif parent(weight) == parent("string"): # Weight given as string: parse it.
856
        weightSo = sollya_lib_parse_string(func)
857
    elif type(weight) == type(zorglub): # Weight given as symbolice expression.
858
        functionSo = sollya_lib_parse_string_sa_so(weight._assume_str())
859
    else:
860
        return(None)
861
    degreeSo = pobyso_constant_from_int(degree)
862
    rangeSo = pobyso_bounds_to_range_sa_so(lowerBound, upperBound)
863
    if not quality is None:
864
        qualitySo= pobyso_constant_sa_so(quality)
865
    else:
866
        qualitySo = None
867
        
868
    remezPolySo = sollya_lib_remez(functionSo, \
869
                                   degreeSo, \
870
                                   rangeSo, \
871
                                   weightSo, \
872
                                   qualitySo, \
873
                                   None)
874
    sollya_lib_clear_obj(functionSo)
875
    sollya_lib_clear_obj(degreeSo)
876
    sollya_lib_clear_obj(rangeSo)
877
    sollya_lib_clear_obj(weightSo)
878
    if not qualitySo is None:
879
        sollya_lib_clear_obj(qualitySo)
880
    return(remezPolySo)
881
# End pobyso_remez_canonical_sa_so
882

    
883
def pobyso_remez_canonical_so_so(funcSo, \
884
                                 degreeSo, \
885
                                 rangeSo, \
886
                                 weightSo = pobyso_constant_1_sa_so(),\
887
                                 qualitySo = None):
888
    """
889
    All arguments are pointers to Sollya objects.
890
    The return value is a pointer to a Sollya function.
891
    """
892
    if not sollya_lib_obj_is_function(funcSo):
893
        return(None)
894
    return(sollya_lib_remez(funcSo, degreeSo, rangeSo, weightSo, qualitySo, None))
895
    
896
def pobyso_set_canonical_off():
897
    sollya_lib_set_canonical(sollya_lib_off())
898

    
899
def pobyso_set_canonical_on():
900
    sollya_lib_set_canonical(sollya_lib_on())
901

    
902
def pobyso_set_prec(p):
903
    """ Legacy function. See pobyso_set_prec_sa_so. """
904
    pobyso_set_prec_sa_so(p)
905

    
906
def pobyso_set_prec_sa_so(p):
907
    a = c_int(p)
908
    precSo = c_void_p(sollya_lib_constant_from_int(a))
909
    sollya_lib_set_prec(precSo, None)
910

    
911
def pobyso_set_prec_so_so(newPrecSo):
912
    sollya_lib_set_prec(newPrecSo, None)
913

    
914
def pobyso_supnorm_so_so(polySo, funcSo, intervalSo, errorTypeSo = None,\
915
                         accuracySo = None):
916
    """
917
    Computes the supnorm of the approximation error between the given 
918
    polynomial and function.
919
    errorTypeSo defaults to "absolute".
920
    accuracySo defaults to 2^(-40).
921
    """
922
    if errorTypeSo is None:
923
        errorTypeSo = sollya_lib_absolute(None)
924
        errorTypeIsNone = True
925
    else:
926
        errorTypeIsNone = False
927
    #
928
    if accuracySo is None:
929
        # Notice the **!
930
        accuracySo = pobyso_constant_sa_so(RR(2**(-40)))
931
        accuracyIsNone = True
932
    else:
933
        accuracyIsNone = False
934
    pobyso_autoprint(accuracySo)
935
    resultSo = \
936
        sollya_lib_supnorm(polySo, funcSo, intervalSo, errorTypeSo, \
937
                              accuracySo)
938
    if errorTypeIsNone:
939
        sollya_lib_clear_obj(errorTypeSo)
940
    if accuracyIsNone:
941
        sollya_lib_clear_obj(accuracySo)
942
    return resultSo
943
# End pobyso_supnorm_so_so
944

    
945
def pobyso_taylor_expansion_with_change_var_so_so(functionSo, degreeSo, \
946
                                                  rangeSo, \
947
                                                  errorTypeSo=None, \
948
                                                  sollyaPrecSo=None):
949
    """
950
    Compute the Taylor expansion with the variable change
951
    x -> (x-intervalCenter) included.
952
    """
953
    # No global change of the working precision.
954
    if not sollyaPrecSo is None:
955
        initialPrecSo = sollya_lib_get_prec(None)
956
        sollya_lib_set_prec(sollyaPrecSo)
957
    #
958
    # Error type stuff: default to absolute.
959
    if errorTypeSo is None:
960
        errorTypeIsNone = True
961
        errorTypeSo = sollya_lib_absolute(None)
962
    else:
963
        errorTypeIsNone = False
964
    intervalCenterSo = sollya_lib_mid(rangeSo)
965
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, \
966
                                         intervalCenterSo, \
967
                                         rangeSo, errorTypeSo, None)
968
    (taylorFormListSo, numElements, isEndElliptic) = \
969
        pobyso_get_list_elements_so_so(taylorFormSo)
970
    polySo = taylorFormListSo[0]
971
    errorRangeSo = taylorFormListSo[2]
972
    maxErrorSo = sollya_lib_sup(errorRangeSo)
973
    changeVarExpSo = sollya_lib_build_function_sub(\
974
                       sollya_lib_build_function_free_variable(),\
975
                       sollya_lib_copy_obj(intervalCenterSo))
976
    polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpSo) 
977
    # If changed, reset the Sollya working precision.
978
    if not sollyaPrecSo is None:
979
        sollya_lib_set_prec(initialPrecSo)
980
        sollya_lib_clear_obj(initialPrecSo)
981
    if errorTypeIsNone:
982
        sollya_lib_clear_obj(errorTypeSo)
983
    sollya_lib_clear_obj(taylorFormSo)
984
    # Do not clear maxErrorSo.
985
    return((polyVarChangedSo, intervalCenterSo, maxErrorSo))
986
# end pobyso_taylor_expansion_with_change_var_so_so
987

    
988
def pobyso_taylor_expansion_no_change_var_so_so(functionSo, degreeSo, rangeSo, \
989
                                                errorTypeSo=None, \
990
                                                sollyaPrecSo=None):
991
    """
992
    Compute the Taylor expansion without the variable change
993
    x -> x-intervalCenter.
994
    """
995
    # No global change of the working precision.
996
    if not sollyaPrecSo is None:
997
        initialPrecSo = sollya_lib_get_prec(None)
998
        sollya_lib_set_prec(sollyaPrecSo)
999
    # Error type stuff: default to absolute.
1000
    if errorTypeSo is None:
1001
        errorTypeIsNone = True
1002
        errorTypeSo = sollya_lib_absolute(None)
1003
    else:
1004
        errorTypeIsNone = False
1005
    intervalCenterSo = sollya_lib_mid(rangeSo)
1006
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, \
1007
                                         intervalCenterSo, \
1008
                                         rangeSo, errorTypeSo, None)
1009
    (taylorFormListSo, numElementsSo, isEndEllipticSo) = \
1010
        pobyso_get_list_elements_so_so(taylorFormSo)
1011
    polySo = sollya_lib_copy_obj(taylorFormListSo[0])
1012
    errorRangeSo = taylorFormListSo[2]
1013
    # No copy_obj needed here: a new object is created.
1014
    maxErrorSo = sollya_lib_sup(errorRangeSo)
1015
    # If changed, reset the Sollya working precision.
1016
    if not sollyaPrecSo is None:
1017
        sollya_lib_set_prec(initialPrecSo)
1018
        sollya_lib_clear_obj(initialPrecSo)
1019
    if errorTypeIsNone:
1020
        sollya_lib_clear_obj(errorTypeSo)
1021
    sollya_lib_clear_obj(taylorFormSo)
1022
    for element in taylorFormListSo:
1023
        sollya_lib_clear_obj(element)
1024
    # Those are cleared with taylorForSo.
1025
    #sollya_lib_clear_obj(numElementsSo)
1026
    #sollya_lib_clear_obj(isEndEllipticSo)
1027
    return((polySo, intervalCenterSo, maxErrorSo))
1028
# end pobyso_taylor_expansion_no_change_var_so_so
1029

    
1030
def pobyso_taylor(function, degree, point):
1031
    """ Legacy function. See pobysoTaylor_so_so. """
1032
    return(pobyso_taylor_so_so(function, degree, point))
1033

    
1034
def pobyso_taylor_so_so(functionSo, degreeSo, pointSo):
1035
    return(sollya_lib_taylor(functionSo, degreeSo, pointSo))
1036
    
1037
def pobyso_taylorform(function, degree, point = None, 
1038
                      interval = None, errorType=None):
1039
    """ Legacy function. See pobyso_taylorform_sa_sa;"""
1040
    
1041
def pobyso_taylorform_sa_sa(functionSa, \
1042
                            degreeSa, \
1043
                            pointSa, \
1044
                            intervalSa=None, \
1045
                            errorTypeSa=None, \
1046
                            precisionSa=None):
1047
    """
1048
    Compute the Taylor form of 'degreeSa' for 'functionSa' at 'pointSa' 
1049
    for 'intervalSa' with 'errorTypeSa' (a string) using 'precisionSa'. 
1050
    point: must be a Real or a Real interval.
1051
    return the Taylor form as an array
1052
    TODO: take care of the interval and of the point when it is an interval;
1053
          when errorType is not None;
1054
          take care of the other elements of the Taylor form (coefficients 
1055
          errors and delta.
1056
    """
1057
    # Absolute as the default error.
1058
    if errorTypeSa is None:
1059
        errorTypeSo = sollya_lib_absolute()
1060
    elif errorTypeSa == "relative":
1061
        errorTypeSo = sollya_lib_relative()
1062
    elif errortypeSa == "absolute":
1063
        errorTypeSo = sollya_lib_absolute()
1064
    else:
1065
        # No clean up needed.
1066
        return None
1067
    # Global precision stuff
1068
    precisionChangedSa = False
1069
    currentSollyaPrecSo = pobyso_get_prec_so()
1070
    currentSollyaPrecSa = pobyso_constant_from_int_so_sa(currentSollyaPrecSo)
1071
    if not precisionSa is None:
1072
        if precisionSa > currentSollyaPrecSa:
1073
            pobyso_set_prec_sa_so(precisionSa)
1074
            precisionChangedSa = True
1075
            
1076
    if len(functionSa.variables()) > 0:
1077
        varSa = functionSa.variables()[0]
1078
        pobyso_name_free_variable_sa_so(str(varSa))
1079
    # In any case (point or interval) the parent of pointSa has a precision
1080
    # method.
1081
    pointPrecSa = pointSa.parent().precision()
1082
    if precisionSa > pointPrecSa:
1083
        pointPrecSa = precisionSa
1084
    # In any case (point or interval) pointSa has a base_ring() method.
1085
    pointBaseRingString = str(pointSa.base_ring())
1086
    if re.search('Interval', pointBaseRingString) is None: # Point
1087
        pointSo = pobyso_constant_sa_so(pointSa, pointPrecSa)
1088
    else: # Interval.
1089
        pointSo = pobyso_interval_to_range_sa_so(pointSa, pointPrecSa)
1090
    # Sollyafy the function.
1091
    functionSo = pobyso_parse_string_sa_so(functionSa._assume_str())
1092
    if sollya_lib_obj_is_error(functionSo):
1093
        print "pobyso_tailorform: function string can't be parsed!"
1094
        return None
1095
    # Sollyafy the degree
1096
    degreeSo = sollya_lib_constant_from_int(int(degreeSa))
1097
    # Sollyafy the point
1098
    # Call Sollya
1099
    taylorFormSo = \
1100
        sollya_lib_taylorform(functionSo, degreeSo, pointSo, errorTypeSo,\
1101
                                         None)
1102
    sollya_lib_clear_obj(functionSo)
1103
    sollya_lib_clear_obj(degreeSo)
1104
    sollya_lib_clear_obj(pointSo)
1105
    sollya_lib_clear_obj(errorTypeSo)
1106
    (tfsAsList, numElements, isEndElliptic) = \
1107
            pobyso_get_list_elements_so_so(taylorFormSo)
1108
    polySo = tfsAsList[0]
1109
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
1110
    polyRealField = RealField(maxPrecision)
1111
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, polyRealField)
1112
    if precisionChangedSa:
1113
        sollya_lib_set_prec(currentSollyaPrecSo)
1114
        sollya_lib_clear_obj(currentSollyaPrecSo)
1115
    polynomialRing = polyRealField[str(varSa)]
1116
    polySa = polynomial(expSa, polynomialRing)
1117
    taylorFormSa = [polySa]
1118
    # Final clean-up.
1119
    sollya_lib_clear_obj(taylorFormSo)
1120
    return(taylorFormSa)
1121
# End pobyso_taylor_form_sa_sa
1122

    
1123
def pobyso_taylorform_so_so(functionSo, degreeSo, pointSo, intervalSo=None, \
1124
                            errorTypeSo=None):
1125
    createdErrorType = False
1126
    if errorTypeSo is None:
1127
        errorTypeSo = sollya_lib_absolute()
1128
        createdErrorType = True
1129
    else:
1130
        #TODO: deal with the other case.
1131
        pass
1132
    if intervalSo is None:
1133
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
1134
                                         errorTypeSo, None)
1135
    else:
1136
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
1137
                                         intervalSo, errorTypeSo, None)
1138
    if createdErrorType:
1139
        sollya_lib_clear_obj(errorTypeSo)
1140
    return(resultSo)
1141
        
1142

    
1143
def pobyso_univar_polynomial_print_reverse(polySa):
1144
    """ Legacy function. See pobyso_univar_polynomial_print_reverse_sa_sa. """
1145
    return(pobyso_univar_polynomial_print_reverse_sa_sa(polySa))
1146

    
1147
def pobyso_univar_polynomial_print_reverse_sa_sa(polySa):
1148
    """
1149
    Return the string representation of a univariate polynomial with
1150
    monomials ordered in the x^0..x^n order of the monomials.
1151
    Remember: Sage
1152
    """
1153
    polynomialRing = polySa.base_ring()
1154
    # A very expensive solution:
1155
    # -create a fake multivariate polynomial field with only one variable,
1156
    #   specifying a negative lexicographical order;
1157
    mpolynomialRing = PolynomialRing(polynomialRing.base(), \
1158
                                     polynomialRing.variable_name(), \
1159
                                     1, order='neglex')
1160
    # - convert the univariate argument polynomial into a multivariate
1161
    #   version;
1162
    p = mpolynomialRing(polySa)
1163
    # - return the string representation of the converted form.
1164
    # There is no simple str() method defined for p's class.
1165
    return(p.__str__())
1166
#
1167
print pobyso_get_prec()  
1168
pobyso_set_prec(165)
1169
print pobyso_get_prec()  
1170
a=100
1171
print type(a)
1172
id(a)
1173
print "Max arity: ", pobyso_max_arity
1174
print "Function tripleDouble (43) as a string: ", pobyso_function_type_as_string(43)
1175
print "Function None (44) as a string: ", pobyso_function_type_as_string(44)
1176
print "...Pobyso check done"