Maxima is a free GPL’d general purpose computer algebra system
whose development started in 1968 at MIT. It contains symbolic
manipulation algorithms, as well as implementations of special
functions, including elliptic functions and generalized
hypergeometric functions. Moreover, Maxima has implementations of
many functions relating to the invariant theory of the symmetric
group . (However, the commands for group invariants,
and the corresponding Maxima documentation, are in French.) For many
links to Maxima documentation see
http://maxima.sourceforge.net/docs.shtml/.
AUTHORS:
This is the interface used by the maxima object:
sage: type(maxima)
<class 'sage.interfaces.maxima.Maxima'>
If the string “error” (case insensitive) occurs in the output of anything from Maxima, a RuntimeError exception is raised.
EXAMPLES: We evaluate a very simple expression in Maxima.
sage: maxima('3 * 5')
15
We factor in Maxima in several different ways.
The first way yields a Maxima object.
sage: F = maxima.factor('x^5 - y^5')
sage: F
-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
sage: type(F)
<class 'sage.interfaces.maxima.MaximaElement'>
Note that Maxima objects can also be displayed using “ASCII art”; to see a normal linear representation of any Maxima object x. Just use the print command: use str(x).
sage: print F
4 3 2 2 3 4
- (y - x) (y + x y + x y + x y + x )
You can always use repr(x) to obtain the linear representation of an object. This can be useful for moving maxima data to other systems.
sage: repr(F)
'-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
sage: F.str()
'-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
The maxima.eval command evaluates an expression in maxima and returns the result as a string not a maxima object.
sage: print maxima.eval('factor(x^5 - y^5)')
-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
We can create the polynomial as a Maxima polynomial,
then call the factor method on it. Notice that the notation
f.factor() is consistent with how the rest of Sage
works.
sage: f = maxima('x^5 - y^5')
sage: f^2
(x^5-y^5)^2
sage: f.factor()
-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
Control-C interruption works well with the maxima interface, because of the excellent implementation of maxima. For example, try the following sum but with a much bigger range, and hit control-C.
sage: maxima('sum(1/x^2, x, 1, 10)')
1968329/1270080
We follow the tutorial at http://maxima.sourceforge.net/docs/intromax/.
sage: maxima('1/100 + 1/101')
201/10100
sage: a = maxima('(1 + sqrt(2))^5'); a
(sqrt(2)+1)^5
sage: a.expand()
29*sqrt(2)+41
sage: a = maxima('(1 + sqrt(2))^5')
sage: float(a)
82.01219330881975
sage: a.numer()
82.01219330881975
sage: maxima.eval('fpprec : 100')
'100'
sage: a.bfloat()
8.20121933088197564152489730020812442785204843859314941221237124017312418754011041266612384955016056b1
sage: maxima('100!')
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
sage: f = maxima('(x + 3*y + x^2*y)^3')
sage: f.expand()
x^6*y^3+9*x^4*y^3+27*x^2*y^3+27*y^3+3*x^5*y^2+18*x^3*y^2+27*x*y^2+3*x^4*y+9*x^2*y+x^3
sage: f.subst('x=5/z')
(5/z+25*y/z^2+3*y)^3
sage: g = f.subst('x=5/z')
sage: h = g.ratsimp(); h
(27*y^3*z^6+135*y^2*z^5+(675*y^3+225*y)*z^4+(2250*y^2+125)*z^3+(5625*y^3+1875*y)*z^2+9375*y^2*z+15625*y^3)/z^6
sage: h.factor()
(3*y*z^2+5*z+25*y)^3/z^6
sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])
sage: s = eqn.solve('[a,b,c]'); s
[[a=(25*sqrt(79)*%i+25)/(6*sqrt(79)*%i-34),b=(5*sqrt(79)*%i+5)/(sqrt(79)*%i+11),c=(sqrt(79)*%i+1)/10],[a=(25*sqrt(79)*%i-25)/(6*sqrt(79)*%i+34),b=(5*sqrt(79)*%i-5)/(sqrt(79)*%i-11),c=-(sqrt(79)*%i-1)/10]]
Here is an example of solving an algebraic equation:
sage: maxima('x^2+y^2=1').solve('y')
[y=-sqrt(1-x^2),y=sqrt(1-x^2)]
sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y')
[y=-sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2),y=sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2)]
You can even nicely typeset the solution in latex:
sage: latex(s)
\left[ \left[ a={{25\,\sqrt{79}\,i+25}\over{6\,\sqrt{79}\,i-34}} , b={{5\,\sqrt{79}\,i+5}\over{\sqrt{79}\,i+11}} , c={{\sqrt{79}\,i+1 }\over{10}} \right] , \left[ a={{25\,\sqrt{79}\,i-25}\over{6\, \sqrt{79}\,i+34}} , b={{5\,\sqrt{79}\,i-5}\over{\sqrt{79}\,i-11}} , c=-{{\sqrt{79}\,i-1}\over{10}} \right] \right]
To have the above appear onscreen via xdvi, type view(s). (TODO: For OS X should create pdf output and use preview instead?)
sage: e = maxima('sin(u + v) * cos(u)^3'); e
cos(u)^3*sin(v+u)
sage: f = e.trigexpand(); f
cos(u)^3*(cos(u)*sin(v)+sin(u)*cos(v))
sage: f.trigreduce()
(sin(v+4*u)+sin(v-2*u))/8+(3*sin(v+2*u)+3*sin(v))/8
sage: w = maxima('3 + k*%i')
sage: f = w^2 + maxima('%e')^w
sage: f.realpart()
%e^3*cos(k)-k^2+9
sage: f = maxima('x^3 * %e^(k*x) * sin(w*x)'); f
x^3*%e^(k*x)*sin(w*x)
sage: f.diff('x')
k*x^3*%e^(k*x)*sin(w*x)+3*x^2*%e^(k*x)*sin(w*x)+w*x^3*%e^(k*x)*cos(w*x)
sage: f.integrate('x')
(((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3+(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+(-18*k*w^4-12*k^3*w^2+6*k^5)*x-6*w^4+36*k^2*w^2-6*k^4)*%e^(k*x)*sin(w*x)+((-w^7-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3+(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3+24*k^3*w)*%e^(k*x)*cos(w*x))/(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8)
sage: f = maxima('1/x^2')
sage: f.integrate('x', 1, 'inf')
1
sage: g = maxima('f/sinh(k*x)^4')
sage: g.taylor('x', 0, 3)
f/(k^4*x^4)-2*f/(3*k^2*x^2)+11*f/45-62*k^2*f*x^2/945
sage: maxima.taylor('asin(x)','x',0, 10)
x+x^3/6+3*x^5/40+5*x^7/112+35*x^9/1152
We illustrate computing with the matrix whose entry
is
, for
.
sage: f = maxima.eval('f[i,j] := i/j')
sage: A = maxima('genmatrix(f,4,4)'); A
matrix([1,1/2,1/3,1/4],[2,1,2/3,1/2],[3,3/2,1,3/4],[4,2,4/3,1])
sage: A.determinant()
0
sage: A.echelon()
matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0])
sage: A.eigenvalues()
[[0,4],[3,1]]
sage: A.eigenvectors()
[[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]]
We can also compute the echelon form in Sage:
sage: B = matrix(QQ, A)
sage: B.echelon_form()
[ 1 1/2 1/3 1/4]
[ 0 0 0 0]
[ 0 0 0 0]
[ 0 0 0 0]
sage: B.charpoly('x').factor()
(x - 4) * x^3
We illustrate Laplace transforms:
sage: _ = maxima.eval("f(t) := t*sin(t)")
sage: maxima("laplace(f(t),t,s)")
2*s/(s^2+1)^2
sage: maxima("laplace(delta(t-3),t,s)") #Dirac delta function
%e^-(3*s)
sage: _ = maxima.eval("f(t) := exp(t)*sin(t)")
sage: maxima("laplace(f(t),t,s)")
1/(s^2-2*s+2)
sage: _ = maxima.eval("f(t) := t^5*exp(t)*sin(t)")
sage: maxima("laplace(f(t),t,s)")
360*(2*s-2)/(s^2-2*s+2)^4-480*(2*s-2)^3/(s^2-2*s+2)^5+120*(2*s-2)^5/(s^2-2*s+2)^6
sage: print maxima("laplace(f(t),t,s)")
3 5
360 (2 s - 2) 480 (2 s - 2) 120 (2 s - 2)
--------------- - --------------- + ---------------
2 4 2 5 2 6
(s - 2 s + 2) (s - 2 s + 2) (s - 2 s + 2)
sage: maxima("laplace(diff(x(t),t),t,s)")
s*'laplace(x(t),t,s)-x(0)
sage: maxima("laplace(diff(x(t),t,2),t,s)")
-?%at('diff(x(t),t,1),t=0)+s^2*'laplace(x(t),t,s)-x(0)*s
It is difficult to read some of these without the 2d representation:
sage: print maxima("laplace(diff(x(t),t,2),t,s)")
!
d ! 2
- -- (x(t))! + s laplace(x(t), t, s) - x(0) s
dt !
!t = 0
Even better, use view(maxima("laplace(diff(x(t),t,2),t,s)")) to see a typeset version.
A continued fraction is
represented in maxima by the list
.
sage: maxima("cf((1 + sqrt(5))/2)")
[1,1,1,1,2]
sage: maxima("cf ((1 + sqrt(341))/2)")
[9,1,2,1,2,1,17,1,2,1,2,1,17,1,2,1,2,1,17,2]
In this section we illustrate calculations that would be awkward to do (as far as I know) in non-symbolic computer algebra systems like MAGMA or GAP.
We compute the gcd of and
for arbitrary
.
sage: f = maxima('2*x^(n+4) - x^(n+2)')
sage: g = maxima('4*x^(n+1) + 3*x^n')
sage: f.gcd(g)
x^n
You can plot 3d graphs (via gnuplot):
sage: maxima('plot3d(x^2-y^2, [x,-2,2], [y,-2,2], [grid,12,12])') # not tested
[displays a 3 dimensional graph]
You can formally evaluate sums (note the nusum command):
sage: S = maxima('nusum(exp(1+2*i/n),i,1,n)')
sage: print S
2/n + 3 2/n + 1
%e %e
----------------------- - -----------------------
1/n 1/n 1/n 1/n
(%e - 1) (%e + 1) (%e - 1) (%e + 1)
We formally compute the limit as of
as follows:
sage: T = S*maxima('2/n')
sage: T.tlimit('n','inf')
%e^3-%e
Obtaining digits of :
sage: maxima.eval('fpprec : 100')
'100'
sage: maxima(pi).bfloat()
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068b0
Defining functions in maxima:
sage: maxima.eval('fun[a] := a^2')
'fun[a]:=a^2'
sage: maxima('fun[10]')
100
Unfortunately maxima doesn’t seem to have a non-interactive mode, which is needed for the Sage interface. If any Sage call leads to maxima interactively answering questions, then the questions can’t be answered and the maxima session may hang. See the discussion at http://www.ma.utexas.edu/pipermail/maxima/2005/011061.html for some ideas about how to fix this problem. An example that illustrates this problem is maxima.eval('integrate (exp(a*x), x, 0, inf)').
To TeX a maxima object do this:
sage: latex(maxima('sin(u) + sinh(v^2)'))
\sinh v^2+\sin u
Here’s another example:
sage: g = maxima('exp(3*%i*x)/(6*%i) + exp(%i*x)/(2*%i) + c')
sage: latex(g)
-{{i\,e^{3\,i\,x}}\over{6}}-{{i\,e^{i\,x}}\over{2}}+c
The MAXIMA interface reads in even very long input (using files) in a robust manner, as long as you are creating a new object.
Note
Using maxima.eval for long input is much less robust, and is not recommended.
sage: t = '"%s"'%10^10000 # ten thousand character string.
sage: a = maxima(t)
TESTS: This working tests that a subtle bug has been fixed:
sage: f = maxima.function('x','gamma(x)')
sage: g = f(1/7)
sage: g
gamma(1/7)
sage: del f
sage: maxima(sin(x))
sin(x)
This tests to make sure we handle the case where Maxima asks if an expression is positive or zero.
sage: var('Ax,Bx,By')
(Ax, Bx, By)
sage: t = -Ax*sin(sqrt(Ax^2)/2)/(sqrt(Ax^2)*sqrt(By^2 + Bx^2))
sage: t.limit(Ax=0, dir='+')
0
A long complicated input expression:
sage: maxima._eval_line('((((((((((0) + ((1) / ((n0) ^ (0)))) + ((1) / ((n1) ^ (1)))) + ((1) / ((n2) ^ (2)))) + ((1) / ((n3) ^ (3)))) + ((1) / ((n4) ^ (4)))) + ((1) / ((n5) ^ (5)))) + ((1) / ((n6) ^ (6)))) + ((1) / ((n7) ^ (7)))) + ((1) / ((n8) ^ (8)))) + ((1) / ((n9) ^ (9)));')
'1/n9^9+1/n8^8+1/n7^7+1/n6^6+1/n5^5+1/n4^4+1/n3^3+1/n2^2+1/n1+1'
Bases: sage.interfaces.maxima_abstract.MaximaAbstract, sage.interfaces.expect.Expect
Interface to the Maxima interpreter.
EXAMPLES:
sage: m = Maxima()
sage: m == maxima
False
Clear the variable named var.
EXAMPLES:
sage: maxima.set('xxxxx', '2')
sage: maxima.get('xxxxx')
'2'
sage: maxima.clear('xxxxx')
sage: maxima.get('xxxxx')
'xxxxx'
Get the string value of the variable var.
EXAMPLES:
sage: maxima.set('xxxxx', '2')
sage: maxima.get('xxxxx')
'2'
Send a lisp command to Maxima.
Note
The output of this command is very raw - not pretty.
EXAMPLES:
sage: maxima.lisp("(+ 2 17)") # random formatted output
:lisp (+ 2 17)
19
(
Set the variable var to the given value.
INPUT:
EXAMPLES:
sage: maxima.set('xxxxx', '2')
sage: maxima.get('xxxxx')
'2'
Bases: sage.interfaces.maxima_abstract.MaximaAbstractElement, sage.interfaces.expect.ExpectElement
Element of Maxima through Pexpect interface.
EXAMPLES:
Elements of this class should not be created directly. The targeted parent should be used instead:
sage: maxima(3)
3
sage: maxima(cos(x)+e^234)
cos(x)+%e^234
Return the 2d string representation of this Maxima object.
EXAMPLES:
sage: F = maxima('x^5 - y^5').factor()
sage: F.display2d()
4 3 2 2 3 4
- (y - x) (y + x y + x y + x y + x )
Bases: sage.interfaces.maxima.MaximaElement, sage.interfaces.maxima_abstract.MaximaAbstractElementFunction
Maxima user-defined functions.
EXAMPLES:
Elements of this class should not be created directly. The method function of the targeted parent should be used instead:
sage: maxima.function('x,y','h(x)*y')
h(x)*y
Bases: sage.interfaces.maxima_abstract.MaximaAbstractFunction, sage.interfaces.expect.ExpectFunction
Bases: sage.interfaces.maxima_abstract.MaximaAbstractFunctionElement, sage.interfaces.expect.FunctionElement
Returns True if x is of type MaximaElement.
EXAMPLES:
sage: from sage.interfaces.maxima import is_MaximaElement
sage: m = maxima(1)
sage: is_MaximaElement(m)
True
sage: is_MaximaElement(1)
False
Unpickle a Maxima Pexpect interface.
EXAMPLES:
sage: from sage.interfaces.maxima import reduce_load_Maxima
sage: reduce_load_Maxima()
Maxima
Unpickle a Maxima function.
EXAMPLES:
sage: from sage.interfaces.maxima import reduce_load_Maxima_function
sage: f = maxima.function('x,y','sin(x+y)')
sage: _,args = f.__reduce__()
sage: g = reduce_load_Maxima_function(*args)
sage: g == f
True