passagemath-symbolics 10.6.40__cp314-cp314t-macosx_13_0_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/.dylibs/libgmp.10.dylib +0 -0
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.40.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.40.dist-info/RECORD +172 -0
- passagemath_symbolics-10.6.40.dist-info/WHEEL +6 -0
- passagemath_symbolics-10.6.40.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-darwin.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-darwin.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-darwin.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-darwin.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-darwin.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
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Factory for symbolic functions
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
###############################################################################
|
|
7
|
+
# Sage: Open Source Mathematical Software
|
|
8
|
+
# Copyright (C) 2009 Burcin Erocal <burcin@erocal.org>
|
|
9
|
+
# Distributed under the terms of the GNU General Public License (GPL),
|
|
10
|
+
# version 2 or any later version. The full text of the GPL is available at:
|
|
11
|
+
# https://www.gnu.org/licenses/
|
|
12
|
+
###############################################################################
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from sage.symbolic.function import (SymbolicFunction, sfunctions_funcs,
|
|
16
|
+
unpickle_wrapper)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def function_factory(name, nargs=0, latex_name=None, conversions=None,
|
|
20
|
+
evalf_params_first=True, eval_func=None, evalf_func=None,
|
|
21
|
+
conjugate_func=None, real_part_func=None, imag_part_func=None,
|
|
22
|
+
derivative_func=None, tderivative_func=None, power_func=None,
|
|
23
|
+
series_func=None, print_func=None, print_latex_func=None):
|
|
24
|
+
r"""
|
|
25
|
+
Create a formal symbolic function. For an explanation of the arguments see
|
|
26
|
+
the documentation for the method :meth:`function`.
|
|
27
|
+
|
|
28
|
+
EXAMPLES::
|
|
29
|
+
|
|
30
|
+
sage: from sage.symbolic.function_factory import function_factory
|
|
31
|
+
sage: f = function_factory('f', 2, '\\foo', {'mathematica':'Foo'})
|
|
32
|
+
sage: f(2,4)
|
|
33
|
+
f(2, 4)
|
|
34
|
+
sage: latex(f(1,2))
|
|
35
|
+
\foo\left(1, 2\right)
|
|
36
|
+
sage: f._mathematica_init_()
|
|
37
|
+
'Foo'
|
|
38
|
+
|
|
39
|
+
sage: def evalf_f(self, x, parent=None, algorithm=None): return x*.5r
|
|
40
|
+
sage: g = function_factory('g',1,evalf_func=evalf_f)
|
|
41
|
+
sage: g(2)
|
|
42
|
+
g(2)
|
|
43
|
+
sage: g(2).n()
|
|
44
|
+
1.00000000000000
|
|
45
|
+
"""
|
|
46
|
+
class NewSymbolicFunction(SymbolicFunction):
|
|
47
|
+
def __init__(self):
|
|
48
|
+
"""
|
|
49
|
+
EXAMPLES::
|
|
50
|
+
|
|
51
|
+
sage: from sage.symbolic.function_factory import function_factory
|
|
52
|
+
sage: f = function_factory('f', 2) # indirect doctest
|
|
53
|
+
sage: f(2,4)
|
|
54
|
+
f(2, 4)
|
|
55
|
+
"""
|
|
56
|
+
SymbolicFunction.__init__(self, name, nargs, latex_name,
|
|
57
|
+
conversions, evalf_params_first)
|
|
58
|
+
|
|
59
|
+
def _maxima_init_(self):
|
|
60
|
+
"""
|
|
61
|
+
EXAMPLES::
|
|
62
|
+
|
|
63
|
+
sage: from sage.symbolic.function_factory import function_factory
|
|
64
|
+
sage: f = function_factory('f', 2) # indirect doctest
|
|
65
|
+
sage: f._maxima_init_()
|
|
66
|
+
"'f"
|
|
67
|
+
"""
|
|
68
|
+
return "'%s" % self.name()
|
|
69
|
+
|
|
70
|
+
def _fricas_init_(self):
|
|
71
|
+
"""
|
|
72
|
+
Return the FriCAS equivalent of a formal function.
|
|
73
|
+
|
|
74
|
+
Note that the arity is ignored.
|
|
75
|
+
|
|
76
|
+
EXAMPLES::
|
|
77
|
+
|
|
78
|
+
sage: from sage.symbolic.function_factory import function_factory
|
|
79
|
+
sage: f = function_factory('f', 2) # indirect doctest
|
|
80
|
+
sage: f._fricas_init_()
|
|
81
|
+
'operator("f")'
|
|
82
|
+
"""
|
|
83
|
+
return 'operator("%s")' % self.name()
|
|
84
|
+
|
|
85
|
+
def _sympy_(self):
|
|
86
|
+
from sympy import Function
|
|
87
|
+
return Function(self.name())
|
|
88
|
+
|
|
89
|
+
def __reduce__(self):
|
|
90
|
+
"""
|
|
91
|
+
EXAMPLES::
|
|
92
|
+
|
|
93
|
+
sage: from sage.symbolic.function_factory import function_factory
|
|
94
|
+
sage: f = function_factory('f', 2) # indirect doctest
|
|
95
|
+
sage: nf = loads(dumps(f))
|
|
96
|
+
sage: nf(1, 2)
|
|
97
|
+
f(1, 2)
|
|
98
|
+
"""
|
|
99
|
+
pickled_functions = self.__getstate__()[6]
|
|
100
|
+
return (unpickle_function, (name, nargs, latex_name, conversions,
|
|
101
|
+
evalf_params_first, pickled_functions))
|
|
102
|
+
|
|
103
|
+
l = locals()
|
|
104
|
+
for func_name in sfunctions_funcs:
|
|
105
|
+
func = l.get(func_name+"_func", None)
|
|
106
|
+
if func:
|
|
107
|
+
if not callable(func):
|
|
108
|
+
raise ValueError(func_name + "_func" + " parameter must be callable")
|
|
109
|
+
setattr(NewSymbolicFunction, '_%s_' % func_name, func)
|
|
110
|
+
|
|
111
|
+
return NewSymbolicFunction()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def unpickle_function(name, nargs, latex_name, conversions, evalf_params_first,
|
|
115
|
+
pickled_funcs):
|
|
116
|
+
r"""
|
|
117
|
+
This is returned by the ``__reduce__`` method of symbolic functions to be
|
|
118
|
+
called during unpickling to recreate the given function.
|
|
119
|
+
|
|
120
|
+
It calls :meth:`function_factory` with the supplied arguments.
|
|
121
|
+
|
|
122
|
+
EXAMPLES::
|
|
123
|
+
|
|
124
|
+
sage: from sage.symbolic.function_factory import unpickle_function
|
|
125
|
+
sage: nf = unpickle_function('f', 2, '\\foo', {'mathematica':'Foo'}, True, [])
|
|
126
|
+
sage: nf
|
|
127
|
+
f
|
|
128
|
+
sage: nf(1,2)
|
|
129
|
+
f(1, 2)
|
|
130
|
+
sage: latex(nf(x,x))
|
|
131
|
+
\foo\left(x, x\right)
|
|
132
|
+
sage: nf._mathematica_init_()
|
|
133
|
+
'Foo'
|
|
134
|
+
|
|
135
|
+
sage: from sage.symbolic.function import pickle_wrapper
|
|
136
|
+
sage: def evalf_f(self, x, parent=None, algorithm=None): return 2r*x + 5r
|
|
137
|
+
sage: def conjugate_f(self, x): return x/2r
|
|
138
|
+
sage: nf = unpickle_function('g', 1, None, None, True, [None, pickle_wrapper(evalf_f), pickle_wrapper(conjugate_f)] + [None]*8)
|
|
139
|
+
sage: nf
|
|
140
|
+
g
|
|
141
|
+
sage: nf(2)
|
|
142
|
+
g(2)
|
|
143
|
+
sage: nf(2).n()
|
|
144
|
+
9.00000000000000
|
|
145
|
+
sage: nf(2).conjugate()
|
|
146
|
+
1
|
|
147
|
+
"""
|
|
148
|
+
funcs = [unpickle_wrapper(_) for _ in pickled_funcs]
|
|
149
|
+
args = [name, nargs, latex_name, conversions, evalf_params_first] + funcs
|
|
150
|
+
return function_factory(*args)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def function(s, **kwds) -> SymbolicFunction | list[SymbolicFunction]:
|
|
154
|
+
r"""
|
|
155
|
+
Create a formal symbolic function with the name *s*.
|
|
156
|
+
|
|
157
|
+
INPUT:
|
|
158
|
+
|
|
159
|
+
- ``nargs=0`` -- number of arguments the function accepts, defaults to
|
|
160
|
+
variable number of arguments, or 0
|
|
161
|
+
- ``latex_name`` -- name used when printing in latex mode
|
|
162
|
+
- ``conversions`` -- dictionary specifying names of this function in
|
|
163
|
+
other systems, this is used by the interfaces internally during conversion
|
|
164
|
+
- ``eval_func`` -- method used for automatic evaluation
|
|
165
|
+
- ``evalf_func`` -- method used for numeric evaluation
|
|
166
|
+
- ``evalf_params_first`` -- boolean to indicate if parameters should be
|
|
167
|
+
evaluated numerically before calling the custom evalf function
|
|
168
|
+
- ``conjugate_func`` -- method used for complex conjugation
|
|
169
|
+
- ``real_part_func`` -- method used when taking real parts
|
|
170
|
+
- ``imag_part_func`` -- method used when taking imaginary parts
|
|
171
|
+
- ``derivative_func`` -- method to be used for (partial) derivation
|
|
172
|
+
This method should take a keyword argument deriv_param specifying
|
|
173
|
+
the index of the argument to differentiate w.r.t
|
|
174
|
+
- ``tderivative_func`` -- method to be used for derivatives
|
|
175
|
+
- ``power_func`` -- method used when taking powers
|
|
176
|
+
This method should take a keyword argument power_param specifying
|
|
177
|
+
the exponent
|
|
178
|
+
- ``series_func`` -- method used for series expansion
|
|
179
|
+
This method should expect keyword arguments
|
|
180
|
+
- ``order`` -- order for the expansion to be computed
|
|
181
|
+
- ``var`` -- variable to expand w.r.t.
|
|
182
|
+
- ``at`` -- expand at this value
|
|
183
|
+
- ``print_func`` -- method for custom printing
|
|
184
|
+
- ``print_latex_func`` -- method for custom printing in latex mode
|
|
185
|
+
|
|
186
|
+
Note that custom methods must be instance methods, i.e., expect the instance
|
|
187
|
+
of the symbolic function as the first argument.
|
|
188
|
+
|
|
189
|
+
EXAMPLES::
|
|
190
|
+
|
|
191
|
+
sage: from sage.symbolic.function_factory import function
|
|
192
|
+
sage: var('a, b')
|
|
193
|
+
(a, b)
|
|
194
|
+
sage: cr = function('cr')
|
|
195
|
+
sage: f = cr(a)
|
|
196
|
+
sage: g = f.diff(a).integral(b); g
|
|
197
|
+
b*diff(cr(a), a)
|
|
198
|
+
sage: foo = function("foo", nargs=2)
|
|
199
|
+
sage: x,y,z = var("x y z")
|
|
200
|
+
sage: foo(x, y) + foo(y, z)^2
|
|
201
|
+
foo(y, z)^2 + foo(x, y)
|
|
202
|
+
|
|
203
|
+
You need to use :meth:`substitute_function` to
|
|
204
|
+
replace all occurrences of a function with another::
|
|
205
|
+
|
|
206
|
+
sage: g.substitute_function(cr, cos)
|
|
207
|
+
-b*sin(a)
|
|
208
|
+
|
|
209
|
+
sage: g.substitute_function(cr, (sin(x) + cos(x)).function(x))
|
|
210
|
+
b*(cos(a) - sin(a))
|
|
211
|
+
|
|
212
|
+
Basic arithmetic with unevaluated functions is no
|
|
213
|
+
longer supported::
|
|
214
|
+
|
|
215
|
+
sage: x = var('x')
|
|
216
|
+
sage: f = function('f')
|
|
217
|
+
sage: 2*f
|
|
218
|
+
Traceback (most recent call last):
|
|
219
|
+
...
|
|
220
|
+
TypeError: unsupported operand parent(s) for *: 'Integer Ring' and
|
|
221
|
+
'<class 'sage.symbolic.function_factory...NewSymbolicFunction'>'
|
|
222
|
+
|
|
223
|
+
You now need to evaluate the function in order to do the arithmetic::
|
|
224
|
+
|
|
225
|
+
sage: 2*f(x)
|
|
226
|
+
2*f(x)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
We create a formal function of one variable, write down
|
|
230
|
+
an expression that involves first and second derivatives,
|
|
231
|
+
and extract off coefficients.
|
|
232
|
+
|
|
233
|
+
::
|
|
234
|
+
|
|
235
|
+
sage: r, kappa = var('r,kappa')
|
|
236
|
+
sage: psi = function('psi', nargs=1)(r); psi
|
|
237
|
+
psi(r)
|
|
238
|
+
sage: g = 1/r^2*(2*r*psi.derivative(r,1) + r^2*psi.derivative(r,2)); g
|
|
239
|
+
(r^2*diff(psi(r), r, r) + 2*r*diff(psi(r), r))/r^2
|
|
240
|
+
sage: g.expand()
|
|
241
|
+
2*diff(psi(r), r)/r + diff(psi(r), r, r)
|
|
242
|
+
sage: g.coefficient(psi.derivative(r,2))
|
|
243
|
+
1
|
|
244
|
+
sage: g.coefficient(psi.derivative(r,1))
|
|
245
|
+
2/r
|
|
246
|
+
|
|
247
|
+
Defining custom methods for automatic or numeric evaluation, derivation,
|
|
248
|
+
conjugation, etc. is supported::
|
|
249
|
+
|
|
250
|
+
sage: def ev(self, x): return 2*x
|
|
251
|
+
sage: foo = function("foo", nargs=1, eval_func=ev)
|
|
252
|
+
sage: foo(x)
|
|
253
|
+
2*x
|
|
254
|
+
sage: foo = function("foo", nargs=1, eval_func=lambda self, x: 5)
|
|
255
|
+
sage: foo(x)
|
|
256
|
+
5
|
|
257
|
+
sage: def ef(self, x): pass
|
|
258
|
+
sage: bar = function("bar", nargs=1, eval_func=ef)
|
|
259
|
+
sage: bar(x)
|
|
260
|
+
bar(x)
|
|
261
|
+
|
|
262
|
+
sage: def evalf_f(self, x, parent=None, algorithm=None): return 6
|
|
263
|
+
sage: foo = function("foo", nargs=1, evalf_func=evalf_f)
|
|
264
|
+
sage: foo(x)
|
|
265
|
+
foo(x)
|
|
266
|
+
sage: foo(x).n()
|
|
267
|
+
6
|
|
268
|
+
|
|
269
|
+
sage: foo = function("foo", nargs=1, conjugate_func=ev)
|
|
270
|
+
sage: foo(x).conjugate()
|
|
271
|
+
2*x
|
|
272
|
+
|
|
273
|
+
sage: def deriv(self, *args, **kwds):
|
|
274
|
+
....: print("{} {}".format(args, kwds))
|
|
275
|
+
....: return args[kwds['diff_param']]^2
|
|
276
|
+
sage: foo = function("foo", nargs=2, derivative_func=deriv)
|
|
277
|
+
sage: foo(x,y).derivative(y)
|
|
278
|
+
(x, y) {'diff_param': 1}
|
|
279
|
+
y^2
|
|
280
|
+
|
|
281
|
+
sage: def pow(self, x, power_param=None):
|
|
282
|
+
....: print("{} {}".format(x, power_param))
|
|
283
|
+
....: return x*power_param
|
|
284
|
+
sage: foo = function("foo", nargs=1, power_func=pow)
|
|
285
|
+
sage: foo(y)^(x+y)
|
|
286
|
+
y x + y
|
|
287
|
+
(x + y)*y
|
|
288
|
+
|
|
289
|
+
sage: def expand(self, *args, **kwds):
|
|
290
|
+
....: print("{} {}".format(args, sorted(kwds.items())))
|
|
291
|
+
....: return sum(args[0]^i for i in range(kwds['order']))
|
|
292
|
+
sage: foo = function("foo", nargs=1, series_func=expand)
|
|
293
|
+
sage: foo(y).series(y, 5)
|
|
294
|
+
(y,) [('at', 0), ('options', 0), ('order', 5), ('var', y)]
|
|
295
|
+
y^4 + y^3 + y^2 + y + 1
|
|
296
|
+
|
|
297
|
+
sage: def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args))
|
|
298
|
+
sage: foo = function('t', nargs=2, print_func=my_print)
|
|
299
|
+
sage: foo(x,y^z)
|
|
300
|
+
my args are: x, y^z
|
|
301
|
+
|
|
302
|
+
sage: latex(foo(x,y^z))
|
|
303
|
+
t\left(x, y^{z}\right)
|
|
304
|
+
sage: foo = function('t', nargs=2, print_latex_func=my_print)
|
|
305
|
+
sage: foo(x,y^z)
|
|
306
|
+
t(x, y^z)
|
|
307
|
+
sage: latex(foo(x,y^z))
|
|
308
|
+
my args are: x, y^z
|
|
309
|
+
sage: foo = function('t', nargs=2, latex_name='foo')
|
|
310
|
+
sage: latex(foo(x,y^z))
|
|
311
|
+
foo\left(x, y^{z}\right)
|
|
312
|
+
|
|
313
|
+
Chain rule::
|
|
314
|
+
|
|
315
|
+
sage: def print_args(self, *args, **kwds): print("args: {}".format(args)); print("kwds: {}".format(kwds)); return args[0]
|
|
316
|
+
sage: foo = function('t', nargs=2, tderivative_func=print_args)
|
|
317
|
+
sage: foo(x,x).derivative(x)
|
|
318
|
+
args: (x, x)
|
|
319
|
+
kwds: {'diff_param': x}
|
|
320
|
+
x
|
|
321
|
+
sage: foo = function('t', nargs=2, derivative_func=print_args)
|
|
322
|
+
sage: foo(x,x).derivative(x)
|
|
323
|
+
args: (x, x)
|
|
324
|
+
kwds: {'diff_param': 0}
|
|
325
|
+
args: (x, x)
|
|
326
|
+
kwds: {'diff_param': 1}
|
|
327
|
+
2*x
|
|
328
|
+
|
|
329
|
+
TESTS:
|
|
330
|
+
|
|
331
|
+
Make sure that :issue:`15860` is fixed and whitespaces are removed::
|
|
332
|
+
|
|
333
|
+
sage: C, D, E = function(' C D E')
|
|
334
|
+
sage: C(D(x))
|
|
335
|
+
C(D(x))
|
|
336
|
+
sage: E
|
|
337
|
+
E
|
|
338
|
+
"""
|
|
339
|
+
if not isinstance(s, str):
|
|
340
|
+
raise TypeError("expect string as first argument")
|
|
341
|
+
|
|
342
|
+
# create the function or functions
|
|
343
|
+
if ',' in s:
|
|
344
|
+
names = s.split(',')
|
|
345
|
+
elif ' ' in s:
|
|
346
|
+
names = s.split(' ')
|
|
347
|
+
else:
|
|
348
|
+
names = [s]
|
|
349
|
+
names = [sn.strip() for sn in names if sn.strip()]
|
|
350
|
+
|
|
351
|
+
funcs = tuple(function_factory(name, **kwds) for name in names)
|
|
352
|
+
|
|
353
|
+
if len(funcs) == 1:
|
|
354
|
+
return funcs[0]
|
|
355
|
+
return funcs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
"""Symbolic Integration via External Software
|
|
3
|
+
|
|
4
|
+
TESTS::
|
|
5
|
+
|
|
6
|
+
sage: from sage.symbolic.integration.external import sympy_integrator
|
|
7
|
+
sage: sympy_integrator(sin(x), x) # needs sympy
|
|
8
|
+
-cos(x)
|
|
9
|
+
"""
|
|
10
|
+
from sage.symbolic.expression import Expression
|
|
11
|
+
from sage.symbolic.ring import SR
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def maxima_integrator(expression, v, a=None, b=None):
|
|
15
|
+
"""
|
|
16
|
+
Integration using Maxima.
|
|
17
|
+
|
|
18
|
+
EXAMPLES::
|
|
19
|
+
|
|
20
|
+
sage: from sage.symbolic.integration.external import maxima_integrator
|
|
21
|
+
sage: maxima_integrator(sin(x), x)
|
|
22
|
+
-cos(x)
|
|
23
|
+
sage: maxima_integrator(cos(x), x)
|
|
24
|
+
sin(x)
|
|
25
|
+
sage: f(x) = function('f')(x)
|
|
26
|
+
sage: maxima_integrator(f(x), x)
|
|
27
|
+
integrate(f(x), x)
|
|
28
|
+
|
|
29
|
+
TESTS:
|
|
30
|
+
|
|
31
|
+
Check that :issue:`25817` is fixed::
|
|
32
|
+
|
|
33
|
+
sage: maxima_integrator(log(e^x*log(x)*sin(x))/x^2, x)
|
|
34
|
+
1/2*(x*(Ei(-log(x)) + conjugate(Ei(-log(x))))
|
|
35
|
+
- 2*x*integrate(sin(x)/(x*cos(x)^2 + x*sin(x)^2
|
|
36
|
+
+ 2*x*cos(x) + x), x) + 2*x*integrate(sin(x)/(x*cos(x)^2
|
|
37
|
+
+ x*sin(x)^2 - 2*x*cos(x) + x), x) + 2*x*log(x) + 2*log(2)
|
|
38
|
+
- log(cos(x)^2 + sin(x)^2 + 2*cos(x) + 1) - log(cos(x)^2
|
|
39
|
+
+ sin(x)^2 - 2*cos(x) + 1) - 2*log(log(x)))/x
|
|
40
|
+
"""
|
|
41
|
+
from sage.calculus.calculus import maxima
|
|
42
|
+
if not isinstance(expression, Expression):
|
|
43
|
+
expression = SR(expression)
|
|
44
|
+
if a is None:
|
|
45
|
+
result = maxima.sr_integral(expression, v)
|
|
46
|
+
else:
|
|
47
|
+
result = maxima.sr_integral(expression, v, a, b)
|
|
48
|
+
return result._sage_()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def sympy_integrator(expression, v, a=None, b=None):
|
|
52
|
+
"""
|
|
53
|
+
Integration using SymPy.
|
|
54
|
+
|
|
55
|
+
EXAMPLES::
|
|
56
|
+
|
|
57
|
+
sage: from sage.symbolic.integration.external import sympy_integrator
|
|
58
|
+
sage: sympy_integrator(sin(x), x) # needs sympy
|
|
59
|
+
-cos(x)
|
|
60
|
+
sage: sympy_integrator(cos(x), x) # needs sympy
|
|
61
|
+
sin(x)
|
|
62
|
+
"""
|
|
63
|
+
import sympy
|
|
64
|
+
ex = expression._sympy_()
|
|
65
|
+
v = v._sympy_()
|
|
66
|
+
if a is None:
|
|
67
|
+
result = sympy.integrate(ex, v)
|
|
68
|
+
else:
|
|
69
|
+
result = sympy.integrate(ex, (v, a._sympy_(), b._sympy_()))
|
|
70
|
+
return result._sage_()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def mma_free_integrator(expression, v, a=None, b=None):
|
|
74
|
+
"""
|
|
75
|
+
Integration using Mathematica's online integrator.
|
|
76
|
+
|
|
77
|
+
EXAMPLES::
|
|
78
|
+
|
|
79
|
+
sage: from sage.symbolic.integration.external import mma_free_integrator
|
|
80
|
+
sage: mma_free_integrator(sin(x), x) # optional - internet
|
|
81
|
+
-cos(x)
|
|
82
|
+
|
|
83
|
+
A definite integral::
|
|
84
|
+
|
|
85
|
+
sage: mma_free_integrator(e^(-x), x, a=0, b=oo) # optional - internet
|
|
86
|
+
1
|
|
87
|
+
|
|
88
|
+
TESTS:
|
|
89
|
+
|
|
90
|
+
Check that :issue:`18212` is resolved::
|
|
91
|
+
|
|
92
|
+
sage: var('y') # optional - internet
|
|
93
|
+
y
|
|
94
|
+
sage: result = integral(sin(y)^2, y, algorithm='mathematica_free') # optional - internet
|
|
95
|
+
sage: result.simplify_trig() # optional - internet
|
|
96
|
+
-1/2*cos(y)*sin(y) + 1/2*y
|
|
97
|
+
|
|
98
|
+
Check that :issue:`14764` is resolved::
|
|
99
|
+
|
|
100
|
+
sage: integrate(x^2, x, 0, 1, algorithm='mathematica_free') # optional - internet
|
|
101
|
+
1/3
|
|
102
|
+
sage: integrate(sin(x), [x, 0, pi], algorithm='mathematica_free') # optional - internet
|
|
103
|
+
2
|
|
104
|
+
sage: integrate(sqrt(x), (x, 0, 1), algorithm='mathematica_free') # optional - internet
|
|
105
|
+
2/3
|
|
106
|
+
|
|
107
|
+
::
|
|
108
|
+
|
|
109
|
+
sage: mma_free_integrator(exp(-x^2)*log(x), x) # optional - internet
|
|
110
|
+
1/2*sqrt(pi)*erf(x)*log(x) - x*hypergeometric((1/2, 1/2), (3/2, 3/2), -x^2)
|
|
111
|
+
"""
|
|
112
|
+
from sage.interfaces.mathematica import request_wolfram_alpha, parse_moutput_from_json, symbolic_expression_from_mathematica_string
|
|
113
|
+
math_expr = expression._mathematica_init_()
|
|
114
|
+
variable = v._mathematica_init_()
|
|
115
|
+
if a is None and b is None:
|
|
116
|
+
input = "Integrate[{},{}]".format(math_expr, variable)
|
|
117
|
+
elif a is not None and b is not None:
|
|
118
|
+
input = "Integrate[{},{{{},{},{}}}]".format(math_expr, variable,
|
|
119
|
+
a._mathematica_init_(),
|
|
120
|
+
b._mathematica_init_())
|
|
121
|
+
else:
|
|
122
|
+
raise ValueError('a(={}) and b(={}) should be both None'
|
|
123
|
+
' or both defined'.format(a, b))
|
|
124
|
+
json_page_data = request_wolfram_alpha(input)
|
|
125
|
+
all_outputs = parse_moutput_from_json(json_page_data)
|
|
126
|
+
if not all_outputs:
|
|
127
|
+
raise ValueError("no outputs found in the answer from Wolfram Alpha")
|
|
128
|
+
first_output = all_outputs[0]
|
|
129
|
+
return symbolic_expression_from_mathematica_string(first_output)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def fricas_integrator(expression, v, a=None, b=None, noPole=True):
|
|
133
|
+
"""
|
|
134
|
+
Integration using FriCAS.
|
|
135
|
+
|
|
136
|
+
EXAMPLES::
|
|
137
|
+
|
|
138
|
+
sage: # optional - fricas
|
|
139
|
+
sage: from sage.symbolic.integration.external import fricas_integrator
|
|
140
|
+
sage: fricas_integrator(sin(x), x)
|
|
141
|
+
-cos(x)
|
|
142
|
+
sage: fricas_integrator(cos(x), x)
|
|
143
|
+
sin(x)
|
|
144
|
+
sage: fricas_integrator(1/(x^2-2), x, 0, 1)
|
|
145
|
+
-1/8*sqrt(2)*(log(2) - log(-24*sqrt(2) + 34))
|
|
146
|
+
sage: fricas_integrator(1/(x^2+6), x, -oo, oo)
|
|
147
|
+
1/6*sqrt(6)*pi
|
|
148
|
+
|
|
149
|
+
TESTS:
|
|
150
|
+
|
|
151
|
+
Check that :issue:`25220` is fixed::
|
|
152
|
+
|
|
153
|
+
sage: integral(sqrt(1-cos(x)), x, 0, 2*pi, algorithm='fricas') # optional - fricas
|
|
154
|
+
4*sqrt(2)
|
|
155
|
+
|
|
156
|
+
Check that in case of failure one gets unevaluated integral::
|
|
157
|
+
|
|
158
|
+
sage: integral(cos(ln(cos(x))), x, 0, pi/8, algorithm='fricas') # optional - fricas
|
|
159
|
+
integrate(cos(log(cos(x))), x, 0, 1/8*pi)
|
|
160
|
+
|
|
161
|
+
sage: integral(cos(ln(cos(x))), x, algorithm='fricas') # optional - fricas
|
|
162
|
+
integral(cos(log(cos(x))), x)
|
|
163
|
+
|
|
164
|
+
Check that :issue:`28641` is fixed::
|
|
165
|
+
|
|
166
|
+
sage: integrate(sqrt(2)*x^2 + 2*x, x, algorithm='fricas') # optional - fricas
|
|
167
|
+
1/3*sqrt(2)*x^3 + x^2
|
|
168
|
+
|
|
169
|
+
sage: integrate(sqrt(2), x, algorithm='fricas') # optional - fricas
|
|
170
|
+
sqrt(2)*x
|
|
171
|
+
|
|
172
|
+
sage: integrate(1, x, algorithm='fricas') # optional - fricas
|
|
173
|
+
x
|
|
174
|
+
|
|
175
|
+
Check that :issue:`28630` is fixed::
|
|
176
|
+
|
|
177
|
+
sage: f = polylog(3, x)
|
|
178
|
+
sage: f.integral(x, algorithm='fricas') # optional - fricas
|
|
179
|
+
-x*dilog(x) - (x - 1)*log(-x + 1) + x*polylog(3, x) + x
|
|
180
|
+
|
|
181
|
+
Check that :issue:`29043` is fixed::
|
|
182
|
+
|
|
183
|
+
sage: var("a c d"); f = (I*a*tan(d*x + c) + a)*sec(d*x + c)^10
|
|
184
|
+
(a, c, d)
|
|
185
|
+
sage: ii = integrate(f, x, algorithm='fricas') # optional - fricas
|
|
186
|
+
sage: 1/315*(64512*I*a*e^(10*I*d*x + 10*I*c) + 53760*I*a*e^(8*I*d*x + 8*I*c) + 30720*I*a*e^(6*I*d*x + 6*I*c) + 11520*I*a*e^(4*I*d*x + 4*I*c) + 2560*I*a*e^(2*I*d*x + 2*I*c) + 256*I*a)/(d*e^(20*I*d*x + 20*I*c) + 10*d*e^(18*I*d*x + 18*I*c) + 45*d*e^(16*I*d*x + 16*I*c) + 120*d*e^(14*I*d*x + 14*I*c) + 210*d*e^(12*I*d*x + 12*I*c) + 252*d*e^(10*I*d*x + 10*I*c) + 210*d*e^(8*I*d*x + 8*I*c) + 120*d*e^(6*I*d*x + 6*I*c) + 45*d*e^(4*I*d*x + 4*I*c) + 10*d*e^(2*I*d*x + 2*I*c) + d) - ii # optional - fricas
|
|
187
|
+
0
|
|
188
|
+
"""
|
|
189
|
+
if not isinstance(expression, Expression):
|
|
190
|
+
expression = SR(expression)
|
|
191
|
+
|
|
192
|
+
from sage.interfaces.fricas import fricas
|
|
193
|
+
e_fricas = fricas(expression)
|
|
194
|
+
v_fricas = fricas(v)
|
|
195
|
+
|
|
196
|
+
if a is None:
|
|
197
|
+
result = e_fricas.integrate(v_fricas)
|
|
198
|
+
else:
|
|
199
|
+
seg = fricas.equation(v_fricas, fricas.segment(a, b))
|
|
200
|
+
|
|
201
|
+
if noPole:
|
|
202
|
+
result = e_fricas.integrate(seg, '"noPole"')
|
|
203
|
+
else:
|
|
204
|
+
result = e_fricas.integrate(seg)
|
|
205
|
+
|
|
206
|
+
result = result.sage()
|
|
207
|
+
|
|
208
|
+
if result == "failed":
|
|
209
|
+
result = expression.integrate(v, a, b, hold=True)
|
|
210
|
+
|
|
211
|
+
elif result == "potentialPole":
|
|
212
|
+
raise ValueError("The integrand has a potential pole"
|
|
213
|
+
" in the integration interval")
|
|
214
|
+
|
|
215
|
+
return result
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def libgiac_integrator(expression, v, a=None, b=None):
|
|
219
|
+
r"""
|
|
220
|
+
Integration using libgiac.
|
|
221
|
+
|
|
222
|
+
EXAMPLES::
|
|
223
|
+
|
|
224
|
+
sage: # needs sage.libs.giac
|
|
225
|
+
sage: import sage.libs.giac
|
|
226
|
+
...
|
|
227
|
+
sage: from sage.symbolic.integration.external import libgiac_integrator
|
|
228
|
+
sage: libgiac_integrator(sin(x), x)
|
|
229
|
+
-cos(x)
|
|
230
|
+
sage: libgiac_integrator(1/(x^2+6), x, -oo, oo)
|
|
231
|
+
1/6*sqrt(6)*pi
|
|
232
|
+
|
|
233
|
+
TESTS::
|
|
234
|
+
|
|
235
|
+
sage: # needs sage.libs.giac
|
|
236
|
+
sage: libgiac_integrator(e^(-x^2)*log(x), x)
|
|
237
|
+
integrate(e^(-x^2)*log(x), x)
|
|
238
|
+
|
|
239
|
+
The following integral fails with the Giac Pexpect interface, but works
|
|
240
|
+
with libgiac (:issue:`31873`)::
|
|
241
|
+
|
|
242
|
+
sage: # needs sage.libs.giac
|
|
243
|
+
sage: a, x = var('a,x')
|
|
244
|
+
sage: f = sec(2*a*x)
|
|
245
|
+
sage: F = libgiac_integrator(f, x)
|
|
246
|
+
...
|
|
247
|
+
sage: (F.derivative(x) - f).simplify_trig()
|
|
248
|
+
0
|
|
249
|
+
"""
|
|
250
|
+
try:
|
|
251
|
+
from sage.libs.giac import libgiac
|
|
252
|
+
except ImportError:
|
|
253
|
+
# If libgiac isn't available, return a symbolic answer
|
|
254
|
+
# (without actually integrating anything). This is essentially
|
|
255
|
+
# the failure case of any integration: see below for what we
|
|
256
|
+
# do if libgiac is *available* but unable to do much.
|
|
257
|
+
return expression.integrate(v, a, b, hold=True)
|
|
258
|
+
|
|
259
|
+
from sage.libs.giac.giac import Pygen
|
|
260
|
+
# We call Pygen on first argument because otherwise some
|
|
261
|
+
# expressions involving derivatives result in doctest failures in
|
|
262
|
+
# sage/interfaces/sympy.py
|
|
263
|
+
if a is None:
|
|
264
|
+
result = libgiac.integrate(Pygen(expression), v)
|
|
265
|
+
else:
|
|
266
|
+
result = libgiac.integrate(Pygen(expression), v, a, b)
|
|
267
|
+
if 'integrate' in format(result) or 'integration' in format(result):
|
|
268
|
+
return expression.integrate(v, a, b, hold=True)
|
|
269
|
+
else:
|
|
270
|
+
return result.sage()
|