from sage.structure.sage_object import SageObject
from sage.interfaces.maxima import MaximaFunctionElement
class MaximaFunctionElementWrapper(MaximaFunctionElement):
def __call__(self, *args, **kwds):
"""
Returns a Sage expression instead of a Maxima pexpect interface element.
EXAMPLES::
sage: t = sin(x)^2 + cos(x)^2; t
sin(x)^2 + cos(x)^2
sage: res = t.maxima_methods().trigsimp(); res
1
sage: type(res)
<type 'sage.symbolic.expression.Expression'>
"""
return super(MaximaFunctionElementWrapper, self).__call__(*args,
**kwds).sage()
class MaximaWrapper(SageObject):
def __init__(self, exp):
"""
Wrapper around Sage expressions to give access to Maxima methods.
We convert the given expression to Maxima and convert the return value
back to a Sage expression. Tab completion and help strings of Maxima
methods also work as expected.
EXAMPLES::
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t
log(sqrt(2) - 1) + log(sqrt(2) + 1)
sage: u = t.maxima_methods(); u
MaximaWrapper(log(sqrt(2) - 1) + log(sqrt(2) + 1))
sage: type(u)
<class 'sage.symbolic.maxima_wrapper.MaximaWrapper'>
sage: u.logcontract()
log((sqrt(2) - 1)*(sqrt(2) + 1))
sage: u.logcontract().parent()
Symbolic Ring
TESTS:
Test tab completions::
sage: import sagenb.misc.support as s
sage: u = t.maxima_methods()
sage: s.completions('u.elliptic_',globals(),system='python')
['u.elliptic_e', 'u.elliptic_ec', 'u.elliptic_eu', 'u.elliptic_f', 'u.elliptic_kc', 'u.elliptic_pi']
"""
self._exp = exp
self._maxima_exp = None
def __getattr__(self, s):
"""
Direct attempts to get attributes of this wrapper to the corresponding
Maxima expression. This allows tab completion to work as expected.
We wrap the function calls in order to convert results back to Sage.
EXAMPLES::
sage: t = sin(x)^2 + cos(x)^2; t
sin(x)^2 + cos(x)^2
sage: u = t.maxima_methods()
sage: import sagenb.misc.support as s
sage: s.completions('u.airy_',globals(),system='python')
['u.airy_ai', 'u.airy_bi', 'u.airy_dai', 'u.airy_dbi']
sage: type(u.airy_ai)
<class 'sage.symbolic.maxima_wrapper.MaximaFunctionElementWrapper'>
sage: u.airy_ai()
airy_ai(sin(x)^2 + cos(x)^2)
"""
if self._maxima_exp is None:
self._maxima_exp = self._exp._maxima_()
if s == 'trait_names' or s[:1] == '_':
return getattr(self._maxima_exp, s)
else:
return MaximaFunctionElementWrapper(self._maxima_exp, s)
def sage(self):
"""
Return the Sage expression this wrapper corresponds to.
EXAMPLES::
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t
log(sqrt(2) - 1) + log(sqrt(2) + 1)
sage: u = t.maxima_methods().sage()
sage: u is t
True
"""
return self._exp
def _symbolic_(self, parent):
"""
EXAMPLES::
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t
log(sqrt(2) - 1) + log(sqrt(2) + 1)
sage: u = t.maxima_methods()
sage: SR(u) is t # indirect doctest
True
"""
return parent(self._exp)
def __reduce__(self):
"""
EXAMPLES::
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t
log(sqrt(2) - 1) + log(sqrt(2) + 1)
sage: u = t.maxima_methods(); u
MaximaWrapper(log(sqrt(2) - 1) + log(sqrt(2) + 1))
sage: loads(dumps(u))
MaximaWrapper(log(sqrt(2) - 1) + log(sqrt(2) + 1))
"""
return (MaximaWrapper, (self._exp,))
def _repr_(self):
"""
EXAMPLES::
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t
log(sqrt(2) - 1) + log(sqrt(2) + 1)
sage: u = t.maxima_methods(); u
MaximaWrapper(log(sqrt(2) - 1) + log(sqrt(2) + 1))
sage: u._repr_()
'MaximaWrapper(log(sqrt(2) - 1) + log(sqrt(2) + 1))'
"""
return "MaximaWrapper(%s)"%(self._exp)