|
21 | 21 | eulers_method_2x2_plot, desolve_rk4, desolve_system_rk4,
|
22 | 22 | desolve_odeint, desolve_mintides, desolve_tides_mpfr)
|
23 | 23 |
|
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) |
25 | 26 |
|
26 | 27 | from .transforms.all import *
|
27 | 28 |
|
|
30 | 31 | lazy_import("sage.calculus.riemann", ["Riemann_Map"])
|
31 | 32 | lazy_import("sage.calculus.interpolators", ["polygon_spline", "complex_cubic_spline"])
|
32 | 33 |
|
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 |
| - |
233 | 34 | from . import desolvers
|
0 commit comments