Statistiques
| Révision :

root / pobysoPythonSage / src / pobyso.py @ 116

Historique | Voir | Annoter | Télécharger (44,9 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_cmp(rnArgSa, cteSo):
151
    """
152
    Compare the MPFR value a RealNumber with that of a Sollya constant.
153
    
154
    Get the value of the Sollya constant into a RealNumber and compare
155
    using MPFR. Could be optimized by working directly with a mpfr_t
156
    for the intermediate number. 
157
    """
158
    # Get the precision of the Sollya constant to build a Sage RealNumber 
159
    # with enough precision.to hold it.
160
    precisionOfCte = c_int(0)
161
    # From the Sollya constant, create a local Sage RealNumber.
162
    sollya_lib_get_prec_of_constant(precisionOfCte, cteSo) 
163
    #print "Precision of constant: ", precisionOfCte
164
    RRRR = RealField(precisionOfCte.value)
165
    rnLocalSa = RRRR(0)
166
    sollya_lib_get_constant(get_rn_value(rnLocalSa), cteSo)
167
    #
168
    ## Compare the Sage RealNumber version of the Sollya constant with rnArg.
169
    return(cmp_rn_value(rnArgSa, rnLocal))
170
# End pobyso_smp
171

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

    
209
def pobyso_constant(rnArg):
210
    """ Legacy function. See pobyso_constant_sa_so. """
211
    return(pobyso_constant_sa_so(rnArg))
212
    
213
def pobyso_constant_sa_so(rnArgSa, precisionSa=None):
214
    """
215
    Create a Sollya constant from a Sage RealNumber.
216
    """
217
    # Precision stuff
218
    if precisionSa is None:
219
        precisionSa = rnArgSa.parent().precision()
220
    currentSollyaPrecisionSo = sollya_lib_get_prec()
221
    currentSollyaPrecisionSa = \
222
        pobyso_constant_from_int(currentSollyaPrecisionSo)
223
    # Sollya constant creation takes place here.
224
    if precisionSa > currentSollyaPrecisionSa:
225
        pobyso_set_prec_sa_so(precisionSa)
226
        constantSo = sollya_lib_constant(get_rn_value(rnArgSa))
227
        pobyso_set_prec_sa_so(currentSollyaPrecision)
228
    else:
229
        constantSo = sollya_lib_constant(get_rn_value(rnArgSa))
230
    sollya_lib_clear_obj(currentSollyaPrecisionSo)
231
    return(constantSo)
232
# End pobyso_constant_sa_so
233
     
234
def pobyso_constant_0_sa_so():
235
    """
236
    Obvious.
237
    """
238
    return(pobyso_constant_from_int_sa_so(0))
239

    
240
def pobyso_constant_1():
241
    """
242
    Obvious.
243
    Legacy function. See pobyso_constant_so_so. 
244
    """
245
    return(pobyso_constant_1_sa_so())
246

    
247
def pobyso_constant_1_sa_so():
248
    """
249
    Obvious.
250
    """
251
    return(pobyso_constant_from_int_sa_so(1))
252

    
253
def pobyso_constant_from_int(anInt):
254
    """ Legacy function. See pobyso_constant_from_int_sa_so. """
255
    return(pobyso_constant_from_int_sa_so(anInt))
256

    
257
def pobyso_constant_from_int_sa_so(anInt):
258
    """
259
    Get a Sollya constant from a Sage int.
260
    """
261
    return(sollya_lib_constant_from_int(int(anInt)))
262

    
263
def pobyso_constant_from_int_so_sa(constSo):
264
    """
265
    Get Sage int from a Sollya int constant.
266
    Usefull for precision or powers in polynomials.
267
    """
268
    constSa = c_int(0)
269
    sollya_lib_get_constant_as_int(byref(constSa), constSo)
270
    return(constSa.value)
271
# End pobyso_constant_from_int_so_sa
272

    
273
def pobyso_function_type_as_string(funcType):
274
    """ Legacy function. See pobyso_function_type_as_string_so_sa. """
275
    return(pobyso_function_type_as_string_so_sa(funcType))
276

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

    
373
def pobyso_get_constant(rnArgSa, constSo):
374
    """ Legacy function. See pobyso_get_constant_so_sa. """
375
    return(pobyso_get_constant_so_sa(rnArgSa, constSo))
376

    
377
def pobyso_get_constant_so_sa(rnArgSa, constSo):
378
    """
379
    Set the value of rnArgSo to the value of constSo in MPFR_RNDN mode.
380
    rnArg must already exist and belong to some RealField.
381
    We assume that constSo points to a Sollya constant.
382
    """
383
    return(sollya_lib_get_constant(get_rn_value(rnArgSa), constSo))
384
    
385
def pobyso_get_constant_as_rn(ctExpSo):
386
    """ 
387
    Legacy function. See pobyso_get_constant_as_rn_so_sa. 
388
    """ 
389
    return(pobyso_get_constant_as_rn_so_sa(ctExpSo))
390
    
391
def pobyso_get_constant_as_rn_so_sa(constExpSo):
392
    """
393
    Get a Sollya constant as a Sage "real number".
394
    The precision of the floating-point number returned is that of the Sollya
395
    constant.
396
    """
397
    precisionSa  = pobyso_get_prec_of_constant_so_sa(constExpSo) 
398
    RRRR = RealField(precisionSa)
399
    rnSa = RRRR(0)
400
    sollya_lib_get_constant(get_rn_value(rnSa), constExpSo)
401
    return(rnSa)
402
# End pobyso_get_constant_as_rn_so_sa
403

    
404
def pobyso_get_constant_as_rn_with_rf(ctExp, realField):
405
    """ 
406
    Legacy function. See pobyso_get_constant_as_rn_with_rf_so_sa.
407
    """
408
    return(pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField))
409
    
410
def pobyso_get_constant_as_rn_with_rf_so_sa(ctExpSo, realFieldSa = None):
411
    """
412
    Get a Sollya constant as a Sage "real number".
413
    If no real field is specified, the precision of the floating-point number 
414
    returned is that of the Sollya constant.
415
    Otherwise is is that of the real field. Hence rounding may happen.
416
    """
417
    if realFieldSa is None:
418
        sollyaPrecSa = pobyso_get_prec_of_constant_so_sa(ctExpSo)
419
        realFieldSa = RealField(sollyaPrecSa)
420
    rnSa = realFieldSa(0)
421
    sollya_lib_get_constant(get_rn_value(rnSa), ctExpSo)
422
    return(rnSa)
423
# End pobyso_get_constant_as_rn_with_rf_so_sa
424

    
425
def pobyso_get_free_variable_name():
426
    """ 
427
    Legacy function. See pobyso_get_free_variable_name_so_sa.
428
    """
429
    return(pobyso_get_free_variable_name_so_sa())
430

    
431
def pobyso_get_free_variable_name_so_sa():
432
    return(sollya_lib_get_free_variable_name())
433
    
434
def pobyso_get_function_arity(expressionSo):
435
    """ 
436
    Legacy function. See pobyso_get_function_arity_so_sa.
437
    """
438
    return(pobyso_get_function_arity_so_sa(expressionSo))
439

    
440
def pobyso_get_function_arity_so_sa(expressionSo):
441
    arity = c_int(0)
442
    sollya_lib_get_function_arity(byref(arity),expressionSo)
443
    return(int(arity.value))
444

    
445
def pobyso_get_head_function(expressionSo):
446
    """ 
447
    Legacy function. See pobyso_get_head_function_so_sa. 
448
    """
449
    return(pobyso_get_head_function_so_sa(expressionSo)) 
450

    
451
def pobyso_get_head_function_so_sa(expressionSo):
452
    functionType = c_int(0)
453
    sollya_lib_get_head_function(byref(functionType), expressionSo, None)
454
    return(int(functionType.value))
455

    
456
def pobyso_get_interval_from_range_so_sa(soRange, realIntervalFieldSa = None ):
457
    """
458
    Return the Sage interval corresponding to the Sollya range argument.
459
    If no reaIntervalField is passed as an argument, the interval bounds are not
460
    rounded: they are elements of RealIntervalField of the "right" precision
461
    to hold all the digits.
462
    """
463
    prec = c_int(0)
464
    if realIntervalFieldSa is None:
465
        retval = sollya_lib_get_prec_of_range(byref(prec), soRange, None)
466
        if retval == 0:
467
            return(None)
468
        realIntervalFieldSa = RealIntervalField(prec.value)
469
    intervalSa = realIntervalFieldSa(0,0)
470
    retval = \
471
        sollya_lib_get_interval_from_range(get_interval_value(intervalSa),\
472
                                           soRange)
473
    if retval == 0:
474
        return(None)
475
    return(intervalSa)
476
# End pobyso_get_interval_from_range_so_sa
477

    
478
def pobyso_get_list_elements(soObj):
479
    """ Legacy function. See pobyso_get_list_elements_so_so. """
480
    return(pobyso_get_list_elements_so_so(soObj))
481
 
482
def pobyso_get_list_elements_so_so(objSo):
483
    """
484
    Get the list elements as a Sage/Python array of Sollya objects.
485
    The other data returned are Sage/Python objects.
486
    """
487
    listAddress = POINTER(c_longlong)()
488
    numElements = c_int(0)
489
    isEndElliptic = c_int(0)
490
    listAsList = []
491
    result = sollya_lib_get_list_elements(byref(listAddress),\
492
                                          byref(numElements),\
493
                                          byref(isEndElliptic),\
494
                                          objSo)
495
    if result == 0 :
496
        return None
497
    for i in xrange(0, numElements.value, 1):
498
       listAsList.append(sollya_lib_copy_obj(listAddress[i]))
499
    return(listAsList, numElements.value, isEndElliptic.value)
500

    
501
def pobyso_get_max_prec_of_exp(soExp):
502
    """ Legacy function. See pobyso_get_max_prec_of_exp_so_sa. """
503
    return(pobyso_get_max_prec_of_exp_so_sa(soExp))
504

    
505
def pobyso_get_max_prec_of_exp_so_sa(expSo):
506
    """
507
    Get the maximum precision used for the numbers in a Sollya expression.
508
    
509
    Arguments:
510
    soExp -- a Sollya expression pointer
511
    Return value:
512
    A Python integer
513
    TODO: 
514
    - error management;
515
    - correctly deal with numerical type such as DOUBLEEXTENDED.
516
    """
517
    maxPrecision = 0
518
    minConstPrec = 0
519
    currentConstPrec = 0
520
    operator = pobyso_get_head_function_so_sa(expSo)
521
    if (operator != SOLLYA_BASE_FUNC_CONSTANT) and \
522
    (operator != SOLLYA_BASE_FUNC_FREE_VARIABLE):
523
        (arity, subexpressions) = pobyso_get_subfunctions_so_sa(expSo)
524
        for i in xrange(arity):
525
            maxPrecisionCandidate = \
526
                pobyso_get_max_prec_of_exp_so_sa(subexpressions[i])
527
            if maxPrecisionCandidate > maxPrecision:
528
                maxPrecision = maxPrecisionCandidate
529
        return(maxPrecision)
530
    elif operator == SOLLYA_BASE_FUNC_CONSTANT:
531
        #minConstPrec = pobyso_get_min_prec_of_constant_so_sa(expSo)
532
        #currentConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
533
        #print minConstPrec, " - ", currentConstPrec 
534
        return(pobyso_get_min_prec_of_constant_so_sa(expSo))
535
    
536
    elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
537
        return(0)
538
    else:
539
        print "pobyso_get_max_prec_of_exp_so_sa: unexepected operator."
540
        return(0)
541

    
542
def pobyso_get_min_prec_of_constant_so_sa(constExpSo):
543
    """
544
    Get the minimum precision necessary to represent the value of a Sollya
545
    constant.
546
    MPFR_MIN_PREC and powers of 2 are taken into account.
547
    We assume that constExpSo is a point
548
    """
549
    constExpAsRnSa = pobyso_get_constant_as_rn_so_sa(constExpSo)
550
    return(min_mpfr_size(get_rn_value(constExpAsRnSa)))
551

    
552
def pobyso_get_sage_exp_from_sollya_exp(sollyaExpSo, realField = RR):
553
    """ Legacy function. See pobyso_get_sage_exp_from_sollya_exp_so_sa. """
554
    return(pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, \
555
                                                     realField = RR))
556

    
557
def pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExpSo, realFieldSa = RR):
558
    """
559
    Get a Sage expression from a Sollya expression. 
560
    Currently only tested with polynomials with floating-point coefficients.
561
    Notice that, in the returned polynomial, the exponents are RealNumbers.
562
    """
563
    #pobyso_autoprint(sollyaExp)
564
    operatorSa = pobyso_get_head_function_so_sa(sollyaExpSo)
565
    sollyaLibFreeVariableName = sollya_lib_get_free_variable_name()
566
    # Constants and the free variable are special cases.
567
    # All other operator are dealt with in the same way.
568
    if (operatorSa != SOLLYA_BASE_FUNC_CONSTANT) and \
569
       (operatorSa != SOLLYA_BASE_FUNC_FREE_VARIABLE):
570
        (aritySa, subexpressionsSa) = pobyso_get_subfunctions_so_sa(sollyaExpSo)
571
        if aritySa == 1:
572
            sageExpSa = eval(pobyso_function_type_as_string_so_sa(operatorSa) + \
573
            "(" + pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], \
574
            realFieldSa) + ")")
575
        elif aritySa == 2:
576
            # We do not get through the preprocessor.
577
            # The "^" operator is then a special case.
578
            if operatorSa == SOLLYA_BASE_FUNC_POW:
579
                operatorAsStringSa = "**"
580
            else:
581
                operatorAsStringSa = \
582
                    pobyso_function_type_as_string_so_sa(operatorSa)
583
            sageExpSa = \
584
              eval("pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[0], realFieldSa)"\
585
              + " " + operatorAsStringSa + " " + \
586
                   "pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressionsSa[1], realFieldSa)")
587
        # We do not know yet how to deal with arity >= 3 
588
        # (is there any in Sollya anyway?).
589
        else:
590
            sageExpSa = eval('None')
591
        return(sageExpSa)
592
    elif operatorSa == SOLLYA_BASE_FUNC_CONSTANT:
593
        #print "This is a constant"
594
        return pobyso_get_constant_as_rn_with_rf_so_sa(sollyaExpSo, realFieldSa)
595
    elif operatorSa == SOLLYA_BASE_FUNC_FREE_VARIABLE:
596
        #print "This is free variable"
597
        return(eval(sollyaLibFreeVariableName))
598
    else:
599
        print "Unexpected"
600
        return eval('None')
601
# End pobyso_get_sage_poly_from_sollya_poly
602

    
603
def pobyso_get_poly_sa_so(polySo, realFieldSa=None):
604
    """
605
    Create a Sollya polynomial from a Sage polynomial.
606
    """
607
    pass
608
# pobyso_get_poly_sa_so
609

    
610
def pobyso_get_poly_so_sa(polySo, realFieldSa=None):
611
    """
612
    Convert a Sollya polynomial into a Sage polynomial.
613
    We assume that the polynomial is in canonical form.
614
    If no realField is given, a RealField corresponding to the maximum precision 
615
    of the coefficients is internally computed.
616
    It is not returned but can be easily retrieved from the polynomial itself.
617
    Main steps:
618
    - (optional) compute the RealField of the coefficients;
619
    - convert the Sollya expression into a Sage expression;
620
    - convert the Sage expression into a Sage polynomial
621
    TODO: the canonical thing for the polynomial.
622
    """    
623
    if realFieldSa is None:
624
        expressionPrecSa = pobyso_get_max_prec_of_exp_so_sa(polySo)
625
        realFieldSa = RealField(expressionPrecSa)
626
    #print "Sollya expression before...",
627
    #pobyso_autoprint(polySo)
628

    
629
    expressionSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, \
630
                                                             realFieldSa)
631
    #print "...Sollya expression after.",
632
    #pobyso_autoprint(polySo)
633
    polyVariableSa = expressionSa.variables()[0]
634
    polyRingSa = realFieldSa[str(polyVariableSa)]
635
    #print polyRingSa
636
    # Do not use the polynomial(expressionSa, ring=polyRingSa) form!
637
    polynomialSa = polyRingSa(expressionSa)
638
    return(polynomialSa)
639
# End pobyso_get_sage_poly_from_sollya_poly
640

    
641
def pobyso_get_subfunctions(expressionSo):
642
    """ Legacy function. See pobyso_get_subfunctions_so_sa. """
643
    return(pobyso_get_subfunctions_so_sa(expressionSo)) 
644

    
645
def pobyso_get_subfunctions_so_sa(expressionSo):
646
    """
647
    Get the subfunctions of an expression.
648
    Return the number of subfunctions and the list of subfunctions addresses.
649
    S.T.: Could not figure out another way than that ugly list of declarations
650
    to recover the addresses of the subfunctions.
651
    We limit ourselves to arity 8 functions. 
652
    """
653
    subf0 = c_int(0)
654
    subf1 = c_int(0)
655
    subf2 = c_int(0)
656
    subf3 = c_int(0)
657
    subf4 = c_int(0)
658
    subf5 = c_int(0)
659
    subf6 = c_int(0)
660
    subf7 = c_int(0)
661
    subf8 = c_int(0)
662
    arity = c_int(0)
663
    nullPtr = POINTER(c_int)()
664
    sollya_lib_get_subfunctions(expressionSo, byref(arity), \
665
      byref(subf0), byref(subf1), byref(subf2), byref(subf3), \
666
      byref(subf4), byref(subf5),\
667
      byref(subf6), byref(subf7), byref(subf8), nullPtr, None) 
668
#    byref(cast(subfunctions[0], POINTER(c_int))), \
669
#    byref(cast(subfunctions[0], POINTER(c_int))), \
670
#    byref(cast(subfunctions[2], POINTER(c_int))), \
671
#    byref(cast(subfunctions[3], POINTER(c_int))), \
672
#    byref(cast(subfunctions[4], POINTER(c_int))), \
673
#    byref(cast(subfunctions[5], POINTER(c_int))), \
674
#    byref(cast(subfunctions[6], POINTER(c_int))), \
675
#    byref(cast(subfunctions[7], POINTER(c_int))), \
676
#    byref(cast(subfunctions[8], POINTER(c_int))), nullPtr)
677
    subfunctions = [subf0, subf1, subf2, subf3, subf4, subf5, subf6, subf7, \
678
                    subf8]
679
    subs = []
680
    if arity.value > pobyso_max_arity:
681
        return(0,[])
682
    for i in xrange(arity.value):
683
        subs.append(int(subfunctions[i].value))
684
        #print subs[i]
685
    return(int(arity.value), subs)
686
    
687
def pobyso_get_prec():
688
    """ Legacy function. See pobyso_get_prec_so_sa(). """
689
    return(pobyso_get_prec_so_sa())
690

    
691
def pobyso_get_prec_so():
692
    """
693
    Get the current default precision in Sollya.
694
    The return value is a Sollya object.
695
    Usefull when modifying the precision back and forth by avoiding
696
    extra conversions.
697
    """
698
    return(sollya_lib_get_prec(None))
699
    
700
def pobyso_get_prec_so_sa():
701
    """
702
    Get the current default precision in Sollya.
703
    The return value is Sage/Python int.
704
    """
705
    precSo = sollya_lib_get_prec(None)
706
    precSa = c_int(0)
707
    sollya_lib_get_constant_as_int(byref(precSa), precSo)
708
    sollya_lib_clear_obj(precSo)
709
    return(int(precSa.value))
710
# End pobyso_get_prec_so_sa.
711

    
712
def pobyso_get_prec_of_constant(ctExpSo):
713
    """ Legacy function. See pobyso_get_prec_of_constant_so_sa. """
714
    return(pobyso_get_prec_of_constant_so_sa(ctExpSo))
715

    
716
def pobyso_get_prec_of_constant_so_sa(ctExpSo):
717
    prec = c_int(0)
718
    retc = sollya_lib_get_prec_of_constant(byref(prec), ctExpSo, None)
719
    if retc == 0:
720
        return(None)
721
    return(int(prec.value))
722

    
723
def pobyso_get_prec_of_range_so_sa(rangeSo):
724
    prec = c_int(0)
725
    retc = sollya_lib_get_prec_of_range(byref(prec), rangeSo, None)
726
    if retc == 0:
727
        return(None)
728
    return(int(prec.value))
729

    
730
def pobyso_infnorm_so_so(func, interval, file = None, intervalList = None):
731
    print "Do not use this function. User pobyso_supnorm_so_so instead."
732
    return(None)
733

    
734
def pobyso_interval_to_range_sa_so(intervalSa, precisionSa=None):
735
    if precisionSa is None:
736
        precisionSa = intervalSa.parent().precision()
737
    intervalSo = pobyso_bounds_to_range_sa_so(intervalSa.lower(),\
738
                                              intervalSa.upper(),\
739
                                              precisionSa)
740
    return(intervalSo)
741
# End pobyso_interval_to_range_sa_so
742

    
743
def pobyso_lib_init():
744
    sollya_lib_init(None)
745

    
746
def pobyso_lib_close():
747
    sollya_lib_close(None)
748
    
749
def pobyso_name_free_variable(freeVariableNameSa):
750
    """ Legacy function. See pobyso_name_free_variable_sa_so. """
751
    pobyso_name_free_variable_sa_so(freeVariableNameSa)
752

    
753
def pobyso_name_free_variable_sa_so(freeVariableNameSa):
754
    """
755
    Set the free variable name in Sollya from a Sage string.
756
    """
757
    sollya_lib_name_free_variable(freeVariableNameSa)
758

    
759
def pobyso_parse_string(string):
760
    """ Legacy function. See pobyso_parse_string_sa_so. """
761
    return(pobyso_parse_string_sa_so(string))
762
 
763
def pobyso_parse_string_sa_so(string):
764
    """
765
    Get the Sollya expression computed from a Sage string.
766
    """
767
    return(sollya_lib_parse_string(string))
768

    
769
def pobyso_range(rnLowerBound, rnUpperBound):
770
    """ Legacy function. See pobyso_range_sa_so. """
771
    return(pobyso_range_sa_so(rnLowerBound, rnUpperBound)) 
772

    
773

    
774
def pobyso_range_to_interval_so_sa(rangeSo, realIntervalFieldSa = None):
775
    """
776
    Get a Sage interval from a Sollya range.
777
    If no realIntervalField is given as a parameter, the Sage interval
778
    precision is that of the Sollya range.
779
    Otherwise, the precision is that of the realIntervalField. In this case
780
    rounding may happen.
781
    """
782
    if realIntervalFieldSa is None:
783
        precSa = pobyso_get_prec_of_range_so_sa(rangeSo)
784
        realIntervalFieldSa = RealIntervalField(precSa)
785
    intervalSa = \
786
        pobyso_get_interval_from_range_so_sa(rangeSo, realIntervalFieldSa) 
787
    return(intervalSa)
788

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

    
906
def pobyso_remez_canonical_so_so(funcSo, \
907
                                 degreeSo, \
908
                                 rangeSo, \
909
                                 weightSo = pobyso_constant_1_sa_so(),\
910
                                 qualitySo = None):
911
    """
912
    All arguments are pointers to Sollya objects.
913
    The return value is a pointer to a Sollya function.
914
    """
915
    if not sollya_lib_obj_is_function(funcSo):
916
        return(None)
917
    return(sollya_lib_remez(funcSo, degreeSo, rangeSo, weightSo, qualitySo, None))
918
    
919
def pobyso_set_canonical_off():
920
    sollya_lib_set_canonical(sollya_lib_off())
921

    
922
def pobyso_set_canonical_on():
923
    sollya_lib_set_canonical(sollya_lib_on())
924

    
925
def pobyso_set_prec(p):
926
    """ Legacy function. See pobyso_set_prec_sa_so. """
927
    pobyso_set_prec_sa_so(p)
928

    
929
def pobyso_set_prec_sa_so(p):
930
    a = c_int(p)
931
    precSo = c_void_p(sollya_lib_constant_from_int(a))
932
    sollya_lib_set_prec(precSo, None)
933

    
934
def pobyso_set_prec_so_so(newPrecSo):
935
    sollya_lib_set_prec(newPrecSo, None)
936

    
937
def pobyso_supnorm_so_so(polySo, funcSo, intervalSo, errorTypeSo = None,\
938
                         accuracySo = None):
939
    """
940
    Computes the supnorm of the approximation error between the given 
941
    polynomial and function.
942
    errorTypeSo defaults to "absolute".
943
    accuracySo defaults to 2^(-40).
944
    """
945
    if errorTypeSo is None:
946
        errorTypeSo = sollya_lib_absolute(None)
947
        errorTypeIsNone = True
948
    else:
949
        errorTypeIsNone = False
950
    #
951
    if accuracySo is None:
952
        # Notice the **!
953
        accuracySo = pobyso_constant_sa_so(RR(2**(-40)))
954
        accuracyIsNone = True
955
    else:
956
        accuracyIsNone = False
957
    pobyso_autoprint(accuracySo)
958
    resultSo = \
959
        sollya_lib_supnorm(polySo, funcSo, intervalSo, errorTypeSo, \
960
                              accuracySo)
961
    if errorTypeIsNone:
962
        sollya_lib_clear_obj(errorTypeSo)
963
    if accuracyIsNone:
964
        sollya_lib_clear_obj(accuracySo)
965
    return resultSo
966
# End pobyso_supnorm_so_so
967

    
968
def pobyso_taylor_expansion_with_change_var_so_so(functionSo, degreeSo, \
969
                                                  rangeSo, \
970
                                                  errorTypeSo=None, \
971
                                                  sollyaPrecSo=None):
972
    """
973
    Compute the Taylor expansion with the variable change
974
    x -> (x-intervalCenter) included.
975
    """
976
    # No global change of the working precision.
977
    if not sollyaPrecSo is None:
978
        initialPrecSo = sollya_lib_get_prec(None)
979
        sollya_lib_set_prec(sollyaPrecSo)
980
    #
981
    # Error type stuff: default to absolute.
982
    if errorTypeSo is None:
983
        errorTypeIsNone = True
984
        errorTypeSo = sollya_lib_absolute(None)
985
    else:
986
        errorTypeIsNone = False
987
    intervalCenterSo = sollya_lib_mid(rangeSo)
988
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, \
989
                                         intervalCenterSo, \
990
                                         rangeSo, errorTypeSo, None)
991
    (taylorFormListSo, numElements, isEndElliptic) = \
992
        pobyso_get_list_elements_so_so(taylorFormSo)
993
    polySo = taylorFormListSo[0]
994
    errorRangeSo = taylorFormListSo[2]
995
    maxErrorSo = sollya_lib_sup(errorRangeSo)
996
    changeVarExpSo = sollya_lib_build_function_sub(\
997
                       sollya_lib_build_function_free_variable(),\
998
                       sollya_lib_copy_obj(intervalCenterSo))
999
    polyVarChangedSo = sollya_lib_evaluate(polySo, changeVarExpSo) 
1000
    sollya_lib_clear_obj(changeVarExpSo)
1001
    # If changed, reset the Sollya working precision.
1002
    if not sollyaPrecSo is None:
1003
        sollya_lib_set_prec(initialPrecSo)
1004
        sollya_lib_clear_obj(initialPrecSo)
1005
    if errorTypeIsNone:
1006
        sollya_lib_clear_obj(errorTypeSo)
1007
    sollya_lib_clear_obj(taylorFormSo)
1008
    # Do not clear maxErrorSo.
1009
    return((polyVarChangedSo, intervalCenterSo, maxErrorSo))
1010
# end pobyso_taylor_expansion_with_change_var_so_so
1011

    
1012
def pobyso_taylor_expansion_no_change_var_so_so(functionSo, degreeSo, rangeSo, \
1013
                                                errorTypeSo=None, \
1014
                                                sollyaPrecSo=None):
1015
    """
1016
    Compute the Taylor expansion without the variable change
1017
    x -> x-intervalCenter.
1018
    """
1019
    # No global change of the working precision.
1020
    if not sollyaPrecSo is None:
1021
        initialPrecSo = sollya_lib_get_prec(None)
1022
        sollya_lib_set_prec(sollyaPrecSo)
1023
    # Error type stuff: default to absolute.
1024
    if errorTypeSo is None:
1025
        errorTypeIsNone = True
1026
        errorTypeSo = sollya_lib_absolute(None)
1027
    else:
1028
        errorTypeIsNone = False
1029
    intervalCenterSo = sollya_lib_mid(rangeSo)
1030
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, \
1031
                                         intervalCenterSo, \
1032
                                         rangeSo, errorTypeSo, None)
1033
    # taylorFormListSaSo is a Python list of Sollya objects references that 
1034
    # are copies of the elements of taylorFormSo.
1035
    # pobyso_get_list_elements_so_so clears taylorFormSo.
1036
    (taylorFormListSaSo, numElementsSa, isEndEllipticSa) = \
1037
        pobyso_get_list_elements_so_so(taylorFormSo)
1038
    polySo = sollya_lib_copy_obj(taylorFormListSaSo[0])
1039
    #errorRangeSo = sollya_lib_copy_obj(taylorFormListSaSo[2])
1040
    #polySo = taylorFormListSaSo[0]
1041
    errorRangeSo = taylorFormListSaSo[2]
1042
    # No copy_obj needed here: a new object is created.
1043
    maxErrorSo = sollya_lib_sup(errorRangeSo)
1044
    # If changed, reset the Sollya working precision.
1045
    if not sollyaPrecSo is None:
1046
        sollya_lib_set_prec(initialPrecSo)
1047
        sollya_lib_clear_obj(initialPrecSo)
1048
    if errorTypeIsNone:
1049
        sollya_lib_clear_obj(errorTypeSo)
1050
    for element in taylorFormListSaSo:
1051
        sollya_lib_clear_obj(element)
1052
    return((polySo, intervalCenterSo, maxErrorSo))
1053
# end pobyso_taylor_expansion_no_change_var_so_so
1054

    
1055
def pobyso_taylor(function, degree, point):
1056
    """ Legacy function. See pobysoTaylor_so_so. """
1057
    return(pobyso_taylor_so_so(function, degree, point))
1058

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

    
1148
def pobyso_taylorform_so_so(functionSo, degreeSo, pointSo, intervalSo=None, \
1149
                            errorTypeSo=None):
1150
    createdErrorType = False
1151
    if errorTypeSo is None:
1152
        errorTypeSo = sollya_lib_absolute()
1153
        createdErrorType = True
1154
    else:
1155
        #TODO: deal with the other case.
1156
        pass
1157
    if intervalSo is None:
1158
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
1159
                                         errorTypeSo, None)
1160
    else:
1161
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
1162
                                         intervalSo, errorTypeSo, None)
1163
    if createdErrorType:
1164
        sollya_lib_clear_obj(errorTypeSo)
1165
    return(resultSo)
1166
        
1167

    
1168
def pobyso_univar_polynomial_print_reverse(polySa):
1169
    """ Legacy function. See pobyso_univar_polynomial_print_reverse_sa_sa. """
1170
    return(pobyso_univar_polynomial_print_reverse_sa_sa(polySa))
1171

    
1172
def pobyso_univar_polynomial_print_reverse_sa_sa(polySa):
1173
    """
1174
    Return the string representation of a univariate polynomial with
1175
    monomials ordered in the x^0..x^n order of the monomials.
1176
    Remember: Sage
1177
    """
1178
    polynomialRing = polySa.base_ring()
1179
    # A very expensive solution:
1180
    # -create a fake multivariate polynomial field with only one variable,
1181
    #   specifying a negative lexicographical order;
1182
    mpolynomialRing = PolynomialRing(polynomialRing.base(), \
1183
                                     polynomialRing.variable_name(), \
1184
                                     1, order='neglex')
1185
    # - convert the univariate argument polynomial into a multivariate
1186
    #   version;
1187
    p = mpolynomialRing(polySa)
1188
    # - return the string representation of the converted form.
1189
    # There is no simple str() method defined for p's class.
1190
    return(p.__str__())
1191
#
1192
print pobyso_get_prec()  
1193
pobyso_set_prec(165)
1194
print pobyso_get_prec()  
1195
a=100
1196
print type(a)
1197
id(a)
1198
print "Max arity: ", pobyso_max_arity
1199
print "Function tripleDouble (43) as a string: ", pobyso_function_type_as_string(43)
1200
print "Function None (44) as a string: ", pobyso_function_type_as_string(44)
1201
print "...Pobyso check done"