Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Common Interface Functionality
See the examples in the other sections for how to use specific interfaces. The interface classes all derive from the generic interface that is described in this section.
AUTHORS:
- William Stein (2005): initial version
- William Stein (2006-03-01): got rid of infinite loop on startup if client system missing
- Felix Lawrence (2009-08-21): edited ._sage_() to support lists and float exponents in foreign notation.
- Simon King (2010-09-25): Expect._local_tmpfile() depends on Expect.pid() and is cached; Expect.quit() clears that cache, which is important for forking.
- Jean-Pierre Flori (2010,2011): Split non Pexpect stuff into a parent class.
- Simon King (2015): Improve pickling for InterfaceElement """
#***************************************************************************** # Copyright (C) 2005 William Stein <wstein@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function from six import iteritems, integer_types, string_types
import operator
from sage.structure.sage_object import SageObject from sage.structure.parent_base import ParentWithBase from sage.structure.element import Element, parent
import sage.misc.sage_eval from sage.misc.fast_methods import WithEqualityById from sage.docs.instancedoc import instancedoc
class AsciiArtString(str): def __repr__(self):
class Interface(WithEqualityById, ParentWithBase): """ Interface interface object.
.. NOTE::
Two interfaces compare equal if and only if they are identical objects (this is a critical constraint so that caching of representations of objects in interfaces works correctly). Otherwise they are never equal. """ def __init__(self, name): """ Initialize ``self``.
EXAMPLES::
sage: Maxima() == maxima False sage: maxima == maxima True
sage: Maxima() != maxima True sage: maxima != maxima False """
def _repr_(self):
def name(self, new_name=None):
def get_seed(self): """ Return the seed used to set the random number generator in this interface.
The seed is initialized as ``None`` but should be set when the interface starts.
EXAMPLES::
sage: s = Singular() sage: s.set_seed(107) 107 sage: s.get_seed() 107 """
def rand_seed(self): """ Return a random seed that can be put into ``set_seed`` function for any interpreter.
This should be overridden if the particular interface needs something other than a small positive integer.
EXAMPLES::
sage: from sage.interfaces.interface import Interface sage: i = Interface("") sage: i.rand_seed() # random 318491487L
sage: s = Singular() sage: s.rand_seed() # random 365260051L """
def set_seed(self, seed=None): """ Set the random seed for the interpreter and return the new value of the seed.
This is dependent on which interpreter so must be implemented in each separately. For examples see gap.py or singular.py.
If seed is ``None`` then should generate a random seed.
EXAMPLES::
sage: s = Singular() sage: s.set_seed(1) 1 sage: [s.random(1,10) for i in range(5)] [8, 10, 4, 9, 1]
sage: from sage.interfaces.interface import Interface sage: i = Interface("") sage: i.set_seed() Traceback (most recent call last): ... NotImplementedError: This interpreter did not implement a set_seed function """
def interact(self): r""" This allows you to interactively interact with the child interpreter. Press Ctrl-D or type 'quit' or 'exit' to exit and return to Sage.
.. note::
This is completely different than the console() member function. The console function opens a new copy of the child interpreter, whereas the interact function gives you interactive access to the interpreter that is being used by Sage. Use sage(xxx) or interpretername(xxx) to pull objects in from sage to the interpreter. """ from sage.repl.interpreter import interface_shell_embed shell = interface_shell_embed(self) try: ipython = get_ipython() except NameError: shell() else: shell(local_ns=dict(ipython.user_ns))
def _pre_interact(self): pass
def _post_interact(self): pass
def cputime(self): """ CPU time since this process started running. """ raise NotImplementedError
def read(self, filename): r""" EXAMPLES::
sage: filename = tmp_filename() sage: f = open(filename, 'w') sage: _ = f.write('x = 2\n') sage: f.close() sage: octave.read(filename) # optional - octave sage: octave.get('x') # optional - octave ' 2' sage: import os sage: os.unlink(filename) """
def _read_in_file_command(self, filename):
def eval(self, code, **kwds): """ Evaluate code in an interface.
This method needs to be implemented in sub-classes.
Note that it is not always to be expected that it returns a non-empty string. In contrast, :meth:`get` is supposed to return the result of applying a print command to the object so that the output is easier to parse.
Likewise, the method :meth:`_eval_line` for evaluation of a single line, often makes sense to be overridden. """ raise NotImplementedError
_eval_line = eval
def execute(self, *args, **kwds):
def __call__(self, x, name=None):
r""" Create a new object in self from x.
The object X returned can be used like any Sage object, and wraps an object in self. The standard arithmetic operators work. Moreover if foo is a function then X.foo(y,z,...) calls foo(X, y, z, ...) and returns the corresponding object.
EXAMPLES::
sage: gp(2) 2 sage: gp('2') 2 sage: a = gp(2); gp(a) is a True
"""
#Handle the case when x is an object #in some interface.
#We convert x into an object in this #interface by first going through Sage. except (NotImplementedError, TypeError): pass
except TypeError: raise TypeError(msg)
def _coerce_from_special_method(self, x): """ Tries to coerce to self by calling a special underscore method.
If no such method is defined, raises an AttributeError instead of a TypeError. """
def _coerce_impl(self, x, use_special=True): pass
else:
raise TypeError("unable to coerce element into %s"%self.name())
def new(self, code):
################################################################### # these should all be appropriately overloaded by the derived class ###################################################################
def _left_list_delim(self):
def _right_list_delim(self):
def _left_func_delim(self):
def _right_func_delim(self):
def _assign_symbol(self): return "="
def _equality_symbol(self): raise NotImplementedError
# For efficiency purposes, you should definitely override these # in your derived class. def _true_symbol(self): try: return self.__true_symbol except AttributeError: self.__true_symbol = self.get('1 %s 1'%self._equality_symbol()) return self.__true_symbol
def _false_symbol(self): try: return self.__false_symbol except AttributeError: self.__false_symbol = self.get('1 %s 2'%self._equality_symbol()) return self.__false_symbol
def _lessthan_symbol(self):
def _greaterthan_symbol(self):
def _inequality_symbol(self):
def _relation_symbols(self): """ Returns a dictionary with operators as the keys and their string representation as the values.
EXAMPLES::
sage: import operator sage: symbols = mathematica._relation_symbols() sage: symbols[operator.eq] '==' """ (operator.lt, self._lessthan_symbol()), (operator.le, "<="), (operator.gt, self._greaterthan_symbol()), (operator.ge, ">=")])
def _exponent_symbol(self): """ Return the symbol used to denote *10^ in floats, e.g 'e' in 1.5e6
EXAMPLES::
sage: from sage.interfaces.expect import Expect sage: Expect('nonexistent_interface', 'fake')._exponent_symbol() 'e' """
############################################################ # Functions for working with variables. # The first three must be overloaded by derived classes, # and the definition depends a lot on the class. But # the functionality one gets from this is very nice. ############################################################
def set(self, var, value): """ Set the variable var to the given value. """
def get(self, var): """ Get the value of the variable var.
Note that this needs to be overridden in some interfaces, namely when getting the string representation of an object requires an explicit print command. """ return self.eval(var)
def get_using_file(self, var): r""" Return the string representation of the variable var in self, possibly using a file. Use this if var has a huge string representation, since it may be way faster.
.. warning::
In fact unless a special derived class implements this, it will *not* be any faster. This is the case for this class if you're reading it through introspection and seeing this. """
def clear(self, var): """ Clear the variable named var. """
def _next_var_name(self):
def _create(self, value, name=None):
def _object_class(self): """ EXAMPLES::
sage: from sage.interfaces.expect import Expect sage: Expect._object_class(maxima) <class 'sage.interfaces.expect.ExpectElement'> """ return InterfaceElement
def _function_class(self): """ EXAMPLES::
sage: from sage.interfaces.interface import Interface sage: Interface._function_class(maxima) <class 'sage.interfaces.interface.InterfaceFunction'> """
def _function_element_class(self): """ EXAMPLES::
sage: from sage.interfaces.interface import Interface sage: Interface._function_element_class(maxima) <class 'sage.interfaces.interface.InterfaceFunctionElement'> """
def _convert_args_kwds(self, args=None, kwds=None): """ Converts all of the args and kwds to be elements of this interface.
EXAMPLES::
sage: args = [5] sage: kwds = {'x': 6} sage: args, kwds = gap._convert_args_kwds(args, kwds) sage: args [5] sage: list(map(type, args)) [<class 'sage.interfaces.gap.GapElement'>] sage: type(kwds['x']) <class 'sage.interfaces.gap.GapElement'> """
def _check_valid_function_name(self, function): """ Checks to see if function is a valid function name in this interface. If it is not, an exception is raised. Otherwise, nothing is done.
EXAMPLES::
sage: gap._check_valid_function_name('SymmetricGroup') sage: gap._check_valid_function_name('') Traceback (most recent call last): ... ValueError: function name must be nonempty sage: gap._check_valid_function_name('__foo') Traceback (most recent call last): ... AttributeError """
def function_call(self, function, args=None, kwds=None): """ EXAMPLES::
sage: maxima.quad_qags(x, x, 0, 1, epsrel=1e-4) [0.5,0.55511151231257...e-14,21,0] sage: maxima.function_call('quad_qags', [x, x, 0, 1], {'epsrel':'1e-4'}) [0.5,0.55511151231257...e-14,21,0] """ [s.name() for s in args], ['%s=%s'%(key,value.name()) for key, value in kwds.items()])
def _function_call_string(self, function, args, kwds): """ Returns the string used to make function calls.
EXAMPLES::
sage: maxima._function_call_string('diff', ['f(x)', 'x'], []) 'diff(f(x),x)' """
def call(self, function_name, *args, **kwds): return self.function_call(function_name, args, kwds)
def _contains(self, v1, v2): raise NotImplementedError
def __getattr__(self, attrname): """ TESTS::
sage: ParentWithBase.__getattribute__(singular, '_coerce_map_from_') <bound method Singular._coerce_map_from_ of Singular> """
def console(self): raise NotImplementedError
def help(self, s):
@instancedoc class InterfaceFunction(SageObject): """ Interface function. """ def __init__(self, parent, name):
def _repr_(self):
def __call__(self, *args, **kwds):
def _instancedoc_(self): """ EXAMPLES::
sage: gp.gcd.__doc__ 'gcd(x,{y}): greatest common divisor of x and y.' """
@instancedoc class InterfaceFunctionElement(SageObject): """ Interface function element. """ def __init__(self, obj, name):
def _repr_(self):
def __call__(self, *args, **kwds):
def help(self): print(self.__doc__)
def _instancedoc_(self): """ EXAMPLES::
sage: gp(2).gcd.__doc__ 'gcd(x,{y}): greatest common divisor of x and y.' """
def is_InterfaceElement(x): return isinstance(x, InterfaceElement)
@instancedoc class InterfaceElement(Element): """ Interface element. """ def __init__(self, parent, value, is_name=False, name=None): # idea: Joe Wetherell -- try to find out if the output # is too long and if so get it using file, otherwise # don't.
else:
def _latex_(self): # return "\\begin{verbatim}%s\\end{verbatim}"%self string = str(self) if not '|' in string: delim = '|' elif not '#' in string: delim = '#' elif not '@' in string: delim = '@' elif not '~' in string: delim = '~' return "\\verb%s%s%s"%(delim, string, delim)
def __iter__(self):
def __len__(self): """ Call self.sage() and return the length of that sage object.
This approach is inefficient - each interface should override this method with one that calls the external program's length function.
EXAMPLES::
sage: len(gp([1,2,3])) 3
AUTHORS:
- Felix Lawrence (2009-08-21) """ return len(self.sage())
def __reduce__(self): """ The default linearisation is to return self's parent, which will then get the items returned by :meth:`_reduce` as arguments to reconstruct the element.
EXAMPLES::
sage: G = gap.SymmetricGroup(6) sage: loads(dumps(G)) == G # indirect doctest True sage: y = gap(34) sage: loads(dumps(y)) 34 sage: type(_) <class 'sage.interfaces.gap.GapElement'> sage: y = singular(34) sage: loads(dumps(y)) 34 sage: type(_) <class 'sage.interfaces.singular.SingularElement'> sage: G = gap.PolynomialRing(QQ, ['x']) sage: loads(dumps(G)) PolynomialRing( Rationals, ["x"] ) sage: S = singular.ring(0, ('x')) sage: loads(dumps(S)) polynomial ring, over a field, global ordering // coefficients: QQ // number of vars : 1 // block 1 : ordering lp // : names x // block 2 : ordering C
Here are further examples of pickling of interface elements::
sage: loads(dumps(gp('"abc"'))) abc sage: loads(dumps(gp([1,2,3]))) [1, 2, 3] sage: loads(dumps(pari('"abc"'))) "abc" sage: loads(dumps(pari([1,2,3]))) [1, 2, 3] sage: loads(dumps(r('"abc"'))) [1] "abc" sage: loads(dumps(r([1,2,3]))) [1] 1 2 3 sage: loads(dumps(maxima([1,2,3]))) [1,2,3]
Unfortunately, strings in maxima can't be pickled yet::
sage: loads(dumps(maxima('"abc"'))) Traceback (most recent call last): ... TypeError: unable to make sense of Maxima expression '"abc"' in Sage
"""
def _reduce(self): """ Helper for pickling.
By default, if self is a string, then the representation of that string is returned (not the string itself). Otherwise, it is attempted to return the corresponding Sage object. If this fails with a NotImplementedError, the string representation of self is returned instead.
EXAMPLES::
sage: S = singular.ring(0, ('x')) sage: S._reduce() Univariate Polynomial Ring in x over Rational Field sage: G = gap.PolynomialRing(QQ, ['x']) sage: G._reduce() 'PolynomialRing( Rationals, ["x"] )' sage: G.sage() Traceback (most recent call last): ... NotImplementedError: Unable to parse output: PolynomialRing( Rationals, ["x"] ) sage: singular('"abc"')._reduce() "'abc'" sage: singular('1')._reduce() 1
"""
def __call__(self, *args):
def __contains__(self, x):
def _instancedoc_(self): """ EXAMPLES::
sage: gp(2).__doc__ '2' """
def __hash__(self): """ Returns the hash of self. This is a default implementation of hash which just takes the hash of the string of self. """ return hash('%s'%(self))
def __cmp__(self, other): """ Comparison of interface elements.
NOTE:
GAP has a special role here. It may in some cases raise an error when comparing objects, which is unwanted in Python. We catch these errors. Moreover, GAP does not recognise certain objects as equal even if there definitions are identical.
NOTE:
This methods need to be overridden if the subprocess would not return a string representation of a boolean value unless an explicit print command is used.
TESTS:
Here are examples in which GAP succeeds with a comparison::
sage: gap('SymmetricGroup(8)')==gap('SymmetricGroup(8)') True sage: gap('SymmetricGroup(8)')>gap('AlternatingGroup(8)') False sage: gap('SymmetricGroup(8)')<gap('AlternatingGroup(8)') True
Here, GAP fails to compare, and so ``False`` is returned. In previous Sage versions, this example actually resulted in an error; compare :trac:`5962`. ::
sage: gap('DihedralGroup(8)')==gap('DihedralGroup(8)') False
""" other.name())) == P._true_symbol(): except RuntimeError: pass
# everything is supposed to be comparable in Python, so we define # the comparison thus when no comparison is available in interfaced system. else:
def is_string(self): """ Tell whether this element is a string.
By default, the answer is negative. """
raise NotImplementedError
raise NotImplementedError
def _check_valid(self): """ Check that this object is valid, i.e., the session in which this object is defined is still running. This is relevant for interpreters that can't be interrupted via ctrl-C, hence get restarted. """ raise ValueError("The %s session in which this object was defined is no longer running."%P.name()) except AttributeError: raise ValueError("The session in which this object was defined is no longer running.")
def __del__(self): except ValueError: return
def _sage_repr(self): """ Return a sage-friendly string representation of the object.
Some programs use different notation to Sage, e.g. Mathematica writes lists with {} instead of []. This method calls repr(self) then converts the foreign notation into Sage's notation.
OUTPUT:
A string representation of the object that is ready for sage_eval().
EXAMPLES::
sage: repr(mathematica([1,2,3])) # optional - mathematica '{1, 2, 3}' sage: mathematica([1,2,3])._sage_repr() # optional - mathematica '[1, 2, 3]'
::
sage: gp(10.^80)._sage_repr() '1.0000000000000000000000000000000000000e80' # 64-bit '1.000000000000000000000000000e80' # 32-bit sage: mathematica('10.^80')._sage_repr() # optional - mathematica '1.e80'
AUTHORS:
- Felix Lawrence (2009-08-21) """ #TO DO: this could use file transfers when self.is_remote()
# Translate the external program's function notation to Sage's # Translate the external program's list formatting to Sage's # Translate the external program's exponent formatting
def _sage_(self): """ Attempt to return a Sage version of this object. This is a generic routine that just tries to evaluate the repr(self).
EXAMPLES::
sage: gp(1/2)._sage_() 1/2 sage: _.parent() Rational Field
AUTHORS:
- William Stein
- Felix Lawrence (2009-08-21) """
def sage(self, *args, **kwds): """ Attempt to return a Sage version of this object.
This method does nothing more than calling :meth:`_sage_`, simply forwarding any additional arguments.
EXAMPLES::
sage: gp(1/2).sage() 1/2 sage: _.parent() Rational Field sage: singular.lib("matrix") sage: R = singular.ring(0, '(x,y,z)', 'dp') sage: singular.matrix(2,2).sage() [0 0] [0 0] """
def __repr__(self): """ To obtain the string representation, it is first checked whether the element is still valid. Then, if ``self._cached_repr`` is a string then it is returned. Otherwise, ``self._repr_()`` is called (and the result is cached, if ``self._cached_repr`` evaluates to ``True``).
If the string obtained so far contains ``self._name``, then it is replaced by ``self``'s custom name, if available.
To implement a custom string representation, override the method ``_repr_``, but do not override this double underscore method.
EXAMPLE:
Here is one example showing that the string representation will be cached when requested::
sage: from sage.interfaces.maxima_lib import maxima_lib sage: M = maxima_lib('sqrt(2) + 1/3') sage: M._cached_repr True sage: repr(M) is repr(M) # indirect doctest True sage: M._cached_repr 'sqrt(2)+1/3' sage: M sqrt(2)+1/3
If the interface breaks then it is reflected in the string representation::
sage: s = singular('2') sage: s 2 sage: singular.quit() sage: s (invalid Singular object -- The singular session in which this object was defined is no longer running.)
""" else:
def _repr_(self): """ Default implementation of a helper method for string representation.
It is supposed that immediately before calling this method, the validity of ``self``'s parent was confirmed. So, when you override this method, you can assume that the parent is valid.
TESTS:
In :trac:`22501`, several string representation methods have been removed in favour of using the default implementation. The corresponding tests have been moved here::
sage: gap(SymmetricGroup(8)) # indirect doctest SymmetricGroup( [ 1 .. 8 ] ) sage: gap(2) 2 sage: x = var('x') sage: giac(x) x sage: giac(5) 5 sage: M = matrix(QQ,2,range(4)) sage: giac(M) [[0,1],[2,3]] sage: x = var('x') # optional - maple sage: maple(x) # optional - maple x sage: maple(5) # optional - maple 5 sage: M = matrix(QQ,2,range(4)) # optional - maple sage: maple(M) # optional - maple Matrix(2, 2, [[0,1],[2,3]]) sage: maxima('sqrt(2) + 1/3') sqrt(2)+1/3 sage: mupad.package('"MuPAD-Combinat"') # optional - mupad-Combinat sage: S = mupad.examples.SymmetricFunctions(); S # optional - mupad-Combinat examples::SymmetricFunctions(Dom::ExpressionField())
"""
def __getattr__(self, attrname):
def get_using_file(self): """ Return this element's string representation using a file. Use this if self has a huge string representation. It'll be way faster.
EXAMPLES::
sage: a = maxima(str(2^1000)) sage: a.get_using_file() '10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376' """ except ValueError as msg: return '(invalid {} object -- {})'.format(self.parent() or type(self), msg)
def hasattr(self, attrname): """ Returns whether the given attribute is already defined by this object, and in particular is not dynamically generated.
EXAMPLES::
sage: m = maxima('2') sage: m.hasattr('integral') True sage: m.hasattr('gcd') False """
def attribute(self, attrname): """ If this wraps the object x in the system, this returns the object x.attrname. This is useful for some systems that have object oriented attribute access notation.
EXAMPLES::
sage: g = gap('SO(1,4,7)') sage: k = g.InvariantQuadraticForm() sage: k.attribute('matrix') [ [ 0*Z(7), Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ] ]
::
sage: e = gp('ellinit([0,-1,1,-10,-20])') sage: e.attribute('j') -122023936/161051 """
def __getitem__(self, n): else:
def __int__(self): """ EXAMPLES::
sage: int(maxima('1')) 1 sage: type(_) <... 'int'> """
def bool(self): """ Return whether this element is equal to ``True``.
NOTE:
This method needs to be overridden if the subprocess would not return a string representation of a boolean value unless an explicit print command is used.
EXAMPLES::
sage: singular(0).bool() False sage: singular(1).bool() True
"""
def __bool__(self): """ EXAMPLES::
sage: bool(maxima(0)) False sage: bool(maxima(1)) True """
__nonzero__ = __bool__
def __long__(self): """ EXAMPLES::
sage: m = maxima('1') sage: long(m) 1L """
def __float__(self): """ EXAMPLES::
sage: m = maxima('1/2') sage: m.__float__() 0.5 sage: float(m) 0.5 """
def _integer_(self, ZZ=None): """ EXAMPLES::
sage: m = maxima('1') sage: m._integer_() 1 sage: _.parent() Integer Ring sage: QQ(m) 1 """
def _rational_(self): """ EXAMPLES::
sage: m = maxima('1/2') sage: m._rational_() 1/2 sage: _.parent() Rational Field sage: QQ(m) 1/2 """
def name(self, new_name=None): """ Returns the name of self. If new_name is passed in, then this function returns a new object identical to self whose name is new_name.
Note that this can overwrite existing variables in the system.
EXAMPLES::
sage: x = r([1,2,3]); x [1] 1 2 3 sage: x.name() 'sage3' sage: x = r([1,2,3]).name('x'); x [1] 1 2 3 sage: x.name() 'x'
::
sage: s5 = gap.SymmetricGroup(5).name('s5') sage: s5 SymmetricGroup( [ 1 .. 5 ] ) sage: s5.name() 's5' """ raise TypeError("new_name must be a string")
def gen(self, n):
def _operation(self, operation, other=None): r""" Return the result of applying the binary operation ``operation`` on the arguments ``self`` and ``other``, or the unary operation on ``self`` if ``other`` is not given.
This is a utility function which factors out much of the commonality used in the arithmetic operations for interface elements.
INPUT:
- ``operation`` -- a string representing the operation being performed. For example, '*', or '1/'.
- ``other`` -- the other operand. If ``other`` is ``None``, then the operation is assumed to be unary rather than binary.
OUTPUT: an interface element
EXAMPLES::
sage: a = gp('23') sage: b = gp('5') sage: a._operation('%', b) 3 sage: a._operation('19+') 42 sage: a._operation('!@#$%') Traceback (most recent call last): ... TypeError: Error executing code in GP:... """ else:
def _add_(self, right): """ EXAMPLES::
sage: f = maxima.cos(x) sage: g = maxima.sin(x) sage: f + g sin(_SAGE_VAR_x)+cos(_SAGE_VAR_x) sage: f + 2 cos(_SAGE_VAR_x)+2 sage: 2 + f cos(_SAGE_VAR_x)+2
::
sage: x,y = var('x,y') sage: f = maxima.function('x','sin(x)') sage: g = maxima.function('x','-cos(x)') sage: f+g sin(x)-cos(x) sage: f+3 sin(x)+3
The Maxima variable ``x`` is different from the Sage symbolic variable::
sage: (f+maxima.cos(x)) sin(x)+cos(_SAGE_VAR_x) sage: (f+maxima.cos(y)) sin(x)+cos(_SAGE_VAR_y)
Note that you may get unexpected results when calling symbolic expressions and not explicitly giving the variables::
sage: (f+maxima.cos(x))(2) cos(_SAGE_VAR_x)+sin(2) sage: (f+maxima.cos(y))(2) cos(_SAGE_VAR_y)+sin(2) """
def _sub_(self, right): """ EXAMPLES::
sage: f = maxima.cos(x) sage: g = maxima.sin(x) sage: f - g cos(_SAGE_VAR_x)-sin(_SAGE_VAR_x) sage: f - 2 cos(_SAGE_VAR_x)-2 sage: 2 - f 2-cos(_SAGE_VAR_x)
::
sage: x,y = var('x,y') sage: f = maxima.function('x','sin(x)')
The Maxima variable ``x`` is different from the Sage symbolic variable::
sage: (f-maxima.cos(x)) sin(x)-cos(_SAGE_VAR_x) sage: (f-maxima.cos(y)) sin(x)-cos(_SAGE_VAR_y)
Note that you may get unexpected results when calling symbolic expressions and not explicitly giving the variables::
sage: (f-maxima.cos(x))(2) sin(2)-cos(_SAGE_VAR_x) sage: (f-maxima.cos(y))(2) sin(2)-cos(_SAGE_VAR_y) """
def _neg_(self): """ EXAMPLES::
sage: f = maxima('sin(x)') sage: -f -sin(x) sage: f = maxima.function('x','sin(x)') sage: -f -sin(x) """
def _mul_(self, right): """ EXAMPLES::
sage: f = maxima.cos(x) sage: g = maxima.sin(x) sage: f*g cos(_SAGE_VAR_x)*sin(_SAGE_VAR_x) sage: 2*f 2*cos(_SAGE_VAR_x)
::
sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') # not a function! sage: f*g -cos(x)*sin(x) sage: _(2) -cos(2)*sin(2)
::
sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') sage: g*f -cos(x)*sin(x) sage: _(2) -cos(2)*sin(2) sage: 2*f 2*sin(x) """
def _div_(self, right): """ EXAMPLES::
sage: f = maxima.cos(x) sage: g = maxima.sin(x) sage: f/g cos(_SAGE_VAR_x)/sin(_SAGE_VAR_x) sage: f/2 cos(_SAGE_VAR_x)/2
::
sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') sage: f/g -sin(x)/cos(x) sage: _(2) -sin(2)/cos(2)
::
sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') sage: g/f -cos(x)/sin(x) sage: _(2) -cos(2)/sin(2) sage: 2/f 2/sin(x) """
def __invert__(self): """ EXAMPLES::
sage: f = maxima('sin(x)') sage: ~f 1/sin(x) sage: f = maxima.function('x','sin(x)') sage: ~f 1/sin(x) """
def _mod_(self, right): """ EXAMPLES::
sage: f = gp("x^3 + x") sage: g = gp("2*x + 1") sage: f % g -5/8 """
def __pow__(self, n): """ EXAMPLES::
sage: a = maxima('2') sage: a^(3/4) 2^(3/4)
::
sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') sage: f^g 1/sin(x)^cos(x)
::
sage: f = maxima.function('x','sin(x)') sage: g = maxima('-cos(x)') # not a function sage: g^f (-cos(x))^sin(x) """ |