Statistiques
| Révision :

root / pobysoPythonSage / src / pobyso.py @ 54

Historique | Voir | Annoter | Télécharger (30,18 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, includes
10
  the void function and the no arguments function that return a pointer to a Sollya
11
  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 Sollya
14
  world to Sage/Python world);
15
- the _sa_so (arguments are Sage/Python objects, returned objects are 
16
  pointers to Sollya objects);
17
- the sa_sa (arguments and returned objects are all Sage/Python objects);
18
- a catch all flavor, without any suffix, (e. g. functions that have no argument 
19
  nor return value).
20
NOTES:
21
Reported errors in Eclipse come from the calls to
22
the Sollya library
23

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

    
80
pobyso_max_arity = 9
81

    
82
def pobyso_autoprint(arg):
83
    sollya_lib_autoprint(arg,None)
84

    
85
def pobyso_autoprint_so_so(arg):
86
    sollya_lib_autoprint(arg,None)
87
    
88
def pobyso_absolute_so_so():
89
    return(sollya_lib_absolute(None))
90

    
91
def pobyso_build_function_sub_so_so(exp1So, exp2So):
92
    return(sollya_lib_build_function_sub(exp1So, exp2So))
93

    
94
def pobyso_cmp(rnArg, soCte):
95
    """
96
    Compare the MPFR value a RealNumber with that of a Sollya constant.
97
    
98
    Get the value of the Sollya constant into a RealNumber and compare
99
    using MPFR. Could be optimized by working directly with a mpfr_t
100
    for the intermediate number. 
101
    """
102
    precisionOfCte = c_int(0)
103
    # From the Sollya constant, create a local Sage RealNumber.
104
    sollya_lib_get_prec_of_constant(precisionOfCte, soCte) 
105
    #print "Precision of constant: ", precisionOfCte
106
    RRRR = RealField(precisionOfCte.value)
107
    rnLocal = RRRR(0)
108
    sollya_lib_get_constant(get_rn_value(rnLocal), soCte)
109
    #print "rnDummy: ", rnDummy
110
    # Compare the local Sage RealNumber with rnArg.
111
    return(cmp_rn_value(rnArg, rnLocal))
112

    
113
def pobyso_compute_pos_function_abs_val_bounds_sa_sa(funcSa, lowerBoundSa, \
114
                                                     upperBoundSa):
115
    """
116
    TODO: set the variable name in Sollya.
117
    """
118
    funcSo = pobyso_parse_string(funcSa._assume_str())
119
    rangeSo = pobyso_range_sa_so(lowerBoundSa, upperBoundSa)
120
    infnormSo = pobyso_infnorm_so_so(funcSo,rangeSo)
121
    fMaxSa = pobyso_get_interval_from_range_so_sa(infnormSo)
122
    # Get the top bound and compute the binade top limit.
123
    fMaxUpperBoundSa = fMaxSa.upper()
124
    binadeTopLimitSa = 2**ceil(fMaxUpperBoundSa.log2())
125
    # Put up together the function to use to compute the lower bound.
126
    funcAuxSo = pobyso_parse_string(str(binadeTopLimitSa) +  \
127
                                    '-(' + f._assume_str() + ')')
128
    pobyso_autoprint(funcAuxSo)
129
    # Clear the Sollay range before a new call to infnorm and issue the call.
130
    sollya_lib_clear_obj(infnormSo)
131
    infnormSo = pobyso_infnorm_so_so(funcAuxSo,rangeSo)
132
    fMinSa = pobyso_get_interval_from_range_so_sa(infnormSo)
133
    sollya_lib_clear_obj(infnormSo)
134
    fMinLowerBoundSa = topBinadeLimit - fMinSa.lower()
135
    # Compute the maximum of the precisions of the different bounds.
136
    maxPrecSa = max([fMinLowerBoundSa.parent().precision(), \
137
                     fMaxUpperBoundSa.parent().precision()])
138
    # Create a RealIntervalField and create an interval with the "good" bounds.
139
    RRRI = RealIntervalField(maxPrecSa)
140
    imageIntervalSa = RRRI(fMinLowerBoundSa, fMaxUpperBoundSa)
141
    # Free the uneeded Sollya objects
142
    sollya_lib_clear_obj(funcSo)
143
    sollya_lib_clear_obj(funcAuxSo)
144
    sollya_lib_clear_obj(rangeSo)
145
    return(imageIntervalSa)
146
    # End pobyso_compute_function_abs_val_bounds_sa_sa
147

    
148
def pobyso_constant(rnArg):
149
    """ Legacy function. See pobyso_constant_sa_so. """
150
    return(pobyso_constant_sa_so(rnArg))
151
    
152
def pobyso_constant_sa_so(rnArg):
153
    """
154
    Create a Sollya constant from a RealNumber.
155
    """
156
    return(sollya_lib_constant(get_rn_value(rnArg)))
157
    
158
def pobyso_constant_1():
159
    """ Legacy function. See pobyso_constant_so_so. """
160
    return(pobyso_constant_1_sa_so())
161

    
162
def pobyso_constant_1_sa_so():
163
    return(pobyso_constant_from_int_sa_so(1))
164

    
165
def pobyso_constant_from_int(anInt):
166
    """ Legacy function. See pobyso_constant_from_int_sa_so. """
167
    return(pobyso_constant_from_int_sa_so(anInt))
168

    
169
def pobyso_constant_from_int_sa_so(anInt):
170
    return(sollya_lib_constant_from_int(int(anInt)))
171

    
172
def pobyso_function_type_as_string(funcType):
173
    """ Legacy function. See pobyso_function_type_as_string_so_sa. """
174
    return(pobyso_function_type_as_string_so_sa(funcType))
175

    
176
def pobyso_function_type_as_string_so_sa(funcType):
177
    """
178
    Numeric Sollya function codes -> Sage mathematical function names.
179
    Notice that pow -> ^ (a la Sage, not a la Python).
180
    """
181
    if funcType == SOLLYA_BASE_FUNC_ABS:
182
        return "abs"
183
    elif funcType == SOLLYA_BASE_FUNC_ACOS:
184
        return "arccos"
185
    elif funcType == SOLLYA_BASE_FUNC_ACOSH:
186
        return "arccosh"
187
    elif funcType == SOLLYA_BASE_FUNC_ADD:
188
        return "+"
189
    elif funcType == SOLLYA_BASE_FUNC_ASIN:
190
        return "arcsin"
191
    elif funcType == SOLLYA_BASE_FUNC_ASINH:
192
        return "arcsinh"
193
    elif funcType == SOLLYA_BASE_FUNC_ATAN:
194
        return "arctan"
195
    elif funcType == SOLLYA_BASE_FUNC_ATANH:
196
        return "arctanh"
197
    elif funcType == SOLLYA_BASE_FUNC_CEIL:
198
        return "ceil"
199
    elif funcType == SOLLYA_BASE_FUNC_CONSTANT:
200
        return "cte"
201
    elif funcType == SOLLYA_BASE_FUNC_COS:
202
        return "cos"
203
    elif funcType == SOLLYA_BASE_FUNC_COSH:
204
        return "cosh"
205
    elif funcType == SOLLYA_BASE_FUNC_DIV:
206
        return "/"
207
    elif funcType == SOLLYA_BASE_FUNC_DOUBLE:
208
        return "double"
209
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEDOUBLE:
210
        return "doubleDouble"
211
    elif funcType == SOLLYA_BASE_FUNC_DOUBLEEXTENDED:
212
        return "doubleDxtended"
213
    elif funcType == SOLLYA_BASE_FUNC_ERF:
214
        return "erf"
215
    elif funcType == SOLLYA_BASE_FUNC_ERFC:
216
        return "erfc"
217
    elif funcType == SOLLYA_BASE_FUNC_EXP:
218
        return "exp"
219
    elif funcType == SOLLYA_BASE_FUNC_EXP_M1:
220
        return "expm1"
221
    elif funcType == SOLLYA_BASE_FUNC_FLOOR:
222
        return "floor"
223
    elif funcType == SOLLYA_BASE_FUNC_FREE_VARIABLE:
224
        return "freeVariable"
225
    elif funcType == SOLLYA_BASE_FUNC_HALFPRECISION:
226
        return "halfPrecision"
227
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYCONSTANT:
228
        return "libraryConstant"
229
    elif funcType == SOLLYA_BASE_FUNC_LIBRARYFUNCTION:
230
        return "libraryFunction"
231
    elif funcType == SOLLYA_BASE_FUNC_LOG:
232
        return "log"
233
    elif funcType == SOLLYA_BASE_FUNC_LOG_10:
234
        return "log10"
235
    elif funcType == SOLLYA_BASE_FUNC_LOG_1P:
236
        return "log1p"
237
    elif funcType == SOLLYA_BASE_FUNC_LOG_2:
238
        return "log2"
239
    elif funcType == SOLLYA_BASE_FUNC_MUL:
240
        return "*"
241
    elif funcType == SOLLYA_BASE_FUNC_NEARESTINT:
242
        return "round"
243
    elif funcType == SOLLYA_BASE_FUNC_NEG:
244
        return "__neg__"
245
    elif funcType == SOLLYA_BASE_FUNC_PI:
246
        return "pi"
247
    elif funcType == SOLLYA_BASE_FUNC_POW:
248
        return "^"
249
    elif funcType == SOLLYA_BASE_FUNC_PROCEDUREFUNCTION:
250
        return "procedureFunction"
251
    elif funcType == SOLLYA_BASE_FUNC_QUAD:
252
        return "quad"
253
    elif funcType == SOLLYA_BASE_FUNC_SIN:
254
        return "sin"
255
    elif funcType == SOLLYA_BASE_FUNC_SINGLE:
256
        return "single"
257
    elif funcType == SOLLYA_BASE_FUNC_SINH:
258
        return "sinh"
259
    elif funcType == SOLLYA_BASE_FUNC_SQRT:
260
        return "sqrt"
261
    elif funcType == SOLLYA_BASE_FUNC_SUB:
262
        return "-"
263
    elif funcType == SOLLYA_BASE_FUNC_TAN:
264
        return "tan"
265
    elif funcType == SOLLYA_BASE_FUNC_TANH:
266
        return "tanh"
267
    elif funcType == SOLLYA_BASE_FUNC_TRIPLEDOUBLE:
268
        return "tripleDouble"
269
    else:
270
        return None
271

    
272
def pobyso_get_constant(rnArg, soConst):
273
    """ Legacy function. See pobyso_get_constant_so_sa. """
274
    return(pobyso_get_constant_so_sa(rnArg, soConst))
275

    
276
def pobyso_get_constant_so_sa(rnArg, soConst):
277
    """
278
    Set the value of rnArg to the value of soConst in MPFR_RNDN mode.
279
    rnArg must already exist and belong to some RealField.
280
    We assume that soConst points to a Sollya constant.
281
    """
282
    return(sollya_lib_get_constant(get_rn_value(rnArg), soConst))
283
    
284
def pobyso_get_constant_as_rn(ctExp):
285
    """ Legacy function. See pobyso_get_constant_as_rn_so_sa. """ 
286
    return(pobyso_get_constant_as_rn_so_sa(ctExp))
287
    
288
def pobyso_get_constant_as_rn_so_sa(constExp):
289
    precision  = pobyso_get_prec_of_constant(constExp) 
290
    RRRR = RealField(precision)
291
    rn = RRRR(0)
292
    sollya_lib_get_constant(get_rn_value(rn), constExp)
293
    return(rn)
294

    
295
def pobyso_get_constant_as_rn_with_rf(ctExp, realField):
296
    """ Legacy function. See pobyso_get_constant_as_rn_with_rf_so_sa."""
297
    return(pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField))
298
    
299
def pobyso_get_constant_as_rn_with_rf_so_sa(ctExp, realField):
300
    rn = realField(0)
301
    sollya_lib_get_constant(get_rn_value(rn), ctExp)
302
    return(rn)
303

    
304
def pobyso_get_free_variable_name():
305
    """ Legacy function. See pobyso_get_free_variable_name_so_sa."""
306
    return(pobyso_get_free_variable_name_so_sa())
307

    
308
def pobyso_get_free_variable_name_so_sa():
309
    return(sollya_lib_get_free_variable_name())
310
    
311
def pobyso_get_function_arity(expressionSo):
312
    """ Legacy function. See pobyso_get_function_arity_so_sa."""
313
    return(pobyso_get_function_arity_so_sa(expressionSo))
314

    
315
def pobyso_get_function_arity_so_sa(expressionSo):
316
    arity = c_int(0)
317
    sollya_lib_get_function_arity(byref(arity),expressionSo)
318
    return(int(arity.value))
319

    
320
def pobyso_get_head_function(expressionSo):
321
    """ Legacy function. See pobyso_get_head_function_so_sa. """
322
    return(pobyso_get_head_function_so_sa(expressionSo)) 
323

    
324
def pobyso_get_head_function_so_sa(expressionSo):
325
    functionType = c_int(0)
326
    sollya_lib_get_head_function(byref(functionType), expressionSo, None)
327
    return(int(functionType.value))
328

    
329
def pobyso_get_interval_from_range_so_sa(soRange):
330
    """
331
    Return the Sage interval corresponding to the Sollya range argument.
332
    The interval bounds are not rounded: they are elements of RealIntervalField
333
    of the "right" precision.
334
    """
335
    prec = c_int(0)
336
    retval = sollya_lib_get_prec_of_range(byref(prec), soRange, None)
337
    if retval == 0:
338
        return(None)
339
    RRRI = RealIntervalField(prec.value)
340
    intervalSa = RRRI(0,0)
341
    retval = \
342
        sollya_lib_get_interval_from_range(get_interval_value(intervalSa),\
343
                                           soRange)
344
    if retval == 0:
345
        return(None)
346
    return(intervalSa)
347
    
348
def pobyso_get_list_elements(soObj):
349
    """ Legacy function. See pobyso_get_list_elements_so_so. """
350
    return(pobyso_get_list_elements_so_so(soObj))
351
 
352
def pobyso_get_list_elements_so_so(soObj):
353
    """
354
    Get the list elements as a Sage/Python array of Sollya objects.
355
    The other data returned are also Sage/Python objects.
356
    """
357
    listAddress = POINTER(c_longlong)()
358
    numElements = c_int(0)
359
    isEndElliptic = c_int(0)
360
    listAsList = []
361
    result = sollya_lib_get_list_elements(byref(listAddress),\
362
                                          byref(numElements),\
363
                                          byref(isEndElliptic),\
364
                                          soObj)
365
    if result == 0 :
366
        return None
367
    for i in xrange(0, numElements.value, 1):
368
        listAsList.append(listAddress[i])
369
    return(listAsList, numElements.value, isEndElliptic.value)
370

    
371
def pobyso_get_max_prec_of_exp(soExp):
372
    """ Legacy function. See pobyso_get_max_prec_of_exp_so_sa. """
373
    return(pobyso_get_max_prec_of_exp_so_sa(soExp))
374

    
375
def pobyso_get_max_prec_of_exp_so_sa(soExp):
376
    """
377
    Get the maximum precision used for the numbers in a Sollya expression.
378
    
379
    Arguments:
380
    soExp -- a Sollya expression pointer
381
    Return value:
382
    A Python integer
383
    TODO: 
384
    - error management;
385
    - correctly deal with numerical type such as DOUBLEEXTENDED.
386
    """
387
    maxPrecision = 0
388
    minConstPrec = 0
389
    currentConstPrec = 0
390
    operator = pobyso_get_head_function_so_sa(soExp)
391
    if (operator != SOLLYA_BASE_FUNC_CONSTANT) and \
392
    (operator != SOLLYA_BASE_FUNC_FREE_VARIABLE):
393
        (arity, subexpressions) = pobyso_get_subfunctions_so_sa(soExp)
394
        for i in xrange(arity):
395
            maxPrecisionCandidate = \
396
                pobyso_get_max_prec_of_exp_so_sa(subexpressions[i])
397
            if maxPrecisionCandidate > maxPrecision:
398
                maxPrecision = maxPrecisionCandidate
399
        return(maxPrecision)
400
    elif operator == SOLLYA_BASE_FUNC_CONSTANT:
401
        minConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
402
        #currentConstPrec = pobyso_get_min_prec_of_constant_so_sa(soExp)
403
        #print minConstPrec, " - ", currentConstPrec 
404
        return(pobyso_get_min_prec_of_constant_so_sa(soExp))
405
    
406
    elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
407
        return(0)
408
    else:
409
        print "pobyso_get_max_prec_of_exp_so_sa: unexepected operator."
410
        return(0)
411

    
412
def pobyso_get_min_prec_of_constant_so_sa(soConstExp):
413
    """
414
    Get the minimum precision necessary to represent the value of a Sollya
415
    constant.
416
    MPFR_MIN_PREC and powers of 2 are taken into account.
417
    We assume that soCteExp is a point
418
    """
419
    constExpAsRn = pobyso_get_constant_as_rn_so_sa(soConstExp)
420
    return(min_mpfr_size(get_rn_value(constExpAsRn)))
421

    
422
def pobyso_get_sage_exp_from_sollya_exp(sollyaExp, realField = RR):
423
    """ Legacy function. See pobyso_get_sage_exp_from_sollya_exp_so_sa. """
424
    return(pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExp, realField = RR))
425

    
426
def pobyso_get_sage_exp_from_sollya_exp_so_sa(sollyaExp, realField = RR):
427
    """
428
    Get a Sage expression from a Sollya expression. 
429
    Currently only tested with polynomials with floating-point coefficients.
430
    Notice that, in the returned polynomial, the exponents are RealNumbers.
431
    """
432
    #pobyso_autoprint(sollyaExp)
433
    operator = pobyso_get_head_function(sollyaExp)
434
    # Constants and the free variable are special cases.
435
    # All other operator are dealt with in the same way.
436
    if (operator != SOLLYA_BASE_FUNC_CONSTANT) and \
437
       (operator != SOLLYA_BASE_FUNC_FREE_VARIABLE):
438
        (arity, subexpressions) = pobyso_get_subfunctions_so_sa(sollyaExp)
439
        if arity == 1:
440
            sageExp = eval(pobyso_function_type_as_string_so_sa(operator) + \
441
            "(" + pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressions[0], \
442
            realField) + ")")
443
        elif arity == 2:
444
            if operator == SOLLYA_BASE_FUNC_POW:
445
                operatorAsString = "**"
446
            else:
447
                operatorAsString = \
448
                    pobyso_function_type_as_string_so_sa(operator)
449
            sageExp = \
450
              eval("pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressions[0], realField)"\
451
              + " " + operatorAsString + " " + \
452
                   "pobyso_get_sage_exp_from_sollya_exp_so_sa(subexpressions[1], realField)")
453
        # We do not know yet how to deal with arity > 3 (is there any in Sollya anyway?).
454
        else:
455
            sageExp = eval('None')
456
        return(sageExp)
457
    elif operator == SOLLYA_BASE_FUNC_CONSTANT:
458
        #print "This is a constant"
459
        return pobyso_get_constant_as_rn_with_rf_so_sa(sollyaExp, realField)
460
    elif operator == SOLLYA_BASE_FUNC_FREE_VARIABLE:
461
        #print "This is free variable"
462
        return(eval(sollya_lib_get_free_variable_name()))
463
    else:
464
        print "Unexpected"
465
        return eval('None')
466
# End pobyso_get_sage_poly_from_sollya_poly
467
    
468
def pobyso_get_subfunctions(expressionSo):
469
    """ Legacy function. See pobyso_get_subfunctions_so_sa. """
470
    return(pobyso_get_subfunctions_so_sa(expressionSo)) 
471

    
472
def pobyso_get_subfunctions_so_sa(expressionSo):
473
    """
474
    Get the subfunctions of an expression.
475
    Return the number of subfunctions and the list of subfunctions addresses.
476
    Could not figure out another way than that ugly list of declarations
477
    to recover the addresses of the subfunctions.
478
    Arity is limited to 9.
479
    """
480
    subf0 = c_int(0)
481
    subf1 = c_int(0)
482
    subf2 = c_int(0)
483
    subf3 = c_int(0)
484
    subf4 = c_int(0)
485
    subf5 = c_int(0)
486
    subf6 = c_int(0)
487
    subf7 = c_int(0)
488
    subf8 = c_int(0)
489
    arity = c_int(0)
490
    nullPtr = POINTER(c_int)()
491
    sollya_lib_get_subfunctions(expressionSo, byref(arity), \
492
    byref(subf0), byref(subf1), byref(subf2), byref(subf3), byref(subf4), byref(subf5),\
493
     byref(subf6), byref(subf7), byref(subf8), nullPtr, None) 
494
#    byref(cast(subfunctions[0], POINTER(c_int))), byref(cast(subfunctions[0], POINTER(c_int))), \
495
#    byref(cast(subfunctions[2], POINTER(c_int))), byref(cast(subfunctions[3], POINTER(c_int))), \
496
#    byref(cast(subfunctions[4], POINTER(c_int))), byref(cast(subfunctions[5], POINTER(c_int))), \
497
#    byref(cast(subfunctions[6], POINTER(c_int))), byref(cast(subfunctions[7], POINTER(c_int))), \
498
#    byref(cast(subfunctions[8], POINTER(c_int))), nullPtr)
499
    subfunctions = [subf0, subf1, subf2, subf3, subf4, subf5, subf6, subf7, subf8]
500
    subs = []
501
    if arity.value > pobyso_max_arity:
502
        return(0,[])
503
    for i in xrange(arity.value):
504
        subs.append(int(subfunctions[i].value))
505
        #print subs[i]
506
    return(int(arity.value), subs)
507
    
508
def pobyso_get_prec():
509
    """ Legacy function. See pobyso_get_prec_so_sa(). """
510
    return(pobyso_get_prec_so_sa())
511

    
512
def pobyso_get_prec_so_sa():
513
    """
514
    Get the current default precision in Sollya.
515
    The return value is Sage/Python int.
516
    """
517
    retc = sollya_lib_get_prec(None)
518
    a = c_int(0)
519
    sollya_lib_get_constant_as_int(byref(a), retc)
520
    return(int(a.value))
521

    
522
def pobyso_get_prec_of_constant(ctExpSo):
523
    """ Legacy function. See pobyso_get_prec_of_constant_so_sa. """
524
    return(pobyso_get_prec_of_constant_so_sa(ctExpSo))
525

    
526
def pobyso_get_prec_of_range_so_sa(rangeSo):
527
    prec = c_int(0)
528
    retc = sollya_lib_get_prec_of_range(byref(prec), rangeSo, None)
529
    return(int(prec.value))
530

    
531
def pobyso_infnorm_so_so(func, interval, file = None, intervalList = None):
532
    print "Do not use this function. User pobyso_supnorm_so_so instead."
533
    return(None)
534

    
535
def pobyso_lib_init():
536
    sollya_lib_init(None)
537
    
538
def pobyso_name_free_variable(freeVariableName):
539
    """ Legacy function. See pobyso_name_free_variable_sa_so. """
540
    pobyso_name_free_variable_sa_so(freeVariableName)
541

    
542
def pobyso_name_free_variable_sa_so(freeVariableName):
543
    sollya_lib_name_free_variable(freeVariableName)
544

    
545
def pobyso_parse_string(string):
546
    """ Legacy function. See pobyso_parse_string_sa_so. """
547
    return(pobyso_parse_string_sa_so(string))
548
 
549
def pobyso_parse_string_sa_so(string):
550
    return(sollya_lib_parse_string(string))
551

    
552
def pobyso_range(rnLowerBound, rnUpperBound):
553
    """ Legacy function. See pobyso_range_sa_so. """
554
    return(pobyso_range_sa_so(rnLowerBound, rnUpperBound)) 
555

    
556
def pobyso_range_sa_so(rnLowerBound, rnUpperBound):
557
    lowerBoundSo = sollya_lib_constant(get_rn_value(rnLowerBound))
558
    upperBoundSo = sollya_lib_constant(get_rn_value(rnUpperBound))
559
    rangeSo = sollya_lib_range(lowerBoundSo, upperBoundSo)
560
    return(rangeSo)
561

    
562
def pobyso_remez_canonical_sa_sa(func, \
563
                                 degree, \
564
                                 lowerBound, \
565
                                 upperBound, \
566
                                 weight = None, \
567
                                 quality = None):
568
    """
569
    All arguments are Sage/Python.
570
    The functions (func and weight) must be passed as expressions or strings.
571
    Otherwise the function fails. 
572
    The return value is a pointer is a Sage polynomial.
573
    """
574
    var('zorglub')    # Dummy variable name for type check only.
575
    polySo = pobyso_remez_canonical_sa_so(func, \
576
                                 degree, \
577
                                 lowerBound, \
578
                                 upperBound, \
579
                                 weight = None, \
580
                                 quality = None)
581
    if parent(func) == parent("string"):
582
        functionSa = eval(func)
583
    # Expression test.
584
    elif type(func) == type(zorglub):
585
        functionSa = func
586
    maxPrecision = 0
587
    if polySo is None:
588
        return(None)
589
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
590
    RRRR = RealField(maxPrecision)
591
    polynomialRing = RRRR[functionSa.variables()[0]]
592
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, RRRR)
593
    polySa = polynomial(expSa, polynomialRing)
594
    return(polySa)
595
    
596
def pobyso_remez_canonical(func, \
597
                           degree, \
598
                           lowerBound, \
599
                           upperBound, \
600
                           weight = "1", \
601
                           quality = None):
602
    """ Legacy function. See pobyso_remez_canonical_sa_so. """
603
    return(pobyso_remez_canonical_sa_so(func, \
604
                                        degree, \
605
                                        lowerBound, \
606
                                        upperBound, \
607
                                        weight, \
608
                                        quality))
609
def pobyso_remez_canonical_sa_so(func, \
610
                                 degree, \
611
                                 lowerBound, \
612
                                 upperBound, \
613
                                 weight = None, \
614
                                 quality = None):
615
    """
616
    All arguments are Sage/Python.
617
    The functions (func and weight) must be passed as expressions or strings.
618
    Otherwise the function fails. 
619
    The return value is a pointer to a Sollya function.
620
    """
621
    var('zorglub')    # Dummy variable name for type check only.
622
    currentVariableName = None
623
    # The func argument can be of different types (string, 
624
    # symbolic expression...)
625
    if parent(func) == parent("string"):
626
        functionSo = sollya_lib_parse_string(func)
627
    # Expression test.
628
    elif type(func) == type(zorglub):
629
        # Until we are able to translate Sage expressions into Sollya 
630
        # expressions : parse the string version.
631
        currentVariableName = func.variables()[0]
632
        sollya_lib_name_free_variable(str(currentVariableName))
633
        functionSo = sollya_lib_parse_string(func._assume_str())
634
    else:
635
        return(None)
636
    if weight is None:
637
        weightSo = pobyso_constant_1_sa_so()
638
    elif parent(weight) == parent("string"):
639
        weightSo = sollya_lib_parse_string(func)
640
    elif type(weight) == type(zorglub): 
641
        functionSo = sollya_lib_parse_string_sa_so(weight._assume_str())
642
    else:
643
        return(None)
644
    degreeSo = pobyso_constant_from_int(degree)
645
    rangeSo = pobyso_range_sa_so(lowerBound, upperBound)
646
    if not quality is None:
647
        qualitySo= pobyso_constant_sa_so(quality)
648
    else:
649
        qualitySo = None
650
    return(sollya_lib_remez(functionSo, \
651
                            degreeSo, \
652
                            rangeSo, \
653
                            weightSo, \
654
                            qualitySo, \
655
                            None))
656
    
657
def pobyso_remez_canonical_so_so(funcSo, \
658
                                 degreeSo, \
659
                                 rangeSo, \
660
                                 weightSo = pobyso_constant_1_sa_so(),\
661
                                 qualitySo = None):
662
    """
663
    All arguments are pointers to Sollya objects.
664
    The return value is a pointer to a Sollya function.
665
    """
666
    if not sollya_lib_obj_is_function(funcSo):
667
        return(None)
668
    return(sollya_lib_remez(funcSo, degreeSo, rangeSo, weightSo, qualitySo, None))
669
    
670
def pobyso_set_canonical_off():
671
    sollya_lib_set_canonical(sollya_lib_off())
672

    
673
def pobyso_set_canonical_on():
674
    sollya_lib_set_canonical(sollya_lib_on())
675

    
676
def pobyso_set_prec(p):
677
    """ Legacy function. See pobyso_set_prec_sa_so. """
678
    return( pobyso_set_prec_sa_so(p))
679

    
680
def pobyso_set_prec_sa_so(p):
681
    a = c_int(p)
682
    precSo = c_void_p(sollya_lib_constant_from_int(a))
683
    sollya_lib_set_prec(precSo)
684

    
685
def pobyso_supnorm_so_so(polySo, funcSo, intervalSo, errorTypeSo, accuracySo):
686
    return(sollya_lib_supnorm(polySo, funcSo, intervalSo, errorTypeSo, \
687
                              accuracySo))
688

    
689
def pobyso_taylor(function, degree, point):
690
    """ Legacy function. See pobysoTaylor_so_so. """
691
    return(pobyso_taylor_so_so(function, degree, point))
692

    
693
def pobyso_taylor_so_so(function, degree, point):
694
    return(sollya_lib_taylor(function, degree, point))
695
    
696
def pobyso_taylorform(function, degree, point = None, interval = None, errorType=None):
697
    """ Legacy function. See ;"""
698
    
699
def pobyso_taylorform_sa_sa(functionSa, \
700
                            degree, \
701
                            point, \
702
                            precision, \
703
                            interval=None, \
704
                            errorType=None):
705
    """
706
    Compute the Taylor form of 'degree' for 'functionSa' at 'point' 
707
    for 'interval' with 'errorType'. 
708
    point: must be a Real or a Real interval.
709
    return the Taylor form as an array
710
    TODO: take care of the interval and of point when it is an interval;
711
          when errorType is not None;
712
          take care of the other elements of the Taylor form (coefficients errors and
713
          delta.
714
    """
715
    # Absolute as the default error.
716
    if errorType is None:
717
        errorTypeSo = sollya_lib_absolute()
718
    else:
719
        #TODO: deal with the other case.
720
        pass
721
    varSa = functionSa.variables()[0]
722
    pointBaseRingString = str(point.base_ring())
723
    if not re.search('Real', pointBaseRingString):
724
        return None
725
    # Call Sollya but first "sollyafy" the arguments.
726
    pobyso_name_free_variable_sa_so(str(varSa))
727
    #pobyso_set_prec_sa_so(300)
728
    # Sollyafy the function.
729
    functionSo = pobyso_parse_string_sa_so(functionSa._assume_str())
730
    if sollya_lib_obj_is_error(functionSo):
731
        print "pobyso_tailorform: function string can't be parsed!"
732
        return None
733
    # Sollyafy the degree
734
    degreeSo = sollya_lib_constant_from_int(int(degree))
735
    # Sollyafy the point
736
    if not re.search('Interval', pointBaseRingString):
737
        pointSo  = pobyso_constant_sa_so(point)
738
    else:
739
        # TODO: deal with the interval case.
740
        pass
741
    # Call Sollya
742
    taylorFormSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, errorTypeSo,\
743
                                         None)
744
    (tfsAsList, numElements, isEndElliptic) = \
745
            pobyso_get_list_elements_so_so(taylorFormSo)
746
    polySo = tfsAsList[0]
747
    maxPrecision = pobyso_get_max_prec_of_exp_so_sa(polySo)
748
    polyRealField = RealField(maxPrecision)
749
    expSa = pobyso_get_sage_exp_from_sollya_exp_so_sa(polySo, polyRealField)
750
    sollya_lib_close()
751
    polynomialRing = polyRealField[str(varSa)]
752
    polySa = polynomial(expSa, polynomialRing)
753
    taylorFormSa = [polySa]
754
    return(taylorFormSa)
755
# End pobyso_taylor_form_sa_sa
756

    
757
def pobyso_taylorform_so_so(functionSo, degreeSo, pointSo, intervalSo=None, \
758
                            errorTypeSo=None):
759
    createdErrorType = False
760
    if errorTypeSo is None:
761
        errorTypeSo = sollya_lib_absolute()
762
        createdErrorType = True
763
    else:
764
        #TODO: deal with the other case.
765
        pass
766
    if intervalSo is None:
767
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
768
                                         errorTypeSo, None)
769
    else:
770
        resultSo = sollya_lib_taylorform(functionSo, degreeSo, pointSo, \
771
                                         intervalSo, errorTypeSo, None)
772
    if createdErrorType:
773
        sollya_lib_clear_obj(errorTypeSo)
774
    return(resultSo)
775
        
776

    
777
def pobyso_univar_polynomial_print_reverse(polySa):
778
    """ Legacy function. See pobyso_univar_polynomial_print_reverse_sa_sa. """
779
    return(pobyso_univar_polynomial_print_reverse_sa_sa(polySa))
780

    
781
def pobyso_univar_polynomial_print_reverse_sa_sa(polySa):
782
    """
783
    Return the string representation of a univariate polynomial with
784
    monomials ordered in the x^0..x^n order of the monomials.
785
    Remember: Sage
786
    """
787
    polynomialRing = polySa.base_ring()
788
    # A very expensive solution:
789
    # -create a fake multivariate polynomial field with only one variable,
790
    #   specifying a negative lexicographical order;
791
    mpolynomialRing = PolynomialRing(polynomialRing.base(), \
792
                                     polynomialRing.variable_name(), \
793
                                     1, order='neglex')
794
    # - convert the univariate argument polynomial into a multivariate
795
    #   version;
796
    p = mpolynomialRing(polySa)
797
    # - return the string representation of the converted form.
798
    # There is no simple str() method defined for p's class.
799
    return(p.__str__())
800
#
801
print "Superficial test of pobyso:"    
802
print pobyso_get_prec()  
803
pobyso_set_prec(165)
804
print pobyso_get_prec()  
805
a=100
806
print type(a)
807
id(a)
808
print "Max arity: ", pobyso_max_arity
809
print "Function tripleDouble (43) as a string: ", pobyso_function_type_as_string(43)
810
print "Function None (44) as a string: ", pobyso_function_type_as_string(44)