Skip to content

Commit 7ace843

Browse files
author
Release Manager
committed
sagemathgh-40265: Migrate from Maxima pexpect interface to ECL interface <!-- ^ Please provide a concise and informative title. --> <!-- ^ Don't put issue numbers in the title, do this in the PR description below. --> <!-- ^ For example, instead of "Fixes sagemath#12345" use "Introduce new method to calculate 1 + 2". --> <!-- v Describe your changes below in detail. --> <!-- v Why is this change required? What problem does it solve? --> <!-- v If this PR resolves an open issue, please link to it here. For example, "Fixes sagemath#12345". --> Fixes sagemath#17753 and fixes sagemath#30071 by migrating the last usages of the pexpect interface to `maxima_lib`. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [ ] The title is concise and informative. - [ ] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on. For example, --> <!-- - sagemath#12345: short description why this is a dependency --> <!-- - sagemath#34567: ... --> URL: sagemath#40265 Reported by: Tobias Diez Reviewer(s): Dima Pasechnik, nbruin, Tobias Diez, user202729, Vincent Macri
2 parents 9f90540 + c67f95d commit 7ace843

File tree

24 files changed

+353
-232
lines changed

24 files changed

+353
-232
lines changed

src/doc/en/constructions/plotting.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ Terminal application.)
214214
::
215215

216216
sage: maxima.eval('load("plotdf");')
217-
'".../share/maxima.../share/dynamics/plotdf.lisp"'
217+
.../share/maxima.../share/dynamics/plotdf.lisp...
218218
sage: maxima.eval('plotdf(x+y,[trajectory_at,2,-0.1]); ') # not tested
219219

220220
This plots a direction field (the plotdf Maxima package was also

src/doc/en/developer/coding_basics.rst

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,6 @@ included in one of the following places:
186186
:func:`importlib.resources.as_file`. It should be imported in the
187187
same way as shown above.
188188

189-
- Older code in the Sage library accesses
190-
the package data in more direct ways. For example,
191-
:sage_root:`src/sage/interfaces/maxima.py` uses the file
192-
:sage_root:`src/sage/interfaces/maxima.lisp` at runtime, so it
193-
refers to it as::
194-
195-
os.path.join(os.path.dirname(__file__), 'sage-maxima.lisp')
196-
197189
- In an appropriate subdirectory of :sage_root:`src/sage/ext_data/`.
198190
(At runtime, it is then available in the directory indicated by
199191
``SAGE_EXTCODE``). For example, if ``file`` is placed in

src/doc/en/reference/calculus/index.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ Internal functionality supporting calculus
5656
- :doc:`sage/symbolic/expression_conversions`
5757
- :doc:`sage/symbolic/benchmark`
5858
- :doc:`sage/symbolic/random_tests`
59-
- :doc:`sage/symbolic/maxima_wrapper`
6059
- :doc:`External integrators <sage/symbolic/integration/external>`
6160
- :doc:`External interpolators <sage/calculus/interpolators>`
6261

@@ -94,7 +93,6 @@ Internal functionality supporting calculus
9493
sage/calculus/interpolators
9594
sage/calculus/functions
9695
sage/calculus/var
97-
sage/symbolic/maxima_wrapper
9896
sage/symbolic/operators
9997
sage/symbolic/benchmark
10098
sage/symbolic/random_tests

src/sage/calculus/calculus.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@
349349
Note that ``x`` is still ``x``, since the
350350
maxima used by the calculus package is different than the one in
351351
the interactive interpreter.
352+
Clear the maxima variables to avoid interference with other tests::
353+
354+
sage: maxima('kill(x,y)')
355+
done
352356
353357
Check to see that the problem with the variables method mentioned
354358
in :issue:`3779` is actually fixed::
@@ -395,7 +399,7 @@
395399
Check if maxima has redundant variables defined after initialization,
396400
see :issue:`9538`::
397401
398-
sage: maxima = sage.interfaces.maxima.maxima
402+
sage: maxima = sage.interfaces.maxima_lib.maxima
399403
sage: maxima('f1')
400404
f1
401405
sage: sage.calculus.calculus.maxima('f1')
@@ -419,26 +423,23 @@
419423
"""
420424

421425
import re
426+
from types import FunctionType
427+
422428
from sage.arith.misc import algebraic_dependency
429+
from sage.interfaces.maxima_lib import maxima
430+
from sage.misc.latex import latex
431+
from sage.misc.parser import LookupNameMaker, Parser
432+
from sage.rings.cc import CC
423433
from sage.rings.integer import Integer
424434
from sage.rings.rational_field import QQ
425435
from sage.rings.real_double import RealDoubleElement
426436
from sage.rings.real_mpfr import RR, create_RealNumber
427-
from sage.rings.cc import CC
428-
429-
from sage.misc.latex import latex
430-
from sage.misc.parser import Parser, LookupNameMaker
431437
from sage.structure.element import Expression
432-
from sage.symbolic.ring import var, SR
433-
from sage.symbolic.symbols import symbol_table
434438
from sage.symbolic.function import Function
435439
from sage.symbolic.function_factory import function_factory
436-
from sage.symbolic.integration.integral import (indefinite_integral,
437-
definite_integral)
438-
439-
from sage.misc.lazy_import import lazy_import
440-
lazy_import('sage.interfaces.maxima_lib', 'maxima')
441-
from types import FunctionType
440+
from sage.symbolic.integration.integral import definite_integral, indefinite_integral
441+
from sage.symbolic.ring import SR, var
442+
from sage.symbolic.symbols import symbol_table
442443

443444

444445
########################################################
@@ -667,6 +668,7 @@ def symbolic_sum(expression, v, a, b, algorithm='maxima', hold=False):
667668
elif algorithm == 'sympy':
668669
expression,v,a,b = (expr._sympy_() for expr in (expression, v, a, b))
669670
from sympy import summation
671+
670672
from sage.interfaces.sympy import sympy_init
671673
sympy_init()
672674
result = summation(expression, (v, a, b))
@@ -920,6 +922,7 @@ def symbolic_product(expression, v, a, b, algorithm='maxima', hold=False):
920922
elif algorithm == 'sympy':
921923
expression,v,a,b = (expr._sympy_() for expr in (expression, v, a, b))
922924
from sympy import product as sproduct
925+
923926
from sage.interfaces.sympy import sympy_init
924927
sympy_init()
925928
result = sproduct(expression, (v, a, b))
@@ -1674,7 +1677,11 @@ def mma_free_limit(expression, v, a, dir=None):
16741677
sage: mma_free_limit(e^(-x), x, a=oo) # optional - internet
16751678
0
16761679
"""
1677-
from sage.interfaces.mathematica import request_wolfram_alpha, parse_moutput_from_json, symbolic_expression_from_mathematica_string
1680+
from sage.interfaces.mathematica import (
1681+
parse_moutput_from_json,
1682+
request_wolfram_alpha,
1683+
symbolic_expression_from_mathematica_string,
1684+
)
16781685
dir_plus = ['plus', '+', 'above', 'right']
16791686
dir_minus = ['minus', '-', 'below', 'left']
16801687
math_expr = expression._mathematica_init_()
@@ -1915,6 +1922,7 @@ def laplace(ex, t, s, algorithm='maxima'):
19151922
elif algorithm == 'sympy':
19161923
ex_sy, t, s = (expr._sympy_() for expr in (ex, t, s))
19171924
from sympy import laplace_transform
1925+
19181926
from sage.interfaces.sympy import sympy_init
19191927
sympy_init()
19201928
result = laplace_transform(ex_sy, t, s)
@@ -2100,6 +2108,7 @@ def inverse_laplace(ex, s, t, algorithm='maxima'):
21002108
elif algorithm == 'sympy':
21012109
ex_sy, s, t = (expr._sympy_() for expr in (ex, s, t))
21022110
from sympy import inverse_laplace_transform
2111+
21032112
from sage.interfaces.sympy import sympy_init
21042113
sympy_init()
21052114
result = inverse_laplace_transform(ex_sy, s, t)
@@ -2460,10 +2469,12 @@ def symbolic_expression_from_maxima_string(x, equals_sub=False, maxima=maxima):
24602469
24612470
Make sure that we don't accidentally pick up variables in the maxima namespace (:issue:`8734`)::
24622471
2463-
sage: sage.calculus.calculus.maxima('my_new_var : 2')
2472+
sage: maxima('my_new_var : 2')
24642473
2
24652474
sage: var('my_new_var').full_simplify()
24662475
my_new_var
2476+
sage: maxima('kill(my_new_var)')
2477+
done
24672478
24682479
ODE solution constants are treated differently (:issue:`16007`)::
24692480

src/sage/calculus/desolvers.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,15 @@
7171
# https://www.gnu.org/licenses/
7272
##########################################################################
7373

74-
import shutil
7574
import os
75+
import shutil
7676

77-
from sage.interfaces.maxima import Maxima
77+
from sage.calculus.functional import diff
78+
from sage.interfaces.maxima_lib import maxima
7879
from sage.misc.functional import N
7980
from sage.rings.real_mpfr import RealField
8081
from sage.structure.element import Expression
8182

82-
from .functional import diff
83-
84-
85-
maxima = Maxima()
86-
8783

8884
def fricas_desolve(de, dvar, ics, ivar):
8985
r"""
@@ -156,8 +152,8 @@ def fricas_desolve_system(des, dvars, ics, ivar):
156152
[x(t) == cos(t)^2 + sin(t)^2 + 2*sin(t), y(t) == -2*cos(t) + 1]
157153
"""
158154
from sage.interfaces.fricas import fricas
159-
from sage.symbolic.ring import SR
160155
from sage.symbolic.relation import solve
156+
from sage.symbolic.ring import SR
161157
ops = [dvar.operator() for dvar in dvars]
162158
y = fricas(des).solve(ops, ivar).sage()
163159
basis = y["basis"]
@@ -1364,9 +1360,9 @@ def desolve_rk4_inner(de, dvar):
13641360
return plot_slope_field(de, (ivar, XMIN, XMAX), (dvar, YMIN, YMAX)) + R
13651361

13661362
if not (isinstance(dvar, Expression) and dvar.is_symbol()):
1367-
from sage.symbolic.ring import SR
13681363
from sage.calculus.functional import diff
13691364
from sage.symbolic.relation import solve
1365+
from sage.symbolic.ring import SR
13701366
if isinstance(de, Expression) and de.is_relational():
13711367
de = de.lhs() - de.rhs()
13721368
# consider to add warning if the solution is not unique
@@ -1614,8 +1610,9 @@ def desolve_odeint(des, ics, times, dvars, ivar=None, compute_jac=False, args=()
16141610
"""
16151611

16161612
from scipy.integrate import odeint
1617-
from sage.ext.fast_eval import fast_float
1613+
16181614
from sage.calculus.functions import jacobian
1615+
from sage.ext.fast_eval import fast_float
16191616

16201617
def desolve_odeint_inner(ivar):
16211618
# one-dimensional systems:
@@ -1838,9 +1835,9 @@ def desolve_tides_mpfr(f, ics, initial, final, delta, tolrel=1e-16, tolabs=1e-16
18381835
import subprocess
18391836
if subprocess.call('command -v gcc', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE):
18401837
raise RuntimeError('Unable to run because gcc cannot be found')
1841-
from sage.interfaces.tides import genfiles_mpfr
1842-
from sage.functions.other import ceil
18431838
from sage.functions.log import log
1839+
from sage.functions.other import ceil
1840+
from sage.interfaces.tides import genfiles_mpfr
18441841
from sage.misc.temporary_file import tmp_dir
18451842
tempdir = tmp_dir()
18461843
intfile = os.path.join(tempdir, 'integrator.c')

src/sage/categories/pushout.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3936,6 +3936,7 @@ def __init__(self, box):
39363936
TESTS::
39373937
39383938
sage: from sage.categories.pushout import BlackBoxConstructionFunctor
3939+
sage: from sage.interfaces.maxima_lib import maxima
39393940
sage: FG = BlackBoxConstructionFunctor(gap)
39403941
sage: FM = BlackBoxConstructionFunctor(maxima) # needs sage.symbolic
39413942
sage: FM == FG # needs sage.libs.gap sage.symbolic
@@ -3967,6 +3968,7 @@ def __eq__(self, other):
39673968
TESTS::
39683969
39693970
sage: from sage.categories.pushout import BlackBoxConstructionFunctor
3971+
sage: from sage.interfaces.maxima_lib import maxima
39703972
sage: FG = BlackBoxConstructionFunctor(gap)
39713973
sage: FM = BlackBoxConstructionFunctor(maxima) # needs sage.symbolic
39723974
sage: FM == FG # indirect doctest # needs sage.libs.gap sage.symbolic
@@ -3986,6 +3988,7 @@ def __ne__(self, other):
39863988
EXAMPLES::
39873989
39883990
sage: from sage.categories.pushout import BlackBoxConstructionFunctor
3991+
sage: from sage.interfaces.maxima_lib import maxima
39893992
sage: FG = BlackBoxConstructionFunctor(gap)
39903993
sage: FM = BlackBoxConstructionFunctor(maxima) # needs sage.symbolic
39913994
sage: FM != FG # indirect doctest # needs sage.libs.gap sage.symbolic

src/sage/features/sagemath.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,6 @@ def __init__(self):
11161116
PythonModule('sage.interfaces.maple'),
11171117
PythonModule('sage.interfaces.mathematica'),
11181118
PythonModule('sage.interfaces.mathics'),
1119-
PythonModule('sage.interfaces.maxima'),
11201119
PythonModule('sage.interfaces.maxima_abstract'),
11211120
PythonModule('sage.interfaces.maxima_lib'),
11221121
PythonModule('sage.interfaces.qepcad'),

src/sage/functions/orthogonal_polys.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,12 @@
396396
import warnings
397397

398398
import sage.rings.abc
399-
400399
from sage.arith.misc import rising_factorial
401400
from sage.misc.lazy_import import lazy_import
402401
from sage.rings.integer_ring import ZZ
403402
from sage.rings.rational_field import QQ
404-
from sage.symbolic.function import BuiltinFunction, GinacFunction
405403
from sage.structure.element import Expression, parent
404+
from sage.symbolic.function import BuiltinFunction, GinacFunction
406405

407406
lazy_import('sage.functions.other', ['factorial', 'binomial'])
408407

@@ -2444,8 +2443,8 @@ def _eval_(self, n, x, *args, **kwds):
24442443
sage: laguerre(-9,2) # needs sage.symbolic
24452444
66769/315*e^2
24462445
"""
2447-
from sage.rings.integer import Integer
24482446
from sage.functions.log import exp
2447+
from sage.rings.integer import Integer
24492448
ret = self._eval_special_values_(n, x)
24502449
if ret is not None:
24512450
return ret
@@ -2558,14 +2557,15 @@ def __init__(self):
25582557
25592558
EXAMPLES::
25602559
2560+
sage: from sage.interfaces.maxima_lib import maxima
25612561
sage: # needs sage.symbolic
25622562
sage: a, n, x = var('a, n, x')
25632563
sage: gen_laguerre(x, x, x)._sympy_() # needs sympy
25642564
assoc_laguerre(x, x, x)
25652565
sage: maxima(gen_laguerre(1, 2, x, hold=True))
25662566
3*(1-_SAGE_VAR_x/3)
25672567
sage: maxima(gen_laguerre(n, a, gen_laguerre(n, a, x)))
2568-
gen_laguerre(_SAGE_VAR_n,_SAGE_VAR_a, gen_laguerre(_SAGE_VAR_n,_SAGE_VAR_a,_SAGE_VAR_x))
2568+
gen_laguerre(_SAGE_VAR_n,_SAGE_VAR_a,gen_laguerre(_SAGE_VAR_n,_SAGE_VAR_a,_SAGE_VAR_x))
25692569
25702570
TESTS::
25712571
@@ -2914,8 +2914,8 @@ def _eval_(self, n, x, b, c, *args, **kwds):
29142914
if kwds.get('hold', False):
29152915
return None
29162916
if n not in ZZ or n < 0:
2917-
from sage.functions.hypergeometric import hypergeometric
29182917
from sage.functions.gamma import gamma
2918+
from sage.functions.hypergeometric import hypergeometric
29192919
return gamma(b + n) / gamma(b) * hypergeometric([-n, -x], [b], 1 - 1/c)
29202920
try:
29212921
return self.eval_formula(n, x, b, c)

src/sage/interfaces/all.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
# interfaces to other interpreters
22

3-
# import problems
4-
try:
5-
# from maxima_lib import maxima_lib
6-
from sage.interfaces.maxima import maxima, Maxima
7-
except ImportError:
8-
pass
9-
103
from sage.misc.lazy_import import lazy_import
114

5+
lazy_import('sage.interfaces.maxima', 'maxima')
126
lazy_import('sage.interfaces.sage0', ['sage0', 'sage0_version', 'Sage'])
137
lazy_import('sage.interfaces.axiom', ['Axiom', 'axiom'])
148
lazy_import('sage.interfaces.ecm', ['ECM', 'ecm'])

0 commit comments

Comments
 (0)