Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/interfaces/maxima_abstract.py
4054 views
1
r"""
2
Abstract 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 an abstract class implementing the functions shared between the Pexpect
33
and library interfaces to Maxima.
34
"""
35
36
#*****************************************************************************
37
# Copyright (C) 2005 William Stein <[email protected]>
38
#
39
# Distributed under the terms of the GNU General Public License (GPL)
40
#
41
# This code is distributed in the hope that it will be useful,
42
# but WITHOUT ANY WARRANTY; without even the implied warranty of
43
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44
# General Public License for more details.
45
#
46
# The full text of the GPL is available at:
47
#
48
# http://www.gnu.org/licenses/
49
#*****************************************************************************
50
51
import os, re, sys, subprocess
52
53
from sage.misc.misc import DOT_SAGE
54
COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE
55
56
from sage.misc.multireplace import multiple_replace
57
58
import sage.server.support
59
60
##import sage.rings.all
61
62
from interface import (Interface, InterfaceElement, InterfaceFunctionElement,
63
InterfaceFunction, AsciiArtString)
64
65
# The Maxima "apropos" command, e.g., apropos(det) gives a list
66
# of all identifiers that begin in a certain way. This could
67
# maybe be useful somehow... (?) Also maxima has a lot for getting
68
# documentation from the system -- this could also be useful.
69
70
class MaximaAbstract(Interface):
71
r"""
72
Abstract interface to Maxima.
73
74
INPUT:
75
76
- ``name`` - string
77
78
OUTPUT: the interface
79
80
EXAMPLES:
81
82
This class should not be instantiated directly,
83
but through its subclasses Maxima (Pexpect interface)
84
or MaximaLib (library interface)::
85
86
sage: m = Maxima()
87
sage: from sage.interfaces.maxima_abstract import MaximaAbstract
88
sage: isinstance(m,MaximaAbstract)
89
True
90
"""
91
92
def __init__(self, name='maxima_abstract'):
93
r"""
94
Create an instance of an abstract interface to Maxima.
95
See ``MaximaAbstract`` for full documentation.
96
97
EXAMPLES::
98
99
sage: from sage.interfaces.maxima_abstract import MaximaAbstract
100
sage: isinstance(maxima,MaximaAbstract)
101
True
102
103
TESTS::
104
105
sage: from sage.interfaces.maxima_abstract import MaximaAbstract
106
sage: loads(dumps(MaximaAbstract)) == MaximaAbstract
107
True
108
"""
109
Interface.__init__(self,name)
110
111
###########################################
112
# System -- change directory, etc
113
###########################################
114
def chdir(self, dir):
115
r"""
116
Change Maxima's current working directory.
117
118
INPUT:
119
120
- ``dir`` - string
121
122
OUTPUT: none
123
124
EXAMPLES::
125
126
sage: maxima.chdir('/')
127
"""
128
self.lisp('(ext::cd "%s")'%dir)
129
130
###########################################
131
# Interactive help
132
###########################################
133
def _command_runner(self, command, s, redirect=True):
134
r"""
135
Run ``command`` in a new Maxima session and return its
136
output as an ``AsciiArtString``.
137
138
INPUT:
139
140
- ``command`` - string; function to call
141
142
- ``s`` - string; argument to the function
143
144
- ``redirect`` - boolean (default: True); if redirect is set to False,
145
then the output of the command is not returned as a string.
146
Instead, it behaves like os.system. This is used for interactive
147
things like Maxima's demos. See maxima.demo?
148
149
OUTPUT:
150
151
Output of ``command(s)`` as an ``AsciiArtString`` if ``redirect`` is set
152
to False; None otherwise.
153
154
EXAMPLES::
155
156
sage: maxima._command_runner('describe', 'gcd')
157
-- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
158
...
159
"""
160
cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s)
161
if sage.server.support.EMBEDDED_MODE:
162
cmd += '< /dev/null'
163
164
if redirect:
165
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
166
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
167
res = p.stdout.read()
168
# ecl-10.2 : 3 lines
169
# ecl-10.4 : 5 lines
170
# ecl-11.1 : 4 lines fancy a tango?
171
# We now get 4 lines of commented verbosity
172
# every time Maxima starts, so we need to get rid of them
173
for _ in range(4):
174
res = res[res.find('\n')+1:]
175
return AsciiArtString(res)
176
else:
177
subprocess.Popen(cmd, shell=True)
178
179
def help(self, s):
180
r"""
181
Return Maxima's help for ``s``.
182
183
INPUT:
184
185
- ``s`` - string
186
187
OUTPUT:
188
189
Maxima's help for ``s``
190
191
EXAMPLES::
192
193
sage: maxima.help('gcd')
194
-- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
195
...
196
"""
197
# Should this be implemented without launching a new Maxima session
198
# i.e. using eval_line ?
199
return self._command_runner("describe", s)
200
201
def example(self, s):
202
r"""
203
Return Maxima's examples for ``s``.
204
205
INPUT:
206
207
- ``s`` - string
208
209
OUTPUT:
210
211
Maxima's examples for ``s``
212
213
EXAMPLES::
214
215
sage: maxima.example('arrays')
216
a[n]:=n*a[n-1]
217
a := n a
218
n n - 1
219
a[0]:1
220
a[5]
221
120
222
a[n]:=n
223
a[6]
224
6
225
a[4]
226
24
227
done
228
"""
229
# Should this be implemented without launching a new Maxima session
230
# i.e. using eval_line ?
231
return self._command_runner("example", s)
232
233
describe = help
234
235
def demo(self, s):
236
r"""
237
Run Maxima's demo for ``s``.
238
239
INPUT:
240
241
- ``s`` - string
242
243
OUTPUT: none
244
245
EXAMPLES::
246
247
sage: maxima.demo('array') # not tested
248
batching /opt/sage/local/share/maxima/5.16.3/demo/array.dem
249
250
At the _ prompt, type ';' followed by enter to get next demo
251
subscrmap : true _
252
"""
253
# Should this be implemented without launching a new Maxima session
254
# i.e. using eval_line ?
255
return self._command_runner("demo", s, redirect=False)
256
257
def completions(self, s, verbose=True):
258
r"""
259
Return all commands that complete the command starting with the
260
string ``s``. This is like typing s[tab] in the Maxima interpreter.
261
262
INPUT:
263
264
- ``s`` - string
265
266
- ``verbose`` - boolean (default: True)
267
268
OUTPUT: array of strings
269
270
EXAMPLES::
271
272
sage: sorted(maxima.completions('gc', verbose=False))
273
['gcd', 'gcdex', 'gcfactor', 'gcprint', 'gctime']
274
"""
275
if verbose:
276
print s,
277
sys.stdout.flush()
278
# in Maxima 5.19.1, apropos returns all commands that contain
279
# the given string, instead of all commands that start with
280
# the given string
281
cmd_list = self._eval_line('apropos("%s")'%s, error_check=False).replace('\\ - ','-')
282
cmd_list = [x for x in cmd_list[1:-1].split(',') if x[0] != '?']
283
return [x for x in cmd_list if x.find(s) == 0]
284
285
def _commands(self, verbose=True):
286
"""
287
Return list of all commands defined in Maxima.
288
289
INPUT:
290
291
- ``verbose`` - boolean (default: True)
292
293
OUTPUT: array of strings
294
295
EXAMPLES::
296
297
# The output is kind of random
298
sage: sorted(maxima._commands(verbose=False))
299
[...
300
'display',
301
...
302
'gcd',
303
...
304
'verbose',
305
...]
306
"""
307
try:
308
return self.__commands
309
except AttributeError:
310
self.__commands = sum(
311
[self.completions(chr(65+n), verbose=verbose)+
312
self.completions(chr(97+n), verbose=verbose)
313
for n in range(26)], [])
314
return self.__commands
315
316
def trait_names(self, verbose=True, use_disk_cache=True):
317
r"""
318
Return all Maxima commands, which is useful for tab completion.
319
320
INPUT:
321
322
- ``verbose`` - boolean (default: True)
323
324
- ``use_disk_cache`` - boolean (default: True); if set to True,
325
try to read cached result from disk
326
327
OUTPUT: array of strings
328
329
EXAMPLES::
330
331
sage: t = maxima.trait_names(verbose=False)
332
sage: 'gcd' in t
333
True
334
sage: len(t) # random output
335
1840
336
"""
337
try:
338
return self.__trait_names
339
except AttributeError:
340
import sage.misc.persist
341
if use_disk_cache:
342
try:
343
self.__trait_names = sage.misc.persist.load(COMMANDS_CACHE)
344
return self.__trait_names
345
except IOError:
346
pass
347
if verbose:
348
print "\nBuilding Maxima command completion list (this takes"
349
print "a few seconds only the first time you do it)."
350
print "To force rebuild later, delete %s."%COMMANDS_CACHE
351
v = self._commands(verbose=verbose)
352
if verbose:
353
print "\nDone!"
354
self.__trait_names = v
355
sage.misc.persist.save(v, COMMANDS_CACHE)
356
return v
357
358
def console(self):
359
r"""
360
Start the interactive Maxima console. This is a completely separate
361
maxima session from this interface. To interact with this session,
362
you should instead use ``maxima.interact()``.
363
364
INPUT: none
365
366
OUTPUT: none
367
368
EXAMPLES::
369
370
sage: maxima.console() # not tested (since we can't)
371
Maxima 5.13.0 http://maxima.sourceforge.net
372
Using Lisp CLISP 2.41 (2006-10-13)
373
Distributed under the GNU Public License. See the file COPYING.
374
Dedicated to the memory of William Schelter.
375
This is a development version of Maxima. The function bug_report()
376
provides bug reporting information.
377
(%i1)
378
379
::
380
381
sage: maxima.interact() # this is not tested either
382
--> Switching to Maxima <--
383
maxima: 2+2
384
4
385
maxima:
386
--> Exiting back to Sage <--
387
"""
388
maxima_console()
389
390
def cputime(self, t=None):
391
r"""
392
Returns the amount of CPU time that this Maxima session has used.
393
394
INPUT:
395
396
- ``t`` - float (default: None); If \var{t} is not None, then
397
it returns the difference between the current CPU time and \var{t}.
398
399
OUTPUT: float
400
401
EXAMPLES:
402
sage: t = maxima.cputime()
403
sage: _ = maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1])
404
sage: maxima.cputime(t) # output random
405
0.568913
406
"""
407
if t:
408
return float(self.eval('elapsed_run_time()')) - t
409
else:
410
return float(self.eval('elapsed_run_time()'))
411
412
def version(self):
413
r"""
414
Return the version of Maxima that Sage includes.
415
416
INPUT: none
417
418
OUTPUT: none
419
420
EXAMPLES::
421
422
sage: maxima.version()
423
'5.26.0'
424
"""
425
return maxima_version()
426
427
####
428
# Overriding default values
429
###
430
431
def _assign_symbol(self):
432
r"""
433
Return the assign symbol in Maxima.
434
435
INPUT: none
436
437
OUTPUT: string
438
439
EXAMPLES::
440
441
sage: maxima._assign_symbol()
442
':'
443
sage: maxima.eval('t : 8')
444
'8'
445
sage: maxima.eval('t')
446
'8'
447
"""
448
return ":"
449
450
def _true_symbol(self):
451
"""
452
Return the true symbol in Maxima.
453
454
INPUT: none
455
456
OUTPUT: string
457
458
EXAMPLES::
459
460
sage: maxima._true_symbol()
461
'true'
462
sage: maxima.eval('is(2 = 2)')
463
'true'
464
"""
465
return 'true'
466
467
def _false_symbol(self):
468
"""
469
Return the false symbol in Maxima.
470
471
INPUT: none
472
473
OUTPUT: string
474
475
EXAMPLES::
476
477
sage: maxima._false_symbol()
478
'false'
479
sage: maxima.eval('is(2 = 4)')
480
'false'
481
"""
482
return 'false'
483
484
def _equality_symbol(self):
485
"""
486
Returns the equality symbol in Maxima.
487
488
INPUT: none
489
490
OUTPUT: string
491
492
EXAMPLES::
493
494
sage: maxima._equality_symbol()
495
'='
496
sage: var('x y')
497
(x, y)
498
sage: maxima(x == y)
499
x=y
500
"""
501
return '='
502
503
def _inequality_symbol(self):
504
"""
505
Returns the inequality symbol in Maxima.
506
507
INPUT: none
508
509
OUTPUT: string
510
511
EXAMPLES::
512
513
sage: maxima._inequality_symbol()
514
'#'
515
sage: maxima((x != 1))
516
x#1
517
"""
518
return '#'
519
520
def _function_class(self):
521
"""
522
Return the Python class of Maxima functions.
523
524
INPUT: none
525
526
OUTPUT: type
527
528
EXAMPLES::
529
530
sage: maxima._function_class()
531
<class 'sage.interfaces.maxima.MaximaFunction'>
532
"""
533
return MaximaAbstractFunction
534
535
def _object_class(self):
536
"""
537
Return the Python class of Maxima elements.
538
539
INPUT: none
540
541
OUTPUT: type
542
543
EXAMPLES::
544
545
sage: maxima._object_class()
546
<class 'sage.interfaces.maxima.MaximaElement'>
547
"""
548
return MaximaAbstractElement
549
550
def _function_element_class(self):
551
"""
552
Return the Python class of Maxima functions of elements.
553
554
INPUT: none
555
556
OUTPUT: type
557
558
EXAMPLES::
559
560
sage: maxima._function_element_class()
561
<class 'sage.interfaces.maxima.MaximaFunctionElement'>
562
"""
563
return MaximaAbstractFunctionElement
564
565
def _object_function_class(self):
566
"""
567
Return the Python class of Maxima user-defined functions.
568
569
INPUT: none
570
571
OUTPUT: type
572
573
EXAMPLES::
574
575
sage: maxima._object_function_class()
576
<class 'sage.interfaces.maxima.MaximaElementFunction'>
577
"""
578
return MaximaAbstractElementFunction
579
580
####################
581
# Maxima functions #
582
####################
583
584
def function(self, args, defn, rep=None, latex=None):
585
"""
586
Return the Maxima function with given arguments and definition.
587
588
INPUT:
589
590
- ``args`` - a string with variable names separated by
591
commas
592
593
- ``defn`` - a string (or Maxima expression) that
594
defines a function of the arguments in Maxima.
595
596
- ``rep`` - an optional string; if given, this is how
597
the function will print.
598
599
OUTPUT: Maxima function
600
601
EXAMPLES::
602
603
sage: f = maxima.function('x', 'sin(x)')
604
sage: f(3.2)
605
-.058374143427580...
606
sage: f = maxima.function('x,y', 'sin(x)+cos(y)')
607
sage: f(2,3.5)
608
sin(2)-.9364566872907963
609
sage: f
610
sin(x)+cos(y)
611
612
::
613
614
sage: g = f.integrate('z')
615
sage: g
616
(cos(y)+sin(x))*z
617
sage: g(1,2,3)
618
3*(cos(2)+sin(1))
619
620
The function definition can be a Maxima object::
621
622
sage: an_expr = maxima('sin(x)*gamma(x)')
623
sage: t = maxima.function('x', an_expr)
624
sage: t
625
gamma(x)*sin(x)
626
sage: t(2)
627
sin(2)
628
sage: float(t(2))
629
0.9092974268256817
630
sage: loads(t.dumps())
631
gamma(x)*sin(x)
632
"""
633
name = self._next_var_name()
634
if isinstance(defn, MaximaAbstractElement):
635
defn = defn.str()
636
elif not isinstance(defn, str):
637
defn = str(defn)
638
if isinstance(args, MaximaAbstractElement):
639
args = args.str()
640
elif not isinstance(args, str):
641
args = str(args)
642
cmd = '%s(%s) := %s'%(name, args, defn)
643
self._eval_line(cmd)
644
if rep is None:
645
rep = defn
646
f = self._object_function_class()(self, name, rep, args, latex)
647
return f
648
649
## def display2d(self, flag=True):
650
## """
651
## Set the flag that determines whether Maxima objects are
652
## printed using their 2-d ASCII art representation. When the
653
## maxima interface starts the default is that objects are not
654
## represented in 2-d.
655
656
## INPUT:
657
## flag -- bool (default: True)
658
659
## EXAMPLES
660
## sage: maxima('1/2')
661
## 1/2
662
## sage: maxima.display2d(True)
663
## sage: maxima('1/2')
664
## 1
665
## -
666
## 2
667
## sage: maxima.display2d(False)
668
## """
669
## self._display2d = bool(flag)
670
671
def plot2d(self, *args):
672
r"""
673
Plot a 2d graph using Maxima / gnuplot.
674
675
maxima.plot2d(f, '[var, min, max]', options)
676
677
INPUT:
678
679
- ``f`` - a string representing a function (such as
680
f="sin(x)") [var, xmin, xmax]
681
682
- ``options`` - an optional string representing plot2d
683
options in gnuplot format
684
685
EXAMPLES::
686
687
sage: maxima.plot2d('sin(x)','[x,-5,5]') # not tested
688
sage: opts = '[gnuplot_term, ps], [gnuplot_out_file, "sin-plot.eps"]'
689
sage: maxima.plot2d('sin(x)','[x,-5,5]',opts) # not tested
690
691
The eps file is saved in the current directory.
692
"""
693
self('plot2d(%s)'%(','.join([str(x) for x in args])))
694
695
def plot2d_parametric(self, r, var, trange, nticks=50, options=None):
696
r"""
697
Plot r = [x(t), y(t)] for t = tmin...tmax using gnuplot with
698
options.
699
700
INPUT:
701
702
- ``r`` - a string representing a function (such as
703
r="[x(t),y(t)]")
704
705
- ``var`` - a string representing the variable (such
706
as var = "t")
707
708
- ``trange`` - [tmin, tmax] are numbers with tmintmax
709
710
- ``nticks`` - int (default: 50)
711
712
- ``options`` - an optional string representing plot2d
713
options in gnuplot format
714
715
EXAMPLES::
716
717
sage: maxima.plot2d_parametric(["sin(t)","cos(t)"], "t",[-3.1,3.1]) # not tested
718
719
::
720
721
sage: opts = '[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "circle-plot.eps"]'
722
sage: maxima.plot2d_parametric(["sin(t)","cos(t)"], "t", [-3.1,3.1], options=opts) # not tested
723
724
The eps file is saved to the current working directory.
725
726
Here is another fun plot::
727
728
sage: maxima.plot2d_parametric(["sin(5*t)","cos(11*t)"], "t", [0,2*pi()], nticks=400) # not tested
729
"""
730
tmin = trange[0]
731
tmax = trange[1]
732
cmd = "plot2d([parametric, %s, %s, [%s, %s, %s], [nticks, %s]]"%( \
733
r[0], r[1], var, tmin, tmax, nticks)
734
if options is None:
735
cmd += ")"
736
else:
737
cmd += ", %s)"%options
738
self(cmd)
739
740
def plot3d(self, *args):
741
r"""
742
Plot a 3d graph using Maxima / gnuplot.
743
744
maxima.plot3d(f, '[x, xmin, xmax]', '[y, ymin, ymax]', '[grid, nx,
745
ny]', options)
746
747
INPUT:
748
749
- ``f`` - a string representing a function (such as
750
f="sin(x)") [var, min, max]
751
752
- ``args`` should be of the form '[x, xmin, xmax]', '[y, ymin, ymax]',
753
'[grid, nx, ny]', options
754
755
EXAMPLES::
756
757
sage: maxima.plot3d('1 + x^3 - y^2', '[x,-2,2]', '[y,-2,2]', '[grid,12,12]') # not tested
758
sage: maxima.plot3d('sin(x)*cos(y)', '[x,-2,2]', '[y,-2,2]', '[grid,30,30]') # not tested
759
sage: opts = '[gnuplot_term, ps], [gnuplot_out_file, "sin-plot.eps"]'
760
sage: maxima.plot3d('sin(x+y)', '[x,-5,5]', '[y,-1,1]', opts) # not tested
761
762
The eps file is saved in the current working directory.
763
"""
764
self('plot3d(%s)'%(','.join([str(x) for x in args])))
765
766
def plot3d_parametric(self, r, vars, urange, vrange, options=None):
767
r"""
768
Plot a 3d parametric graph with r=(x,y,z), x = x(u,v), y = y(u,v),
769
z = z(u,v), for u = umin...umax, v = vmin...vmax using gnuplot with
770
options.
771
772
INPUT:
773
774
- ``x, y, z`` - a string representing a function (such
775
as ``x="u2+v2"``, ...) vars is a list or two strings
776
representing variables (such as vars = ["u","v"])
777
778
- ``urange`` - [umin, umax]
779
780
- ``vrange`` - [vmin, vmax] are lists of numbers with
781
umin umax, vmin vmax
782
783
- ``options`` - optional string representing plot2d
784
options in gnuplot format
785
786
OUTPUT: displays a plot on screen or saves to a file
787
788
EXAMPLES::
789
790
sage: maxima.plot3d_parametric(["v*sin(u)","v*cos(u)","v"], ["u","v"],[-3.2,3.2],[0,3]) # not tested
791
sage: opts = '[gnuplot_term, ps], [gnuplot_out_file, "sin-cos-plot.eps"]'
792
sage: maxima.plot3d_parametric(["v*sin(u)","v*cos(u)","v"], ["u","v"],[-3.2,3.2],[0,3],opts) # not tested
793
794
The eps file is saved in the current working directory.
795
796
Here is a torus::
797
798
sage: _ = 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);") # optional
799
sage: maxima.plot3d_parametric(["expr_1","expr_2","expr_3"], ["x","y"],[0,6],[0,6]) # not tested
800
801
Here is a Mobius strip::
802
803
sage: x = "cos(u)*(3 + v*cos(u/2))"
804
sage: y = "sin(u)*(3 + v*cos(u/2))"
805
sage: z = "v*sin(u/2)"
806
sage: maxima.plot3d_parametric([x,y,z],["u","v"],[-3.1,3.2],[-1/10,1/10]) # not tested
807
"""
808
umin = urange[0]
809
umax = urange[1]
810
vmin = vrange[0]
811
vmax = vrange[1]
812
cmd = 'plot3d([%s, %s, %s], [%s, %s, %s], [%s, %s, %s]'%(
813
r[0], r[1], r[2], vars[0], umin, umax, vars[1], vmin, vmax)
814
if options is None:
815
cmd += ')'
816
else:
817
cmd += ', %s)'%options
818
self(cmd)
819
820
def de_solve(self, de, vars, ics=None):
821
"""
822
Solves a 1st or 2nd order ordinary differential equation (ODE) in
823
two variables, possibly with initial conditions.
824
825
INPUT:
826
827
- ``de`` - a string representing the ODE
828
829
- ``vars`` - a list of strings representing the two
830
variables.
831
832
- ``ics`` - a triple of numbers [a,b1,b2] representing
833
y(a)=b1, y'(a)=b2
834
835
EXAMPLES::
836
837
sage: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1])
838
y=3*x-2*%e^(x-1)
839
sage: maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'])
840
y=%k1*%e^x+%k2*%e^-x+3*x
841
sage: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'])
842
y=(%c-3*(-x-1)*%e^-x)*%e^x
843
sage: maxima.de_solve('diff(y,x) + 3*x = y', ['x','y'],[1,1])
844
y=-%e^-1*(5*%e^x-3*%e*x-3*%e)
845
"""
846
if not isinstance(vars, str):
847
str_vars = '%s, %s'%(vars[1], vars[0])
848
else:
849
str_vars = vars
850
self.eval('depends(%s)'%str_vars)
851
m = self(de)
852
a = 'ode2(%s, %s)'%(m.name(), str_vars)
853
if ics != None:
854
if len(ics) == 3:
855
cmd = "ic2("+a+",%s=%s,%s=%s,diff(%s,%s)=%s);"%(vars[0],ics[0], vars[1],ics[1], vars[1], vars[0], ics[2])
856
return self(cmd)
857
if len(ics) == 2:
858
return self("ic1("+a+",%s=%s,%s=%s);"%(vars[0],ics[0], vars[1],ics[1]))
859
return self(a+";")
860
861
def de_solve_laplace(self, de, vars, ics=None):
862
"""
863
Solves an ordinary differential equation (ODE) using Laplace
864
transforms.
865
866
INPUT:
867
868
- ``de`` - a string representing the ODE (e.g., de =
869
"diff(f(x),x,2)=diff(f(x),x)+sin(x)")
870
871
- ``vars`` - a list of strings representing the
872
variables (e.g., vars = ["x","f"])
873
874
- ``ics`` - a list of numbers representing initial
875
conditions, with symbols allowed which are represented by strings
876
(eg, f(0)=1, f'(0)=2 is ics = [0,1,2])
877
878
EXAMPLES::
879
880
sage: maxima.clear('x'); maxima.clear('f')
881
sage: maxima.de_solve_laplace("diff(f(x),x,2) = 2*diff(f(x),x)-f(x)", ["x","f"], [0,1,2])
882
f(x)=x*%e^x+%e^x
883
884
::
885
886
sage: maxima.clear('x'); maxima.clear('f')
887
sage: f = maxima.de_solve_laplace("diff(f(x),x,2) = 2*diff(f(x),x)-f(x)", ["x","f"])
888
sage: f
889
f(x)=x*%e^x*('at('diff(f(x),x,1),x=0))-f(0)*x*%e^x+f(0)*%e^x
890
sage: print f
891
!
892
x d ! x x
893
f(x) = x %e (-- (f(x))! ) - f(0) x %e + f(0) %e
894
dx !
895
!x = 0
896
897
.. note::
898
899
The second equation sets the values of `f(0)` and
900
`f'(0)` in Maxima, so subsequent ODEs involving these
901
variables will have these initial conditions automatically
902
imposed.
903
"""
904
if not (ics is None):
905
d = len(ics)
906
for i in range(0,d-1):
907
ic = 'atvalue(diff(%s(%s), %s, %s), %s = %s, %s)'%(
908
vars[1], vars[0], vars[0], i, vars[0], ics[0], ics[1+i])
909
self.eval(ic)
910
return self('desolve(%s, %s(%s))'%(de, vars[1], vars[0]))
911
912
def solve_linear(self, eqns,vars):
913
"""
914
Wraps maxima's linsolve.
915
916
INPUT:
917
918
- ``eqns`` - a list of m strings; each representing a linear
919
question in m = n variables
920
921
- ``vars`` - a list of n strings; each
922
representing a variable
923
924
EXAMPLES::
925
926
sage: eqns = ["x + z = y","2*a*x - y = 2*a^2","y - 2*z = 2"]
927
sage: vars = ["x","y","z"]
928
sage: maxima.solve_linear(eqns, vars)
929
[x=a+1,y=2*a,z=a-1]
930
"""
931
eqs = "["
932
for i in range(len(eqns)):
933
if i<len(eqns)-1:
934
eqs = eqs + eqns[i]+","
935
if i==len(eqns)-1:
936
eqs = eqs + eqns[i]+"]"
937
vrs = "["
938
for i in range(len(vars)):
939
if i<len(vars)-1:
940
vrs = vrs + vars[i]+","
941
if i==len(vars)-1:
942
vrs = vrs + vars[i]+"]"
943
return self('linsolve(%s, %s)'%(eqs, vrs))
944
945
def unit_quadratic_integer(self, n):
946
r"""
947
Finds a unit of the ring of integers of the quadratic number field
948
`\QQ(\sqrt{n})`, `n>1`, using the qunit maxima command.
949
950
INPUT:
951
952
- ``n`` - an integer
953
954
EXAMPLES::
955
956
sage: u = maxima.unit_quadratic_integer(101); u
957
a + 10
958
sage: u.parent()
959
Number Field in a with defining polynomial x^2 - 101
960
sage: u = maxima.unit_quadratic_integer(13)
961
sage: u
962
5*a + 18
963
sage: u.parent()
964
Number Field in a with defining polynomial x^2 - 13
965
"""
966
from sage.rings.all import QuadraticField, Integer
967
# Take square-free part so sqrt(n) doesn't get simplified
968
# further by maxima
969
# (The original version of this function would yield wrong answers if
970
# n is not squarefree.)
971
n = Integer(n).squarefree_part()
972
if n < 1:
973
raise ValueError, "n (=%s) must be >= 1"%n
974
s = repr(self('qunit(%s)'%n)).lower()
975
r = re.compile('sqrt\(.*\)')
976
s = r.sub('a', s)
977
a = QuadraticField(n, 'a').gen()
978
return eval(s)
979
980
def plot_list(self, ptsx, ptsy, options=None):
981
r"""
982
Plots a curve determined by a sequence of points.
983
984
INPUT:
985
986
- ``ptsx`` - [x1,...,xn], where the xi and yi are
987
real,
988
989
- ``ptsy`` - [y1,...,yn]
990
991
- ``options`` - a string representing maxima plot2d
992
options.
993
994
The points are (x1,y1), (x2,y2), etc.
995
996
This function requires maxima 5.9.2 or newer.
997
998
.. note::
999
1000
More that 150 points can sometimes lead to the program
1001
hanging. Why?
1002
1003
EXAMPLES::
1004
1005
sage: zeta_ptsx = [ (pari(1/2 + i*I/10).zeta().real()).precision(1) for i in range (70,150)]
1006
sage: zeta_ptsy = [ (pari(1/2 + i*I/10).zeta().imag()).precision(1) for i in range (70,150)]
1007
sage: maxima.plot_list(zeta_ptsx, zeta_ptsy) # not tested
1008
sage: opts='[gnuplot_preamble, "set nokey"], [gnuplot_term, ps], [gnuplot_out_file, "zeta.eps"]'
1009
sage: maxima.plot_list(zeta_ptsx, zeta_ptsy, opts) # not tested
1010
"""
1011
cmd = 'plot2d([discrete,%s, %s]'%(ptsx, ptsy)
1012
if options is None:
1013
cmd += ')'
1014
else:
1015
cmd += ', %s)'%options
1016
self(cmd)
1017
1018
1019
def plot_multilist(self, pts_list, options=None):
1020
r"""
1021
Plots a list of list of points pts_list=[pts1,pts2,...,ptsn],
1022
where each ptsi is of the form [[x1,y1],...,[xn,yn]] x's must be
1023
integers and y's reals options is a string representing maxima
1024
plot2d options.
1025
1026
INPUT:
1027
1028
- ``pts_lst`` - list of points; each point must be of the form [x,y]
1029
where ``x`` is an integer and ``y`` is a real
1030
1031
- ``var`` - string; representing Maxima's plot2d options
1032
1033
Requires maxima 5.9.2 at least.
1034
1035
.. note::
1036
1037
More that 150 points can sometimes lead to the program
1038
hanging.
1039
1040
EXAMPLES::
1041
1042
sage: xx = [ i/10.0 for i in range (-10,10)]
1043
sage: yy = [ i/10.0 for i in range (-10,10)]
1044
sage: x0 = [ 0 for i in range (-10,10)]
1045
sage: y0 = [ 0 for i in range (-10,10)]
1046
sage: zeta_ptsx1 = [ (pari(1/2+i*I/10).zeta().real()).precision(1) for i in range (10)]
1047
sage: zeta_ptsy1 = [ (pari(1/2+i*I/10).zeta().imag()).precision(1) for i in range (10)]
1048
sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]]) # not tested
1049
sage: zeta_ptsx1 = [ (pari(1/2+i*I/10).zeta().real()).precision(1) for i in range (10,150)]
1050
sage: zeta_ptsy1 = [ (pari(1/2+i*I/10).zeta().imag()).precision(1) for i in range (10,150)]
1051
sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]]) # not tested
1052
sage: opts='[gnuplot_preamble, "set nokey"]'
1053
sage: maxima.plot_multilist([[zeta_ptsx1,zeta_ptsy1],[xx,y0],[x0,yy]],opts) # not tested
1054
"""
1055
n = len(pts_list)
1056
cmd = '['
1057
for i in range(n):
1058
if i < n-1:
1059
cmd = cmd+'[discrete,'+str(pts_list[i][0])+','+str(pts_list[i][1])+'],'
1060
if i==n-1:
1061
cmd = cmd+'[discrete,'+str(pts_list[i][0])+','+str(pts_list[i][1])+']]'
1062
#print cmd
1063
if options is None:
1064
self('plot2d('+cmd+')')
1065
else:
1066
self('plot2d('+cmd+','+options+')')
1067
1068
1069
class MaximaAbstractElement(InterfaceElement):
1070
r"""
1071
Element of Maxima through an abstract interface.
1072
1073
EXAMPLES:
1074
1075
Elements of this class should not be created directly.
1076
The targeted parent of a concrete inherited class should be used instead::
1077
1078
sage: from sage.interfaces.maxima_lib import maxima_lib
1079
sage: xp = maxima(x)
1080
sage: type(xp)
1081
<class 'sage.interfaces.maxima.MaximaElement'>
1082
sage: xl = maxima_lib(x)
1083
sage: type(xl)
1084
<class 'sage.interfaces.maxima_lib.MaximaLibElement'>
1085
"""
1086
1087
def __str__(self):
1088
"""
1089
Printing an object explicitly gives ASCII art.
1090
1091
INPUT: none
1092
1093
OUTPUT: string
1094
1095
EXAMPLES::
1096
1097
sage: f = maxima('1/(x-1)^3'); f
1098
1/(x-1)^3
1099
sage: print f
1100
1
1101
--------
1102
3
1103
(x - 1)
1104
"""
1105
return self.display2d(onscreen=False)
1106
1107
def bool(self):
1108
"""
1109
Convert ``self`` into a boolean.
1110
1111
INPUT: none
1112
1113
OUTPUT: boolean
1114
1115
EXAMPLES::
1116
1117
sage: maxima(0).bool()
1118
False
1119
sage: maxima(1).bool()
1120
True
1121
"""
1122
P = self._check_valid()
1123
return 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 needs
1124
1125
def __cmp__(self, other):
1126
"""
1127
Compare this Maxima object with ``other``.
1128
1129
INPUT:
1130
1131
- ``other`` - an object to compare to
1132
1133
OUTPUT: integer
1134
1135
EXAMPLES::
1136
1137
sage: a = maxima(1); b = maxima(2)
1138
sage: a == b
1139
False
1140
sage: a < b
1141
True
1142
sage: a > b
1143
False
1144
sage: b < a
1145
False
1146
sage: b > a
1147
True
1148
1149
We can also compare more complicated object such as functions::
1150
1151
sage: f = maxima('sin(x)'); g = maxima('cos(x)')
1152
sage: -f == g.diff('x')
1153
True
1154
"""
1155
1156
# thanks to David Joyner for telling me about using "is".
1157
# but be careful, since for relations things like is(equal(a,b))
1158
# are what Maxima needs
1159
P = self.parent()
1160
try:
1161
if P.eval("is (%s < %s)"%(self.name(), other.name())) == P._true_symbol():
1162
return -1
1163
elif P.eval("is (%s > %s)"%(self.name(), other.name())) == P._true_symbol():
1164
return 1
1165
elif P.eval("is (%s = %s)"%(self.name(), other.name())) == P._true_symbol():
1166
return 0
1167
except TypeError:
1168
pass
1169
return cmp(repr(self),repr(other))
1170
# everything is supposed to be comparable in Python,
1171
# so we define the comparison thus when no comparable
1172
# in interfaced system.
1173
1174
def _sage_(self):
1175
"""
1176
Attempt to make a native Sage object out of this Maxima object.
1177
This is useful for automatic coercions in addition to other
1178
things.
1179
1180
INPUT: none
1181
1182
OUTPUT: Sage object
1183
1184
EXAMPLES::
1185
1186
sage: a = maxima('sqrt(2) + 2.5'); a
1187
sqrt(2)+2.5
1188
sage: b = a._sage_(); b
1189
sqrt(2) + 2.5
1190
sage: type(b)
1191
<type 'sage.symbolic.expression.Expression'>
1192
1193
We illustrate an automatic coercion::
1194
1195
sage: c = b + sqrt(3); c
1196
sqrt(2) + sqrt(3) + 2.5
1197
sage: type(c)
1198
<type 'sage.symbolic.expression.Expression'>
1199
sage: d = sqrt(3) + b; d
1200
sqrt(2) + sqrt(3) + 2.5
1201
sage: type(d)
1202
<type 'sage.symbolic.expression.Expression'>
1203
1204
sage: a = sage.calculus.calculus.maxima('x^(sqrt(y)+%pi) + sin(%e + %pi)')
1205
sage: a._sage_()
1206
x^(pi + sqrt(y)) - sin(e)
1207
sage: var('x, y')
1208
(x, y)
1209
sage: v = sage.calculus.calculus.maxima.vandermonde_matrix([x, y, 1/2])
1210
sage: v._sage_()
1211
[ 1 x x^2]
1212
[ 1 y y^2]
1213
[ 1 1/2 1/4]
1214
1215
Check if #7661 is fixed::
1216
1217
sage: var('delta')
1218
delta
1219
sage: (2*delta).simplify()
1220
2*delta
1221
"""
1222
import sage.calculus.calculus as calculus
1223
return calculus.symbolic_expression_from_maxima_string(self.name(),
1224
maxima=self.parent())
1225
1226
def _symbolic_(self, R):
1227
"""
1228
Return a symbolic expression equivalent to this Maxima object.
1229
1230
INPUT:
1231
1232
- ``R`` - symbolic ring to convert into
1233
1234
OUTPUT: symbolic expression
1235
1236
EXAMPLES::
1237
1238
sage: t = sqrt(2)._maxima_()
1239
sage: u = t._symbolic_(SR); u
1240
sqrt(2)
1241
sage: u.parent()
1242
Symbolic Ring
1243
1244
This is used when converting Maxima objects to the Symbolic Ring::
1245
1246
sage: SR(t)
1247
sqrt(2)
1248
"""
1249
return R(self._sage_())
1250
1251
def __complex__(self):
1252
"""
1253
Return a complex number equivalent to this Maxima object.
1254
1255
INPUT: none
1256
1257
OUTPUT: complex
1258
1259
EXAMPLES::
1260
1261
sage: complex(maxima('sqrt(-2)+1'))
1262
(1+1.4142135623730951j)
1263
"""
1264
return complex(self._sage_())
1265
1266
def _complex_mpfr_field_(self, C):
1267
"""
1268
Return a mpfr complex number equivalent to this Maxima object.
1269
1270
INPUT:
1271
1272
- ``C`` - complex numbers field to convert into
1273
1274
OUTPUT: complex
1275
1276
EXAMPLES::
1277
1278
sage: CC(maxima('1+%i'))
1279
1.00000000000000 + 1.00000000000000*I
1280
sage: CC(maxima('2342.23482943872+234*%i'))
1281
2342.23482943872 + 234.000000000000*I
1282
sage: ComplexField(10)(maxima('2342.23482943872+234*%i'))
1283
2300. + 230.*I
1284
sage: ComplexField(200)(maxima('1+%i'))
1285
1.0000000000000000000000000000000000000000000000000000000000 + 1.0000000000000000000000000000000000000000000000000000000000*I
1286
sage: ComplexField(200)(maxima('sqrt(-2)'))
1287
1.4142135623730950488016887242096980785696718753769480731767*I
1288
sage: N(sqrt(-2), 200)
1289
8.0751148893563733350506651837615871941533119425962889089783e-62 + 1.4142135623730950488016887242096980785696718753769480731767*I
1290
"""
1291
return C(self._sage_())
1292
1293
def _mpfr_(self, R):
1294
"""
1295
Return a mpfr real number equivalent to this Maxima object.
1296
1297
INPUT:
1298
1299
- ``R`` - real numbers field to convert into
1300
1301
OUTPUT: real
1302
1303
EXAMPLES::
1304
1305
sage: RealField(100)(maxima('sqrt(2)+1'))
1306
2.4142135623730950488016887242
1307
"""
1308
return R(self._sage_())
1309
1310
def _complex_double_(self, C):
1311
"""
1312
Return a double precision complex number equivalent to this Maxima object.
1313
1314
INPUT:
1315
1316
- ``C`` - double precision complex numbers field to convert into
1317
1318
OUTPUT: complex
1319
1320
EXAMPLES::
1321
1322
sage: CDF(maxima('sqrt(2)+1'))
1323
2.41421356237
1324
"""
1325
return C(self._sage_())
1326
1327
def _real_double_(self, R):
1328
"""
1329
Return a double precision real number equivalent to this Maxima object.
1330
1331
INPUT:
1332
1333
- ``R`` - double precision real numbers field to convert into
1334
1335
OUTPUT: real
1336
1337
EXAMPLES::
1338
1339
sage: RDF(maxima('sqrt(2)+1'))
1340
2.41421356237
1341
"""
1342
return R(self._sage_())
1343
1344
def real(self):
1345
"""
1346
Return the real part of this Maxima element.
1347
1348
INPUT: none
1349
1350
OUTPUT: Maxima real
1351
1352
EXAMPLES::
1353
1354
sage: maxima('2 + (2/3)*%i').real()
1355
2
1356
"""
1357
return self.realpart()
1358
1359
def imag(self):
1360
"""
1361
Return the imaginary part of this Maxima element.
1362
1363
INPUT: none
1364
1365
OUTPUT: Maxima real
1366
1367
EXAMPLES::
1368
1369
sage: maxima('2 + (2/3)*%i').imag()
1370
2/3
1371
"""
1372
return self.imagpart()
1373
1374
def numer(self):
1375
"""
1376
Return numerical approximation to self as a Maxima object.
1377
1378
INPUT: none
1379
1380
OUTPUT: Maxima object
1381
1382
EXAMPLES::
1383
1384
sage: a = maxima('sqrt(2)').numer(); a
1385
1.41421356237309...
1386
sage: type(a)
1387
<class 'sage.interfaces.maxima.MaximaElement'>
1388
"""
1389
return self.comma('numer')
1390
1391
def str(self):
1392
"""
1393
Return string representation of this Maxima object.
1394
1395
INPUT: none
1396
1397
OUTPUT: string
1398
1399
EXAMPLES::
1400
1401
sage: maxima('sqrt(2) + 1/3').str()
1402
'sqrt(2)+1/3'
1403
"""
1404
P = self._check_valid()
1405
return P.get(self._name)
1406
1407
def __repr__(self):
1408
"""
1409
Return print representation of this Maxima object.
1410
1411
INPUT: none
1412
1413
OUTPUT: string
1414
1415
The result is cached.
1416
1417
EXAMPLES::
1418
1419
sage: maxima('sqrt(2) + 1/3').__repr__()
1420
'sqrt(2)+1/3'
1421
"""
1422
P = self._check_valid()
1423
try:
1424
return self.__repr
1425
except AttributeError:
1426
pass
1427
r = P.get(self._name)
1428
self.__repr = r
1429
return r
1430
1431
def diff(self, var='x', n=1):
1432
"""
1433
Return the n-th derivative of self.
1434
1435
INPUT:
1436
1437
- ``var`` - variable (default: 'x')
1438
1439
- ``n`` - integer (default: 1)
1440
1441
OUTPUT: n-th derivative of self with respect to the variable var
1442
1443
EXAMPLES::
1444
1445
sage: f = maxima('x^2')
1446
sage: f.diff()
1447
2*x
1448
sage: f.diff('x')
1449
2*x
1450
sage: f.diff('x', 2)
1451
2
1452
sage: maxima('sin(x^2)').diff('x',4)
1453
16*x^4*sin(x^2)-12*sin(x^2)-48*x^2*cos(x^2)
1454
1455
::
1456
1457
sage: f = maxima('x^2 + 17*y^2')
1458
sage: f.diff('x')
1459
34*y*'diff(y,x,1)+2*x
1460
sage: f.diff('y')
1461
34*y
1462
"""
1463
return InterfaceElement.__getattr__(self, 'diff')(var, n)
1464
1465
derivative = diff
1466
1467
def nintegral(self, var='x', a=0, b=1,
1468
desired_relative_error='1e-8',
1469
maximum_num_subintervals=200):
1470
r"""
1471
Return a numerical approximation to the integral of self from a to
1472
b.
1473
1474
INPUT:
1475
1476
- ``var`` - variable to integrate with respect to
1477
1478
- ``a`` - lower endpoint of integration
1479
1480
- ``b`` - upper endpoint of integration
1481
1482
- ``desired_relative_error`` - (default: '1e-8') the
1483
desired relative error
1484
1485
- ``maximum_num_subintervals`` - (default: 200)
1486
maxima number of subintervals
1487
1488
OUTPUT:
1489
1490
- approximation to the integral
1491
1492
- estimated absolute error of the
1493
approximation
1494
1495
- the number of integrand evaluations
1496
1497
- an error code:
1498
1499
- ``0`` - no problems were encountered
1500
1501
- ``1`` - too many subintervals were done
1502
1503
- ``2`` - excessive roundoff error
1504
1505
- ``3`` - extremely bad integrand behavior
1506
1507
- ``4`` - failed to converge
1508
1509
- ``5`` - integral is probably divergent or slowly convergent
1510
1511
- ``6`` - the input is invalid
1512
1513
EXAMPLES::
1514
1515
sage: maxima('exp(-sqrt(x))').nintegral('x',0,1)
1516
(.5284822353142306, 4.16331413788384...e-11, 231, 0)
1517
1518
Note that GP also does numerical integration, and can do so to very
1519
high precision very quickly::
1520
1521
sage: gp('intnum(x=0,1,exp(-sqrt(x)))')
1522
0.5284822353142307136179049194 # 32-bit
1523
0.52848223531423071361790491935415653022 # 64-bit
1524
sage: _ = gp.set_precision(80)
1525
sage: gp('intnum(x=0,1,exp(-sqrt(x)))')
1526
0.52848223531423071361790491935415653021675547587292866196865279321015401702040079
1527
"""
1528
from sage.rings.all import Integer
1529
v = self.quad_qags(var, a, b, epsrel=desired_relative_error,
1530
limit=maximum_num_subintervals)
1531
return v[0], v[1], Integer(v[2]), Integer(v[3])
1532
1533
def integral(self, var='x', min=None, max=None):
1534
r"""
1535
Return the integral of self with respect to the variable x.
1536
1537
INPUT:
1538
1539
- ``var`` - variable
1540
1541
- ``min`` - default: None
1542
1543
- ``max`` - default: None
1544
1545
OUTPUT:
1546
1547
- the definite integral if xmin is not None
1548
1549
- an indefinite integral otherwise
1550
1551
EXAMPLES::
1552
1553
sage: maxima('x^2+1').integral()
1554
x^3/3+x
1555
sage: maxima('x^2+ 1 + y^2').integral('y')
1556
y^3/3+x^2*y+y
1557
sage: maxima('x / (x^2+1)').integral()
1558
log(x^2+1)/2
1559
sage: maxima('1/(x^2+1)').integral()
1560
atan(x)
1561
sage: maxima('1/(x^2+1)').integral('x', 0, infinity)
1562
%pi/2
1563
sage: maxima('x/(x^2+1)').integral('x', -1, 1)
1564
0
1565
1566
::
1567
1568
sage: f = maxima('exp(x^2)').integral('x',0,1); f
1569
-sqrt(%pi)*%i*erf(%i)/2
1570
sage: f.numer()
1571
1.46265174590718...
1572
"""
1573
I = InterfaceElement.__getattr__(self, 'integrate')
1574
if min is None:
1575
return I(var)
1576
else:
1577
if max is None:
1578
raise ValueError, "neither or both of min/max must be specified."
1579
return I(var, min, max)
1580
1581
integrate = integral
1582
1583
def __float__(self):
1584
"""
1585
Return floating point version of this Maxima element.
1586
1587
INPUT: none
1588
1589
OUTPUT: real
1590
1591
EXAMPLES::
1592
1593
sage: float(maxima("3.14"))
1594
3.14
1595
sage: float(maxima("1.7e+17"))
1596
1.7e+17
1597
sage: float(maxima("1.7e-17"))
1598
1.7e-17
1599
"""
1600
try:
1601
return float(repr(self.numer()))
1602
except ValueError:
1603
raise TypeError, "unable to coerce '%s' to float"%repr(self)
1604
1605
def __len__(self):
1606
"""
1607
Return the length of a list.
1608
1609
INPUT: none
1610
1611
OUTPUT: integer
1612
1613
EXAMPLES::
1614
1615
sage: v = maxima('create_list(x^i,i,0,5)')
1616
sage: len(v)
1617
6
1618
"""
1619
P = self._check_valid()
1620
return int(P.eval('length(%s)'%self.name()))
1621
1622
def dot(self, other):
1623
"""
1624
Implements the notation self . other.
1625
1626
INPUT:
1627
1628
- ``other`` - matrix; argument to dot.
1629
1630
OUTPUT: Maxima matrix
1631
1632
EXAMPLES::
1633
1634
sage: A = maxima('matrix ([a1],[a2])')
1635
sage: B = maxima('matrix ([b1, b2])')
1636
sage: A.dot(B)
1637
matrix([a1*b1,a1*b2],[a2*b1,a2*b2])
1638
"""
1639
P = self._check_valid()
1640
Q = P(other)
1641
return P('%s . %s'%(self.name(), Q.name()))
1642
1643
def __getitem__(self, n):
1644
r"""
1645
Return the n-th element of this list.
1646
1647
INPUT:
1648
1649
- ``n`` - integer
1650
1651
OUTPUT: Maxima object
1652
1653
.. note::
1654
1655
Lists are 0-based when accessed via the Sage interface, not
1656
1-based as they are in the Maxima interpreter.
1657
1658
EXAMPLES::
1659
1660
sage: v = maxima('create_list(i*x^i,i,0,5)'); v
1661
[0,x,2*x^2,3*x^3,4*x^4,5*x^5]
1662
sage: v[3]
1663
3*x^3
1664
sage: v[0]
1665
0
1666
sage: v[10]
1667
Traceback (most recent call last):
1668
...
1669
IndexError: n = (10) must be between 0 and 5
1670
"""
1671
n = int(n)
1672
if n < 0 or n >= len(self):
1673
raise IndexError, "n = (%s) must be between %s and %s"%(n, 0, len(self)-1)
1674
# If you change the n+1 to n below, better change __iter__ as well.
1675
return InterfaceElement.__getitem__(self, n+1)
1676
1677
def __iter__(self):
1678
"""
1679
Return an iterator for self.
1680
1681
INPUT: none
1682
1683
OUTPUT: iterator
1684
1685
EXAMPLES::
1686
1687
sage: v = maxima('create_list(i*x^i,i,0,5)')
1688
sage: L = list(v)
1689
sage: [e._sage_() for e in L]
1690
[0, x, 2*x^2, 3*x^3, 4*x^4, 5*x^5]
1691
"""
1692
for i in range(len(self)):
1693
yield self[i]
1694
1695
def subst(self, val):
1696
"""
1697
Substitute a value or several values into this Maxima object.
1698
1699
INPUT:
1700
1701
- ``val`` - string representing substitution(s) to perform
1702
1703
OUTPUT: Maxima object
1704
1705
EXAMPLES::
1706
1707
sage: maxima('a^2 + 3*a + b').subst('b=2')
1708
a^2+3*a+2
1709
sage: maxima('a^2 + 3*a + b').subst('a=17')
1710
b+340
1711
sage: maxima('a^2 + 3*a + b').subst('a=17, b=2')
1712
342
1713
"""
1714
return self.comma(val)
1715
1716
def comma(self, args):
1717
"""
1718
Form the expression that would be written 'self, args' in Maxima.
1719
1720
INPUT:
1721
1722
- ``args`` - string
1723
1724
OUTPUT: Maxima object
1725
1726
EXAMPLES::
1727
1728
sage: maxima('sqrt(2) + I').comma('numer')
1729
I+1.41421356237309...
1730
sage: maxima('sqrt(2) + I*a').comma('a=5')
1731
5*I+sqrt(2)
1732
"""
1733
self._check_valid()
1734
P = self.parent()
1735
return P('%s, %s'%(self.name(), args))
1736
1737
def _latex_(self):
1738
"""
1739
Return Latex representation of this Maxima object.
1740
1741
INPUT: none
1742
1743
OUTPUT: string
1744
1745
This calls the tex command in Maxima, then does a little
1746
post-processing to fix bugs in the resulting Maxima output.
1747
1748
EXAMPLES::
1749
1750
sage: maxima('sqrt(2) + 1/3 + asin(5)')._latex_()
1751
'\\sin^{-1}\\cdot5+\\sqrt{2}+{{1}\\over{3}}'
1752
1753
sage: y,d = var('y,d')
1754
sage: f = function('f')
1755
sage: latex(maxima(derivative(f(x*y), x)))
1756
\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)\,y
1757
sage: latex(maxima(derivative(f(x,y,d), d,x,x,y)))
1758
{{{\it \partial}^4}\over{{\it \partial}\,d\,{\it \partial}\,x^2\, {\it \partial}\,y}}\,f\left(x , y , d\right)
1759
sage: latex(maxima(d/(d-2)))
1760
{{d}\over{d-2}}
1761
"""
1762
self._check_valid()
1763
P = self.parent()
1764
s = P._eval_line('tex(%s);'%self.name(), reformat=False)
1765
if not '$$' in s:
1766
raise RuntimeError, "Error texing Maxima object."
1767
i = s.find('$$')
1768
j = s.rfind('$$')
1769
s = s[i+2:j]
1770
s = multiple_replace({'\r\n':' ',
1771
'\\%':'',
1772
'\\arcsin ':'\\sin^{-1} ',
1773
'\\arccos ':'\\cos^{-1} ',
1774
'\\arctan ':'\\tan^{-1} '}, s)
1775
1776
# Fix a maxima bug, which gives a latex representation of multiplying
1777
# two numbers as a single space. This was really bad when 2*17^(1/3)
1778
# gets TeXed as '2 17^{\frac{1}{3}}'
1779
#
1780
# This regex matches a string of spaces preceded by either a '}', a
1781
# decimal digit, or a ')', and followed by a decimal digit. The spaces
1782
# get replaced by a '\cdot'.
1783
s = re.sub(r'(?<=[})\d]) +(?=\d)', '\cdot', s)
1784
1785
return s
1786
1787
def trait_names(self, verbose=False):
1788
"""
1789
Return all Maxima commands, which is useful for tab completion.
1790
1791
INPUT:
1792
1793
- ``verbose`` - boolean
1794
1795
OUTPUT: list of strings
1796
1797
EXAMPLES::
1798
1799
sage: m = maxima(2)
1800
sage: 'gcd' in m.trait_names()
1801
True
1802
"""
1803
return self.parent().trait_names(verbose=False)
1804
1805
def _matrix_(self, R):
1806
r"""
1807
If self is a Maxima matrix, return the corresponding Sage matrix
1808
over the Sage ring `R`.
1809
1810
INPUT:
1811
1812
- ``R`` - ring to coerce into
1813
1814
OUTPUT: matrix
1815
1816
This may or may not work depending in how complicated the entries
1817
of self are! It only works if the entries of self can be coerced as
1818
strings to produce meaningful elements of `R`.
1819
1820
EXAMPLES::
1821
1822
sage: _ = maxima.eval("f[i,j] := i/j")
1823
sage: A = maxima('genmatrix(f,4,4)'); A
1824
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])
1825
sage: A._matrix_(QQ)
1826
[ 1 1/2 1/3 1/4]
1827
[ 2 1 2/3 1/2]
1828
[ 3 3/2 1 3/4]
1829
[ 4 2 4/3 1]
1830
1831
You can also use the ``matrix`` command (which is
1832
defined in ``sage.misc.functional``)::
1833
1834
sage: matrix(QQ, A)
1835
[ 1 1/2 1/3 1/4]
1836
[ 2 1 2/3 1/2]
1837
[ 3 3/2 1 3/4]
1838
[ 4 2 4/3 1]
1839
"""
1840
from sage.matrix.all import MatrixSpace
1841
self._check_valid()
1842
P = self.parent()
1843
nrows = int(P.eval('length(%s)'%self.name()))
1844
if nrows == 0:
1845
return MatrixSpace(R, 0, 0)(0)
1846
ncols = int(P.eval('length(%s[1])'%self.name()))
1847
M = MatrixSpace(R, nrows, ncols)
1848
s = self.str().replace('matrix','').replace(',',"','").\
1849
replace("]','[","','").replace('([',"['").replace('])',"']")
1850
s = eval(s)
1851
return M([R(x) for x in s])
1852
1853
def partial_fraction_decomposition(self, var='x'):
1854
"""
1855
Return the partial fraction decomposition of self with respect to
1856
the variable var.
1857
1858
INPUT:
1859
1860
- ``var`` - string
1861
1862
OUTPUT: Maxima object
1863
1864
EXAMPLES::
1865
1866
sage: f = maxima('1/((1+x)*(x-1))')
1867
sage: f.partial_fraction_decomposition('x')
1868
1/(2*(x-1))-1/(2*(x+1))
1869
sage: print f.partial_fraction_decomposition('x')
1870
1 1
1871
--------- - ---------
1872
2 (x - 1) 2 (x + 1)
1873
"""
1874
return self.partfrac(var)
1875
1876
def _operation(self, operation, right):
1877
r"""
1878
Return the result of "self operation right" in Maxima.
1879
1880
INPUT:
1881
1882
- ``operation`` - string; operator
1883
1884
- ``right`` - Maxima object; right operand
1885
1886
OUTPUT: Maxima object
1887
1888
Note that right's parent should already be Maxima since this should
1889
be called after coercion has been performed.
1890
1891
If right is a ``MaximaFunction``, then we convert
1892
``self`` to a ``MaximaFunction`` that takes
1893
no arguments, and let the
1894
``MaximaFunction._operation`` code handle everything
1895
from there.
1896
1897
EXAMPLES::
1898
1899
sage: f = maxima.cos(x)
1900
sage: f._operation("+", f)
1901
2*cos(x)
1902
"""
1903
P = self._check_valid()
1904
1905
if isinstance(right, P._object_function_class()):
1906
fself = P.function('', repr(self))
1907
return fself._operation(operation, right)
1908
1909
try:
1910
return P.new('%s %s %s'%(self._name, operation, right._name))
1911
except Exception, msg:
1912
raise TypeError, msg
1913
1914
1915
class MaximaAbstractFunctionElement(InterfaceFunctionElement):
1916
pass
1917
1918
1919
class MaximaAbstractFunction(InterfaceFunction):
1920
pass
1921
1922
1923
class MaximaAbstractElementFunction(MaximaAbstractElement):
1924
r"""
1925
Create a Maxima function with the parent ``parent``,
1926
name ``name``, definition ``defn``, arguments ``args``
1927
and latex representation ``latex``.
1928
1929
INPUT:
1930
1931
- ``parent`` - an instance of a concrete Maxima interface
1932
1933
- ``name`` - string
1934
1935
- ``defn`` - string
1936
1937
- ``args`` - string; comma separated names of arguments
1938
1939
- ``latex`` - string
1940
1941
OUTPUT: Maxima function
1942
1943
EXAMPLES::
1944
1945
sage: maxima.function('x,y','e^cos(x)')
1946
e^cos(x)
1947
"""
1948
1949
def __init__(self, parent, name, defn, args, latex):
1950
"""
1951
Create a Maxima function.
1952
See ``MaximaAbstractElementFunction`` for full documentation.
1953
1954
TESTS::
1955
1956
sage: from sage.interfaces.maxima_abstract import MaximaAbstractElementFunction
1957
sage: MaximaAbstractElementFunction == loads(dumps(MaximaAbstractElementFunction))
1958
True
1959
sage: f = maxima.function('x,y','sin(x+y)')
1960
sage: f == loads(dumps(f))
1961
True
1962
"""
1963
MaximaAbstractElement.__init__(self, parent, name, is_name=True)
1964
self.__defn = defn
1965
self.__args = args
1966
self.__latex = latex
1967
1968
def __reduce__(self):
1969
"""
1970
Implement __reduce__ for ``MaximaAbstractElementFunction``.
1971
1972
INPUT: none
1973
1974
OUTPUT:
1975
1976
A couple consisting of:
1977
1978
- the function to call for unpickling
1979
1980
- a tuple of arguments for the function
1981
1982
EXAMPLES::
1983
1984
sage: f = maxima.function('x,y','sin(x+y)')
1985
sage: f.__reduce__()
1986
(<function reduce_load_MaximaAbstract_function at 0x...>,
1987
(Maxima, 'sin(x+y)', 'x,y', None))
1988
"""
1989
return reduce_load_MaximaAbstract_function, (self.parent(),
1990
self.__defn, self.__args, self.__latex)
1991
1992
def __call__(self, *args):
1993
"""
1994
Return the result of calling this Maxima function
1995
with the given arguments.
1996
1997
INPUT:
1998
1999
- ``args`` - a variable number of arguments
2000
2001
OUTPUT: Maxima object
2002
2003
EXAMPLES::
2004
2005
sage: f = maxima.function('x,y','sin(x+y)')
2006
sage: f(1,2)
2007
sin(3)
2008
sage: f(x,x)
2009
sin(2*x)
2010
"""
2011
P = self._check_valid()
2012
if len(args) == 1:
2013
args = '(%s)'%args
2014
return P('%s%s'%(self.name(), args))
2015
2016
def __repr__(self):
2017
"""
2018
Return print representation of this Maxima function.
2019
2020
INPUT: none
2021
2022
OUTPUT: string
2023
2024
EXAMPLES::
2025
2026
sage: f = maxima.function('x,y','sin(x+y)')
2027
sage: repr(f)
2028
'sin(x+y)'
2029
"""
2030
return self.definition()
2031
2032
def _latex_(self):
2033
"""
2034
Return latex representation of this Maxima function.
2035
2036
INPUT: none
2037
2038
OUTPUT: string
2039
2040
EXAMPLES::
2041
2042
sage: f = maxima.function('x,y','sin(x+y)')
2043
sage: latex(f)
2044
\mathrm{sin(x+y)}
2045
"""
2046
if self.__latex is None:
2047
return r'\mathrm{%s}'%self.__defn
2048
else:
2049
return self.__latex
2050
2051
def arguments(self, split=True):
2052
r"""
2053
Returns the arguments of this Maxima function.
2054
2055
INPUT:
2056
2057
- ``split`` - boolean; if True return a tuple of strings,
2058
otherwise return a string of comma-separated arguments
2059
2060
OUTPUT:
2061
2062
- a string if ``split`` is False
2063
2064
- a list of strings if ``split`` is True
2065
2066
EXAMPLES::
2067
2068
sage: f = maxima.function('x,y','sin(x+y)')
2069
sage: f.arguments()
2070
['x', 'y']
2071
sage: f.arguments(split=False)
2072
'x,y'
2073
sage: f = maxima.function('', 'sin(x)')
2074
sage: f.arguments()
2075
[]
2076
"""
2077
if split:
2078
return self.__args.split(',') if self.__args != '' else []
2079
else:
2080
return self.__args
2081
2082
def definition(self):
2083
"""
2084
Returns the definition of this Maxima function as a string.
2085
2086
INPUT: none
2087
2088
OUTPUT: string
2089
2090
EXAMPLES::
2091
2092
sage: f = maxima.function('x,y','sin(x+y)')
2093
sage: f.definition()
2094
'sin(x+y)'
2095
"""
2096
return self.__defn
2097
2098
def integral(self, var):
2099
"""
2100
Returns the integral of self with respect to the variable var.
2101
2102
INPUT:
2103
2104
- ``var`` - a variable
2105
2106
OUTPUT: Maxima function
2107
2108
Note that integrate is an alias of integral.
2109
2110
EXAMPLES::
2111
2112
sage: x,y = var('x,y')
2113
sage: f = maxima.function('x','sin(x)')
2114
sage: f.integral(x)
2115
-cos(x)
2116
sage: f.integral(y)
2117
sin(x)*y
2118
"""
2119
var = str(var)
2120
P = self._check_valid()
2121
f = P('integrate(%s(%s), %s)'%(self.name(),
2122
self.arguments(split=False), var))
2123
2124
args = self.arguments()
2125
if var not in args:
2126
args.append(var)
2127
return P.function(",".join(args), repr(f))
2128
2129
integrate = integral
2130
2131
def _operation(self, operation, f=None):
2132
r"""
2133
This is a utility function which factors out much of the
2134
commonality used in the arithmetic operations for
2135
``MaximaAbstractElementFunction``.
2136
2137
INPUT:
2138
2139
- ``operation`` - A string representing the operation
2140
being performed. For example, '\*', or '1/'.
2141
2142
- ``f`` - The other operand. If f is
2143
``None``, then the operation is assumed to be unary
2144
rather than binary.
2145
2146
EXAMPLES::
2147
2148
sage: f = maxima.function('x,y','sin(x+y)')
2149
sage: f._operation("+", f)
2150
2*sin(y+x)
2151
sage: f._operation("+", 2)
2152
sin(y+x)+2
2153
sage: f._operation('-')
2154
-sin(y+x)
2155
sage: f._operation('1/')
2156
1/sin(y+x)
2157
"""
2158
P = self._check_valid()
2159
if isinstance(f, P._object_function_class()):
2160
tmp = list(sorted(set(self.arguments() + f.arguments())))
2161
args = ','.join(tmp)
2162
defn = "(%s)%s(%s)"%(self.definition(), operation, f.definition())
2163
elif f is None:
2164
args = self.arguments(split=False)
2165
defn = "%s(%s)"%(operation, self.definition())
2166
else:
2167
args = self.arguments(split=False)
2168
defn = "(%s)%s(%s)"%(self.definition(), operation, repr(f))
2169
2170
return P.function(args,P.eval(defn))
2171
2172
def _add_(self, f):
2173
"""
2174
This Maxima function as left summand.
2175
2176
EXAMPLES::
2177
2178
sage: x,y = var('x,y')
2179
sage: f = maxima.function('x','sin(x)')
2180
sage: g = maxima.function('x','-cos(x)')
2181
sage: f+g
2182
sin(x)-cos(x)
2183
sage: f+3
2184
sin(x)+3
2185
2186
::
2187
2188
sage: (f+maxima.cos(x))(2)
2189
sin(2)+cos(2)
2190
sage: (f+maxima.cos(y)) # This is a function with only ONE argument!
2191
cos(y)+sin(x)
2192
sage: (f+maxima.cos(y))(2)
2193
cos(y)+sin(2)
2194
2195
::
2196
2197
sage: f = maxima.function('x','sin(x)')
2198
sage: g = -maxima.cos(x)
2199
sage: g+f
2200
sin(x)-cos(x)
2201
sage: (g+f)(2) # The sum IS a function
2202
sin(2)-cos(2)
2203
sage: 2+f
2204
sin(x)+2
2205
"""
2206
return self._operation("+", f)
2207
2208
def _sub_(self, f):
2209
r"""
2210
This Maxima function as minuend.
2211
2212
EXAMPLES::
2213
2214
sage: x,y = var('x,y')
2215
sage: f = maxima.function('x','sin(x)')
2216
sage: g = -maxima.cos(x) # not a function
2217
sage: f-g
2218
sin(x)+cos(x)
2219
sage: (f-g)(2)
2220
sin(2)+cos(2)
2221
sage: (f-maxima.cos(y)) # This function only has the argument x!
2222
sin(x)-cos(y)
2223
sage: _(2)
2224
sin(2)-cos(y)
2225
2226
::
2227
2228
sage: g-f
2229
-sin(x)-cos(x)
2230
"""
2231
return self._operation("-", f)
2232
2233
def _mul_(self, f):
2234
r"""
2235
This Maxima function as left factor.
2236
2237
EXAMPLES::
2238
2239
sage: f = maxima.function('x','sin(x)')
2240
sage: g = maxima('-cos(x)') # not a function!
2241
sage: f*g
2242
-cos(x)*sin(x)
2243
sage: _(2)
2244
-cos(2)*sin(2)
2245
2246
::
2247
2248
sage: f = maxima.function('x','sin(x)')
2249
sage: g = maxima('-cos(x)')
2250
sage: g*f
2251
-cos(x)*sin(x)
2252
sage: _(2)
2253
-cos(2)*sin(2)
2254
sage: 2*f
2255
2*sin(x)
2256
"""
2257
return self._operation("*", f)
2258
2259
def _div_(self, f):
2260
r"""
2261
This Maxima function as dividend.
2262
2263
EXAMPLES::
2264
2265
sage: f=maxima.function('x','sin(x)')
2266
sage: g=maxima('-cos(x)')
2267
sage: f/g
2268
-sin(x)/cos(x)
2269
sage: _(2)
2270
-sin(2)/cos(2)
2271
2272
::
2273
2274
sage: f=maxima.function('x','sin(x)')
2275
sage: g=maxima('-cos(x)')
2276
sage: g/f
2277
-cos(x)/sin(x)
2278
sage: _(2)
2279
-cos(2)/sin(2)
2280
sage: 2/f
2281
2/sin(x)
2282
"""
2283
return self._operation("/", f)
2284
2285
def __neg__(self):
2286
r"""
2287
Additive inverse of this Maxima function.
2288
2289
EXAMPLES::
2290
2291
sage: f=maxima.function('x','sin(x)')
2292
sage: -f
2293
-sin(x)
2294
"""
2295
return self._operation('-')
2296
2297
def __inv__(self):
2298
r"""
2299
Multiplicative inverse of this Maxima function.
2300
2301
EXAMPLES::
2302
2303
sage: f = maxima.function('x','sin(x)')
2304
sage: ~f
2305
1/sin(x)
2306
"""
2307
return self._operation('1/')
2308
2309
def __pow__(self,f):
2310
r"""
2311
This Maxima function raised to some power.
2312
2313
EXAMPLES::
2314
2315
sage: f=maxima.function('x','sin(x)')
2316
sage: g=maxima('-cos(x)')
2317
sage: f^g
2318
1/sin(x)^cos(x)
2319
2320
::
2321
2322
sage: f=maxima.function('x','sin(x)')
2323
sage: g=maxima('-cos(x)') # not a function
2324
sage: g^f
2325
(-cos(x))^sin(x)
2326
"""
2327
return self._operation("^", f)
2328
2329
2330
def reduce_load_MaximaAbstract_function(parent, defn, args, latex):
2331
r"""
2332
Unpickle a Maxima function.
2333
2334
EXAMPLES::
2335
2336
sage: from sage.interfaces.maxima_abstract import reduce_load_MaximaAbstract_function
2337
sage: f = maxima.function('x,y','sin(x+y)')
2338
sage: _,args = f.__reduce__()
2339
sage: g = reduce_load_MaximaAbstract_function(*args)
2340
sage: g == f
2341
True
2342
"""
2343
return parent.function(args, defn, defn, latex)
2344
2345
def maxima_version():
2346
"""
2347
Return Maxima version.
2348
2349
Currently this calls a new copy of Maxima.
2350
2351
EXAMPLES::
2352
2353
sage: from sage.interfaces.maxima_abstract import maxima_version
2354
sage: maxima_version()
2355
'5.26.0'
2356
"""
2357
return os.popen('maxima --version').read().split()[-1]
2358
2359
def maxima_console():
2360
"""
2361
Spawn a new Maxima command-line session.
2362
2363
EXAMPLES::
2364
2365
sage: from sage.interfaces.maxima_abstract import maxima_console
2366
sage: maxima_console() # not tested
2367
Maxima 5.26.0 http://maxima.sourceforge.net
2368
...
2369
"""
2370
os.system('maxima')
2371
2372