Skip to content

Commit fc6291c

Browse files
author
Release Manager
committed
sagemathgh-37993: `sage.calculus.expr`: Split out from `sage.calculus.all` <!-- ^ 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". --> Cherry-picked from sagemath#36676/sagemath#37900. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [ ] The description explains in detail what this PR is about. - [x] 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#37993 Reported by: Matthias Köppe Reviewer(s): John H. Palmieri, Matthias Köppe
2 parents 5ebb4c8 + d64bfa1 commit fc6291c

File tree

3 files changed

+207
-201
lines changed

3 files changed

+207
-201
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Using calculus
2323

2424
- :doc:`More about symbolic variables and functions <sage/calculus/var>`
2525
- :doc:`Main operations on symbolic expressions <sage/symbolic/expression>`
26+
- :doc:`sage/calculus/expr`
2627
- :doc:`Assumptions about symbols and functions <sage/symbolic/assumptions>`
2728
- :doc:`sage/symbolic/relation`
2829
- :doc:`sage/symbolic/integration/integral`
@@ -65,6 +66,7 @@ Internal functionality supporting calculus
6566

6667
sage/symbolic/expression
6768
sage/symbolic/callable
69+
sage/calculus/expr
6870
sage/symbolic/assumptions
6971
sage/symbolic/relation
7072
sage/calculus/calculus

src/sage/calculus/all.py

+2-201
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
eulers_method_2x2_plot, desolve_rk4, desolve_system_rk4,
2222
desolve_odeint, desolve_mintides, desolve_tides_mpfr)
2323

24-
from .var import (var, function, clear_vars)
24+
from sage.calculus.expr import symbolic_expression
25+
from sage.calculus.var import (var, function, clear_vars)
2526

2627
from .transforms.all import *
2728

@@ -30,204 +31,4 @@
3031
lazy_import("sage.calculus.riemann", ["Riemann_Map"])
3132
lazy_import("sage.calculus.interpolators", ["polygon_spline", "complex_cubic_spline"])
3233

33-
from sage.modules.free_module_element import vector
34-
from sage.matrix.constructor import matrix
35-
36-
37-
def symbolic_expression(x):
38-
"""
39-
Create a symbolic expression or vector of symbolic expressions from x.
40-
41-
INPUT:
42-
43-
- ``x`` - an object
44-
45-
OUTPUT:
46-
47-
- a symbolic expression.
48-
49-
EXAMPLES::
50-
51-
sage: a = symbolic_expression(3/2); a
52-
3/2
53-
sage: type(a)
54-
<class 'sage.symbolic.expression.Expression'>
55-
sage: R.<x> = QQ[]; type(x)
56-
<class 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>
57-
sage: a = symbolic_expression(2*x^2 + 3); a
58-
2*x^2 + 3
59-
sage: type(a)
60-
<class 'sage.symbolic.expression.Expression'>
61-
sage: from sage.structure.element import Expression
62-
sage: isinstance(a, Expression)
63-
True
64-
sage: a in SR
65-
True
66-
sage: a.parent()
67-
Symbolic Ring
68-
69-
Note that equations exist in the symbolic ring::
70-
71-
sage: E = EllipticCurve('15a'); E
72-
Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10 over Rational Field
73-
sage: symbolic_expression(E)
74-
x*y + y^2 + y == x^3 + x^2 - 10*x - 10
75-
sage: symbolic_expression(E) in SR
76-
True
77-
78-
If ``x`` is a list or tuple, create a vector of symbolic expressions::
79-
80-
sage: v = symbolic_expression([x,1]); v
81-
(x, 1)
82-
sage: v.base_ring()
83-
Symbolic Ring
84-
sage: v = symbolic_expression((x,1)); v
85-
(x, 1)
86-
sage: v.base_ring()
87-
Symbolic Ring
88-
sage: v = symbolic_expression((3,1)); v
89-
(3, 1)
90-
sage: v.base_ring()
91-
Symbolic Ring
92-
sage: E = EllipticCurve('15a'); E
93-
Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10 over Rational Field
94-
sage: v = symbolic_expression([E,E]); v
95-
(x*y + y^2 + y == x^3 + x^2 - 10*x - 10, x*y + y^2 + y == x^3 + x^2 - 10*x - 10)
96-
sage: v.base_ring()
97-
Symbolic Ring
98-
99-
Likewise, if ``x`` is a vector, create a vector of symbolic expressions::
100-
101-
sage: u = vector([1, 2, 3])
102-
sage: v = symbolic_expression(u); v
103-
(1, 2, 3)
104-
sage: v.parent()
105-
Vector space of dimension 3 over Symbolic Ring
106-
107-
If ``x`` is a list or tuple of lists/tuples/vectors, create a matrix of symbolic expressions::
108-
109-
sage: M = symbolic_expression([[1, x, x^2], (x, x^2, x^3), vector([x^2, x^3, x^4])]); M
110-
[ 1 x x^2]
111-
[ x x^2 x^3]
112-
[x^2 x^3 x^4]
113-
sage: M.parent()
114-
Full MatrixSpace of 3 by 3 dense matrices over Symbolic Ring
115-
116-
If ``x`` is a matrix, create a matrix of symbolic expressions::
117-
118-
sage: A = matrix([[1, 2, 3], [4, 5, 6]])
119-
sage: B = symbolic_expression(A); B
120-
[1 2 3]
121-
[4 5 6]
122-
sage: B.parent()
123-
Full MatrixSpace of 2 by 3 dense matrices over Symbolic Ring
124-
125-
If ``x`` is a function, for example defined by a ``lambda`` expression, create a
126-
symbolic function::
127-
128-
sage: f = symbolic_expression(lambda z: z^2 + 1); f
129-
z |--> z^2 + 1
130-
sage: f.parent()
131-
Callable function ring with argument z
132-
sage: f(7)
133-
50
134-
135-
If ``x`` is a list or tuple of functions, or if ``x`` is a function that returns a list
136-
or tuple, create a callable symbolic vector::
137-
138-
sage: symbolic_expression([lambda mu, nu: mu^2 + nu^2, lambda mu, nu: mu^2 - nu^2])
139-
(mu, nu) |--> (mu^2 + nu^2, mu^2 - nu^2)
140-
sage: f = symbolic_expression(lambda uwu: [1, uwu, uwu^2]); f
141-
uwu |--> (1, uwu, uwu^2)
142-
sage: f.parent()
143-
Vector space of dimension 3 over Callable function ring with argument uwu
144-
sage: f(5)
145-
(1, 5, 25)
146-
sage: f(5).parent()
147-
Vector space of dimension 3 over Symbolic Ring
148-
149-
TESTS:
150-
151-
Lists, tuples, and vectors of length 0 become vectors over a symbolic ring::
152-
153-
sage: symbolic_expression([]).parent()
154-
Vector space of dimension 0 over Symbolic Ring
155-
sage: symbolic_expression(()).parent()
156-
Vector space of dimension 0 over Symbolic Ring
157-
sage: symbolic_expression(vector(QQ, 0)).parent()
158-
Vector space of dimension 0 over Symbolic Ring
159-
160-
If a matrix has dimension 0, the result is still a matrix over a symbolic ring::
161-
162-
sage: symbolic_expression(matrix(QQ, 2, 0)).parent()
163-
Full MatrixSpace of 2 by 0 dense matrices over Symbolic Ring
164-
sage: symbolic_expression(matrix(QQ, 0, 3)).parent()
165-
Full MatrixSpace of 0 by 3 dense matrices over Symbolic Ring
166-
167-
Also functions defined using ``def`` can be used, but we do not advertise it as a use case::
168-
169-
sage: def sos(x, y):
170-
....: return x^2 + y^2
171-
sage: symbolic_expression(sos)
172-
(x, y) |--> x^2 + y^2
173-
174-
Functions that take a varying number of arguments or keyword-only arguments are not accepted::
175-
176-
sage: def variadic(x, *y):
177-
....: return x
178-
sage: symbolic_expression(variadic)
179-
Traceback (most recent call last):
180-
...
181-
TypeError: unable to convert <function variadic at 0x...> to a symbolic expression
182-
183-
sage: def function_with_keyword_only_arg(x, *, sign=1):
184-
....: return sign * x
185-
sage: symbolic_expression(function_with_keyword_only_arg)
186-
Traceback (most recent call last):
187-
...
188-
TypeError: unable to convert <function function_with_keyword_only_arg at 0x...>
189-
to a symbolic expression
190-
"""
191-
from sage.symbolic.expression import Expression
192-
from sage.symbolic.ring import SR
193-
from sage.modules.free_module_element import is_FreeModuleElement
194-
from sage.structure.element import is_Matrix
195-
196-
if isinstance(x, Expression):
197-
return x
198-
elif hasattr(x, '_symbolic_'):
199-
return x._symbolic_(SR)
200-
elif isinstance(x, (tuple, list)) or is_FreeModuleElement(x):
201-
expressions = [symbolic_expression(item) for item in x]
202-
if not expressions:
203-
# Make sure it is symbolic also when length is 0
204-
return vector(SR, 0)
205-
if is_FreeModuleElement(expressions[0]):
206-
return matrix(expressions)
207-
return vector(expressions)
208-
elif is_Matrix(x):
209-
if not x.nrows() or not x.ncols():
210-
# Make sure it is symbolic and of correct dimensions
211-
# also when a matrix dimension is 0
212-
return matrix(SR, x.nrows(), x.ncols())
213-
rows = [symbolic_expression(row) for row in x.rows()]
214-
return matrix(rows)
215-
elif callable(x):
216-
from inspect import signature, Parameter
217-
try:
218-
s = signature(x)
219-
except ValueError:
220-
pass
221-
else:
222-
if all(param.kind in (Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD)
223-
for param in s.parameters.values()):
224-
vars = [SR.var(name) for name in s.parameters.keys()]
225-
result = x(*vars)
226-
if isinstance(result, (tuple, list)):
227-
return vector(SR, result).function(*vars)
228-
else:
229-
return SR(result).function(*vars)
230-
return SR(x)
231-
232-
23334
from . import desolvers

0 commit comments

Comments
 (0)