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