1 | initial version |
Here is an attempt:
def my_lerch_phi_evalf(self, z, s, a, parent=None, algorithm=None):
if parent is None:
return self(z, s, a)._sympy_().evalf()._sage_()
else:
digits = ceil(log(float(2), float(10)) * parent.prec())
return self(z, s, a)._sympy_().evalf(n=digits)._sage_()
my_lerch_phi = function('my_lerch_phi', nargs=3,
conversions=dict(sympy='lerchphi'),
evalf_func=my_lerch_phi_evalf)
Now we can convert our function to SymPy:
sage: _ = var('z,s,a')
sage: f = my_lerch_phi(z, s, a); f
my_lerch_phi(z, s, a)
sage: f._sympy_()
lerchphi(z, s, a)
sage: unicode_art(f)
Φ(z, s, a)
and evaluate it numerically:
sage: my_lerch_phi(1, 2, 3).n()
0.394934066848226
sage: my_lerch_phi(1, 2, 3).n(100)
0.394934066848226436472415166646
sage: my_lerch_phi(11/10, 2, 3).n()
0.420359955902005 - 0.224963005774297*I
Note that the precision is a bit higher than needed because we rounded up, so some more adjustments are needed to convert to the parent of the correct precision. Moreover, function
has several more optional arguments that may be useful.
For the conversion from SymPy to Sage, one could use this hack which is based on the current implementation of _sympysage_function. (It might be better if the SymPy interface made use of the symbol_table
for the conversion to Sage, like the Mathematica interface does, which allows for customization.)
sage: f._sympy_()._sage_()
...
AttributeError:
sage: sage.functions.all.lerchphi = my_lerch_phi # this is a hack
sage: f._sympy_()._sage_() # now this works
my_lerch_phi(z, s, a)
Now also this gives a correct error message:
sage: my_lerch_phi(z, s, a).n()
...
TypeError: cannot evaluate symbolic expression numerically