Path: blob/master/src/sage/interfaces/maxima_abstract.py
8814 views
r"""1Abstract interface to Maxima23Maxima is a free GPL'd general purpose computer algebra system4whose development started in 1968 at MIT. It contains symbolic5manipulation algorithms, as well as implementations of special6functions, including elliptic functions and generalized7hypergeometric functions. Moreover, Maxima has implementations of8many functions relating to the invariant theory of the symmetric9group `S_n`. (However, the commands for group invariants,10and the corresponding Maxima documentation, are in French.) For many11links to Maxima documentation see12http://maxima.sourceforge.net/docs.shtml/.1314AUTHORS:1516- William Stein (2005-12): Initial version1718- David Joyner: Improved documentation1920- William Stein (2006-01-08): Fixed bug in parsing2122- William Stein (2006-02-22): comparisons (following suggestion of23David Joyner)2425- William Stein (2006-02-24): *greatly* improved robustness by adding26sequence numbers to IO bracketing in _eval_line2728- Robert Bradshaw, Nils Bruin, Jean-Pierre Flori (2010,2011): Binary library29interface3031This is an abstract class implementing the functions shared between the Pexpect32and library interfaces to Maxima.33"""3435#*****************************************************************************36# Copyright (C) 2005 William Stein <[email protected]>37#38# Distributed under the terms of the GNU General Public License (GPL)39#40# This code is distributed in the hope that it will be useful,41# but WITHOUT ANY WARRANTY; without even the implied warranty of42# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU43# General Public License for more details.44#45# The full text of the GPL is available at:46#47# http://www.gnu.org/licenses/48#*****************************************************************************4950import os, re, sys, subprocess5152from sage.misc.misc import DOT_SAGE53COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE5455from sage.misc.multireplace import multiple_replace5657import sage.server.support5859##import sage.rings.all6061from interface import (Interface, InterfaceElement, InterfaceFunctionElement,62InterfaceFunction, AsciiArtString)6364# The Maxima "apropos" command, e.g., apropos(det) gives a list65# of all identifiers that begin in a certain way. This could66# maybe be useful somehow... (?) Also maxima has a lot for getting67# documentation from the system -- this could also be useful.6869class MaximaAbstract(Interface):70r"""71Abstract interface to Maxima.7273INPUT:7475- ``name`` - string7677OUTPUT: the interface7879EXAMPLES:8081This class should not be instantiated directly,82but through its subclasses Maxima (Pexpect interface)83or MaximaLib (library interface)::8485sage: m = Maxima()86sage: from sage.interfaces.maxima_abstract import MaximaAbstract87sage: isinstance(m,MaximaAbstract)88True89"""9091def __init__(self, name='maxima_abstract'):92r"""93Create an instance of an abstract interface to Maxima.94See ``MaximaAbstract`` for full documentation.9596EXAMPLES::9798sage: from sage.interfaces.maxima_abstract import MaximaAbstract99sage: isinstance(maxima,MaximaAbstract)100True101102TESTS::103104sage: from sage.interfaces.maxima_abstract import MaximaAbstract105sage: loads(dumps(MaximaAbstract)) == MaximaAbstract106True107"""108Interface.__init__(self,name)109110###########################################111# System -- change directory, etc112###########################################113def chdir(self, dir):114r"""115Change Maxima's current working directory.116117INPUT:118119- ``dir`` - string120121OUTPUT: none122123EXAMPLES::124125sage: maxima.chdir('/')126"""127self.lisp('(ext::cd "%s")'%dir)128129###########################################130# Interactive help131###########################################132def _command_runner(self, command, s, redirect=True):133r"""134Run ``command`` in a new Maxima session and return its135output as an ``AsciiArtString``.136137INPUT:138139- ``command`` - string; function to call140141- ``s`` - string; argument to the function142143- ``redirect`` - boolean (default: True); if redirect is set to False,144then the output of the command is not returned as a string.145Instead, it behaves like os.system. This is used for interactive146things like Maxima's demos. See maxima.demo?147148OUTPUT:149150Output of ``command(s)`` as an ``AsciiArtString`` if ``redirect`` is set151to False; None otherwise.152153EXAMPLES::154155sage: maxima._command_runner('describe', 'gcd')156-- Function: gcd (<p_1>, <p_2>, <x_1>, ...)157...158"""159cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s)160if sage.server.support.EMBEDDED_MODE:161cmd += '< /dev/null'162163if redirect:164p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,165stdout=subprocess.PIPE, stderr=subprocess.PIPE)166res = p.stdout.read()167# ecl-10.2 : 3 lines168# ecl-10.4 : 5 lines169# ecl-11.1 : 4 lines fancy a tango?170# We now get 4 lines of commented verbosity171# every time Maxima starts, so we need to get rid of them172for _ in range(4):173res = res[res.find('\n')+1:]174return AsciiArtString(res)175else:176subprocess.Popen(cmd, shell=True)177178def help(self, s):179r"""180Return Maxima's help for ``s``.181182INPUT:183184- ``s`` - string185186OUTPUT:187188Maxima's help for ``s``189190EXAMPLES::191192sage: maxima.help('gcd')193-- Function: gcd (<p_1>, <p_2>, <x_1>, ...)194...195"""196# Should this be implemented without launching a new Maxima session197# i.e. using eval_line ?198return self._command_runner("describe", s)199200def example(self, s):201r"""202Return Maxima's examples for ``s``.203204INPUT:205206- ``s`` - string207208OUTPUT:209210Maxima's examples for ``s``211212EXAMPLES::213214sage: maxima.example('arrays')215a[n]:=n*a[n-1]216a := n a217n n - 1218a[0]:1219a[5]220120221a[n]:=n222a[6]2236224a[4]22524226done227"""228# Should this be implemented without launching a new Maxima session229# i.e. using eval_line ?230return self._command_runner("example", s)231232describe = help233234def demo(self, s):235r"""236Run Maxima's demo for ``s``.237238INPUT:239240- ``s`` - string241242OUTPUT: none243244EXAMPLES::245246sage: maxima.demo('array') # not tested247batching /opt/sage/local/share/maxima/5.16.3/demo/array.dem248249At the _ prompt, type ';' followed by enter to get next demo250subscrmap : true _251"""252# Should this be implemented without launching a new Maxima session253# i.e. using eval_line ?254return self._command_runner("demo", s, redirect=False)255256def completions(self, s, verbose=True):257r"""258Return all commands that complete the command starting with the259string ``s``. This is like typing s[tab] in the Maxima interpreter.260261INPUT:262263- ``s`` - string264265- ``verbose`` - boolean (default: True)266267OUTPUT: array of strings268269EXAMPLES::270271sage: sorted(maxima.completions('gc', verbose=False))272['gcd', 'gcdex', 'gcfactor', 'gcprint', 'gctime']273"""274if verbose:275print s,276sys.stdout.flush()277# in Maxima 5.19.1, apropos returns all commands that contain278# the given string, instead of all commands that start with279# the given string280cmd_list = self._eval_line('apropos("%s")'%s, error_check=False).replace('\\ - ','-')281cmd_list = [x for x in cmd_list[1:-1].split(',') if x[0] != '?']282return [x for x in cmd_list if x.find(s) == 0]283284def _commands(self, verbose=True):285"""286Return list of all commands defined in Maxima.287288INPUT:289290- ``verbose`` - boolean (default: True)291292OUTPUT: array of strings293294EXAMPLES::295296# The output is kind of random297sage: sorted(maxima._commands(verbose=False))298[...299'display',300...301'gcd',302...303'verbose',304...]305"""306try:307return self.__commands308except AttributeError:309self.__commands = sum(310[self.completions(chr(65+n), verbose=verbose)+311self.completions(chr(97+n), verbose=verbose)312for n in range(26)], [])313return self.__commands314315def trait_names(self, verbose=True, use_disk_cache=True):316r"""317Return all Maxima commands, which is useful for tab completion.318319INPUT:320321- ``verbose`` - boolean (default: True)322323- ``use_disk_cache`` - boolean (default: True); if set to True,324try to read cached result from disk325326OUTPUT: array of strings327328EXAMPLES::329330sage: t = maxima.trait_names(verbose=False)331sage: 'gcd' in t332True333sage: len(t) # random output3341840335"""336try:337return self.__trait_names338except AttributeError:339import sage.misc.persist340if use_disk_cache:341try:342self.__trait_names = sage.misc.persist.load(COMMANDS_CACHE)343return self.__trait_names344except IOError:345pass346if verbose:347print "\nBuilding Maxima command completion list (this takes"348print "a few seconds only the first time you do it)."349print "To force rebuild later, delete %s."%COMMANDS_CACHE350v = self._commands(verbose=verbose)351if verbose:352print "\nDone!"353self.__trait_names = v354sage.misc.persist.save(v, COMMANDS_CACHE)355return v356357def console(self):358r"""359Start the interactive Maxima console. This is a completely separate360maxima session from this interface. To interact with this session,361you should instead use ``maxima.interact()``.362363INPUT: none364365OUTPUT: none366367EXAMPLES::368369sage: maxima.console() # not tested (since we can't)370Maxima 5.13.0 http://maxima.sourceforge.net371Using Lisp CLISP 2.41 (2006-10-13)372Distributed under the GNU Public License. See the file COPYING.373Dedicated to the memory of William Schelter.374This is a development version of Maxima. The function bug_report()375provides bug reporting information.376(%i1)377378::379380sage: maxima.interact() # this is not tested either381--> Switching to Maxima <--382maxima: 2+23834384maxima:385--> Exiting back to Sage <--386"""387maxima_console()388389def cputime(self, t=None):390r"""391Returns the amount of CPU time that this Maxima session has used.392393INPUT:394395- ``t`` - float (default: None); If \var{t} is not None, then396it returns the difference between the current CPU time and \var{t}.397398OUTPUT: float399400EXAMPLES:401sage: t = maxima.cputime()402sage: _ = maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1])403sage: maxima.cputime(t) # output random4040.568913405"""406if t:407return float(self.eval('elapsed_run_time()')) - t408else:409return float(self.eval('elapsed_run_time()'))410411def version(self):412r"""413Return the version of Maxima that Sage includes.414415INPUT: none416417OUTPUT: none418419EXAMPLES::420421sage: maxima.version()422'5.29.1'423"""424return maxima_version()425426####427# Overriding default values428###429430def _assign_symbol(self):431r"""432Return the assign symbol in Maxima.433434INPUT: none435436OUTPUT: string437438EXAMPLES::439440sage: maxima._assign_symbol()441':'442sage: maxima.eval('t : 8')443'8'444sage: maxima.eval('t')445'8'446"""447return ":"448449def _true_symbol(self):450"""451Return the true symbol in Maxima.452453INPUT: none454455OUTPUT: string456457EXAMPLES::458459sage: maxima._true_symbol()460'true'461sage: maxima.eval('is(2 = 2)')462'true'463"""464return 'true'465466def _false_symbol(self):467"""468Return the false symbol in Maxima.469470INPUT: none471472OUTPUT: string473474EXAMPLES::475476sage: maxima._false_symbol()477'false'478sage: maxima.eval('is(2 = 4)')479'false'480"""481return 'false'482483def _equality_symbol(self):484"""485Returns the equality symbol in Maxima.486487INPUT: none488489OUTPUT: string490491EXAMPLES::492493sage: maxima._equality_symbol()494'='495sage: var('x y')496(x, y)497sage: maxima(x == y)498x=y499"""500return '='501502def _inequality_symbol(self):503"""504Returns the inequality symbol in Maxima.505506INPUT: none507508OUTPUT: string509510EXAMPLES::511512sage: maxima._inequality_symbol()513'#'514sage: maxima((x != 1))515x#1516"""517return '#'518519def _function_class(self):520"""521Return the Python class of Maxima functions.522523INPUT: none524525OUTPUT: type526527EXAMPLES::528529sage: maxima._function_class()530<class 'sage.interfaces.maxima.MaximaFunction'>531"""532return MaximaAbstractFunction533534def _object_class(self):535"""536Return the Python class of Maxima elements.537538INPUT: none539540OUTPUT: type541542EXAMPLES::543544sage: maxima._object_class()545<class 'sage.interfaces.maxima.MaximaElement'>546"""547return MaximaAbstractElement548549def _function_element_class(self):550"""551Return the Python class of Maxima functions of elements.552553INPUT: none554555OUTPUT: type556557EXAMPLES::558559sage: maxima._function_element_class()560<class 'sage.interfaces.maxima.MaximaFunctionElement'>561"""562return MaximaAbstractFunctionElement563564def _object_function_class(self):565"""566Return the Python class of Maxima user-defined functions.567568INPUT: none569570OUTPUT: type571572EXAMPLES::573574sage: maxima._object_function_class()575<class 'sage.interfaces.maxima.MaximaElementFunction'>576"""577return MaximaAbstractElementFunction578579####################580# Maxima functions #581####################582583def function(self, args, defn, rep=None, latex=None):584"""585Return the Maxima function with given arguments and definition.586587INPUT:588589- ``args`` - a string with variable names separated by590commas591592- ``defn`` - a string (or Maxima expression) that593defines a function of the arguments in Maxima.594595- ``rep`` - an optional string; if given, this is how596the function will print.597598OUTPUT: Maxima function599600EXAMPLES::601602sage: f = maxima.function('x', 'sin(x)')603sage: f(3.2)604-.058374143427580...605sage: f = maxima.function('x,y', 'sin(x)+cos(y)')606sage: f(2,3.5)607sin(2)-.9364566872907963608sage: f609sin(x)+cos(y)610611::612613sage: g = f.integrate('z')614sage: g615(cos(y)+sin(x))*z616sage: g(1,2,3)6173*(cos(2)+sin(1))618619The function definition can be a Maxima object::620621sage: an_expr = maxima('sin(x)*gamma(x)')622sage: t = maxima.function('x', an_expr)623sage: t624gamma(x)*sin(x)625sage: t(2)626sin(2)627sage: float(t(2))6280.9092974268256817629sage: loads(t.dumps())630gamma(x)*sin(x)631"""632name = self._next_var_name()633if isinstance(defn, MaximaAbstractElement):634defn = defn.str()635elif not isinstance(defn, str):636defn = str(defn)637if isinstance(args, MaximaAbstractElement):638args = args.str()639elif not isinstance(args, str):640args = str(args)641cmd = '%s(%s) := %s'%(name, args, defn)642self._eval_line(cmd)643if rep is None:644rep = defn645f = self._object_function_class()(self, name, rep, args, latex)646return f647648## def display2d(self, flag=True):649## """650## Set the flag that determines whether Maxima objects are651## printed using their 2-d ASCII art representation. When the652## maxima interface starts the default is that objects are not653## represented in 2-d.654655## INPUT:656## flag -- bool (default: True)657658## EXAMPLES659## sage: maxima('1/2')660## 1/2661## sage: maxima.display2d(True)662## sage: maxima('1/2')663## 1664## -665## 2666## sage: maxima.display2d(False)667## """668## self._display2d = bool(flag)669670def plot2d(self, *args):671r"""672Plot a 2d graph using Maxima / gnuplot.673674maxima.plot2d(f, '[var, min, max]', options)675676INPUT:677678- ``f`` - a string representing a function (such as679f="sin(x)") [var, xmin, xmax]680681- ``options`` - an optional string representing plot2d682options in gnuplot format683684EXAMPLES::685686sage: maxima.plot2d('sin(x)','[x,-5,5]') # not tested687sage: opts = '[gnuplot_term, ps], [gnuplot_out_file, "sin-plot.eps"]'688sage: maxima.plot2d('sin(x)','[x,-5,5]',opts) # not tested689690The eps file is saved in the current directory.691"""692self('plot2d(%s)'%(','.join([str(x) for x in args])))693694def plot2d_parametric(self, r, var, trange, nticks=50, options=None):695r"""696Plot r = [x(t), y(t)] for t = tmin...tmax using gnuplot with697options.698699INPUT:700701- ``r`` - a string representing a function (such as702r="[x(t),y(t)]")703704- ``var`` - a string representing the variable (such705as var = "t")706707- ``trange`` - [tmin, tmax] are numbers with tmintmax708709- ``nticks`` - int (default: 50)710711- ``options`` - an optional string representing plot2d712options in gnuplot format713714EXAMPLES::715716sage: maxima.plot2d_parametric(["sin(t)","cos(t)"], "t",[-3.1,3.1]) # not tested717718::719720sage: opts = '[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "circle-plot.eps"]'721sage: maxima.plot2d_parametric(["sin(t)","cos(t)"], "t", [-3.1,3.1], options=opts) # not tested722723The eps file is saved to the current working directory.724725Here is another fun plot::726727sage: maxima.plot2d_parametric(["sin(5*t)","cos(11*t)"], "t", [0,2*pi()], nticks=400) # not tested728"""729tmin = trange[0]730tmax = trange[1]731cmd = "plot2d([parametric, %s, %s, [%s, %s, %s], [nticks, %s]]"%( \732r[0], r[1], var, tmin, tmax, nticks)733if options is None:734cmd += ")"735else:736cmd += ", %s)"%options737self(cmd)738739def plot3d(self, *args):740r"""741Plot a 3d graph using Maxima / gnuplot.742743maxima.plot3d(f, '[x, xmin, xmax]', '[y, ymin, ymax]', '[grid, nx,744ny]', options)745746INPUT:747748- ``f`` - a string representing a function (such as749f="sin(x)") [var, min, max]750751- ``args`` should be of the form '[x, xmin, xmax]', '[y, ymin, ymax]',752'[grid, nx, ny]', options753754EXAMPLES::755756sage: maxima.plot3d('1 + x^3 - y^2', '[x,-2,2]', '[y,-2,2]', '[grid,12,12]') # not tested757sage: maxima.plot3d('sin(x)*cos(y)', '[x,-2,2]', '[y,-2,2]', '[grid,30,30]') # not tested758sage: opts = '[gnuplot_term, ps], [gnuplot_out_file, "sin-plot.eps"]'759sage: maxima.plot3d('sin(x+y)', '[x,-5,5]', '[y,-1,1]', opts) # not tested760761The eps file is saved in the current working directory.762"""763self('plot3d(%s)'%(','.join([str(x) for x in args])))764765def plot3d_parametric(self, r, vars, urange, vrange, options=None):766r"""767Plot a 3d parametric graph with r=(x,y,z), x = x(u,v), y = y(u,v),768z = z(u,v), for u = umin...umax, v = vmin...vmax using gnuplot with769options.770771INPUT:772773- ``x, y, z`` - a string representing a function (such774as ``x="u2+v2"``, ...) vars is a list or two strings775representing variables (such as vars = ["u","v"])776777- ``urange`` - [umin, umax]778779- ``vrange`` - [vmin, vmax] are lists of numbers with780umin umax, vmin vmax781782- ``options`` - optional string representing plot2d783options in gnuplot format784785OUTPUT: displays a plot on screen or saves to a file786787EXAMPLES::788789sage: maxima.plot3d_parametric(["v*sin(u)","v*cos(u)","v"], ["u","v"],[-3.2,3.2],[0,3]) # not tested790sage: opts = '[gnuplot_term, ps], [gnuplot_out_file, "sin-cos-plot.eps"]'791sage: maxima.plot3d_parametric(["v*sin(u)","v*cos(u)","v"], ["u","v"],[-3.2,3.2],[0,3],opts) # not tested792793The eps file is saved in the current working directory.794795Here is a torus::796797sage: _ = maxima.eval("expr_1: cos(y)*(10.0+6*cos(x)); expr_2: sin(y)*(10.0+6*cos(x)); expr_3: -6*sin(x);") # optional798sage: maxima.plot3d_parametric(["expr_1","expr_2","expr_3"], ["x","y"],[0,6],[0,6]) # not tested799800Here is a Mobius strip::801802sage: x = "cos(u)*(3 + v*cos(u/2))"803sage: y = "sin(u)*(3 + v*cos(u/2))"804sage: z = "v*sin(u/2)"805sage: maxima.plot3d_parametric([x,y,z],["u","v"],[-3.1,3.2],[-1/10,1/10]) # not tested806"""807umin = urange[0]808umax = urange[1]809vmin = vrange[0]810vmax = vrange[1]811cmd = 'plot3d([%s, %s, %s], [%s, %s, %s], [%s, %s, %s]'%(812r[0], r[1], r[2], vars[0], umin, umax, vars[1], vmin, vmax)813if options is None:814cmd += ')'815else:816cmd += ', %s)'%options817self(cmd)818819def de_solve(self, de, vars, ics=None):820"""821Solves a 1st or 2nd order ordinary differential equation (ODE) in822two variables, possibly with initial conditions.823824INPUT:825826- ``de`` - a string representing the ODE827828- ``vars`` - a list of strings representing the two829variables.830831- ``ics`` - a triple of numbers [a,b1,b2] representing832y(a)=b1, y'(a)=b2833834EXAMPLES::835836sage: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1])837y=3*x-2*%e^(x-1)838sage: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'])839y=%k1*%e^x+%k2*%e^-x+3*x840sage: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'])841y=(%c-3*(-x-1)*%e^-x)*%e^x842sage: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'],[1,1])843y=-%e^-1*(5*%e^x-3*%e*x-3*%e)844"""845if not isinstance(vars, str):846str_vars = '%s, %s'%(vars[1], vars[0])847else:848str_vars = vars849self.eval('depends(%s)'%str_vars)850m = self(de)851a = 'ode2(%s, %s)'%(m.name(), str_vars)852if ics != None:853if len(ics) == 3:854cmd = "ic2("+a+",%s=%s,%s=%s,diff(%s,%s)=%s);"%(vars[0],ics[0], vars[1],ics[1], vars[1], vars[0], ics[2])855return self(cmd)856if len(ics) == 2:857return self("ic1("+a+",%s=%s,%s=%s);"%(vars[0],ics[0], vars[1],ics[1]))858return self(a+";")859860def de_solve_laplace(self, de, vars, ics=None):861"""862Solves an ordinary differential equation (ODE) using Laplace863transforms.864865INPUT:866867- ``de`` - a string representing the ODE (e.g., de =868"diff(f(x),x,2)=diff(f(x),x)+sin(x)")869870- ``vars`` - a list of strings representing the871variables (e.g., vars = ["x","f"])872873- ``ics`` - a list of numbers representing initial874conditions, with symbols allowed which are represented by strings875(eg, f(0)=1, f'(0)=2 is ics = [0,1,2])876877EXAMPLES::878879sage: maxima.clear('x'); maxima.clear('f')880sage: maxima.de_solve_laplace("diff(f(x),x,2) = 2*diff(f(x),x)-f(x)", ["x","f"], [0,1,2])881f(x)=x*%e^x+%e^x882883::884885sage: maxima.clear('x'); maxima.clear('f')886sage: f = maxima.de_solve_laplace("diff(f(x),x,2) = 2*diff(f(x),x)-f(x)", ["x","f"])887sage: f888f(x)=x*%e^x*('at('diff(f(x),x,1),x=0))-f(0)*x*%e^x+f(0)*%e^x889sage: print f890!891x d ! x x892f(x) = x %e (-- (f(x))! ) - f(0) x %e + f(0) %e893dx !894!x = 0895896.. note::897898The second equation sets the values of `f(0)` and899`f'(0)` in Maxima, so subsequent ODEs involving these900variables will have these initial conditions automatically901imposed.902"""903if not (ics is None):904d = len(ics)905for i in range(0,d-1):906ic = 'atvalue(diff(%s(%s), %s, %s), %s = %s, %s)'%(907vars[1], vars[0], vars[0], i, vars[0], ics[0], ics[1+i])908self.eval(ic)909return self('desolve(%s, %s(%s))'%(de, vars[1], vars[0]))910911def solve_linear(self, eqns,vars):912"""913Wraps maxima's linsolve.914915INPUT:916917- ``eqns`` - a list of m strings; each representing a linear918question in m = n variables919920- ``vars`` - a list of n strings; each921representing a variable922923EXAMPLES::924925sage: eqns = ["x + z = y","2*a*x - y = 2*a^2","y - 2*z = 2"]926sage: vars = ["x","y","z"]927sage: maxima.solve_linear(eqns, vars)928[x=a+1,y=2*a,z=a-1]929"""930eqs = "["931for i in range(len(eqns)):932if i<len(eqns)-1:933eqs = eqs + eqns[i]+","934if i==len(eqns)-1:935eqs = eqs + eqns[i]+"]"936vrs = "["937for i in range(len(vars)):938if i<len(vars)-1:939vrs = vrs + vars[i]+","940if i==len(vars)-1:941vrs = vrs + vars[i]+"]"942return self('linsolve(%s, %s)'%(eqs, vrs))943944def unit_quadratic_integer(self, n):945r"""946Finds a unit of the ring of integers of the quadratic number field947`\QQ(\sqrt{n})`, `n>1`, using the qunit maxima command.948949INPUT:950951- ``n`` - an integer952953EXAMPLES::954955sage: u = maxima.unit_quadratic_integer(101); u956a + 10957sage: u.parent()958Number Field in a with defining polynomial x^2 - 101959sage: u = maxima.unit_quadratic_integer(13)960sage: u9615*a + 18962sage: u.parent()963Number Field in a with defining polynomial x^2 - 13964"""965from sage.rings.all import QuadraticField, Integer966# Take square-free part so sqrt(n) doesn't get simplified967# further by maxima968# (The original version of this function would yield wrong answers if969# n is not squarefree.)970n = Integer(n).squarefree_part()971if n < 1:972raise ValueError, "n (=%s) must be >= 1"%n973s = repr(self('qunit(%s)'%n)).lower()974r = re.compile('sqrt\(.*\)')975s = r.sub('a', s)976a = QuadraticField(n, 'a').gen()977return eval(s)978979def plot_list(self, ptsx, ptsy, options=None):980r"""981Plots a curve determined by a sequence of points.982983INPUT:984985- ``ptsx`` - [x1,...,xn], where the xi and yi are986real,987988- ``ptsy`` - [y1,...,yn]989990- ``options`` - a string representing maxima plot2d991options.992993The points are (x1,y1), (x2,y2), etc.994995This function requires maxima 5.9.2 or newer.996997.. note::998999More that 150 points can sometimes lead to the program1000hanging. Why?10011002EXAMPLES::10031004sage: zeta_ptsx = [ (pari(1/2 + i*I/10).zeta().real()).precision(1) for i in range (70,150)]1005sage: zeta_ptsy = [ (pari(1/2 + i*I/10).zeta().imag()).precision(1) for i in range (70,150)]1006sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested1007sage: opts='[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "zeta.eps"]'1008sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested1009"""1010cmd = 'plot2d([discrete,%s, %s]'%(ptsx, ptsy)1011if options is None:1012cmd += ')'1013else:1014cmd += ', %s)'%options1015self(cmd)101610171018def plot_multilist(self, pts_list, options=None):1019r"""1020Plots a list of list of points pts_list=[pts1,pts2,...,ptsn],1021where each ptsi is of the form [[x1,y1],...,[xn,yn]] x's must be1022integers and y's reals options is a string representing maxima1023plot2d options.10241025INPUT:10261027- ``pts_lst`` - list of points; each point must be of the form [x,y]1028where ``x`` is an integer and ``y`` is a real10291030- ``var`` - string; representing Maxima's plot2d options10311032Requires maxima 5.9.2 at least.10331034.. note::10351036More that 150 points can sometimes lead to the program1037hanging.10381039EXAMPLES::10401041sage: xx = [ i/10.0 for i in range (-10,10)]1042sage: yy = [ i/10.0 for i in range (-10,10)]1043sage: x0 = [ 0 for i in range (-10,10)]1044sage: y0 = [ 0 for i in range (-10,10)]1045sage: zeta_ptsx1 = [ (pari(1/2+i*I/10).zeta().real()).precision(1) for i in range (10)]1046sage: zeta_ptsy1 = [ (pari(1/2+i*I/10).zeta().imag()).precision(1) for i in range (10)]1047sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]]) # not tested1048sage: zeta_ptsx1 = [ (pari(1/2+i*I/10).zeta().real()).precision(1) for i in range (10,150)]1049sage: zeta_ptsy1 = [ (pari(1/2+i*I/10).zeta().imag()).precision(1) for i in range (10,150)]1050sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]]) # not tested1051sage: opts='[gnuplot_preamble, "set nokey"]'1052sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]],opts) # not tested1053"""1054n = len(pts_list)1055cmd = '['1056for i in range(n):1057if i < n-1:1058cmd = cmd+'[discrete,'+str(pts_list[i][0])+','+str(pts_list[i][1])+'],'1059if i==n-1:1060cmd = cmd+'[discrete,'+str(pts_list[i][0])+','+str(pts_list[i][1])+']]'1061#print cmd1062if options is None:1063self('plot2d('+cmd+')')1064else:1065self('plot2d('+cmd+','+options+')')106610671068class MaximaAbstractElement(InterfaceElement):1069r"""1070Element of Maxima through an abstract interface.10711072EXAMPLES:10731074Elements of this class should not be created directly.1075The targeted parent of a concrete inherited class should be used instead::10761077sage: from sage.interfaces.maxima_lib import maxima_lib1078sage: xp = maxima(x)1079sage: type(xp)1080<class 'sage.interfaces.maxima.MaximaElement'>1081sage: xl = maxima_lib(x)1082sage: type(xl)1083<class 'sage.interfaces.maxima_lib.MaximaLibElement'>1084"""10851086def __str__(self):1087"""1088Printing an object explicitly gives ASCII art.10891090INPUT: none10911092OUTPUT: string10931094EXAMPLES::10951096sage: f = maxima('1/(x-1)^3'); f10971/(x-1)^31098sage: print f109911100--------110131102(x - 1)1103"""1104return self.display2d(onscreen=False)11051106def bool(self):1107"""1108Convert ``self`` into a boolean.11091110INPUT: none11111112OUTPUT: boolean11131114EXAMPLES::11151116sage: maxima(0).bool()1117False1118sage: maxima(1).bool()1119True1120"""1121P = self._check_valid()1122return P.eval('is(%s = 0);'%self.name()) == P._false_symbol() # but be careful, since for relations things like is(equal(a,b)) are what Maxima needs11231124def __cmp__(self, other):1125"""1126Compare this Maxima object with ``other``.11271128INPUT:11291130- ``other`` - an object to compare to11311132OUTPUT: integer11331134EXAMPLES::11351136sage: a = maxima(1); b = maxima(2)1137sage: a == b1138False1139sage: a < b1140True1141sage: a > b1142False1143sage: b < a1144False1145sage: b > a1146True11471148We can also compare more complicated object such as functions::11491150sage: f = maxima('sin(x)'); g = maxima('cos(x)')1151sage: -f == g.diff('x')1152True1153"""11541155# thanks to David Joyner for telling me about using "is".1156# but be careful, since for relations things like is(equal(a,b))1157# are what Maxima needs1158P = self.parent()1159try:1160if P.eval("is (%s < %s)"%(self.name(), other.name())) == P._true_symbol():1161return -11162elif P.eval("is (%s > %s)"%(self.name(), other.name())) == P._true_symbol():1163return 11164elif P.eval("is (%s = %s)"%(self.name(), other.name())) == P._true_symbol():1165return 01166except TypeError:1167pass1168return cmp(repr(self),repr(other))1169# everything is supposed to be comparable in Python,1170# so we define the comparison thus when no comparable1171# in interfaced system.11721173def _sage_(self):1174"""1175Attempt to make a native Sage object out of this Maxima object.1176This is useful for automatic coercions in addition to other1177things.11781179INPUT: none11801181OUTPUT: Sage object11821183EXAMPLES::11841185sage: a = maxima('sqrt(2) + 2.5'); a1186sqrt(2)+2.51187sage: b = a._sage_(); b1188sqrt(2) + 2.51189sage: type(b)1190<type 'sage.symbolic.expression.Expression'>11911192We illustrate an automatic coercion::11931194sage: c = b + sqrt(3); c1195sqrt(3) + sqrt(2) + 2.51196sage: type(c)1197<type 'sage.symbolic.expression.Expression'>1198sage: d = sqrt(3) + b; d1199sqrt(3) + sqrt(2) + 2.51200sage: type(d)1201<type 'sage.symbolic.expression.Expression'>12021203sage: a = sage.calculus.calculus.maxima('x^(sqrt(y)+%pi) + sin(%e + %pi)')1204sage: a._sage_()1205x^(pi + sqrt(y)) - sin(e)1206sage: var('x, y')1207(x, y)1208sage: v = sage.calculus.calculus.maxima.vandermonde_matrix([x, y, 1/2])1209sage: v._sage_()1210[ 1 x x^2]1211[ 1 y y^2]1212[ 1 1/2 1/4]12131214Check if #7661 is fixed::12151216sage: var('delta')1217delta1218sage: (2*delta).simplify()12192*delta1220"""1221import sage.calculus.calculus as calculus1222return calculus.symbolic_expression_from_maxima_string(self.name(),1223maxima=self.parent())12241225def _symbolic_(self, R):1226"""1227Return a symbolic expression equivalent to this Maxima object.12281229INPUT:12301231- ``R`` - symbolic ring to convert into12321233OUTPUT: symbolic expression12341235EXAMPLES::12361237sage: t = sqrt(2)._maxima_()1238sage: u = t._symbolic_(SR); u1239sqrt(2)1240sage: u.parent()1241Symbolic Ring12421243This is used when converting Maxima objects to the Symbolic Ring::12441245sage: SR(t)1246sqrt(2)1247"""1248return R(self._sage_())12491250def __complex__(self):1251"""1252Return a complex number equivalent to this Maxima object.12531254INPUT: none12551256OUTPUT: complex12571258EXAMPLES::12591260sage: complex(maxima('sqrt(-2)+1'))1261(1+1.4142135623730951j)1262"""1263return complex(self._sage_())12641265def _complex_mpfr_field_(self, C):1266"""1267Return a mpfr complex number equivalent to this Maxima object.12681269INPUT:12701271- ``C`` - complex numbers field to convert into12721273OUTPUT: complex12741275EXAMPLES::12761277sage: CC(maxima('1+%i'))12781.00000000000000 + 1.00000000000000*I1279sage: CC(maxima('2342.23482943872+234*%i'))12802342.23482943872 + 234.000000000000*I1281sage: ComplexField(10)(maxima('2342.23482943872+234*%i'))12822300. + 230.*I1283sage: ComplexField(200)(maxima('1+%i'))12841.0000000000000000000000000000000000000000000000000000000000 + 1.0000000000000000000000000000000000000000000000000000000000*I1285sage: ComplexField(200)(maxima('sqrt(-2)'))12861.4142135623730950488016887242096980785696718753769480731767*I1287sage: N(sqrt(-2), 200)12888.0751148893563733350506651837615871941533119425962889089783e-62 + 1.4142135623730950488016887242096980785696718753769480731767*I1289"""1290return C(self._sage_())12911292def _mpfr_(self, R):1293"""1294Return a mpfr real number equivalent to this Maxima object.12951296INPUT:12971298- ``R`` - real numbers field to convert into12991300OUTPUT: real13011302EXAMPLES::13031304sage: RealField(100)(maxima('sqrt(2)+1'))13052.41421356237309504880168872421306"""1307return R(self._sage_())13081309def _complex_double_(self, C):1310"""1311Return a double precision complex number equivalent to this Maxima object.13121313INPUT:13141315- ``C`` - double precision complex numbers field to convert into13161317OUTPUT: complex13181319EXAMPLES::13201321sage: CDF(maxima('sqrt(2)+1'))13222.414213562371323"""1324return C(self._sage_())13251326def _real_double_(self, R):1327"""1328Return a double precision real number equivalent to this Maxima object.13291330INPUT:13311332- ``R`` - double precision real numbers field to convert into13331334OUTPUT: real13351336EXAMPLES::13371338sage: RDF(maxima('sqrt(2)+1'))13392.414213562371340"""1341return R(self._sage_())13421343def real(self):1344"""1345Return the real part of this Maxima element.13461347INPUT: none13481349OUTPUT: Maxima real13501351EXAMPLES::13521353sage: maxima('2 + (2/3)*%i').real()135421355"""1356return self.realpart()13571358def imag(self):1359"""1360Return the imaginary part of this Maxima element.13611362INPUT: none13631364OUTPUT: Maxima real13651366EXAMPLES::13671368sage: maxima('2 + (2/3)*%i').imag()13692/31370"""1371return self.imagpart()13721373def numer(self):1374"""1375Return numerical approximation to self as a Maxima object.13761377INPUT: none13781379OUTPUT: Maxima object13801381EXAMPLES::13821383sage: a = maxima('sqrt(2)').numer(); a13841.41421356237309...1385sage: type(a)1386<class 'sage.interfaces.maxima.MaximaElement'>1387"""1388return self.comma('numer')13891390def str(self):1391"""1392Return string representation of this Maxima object.13931394INPUT: none13951396OUTPUT: string13971398EXAMPLES::13991400sage: maxima('sqrt(2) + 1/3').str()1401'sqrt(2)+1/3'1402"""1403P = self._check_valid()1404return P.get(self._name)14051406def __repr__(self):1407"""1408Return print representation of this Maxima object.14091410INPUT: none14111412OUTPUT: string14131414The result is cached.14151416EXAMPLES::14171418sage: maxima('sqrt(2) + 1/3').__repr__()1419'sqrt(2)+1/3'1420"""1421P = self._check_valid()1422try:1423return self.__repr1424except AttributeError:1425pass1426r = P.get(self._name)1427self.__repr = r1428return r14291430def diff(self, var='x', n=1):1431"""1432Return the n-th derivative of self.14331434INPUT:14351436- ``var`` - variable (default: 'x')14371438- ``n`` - integer (default: 1)14391440OUTPUT: n-th derivative of self with respect to the variable var14411442EXAMPLES::14431444sage: f = maxima('x^2')1445sage: f.diff()14462*x1447sage: f.diff('x')14482*x1449sage: f.diff('x', 2)145021451sage: maxima('sin(x^2)').diff('x',4)145216*x^4*sin(x^2)-12*sin(x^2)-48*x^2*cos(x^2)14531454::14551456sage: f = maxima('x^2 + 17*y^2')1457sage: f.diff('x')145834*y*'diff(y,x,1)+2*x1459sage: f.diff('y')146034*y1461"""1462return InterfaceElement.__getattr__(self, 'diff')(var, n)14631464derivative = diff14651466def nintegral(self, var='x', a=0, b=1,1467desired_relative_error='1e-8',1468maximum_num_subintervals=200):1469r"""1470Return a numerical approximation to the integral of self from a to1471b.14721473INPUT:14741475- ``var`` - variable to integrate with respect to14761477- ``a`` - lower endpoint of integration14781479- ``b`` - upper endpoint of integration14801481- ``desired_relative_error`` - (default: '1e-8') the1482desired relative error14831484- ``maximum_num_subintervals`` - (default: 200)1485maxima number of subintervals14861487OUTPUT:14881489- approximation to the integral14901491- estimated absolute error of the1492approximation14931494- the number of integrand evaluations14951496- an error code:14971498- ``0`` - no problems were encountered14991500- ``1`` - too many subintervals were done15011502- ``2`` - excessive roundoff error15031504- ``3`` - extremely bad integrand behavior15051506- ``4`` - failed to converge15071508- ``5`` - integral is probably divergent or slowly convergent15091510- ``6`` - the input is invalid15111512EXAMPLES::15131514sage: maxima('exp(-sqrt(x))').nintegral('x',0,1)1515(.5284822353142306, 4.16331413788384...e-11, 231, 0)15161517Note that GP also does numerical integration, and can do so to very1518high precision very quickly::15191520sage: gp('intnum(x=0,1,exp(-sqrt(x)))')15210.5284822353142307136179049194 # 32-bit15220.52848223531423071361790491935415653022 # 64-bit1523sage: _ = gp.set_precision(80)1524sage: gp('intnum(x=0,1,exp(-sqrt(x)))')15250.528482235314230713617904919354156530216755475872928661968652793210154017020400791526"""1527from sage.rings.all import Integer1528v = self.quad_qags(var, a, b, epsrel=desired_relative_error,1529limit=maximum_num_subintervals)1530return v[0], v[1], Integer(v[2]), Integer(v[3])15311532def integral(self, var='x', min=None, max=None):1533r"""1534Return the integral of self with respect to the variable x.15351536INPUT:15371538- ``var`` - variable15391540- ``min`` - default: None15411542- ``max`` - default: None15431544OUTPUT:15451546- the definite integral if xmin is not None15471548- an indefinite integral otherwise15491550EXAMPLES::15511552sage: maxima('x^2+1').integral()1553x^3/3+x1554sage: maxima('x^2+ 1 + y^2').integral('y')1555y^3/3+x^2*y+y1556sage: maxima('x / (x^2+1)').integral()1557log(x^2+1)/21558sage: maxima('1/(x^2+1)').integral()1559atan(x)1560sage: maxima('1/(x^2+1)').integral('x', 0, infinity)1561%pi/21562sage: maxima('x/(x^2+1)').integral('x', -1, 1)1563015641565::15661567sage: f = maxima('exp(x^2)').integral('x',0,1); f1568-sqrt(%pi)*%i*erf(%i)/21569sage: f.numer()15701.46265174590718...1571"""1572I = InterfaceElement.__getattr__(self, 'integrate')1573if min is None:1574return I(var)1575else:1576if max is None:1577raise ValueError, "neither or both of min/max must be specified."1578return I(var, min, max)15791580integrate = integral15811582def __float__(self):1583"""1584Return floating point version of this Maxima element.15851586INPUT: none15871588OUTPUT: real15891590EXAMPLES::15911592sage: float(maxima("3.14"))15933.141594sage: float(maxima("1.7e+17"))15951.7e+171596sage: float(maxima("1.7e-17"))15971.7e-171598"""1599try:1600return float(repr(self.numer()))1601except ValueError:1602raise TypeError, "unable to coerce '%s' to float"%repr(self)16031604def __len__(self):1605"""1606Return the length of a list.16071608INPUT: none16091610OUTPUT: integer16111612EXAMPLES::16131614sage: v = maxima('create_list(x^i,i,0,5)')1615sage: len(v)161661617"""1618P = self._check_valid()1619return int(P.eval('length(%s)'%self.name()))16201621def dot(self, other):1622"""1623Implements the notation self . other.16241625INPUT:16261627- ``other`` - matrix; argument to dot.16281629OUTPUT: Maxima matrix16301631EXAMPLES::16321633sage: A = maxima('matrix ([a1],[a2])')1634sage: B = maxima('matrix ([b1, b2])')1635sage: A.dot(B)1636matrix([a1*b1,a1*b2],[a2*b1,a2*b2])1637"""1638P = self._check_valid()1639Q = P(other)1640return P('%s . %s'%(self.name(), Q.name()))16411642def __getitem__(self, n):1643r"""1644Return the n-th element of this list.16451646INPUT:16471648- ``n`` - integer16491650OUTPUT: Maxima object16511652.. note::16531654Lists are 0-based when accessed via the Sage interface, not16551-based as they are in the Maxima interpreter.16561657EXAMPLES::16581659sage: v = maxima('create_list(i*x^i,i,0,5)'); v1660[0,x,2*x^2,3*x^3,4*x^4,5*x^5]1661sage: v[3]16623*x^31663sage: v[0]166401665sage: v[10]1666Traceback (most recent call last):1667...1668IndexError: n = (10) must be between 0 and 51669"""1670n = int(n)1671if n < 0 or n >= len(self):1672raise IndexError, "n = (%s) must be between %s and %s"%(n, 0, len(self)-1)1673# If you change the n+1 to n below, better change __iter__ as well.1674return InterfaceElement.__getitem__(self, n+1)16751676def __iter__(self):1677"""1678Return an iterator for self.16791680INPUT: none16811682OUTPUT: iterator16831684EXAMPLES::16851686sage: v = maxima('create_list(i*x^i,i,0,5)')1687sage: L = list(v)1688sage: [e._sage_() for e in L]1689[0, x, 2*x^2, 3*x^3, 4*x^4, 5*x^5]1690"""1691for i in range(len(self)):1692yield self[i]16931694def subst(self, val):1695"""1696Substitute a value or several values into this Maxima object.16971698INPUT:16991700- ``val`` - string representing substitution(s) to perform17011702OUTPUT: Maxima object17031704EXAMPLES::17051706sage: maxima('a^2 + 3*a + b').subst('b=2')1707a^2+3*a+21708sage: maxima('a^2 + 3*a + b').subst('a=17')1709b+3401710sage: maxima('a^2 + 3*a + b').subst('a=17, b=2')17113421712"""1713return self.comma(val)17141715def comma(self, args):1716"""1717Form the expression that would be written 'self, args' in Maxima.17181719INPUT:17201721- ``args`` - string17221723OUTPUT: Maxima object17241725EXAMPLES::17261727sage: maxima('sqrt(2) + I').comma('numer')1728I+1.41421356237309...1729sage: maxima('sqrt(2) + I*a').comma('a=5')17305*I+sqrt(2)1731"""1732self._check_valid()1733P = self.parent()1734return P('%s, %s'%(self.name(), args))17351736def _latex_(self):1737"""1738Return Latex representation of this Maxima object.17391740INPUT: none17411742OUTPUT: string17431744This calls the tex command in Maxima, then does a little1745post-processing to fix bugs in the resulting Maxima output.17461747EXAMPLES::17481749sage: maxima('sqrt(2) + 1/3 + asin(5)')._latex_()1750'\\sin^{-1}\\cdot5+\\sqrt{2}+{{1}\\over{3}}'17511752sage: y,d = var('y,d')1753sage: f = function('f')1754sage: latex(maxima(derivative(f(x*y), x)))1755\left(\left.{{{\it \partial}}\over{{\it \partial}\,{\it t_0}}}\,f \left({\it t_0}\right)\right|_{\left[ {\it t_0}=x\,y \right] } \right)\,y1756sage: latex(maxima(derivative(f(x,y,d), d,x,x,y)))1757{{{\it \partial}^4}\over{{\it \partial}\,d\,{\it \partial}\,x^2\, {\it \partial}\,y}}\,f\left(x , y , d\right)1758sage: latex(maxima(d/(d-2)))1759{{d}\over{d-2}}1760"""1761self._check_valid()1762P = self.parent()1763s = P._eval_line('tex(%s);'%self.name(), reformat=False)1764if not '$$' in s:1765raise RuntimeError, "Error texing Maxima object."1766i = s.find('$$')1767j = s.rfind('$$')1768s = s[i+2:j]1769s = multiple_replace({'\r\n':' ',1770'\\%':'',1771'\\arcsin ':'\\sin^{-1} ',1772'\\arccos ':'\\cos^{-1} ',1773'\\arctan ':'\\tan^{-1} '}, s)17741775# Fix a maxima bug, which gives a latex representation of multiplying1776# two numbers as a single space. This was really bad when 2*17^(1/3)1777# gets TeXed as '2 17^{\frac{1}{3}}'1778#1779# This regex matches a string of spaces preceded by either a '}', a1780# decimal digit, or a ')', and followed by a decimal digit. The spaces1781# get replaced by a '\cdot'.1782s = re.sub(r'(?<=[})\d]) +(?=\d)', '\cdot', s)17831784return s17851786def trait_names(self, verbose=False):1787"""1788Return all Maxima commands, which is useful for tab completion.17891790INPUT:17911792- ``verbose`` - boolean17931794OUTPUT: list of strings17951796EXAMPLES::17971798sage: m = maxima(2)1799sage: 'gcd' in m.trait_names()1800True1801"""1802return self.parent().trait_names(verbose=False)18031804def _matrix_(self, R):1805r"""1806If self is a Maxima matrix, return the corresponding Sage matrix1807over the Sage ring `R`.18081809INPUT:18101811- ``R`` - ring to coerce into18121813OUTPUT: matrix18141815This may or may not work depending in how complicated the entries1816of self are! It only works if the entries of self can be coerced as1817strings to produce meaningful elements of `R`.18181819EXAMPLES::18201821sage: _ = maxima.eval("f[i,j] := i/j")1822sage: A = maxima('genmatrix(f,4,4)'); A1823matrix([1,1/2,1/3,1/4],[2,1,2/3,1/2],[3,3/2,1,3/4],[4,2,4/3,1])1824sage: A._matrix_(QQ)1825[ 1 1/2 1/3 1/4]1826[ 2 1 2/3 1/2]1827[ 3 3/2 1 3/4]1828[ 4 2 4/3 1]18291830You can also use the ``matrix`` command (which is1831defined in ``sage.misc.functional``)::18321833sage: matrix(QQ, A)1834[ 1 1/2 1/3 1/4]1835[ 2 1 2/3 1/2]1836[ 3 3/2 1 3/4]1837[ 4 2 4/3 1]1838"""1839from sage.matrix.all import MatrixSpace1840self._check_valid()1841P = self.parent()1842nrows = int(P.eval('length(%s)'%self.name()))1843if nrows == 0:1844return MatrixSpace(R, 0, 0)(0)1845ncols = int(P.eval('length(%s[1])'%self.name()))1846M = MatrixSpace(R, nrows, ncols)1847s = self.str().replace('matrix','').replace(',',"','").\1848replace("]','[","','").replace('([',"['").replace('])',"']")1849s = eval(s)1850return M([R(x) for x in s])18511852def partial_fraction_decomposition(self, var='x'):1853"""1854Return the partial fraction decomposition of self with respect to1855the variable var.18561857INPUT:18581859- ``var`` - string18601861OUTPUT: Maxima object18621863EXAMPLES::18641865sage: f = maxima('1/((1+x)*(x-1))')1866sage: f.partial_fraction_decomposition('x')18671/(2*(x-1))-1/(2*(x+1))1868sage: print f.partial_fraction_decomposition('x')18691 11870--------- - ---------18712 (x - 1) 2 (x + 1)1872"""1873return self.partfrac(var)18741875def _operation(self, operation, right):1876r"""1877Return the result of "self operation right" in Maxima.18781879INPUT:18801881- ``operation`` - string; operator18821883- ``right`` - Maxima object; right operand18841885OUTPUT: Maxima object18861887Note that right's parent should already be Maxima since this should1888be called after coercion has been performed.18891890If right is a ``MaximaFunction``, then we convert1891``self`` to a ``MaximaFunction`` that takes1892no arguments, and let the1893``MaximaFunction._operation`` code handle everything1894from there.18951896EXAMPLES::18971898sage: f = maxima.cos(x)1899sage: f._operation("+", f)19002*cos(x)1901"""1902P = self._check_valid()19031904if isinstance(right, P._object_function_class()):1905fself = P.function('', repr(self))1906return fself._operation(operation, right)19071908try:1909return P.new('%s %s %s'%(self._name, operation, right._name))1910except Exception, msg:1911raise TypeError, msg191219131914class MaximaAbstractFunctionElement(InterfaceFunctionElement):1915pass191619171918class MaximaAbstractFunction(InterfaceFunction):1919pass192019211922class MaximaAbstractElementFunction(MaximaAbstractElement):1923r"""1924Create a Maxima function with the parent ``parent``,1925name ``name``, definition ``defn``, arguments ``args``1926and latex representation ``latex``.19271928INPUT:19291930- ``parent`` - an instance of a concrete Maxima interface19311932- ``name`` - string19331934- ``defn`` - string19351936- ``args`` - string; comma separated names of arguments19371938- ``latex`` - string19391940OUTPUT: Maxima function19411942EXAMPLES::19431944sage: maxima.function('x,y','e^cos(x)')1945e^cos(x)1946"""19471948def __init__(self, parent, name, defn, args, latex):1949"""1950Create a Maxima function.1951See ``MaximaAbstractElementFunction`` for full documentation.19521953TESTS::19541955sage: from sage.interfaces.maxima_abstract import MaximaAbstractElementFunction1956sage: MaximaAbstractElementFunction == loads(dumps(MaximaAbstractElementFunction))1957True1958sage: f = maxima.function('x,y','sin(x+y)')1959sage: f == loads(dumps(f))1960True1961"""1962MaximaAbstractElement.__init__(self, parent, name, is_name=True)1963self.__defn = defn1964self.__args = args1965self.__latex = latex19661967def __reduce__(self):1968"""1969Implement __reduce__ for ``MaximaAbstractElementFunction``.19701971INPUT: none19721973OUTPUT:19741975A couple consisting of:19761977- the function to call for unpickling19781979- a tuple of arguments for the function19801981EXAMPLES::19821983sage: f = maxima.function('x,y','sin(x+y)')1984sage: f.__reduce__()1985(<function reduce_load_MaximaAbstract_function at 0x...>,1986(Maxima, 'sin(x+y)', 'x,y', None))1987"""1988return reduce_load_MaximaAbstract_function, (self.parent(),1989self.__defn, self.__args, self.__latex)19901991def __call__(self, *args):1992"""1993Return the result of calling this Maxima function1994with the given arguments.19951996INPUT:19971998- ``args`` - a variable number of arguments19992000OUTPUT: Maxima object20012002EXAMPLES::20032004sage: f = maxima.function('x,y','sin(x+y)')2005sage: f(1,2)2006sin(3)2007sage: f(x,x)2008sin(2*x)2009"""2010P = self._check_valid()2011if len(args) == 1:2012args = '(%s)'%args2013return P('%s%s'%(self.name(), args))20142015def __repr__(self):2016"""2017Return print representation of this Maxima function.20182019INPUT: none20202021OUTPUT: string20222023EXAMPLES::20242025sage: f = maxima.function('x,y','sin(x+y)')2026sage: repr(f)2027'sin(x+y)'2028"""2029return self.definition()20302031def _latex_(self):2032"""2033Return latex representation of this Maxima function.20342035INPUT: none20362037OUTPUT: string20382039EXAMPLES::20402041sage: f = maxima.function('x,y','sin(x+y)')2042sage: latex(f)2043\mathrm{sin(x+y)}2044"""2045if self.__latex is None:2046return r'\mathrm{%s}'%self.__defn2047else:2048return self.__latex20492050def arguments(self, split=True):2051r"""2052Returns the arguments of this Maxima function.20532054INPUT:20552056- ``split`` - boolean; if True return a tuple of strings,2057otherwise return a string of comma-separated arguments20582059OUTPUT:20602061- a string if ``split`` is False20622063- a list of strings if ``split`` is True20642065EXAMPLES::20662067sage: f = maxima.function('x,y','sin(x+y)')2068sage: f.arguments()2069['x', 'y']2070sage: f.arguments(split=False)2071'x,y'2072sage: f = maxima.function('', 'sin(x)')2073sage: f.arguments()2074[]2075"""2076if split:2077return self.__args.split(',') if self.__args != '' else []2078else:2079return self.__args20802081def definition(self):2082"""2083Returns the definition of this Maxima function as a string.20842085INPUT: none20862087OUTPUT: string20882089EXAMPLES::20902091sage: f = maxima.function('x,y','sin(x+y)')2092sage: f.definition()2093'sin(x+y)'2094"""2095return self.__defn20962097def integral(self, var):2098"""2099Returns the integral of self with respect to the variable var.21002101INPUT:21022103- ``var`` - a variable21042105OUTPUT: Maxima function21062107Note that integrate is an alias of integral.21082109EXAMPLES::21102111sage: x,y = var('x,y')2112sage: f = maxima.function('x','sin(x)')2113sage: f.integral(x)2114-cos(x)2115sage: f.integral(y)2116sin(x)*y2117"""2118var = str(var)2119P = self._check_valid()2120f = P('integrate(%s(%s), %s)'%(self.name(),2121self.arguments(split=False), var))21222123args = self.arguments()2124if var not in args:2125args.append(var)2126return P.function(",".join(args), repr(f))21272128integrate = integral21292130def _operation(self, operation, f=None):2131r"""2132This is a utility function which factors out much of the2133commonality used in the arithmetic operations for2134``MaximaAbstractElementFunction``.21352136INPUT:21372138- ``operation`` - A string representing the operation2139being performed. For example, '\*', or '1/'.21402141- ``f`` - The other operand. If f is2142``None``, then the operation is assumed to be unary2143rather than binary.21442145EXAMPLES::21462147sage: f = maxima.function('x,y','sin(x+y)')2148sage: f._operation("+", f)21492*sin(y+x)2150sage: f._operation("+", 2)2151sin(y+x)+22152sage: f._operation('-')2153-sin(y+x)2154sage: f._operation('1/')21551/sin(y+x)2156"""2157P = self._check_valid()2158if isinstance(f, P._object_function_class()):2159tmp = list(sorted(set(self.arguments() + f.arguments())))2160args = ','.join(tmp)2161defn = "(%s)%s(%s)"%(self.definition(), operation, f.definition())2162elif f is None:2163args = self.arguments(split=False)2164defn = "%s(%s)"%(operation, self.definition())2165else:2166args = self.arguments(split=False)2167defn = "(%s)%s(%s)"%(self.definition(), operation, repr(f))21682169return P.function(args,P.eval(defn))21702171def _add_(self, f):2172"""2173This Maxima function as left summand.21742175EXAMPLES::21762177sage: x,y = var('x,y')2178sage: f = maxima.function('x','sin(x)')2179sage: g = maxima.function('x','-cos(x)')2180sage: f+g2181sin(x)-cos(x)2182sage: f+32183sin(x)+321842185::21862187sage: (f+maxima.cos(x))(2)2188sin(2)+cos(2)2189sage: (f+maxima.cos(y)) # This is a function with only ONE argument!2190cos(y)+sin(x)2191sage: (f+maxima.cos(y))(2)2192cos(y)+sin(2)21932194::21952196sage: f = maxima.function('x','sin(x)')2197sage: g = -maxima.cos(x)2198sage: g+f2199sin(x)-cos(x)2200sage: (g+f)(2) # The sum IS a function2201sin(2)-cos(2)2202sage: 2+f2203sin(x)+22204"""2205return self._operation("+", f)22062207def _sub_(self, f):2208r"""2209This Maxima function as minuend.22102211EXAMPLES::22122213sage: x,y = var('x,y')2214sage: f = maxima.function('x','sin(x)')2215sage: g = -maxima.cos(x) # not a function2216sage: f-g2217sin(x)+cos(x)2218sage: (f-g)(2)2219sin(2)+cos(2)2220sage: (f-maxima.cos(y)) # This function only has the argument x!2221sin(x)-cos(y)2222sage: _(2)2223sin(2)-cos(y)22242225::22262227sage: g-f2228-sin(x)-cos(x)2229"""2230return self._operation("-", f)22312232def _mul_(self, f):2233r"""2234This Maxima function as left factor.22352236EXAMPLES::22372238sage: f = maxima.function('x','sin(x)')2239sage: g = maxima('-cos(x)') # not a function!2240sage: f*g2241-cos(x)*sin(x)2242sage: _(2)2243-cos(2)*sin(2)22442245::22462247sage: f = maxima.function('x','sin(x)')2248sage: g = maxima('-cos(x)')2249sage: g*f2250-cos(x)*sin(x)2251sage: _(2)2252-cos(2)*sin(2)2253sage: 2*f22542*sin(x)2255"""2256return self._operation("*", f)22572258def _div_(self, f):2259r"""2260This Maxima function as dividend.22612262EXAMPLES::22632264sage: f=maxima.function('x','sin(x)')2265sage: g=maxima('-cos(x)')2266sage: f/g2267-sin(x)/cos(x)2268sage: _(2)2269-sin(2)/cos(2)22702271::22722273sage: f=maxima.function('x','sin(x)')2274sage: g=maxima('-cos(x)')2275sage: g/f2276-cos(x)/sin(x)2277sage: _(2)2278-cos(2)/sin(2)2279sage: 2/f22802/sin(x)2281"""2282return self._operation("/", f)22832284def __neg__(self):2285r"""2286Additive inverse of this Maxima function.22872288EXAMPLES::22892290sage: f=maxima.function('x','sin(x)')2291sage: -f2292-sin(x)2293"""2294return self._operation('-')22952296def __inv__(self):2297r"""2298Multiplicative inverse of this Maxima function.22992300EXAMPLES::23012302sage: f = maxima.function('x','sin(x)')2303sage: ~f23041/sin(x)2305"""2306return self._operation('1/')23072308def __pow__(self,f):2309r"""2310This Maxima function raised to some power.23112312EXAMPLES::23132314sage: f=maxima.function('x','sin(x)')2315sage: g=maxima('-cos(x)')2316sage: f^g23171/sin(x)^cos(x)23182319::23202321sage: f=maxima.function('x','sin(x)')2322sage: g=maxima('-cos(x)') # not a function2323sage: g^f2324(-cos(x))^sin(x)2325"""2326return self._operation("^", f)232723282329def reduce_load_MaximaAbstract_function(parent, defn, args, latex):2330r"""2331Unpickle a Maxima function.23322333EXAMPLES::23342335sage: from sage.interfaces.maxima_abstract import reduce_load_MaximaAbstract_function2336sage: f = maxima.function('x,y','sin(x+y)')2337sage: _,args = f.__reduce__()2338sage: g = reduce_load_MaximaAbstract_function(*args)2339sage: g == f2340True2341"""2342return parent.function(args, defn, defn, latex)23432344def maxima_version():2345"""2346Return Maxima version.23472348Currently this calls a new copy of Maxima.23492350EXAMPLES::23512352sage: from sage.interfaces.maxima_abstract import maxima_version2353sage: maxima_version()2354'5.29.1'2355"""2356return os.popen('maxima --version').read().split()[-1]23572358def maxima_console():2359"""2360Spawn a new Maxima command-line session.23612362EXAMPLES::23632364sage: from sage.interfaces.maxima_abstract import maxima_console2365sage: maxima_console() # not tested2366Maxima 5.29.1 http://maxima.sourceforge.net2367...2368"""2369os.system('maxima')237023712372