Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/interfaces/maxima.py
4045 views
1
r"""
2
Pexpect interface to Maxima
3
4
Maxima is a free GPL'd general purpose computer algebra system
5
whose development started in 1968 at MIT. It contains symbolic
6
manipulation algorithms, as well as implementations of special
7
functions, including elliptic functions and generalized
8
hypergeometric functions. Moreover, Maxima has implementations of
9
many functions relating to the invariant theory of the symmetric
10
group `S_n`. (However, the commands for group invariants,
11
and the corresponding Maxima documentation, are in French.) For many
12
links to Maxima documentation see
13
http://maxima.sourceforge.net/docs.shtml/.
14
15
AUTHORS:
16
17
- William Stein (2005-12): Initial version
18
19
- David Joyner: Improved documentation
20
21
- William Stein (2006-01-08): Fixed bug in parsing
22
23
- William Stein (2006-02-22): comparisons (following suggestion of
24
David Joyner)
25
26
- William Stein (2006-02-24): *greatly* improved robustness by adding
27
sequence numbers to IO bracketing in _eval_line
28
29
- Robert Bradshaw, Nils Bruin, Jean-Pierre Flori (2010,2011): Binary library
30
interface
31
32
This is the interface used by the maxima object::
33
34
sage: type(maxima)
35
<class 'sage.interfaces.maxima.Maxima'>
36
37
If the string "error" (case insensitive) occurs in the output of
38
anything from Maxima, a RuntimeError exception is raised.
39
40
EXAMPLES: We evaluate a very simple expression in Maxima.
41
42
::
43
44
sage: maxima('3 * 5')
45
15
46
47
We factor `x^5 - y^5` in Maxima in several different ways.
48
The first way yields a Maxima object.
49
50
::
51
52
sage: F = maxima.factor('x^5 - y^5')
53
sage: F
54
-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
55
sage: type(F)
56
<class 'sage.interfaces.maxima.MaximaElement'>
57
58
Note that Maxima objects can also be displayed using "ASCII art";
59
to see a normal linear representation of any Maxima object x. Just
60
use the print command: use ``str(x)``.
61
62
::
63
64
sage: print F
65
4 3 2 2 3 4
66
- (y - x) (y + x y + x y + x y + x )
67
68
You can always use ``repr(x)`` to obtain the linear
69
representation of an object. This can be useful for moving maxima
70
data to other systems.
71
72
::
73
74
sage: repr(F)
75
'-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
76
sage: F.str()
77
'-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
78
79
The ``maxima.eval`` command evaluates an expression in
80
maxima and returns the result as a *string* not a maxima object.
81
82
::
83
84
sage: print maxima.eval('factor(x^5 - y^5)')
85
-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
86
87
We can create the polynomial `f` as a Maxima polynomial,
88
then call the factor method on it. Notice that the notation
89
``f.factor()`` is consistent with how the rest of Sage
90
works.
91
92
::
93
94
sage: f = maxima('x^5 - y^5')
95
sage: f^2
96
(x^5-y^5)^2
97
sage: f.factor()
98
-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
99
100
Control-C interruption works well with the maxima interface,
101
because of the excellent implementation of maxima. For example, try
102
the following sum but with a much bigger range, and hit control-C.
103
104
::
105
106
sage: maxima('sum(1/x^2, x, 1, 10)')
107
1968329/1270080
108
109
Tutorial
110
--------
111
112
We follow the tutorial at
113
http://maxima.sourceforge.net/docs/intromax/.
114
115
::
116
117
sage: maxima('1/100 + 1/101')
118
201/10100
119
120
::
121
122
sage: a = maxima('(1 + sqrt(2))^5'); a
123
(sqrt(2)+1)^5
124
sage: a.expand()
125
29*sqrt(2)+41
126
127
::
128
129
sage: a = maxima('(1 + sqrt(2))^5')
130
sage: float(a)
131
82.01219330881975
132
sage: a.numer()
133
82.01219330881975
134
135
::
136
137
sage: maxima.eval('fpprec : 100')
138
'100'
139
sage: a.bfloat()
140
8.20121933088197564152489730020812442785204843859314941221237124017312418754011041266612384955016056b1
141
142
::
143
144
sage: maxima('100!')
145
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
146
147
::
148
149
sage: f = maxima('(x + 3*y + x^2*y)^3')
150
sage: f.expand()
151
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
152
sage: f.subst('x=5/z')
153
(5/z+25*y/z^2+3*y)^3
154
sage: g = f.subst('x=5/z')
155
sage: h = g.ratsimp(); h
156
(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
157
sage: h.factor()
158
(3*y*z^2+5*z+25*y)^3/z^6
159
160
::
161
162
sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])
163
sage: s = eqn.solve('[a,b,c]'); s
164
[[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]]
165
166
Here is an example of solving an algebraic equation::
167
168
sage: maxima('x^2+y^2=1').solve('y')
169
[y=-sqrt(1-x^2),y=sqrt(1-x^2)]
170
sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y')
171
[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)]
172
173
You can even nicely typeset the solution in latex::
174
175
sage: latex(s)
176
\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]
177
178
To have the above appear onscreen via ``xdvi``, type
179
``view(s)``. (TODO: For OS X should create pdf output
180
and use preview instead?)
181
182
::
183
184
sage: e = maxima('sin(u + v) * cos(u)^3'); e
185
cos(u)^3*sin(v+u)
186
sage: f = e.trigexpand(); f
187
cos(u)^3*(cos(u)*sin(v)+sin(u)*cos(v))
188
sage: f.trigreduce()
189
(sin(v+4*u)+sin(v-2*u))/8+(3*sin(v+2*u)+3*sin(v))/8
190
sage: w = maxima('3 + k*%i')
191
sage: f = w^2 + maxima('%e')^w
192
sage: f.realpart()
193
%e^3*cos(k)-k^2+9
194
195
::
196
197
sage: f = maxima('x^3 * %e^(k*x) * sin(w*x)'); f
198
x^3*%e^(k*x)*sin(w*x)
199
sage: f.diff('x')
200
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)
201
sage: f.integrate('x')
202
(((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)
203
204
::
205
206
sage: f = maxima('1/x^2')
207
sage: f.integrate('x', 1, 'inf')
208
1
209
sage: g = maxima('f/sinh(k*x)^4')
210
sage: g.taylor('x', 0, 3)
211
f/(k^4*x^4)-2*f/(3*k^2*x^2)+11*f/45-62*k^2*f*x^2/945
212
213
::
214
215
sage: maxima.taylor('asin(x)','x',0, 10)
216
x+x^3/6+3*x^5/40+5*x^7/112+35*x^9/1152
217
218
Examples involving matrices
219
---------------------------
220
221
We illustrate computing with the matrix whose `i,j` entry
222
is `i/j`, for `i,j=1,\ldots,4`.
223
224
::
225
226
sage: f = maxima.eval('f[i,j] := i/j')
227
sage: A = maxima('genmatrix(f,4,4)'); A
228
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])
229
sage: A.determinant()
230
0
231
sage: A.echelon()
232
matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0])
233
sage: A.eigenvalues()
234
[[0,4],[3,1]]
235
sage: A.eigenvectors()
236
[[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]]
237
238
We can also compute the echelon form in Sage::
239
240
sage: B = matrix(QQ, A)
241
sage: B.echelon_form()
242
[ 1 1/2 1/3 1/4]
243
[ 0 0 0 0]
244
[ 0 0 0 0]
245
[ 0 0 0 0]
246
sage: B.charpoly('x').factor()
247
(x - 4) * x^3
248
249
Laplace Transforms
250
------------------
251
252
We illustrate Laplace transforms::
253
254
sage: _ = maxima.eval("f(t) := t*sin(t)")
255
sage: maxima("laplace(f(t),t,s)")
256
2*s/(s^2+1)^2
257
258
::
259
260
sage: maxima("laplace(delta(t-3),t,s)") #Dirac delta function
261
%e^-(3*s)
262
263
::
264
265
sage: _ = maxima.eval("f(t) := exp(t)*sin(t)")
266
sage: maxima("laplace(f(t),t,s)")
267
1/(s^2-2*s+2)
268
269
::
270
271
sage: _ = maxima.eval("f(t) := t^5*exp(t)*sin(t)")
272
sage: maxima("laplace(f(t),t,s)")
273
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
274
sage: print maxima("laplace(f(t),t,s)")
275
3 5
276
360 (2 s - 2) 480 (2 s - 2) 120 (2 s - 2)
277
--------------- - --------------- + ---------------
278
2 4 2 5 2 6
279
(s - 2 s + 2) (s - 2 s + 2) (s - 2 s + 2)
280
281
::
282
283
sage: maxima("laplace(diff(x(t),t),t,s)")
284
s*'laplace(x(t),t,s)-x(0)
285
286
::
287
288
sage: maxima("laplace(diff(x(t),t,2),t,s)")
289
-?%at('diff(x(t),t,1),t=0)+s^2*'laplace(x(t),t,s)-x(0)*s
290
291
It is difficult to read some of these without the 2d
292
representation::
293
294
sage: print maxima("laplace(diff(x(t),t,2),t,s)")
295
!
296
d ! 2
297
- -- (x(t))! + s laplace(x(t), t, s) - x(0) s
298
dt !
299
!t = 0
300
301
Even better, use
302
``view(maxima("laplace(diff(x(t),t,2),t,s)"))`` to see
303
a typeset version.
304
305
Continued Fractions
306
-------------------
307
308
A continued fraction `a + 1/(b + 1/(c + \cdots))` is
309
represented in maxima by the list `[a, b, c, \ldots]`.
310
311
::
312
313
sage: maxima("cf((1 + sqrt(5))/2)")
314
[1,1,1,1,2]
315
sage: maxima("cf ((1 + sqrt(341))/2)")
316
[9,1,2,1,2,1,17,1,2,1,2,1,17,1,2,1,2,1,17,2]
317
318
Special examples
319
----------------
320
321
In this section we illustrate calculations that would be awkward to
322
do (as far as I know) in non-symbolic computer algebra systems like
323
MAGMA or GAP.
324
325
We compute the gcd of `2x^{n+4} - x^{n+2}` and
326
`4x^{n+1} + 3x^n` for arbitrary `n`.
327
328
::
329
330
sage: f = maxima('2*x^(n+4) - x^(n+2)')
331
sage: g = maxima('4*x^(n+1) + 3*x^n')
332
sage: f.gcd(g)
333
x^n
334
335
You can plot 3d graphs (via gnuplot)::
336
337
sage: maxima('plot3d(x^2-y^2, [x,-2,2], [y,-2,2], [grid,12,12])') # not tested
338
[displays a 3 dimensional graph]
339
340
You can formally evaluate sums (note the ``nusum``
341
command)::
342
343
sage: S = maxima('nusum(exp(1+2*i/n),i,1,n)')
344
sage: print S
345
2/n + 3 2/n + 1
346
%e %e
347
----------------------- - -----------------------
348
1/n 1/n 1/n 1/n
349
(%e - 1) (%e + 1) (%e - 1) (%e + 1)
350
351
We formally compute the limit as `n\to\infty` of
352
`2S/n` as follows::
353
354
sage: T = S*maxima('2/n')
355
sage: T.tlimit('n','inf')
356
%e^3-%e
357
358
Miscellaneous
359
-------------
360
361
Obtaining digits of `\pi`::
362
363
sage: maxima.eval('fpprec : 100')
364
'100'
365
sage: maxima(pi).bfloat()
366
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068b0
367
368
Defining functions in maxima::
369
370
sage: maxima.eval('fun[a] := a^2')
371
'fun[a]:=a^2'
372
sage: maxima('fun[10]')
373
100
374
375
Interactivity
376
-------------
377
378
Unfortunately maxima doesn't seem to have a non-interactive mode,
379
which is needed for the Sage interface. If any Sage call leads to
380
maxima interactively answering questions, then the questions can't be
381
answered and the maxima session may hang. See the discussion at
382
http://www.ma.utexas.edu/pipermail/maxima/2005/011061.html for some
383
ideas about how to fix this problem. An example that illustrates this
384
problem is ``maxima.eval('integrate (exp(a*x), x, 0, inf)')``.
385
386
Latex Output
387
------------
388
389
To TeX a maxima object do this::
390
391
sage: latex(maxima('sin(u) + sinh(v^2)'))
392
\sinh v^2+\sin u
393
394
Here's another example::
395
396
sage: g = maxima('exp(3*%i*x)/(6*%i) + exp(%i*x)/(2*%i) + c')
397
sage: latex(g)
398
-{{i\,e^{3\,i\,x}}\over{6}}-{{i\,e^{i\,x}}\over{2}}+c
399
400
Long Input
401
----------
402
403
The MAXIMA interface reads in even very long input (using files) in
404
a robust manner, as long as you are creating a new object.
405
406
.. note::
407
408
Using ``maxima.eval`` for long input is much less robust, and is
409
not recommended.
410
411
::
412
413
sage: t = '"%s"'%10^10000 # ten thousand character string.
414
sage: a = maxima(t)
415
416
TESTS: This working tests that a subtle bug has been fixed::
417
418
sage: f = maxima.function('x','gamma(x)')
419
sage: g = f(1/7)
420
sage: g
421
gamma(1/7)
422
sage: del f
423
sage: maxima(sin(x))
424
sin(x)
425
426
This tests to make sure we handle the case where Maxima asks if an
427
expression is positive or zero.
428
429
::
430
431
sage: var('Ax,Bx,By')
432
(Ax, Bx, By)
433
sage: t = -Ax*sin(sqrt(Ax^2)/2)/(sqrt(Ax^2)*sqrt(By^2 + Bx^2))
434
sage: t.limit(Ax=0, dir='+')
435
0
436
437
A long complicated input expression::
438
439
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)));')
440
'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'
441
"""
442
443
#*****************************************************************************
444
# Copyright (C) 2005 William Stein <[email protected]>
445
#
446
# Distributed under the terms of the GNU General Public License (GPL)
447
#
448
# This code is distributed in the hope that it will be useful,
449
# but WITHOUT ANY WARRANTY; without even the implied warranty of
450
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
451
# General Public License for more details.
452
#
453
# The full text of the GPL is available at:
454
#
455
# http://www.gnu.org/licenses/
456
#*****************************************************************************
457
458
from __future__ import with_statement
459
460
import os, re
461
import pexpect
462
#cygwin = os.uname()[0][:6]=="CYGWIN"
463
464
from random import randrange
465
466
from sage.misc.misc import DOT_SAGE, SAGE_ROOT
467
468
##import sage.rings.all
469
470
from expect import (Expect, ExpectElement, FunctionElement,
471
ExpectFunction, gc_disabled, AsciiArtString)
472
473
from maxima_abstract import (MaximaAbstract, MaximaAbstractFunction,
474
MaximaAbstractElement,
475
MaximaAbstractFunctionElement,
476
MaximaAbstractElementFunction)
477
478
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
479
# this should work as expected
480
class Maxima(MaximaAbstract, Expect):
481
"""
482
Interface to the Maxima interpreter.
483
484
EXAMPLES::
485
486
sage: m = Maxima()
487
sage: m == maxima
488
False
489
"""
490
def __init__(self, script_subdirectory=None, logfile=None, server=None,
491
init_code = None):
492
"""
493
Create an instance of the Maxima interpreter.
494
495
TESTS::
496
497
sage: Maxima == loads(dumps(Maxima))
498
True
499
sage: maxima == loads(dumps(maxima))
500
True
501
502
Unpickling a Maxima Pexpect interface gives the default interface::
503
504
sage: m = Maxima()
505
sage: maxima == loads(dumps(m))
506
True
507
508
We make sure labels are turned off (see trac 6816)::
509
510
sage: 'nolabels : true' in maxima._Expect__init_code
511
True
512
"""
513
# TODO: Input and output prompts in maxima can be changed by
514
# setting inchar and outchar..
515
eval_using_file_cutoff = 256
516
self.__eval_using_file_cutoff = eval_using_file_cutoff
517
STARTUP = '%s/local/bin/sage-maxima.lisp'%SAGE_ROOT
518
519
# We set maxima's configuration directory to $DOT_SAGE/maxima
520
# This avoids that sage's maxima inadvertently loads
521
# ~/.maxima/maxima-init.mac
522
# If you absolutely want maxima instances that are started by
523
# this interface to preload commands, put them in
524
# $DOT_SAGE/maxima/maxima-init.mac
525
# (we use the "--userdir" option in maxima for this)
526
SAGE_MAXIMA_DIR = os.path.join(DOT_SAGE,"maxima")
527
528
if not os.path.exists(STARTUP):
529
raise RuntimeError, 'You must get the file local/bin/sage-maxima.lisp'
530
531
#self.__init_code = init_code
532
if init_code is None:
533
# display2d -- no ascii art output
534
# keepfloat -- don't automatically convert floats to rationals
535
init_code = ['display2d : false', 'keepfloat : true']
536
537
# Turn off the prompt labels, since computing them *very
538
# dramatically* slows down the maxima interpret after a while.
539
# See the function makelabel in suprv1.lisp.
540
# Many thanks to [email protected] and also
541
# Robert Dodier for figuring this out!
542
# See trac # 6818.
543
init_code.append('nolabels : true')
544
545
MaximaAbstract.__init__(self,"maxima")
546
Expect.__init__(self,
547
name = 'maxima',
548
prompt = '\(\%i[0-9]+\)',
549
command = 'maxima-noreadline --userdir="%s" -p "%s"'%(SAGE_MAXIMA_DIR,STARTUP),
550
maxread = 10000,
551
script_subdirectory = script_subdirectory,
552
restart_on_ctrlc = False,
553
verbose_start = False,
554
init_code = init_code,
555
logfile = logfile,
556
eval_using_file_cutoff=eval_using_file_cutoff)
557
self._display_prompt = '<sage-display>' # must match what is in the file local/bin/sage-maxima.lisp!!
558
self._output_prompt_re = re.compile('\(\%o[0-9]+\)')
559
self._ask = ['zero or nonzero?', 'an integer?', 'positive, negative, or zero?',
560
'positive or negative?', 'positive or zero?']
561
self._prompt_wait = [self._prompt] + [re.compile(x) for x in self._ask] + \
562
['Break [0-9]+'] #note that you might need to change _expect_expr if you
563
#change this
564
self._error_re = re.compile('(Principal Value|debugmode|incorrect syntax|Maxima encountered a Lisp error)')
565
self._display2d = False
566
567
568
569
def _start(self):
570
"""
571
Starts the Maxima interpreter.
572
573
EXAMPLES::
574
575
sage: m = Maxima()
576
sage: m.is_running()
577
False
578
sage: m._start()
579
sage: m.is_running()
580
True
581
582
Test that we can use more than 256MB RAM (see trac 6722):
583
584
sage: a = maxima(10)^(10^5)
585
sage: b = a^600 # long time -- about 10-15 seconds
586
587
"""
588
Expect._start(self)
589
self._sendline(r":lisp (defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\\partial)) l r lop rop ))")
590
591
# Remove limit on the max heapsize (since otherwise it defaults
592
# to 256MB with ECL).
593
self._sendline(":lisp (ext:set-limit 'ext:heap-size 0)")
594
self._eval_line('0;')
595
596
def __reduce__(self):
597
"""
598
Implementation of __reduce__ for ``Maxima``.
599
600
EXAMPLES::
601
602
sage: maxima.__reduce__()
603
(<function reduce_load_Maxima at 0x...>, ())
604
"""
605
return reduce_load_Maxima, tuple([]) #(self.__init_code,)
606
607
def _sendline(self, str):
608
"""
609
Send a string followed by a newline character.
610
611
EXAMPLES::
612
613
sage: maxima._sendline('t : 9;')
614
sage: maxima.get('t')
615
'9'
616
"""
617
self._sendstr(str)
618
os.write(self._expect.child_fd, os.linesep)
619
620
def _expect_expr(self, expr=None, timeout=None):
621
"""
622
Wait for a given expression expr (which could be a regular
623
expression or list of regular expressions) to appear in the output
624
for at most timeout seconds.
625
626
See `sage.interfaces.expect.Expect._expect_expr` for full details
627
on its use and functionality.
628
629
TESTS:
630
631
These tests indirectly show that the interface is working
632
and catching certain errors::
633
634
sage: maxima('2+2')
635
4
636
sage: maxima('integrate(1/(x^3*(a+b*x)^(1/3)),x)')
637
Traceback (most recent call last):
638
...
639
TypeError: Computation failed since Maxima requested additional
640
constraints (try the command "maxima.assume('a>0')"
641
before integral or limit evaluation, for example):
642
Is a positive or negative?
643
sage: maxima.assume('a>0')
644
[a>0]
645
sage: maxima('integrate(1/(x^3*(a+b*x)^(1/3)),x)')
646
-b^2*log((b*x+a)^(2/3)+a^(1/3)*(b*x+a)^(1/3)+a^(2/3))/(9*a^(7/3))+2*b^2*atan((2*(b*x+a)^(1/3)+a^(1/3))/(sqrt(3)*a^(1/3)))/(3^(3/2)*a^(7/3))+2*b^2*log((b*x+a)^(1/3)-a^(1/3))/(9*a^(7/3))+(4*b^2*(b*x+a)^(5/3)-7*a*b^2*(b*x+a)^(2/3))/(6*a^2*(b*x+a)^2-12*a^3*(b*x+a)+6*a^4)
647
sage: maxima('integrate(x^n,x)')
648
Traceback (most recent call last):
649
...
650
TypeError: Computation failed since Maxima requested additional
651
constraints (try the command "maxima.assume('n+1>0')" before
652
integral or limit evaluation, for example):
653
Is n+1 zero or nonzero?
654
sage: maxima.assume('n+1>0')
655
[n>-1]
656
sage: maxima('integrate(x^n,x)')
657
x^(n+1)/(n+1)
658
sage: maxima.forget([fact for fact in maxima.facts()])
659
[[a>0,n>-1]]
660
sage: maxima.facts()
661
[]
662
sage: var('a')
663
a
664
sage: maxima('limit(x^a,x,0)')
665
Traceback (most recent call last):
666
...
667
TypeError: Computation failed since Maxima requested additional
668
constraints (try the command "maxima.assume('a>0')" before
669
integral or limit evaluation, for example):
670
Is a positive, negative, or zero?
671
"""
672
if expr is None:
673
expr = self._prompt_wait
674
if self._expect is None:
675
self._start()
676
try:
677
if timeout:
678
i = self._expect.expect(expr,timeout=timeout)
679
else:
680
i = self._expect.expect(expr)
681
if i > 0:
682
v = self._expect.before
683
684
#We check to see if there is a "serious" error in Maxima.
685
#Note that this depends on the order of self._prompt_wait
686
if expr is self._prompt_wait and i > len(self._ask):
687
self.quit()
688
raise ValueError, "%s\nComputation failed due to a bug in Maxima -- NOTE: Maxima had to be restarted."%v
689
690
j = v.find('Is ')
691
v = v[j:]
692
k = v.find(' ',4)
693
msg = """Computation failed since Maxima requested additional constraints (try the command "maxima.assume('""" + v[4:k] +""">0')" before integral or limit evaluation, for example):\n""" + v + self._ask[i-1]
694
self._sendline(";")
695
self._expect_expr()
696
raise ValueError, msg
697
except KeyboardInterrupt, msg:
698
#print self._expect.before
699
i = 0
700
while True:
701
try:
702
print "Control-C pressed. Interrupting Maxima. Please wait a few seconds..."
703
self._sendstr('quit;\n'+chr(3))
704
self._sendstr('quit;\n'+chr(3))
705
self.interrupt()
706
self.interrupt()
707
except KeyboardInterrupt:
708
i += 1
709
if i > 10:
710
break
711
pass
712
else:
713
break
714
raise KeyboardInterrupt, msg
715
716
def _eval_line(self, line, allow_use_file=False,
717
wait_for_prompt=True, reformat=True, error_check=True, restart_if_needed=False):
718
"""
719
Return result of line evaluation.
720
721
EXAMPLES:
722
723
We check that errors are correctly checked::
724
725
sage: maxima._eval_line('1+1;')
726
'2'
727
sage: maxima._eval_line('sage0: x == x;')
728
Traceback (most recent call last):
729
...
730
TypeError: Error executing code in Maxima...
731
732
733
"""
734
if len(line) == 0:
735
return ''
736
line = line.rstrip()
737
if line[-1] != '$' and line[-1] != ';':
738
line += ';'
739
740
self._synchronize()
741
742
if len(line) > self.__eval_using_file_cutoff:
743
# This implicitly uses the set method, then displays
744
# the result of the thing that was set.
745
# This only works when the input line is an expression.
746
# But this is our only choice, since
747
# batchmode doesn't display expressions to screen.
748
a = self(line)
749
return repr(a)
750
else:
751
self._sendline(line)
752
753
line_echo = self._expect.readline()
754
if not wait_for_prompt:
755
return
756
assert line_echo.strip() == line.strip()
757
758
# This broke in maxima-5.22.1 as discussed in
759
# http://trac.sagemath.org/sage_trac/ticket/10187
760
#self._expect_expr(self._display_prompt)
761
#pre_out = self._before()
762
#self._expect_expr()
763
#out = self._before()
764
#
765
# if error_check:
766
# self._error_check(line, pre_out)
767
# self._error_check(line, out)
768
#
769
# if not reformat:
770
# return out
771
#
772
# r = self._output_prompt_re
773
# m = r.search(out)
774
# if m is None:
775
# o = out[:-2]
776
# else:
777
# o = out[m.end()+1:-2]
778
# o = ''.join([x.strip() for x in o.split()])
779
# return o
780
#
781
# i = o.rfind('(%o')
782
# return o[:i]
783
784
self._expect_expr(self._display_prompt)
785
out = self._before() # input echo + output prompt + output
786
if error_check:
787
self._error_check(line, out)
788
789
if not reformat:
790
return out
791
792
self._expect_expr()
793
assert len(self._before())==0, 'Maxima expect interface is confused!'
794
795
r = self._output_prompt_re
796
m = r.search(out)
797
if m is None:
798
o = out[:-2]
799
else:
800
o = out[m.end()+1:-2]
801
o = ''.join([x.strip() for x in o.split()])
802
return o
803
804
def _synchronize(self):
805
"""
806
Synchronize pexpect interface.
807
808
This put a random integer (plus one!) into the output stream, then
809
waits for it, thus resynchronizing the stream. If the random
810
integer doesn't appear within 1 second, maxima is sent interrupt
811
signals.
812
813
This way, even if you somehow left maxima in a busy state
814
computing, calling _synchronize gets everything fixed.
815
816
EXAMPLES: This makes Maxima start a calculation::
817
818
sage: maxima._sendstr('1/1'*500)
819
820
When you type this command, this synchronize command is implicitly
821
called, and the above running calculation is interrupted::
822
823
sage: maxima('2+2')
824
4
825
"""
826
marker = '__SAGE_SYNCHRO_MARKER_'
827
if self._expect is None: return
828
r = randrange(2147483647)
829
s = marker + str(r+1)
830
831
# The 0; *is* necessary... it comes up in certain rare cases
832
# that are revealed by extensive testing.
833
# Don't delete it. -- william stein
834
cmd = '''0;sconcat("%s",(%s+1));\n'''%(marker,r)
835
self._sendstr(cmd)
836
try:
837
try:
838
self._expect_expr(timeout=0.5)
839
if not s in self._before():
840
self._expect_expr(s,timeout=0.5)
841
self._expect_expr(timeout=0.5)
842
except pexpect.TIMEOUT:
843
# Don't call self._interrupt() here, as that might send multiple
844
# interrupts. On OS X 10.4, maxima takes a long time to
845
# process one interrupt (7.5 seconds on an idle system, but up
846
# to a minute on a loaded system) and gets confused by multiple
847
# interrupts. Instead, send just one interrupt and wait.
848
# See Trac #9361.
849
self._sendstr(chr(3))
850
self._expect_expr(timeout=120)
851
except pexpect.EOF:
852
self._crash_msg()
853
self.quit()
854
855
def _batch(self, s, batchload=True):
856
"""
857
Call Maxima's batch or batchload command with a file
858
containing the given string as argument.
859
860
EXAMPLES::
861
862
sage: maxima._batch('10003;')
863
'...batchload...'
864
sage: maxima._batch('10003;',batchload=False)
865
'...batch...10003...'
866
"""
867
filename = '%s-%s'%(self._local_tmpfile(),randrange(2147483647))
868
F = open(filename, 'w')
869
F.write(s)
870
F.close()
871
if self.is_remote():
872
self._send_tmpfile_to_server(local_file=filename)
873
tmp_to_use = self._remote_tmpfile()
874
tmp_to_use = filename
875
876
if batchload:
877
cmd = 'batchload("%s");'%tmp_to_use
878
else:
879
cmd = 'batch("%s");'%tmp_to_use
880
881
r = randrange(2147483647)
882
s = str(r+1)
883
cmd = "%s1+%s;\n"%(cmd,r)
884
885
self._sendline(cmd)
886
self._expect_expr(s)
887
out = self._before()
888
self._error_check(cmd, out)
889
os.unlink(filename)
890
return out
891
892
def _quit_string(self):
893
"""
894
Return string representation of quit command.
895
896
EXAMPLES::
897
898
sage: maxima._quit_string()
899
'quit();'
900
"""
901
return 'quit();'
902
903
def _crash_msg(self):
904
"""
905
Return string representation of crash message.
906
907
EXAMPLES::
908
909
sage: maxima._crash_msg()
910
Maxima crashed -- automatically restarting.
911
"""
912
print "Maxima crashed -- automatically restarting."
913
914
def _error_check(self, cmd, out):
915
"""
916
Check string for errors.
917
918
EXAMPLES::
919
920
sage: maxima._error_check("1+1;","Principal Value")
921
Traceback (most recent call last):
922
...
923
TypeError: Error executing code in Maxima
924
CODE:
925
1+1;
926
Maxima ERROR:
927
Principal Value
928
"""
929
r = self._error_re
930
m = r.search(out)
931
if not m is None:
932
self._error_msg(cmd, out)
933
934
def _error_msg(self, cmd, out):
935
"""
936
Raise error with formatted description.
937
938
EXAMPLES::
939
940
sage: maxima._error_msg("1+1;","Principal Value")
941
Traceback (most recent call last):
942
...
943
TypeError: Error executing code in Maxima
944
CODE:
945
1+1;
946
Maxima ERROR:
947
Principal Value
948
"""
949
raise TypeError, "Error executing code in Maxima\nCODE:\n\t%s\nMaxima ERROR:\n\t%s"%(cmd, out.replace('-- an error. To debug this try debugmode(true);',''))
950
951
###########################################
952
# Direct access to underlying lisp interpreter.
953
###########################################
954
def lisp(self, cmd):
955
"""
956
Send a lisp command to Maxima.
957
958
.. note::
959
960
The output of this command is very raw - not pretty.
961
962
EXAMPLES::
963
964
sage: maxima.lisp("(+ 2 17)") # random formatted output
965
:lisp (+ 2 17)
966
19
967
(
968
"""
969
self._eval_line(':lisp %s\n""'%cmd, allow_use_file=False,
970
wait_for_prompt=False, reformat=False, error_check=False)
971
self._expect_expr('(%i)')
972
return self._before()
973
974
#####
975
#
976
#####
977
978
def set(self, var, value):
979
"""
980
Set the variable var to the given value.
981
982
INPUT:
983
984
- ``var`` - string
985
986
- ``value`` - string
987
988
EXAMPLES::
989
990
sage: maxima.set('xxxxx', '2')
991
sage: maxima.get('xxxxx')
992
'2'
993
"""
994
if not isinstance(value, str):
995
raise TypeError
996
cmd = '%s : %s$'%(var, value.rstrip(';'))
997
if len(cmd) > self.__eval_using_file_cutoff:
998
self._batch(cmd, batchload=True)
999
else:
1000
self._eval_line(cmd)
1001
#self._sendline(cmd)
1002
#self._expect_expr()
1003
#out = self._before()
1004
#self._error_check(cmd, out)
1005
1006
def clear(self, var):
1007
"""
1008
Clear the variable named var.
1009
1010
EXAMPLES::
1011
1012
sage: maxima.set('xxxxx', '2')
1013
sage: maxima.get('xxxxx')
1014
'2'
1015
sage: maxima.clear('xxxxx')
1016
sage: maxima.get('xxxxx')
1017
'xxxxx'
1018
"""
1019
try:
1020
self._expect.send('kill(%s)$'%var)
1021
except (TypeError, AttributeError):
1022
pass
1023
1024
def get(self, var):
1025
"""
1026
Get the string value of the variable var.
1027
1028
EXAMPLES::
1029
1030
sage: maxima.set('xxxxx', '2')
1031
sage: maxima.get('xxxxx')
1032
'2'
1033
"""
1034
s = self._eval_line('%s;'%var)
1035
return s
1036
1037
def _function_class(self):
1038
"""
1039
Return the Python class of Maxima functions.
1040
1041
EXAMPLES::
1042
1043
sage: maxima._function_class()
1044
<class 'sage.interfaces.maxima.MaximaFunction'>
1045
"""
1046
return MaximaFunction
1047
1048
def _object_class(self):
1049
"""
1050
Return the Python class of Maxima elements.
1051
1052
EXAMPLES::
1053
1054
sage: maxima._object_class()
1055
<class 'sage.interfaces.maxima.MaximaElement'>
1056
"""
1057
return MaximaElement
1058
1059
def _function_element_class(self):
1060
"""
1061
Return the Python class of Maxima functions of elements.
1062
1063
EXAMPLES::
1064
1065
sage: maxima._function_element_class()
1066
<class 'sage.interfaces.maxima.MaximaFunctionElement'>
1067
"""
1068
return MaximaFunctionElement
1069
1070
def _object_function_class(self):
1071
"""
1072
Return the Python class of Maxima user-defined functions.
1073
1074
EXAMPLES::
1075
1076
sage: maxima._object_function_class()
1077
<class 'sage.interfaces.maxima.MaximaElementFunction'>
1078
"""
1079
return MaximaElementFunction
1080
1081
## some old helper functions to wrap the calculus use
1082
## of the Maxima interface. these routines expect arguments
1083
## living in the symbolic ring and return something
1084
## that is hopefully coercible into the symbolic ring again.
1085
##
1086
## def sr_integral(self,*args):
1087
## return args[0]._maxima_().integrate(*args[1:])
1088
##
1089
## def sr_sum(self,expression,v,a,b):
1090
## sum = "'sum(%s, %s, %s, %s)" % tuple([repr(expr._maxima_()) for expr in (expression, v, a, b)])
1091
## result = self.simplify_sum(sum)
1092
## result = result.ratsimp()
1093
## return expression.parent()(result)
1094
##
1095
## def sr_limit(self,ex,*args):
1096
## return ex._maxima_().limit(*args)
1097
##
1098
## def sr_tlimit(self,ex,*args):
1099
## return ex._maxima_().tlimit(*args)
1100
##
1101
1102
def is_MaximaElement(x):
1103
"""
1104
Returns True if x is of type MaximaElement.
1105
1106
EXAMPLES::
1107
1108
sage: from sage.interfaces.maxima import is_MaximaElement
1109
sage: m = maxima(1)
1110
sage: is_MaximaElement(m)
1111
True
1112
sage: is_MaximaElement(1)
1113
False
1114
"""
1115
return isinstance(x, MaximaElement)
1116
1117
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
1118
# this should work as expected
1119
class MaximaElement(MaximaAbstractElement, ExpectElement):
1120
"""
1121
Element of Maxima through Pexpect interface.
1122
1123
EXAMPLES:
1124
1125
Elements of this class should not be created directly.
1126
The targeted parent should be used instead::
1127
1128
sage: maxima(3)
1129
3
1130
sage: maxima(cos(x)+e^234)
1131
cos(x)+%e^234
1132
"""
1133
1134
def __init__(self, parent, value, is_name=False, name=None):
1135
"""
1136
Create a Maxima element.
1137
See ``MaximaElement`` for full documentation.
1138
1139
EXAMPLES::
1140
1141
sage: maxima(zeta(7))
1142
zeta(7)
1143
1144
TESTS::
1145
1146
sage: from sage.interfaces.maxima import MaximaElement
1147
sage: loads(dumps(MaximaElement))==MaximaElement
1148
True
1149
sage: a = maxima(5)
1150
sage: type(a)
1151
<class 'sage.interfaces.maxima.MaximaElement'>
1152
sage: loads(dumps(a))==a
1153
True
1154
"""
1155
ExpectElement.__init__(self, parent, value, is_name=False, name=None)
1156
1157
def display2d(self, onscreen=True):
1158
"""
1159
Return the 2d string representation of this Maxima object.
1160
1161
EXAMPLES::
1162
1163
sage: F = maxima('x^5 - y^5').factor()
1164
sage: F.display2d()
1165
4 3 2 2 3 4
1166
- (y - x) (y + x y + x y + x y + x )
1167
"""
1168
self._check_valid()
1169
P = self.parent()
1170
with gc_disabled():
1171
P._eval_line('display2d : true$')
1172
s = P._eval_line('disp(%s)$'%self.name(), reformat=False)
1173
P._eval_line('display2d : false$')
1174
s = s.strip('\r\n')
1175
1176
# if ever want to dedent, see
1177
# http://mail.python.org/pipermail/python-list/2006-December/420033.html
1178
if onscreen:
1179
print s
1180
else:
1181
return s
1182
1183
1184
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
1185
# this should work as expected
1186
class MaximaFunctionElement(MaximaAbstractFunctionElement, FunctionElement):
1187
pass
1188
# def __init__(self, obj, name):
1189
# MaximaAbstractFunctionElement.__init__(self, obj, name)
1190
# FunctionElement.__init__(self, obj, name)
1191
1192
1193
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
1194
# this should work as expected
1195
class MaximaFunction(MaximaAbstractFunction, ExpectFunction):
1196
pass
1197
# def __init__(self, parent, name):
1198
# MaximaAbstractFunction.__init__(self, parent, name)
1199
# ExpectFunction.__init__(self, parent, name)
1200
1201
1202
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
1203
# this should work as expected
1204
class MaximaElementFunction(MaximaElement, MaximaAbstractElementFunction):
1205
"""
1206
Maxima user-defined functions.
1207
1208
EXAMPLES:
1209
1210
Elements of this class should not be created directly.
1211
The method ``function`` of the targeted parent should be used instead::
1212
1213
sage: maxima.function('x,y','h(x)*y')
1214
h(x)*y
1215
"""
1216
1217
def __init__(self, parent, name, defn, args, latex):
1218
"""
1219
Create a Maxima function.
1220
See ``MaximaElementFunction`` for full documentation.
1221
1222
EXAMPLES::
1223
1224
sage: maxima.function('x,y','cos(x)+y')
1225
cos(x)+y
1226
1227
TESTS::
1228
1229
sage: f = maxima.function('x,y','x+y^9')
1230
sage: f == loads(dumps(f))
1231
True
1232
1233
Unpickling a Maxima Pexpect interface gives the default interface::
1234
1235
sage: m = Maxima()
1236
sage: g = m.function('x,y','x+y^9')
1237
sage: h = loads(dumps(g))
1238
sage: g.parent() == h.parent()
1239
False
1240
"""
1241
MaximaElement.__init__(self, parent, name, is_name=True)
1242
MaximaAbstractElementFunction.__init__(self, parent,
1243
name, defn, args, latex)
1244
1245
1246
# An instance
1247
maxima = Maxima(init_code = ['display2d : false',
1248
'domain : complex', 'keepfloat : true'],
1249
script_subdirectory=None)
1250
1251
1252
def reduce_load_Maxima(): #(init_code=None):
1253
"""
1254
Unpickle a Maxima Pexpect interface.
1255
1256
EXAMPLES::
1257
1258
sage: from sage.interfaces.maxima import reduce_load_Maxima
1259
sage: reduce_load_Maxima()
1260
Maxima
1261
"""
1262
return maxima #Maxima(init_code=init_code)
1263
1264
# This is defined for compatibility with the old Maxima interface.
1265
def reduce_load_Maxima_function(parent, defn, args, latex):
1266
"""
1267
Unpickle a Maxima function.
1268
1269
EXAMPLES::
1270
1271
sage: from sage.interfaces.maxima import reduce_load_Maxima_function
1272
sage: f = maxima.function('x,y','sin(x+y)')
1273
sage: _,args = f.__reduce__()
1274
sage: g = reduce_load_Maxima_function(*args)
1275
sage: g == f
1276
True
1277
"""
1278
return parent.function(args, defn, defn, latex)
1279
1280
def __doctest_cleanup():
1281
"""
1282
Kill all Pexpect interfaces.
1283
1284
EXAMPLES::
1285
1286
sage: from sage.interfaces.maxima import __doctest_cleanup
1287
sage: maxima(1)
1288
1
1289
sage: maxima.is_running()
1290
True
1291
sage: __doctest_cleanup()
1292
sage: maxima.is_running()
1293
False
1294
"""
1295
import sage.interfaces.quit
1296
sage.interfaces.quit.expect_quitall()
1297
1298