passagemath-symbolics 10.6.43__cp314-cp314t-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-symbolics might be problematic. Click here for more details.
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.43.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.43.dist-info/RECORD +171 -0
- passagemath_symbolics-10.6.43.dist-info/WHEEL +5 -0
- passagemath_symbolics-10.6.43.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2826 -0
- sage/calculus/desolvers.py +1866 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-314t-x86_64-linux-musl.so +0 -0
- sage/calculus/var.pyx +401 -0
- sage/dynamics/all__sagemath_symbolics.py +6 -0
- sage/dynamics/complex_dynamics/all.py +5 -0
- sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-x86_64-linux-musl.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
- sage/ext/all__sagemath_symbolics.py +1 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/magma/latex/latex.m +1021 -0
- sage/ext_data/magma/latex/latex.spec +1 -0
- sage/ext_data/magma/sage/basic.m +356 -0
- sage/ext_data/magma/sage/sage.spec +1 -0
- sage/ext_data/magma/spec +9 -0
- sage/geometry/all__sagemath_symbolics.py +8 -0
- sage/geometry/hyperbolic_space/all.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
- sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
- sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
- sage/geometry/riemannian_manifolds/all.py +7 -0
- sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
- sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
- sage/interfaces/all__sagemath_symbolics.py +1 -0
- sage/interfaces/magma.py +3017 -0
- sage/interfaces/magma_free.py +92 -0
- sage/interfaces/maple.py +1397 -0
- sage/interfaces/mathematica.py +1345 -0
- sage/interfaces/mathics.py +1312 -0
- sage/interfaces/sympy.py +1398 -0
- sage/interfaces/sympy_wrapper.py +197 -0
- sage/interfaces/tides.py +938 -0
- sage/libs/all__sagemath_symbolics.py +6 -0
- sage/manifolds/all.py +7 -0
- sage/manifolds/calculus_method.py +555 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4019 -0
- sage/manifolds/chart_func.py +3419 -0
- sage/manifolds/continuous_map.py +2183 -0
- sage/manifolds/continuous_map_image.py +155 -0
- sage/manifolds/differentiable/affine_connection.py +2475 -0
- sage/manifolds/differentiable/all.py +1 -0
- sage/manifolds/differentiable/automorphismfield.py +1383 -0
- sage/manifolds/differentiable/automorphismfield_group.py +604 -0
- sage/manifolds/differentiable/bundle_connection.py +1445 -0
- sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
- sage/manifolds/differentiable/chart.py +1241 -0
- sage/manifolds/differentiable/curve.py +1028 -0
- sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
- sage/manifolds/differentiable/degenerate.py +559 -0
- sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
- sage/manifolds/differentiable/diff_form.py +1658 -0
- sage/manifolds/differentiable/diff_form_module.py +1062 -0
- sage/manifolds/differentiable/diff_map.py +1315 -0
- sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
- sage/manifolds/differentiable/examples/all.py +1 -0
- sage/manifolds/differentiable/examples/euclidean.py +2517 -0
- sage/manifolds/differentiable/examples/real_line.py +897 -0
- sage/manifolds/differentiable/examples/sphere.py +1186 -0
- sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
- sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
- sage/manifolds/differentiable/integrated_curve.py +4035 -0
- sage/manifolds/differentiable/levi_civita_connection.py +841 -0
- sage/manifolds/differentiable/manifold.py +4254 -0
- sage/manifolds/differentiable/manifold_homset.py +1826 -0
- sage/manifolds/differentiable/metric.py +3032 -0
- sage/manifolds/differentiable/mixed_form.py +1507 -0
- sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
- sage/manifolds/differentiable/multivector_module.py +800 -0
- sage/manifolds/differentiable/multivectorfield.py +1520 -0
- sage/manifolds/differentiable/poisson_tensor.py +268 -0
- sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
- sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
- sage/manifolds/differentiable/scalarfield.py +1343 -0
- sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
- sage/manifolds/differentiable/symplectic_form.py +910 -0
- sage/manifolds/differentiable/symplectic_form_test.py +220 -0
- sage/manifolds/differentiable/tangent_space.py +412 -0
- sage/manifolds/differentiable/tangent_vector.py +616 -0
- sage/manifolds/differentiable/tensorfield.py +4665 -0
- sage/manifolds/differentiable/tensorfield_module.py +963 -0
- sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
- sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
- sage/manifolds/differentiable/vector_bundle.py +1728 -0
- sage/manifolds/differentiable/vectorfield.py +1717 -0
- sage/manifolds/differentiable/vectorfield_module.py +2445 -0
- sage/manifolds/differentiable/vectorframe.py +1832 -0
- sage/manifolds/family.py +270 -0
- sage/manifolds/local_frame.py +1490 -0
- sage/manifolds/manifold.py +3090 -0
- sage/manifolds/manifold_homset.py +452 -0
- sage/manifolds/operators.py +359 -0
- sage/manifolds/point.py +994 -0
- sage/manifolds/scalarfield.py +3718 -0
- sage/manifolds/scalarfield_algebra.py +629 -0
- sage/manifolds/section.py +3111 -0
- sage/manifolds/section_module.py +831 -0
- sage/manifolds/structure.py +229 -0
- sage/manifolds/subset.py +2764 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +885 -0
- sage/manifolds/topological_submanifold.py +891 -0
- sage/manifolds/trivialization.py +733 -0
- sage/manifolds/utilities.py +1348 -0
- sage/manifolds/vector_bundle.py +1342 -0
- sage/manifolds/vector_bundle_fiber.py +332 -0
- sage/manifolds/vector_bundle_fiber_element.py +111 -0
- sage/matrix/all__sagemath_symbolics.py +1 -0
- sage/matrix/matrix_symbolic_dense.cpython-314t-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1022 -0
- sage/matrix/matrix_symbolic_sparse.cpython-314t-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
- sage/modules/all__sagemath_symbolics.py +1 -0
- sage/modules/vector_callable_symbolic_dense.py +105 -0
- sage/modules/vector_symbolic_dense.py +116 -0
- sage/modules/vector_symbolic_sparse.py +118 -0
- sage/rings/all__sagemath_symbolics.py +4 -0
- sage/rings/asymptotic/all.py +6 -0
- sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
- sage/rings/asymptotic/asymptotic_ring.py +4858 -0
- sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5237 -0
- sage/rings/function_field/all__sagemath_symbolics.py +2 -0
- sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
- sage/symbolic/all.py +15 -0
- sage/symbolic/assumptions.py +985 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +459 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1287 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1713 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +270 -0
- sage/symbolic/integration/integral.py +1115 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/random_tests.py +462 -0
- sage/symbolic/relation.py +1907 -0
- sage/symbolic/ring.cpython-314t-x86_64-linux-musl.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyx +1396 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1470 -0
sage/interfaces/maple.py
ADDED
|
@@ -0,0 +1,1397 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Interface to Maple
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- William Stein (2005): maple interface
|
|
8
|
+
|
|
9
|
+
- Gregg Musiker (2006-02-02): tutorial
|
|
10
|
+
|
|
11
|
+
- William Stein (2006-03-05): added tab completion, e.g., maple.[tab],
|
|
12
|
+
and help, e.g, maple.sin?.
|
|
13
|
+
|
|
14
|
+
You must have the optional commercial Maple interpreter installed
|
|
15
|
+
and available as the command ``maple`` in your PATH in
|
|
16
|
+
order to use this interface. You do not have to install any
|
|
17
|
+
optional Sage packages.
|
|
18
|
+
|
|
19
|
+
Type ``maple.[tab]`` for a list of all the functions
|
|
20
|
+
available from your Maple install. Type
|
|
21
|
+
``maple.[tab]?`` for Maple's help about a given
|
|
22
|
+
function. Type ``maple(...)`` to create a new Maple
|
|
23
|
+
object, and ``maple.eval(...)`` to run a string using
|
|
24
|
+
Maple (and get the result back as a string).
|
|
25
|
+
|
|
26
|
+
EXAMPLES::
|
|
27
|
+
|
|
28
|
+
sage: # optional - maple
|
|
29
|
+
sage: maple('3 * 5')
|
|
30
|
+
15
|
|
31
|
+
sage: maple.eval('ifactor(2005)')
|
|
32
|
+
'``(5)*``(401)'
|
|
33
|
+
sage: maple.ifactor(2005)
|
|
34
|
+
``(5)*``(401)
|
|
35
|
+
sage: maple.fsolve('x^2=cos(x)+4', 'x=0..5')
|
|
36
|
+
1.914020619
|
|
37
|
+
sage: maple.factor('x^5 - y^5')
|
|
38
|
+
(x-y)*(x^4+x^3*y+x^2*y^2+x*y^3+y^4)
|
|
39
|
+
|
|
40
|
+
If the string "error" (case insensitive) occurs in the output of
|
|
41
|
+
anything from Maple, a :exc:`RuntimeError` exception is raised.
|
|
42
|
+
|
|
43
|
+
Tutorial
|
|
44
|
+
--------
|
|
45
|
+
|
|
46
|
+
AUTHORS:
|
|
47
|
+
|
|
48
|
+
- Gregg Musiker (2006-02-02): initial version.
|
|
49
|
+
|
|
50
|
+
This tutorial is based on the Maple Tutorial for number theory from
|
|
51
|
+
http://www.math.mun.ca/~drideout/m3370/numtheory.html.
|
|
52
|
+
|
|
53
|
+
There are several ways to use the Maple Interface in Sage. We will
|
|
54
|
+
discuss two of those ways in this tutorial.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
#. If you have a maple expression such as
|
|
58
|
+
|
|
59
|
+
::
|
|
60
|
+
|
|
61
|
+
factor( (x^5-1));
|
|
62
|
+
|
|
63
|
+
We can write that in sage as
|
|
64
|
+
|
|
65
|
+
::
|
|
66
|
+
|
|
67
|
+
sage: maple('factor(x^5-1)') # optional - maple
|
|
68
|
+
(x-1)*(x^4+x^3+x^2+x+1)
|
|
69
|
+
|
|
70
|
+
Notice, there is no need to use a semicolon.
|
|
71
|
+
|
|
72
|
+
#. Since Sage is written in Python, we can also import maple
|
|
73
|
+
commands and write our scripts in a Pythonic way. For example,
|
|
74
|
+
``factor()`` is a maple command, so we can also factor
|
|
75
|
+
in Sage using
|
|
76
|
+
|
|
77
|
+
::
|
|
78
|
+
|
|
79
|
+
sage: maple('(x^5-1)').factor() # optional - maple
|
|
80
|
+
(x-1)*(x^4+x^3+x^2+x+1)
|
|
81
|
+
|
|
82
|
+
where ``expression.command()`` means the same thing as
|
|
83
|
+
``command(expression)`` in Maple. We will use this
|
|
84
|
+
second type of syntax whenever possible, resorting to the first
|
|
85
|
+
when needed.
|
|
86
|
+
|
|
87
|
+
::
|
|
88
|
+
|
|
89
|
+
sage: maple('(x^12-1)/(x-1)').simplify() # optional - maple
|
|
90
|
+
(x+1)*(x^2+1)*(x^2+x+1)*(x^2-x+1)*(x^4-x^2+1)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
The normal command will always reduce a rational function to the
|
|
94
|
+
lowest terms. The factor command will factor a polynomial with
|
|
95
|
+
rational coefficients into irreducible factors over the ring of
|
|
96
|
+
integers. So for example,
|
|
97
|
+
|
|
98
|
+
::
|
|
99
|
+
|
|
100
|
+
sage: maple('(x^12-1)').factor( ) # optional - maple
|
|
101
|
+
(x-1)*(x+1)*(x^2+x+1)*(x^2-x+1)*(x^2+1)*(x^4-x^2+1)
|
|
102
|
+
|
|
103
|
+
::
|
|
104
|
+
|
|
105
|
+
sage: maple('(x^28-1)').factor( ) # optional - maple
|
|
106
|
+
(x-1)*(x^6+x^5+x^4+x^3+x^2+x+1)*(x+1)*(x^6-x^5+x^4-x^3+x^2-x+1)*(x^2+1)*(x^12-x^10+x^8-x^6+x^4-x^2+1)
|
|
107
|
+
|
|
108
|
+
Another important feature of maple is its online help. We can
|
|
109
|
+
access this through sage as well. After reading the description of
|
|
110
|
+
the command, you can press :kbd:`q` to immediately get back to your
|
|
111
|
+
original prompt.
|
|
112
|
+
|
|
113
|
+
Incidentally you can always get into a maple console by the
|
|
114
|
+
command ::
|
|
115
|
+
|
|
116
|
+
sage: maple.console() # not tested
|
|
117
|
+
sage: !maple # not tested
|
|
118
|
+
|
|
119
|
+
Note that the above two commands are slightly different, and the
|
|
120
|
+
first is preferred.
|
|
121
|
+
|
|
122
|
+
For example, for help on the maple command fibonacci, we type
|
|
123
|
+
|
|
124
|
+
::
|
|
125
|
+
|
|
126
|
+
sage: maple.help('fibonacci') # not tested, since it uses a pager
|
|
127
|
+
|
|
128
|
+
We see there are two choices. Type
|
|
129
|
+
|
|
130
|
+
::
|
|
131
|
+
|
|
132
|
+
sage: maple.help('combinat, fibonacci') # not tested, since it uses a pager
|
|
133
|
+
|
|
134
|
+
We now see how the Maple command fibonacci works under the
|
|
135
|
+
combinatorics package. Try typing in
|
|
136
|
+
|
|
137
|
+
::
|
|
138
|
+
|
|
139
|
+
sage: maple.fibonacci(10) # optional - maple
|
|
140
|
+
fibonacci(10)
|
|
141
|
+
|
|
142
|
+
You will get fibonacci(10) as output since Maple has not loaded the
|
|
143
|
+
combinatorics package yet. To rectify this type
|
|
144
|
+
|
|
145
|
+
::
|
|
146
|
+
|
|
147
|
+
sage: maple('combinat[fibonacci]')(10) # optional - maple
|
|
148
|
+
55
|
|
149
|
+
|
|
150
|
+
instead.
|
|
151
|
+
|
|
152
|
+
If you want to load the combinatorics package for future
|
|
153
|
+
calculations, in Sage this can be done as
|
|
154
|
+
|
|
155
|
+
::
|
|
156
|
+
|
|
157
|
+
sage: maple.with_package('combinat') # optional - maple
|
|
158
|
+
|
|
159
|
+
or
|
|
160
|
+
|
|
161
|
+
::
|
|
162
|
+
|
|
163
|
+
sage: maple.load('combinat') # optional - maple
|
|
164
|
+
|
|
165
|
+
Now if we type ``maple.fibonacci(10)``, we get the
|
|
166
|
+
correct output::
|
|
167
|
+
|
|
168
|
+
sage: maple.fibonacci(10) # optional - maple
|
|
169
|
+
55
|
|
170
|
+
|
|
171
|
+
Some common maple packages include ``combinat``,
|
|
172
|
+
``linalg``, and ``numtheory``. To produce
|
|
173
|
+
the first 19 Fibonacci numbers, use the sequence command.
|
|
174
|
+
|
|
175
|
+
::
|
|
176
|
+
|
|
177
|
+
sage: maple('seq(fibonacci(i),i=1..19)') # optional - maple
|
|
178
|
+
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584,
|
|
179
|
+
4181
|
|
180
|
+
|
|
181
|
+
Two other useful Maple commands are ifactor and isprime. For
|
|
182
|
+
example
|
|
183
|
+
|
|
184
|
+
::
|
|
185
|
+
|
|
186
|
+
sage: maple.isprime(maple.fibonacci(27)) # optional - maple
|
|
187
|
+
false
|
|
188
|
+
sage: maple.ifactor(maple.fibonacci(27)) # optional - maple
|
|
189
|
+
``(2)*``(17)*``(53)*``(109)
|
|
190
|
+
|
|
191
|
+
Note that the isprime function that is included with Sage (which
|
|
192
|
+
uses PARI) is better than the Maple one (it is faster and gives a
|
|
193
|
+
provably correct answer, whereas Maple is sometimes wrong).
|
|
194
|
+
|
|
195
|
+
::
|
|
196
|
+
|
|
197
|
+
sage: # optional - maple
|
|
198
|
+
sage: alpha = maple('(1+sqrt(5))/2')
|
|
199
|
+
sage: beta = maple('(1-sqrt(5))/2')
|
|
200
|
+
sage: f19 = alpha^19 - beta^19/maple('sqrt(5)')
|
|
201
|
+
sage: f19
|
|
202
|
+
(1/2+1/2*5^(1/2))^19-1/5*(1/2-1/2*5^(1/2))^19*5^(1/2)
|
|
203
|
+
sage: f19.simplify() # somewhat randomly ordered output
|
|
204
|
+
6765+5778/5*5^(1/2)
|
|
205
|
+
|
|
206
|
+
Let's say we want to write a maple program now that squares a
|
|
207
|
+
number if it is positive and cubes it if it is negative. In maple,
|
|
208
|
+
that would look like
|
|
209
|
+
|
|
210
|
+
::
|
|
211
|
+
|
|
212
|
+
mysqcu := proc(x)
|
|
213
|
+
if x > 0 then x^2;
|
|
214
|
+
else x^3; fi;
|
|
215
|
+
end;
|
|
216
|
+
|
|
217
|
+
In Sage, we write
|
|
218
|
+
|
|
219
|
+
::
|
|
220
|
+
|
|
221
|
+
sage: mysqcu = maple('proc(x) if x > 0 then x^2 else x^3 fi end') # optional - maple
|
|
222
|
+
sage: mysqcu(5) # optional - maple
|
|
223
|
+
25
|
|
224
|
+
sage: mysqcu(-5) # optional - maple
|
|
225
|
+
-125
|
|
226
|
+
|
|
227
|
+
More complicated programs should be put in a separate file and
|
|
228
|
+
loaded.
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
#############################################################################
|
|
232
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
|
233
|
+
#
|
|
234
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
235
|
+
#
|
|
236
|
+
# https://www.gnu.org/licenses/
|
|
237
|
+
#############################################################################
|
|
238
|
+
|
|
239
|
+
import os
|
|
240
|
+
|
|
241
|
+
from .expect import Expect, ExpectElement, ExpectFunction, FunctionElement, gc_disabled
|
|
242
|
+
|
|
243
|
+
import pexpect
|
|
244
|
+
|
|
245
|
+
from sage.env import DOT_SAGE
|
|
246
|
+
from sage.misc.pager import pager
|
|
247
|
+
from sage.interfaces.tab_completion import ExtraTabCompletion
|
|
248
|
+
from sage.misc.instancedoc import instancedoc
|
|
249
|
+
from sage.structure.richcmp import rich_to_bool
|
|
250
|
+
from sage.cpython.string import bytes_to_str
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
COMMANDS_CACHE = '%s/maple_commandlist_cache.sobj' % DOT_SAGE
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class Maple(ExtraTabCompletion, Expect):
|
|
257
|
+
"""
|
|
258
|
+
Interface to the Maple interpreter.
|
|
259
|
+
|
|
260
|
+
Type ``maple.[tab]`` for a list of all the functions
|
|
261
|
+
available from your Maple install. Type
|
|
262
|
+
``maple.[tab]?`` for Maple's help about a given
|
|
263
|
+
function. Type ``maple(...)`` to create a new Maple
|
|
264
|
+
object, and ``maple.eval(...)`` to run a string using
|
|
265
|
+
Maple (and get the result back as a string).
|
|
266
|
+
"""
|
|
267
|
+
def __init__(self, maxread=None, script_subdirectory=None, server=None,
|
|
268
|
+
server_tmpdir=None, logfile=None, ulimit=None):
|
|
269
|
+
"""
|
|
270
|
+
Create an instance of the Maple interpreter.
|
|
271
|
+
|
|
272
|
+
EXAMPLES::
|
|
273
|
+
|
|
274
|
+
sage: maple == loads(dumps(maple))
|
|
275
|
+
True
|
|
276
|
+
"""
|
|
277
|
+
__maple_iface_opts = [
|
|
278
|
+
'screenwidth=infinity',
|
|
279
|
+
'errorcursor=false']
|
|
280
|
+
__maple_command = 'maple -t -c "interface({})"'.format(
|
|
281
|
+
','.join(__maple_iface_opts))
|
|
282
|
+
# errorcursor=false avoids maple command line interface to dump
|
|
283
|
+
# into the editor when an error occurs. Thus pexpect interface
|
|
284
|
+
# is not messed up if a maple error occurs.
|
|
285
|
+
# screenwidth=infinity prevents maple command interface from cutting
|
|
286
|
+
# your input lines. By doing this, file interface also works in the
|
|
287
|
+
# event that sage_user_home + sage_tmp_file_stuff exceeds the
|
|
288
|
+
# length of 79 characters.
|
|
289
|
+
Expect.__init__(self,
|
|
290
|
+
name='maple',
|
|
291
|
+
prompt='#-->',
|
|
292
|
+
command=__maple_command,
|
|
293
|
+
server=server,
|
|
294
|
+
server_tmpdir=server_tmpdir,
|
|
295
|
+
ulimit=ulimit,
|
|
296
|
+
script_subdirectory=script_subdirectory,
|
|
297
|
+
restart_on_ctrlc=False,
|
|
298
|
+
verbose_start=False,
|
|
299
|
+
logfile=logfile,
|
|
300
|
+
eval_using_file_cutoff=2048) # 2048 is
|
|
301
|
+
# a small enough value to avoid conflicts with the 4096 limit
|
|
302
|
+
# hardcoded in Expect.
|
|
303
|
+
|
|
304
|
+
def _function_class(self):
|
|
305
|
+
"""
|
|
306
|
+
EXAMPLES::
|
|
307
|
+
|
|
308
|
+
sage: maple._function_class()
|
|
309
|
+
<class 'sage.interfaces.maple.MapleFunction'>
|
|
310
|
+
|
|
311
|
+
::
|
|
312
|
+
|
|
313
|
+
sage: type(maple.diff)
|
|
314
|
+
<class 'sage.interfaces.maple.MapleFunction'>
|
|
315
|
+
"""
|
|
316
|
+
return MapleFunction
|
|
317
|
+
|
|
318
|
+
def _keyboard_interrupt(self):
|
|
319
|
+
"""
|
|
320
|
+
EXAMPLES::
|
|
321
|
+
|
|
322
|
+
sage: maple._keyboard_interrupt() # not tested
|
|
323
|
+
Interrupting Maple...
|
|
324
|
+
...
|
|
325
|
+
RuntimeError: Ctrl-c pressed while running Maple
|
|
326
|
+
|
|
327
|
+
::
|
|
328
|
+
|
|
329
|
+
sage: maple('Matrix(8000,8000)') # not tested
|
|
330
|
+
#Press ctrl-c
|
|
331
|
+
^CInterrupting Maple...
|
|
332
|
+
...
|
|
333
|
+
RuntimeError: Ctrl-c pressed while running Maple
|
|
334
|
+
"""
|
|
335
|
+
print("Interrupting %s..." % self)
|
|
336
|
+
self._expect.sendline(chr(3)) # send ctrl-c
|
|
337
|
+
self._expect.expect(self._prompt)
|
|
338
|
+
raise RuntimeError("Ctrl-c pressed while running %s" % self)
|
|
339
|
+
|
|
340
|
+
def __reduce__(self):
|
|
341
|
+
"""
|
|
342
|
+
EXAMPLES::
|
|
343
|
+
|
|
344
|
+
sage: Maple().__reduce__()
|
|
345
|
+
(<function reduce_load_Maple at 0x...>, ())
|
|
346
|
+
sage: f, args = _
|
|
347
|
+
sage: f(*args)
|
|
348
|
+
Maple
|
|
349
|
+
"""
|
|
350
|
+
return reduce_load_Maple, tuple([])
|
|
351
|
+
|
|
352
|
+
def _read_in_file_command(self, filename):
|
|
353
|
+
r"""
|
|
354
|
+
Return the string used to read filename into Maple.
|
|
355
|
+
|
|
356
|
+
EXAMPLES::
|
|
357
|
+
|
|
358
|
+
sage: maple._read_in_file_command('test')
|
|
359
|
+
'read "test"'
|
|
360
|
+
|
|
361
|
+
::
|
|
362
|
+
|
|
363
|
+
sage: # optional - maple
|
|
364
|
+
sage: filename = tmp_filename()
|
|
365
|
+
sage: with open(filename, 'w') as f:
|
|
366
|
+
....: _ = f.write('xx := 22;\n')
|
|
367
|
+
sage: maple.read(filename)
|
|
368
|
+
sage: maple.get('xx').strip()
|
|
369
|
+
'22'
|
|
370
|
+
"""
|
|
371
|
+
return f'read "{filename}"'
|
|
372
|
+
|
|
373
|
+
def _quit_string(self):
|
|
374
|
+
"""
|
|
375
|
+
EXAMPLES::
|
|
376
|
+
|
|
377
|
+
sage: maple._quit_string()
|
|
378
|
+
'quit'
|
|
379
|
+
|
|
380
|
+
::
|
|
381
|
+
|
|
382
|
+
sage: # optional - maple
|
|
383
|
+
sage: m = Maple()
|
|
384
|
+
sage: a = m(2)
|
|
385
|
+
sage: m.is_running()
|
|
386
|
+
True
|
|
387
|
+
sage: m.quit()
|
|
388
|
+
sage: m.is_running()
|
|
389
|
+
False
|
|
390
|
+
"""
|
|
391
|
+
return 'quit'
|
|
392
|
+
|
|
393
|
+
def _install_hints(self):
|
|
394
|
+
"""
|
|
395
|
+
Hints for installing Maple on your computer.
|
|
396
|
+
|
|
397
|
+
AUTHORS:
|
|
398
|
+
|
|
399
|
+
- William Stein and Justin Walker (2006-02-12).
|
|
400
|
+
|
|
401
|
+
EXAMPLES::
|
|
402
|
+
|
|
403
|
+
sage: print(maple._install_hints())
|
|
404
|
+
In order...
|
|
405
|
+
"""
|
|
406
|
+
return """
|
|
407
|
+
|
|
408
|
+
In order to use the Maple interface you need to have Maple installed
|
|
409
|
+
and have a script in your PATH called "maple" that runs the
|
|
410
|
+
command-line version of Maple. Alternatively, you could use a remote
|
|
411
|
+
connection to a server running Maple; for hints, type
|
|
412
|
+
print(maple._install_hints_ssh())
|
|
413
|
+
|
|
414
|
+
(1) You might have to buy Maple (http://webstore.maplesoft.com/).
|
|
415
|
+
|
|
416
|
+
(2) * LINUX: The maple script comes standard with your Maple install.
|
|
417
|
+
|
|
418
|
+
* APPLE OS X:
|
|
419
|
+
(a) create a file called maple (in your PATH), with the following contents:
|
|
420
|
+
#!/bin/sh
|
|
421
|
+
/Library/Frameworks/Maple.framework/Versions/Current/bin/maple $@
|
|
422
|
+
(b) Save the file.
|
|
423
|
+
(c) Make the file executable.
|
|
424
|
+
chmod +x maple
|
|
425
|
+
|
|
426
|
+
* WINDOWS:
|
|
427
|
+
You must install Maple-for-Linux into the Linux subsystem.
|
|
428
|
+
"""
|
|
429
|
+
|
|
430
|
+
def expect(self):
|
|
431
|
+
"""
|
|
432
|
+
Return the pexpect object for this Maple session.
|
|
433
|
+
|
|
434
|
+
EXAMPLES::
|
|
435
|
+
|
|
436
|
+
sage: # optional - maple
|
|
437
|
+
sage: m = Maple()
|
|
438
|
+
sage: m.expect() is None
|
|
439
|
+
True
|
|
440
|
+
sage: m._start()
|
|
441
|
+
sage: m.expect()
|
|
442
|
+
Maple with PID ...
|
|
443
|
+
sage: m.quit()
|
|
444
|
+
"""
|
|
445
|
+
return self._expect
|
|
446
|
+
|
|
447
|
+
def console(self):
|
|
448
|
+
r"""
|
|
449
|
+
Spawn a new Maple command-line session.
|
|
450
|
+
|
|
451
|
+
EXAMPLES::
|
|
452
|
+
|
|
453
|
+
sage: maple.console() # not tested
|
|
454
|
+
|\^/| Maple 2019 (X86 64 LINUX)
|
|
455
|
+
._|\| |/|_. Copyright (c) Maplesoft, a division of Waterloo Maple Inc. 2019
|
|
456
|
+
\ MAPLE / All rights reserved. Maple is a trademark of
|
|
457
|
+
<____ ____> Waterloo Maple Inc.
|
|
458
|
+
| Type ? for help.
|
|
459
|
+
"""
|
|
460
|
+
maple_console()
|
|
461
|
+
|
|
462
|
+
# def killall(self):
|
|
463
|
+
# """
|
|
464
|
+
# Kill all running instances of the maple interpreter
|
|
465
|
+
# on this system.
|
|
466
|
+
|
|
467
|
+
# TODO: When Sage exits it doesn't correctly by default kill
|
|
468
|
+
# all running Maple interpreters, for some strange reason.
|
|
469
|
+
# Calling this function uses the kill and pidof operating system
|
|
470
|
+
# programs to find all instances of cmaple and kill them.
|
|
471
|
+
# """
|
|
472
|
+
# import os
|
|
473
|
+
# self._expect = None
|
|
474
|
+
# while True:
|
|
475
|
+
# pid = os.popen("pidof cmaple").read()[:-1]
|
|
476
|
+
# if len(pid) > 0:
|
|
477
|
+
# os.system('kill -9 %s'%pid)
|
|
478
|
+
# else:
|
|
479
|
+
# break
|
|
480
|
+
|
|
481
|
+
def completions(self, s):
|
|
482
|
+
"""
|
|
483
|
+
Return all commands that complete the command starting with the
|
|
484
|
+
string ``s``.
|
|
485
|
+
|
|
486
|
+
This is like typing ``s`` + :kbd:`Ctrl` + :kbd:`T`
|
|
487
|
+
in the Maple interpreter.
|
|
488
|
+
|
|
489
|
+
EXAMPLES::
|
|
490
|
+
|
|
491
|
+
sage: c = maple.completions('di') # optional - maple
|
|
492
|
+
sage: 'divide' in c # optional - maple
|
|
493
|
+
True
|
|
494
|
+
"""
|
|
495
|
+
bs = chr(8) * len(s)
|
|
496
|
+
if self._expect is None:
|
|
497
|
+
self._start()
|
|
498
|
+
E = self._expect
|
|
499
|
+
E.sendline('%s%s%s' % (s, chr(20), bs))
|
|
500
|
+
t = E.timeout
|
|
501
|
+
E.timeout = 0.3 # since some things have no completion
|
|
502
|
+
try:
|
|
503
|
+
E.expect('----')
|
|
504
|
+
except pexpect.TIMEOUT:
|
|
505
|
+
E.timeout = t
|
|
506
|
+
return []
|
|
507
|
+
E.timeout = t
|
|
508
|
+
v = E.before
|
|
509
|
+
E.expect(self._prompt)
|
|
510
|
+
E.expect(self._prompt)
|
|
511
|
+
E.expect(self._prompt)
|
|
512
|
+
return [bytes_to_str(l) for l in v.split()[2:]]
|
|
513
|
+
|
|
514
|
+
def _commands(self):
|
|
515
|
+
"""
|
|
516
|
+
Return list of all commands defined in Maple.
|
|
517
|
+
|
|
518
|
+
EXAMPLES::
|
|
519
|
+
|
|
520
|
+
sage: c = maple._commands() # optional - maple
|
|
521
|
+
sage: len(c) > 100 # optional - maple
|
|
522
|
+
True
|
|
523
|
+
sage: 'dilog' in c # optional - maple
|
|
524
|
+
True
|
|
525
|
+
"""
|
|
526
|
+
try:
|
|
527
|
+
v = sum([self.completions(chr(65 + n)) for n in range(26)], []) + \
|
|
528
|
+
sum([self.completions(chr(97 + n)) for n in range(26)], [])
|
|
529
|
+
except RuntimeError:
|
|
530
|
+
print("\n" * 3)
|
|
531
|
+
txt = "WARNING: You do not have a working version of Maple installed!"
|
|
532
|
+
print("═" * len(txt))
|
|
533
|
+
print(txt)
|
|
534
|
+
print("═" * len(txt))
|
|
535
|
+
v = []
|
|
536
|
+
v.sort()
|
|
537
|
+
return v
|
|
538
|
+
|
|
539
|
+
def _tab_completion(self, verbose=True, use_disk_cache=True):
|
|
540
|
+
"""
|
|
541
|
+
Return a list of all the commands defined in Maple and optionally
|
|
542
|
+
(per default) store them to disk.
|
|
543
|
+
|
|
544
|
+
EXAMPLES::
|
|
545
|
+
|
|
546
|
+
sage: c = maple._tab_completion(use_disk_cache=False, verbose=False) # optional - maple
|
|
547
|
+
sage: len(c) > 100 # optional - maple
|
|
548
|
+
True
|
|
549
|
+
sage: 'dilog' in c # optional - maple
|
|
550
|
+
True
|
|
551
|
+
"""
|
|
552
|
+
try:
|
|
553
|
+
return self.__tab_completion
|
|
554
|
+
except AttributeError:
|
|
555
|
+
import sage.misc.persist
|
|
556
|
+
if use_disk_cache:
|
|
557
|
+
try:
|
|
558
|
+
self.__tab_completion = sage.misc.persist.load(COMMANDS_CACHE)
|
|
559
|
+
return self.__tab_completion
|
|
560
|
+
except OSError:
|
|
561
|
+
pass
|
|
562
|
+
if verbose:
|
|
563
|
+
print("\nBuilding Maple command completion list (this takes")
|
|
564
|
+
print("a few seconds only the first time you do it).")
|
|
565
|
+
print("To force rebuild later, delete %s." % COMMANDS_CACHE)
|
|
566
|
+
v = self._commands()
|
|
567
|
+
self.__tab_completion = v
|
|
568
|
+
if len(v) > 200:
|
|
569
|
+
# Maple is actually installed.
|
|
570
|
+
sage.misc.persist.save(v, COMMANDS_CACHE)
|
|
571
|
+
return v
|
|
572
|
+
|
|
573
|
+
def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if_needed=False):
|
|
574
|
+
"""
|
|
575
|
+
EXAMPLES::
|
|
576
|
+
|
|
577
|
+
sage: maple._eval_line('2+2') # optional - maple
|
|
578
|
+
'4'
|
|
579
|
+
"""
|
|
580
|
+
line += ';'
|
|
581
|
+
with gc_disabled():
|
|
582
|
+
z = Expect._eval_line(self, line, allow_use_file=allow_use_file,
|
|
583
|
+
wait_for_prompt=wait_for_prompt).replace('\\\n', '').strip()
|
|
584
|
+
if z.lower().find("error") != -1:
|
|
585
|
+
raise RuntimeError("An error occurred running a Maple command:\nINPUT:\n%s\nOUTPUT:\n%s" % (line, z))
|
|
586
|
+
return z
|
|
587
|
+
|
|
588
|
+
def _eval_line_using_file(self, line, *args, **kwargs):
|
|
589
|
+
"""
|
|
590
|
+
EXAMPLES::
|
|
591
|
+
|
|
592
|
+
sage: maple._eval_line_using_file('2+2') # optional - maple
|
|
593
|
+
'4'
|
|
594
|
+
"""
|
|
595
|
+
line += ';' # Adds the maple ";" thing like in self._eval_line
|
|
596
|
+
return Expect._eval_line_using_file(self, line, *args, **kwargs)
|
|
597
|
+
|
|
598
|
+
def cputime(self, t=None):
|
|
599
|
+
r"""
|
|
600
|
+
Return the amount of CPU time that the Maple session has used.
|
|
601
|
+
|
|
602
|
+
If ``t`` is not None, then it returns the difference
|
|
603
|
+
between the current CPU time and ``t``.
|
|
604
|
+
|
|
605
|
+
EXAMPLES::
|
|
606
|
+
|
|
607
|
+
sage: # optional - maple
|
|
608
|
+
sage: t = maple.cputime()
|
|
609
|
+
sage: t # random
|
|
610
|
+
0.02
|
|
611
|
+
sage: x = maple('x')
|
|
612
|
+
sage: maple.diff(x^2, x)
|
|
613
|
+
2*x
|
|
614
|
+
sage: maple.cputime(t) # random
|
|
615
|
+
0.0
|
|
616
|
+
"""
|
|
617
|
+
if t is None:
|
|
618
|
+
return float(self('time()'))
|
|
619
|
+
return float(self('time() - %s' % float(t)))
|
|
620
|
+
|
|
621
|
+
def set(self, var, value):
|
|
622
|
+
"""
|
|
623
|
+
Set the variable ``var`` to the given ``value``.
|
|
624
|
+
|
|
625
|
+
EXAMPLES::
|
|
626
|
+
|
|
627
|
+
sage: maple.set('xx', '2') # optional - maple
|
|
628
|
+
sage: maple.get('xx') # optional - maple
|
|
629
|
+
'2'
|
|
630
|
+
"""
|
|
631
|
+
cmd = '%s:=%s:' % (var, value)
|
|
632
|
+
out = self.eval(cmd)
|
|
633
|
+
if out.find("error") != -1:
|
|
634
|
+
raise TypeError("Error executing code in Maple\nCODE:\n\t%s\nMaple ERROR:\n\t%s" % (cmd, out))
|
|
635
|
+
|
|
636
|
+
def get(self, var):
|
|
637
|
+
"""
|
|
638
|
+
Get the value of the variable ``var``.
|
|
639
|
+
|
|
640
|
+
EXAMPLES::
|
|
641
|
+
|
|
642
|
+
sage: maple.set('xx', '2') # optional - maple
|
|
643
|
+
sage: maple.get('xx') # optional - maple
|
|
644
|
+
'2'
|
|
645
|
+
"""
|
|
646
|
+
return self.eval('printf("%%q",%s)' % var)
|
|
647
|
+
|
|
648
|
+
def _object_class(self):
|
|
649
|
+
"""
|
|
650
|
+
Return the class of MapleElements.
|
|
651
|
+
|
|
652
|
+
EXAMPLES::
|
|
653
|
+
|
|
654
|
+
sage: maple._object_class()
|
|
655
|
+
<class 'sage.interfaces.maple.MapleElement'>
|
|
656
|
+
|
|
657
|
+
::
|
|
658
|
+
|
|
659
|
+
sage: m = maple(2) # optional - maple
|
|
660
|
+
sage: type(m) # optional - maple
|
|
661
|
+
<class 'sage.interfaces.maple.MapleElement'>
|
|
662
|
+
"""
|
|
663
|
+
return MapleElement
|
|
664
|
+
|
|
665
|
+
def _function_element_class(self):
|
|
666
|
+
"""
|
|
667
|
+
Return the MapleFunctionElement class.
|
|
668
|
+
|
|
669
|
+
EXAMPLES::
|
|
670
|
+
|
|
671
|
+
sage: maple._function_element_class()
|
|
672
|
+
<class 'sage.interfaces.maple.MapleFunctionElement'>
|
|
673
|
+
|
|
674
|
+
::
|
|
675
|
+
|
|
676
|
+
sage: two = maple(2) # optional - maple
|
|
677
|
+
sage: type(two.gcd) # optional - maple
|
|
678
|
+
<class 'sage.interfaces.maple.MapleFunctionElement'>
|
|
679
|
+
"""
|
|
680
|
+
return MapleFunctionElement
|
|
681
|
+
|
|
682
|
+
def _equality_symbol(self):
|
|
683
|
+
"""
|
|
684
|
+
Return the symbol used for equality testing in Maple.
|
|
685
|
+
|
|
686
|
+
EXAMPLES::
|
|
687
|
+
|
|
688
|
+
sage: maple._equality_symbol()
|
|
689
|
+
'='
|
|
690
|
+
|
|
691
|
+
sage: maple(2) == maple(2) # optional - maple
|
|
692
|
+
True
|
|
693
|
+
"""
|
|
694
|
+
return '='
|
|
695
|
+
|
|
696
|
+
def _true_symbol(self):
|
|
697
|
+
"""
|
|
698
|
+
Return the symbol used for truth in Maple.
|
|
699
|
+
|
|
700
|
+
EXAMPLES::
|
|
701
|
+
|
|
702
|
+
sage: maple._true_symbol()
|
|
703
|
+
'true'
|
|
704
|
+
|
|
705
|
+
::
|
|
706
|
+
|
|
707
|
+
sage: maple(2) == maple(2) # optional - maple
|
|
708
|
+
True
|
|
709
|
+
"""
|
|
710
|
+
return 'true'
|
|
711
|
+
|
|
712
|
+
def _assign_symbol(self):
|
|
713
|
+
"""
|
|
714
|
+
Return the symbol used for assignment in Maple.
|
|
715
|
+
|
|
716
|
+
EXAMPLES::
|
|
717
|
+
|
|
718
|
+
sage: maple._assign_symbol()
|
|
719
|
+
':='
|
|
720
|
+
"""
|
|
721
|
+
return ":="
|
|
722
|
+
|
|
723
|
+
def _source(self, s):
|
|
724
|
+
"""
|
|
725
|
+
Try to return the source code of a Maple function ``s`` as a string.
|
|
726
|
+
|
|
727
|
+
EXAMPLES::
|
|
728
|
+
|
|
729
|
+
sage: print(maple._source('curry').strip()) # optional - maple
|
|
730
|
+
... -> subs('_X' = _passed[2 .. _npassed],() -> ...(_X, _passed))
|
|
731
|
+
sage: maple._source('ZZZ') # not tested
|
|
732
|
+
Traceback (most recent call last):
|
|
733
|
+
...
|
|
734
|
+
Exception: no source code could be found
|
|
735
|
+
"""
|
|
736
|
+
cmd = 'echo "interface(verboseproc=2): print(%s);" | maple -q' % s
|
|
737
|
+
src = os.popen(cmd).read()
|
|
738
|
+
if src.strip() == s:
|
|
739
|
+
raise RuntimeError("no source code could be found")
|
|
740
|
+
it = (line.strip() for line in src.splitlines())
|
|
741
|
+
return ''.join(l for l in it if l)
|
|
742
|
+
|
|
743
|
+
def source(self, s):
|
|
744
|
+
"""
|
|
745
|
+
Display the Maple source (if possible) about ``s``.
|
|
746
|
+
|
|
747
|
+
This is the same as
|
|
748
|
+
returning the output produced by the following Maple commands:
|
|
749
|
+
|
|
750
|
+
interface(verboseproc=2): print(s)
|
|
751
|
+
|
|
752
|
+
INPUT:
|
|
753
|
+
|
|
754
|
+
- ``s`` -- string representing the function whose
|
|
755
|
+
source code you want
|
|
756
|
+
|
|
757
|
+
EXAMPLES::
|
|
758
|
+
|
|
759
|
+
sage: maple.source('curry') # not tested
|
|
760
|
+
... -> subs('_X' = _passed[2 .. _npassed],() -> ...(_X, _passed))
|
|
761
|
+
"""
|
|
762
|
+
try:
|
|
763
|
+
pager()(self._source(s))
|
|
764
|
+
except Exception:
|
|
765
|
+
pager()('No source code could be found.')
|
|
766
|
+
|
|
767
|
+
def _help(self, string):
|
|
768
|
+
r"""
|
|
769
|
+
Return the Maple help on ``string``.
|
|
770
|
+
|
|
771
|
+
EXAMPLES::
|
|
772
|
+
|
|
773
|
+
sage: txt = maple._help('igcd') # optional - maple
|
|
774
|
+
sage: txt.find('igcd - greatest common divisor') >= 0 # optional - maple
|
|
775
|
+
True
|
|
776
|
+
"""
|
|
777
|
+
return bytes_to_str(os.popen(f'echo "?{string}" | maple -q').read())
|
|
778
|
+
|
|
779
|
+
def help(self, string):
|
|
780
|
+
"""
|
|
781
|
+
Display Maple help about ``string``.
|
|
782
|
+
|
|
783
|
+
This is the same as typing "?string" in the Maple console.
|
|
784
|
+
|
|
785
|
+
INPUT:
|
|
786
|
+
|
|
787
|
+
- ``string`` -- string to search for in the maple help
|
|
788
|
+
system
|
|
789
|
+
|
|
790
|
+
EXAMPLES::
|
|
791
|
+
|
|
792
|
+
sage: maple.help('Psi') # not tested
|
|
793
|
+
Psi - the Digamma and Polygamma functions
|
|
794
|
+
...
|
|
795
|
+
"""
|
|
796
|
+
pager()(self._help(string))
|
|
797
|
+
|
|
798
|
+
def with_package(self, package):
|
|
799
|
+
"""
|
|
800
|
+
Make a package of Maple procedures available in the interpreter.
|
|
801
|
+
|
|
802
|
+
INPUT:
|
|
803
|
+
|
|
804
|
+
- ``package`` -- string
|
|
805
|
+
|
|
806
|
+
EXAMPLES: Some functions are unknown to Maple until you use with to
|
|
807
|
+
include the appropriate package.
|
|
808
|
+
|
|
809
|
+
::
|
|
810
|
+
|
|
811
|
+
sage: # optional - maple
|
|
812
|
+
sage: maple.quit() # reset maple
|
|
813
|
+
sage: maple('partition(10)')
|
|
814
|
+
partition(10)
|
|
815
|
+
sage: maple('bell(10)')
|
|
816
|
+
bell(10)
|
|
817
|
+
sage: maple.with_package('combinat')
|
|
818
|
+
sage: maple('partition(10)')
|
|
819
|
+
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 2], [1, 1, 1, 1, 1, 1, 2, 2], [1, 1, 1, 1, 2, 2, 2], [1, 1, 2, 2, 2, 2], [2, 2, 2, 2, 2], [1, 1, 1, 1, 1, 1, 1, 3], [1, 1, 1, 1, 1, 2, 3], [1, 1, 1, 2, 2, 3], [1, 2, 2, 2, 3], [1, 1, 1, 1, 3, 3], [1, 1, 2, 3, 3], [2, 2, 3, 3], [1, 3, 3, 3], [1, 1, 1, 1, 1, 1, 4], [1, 1, 1, 1, 2, 4], [1, 1, 2, 2, 4], [2, 2, 2, 4], [1, 1, 1, 3, 4], [1, 2, 3, 4], [3, 3, 4], [1, 1, 4, 4], [2, 4, 4], [1, 1, 1, 1, 1, 5], [1, 1, 1, 2, 5], [1, 2, 2, 5], [1, 1, 3, 5], [2, 3, 5], [1, 4, 5], [5, 5], [1, 1, 1, 1, 6], [1, 1, 2, 6], [2, 2, 6], [1, 3, 6], [4, 6], [1, 1, 1, 7], [1, 2, 7], [3, 7], [1, 1, 8], [2, 8], [1, 9], [10]]
|
|
820
|
+
sage: maple('bell(10)')
|
|
821
|
+
115975
|
|
822
|
+
sage: maple('fibonacci(10)')
|
|
823
|
+
55
|
|
824
|
+
"""
|
|
825
|
+
self.eval('with(%s)' % package)
|
|
826
|
+
|
|
827
|
+
load = with_package
|
|
828
|
+
|
|
829
|
+
def clear(self, var):
|
|
830
|
+
"""
|
|
831
|
+
Clear the variable named ``var``.
|
|
832
|
+
|
|
833
|
+
To clear a Maple variable, you must assign 'itself' to itself.
|
|
834
|
+
In Maple 'expr' prevents expr to be evaluated.
|
|
835
|
+
|
|
836
|
+
EXAMPLES::
|
|
837
|
+
|
|
838
|
+
sage: # optional - maple
|
|
839
|
+
sage: maple.set('xx', '2')
|
|
840
|
+
sage: maple.get('xx')
|
|
841
|
+
'2'
|
|
842
|
+
sage: maple.clear('xx')
|
|
843
|
+
sage: maple.get('xx')
|
|
844
|
+
'xx'
|
|
845
|
+
"""
|
|
846
|
+
self.set(var, f"'{var}'")
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
@instancedoc
|
|
850
|
+
class MapleFunction(ExpectFunction):
|
|
851
|
+
def _instancedoc_(self):
|
|
852
|
+
"""
|
|
853
|
+
Return the Maple help for this function. This gets called when
|
|
854
|
+
doing ``?`` on ``self``.
|
|
855
|
+
|
|
856
|
+
EXAMPLES::
|
|
857
|
+
|
|
858
|
+
sage: txt = maple.igcd._instancedoc_() # optional - maple
|
|
859
|
+
sage: txt.find('igcd - greatest common divisor') >= 0 # optional - maple
|
|
860
|
+
True
|
|
861
|
+
"""
|
|
862
|
+
M = self._parent
|
|
863
|
+
return M._help(self._name)
|
|
864
|
+
|
|
865
|
+
def _sage_src_(self):
|
|
866
|
+
"""
|
|
867
|
+
Return the source code of ``self``.
|
|
868
|
+
|
|
869
|
+
This is the function that eventually gets called when doing
|
|
870
|
+
maple.gcd?? for example.
|
|
871
|
+
|
|
872
|
+
EXAMPLES::
|
|
873
|
+
|
|
874
|
+
sage: print(maple.curry._sage_src_().strip()) # optional - maple
|
|
875
|
+
... -> subs('_X' = _passed[2 .. _npassed],() -> ...(_X, _passed))
|
|
876
|
+
sage: maple.ZZZ._sage_src_() # not tested
|
|
877
|
+
Traceback (most recent call last):
|
|
878
|
+
...
|
|
879
|
+
Exception: no source code could be found
|
|
880
|
+
"""
|
|
881
|
+
M = self._parent
|
|
882
|
+
return M._source(self._name)
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
@instancedoc
|
|
886
|
+
class MapleFunctionElement(FunctionElement):
|
|
887
|
+
def _instancedoc_(self):
|
|
888
|
+
"""
|
|
889
|
+
Return the Maple help for this function.
|
|
890
|
+
|
|
891
|
+
This gets called when doing "?" on ``self``.
|
|
892
|
+
|
|
893
|
+
EXAMPLES::
|
|
894
|
+
|
|
895
|
+
sage: two = maple(2) # optional - maple
|
|
896
|
+
sage: txt = two.igcd._instancedoc_() # optional - maple
|
|
897
|
+
sage: txt.find('igcd - greatest common divisor') >= 0 # optional - maple
|
|
898
|
+
True
|
|
899
|
+
"""
|
|
900
|
+
return self._obj.parent()._help(self._name)
|
|
901
|
+
|
|
902
|
+
def _sage_src_(self):
|
|
903
|
+
"""
|
|
904
|
+
Return the source code of ``self``.
|
|
905
|
+
|
|
906
|
+
EXAMPLES::
|
|
907
|
+
|
|
908
|
+
sage: g = maple('gcd') # optional - maple
|
|
909
|
+
sage: print(g.curry._sage_src_().strip()) # optional - maple
|
|
910
|
+
... -> subs('_X' = _passed[2 .. _npassed],() -> ...(_X, _passed))
|
|
911
|
+
sage: m = maple('2') # optional - maple
|
|
912
|
+
sage: m.ZZZ._sage_src_() # not tested
|
|
913
|
+
Traceback (most recent call last):
|
|
914
|
+
...
|
|
915
|
+
Exception: no source code could be found
|
|
916
|
+
"""
|
|
917
|
+
return self._obj.parent()._source(self._name)
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
@instancedoc
|
|
921
|
+
class MapleElement(ExtraTabCompletion, ExpectElement):
|
|
922
|
+
|
|
923
|
+
def __float__(self):
|
|
924
|
+
"""
|
|
925
|
+
Return a floating point version of ``self``.
|
|
926
|
+
|
|
927
|
+
EXAMPLES::
|
|
928
|
+
|
|
929
|
+
sage: float(maple(1/2)) # optional - maple
|
|
930
|
+
0.5
|
|
931
|
+
sage: type(_) # optional - maple
|
|
932
|
+
<... 'float'>
|
|
933
|
+
"""
|
|
934
|
+
return float(maple.eval('evalf(%s)' % self.name()))
|
|
935
|
+
|
|
936
|
+
def __hash__(self):
|
|
937
|
+
"""
|
|
938
|
+
Return a 64-bit integer representing the hash of ``self``. Since
|
|
939
|
+
Python uses 32-bit hashes, it will automatically convert the result
|
|
940
|
+
of this to a 32-bit hash.
|
|
941
|
+
|
|
942
|
+
These examples are optional, and require Maple to be installed. You
|
|
943
|
+
don't need to install any Sage packages for this.
|
|
944
|
+
|
|
945
|
+
EXAMPLES::
|
|
946
|
+
|
|
947
|
+
sage: # optional - maple
|
|
948
|
+
sage: m = maple('x^2+y^2')
|
|
949
|
+
sage: m.__hash__() # random
|
|
950
|
+
188724254834261060184983038723355865733
|
|
951
|
+
sage: hash(m) # random
|
|
952
|
+
5035731711831192733
|
|
953
|
+
sage: m = maple('x^2+y^3')
|
|
954
|
+
sage: m.__hash__() # random
|
|
955
|
+
264835029579301191531663246434344770556
|
|
956
|
+
sage: hash(m) # random
|
|
957
|
+
-2187277978252104690
|
|
958
|
+
"""
|
|
959
|
+
return int(maple.eval('StringTools:-Hash(convert(%s, string))' % self.name())[1:-1], 16)
|
|
960
|
+
|
|
961
|
+
def _richcmp_(self, other, op):
|
|
962
|
+
"""
|
|
963
|
+
Compare equality between ``self`` and ``other``, using maple.
|
|
964
|
+
|
|
965
|
+
These examples are optional, and require Maple to be installed. You
|
|
966
|
+
don't need to install any Sage packages for this.
|
|
967
|
+
|
|
968
|
+
EXAMPLES::
|
|
969
|
+
|
|
970
|
+
sage: # optional - maple
|
|
971
|
+
sage: a = maple(5)
|
|
972
|
+
sage: b = maple(5)
|
|
973
|
+
sage: a == b
|
|
974
|
+
True
|
|
975
|
+
sage: a == 5
|
|
976
|
+
True
|
|
977
|
+
|
|
978
|
+
::
|
|
979
|
+
|
|
980
|
+
sage: # optional - maple
|
|
981
|
+
sage: c = maple(3)
|
|
982
|
+
sage: a == c
|
|
983
|
+
False
|
|
984
|
+
sage: a < c
|
|
985
|
+
False
|
|
986
|
+
sage: a < 6
|
|
987
|
+
True
|
|
988
|
+
sage: c <= a
|
|
989
|
+
True
|
|
990
|
+
|
|
991
|
+
::
|
|
992
|
+
|
|
993
|
+
sage: # optional - maple
|
|
994
|
+
sage: M = matrix(ZZ, 2, range(1,5))
|
|
995
|
+
sage: Mm = maple(M)
|
|
996
|
+
sage: Mm == Mm
|
|
997
|
+
True
|
|
998
|
+
|
|
999
|
+
TESTS::
|
|
1000
|
+
|
|
1001
|
+
sage: # optional - maple
|
|
1002
|
+
sage: x = var('x')
|
|
1003
|
+
sage: t = maple((x+1)^2)
|
|
1004
|
+
sage: u = maple(x^2+2*x+1)
|
|
1005
|
+
sage: u == t # todo: not implemented
|
|
1006
|
+
True # returns False, should use 'testeq' in maple
|
|
1007
|
+
sage: maple.eval('testeq(%s = %s)' % (t.name(),u.name()))
|
|
1008
|
+
'true'
|
|
1009
|
+
"""
|
|
1010
|
+
P = self.parent()
|
|
1011
|
+
if P.eval("evalb(%s %s %s)" % (self.name(), P._equality_symbol(),
|
|
1012
|
+
other.name())) == P._true_symbol():
|
|
1013
|
+
return rich_to_bool(op, 0)
|
|
1014
|
+
# Maple does not allow comparing objects of different types and
|
|
1015
|
+
# it raises an error in this case.
|
|
1016
|
+
# We catch the error, and return True for <
|
|
1017
|
+
try:
|
|
1018
|
+
if P.eval("evalb(%s %s %s)" % (self.name(), P._lessthan_symbol(),
|
|
1019
|
+
other.name())) == P._true_symbol():
|
|
1020
|
+
return rich_to_bool(op, -1)
|
|
1021
|
+
except RuntimeError as e:
|
|
1022
|
+
msg = str(e)
|
|
1023
|
+
if 'is not valid' in msg and 'to < or <=' in msg:
|
|
1024
|
+
if (hash(str(self)) < hash(str(other))):
|
|
1025
|
+
return rich_to_bool(op, -1)
|
|
1026
|
+
else:
|
|
1027
|
+
return rich_to_bool(op, 1)
|
|
1028
|
+
else:
|
|
1029
|
+
raise RuntimeError(e)
|
|
1030
|
+
if P.eval("evalb(%s %s %s)" % (self.name(), P._greaterthan_symbol(),
|
|
1031
|
+
other.name())) == P._true_symbol():
|
|
1032
|
+
return rich_to_bool(op, 1)
|
|
1033
|
+
return NotImplemented
|
|
1034
|
+
|
|
1035
|
+
def _mul_(self, right):
|
|
1036
|
+
"""
|
|
1037
|
+
These examples are optional, and require Maple to be installed. You
|
|
1038
|
+
don't need to install any Sage packages for this.
|
|
1039
|
+
|
|
1040
|
+
EXAMPLES::
|
|
1041
|
+
|
|
1042
|
+
sage: # optional - maple
|
|
1043
|
+
sage: t = maple(5); u = maple(3)
|
|
1044
|
+
sage: t*u
|
|
1045
|
+
15
|
|
1046
|
+
sage: t._mul_(u)
|
|
1047
|
+
15
|
|
1048
|
+
sage: M = matrix(ZZ,2,range(4))
|
|
1049
|
+
sage: Mm = maple(M)
|
|
1050
|
+
sage: Mm*Mm
|
|
1051
|
+
Matrix(2, 2, [[2,3],[6,11]])
|
|
1052
|
+
|
|
1053
|
+
::
|
|
1054
|
+
|
|
1055
|
+
sage: # optional - maple
|
|
1056
|
+
sage: v = vector(ZZ,2,[2,3])
|
|
1057
|
+
sage: vm = maple(v)
|
|
1058
|
+
sage: vm*Mm
|
|
1059
|
+
Vector[row](2, [6,11])
|
|
1060
|
+
|
|
1061
|
+
::
|
|
1062
|
+
|
|
1063
|
+
sage: t*Mm # optional - maple
|
|
1064
|
+
Matrix(2, 2, [[0,5],[10,15]])
|
|
1065
|
+
"""
|
|
1066
|
+
P = self._check_valid()
|
|
1067
|
+
try:
|
|
1068
|
+
return P.new('%s . %s' % (self._name, right._name))
|
|
1069
|
+
except Exception as msg:
|
|
1070
|
+
raise TypeError(msg)
|
|
1071
|
+
|
|
1072
|
+
def _tab_completion(self):
|
|
1073
|
+
"""
|
|
1074
|
+
EXAMPLES::
|
|
1075
|
+
|
|
1076
|
+
sage: a = maple(2) # optional - maple
|
|
1077
|
+
sage: 'sin' in a._tab_completion() # optional - maple
|
|
1078
|
+
True
|
|
1079
|
+
"""
|
|
1080
|
+
return self.parent()._tab_completion()
|
|
1081
|
+
|
|
1082
|
+
def _latex_(self):
|
|
1083
|
+
r"""
|
|
1084
|
+
You can output Maple expressions in latex.
|
|
1085
|
+
|
|
1086
|
+
EXAMPLES::
|
|
1087
|
+
|
|
1088
|
+
sage: print(latex(maple('(x^4 - y)/(y^2-3*x)'))) # optional - maple
|
|
1089
|
+
{\frac {{x}^{4}-y}{{y}^{2}-3\,x}}
|
|
1090
|
+
sage: print(latex(maple(pi - e^3))) # optional - maple
|
|
1091
|
+
\pi-{{\rm e}^{3}}
|
|
1092
|
+
sage: print(maple(pi - e^3)._latex_()) # optional - maple
|
|
1093
|
+
\pi-{{\rm e}^{3}}
|
|
1094
|
+
|
|
1095
|
+
.. NOTE::
|
|
1096
|
+
|
|
1097
|
+
Some expressions might require the Maple style file
|
|
1098
|
+
``maple2e.sty`` in order to latex correctly.
|
|
1099
|
+
"""
|
|
1100
|
+
return self.parent().eval('latex(%s)' % self.name())
|
|
1101
|
+
|
|
1102
|
+
def op(self, i=None):
|
|
1103
|
+
"""
|
|
1104
|
+
Return the `i`-th operand of this expression.
|
|
1105
|
+
|
|
1106
|
+
INPUT:
|
|
1107
|
+
|
|
1108
|
+
- ``i`` -- integer or ``None``
|
|
1109
|
+
|
|
1110
|
+
EXAMPLES::
|
|
1111
|
+
|
|
1112
|
+
sage: V = maple(vector(QQ,[4,5,6])) # optional - maple
|
|
1113
|
+
sage: V.op(1) # optional - maple
|
|
1114
|
+
3
|
|
1115
|
+
sage: V.op(2) # optional - maple
|
|
1116
|
+
{1 = 4, 2 = 5, 3 = 6}
|
|
1117
|
+
"""
|
|
1118
|
+
if i is None:
|
|
1119
|
+
return self.parent().op(self)
|
|
1120
|
+
return self.parent().op(i, self)
|
|
1121
|
+
|
|
1122
|
+
def _sage_(self):
|
|
1123
|
+
r"""
|
|
1124
|
+
Convert a maple expression back to a Sage expression.
|
|
1125
|
+
|
|
1126
|
+
This currently does not implement a serious parser
|
|
1127
|
+
for the Maple output language.
|
|
1128
|
+
Therefore only very simple expressions will convert successfully.
|
|
1129
|
+
|
|
1130
|
+
REFERENCE:
|
|
1131
|
+
|
|
1132
|
+
https://www.asc.tuwien.ac.at/compmath/download/Monagan_Maple_Programming.pdf
|
|
1133
|
+
|
|
1134
|
+
EXAMPLES::
|
|
1135
|
+
|
|
1136
|
+
sage: m = maple('x^2 + 5*y') # optional - maple
|
|
1137
|
+
sage: m.sage() # optional - maple
|
|
1138
|
+
x^2 + 5*y
|
|
1139
|
+
sage: m._sage_() # optional - maple
|
|
1140
|
+
x^2 + 5*y
|
|
1141
|
+
|
|
1142
|
+
sage: m = maple('sin(sqrt(1-x^2)) * (1 - cos(1/x))^2') # optional - maple
|
|
1143
|
+
sage: m.sage() # optional - maple
|
|
1144
|
+
(cos(1/x) - 1)^2*sin(sqrt(-x^2 + 1))
|
|
1145
|
+
|
|
1146
|
+
Some matrices can be converted back::
|
|
1147
|
+
|
|
1148
|
+
sage: m = matrix(2, 2, [1, 2, x, 3]) # optional - maple
|
|
1149
|
+
sage: mm = maple(m) # optional - maple
|
|
1150
|
+
sage: mm.sage() == m # optional - maple
|
|
1151
|
+
True
|
|
1152
|
+
|
|
1153
|
+
Some vectors can be converted back::
|
|
1154
|
+
|
|
1155
|
+
sage: m = vector([1, x, 2, 3]) # optional - maple
|
|
1156
|
+
sage: mm = maple(m) # optional - maple
|
|
1157
|
+
sage: mm.sage() == m # optional - maple
|
|
1158
|
+
True
|
|
1159
|
+
|
|
1160
|
+
Integers and rationals are converted as such::
|
|
1161
|
+
|
|
1162
|
+
sage: maple(33).sage().parent() # optional - maple
|
|
1163
|
+
Integer Ring
|
|
1164
|
+
sage: maple(191/5).sage().parent() # optional - maple
|
|
1165
|
+
Rational Field
|
|
1166
|
+
|
|
1167
|
+
Sets, lists, sequences::
|
|
1168
|
+
|
|
1169
|
+
sage: maple("[4,5,6]").sage() # optional - maple
|
|
1170
|
+
[4, 5, 6]
|
|
1171
|
+
sage: maple({14,33,6}).sage() # optional - maple
|
|
1172
|
+
{6, 14, 33}
|
|
1173
|
+
sage: maple("seq(i**2,i=1..5)").sage() # optional - maple
|
|
1174
|
+
(1, 4, 9, 16, 25)
|
|
1175
|
+
|
|
1176
|
+
Strings::
|
|
1177
|
+
|
|
1178
|
+
sage: maple('"banane"').sage() # optional - maple
|
|
1179
|
+
'"banane"'
|
|
1180
|
+
|
|
1181
|
+
Floats::
|
|
1182
|
+
|
|
1183
|
+
sage: Z3 = maple('evalf(Zeta(3))') # optional - maple
|
|
1184
|
+
sage: Z3.sage().parent() # optional - maple
|
|
1185
|
+
Real Field with 53 bits of precision
|
|
1186
|
+
|
|
1187
|
+
sage: sq5 = maple('evalf(sqrt(5),100)') # optional - maple
|
|
1188
|
+
sage: sq5 = sq5.sage(); sq5 # optional - maple
|
|
1189
|
+
2.23606797749978969640...
|
|
1190
|
+
sage: sq5.parent() # optional - maple
|
|
1191
|
+
Real Field with 332 bits of precision
|
|
1192
|
+
|
|
1193
|
+
Equations::
|
|
1194
|
+
|
|
1195
|
+
sage: maple("x=4") # optional - maple
|
|
1196
|
+
x = 4
|
|
1197
|
+
sage: _.sage() # optional - maple
|
|
1198
|
+
x == 4
|
|
1199
|
+
|
|
1200
|
+
Functions are now sometimes converted back correctly::
|
|
1201
|
+
|
|
1202
|
+
sage: maple(hypergeometric([3,4],[5],x)) # optional - maple
|
|
1203
|
+
hypergeom([3, 4],[5],x)
|
|
1204
|
+
sage: _.sage() # optional - maple
|
|
1205
|
+
hypergeometric((3, 4), (5,), x)
|
|
1206
|
+
|
|
1207
|
+
sage: maple(zeta(5)) # optional - maple
|
|
1208
|
+
Zeta(5)
|
|
1209
|
+
sage: _.sage() # optional - maple
|
|
1210
|
+
zeta(5)
|
|
1211
|
+
|
|
1212
|
+
sage: maple(psi(2,x)) # optional - maple
|
|
1213
|
+
Psi(2,x)
|
|
1214
|
+
sage: _.sage() # optional - maple
|
|
1215
|
+
psi(2, x)
|
|
1216
|
+
|
|
1217
|
+
sage: maple("4+6*Zeta(3)").sage() # optional - maple
|
|
1218
|
+
6*zeta(3) + 4
|
|
1219
|
+
|
|
1220
|
+
sage: maple("Beta(x,y)^Zeta(9)+1").sage() # optional - maple
|
|
1221
|
+
beta(x, y)^zeta(9) + 1
|
|
1222
|
+
|
|
1223
|
+
Sums and products::
|
|
1224
|
+
|
|
1225
|
+
sage: maple('Sum(x-k,k=1..n)').sage() # optional - maple
|
|
1226
|
+
sum(-k + x, k, 1, n)
|
|
1227
|
+
sage: maple('Product(x-k,k=1..n)').sage() # optional - maple
|
|
1228
|
+
product(-k + x, k, 1, n)
|
|
1229
|
+
|
|
1230
|
+
Integrals::
|
|
1231
|
+
|
|
1232
|
+
sage: maple('Int(exp(x),x=0..y)').sage() # optional - maple
|
|
1233
|
+
integrate(e^x, x, 0, y)
|
|
1234
|
+
"""
|
|
1235
|
+
from sage.matrix.constructor import matrix
|
|
1236
|
+
from sage.modules.free_module_element import vector
|
|
1237
|
+
from sage.rings.integer_ring import ZZ
|
|
1238
|
+
from sage.symbolic.expression import symbol_table
|
|
1239
|
+
symbol_maple = symbol_table["maple"]
|
|
1240
|
+
# The next few lines are a very crude excuse for a maple "parser"
|
|
1241
|
+
maple_type = repr(self.whattype())
|
|
1242
|
+
result = repr(self)
|
|
1243
|
+
result = result.replace("Pi", "pi")
|
|
1244
|
+
if maple_type == 'symbol': # pi
|
|
1245
|
+
pass # left to symbolic ring
|
|
1246
|
+
elif maple_type == 'string': # "banane"
|
|
1247
|
+
return result
|
|
1248
|
+
elif maple_type == 'exprseq': # 2, 2
|
|
1249
|
+
n = self.parent()(f"[{self._name}]").nops()._sage_()
|
|
1250
|
+
return tuple(self[i] for i in range(1, n + 1))
|
|
1251
|
+
elif maple_type == 'set': # {1, 2}
|
|
1252
|
+
n = self.nops()._sage_()
|
|
1253
|
+
return set(self.op(i)._sage_() for i in range(1, n + 1))
|
|
1254
|
+
elif maple_type == 'list': # [1, 2]
|
|
1255
|
+
n = self.nops()._sage_()
|
|
1256
|
+
return [self.op(i)._sage_() for i in range(1, n + 1)]
|
|
1257
|
+
elif maple_type == "Matrix": # Matrix(2, 2, [[1,2],[3,4]])
|
|
1258
|
+
mn = self.op(1)
|
|
1259
|
+
m = mn[1]._sage_()
|
|
1260
|
+
n = mn[2]._sage_()
|
|
1261
|
+
coeffs = [self[i + 1, j + 1]._sage_()
|
|
1262
|
+
for i in range(m) for j in range(n)]
|
|
1263
|
+
return matrix(m, n, coeffs)
|
|
1264
|
+
elif maple_type[:6] == "Vector": # Vector[row](3, [4,5,6])
|
|
1265
|
+
n = self.op(1)._sage_()
|
|
1266
|
+
return vector([self[i + 1]._sage_() for i in range(n)])
|
|
1267
|
+
elif maple_type == 'integer':
|
|
1268
|
+
return ZZ(result)
|
|
1269
|
+
elif maple_type == 'fraction':
|
|
1270
|
+
return self.op(1)._sage_() / self.op(2)._sage_()
|
|
1271
|
+
elif maple_type == "function":
|
|
1272
|
+
# TODO : better back translation of function names
|
|
1273
|
+
fun = str(self.op(0))
|
|
1274
|
+
if fun in ['Sum', 'sum']:
|
|
1275
|
+
from sage.misc.functional import symbolic_sum
|
|
1276
|
+
term = self.op(1)._sage_()
|
|
1277
|
+
variable = self.op(2).op(1)._sage_()
|
|
1278
|
+
bounds = [b._sage_() for b in self.op(2).op(2).op()]
|
|
1279
|
+
return symbolic_sum(term, variable, *bounds, hold=True)
|
|
1280
|
+
if fun in ['Int', 'int']:
|
|
1281
|
+
from sage.misc.functional import integral
|
|
1282
|
+
term = self.op(1)._sage_()
|
|
1283
|
+
variable = self.op(2).op(1)._sage_()
|
|
1284
|
+
bounds = [b._sage_() for b in self.op(2).op(2).op()]
|
|
1285
|
+
return integral(term, variable, *bounds, hold=True)
|
|
1286
|
+
if fun in ['Product', 'product']:
|
|
1287
|
+
from sage.misc.functional import symbolic_prod
|
|
1288
|
+
term = self.op(1)._sage_()
|
|
1289
|
+
variable = self.op(2).op(1)._sage_()
|
|
1290
|
+
bounds = [b._sage_() for b in self.op(2).op(2).op()]
|
|
1291
|
+
return symbolic_prod(term, variable, *bounds, hold=True)
|
|
1292
|
+
else:
|
|
1293
|
+
try:
|
|
1294
|
+
sage_fun = symbol_maple[(fun, int(self.nops()))]
|
|
1295
|
+
if self.nops() == 1:
|
|
1296
|
+
args = [self.op()._sage_()]
|
|
1297
|
+
else:
|
|
1298
|
+
args = [arg._sage_() for arg in self.op()]
|
|
1299
|
+
return sage_fun(*args)
|
|
1300
|
+
except (KeyError, TypeError):
|
|
1301
|
+
pass
|
|
1302
|
+
elif maple_type == "float":
|
|
1303
|
+
from sage.rings.real_mpfr import RealField
|
|
1304
|
+
mantissa = len(repr(self.op(1)))
|
|
1305
|
+
prec = max(53, (mantissa * 13301) // 4004)
|
|
1306
|
+
R = RealField(prec)
|
|
1307
|
+
return R(result)
|
|
1308
|
+
elif maple_type == '`+`':
|
|
1309
|
+
return sum(term._sage_() for term in self.op())
|
|
1310
|
+
elif maple_type == '`*`':
|
|
1311
|
+
from sage.misc.misc_c import prod
|
|
1312
|
+
return prod(term._sage_() for term in self.op())
|
|
1313
|
+
elif maple_type == '`^`':
|
|
1314
|
+
return self.op(1)._sage_()**self.op(2)._sage_()
|
|
1315
|
+
elif maple_type == '`=`': # (1, 1) = 2
|
|
1316
|
+
return (self.op(1)._sage_() == self.op(2)._sage_())
|
|
1317
|
+
try:
|
|
1318
|
+
from sage.symbolic.ring import SR
|
|
1319
|
+
return SR(result)
|
|
1320
|
+
except Exception:
|
|
1321
|
+
raise NotImplementedError("Unable to parse Maple output: %s" % result)
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
maple = Maple() # an instance
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
def reduce_load_Maple():
|
|
1328
|
+
"""
|
|
1329
|
+
Return the maple object created in sage.interfaces.maple.
|
|
1330
|
+
|
|
1331
|
+
EXAMPLES::
|
|
1332
|
+
|
|
1333
|
+
sage: from sage.interfaces.maple import reduce_load_Maple
|
|
1334
|
+
sage: reduce_load_Maple()
|
|
1335
|
+
Maple
|
|
1336
|
+
"""
|
|
1337
|
+
return maple
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
def maple_console():
|
|
1341
|
+
r"""
|
|
1342
|
+
Spawn a new Maple command-line session.
|
|
1343
|
+
|
|
1344
|
+
EXAMPLES::
|
|
1345
|
+
|
|
1346
|
+
sage: maple_console() #not tested
|
|
1347
|
+
|^/| Maple 11 (IBM INTEL LINUX)
|
|
1348
|
+
._|\| |/|_. Copyright (c) Maplesoft, a division of Waterloo Maple Inc. 2007
|
|
1349
|
+
\ MAPLE / All rights reserved. Maple is a trademark of
|
|
1350
|
+
<____ ____> Waterloo Maple Inc.
|
|
1351
|
+
| Type ? for help.
|
|
1352
|
+
>
|
|
1353
|
+
"""
|
|
1354
|
+
from sage.repl.rich_output.display_manager import get_display_manager
|
|
1355
|
+
if not get_display_manager().is_in_terminal():
|
|
1356
|
+
raise RuntimeError('Can use the console only in the terminal. Try %%maple magics instead.')
|
|
1357
|
+
os.system('maple')
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
def __doctest_cleanup():
|
|
1361
|
+
"""
|
|
1362
|
+
EXAMPLES::
|
|
1363
|
+
|
|
1364
|
+
sage: from sage.interfaces.maple import __doctest_cleanup
|
|
1365
|
+
sage: m = maple(2) # optional - maple
|
|
1366
|
+
sage: maple.is_running() # optional - maple
|
|
1367
|
+
True
|
|
1368
|
+
sage: __doctest_cleanup()
|
|
1369
|
+
sage: maple.is_running()
|
|
1370
|
+
False
|
|
1371
|
+
"""
|
|
1372
|
+
import sage.interfaces.quit
|
|
1373
|
+
sage.interfaces.quit.expect_quitall()
|
|
1374
|
+
|
|
1375
|
+
|
|
1376
|
+
"""
|
|
1377
|
+
The following only works in Maple >= 9, I guess, but could
|
|
1378
|
+
be useful.
|
|
1379
|
+
|
|
1380
|
+
From Jaap Spies: In addition Maple has a nice feature the function
|
|
1381
|
+
|
|
1382
|
+
> FunctionAdvisor();
|
|
1383
|
+
|
|
1384
|
+
> FunctionAdvisor(topics, quiet);
|
|
1385
|
+
[DE, analytic_extension, asymptotic_expansion, branch_cuts,
|
|
1386
|
+
branch_points, calling_sequence, class_members,
|
|
1387
|
+
classify_function, definition, describe, differentiation_rule,
|
|
1388
|
+
function_classes, identities, integral_form,
|
|
1389
|
+
known_functions, relate, series, singularities, special_values,
|
|
1390
|
+
specialize, sum_form, synonyms]
|
|
1391
|
+
|
|
1392
|
+
> FunctionAdvisor(syntax, hypergeom);
|
|
1393
|
+
hypergeom([a, b], [c], z)
|
|
1394
|
+
|
|
1395
|
+
Eventually this could be used to do an intelligent command
|
|
1396
|
+
completion.
|
|
1397
|
+
"""
|