Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/interfaces/maxima.py
8814 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/documentation.html.
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/intromax.html.
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
import os, re
459
import pexpect
460
#cygwin = os.uname()[0][:6]=="CYGWIN"
461
462
from random import randrange
463
464
from sage.env import DOT_SAGE, SAGE_LOCAL
465
466
##import sage.rings.all
467
468
from expect import (Expect, ExpectElement, FunctionElement,
469
ExpectFunction, gc_disabled, AsciiArtString)
470
471
from maxima_abstract import (MaximaAbstract, MaximaAbstractFunction,
472
MaximaAbstractElement,
473
MaximaAbstractFunctionElement,
474
MaximaAbstractElementFunction)
475
476
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
477
# this should work as expected
478
class Maxima(MaximaAbstract, Expect):
479
"""
480
Interface to the Maxima interpreter.
481
482
EXAMPLES::
483
484
sage: m = Maxima()
485
sage: m == maxima
486
False
487
"""
488
def __init__(self, script_subdirectory=None, logfile=None, server=None,
489
init_code = None):
490
"""
491
Create an instance of the Maxima interpreter.
492
493
TESTS::
494
495
sage: Maxima == loads(dumps(Maxima))
496
True
497
sage: maxima == loads(dumps(maxima))
498
True
499
500
Unpickling a Maxima Pexpect interface gives the default interface::
501
502
sage: m = Maxima()
503
sage: maxima == loads(dumps(m))
504
True
505
506
We make sure labels are turned off (see trac 6816)::
507
508
sage: 'nolabels : true' in maxima._Expect__init_code
509
True
510
"""
511
# TODO: Input and output prompts in maxima can be changed by
512
# setting inchar and outchar..
513
eval_using_file_cutoff = 256
514
self.__eval_using_file_cutoff = eval_using_file_cutoff
515
STARTUP = os.path.join(SAGE_LOCAL,'bin','sage-maxima.lisp')
516
517
# We set maxima's configuration directory to $DOT_SAGE/maxima
518
# This avoids that sage's maxima inadvertently loads
519
# ~/.maxima/maxima-init.mac
520
# If you absolutely want maxima instances that are started by
521
# this interface to preload commands, put them in
522
# $DOT_SAGE/maxima/maxima-init.mac
523
# (we use the "--userdir" option in maxima for this)
524
SAGE_MAXIMA_DIR = os.path.join(DOT_SAGE,"maxima")
525
526
if not os.path.exists(STARTUP):
527
raise RuntimeError, 'You must get the file local/bin/sage-maxima.lisp'
528
529
#self.__init_code = init_code
530
if init_code is None:
531
# display2d -- no ascii art output
532
# keepfloat -- don't automatically convert floats to rationals
533
init_code = ['display2d : false', 'keepfloat : true']
534
535
# Turn off the prompt labels, since computing them *very
536
# dramatically* slows down the maxima interpret after a while.
537
# See the function makelabel in suprv1.lisp.
538
# Many thanks to [email protected] and also
539
# Robert Dodier for figuring this out!
540
# See trac # 6818.
541
init_code.append('nolabels : true')
542
543
MaximaAbstract.__init__(self,"maxima")
544
Expect.__init__(self,
545
name = 'maxima',
546
prompt = '\(\%i[0-9]+\) ',
547
command = 'maxima --userdir="%s" -p "%s"'%(SAGE_MAXIMA_DIR,STARTUP),
548
maxread = 10000,
549
script_subdirectory = script_subdirectory,
550
restart_on_ctrlc = False,
551
verbose_start = False,
552
init_code = init_code,
553
logfile = logfile,
554
eval_using_file_cutoff=eval_using_file_cutoff)
555
# Must match what is in the file local/bin/sage-maxima.lisp
556
self._display_prompt = '<sage-display>'
557
# See #15440 for the importance of the trailing space
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 :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
# Don't use ! for factorials (#11539)
592
self._sendline(":lisp (remprop 'mfactorial 'grind)")
593
594
# Remove limit on the max heapsize (since otherwise it defaults
595
# to 256MB with ECL).
596
self._sendline(":lisp (ext:set-limit 'ext:heap-size 0)")
597
self._eval_line('0;')
598
599
def __reduce__(self):
600
"""
601
Implementation of __reduce__ for ``Maxima``.
602
603
EXAMPLES::
604
605
sage: maxima.__reduce__()
606
(<function reduce_load_Maxima at 0x...>, ())
607
"""
608
return reduce_load_Maxima, tuple([]) #(self.__init_code,)
609
610
def _sendline(self, str):
611
"""
612
Send a string followed by a newline character.
613
614
EXAMPLES::
615
616
sage: maxima._sendline('t : 9;')
617
sage: maxima.get('t')
618
'9'
619
"""
620
self._sendstr(str)
621
os.write(self._expect.child_fd, os.linesep)
622
623
def _expect_expr(self, expr=None, timeout=None):
624
"""
625
Wait for a given expression expr (which could be a regular
626
expression or list of regular expressions) to appear in the output
627
for at most timeout seconds.
628
629
See `sage.interfaces.expect.Expect._expect_expr` for full details
630
on its use and functionality.
631
632
TESTS:
633
634
These tests indirectly show that the interface is working
635
and catching certain errors::
636
637
sage: maxima('2+2')
638
4
639
sage: maxima('integrate(1/(x^3*(a+b*x)^(1/3)),x)')
640
Traceback (most recent call last):
641
...
642
TypeError: Computation failed since Maxima requested additional
643
constraints (try the command "maxima.assume('a>0')"
644
before integral or limit evaluation, for example):
645
Is a positive or negative?
646
sage: maxima.assume('a>0')
647
[a>0]
648
sage: maxima('integrate(1/(x^3*(a+b*x)^(1/3)),x)')
649
-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)
650
sage: maxima('integrate(x^n,x)')
651
Traceback (most recent call last):
652
...
653
TypeError: Computation failed since Maxima requested additional
654
constraints (try the command "maxima.assume('n+1>0')" before
655
integral or limit evaluation, for example):
656
Is n+1 zero or nonzero?
657
sage: maxima.assume('n+1>0')
658
[n>-1]
659
sage: maxima('integrate(x^n,x)')
660
x^(n+1)/(n+1)
661
sage: maxima.forget([fact for fact in maxima.facts()])
662
[[a>0,n>-1]]
663
sage: maxima.facts()
664
[]
665
sage: var('a')
666
a
667
sage: maxima('limit(x^a,x,0)')
668
Traceback (most recent call last):
669
...
670
TypeError: Computation failed since Maxima requested additional
671
constraints (try the command "maxima.assume('a>0')" before
672
integral or limit evaluation, for example):
673
Is a positive, negative, or zero?
674
"""
675
if expr is None:
676
expr = self._prompt_wait
677
if self._expect is None:
678
self._start()
679
try:
680
if timeout:
681
i = self._expect.expect(expr,timeout=timeout)
682
else:
683
i = self._expect.expect(expr)
684
if i > 0:
685
v = self._expect.before
686
687
#We check to see if there is a "serious" error in Maxima.
688
#Note that this depends on the order of self._prompt_wait
689
if expr is self._prompt_wait and i > len(self._ask):
690
self.quit()
691
raise ValueError, "%s\nComputation failed due to a bug in Maxima -- NOTE: Maxima had to be restarted."%v
692
693
j = v.find('Is ')
694
v = v[j:]
695
k = v.find(' ',4)
696
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]
697
self._sendline(";")
698
self._expect_expr()
699
raise ValueError, msg
700
except KeyboardInterrupt, msg:
701
#print self._expect.before
702
i = 0
703
while True:
704
try:
705
print "Control-C pressed. Interrupting Maxima. Please wait a few seconds..."
706
self._sendstr('quit;\n'+chr(3))
707
self._sendstr('quit;\n'+chr(3))
708
self.interrupt()
709
self.interrupt()
710
except KeyboardInterrupt:
711
i += 1
712
if i > 10:
713
break
714
pass
715
else:
716
break
717
raise KeyboardInterrupt, msg
718
719
def _eval_line(self, line, allow_use_file=False,
720
wait_for_prompt=True, reformat=True, error_check=True, restart_if_needed=False):
721
"""
722
Return result of line evaluation.
723
724
EXAMPLES:
725
726
We check that errors are correctly checked::
727
728
sage: maxima._eval_line('1+1;')
729
'2'
730
sage: maxima._eval_line('sage0: x == x;')
731
Traceback (most recent call last):
732
...
733
TypeError: Error executing code in Maxima...
734
735
736
"""
737
if len(line) == 0:
738
return ''
739
line = line.rstrip()
740
if line[-1] != '$' and line[-1] != ';':
741
line += ';'
742
743
self._synchronize()
744
745
if len(line) > self.__eval_using_file_cutoff:
746
# This implicitly uses the set method, then displays
747
# the result of the thing that was set.
748
# This only works when the input line is an expression.
749
# But this is our only choice, since
750
# batchmode doesn't display expressions to screen.
751
a = self(line)
752
return repr(a)
753
else:
754
self._sendline(line)
755
756
line_echo = self._expect.readline()
757
if not wait_for_prompt:
758
return
759
assert line_echo.strip() == line.strip(), 'mismatch:\n' + line_echo + line
760
761
self._expect_expr(self._display_prompt)
762
out = self._before() # input echo + output prompt + output
763
if error_check:
764
self._error_check(line, out)
765
if not reformat:
766
return out
767
768
self._expect_expr()
769
assert len(self._before())==0, 'Maxima expect interface is confused!'
770
r = self._output_prompt_re
771
m = r.search(out)
772
if m is not None:
773
out = out[m.end():]
774
return re.sub('\s+', '', out)
775
776
def _synchronize(self):
777
"""
778
Synchronize pexpect interface.
779
780
This put a random integer (plus one!) into the output stream, then
781
waits for it, thus resynchronizing the stream. If the random
782
integer doesn't appear within 1 second, maxima is sent interrupt
783
signals.
784
785
This way, even if you somehow left maxima in a busy state
786
computing, calling _synchronize gets everything fixed.
787
788
EXAMPLES: This makes Maxima start a calculation::
789
790
sage: maxima._sendstr('1/1'*500)
791
792
When you type this command, this synchronize command is implicitly
793
called, and the above running calculation is interrupted::
794
795
sage: maxima('2+2')
796
4
797
"""
798
marker = '__SAGE_SYNCHRO_MARKER_'
799
if self._expect is None: return
800
r = randrange(2147483647)
801
s = marker + str(r+1)
802
803
# The 0; *is* necessary... it comes up in certain rare cases
804
# that are revealed by extensive testing.
805
# Don't delete it. -- william stein
806
cmd = '''0;sconcat("%s",(%s+1));\n'''%(marker,r)
807
self._sendstr(cmd)
808
try:
809
try:
810
self._expect_expr(timeout=0.5)
811
if not s in self._before():
812
self._expect_expr(s,timeout=0.5)
813
self._expect_expr(timeout=0.5)
814
except pexpect.TIMEOUT:
815
# Don't call self._interrupt() here, as that might send multiple
816
# interrupts. On OS X 10.4, maxima takes a long time to
817
# process one interrupt (7.5 seconds on an idle system, but up
818
# to a minute on a loaded system) and gets confused by multiple
819
# interrupts. Instead, send just one interrupt and wait.
820
# See Trac #9361.
821
self._sendstr(chr(3))
822
self._expect_expr(timeout=120)
823
except pexpect.EOF:
824
self._crash_msg()
825
self.quit()
826
827
def _batch(self, s, batchload=True):
828
"""
829
Call Maxima's batch or batchload command with a file
830
containing the given string as argument.
831
832
EXAMPLES::
833
834
sage: maxima._batch('10003;')
835
'...batchload...'
836
sage: maxima._batch('10003;',batchload=False)
837
'...batch...10003...'
838
"""
839
filename = '%s-%s'%(self._local_tmpfile(),randrange(2147483647))
840
F = open(filename, 'w')
841
F.write(s)
842
F.close()
843
if self.is_remote():
844
self._send_tmpfile_to_server(local_file=filename)
845
tmp_to_use = self._remote_tmpfile()
846
tmp_to_use = filename
847
848
if batchload:
849
cmd = 'batchload("%s");'%tmp_to_use
850
else:
851
cmd = 'batch("%s");'%tmp_to_use
852
853
r = randrange(2147483647)
854
s = str(r+1)
855
cmd = "%s1+%s;\n"%(cmd,r)
856
857
self._sendline(cmd)
858
self._expect_expr(s)
859
out = self._before()
860
self._error_check(cmd, out)
861
os.unlink(filename)
862
return out
863
864
def _quit_string(self):
865
"""
866
Return string representation of quit command.
867
868
EXAMPLES::
869
870
sage: maxima._quit_string()
871
'quit();'
872
"""
873
return 'quit();'
874
875
def _crash_msg(self):
876
"""
877
Return string representation of crash message.
878
879
EXAMPLES::
880
881
sage: maxima._crash_msg()
882
Maxima crashed -- automatically restarting.
883
"""
884
print "Maxima crashed -- automatically restarting."
885
886
def _error_check(self, cmd, out):
887
"""
888
Check string for errors.
889
890
EXAMPLES::
891
892
sage: maxima._error_check("1+1;","Principal Value")
893
Traceback (most recent call last):
894
...
895
TypeError: Error executing code in Maxima
896
CODE:
897
1+1;
898
Maxima ERROR:
899
Principal Value
900
"""
901
r = self._error_re
902
m = r.search(out)
903
if not m is None:
904
self._error_msg(cmd, out)
905
906
def _error_msg(self, cmd, out):
907
"""
908
Raise error with formatted description.
909
910
EXAMPLES::
911
912
sage: maxima._error_msg("1+1;","Principal Value")
913
Traceback (most recent call last):
914
...
915
TypeError: Error executing code in Maxima
916
CODE:
917
1+1;
918
Maxima ERROR:
919
Principal Value
920
"""
921
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);',''))
922
923
###########################################
924
# Direct access to underlying lisp interpreter.
925
###########################################
926
def lisp(self, cmd):
927
"""
928
Send a lisp command to Maxima.
929
930
.. note::
931
932
The output of this command is very raw - not pretty.
933
934
EXAMPLES::
935
936
sage: maxima.lisp("(+ 2 17)") # random formatted output
937
:lisp (+ 2 17)
938
19
939
(
940
"""
941
self._eval_line(':lisp %s\n""'%cmd, allow_use_file=False,
942
wait_for_prompt=False, reformat=False, error_check=False)
943
self._expect_expr('(%i)')
944
return self._before()
945
946
#####
947
#
948
#####
949
950
def set(self, var, value):
951
"""
952
Set the variable var to the given value.
953
954
INPUT:
955
956
- ``var`` - string
957
958
- ``value`` - string
959
960
EXAMPLES::
961
962
sage: maxima.set('xxxxx', '2')
963
sage: maxima.get('xxxxx')
964
'2'
965
"""
966
if not isinstance(value, str):
967
raise TypeError
968
cmd = '%s : %s$'%(var, value.rstrip(';'))
969
if len(cmd) > self.__eval_using_file_cutoff:
970
self._batch(cmd, batchload=True)
971
else:
972
self._eval_line(cmd)
973
#self._sendline(cmd)
974
#self._expect_expr()
975
#out = self._before()
976
#self._error_check(cmd, out)
977
978
def clear(self, var):
979
"""
980
Clear the variable named var.
981
982
EXAMPLES::
983
984
sage: maxima.set('xxxxx', '2')
985
sage: maxima.get('xxxxx')
986
'2'
987
sage: maxima.clear('xxxxx')
988
sage: maxima.get('xxxxx')
989
'xxxxx'
990
"""
991
try:
992
self._expect.send('kill(%s)$'%var)
993
except (TypeError, AttributeError):
994
pass
995
996
def get(self, var):
997
"""
998
Get the string value of the variable var.
999
1000
EXAMPLES::
1001
1002
sage: maxima.set('xxxxx', '2')
1003
sage: maxima.get('xxxxx')
1004
'2'
1005
"""
1006
s = self._eval_line('%s;'%var)
1007
return s
1008
1009
def _function_class(self):
1010
"""
1011
Return the Python class of Maxima functions.
1012
1013
EXAMPLES::
1014
1015
sage: maxima._function_class()
1016
<class 'sage.interfaces.maxima.MaximaFunction'>
1017
"""
1018
return MaximaFunction
1019
1020
def _object_class(self):
1021
"""
1022
Return the Python class of Maxima elements.
1023
1024
EXAMPLES::
1025
1026
sage: maxima._object_class()
1027
<class 'sage.interfaces.maxima.MaximaElement'>
1028
"""
1029
return MaximaElement
1030
1031
def _function_element_class(self):
1032
"""
1033
Return the Python class of Maxima functions of elements.
1034
1035
EXAMPLES::
1036
1037
sage: maxima._function_element_class()
1038
<class 'sage.interfaces.maxima.MaximaFunctionElement'>
1039
"""
1040
return MaximaFunctionElement
1041
1042
def _object_function_class(self):
1043
"""
1044
Return the Python class of Maxima user-defined functions.
1045
1046
EXAMPLES::
1047
1048
sage: maxima._object_function_class()
1049
<class 'sage.interfaces.maxima.MaximaElementFunction'>
1050
"""
1051
return MaximaElementFunction
1052
1053
## some old helper functions to wrap the calculus use
1054
## of the Maxima interface. these routines expect arguments
1055
## living in the symbolic ring and return something
1056
## that is hopefully coercible into the symbolic ring again.
1057
##
1058
## def sr_integral(self,*args):
1059
## return args[0]._maxima_().integrate(*args[1:])
1060
##
1061
## def sr_sum(self,expression,v,a,b):
1062
## sum = "'sum(%s, %s, %s, %s)" % tuple([repr(expr._maxima_()) for expr in (expression, v, a, b)])
1063
## result = self.simplify_sum(sum)
1064
## result = result.ratsimp()
1065
## return expression.parent()(result)
1066
##
1067
## def sr_limit(self,ex,*args):
1068
## return ex._maxima_().limit(*args)
1069
##
1070
## def sr_tlimit(self,ex,*args):
1071
## return ex._maxima_().tlimit(*args)
1072
##
1073
1074
def is_MaximaElement(x):
1075
"""
1076
Returns True if x is of type MaximaElement.
1077
1078
EXAMPLES::
1079
1080
sage: from sage.interfaces.maxima import is_MaximaElement
1081
sage: m = maxima(1)
1082
sage: is_MaximaElement(m)
1083
True
1084
sage: is_MaximaElement(1)
1085
False
1086
"""
1087
return isinstance(x, MaximaElement)
1088
1089
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
1090
# this should work as expected
1091
class MaximaElement(MaximaAbstractElement, ExpectElement):
1092
"""
1093
Element of Maxima through Pexpect interface.
1094
1095
EXAMPLES:
1096
1097
Elements of this class should not be created directly.
1098
The targeted parent should be used instead::
1099
1100
sage: maxima(3)
1101
3
1102
sage: maxima(cos(x)+e^234)
1103
cos(x)+%e^234
1104
"""
1105
1106
def __init__(self, parent, value, is_name=False, name=None):
1107
"""
1108
Create a Maxima element.
1109
See ``MaximaElement`` for full documentation.
1110
1111
EXAMPLES::
1112
1113
sage: maxima(zeta(7))
1114
zeta(7)
1115
1116
TESTS::
1117
1118
sage: from sage.interfaces.maxima import MaximaElement
1119
sage: loads(dumps(MaximaElement))==MaximaElement
1120
True
1121
sage: a = maxima(5)
1122
sage: type(a)
1123
<class 'sage.interfaces.maxima.MaximaElement'>
1124
sage: loads(dumps(a))==a
1125
True
1126
"""
1127
ExpectElement.__init__(self, parent, value, is_name=False, name=None)
1128
1129
def display2d(self, onscreen=True):
1130
"""
1131
Return the 2d string representation of this Maxima object.
1132
1133
EXAMPLES::
1134
1135
sage: F = maxima('x^5 - y^5').factor()
1136
sage: F.display2d()
1137
4 3 2 2 3 4
1138
- (y - x) (y + x y + x y + x y + x )
1139
"""
1140
self._check_valid()
1141
P = self.parent()
1142
with gc_disabled():
1143
P._eval_line('display2d : true$')
1144
s = P._eval_line('disp(%s)$'%self.name(), reformat=False)
1145
P._eval_line('display2d : false$')
1146
s = s.strip('\r\n')
1147
1148
# if ever want to dedent, see
1149
# http://mail.python.org/pipermail/python-list/2006-December/420033.html
1150
if onscreen:
1151
print s
1152
else:
1153
return s
1154
1155
1156
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
1157
# this should work as expected
1158
class MaximaFunctionElement(MaximaAbstractFunctionElement, FunctionElement):
1159
pass
1160
# def __init__(self, obj, name):
1161
# MaximaAbstractFunctionElement.__init__(self, obj, name)
1162
# FunctionElement.__init__(self, obj, name)
1163
1164
1165
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
1166
# this should work as expected
1167
class MaximaFunction(MaximaAbstractFunction, ExpectFunction):
1168
pass
1169
# def __init__(self, parent, name):
1170
# MaximaAbstractFunction.__init__(self, parent, name)
1171
# ExpectFunction.__init__(self, parent, name)
1172
1173
1174
# Thanks to the MRO for multiple inheritance used by the Sage's Python,
1175
# this should work as expected
1176
class MaximaElementFunction(MaximaElement, MaximaAbstractElementFunction):
1177
"""
1178
Maxima user-defined functions.
1179
1180
EXAMPLES:
1181
1182
Elements of this class should not be created directly.
1183
The method ``function`` of the targeted parent should be used instead::
1184
1185
sage: maxima.function('x,y','h(x)*y')
1186
h(x)*y
1187
"""
1188
1189
def __init__(self, parent, name, defn, args, latex):
1190
"""
1191
Create a Maxima function.
1192
See ``MaximaElementFunction`` for full documentation.
1193
1194
EXAMPLES::
1195
1196
sage: maxima.function('x,y','cos(x)+y')
1197
cos(x)+y
1198
1199
TESTS::
1200
1201
sage: f = maxima.function('x,y','x+y^9')
1202
sage: f == loads(dumps(f))
1203
True
1204
1205
Unpickling a Maxima Pexpect interface gives the default interface::
1206
1207
sage: m = Maxima()
1208
sage: g = m.function('x,y','x+y^9')
1209
sage: h = loads(dumps(g))
1210
sage: g.parent() == h.parent()
1211
False
1212
"""
1213
MaximaElement.__init__(self, parent, name, is_name=True)
1214
MaximaAbstractElementFunction.__init__(self, parent,
1215
name, defn, args, latex)
1216
1217
1218
# An instance
1219
maxima = Maxima(init_code = ['display2d : false',
1220
'domain : complex', 'keepfloat : true'],
1221
script_subdirectory=None)
1222
1223
1224
def reduce_load_Maxima(): #(init_code=None):
1225
"""
1226
Unpickle a Maxima Pexpect interface.
1227
1228
EXAMPLES::
1229
1230
sage: from sage.interfaces.maxima import reduce_load_Maxima
1231
sage: reduce_load_Maxima()
1232
Maxima
1233
"""
1234
return maxima #Maxima(init_code=init_code)
1235
1236
# This is defined for compatibility with the old Maxima interface.
1237
def reduce_load_Maxima_function(parent, defn, args, latex):
1238
"""
1239
Unpickle a Maxima function.
1240
1241
EXAMPLES::
1242
1243
sage: from sage.interfaces.maxima import reduce_load_Maxima_function
1244
sage: f = maxima.function('x,y','sin(x+y)')
1245
sage: _,args = f.__reduce__()
1246
sage: g = reduce_load_Maxima_function(*args)
1247
sage: g == f
1248
True
1249
"""
1250
return parent.function(args, defn, defn, latex)
1251
1252
def __doctest_cleanup():
1253
"""
1254
Kill all Pexpect interfaces.
1255
1256
EXAMPLES::
1257
1258
sage: from sage.interfaces.maxima import __doctest_cleanup
1259
sage: maxima(1)
1260
1
1261
sage: maxima.is_running()
1262
True
1263
sage: __doctest_cleanup()
1264
sage: maxima.is_running()
1265
False
1266
"""
1267
import sage.interfaces.quit
1268
sage.interfaces.quit.expect_quitall()
1269
1270