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
sage/symbolic/ring.pyx
ADDED
|
@@ -0,0 +1,1396 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
"""
|
|
3
|
+
The symbolic ring
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# ****************************************************************************
|
|
7
|
+
# Copyright (C) 2008 William Stein <wstein@gmail.com>
|
|
8
|
+
# Copyright (C) 2008-2013 Burcin Erocal <burcin@erocal.org>
|
|
9
|
+
# Copyright (C) 2009 Mike Hansen
|
|
10
|
+
# Copyright (C) 2011 Karl-Dieter Crisman
|
|
11
|
+
# Copyright (C) 2011-2012 Volker Braun
|
|
12
|
+
# Copyright (C) 2013-2019 Frédéric Chapoton
|
|
13
|
+
# Copyright (C) 2014-2020 Marc Mezzarobba
|
|
14
|
+
# Copyright (C) 2015 Bruno Grenet
|
|
15
|
+
# Copyright (C) 2015-2016 Daniel Krenn
|
|
16
|
+
# Copyright (C) 2015-2016 Jeroen Demeyer
|
|
17
|
+
# Copyright (C) 2015-2017 Vincent Delecroix
|
|
18
|
+
# Copyright (C) 2015-2018 Ralf Stephan
|
|
19
|
+
# Copyright (C) 2016 Julian Rüth
|
|
20
|
+
# Copyright (C) 2017 Marcelo Forets
|
|
21
|
+
# Copyright (C) 2018 Martin Rubey
|
|
22
|
+
# Copyright (C) 2019 E. Madison Bray
|
|
23
|
+
# Copyright (C) 2019 Markus Wageringel
|
|
24
|
+
# Copyright (C) 2021 Marius Gerbershagen
|
|
25
|
+
# Copyright (C) 2021 Matthias Koeppe
|
|
26
|
+
#
|
|
27
|
+
# This program is free software: you can redistribute it and/or modify
|
|
28
|
+
# it under the terms of the GNU General Public License as published by
|
|
29
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
30
|
+
# (at your option) any later version.
|
|
31
|
+
# https://www.gnu.org/licenses/
|
|
32
|
+
# ****************************************************************************
|
|
33
|
+
|
|
34
|
+
from sage.rings.integer cimport Integer
|
|
35
|
+
|
|
36
|
+
import sage.rings.abc
|
|
37
|
+
|
|
38
|
+
from sage.symbolic.expression cimport (
|
|
39
|
+
_latex_Expression,
|
|
40
|
+
_repr_Expression,
|
|
41
|
+
new_Expression,
|
|
42
|
+
new_Expression_from_pyobject,
|
|
43
|
+
new_Expression_wild,
|
|
44
|
+
new_Expression_symbol,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
from sage.categories.commutative_rings import CommutativeRings
|
|
48
|
+
from sage.structure.element cimport Element, Expression
|
|
49
|
+
from sage.structure.parent cimport Parent
|
|
50
|
+
from sage.categories.morphism cimport Morphism
|
|
51
|
+
from sage.structure.coerce cimport is_numpy_type
|
|
52
|
+
|
|
53
|
+
import sage.rings.abc
|
|
54
|
+
from sage.rings.integer_ring import ZZ
|
|
55
|
+
|
|
56
|
+
# is_SymbolicVariable used to be defined here; re-export it
|
|
57
|
+
from sage.symbolic.expression import _is_SymbolicVariable as is_SymbolicVariable
|
|
58
|
+
|
|
59
|
+
import keyword
|
|
60
|
+
import operator
|
|
61
|
+
|
|
62
|
+
# Do not allow any of these keywords as identifiers for symbolic variables
|
|
63
|
+
KEYWORDS = set(keyword.kwlist).union(['exec', 'print', 'None', 'True',
|
|
64
|
+
'False', 'nonlocal'])
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
cdef class SymbolicRing(sage.rings.abc.SymbolicRing):
|
|
68
|
+
"""
|
|
69
|
+
Symbolic Ring, parent object for all symbolic expressions.
|
|
70
|
+
"""
|
|
71
|
+
def __init__(self, base_ring=None):
|
|
72
|
+
"""
|
|
73
|
+
Initialize the Symbolic Ring.
|
|
74
|
+
|
|
75
|
+
This is a commutative ring of symbolic expressions and functions.
|
|
76
|
+
|
|
77
|
+
EXAMPLES::
|
|
78
|
+
|
|
79
|
+
sage: SR
|
|
80
|
+
Symbolic Ring
|
|
81
|
+
|
|
82
|
+
TESTS::
|
|
83
|
+
|
|
84
|
+
sage: isinstance(SR, sage.symbolic.ring.SymbolicRing)
|
|
85
|
+
True
|
|
86
|
+
sage: TestSuite(SR).run(skip=['_test_divides'])
|
|
87
|
+
"""
|
|
88
|
+
if base_ring is None:
|
|
89
|
+
base_ring = self
|
|
90
|
+
Parent.__init__(self, base_ring, category=CommutativeRings())
|
|
91
|
+
self._populate_coercion_lists_(convert_method_name='_symbolic_')
|
|
92
|
+
self.symbols = {}
|
|
93
|
+
|
|
94
|
+
def __reduce__(self):
|
|
95
|
+
"""
|
|
96
|
+
EXAMPLES::
|
|
97
|
+
|
|
98
|
+
sage: loads(dumps(SR)) == SR # indirect doctest
|
|
99
|
+
True
|
|
100
|
+
"""
|
|
101
|
+
return the_SymbolicRing, tuple()
|
|
102
|
+
|
|
103
|
+
def _repr_(self) -> str:
|
|
104
|
+
"""
|
|
105
|
+
Return a string representation of ``self``.
|
|
106
|
+
|
|
107
|
+
EXAMPLES::
|
|
108
|
+
|
|
109
|
+
sage: repr(SR)
|
|
110
|
+
'Symbolic Ring'
|
|
111
|
+
"""
|
|
112
|
+
return "Symbolic Ring"
|
|
113
|
+
|
|
114
|
+
def _latex_(self):
|
|
115
|
+
r"""
|
|
116
|
+
Return latex representation of the symbolic ring.
|
|
117
|
+
|
|
118
|
+
EXAMPLES::
|
|
119
|
+
|
|
120
|
+
sage: latex(SR)
|
|
121
|
+
\text{SR}
|
|
122
|
+
sage: M = MatrixSpace(SR, 2); latex(M)
|
|
123
|
+
\mathrm{Mat}_{2\times 2}(\text{SR})
|
|
124
|
+
"""
|
|
125
|
+
return r'\text{SR}'
|
|
126
|
+
|
|
127
|
+
cpdef _coerce_map_from_(self, R):
|
|
128
|
+
"""
|
|
129
|
+
EXAMPLES::
|
|
130
|
+
|
|
131
|
+
sage: SR.coerce(int(2))
|
|
132
|
+
2
|
|
133
|
+
sage: SR.coerce(-infinity)
|
|
134
|
+
-Infinity
|
|
135
|
+
sage: SR.coerce(unsigned_infinity)
|
|
136
|
+
Infinity
|
|
137
|
+
sage: SR.has_coerce_map_from(ZZ['t'])
|
|
138
|
+
True
|
|
139
|
+
sage: SR.has_coerce_map_from(ZZ['t,u,v'])
|
|
140
|
+
True
|
|
141
|
+
sage: SR.has_coerce_map_from(Frac(ZZ['t,u,v']))
|
|
142
|
+
True
|
|
143
|
+
sage: SR.has_coerce_map_from(GF(5)['t'])
|
|
144
|
+
True
|
|
145
|
+
sage: SR.has_coerce_map_from(SR['t'])
|
|
146
|
+
False
|
|
147
|
+
sage: SR.has_coerce_map_from(Integers(8))
|
|
148
|
+
True
|
|
149
|
+
sage: SR.has_coerce_map_from(GF(9, 'a')) # needs sage.rings.finite_rings
|
|
150
|
+
True
|
|
151
|
+
sage: SR.has_coerce_map_from(RealBallField())
|
|
152
|
+
True
|
|
153
|
+
sage: SR.has_coerce_map_from(ComplexBallField())
|
|
154
|
+
True
|
|
155
|
+
sage: SR.has_coerce_map_from(UnsignedInfinityRing)
|
|
156
|
+
True
|
|
157
|
+
|
|
158
|
+
TESTS::
|
|
159
|
+
|
|
160
|
+
sage: SR.has_coerce_map_from(pari) # needs sage.libs.pari
|
|
161
|
+
False
|
|
162
|
+
|
|
163
|
+
Check if arithmetic with bools works (see :issue:`9560`)::
|
|
164
|
+
|
|
165
|
+
sage: SR.has_coerce_map_from(bool)
|
|
166
|
+
True
|
|
167
|
+
sage: SR(5)*True; True*SR(5)
|
|
168
|
+
5
|
|
169
|
+
5
|
|
170
|
+
sage: SR(5)+True; True+SR(5)
|
|
171
|
+
6
|
|
172
|
+
6
|
|
173
|
+
sage: SR(5)-True
|
|
174
|
+
4
|
|
175
|
+
|
|
176
|
+
TESTS::
|
|
177
|
+
|
|
178
|
+
sage: SR.has_coerce_map_from(SR.subring(accepting_variables=('a',)))
|
|
179
|
+
True
|
|
180
|
+
sage: SR.has_coerce_map_from(SR.subring(rejecting_variables=('r',)))
|
|
181
|
+
True
|
|
182
|
+
sage: SR.has_coerce_map_from(SR.subring(no_variables=True))
|
|
183
|
+
True
|
|
184
|
+
|
|
185
|
+
sage: SR.has_coerce_map_from(AA) # needs sage.rings.number_field
|
|
186
|
+
True
|
|
187
|
+
sage: SR.has_coerce_map_from(QQbar) # needs sage.rings.number_field
|
|
188
|
+
True
|
|
189
|
+
"""
|
|
190
|
+
if isinstance(R, type):
|
|
191
|
+
if R in (int, float, complex, bool):
|
|
192
|
+
return True
|
|
193
|
+
|
|
194
|
+
if is_numpy_type(R):
|
|
195
|
+
import numpy
|
|
196
|
+
if (issubclass(R, numpy.integer) or
|
|
197
|
+
issubclass(R, numpy.floating) or
|
|
198
|
+
issubclass(R, numpy.complexfloating)):
|
|
199
|
+
return NumpyToSRMorphism(R)
|
|
200
|
+
else:
|
|
201
|
+
return None
|
|
202
|
+
|
|
203
|
+
if 'sympy' in R.__module__:
|
|
204
|
+
from sympy.core.basic import Basic
|
|
205
|
+
if issubclass(R, Basic):
|
|
206
|
+
return UnderscoreSageMorphism(R, self)
|
|
207
|
+
|
|
208
|
+
return False
|
|
209
|
+
else:
|
|
210
|
+
from sage.rings.fraction_field import FractionField_generic
|
|
211
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
212
|
+
from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
|
|
213
|
+
from sage.rings.polynomial.laurent_polynomial_ring_base import LaurentPolynomialRing_generic
|
|
214
|
+
from sage.rings.infinity import InfinityRing, UnsignedInfinityRing
|
|
215
|
+
from sage.rings.real_lazy import RLF, CLF
|
|
216
|
+
from sage.rings.finite_rings.finite_field_base import FiniteField
|
|
217
|
+
|
|
218
|
+
from sage.symbolic.subring import GenericSymbolicSubring
|
|
219
|
+
|
|
220
|
+
if R._is_numerical():
|
|
221
|
+
# Almost anything with a coercion into any precision of CC
|
|
222
|
+
return R not in (RLF, CLF)
|
|
223
|
+
elif isinstance(R, (PolynomialRing_generic, MPolynomialRing_base,
|
|
224
|
+
FractionField_generic, LaurentPolynomialRing_generic)):
|
|
225
|
+
base = R.base_ring()
|
|
226
|
+
return base is not self and self.has_coerce_map_from(base)
|
|
227
|
+
elif (R is InfinityRing or R is UnsignedInfinityRing
|
|
228
|
+
or isinstance(R, (sage.rings.abc.RealIntervalField,
|
|
229
|
+
sage.rings.abc.ComplexIntervalField,
|
|
230
|
+
sage.rings.abc.RealBallField,
|
|
231
|
+
sage.rings.abc.ComplexBallField,
|
|
232
|
+
sage.rings.abc.IntegerModRing,
|
|
233
|
+
FiniteField))):
|
|
234
|
+
return True
|
|
235
|
+
elif isinstance(R, GenericSymbolicSubring):
|
|
236
|
+
return True
|
|
237
|
+
|
|
238
|
+
def _element_constructor_(self, x):
|
|
239
|
+
r"""
|
|
240
|
+
Convert `x` into the symbolic expression ring SR.
|
|
241
|
+
|
|
242
|
+
EXAMPLES::
|
|
243
|
+
|
|
244
|
+
sage: a = SR(-3/4); a
|
|
245
|
+
-3/4
|
|
246
|
+
sage: type(a)
|
|
247
|
+
<class 'sage.symbolic.expression.Expression'>
|
|
248
|
+
sage: a.parent()
|
|
249
|
+
Symbolic Ring
|
|
250
|
+
sage: K.<a> = QuadraticField(-3) # needs sage.rings.number_field
|
|
251
|
+
sage: a + sin(x) # needs sage.rings.number_field
|
|
252
|
+
I*sqrt(3) + sin(x)
|
|
253
|
+
sage: x = var('x'); y0,y1 = PolynomialRing(ZZ,2,'y').gens()
|
|
254
|
+
sage: x+y0/y1
|
|
255
|
+
x + y0/y1
|
|
256
|
+
sage: x.subs(x=y0/y1)
|
|
257
|
+
y0/y1
|
|
258
|
+
sage: x + int(1)
|
|
259
|
+
x + 1
|
|
260
|
+
|
|
261
|
+
If `a` is already in the symbolic expression ring, coercing returns
|
|
262
|
+
`a` itself (not a copy)::
|
|
263
|
+
|
|
264
|
+
sage: a = SR(-3/4); a
|
|
265
|
+
-3/4
|
|
266
|
+
sage: SR(a) is a
|
|
267
|
+
True
|
|
268
|
+
|
|
269
|
+
A Python complex number::
|
|
270
|
+
|
|
271
|
+
sage: SR(complex(2,-3))
|
|
272
|
+
(2-3j)
|
|
273
|
+
|
|
274
|
+
Any proper subset of the complex numbers::
|
|
275
|
+
|
|
276
|
+
sage: SR(NN)
|
|
277
|
+
Non negative integer semiring
|
|
278
|
+
sage: SR(ZZ)
|
|
279
|
+
Integer Ring
|
|
280
|
+
sage: SR(Set([1/2, 2/3, 3/4]))
|
|
281
|
+
{3/4, 2/3, 1/2}
|
|
282
|
+
sage: SR(RealSet(0, 1))
|
|
283
|
+
(0, 1)
|
|
284
|
+
|
|
285
|
+
TESTS::
|
|
286
|
+
|
|
287
|
+
sage: SR.coerce(int(5))
|
|
288
|
+
5
|
|
289
|
+
sage: SR.coerce(5)
|
|
290
|
+
5
|
|
291
|
+
sage: SR.coerce(float(5))
|
|
292
|
+
5.0
|
|
293
|
+
sage: SR.coerce(5.0)
|
|
294
|
+
5.00000000000000
|
|
295
|
+
|
|
296
|
+
An interval arithmetic number::
|
|
297
|
+
|
|
298
|
+
sage: SR.coerce(RIF(pi))
|
|
299
|
+
3.141592653589794?
|
|
300
|
+
|
|
301
|
+
The complex number `I`::
|
|
302
|
+
|
|
303
|
+
sage: si = SR.coerce(I)
|
|
304
|
+
sage: si^2
|
|
305
|
+
-1
|
|
306
|
+
sage: bool(si == CC.0)
|
|
307
|
+
True
|
|
308
|
+
|
|
309
|
+
Polynomial ring element factorizations::
|
|
310
|
+
|
|
311
|
+
sage: # needs sage.libs.pari
|
|
312
|
+
sage: R.<x> = QQ[]
|
|
313
|
+
sage: SR(factor(5*x^2 - 5))
|
|
314
|
+
5*(x + 1)*(x - 1)
|
|
315
|
+
sage: R.<x,y> = QQ[]
|
|
316
|
+
sage: SR(factor(x^2 - y^2))
|
|
317
|
+
(x + y)*(x - y)
|
|
318
|
+
sage: R.<x,y,z> = QQ[]
|
|
319
|
+
sage: SR(factor(x^2*y^3 + x^2*y^2*z - x*y^3 - x*y^2*z - 2*x*y*z - 2*x*z^2 + 2*y*z + 2*z^2))
|
|
320
|
+
(x*y^2 - 2*z)*(x - 1)*(y + z)
|
|
321
|
+
|
|
322
|
+
Asymptotic expansions::
|
|
323
|
+
|
|
324
|
+
sage: # needs sage.graphs
|
|
325
|
+
sage: A.<x, y> = AsymptoticRing(growth_group='x^ZZ * y^QQ * log(y)^ZZ', coefficient_ring=ZZ)
|
|
326
|
+
sage: s = SR(3*x^5 * log(y) + 4*y^(3/7) + O(x*log(y))); s
|
|
327
|
+
3*x^5*log(y) + 4*y^(3/7) + Order(x*log(y))
|
|
328
|
+
sage: s.operator(), s.operands()
|
|
329
|
+
(<function add_vararg at 0x...>,
|
|
330
|
+
[3*x^5*log(y), 4*y^(3/7), Order(x*log(y))])
|
|
331
|
+
sage: t = s.operands()[0]; t
|
|
332
|
+
3*x^5*log(y)
|
|
333
|
+
sage: t.operator(), t.operands()
|
|
334
|
+
(<function mul_vararg at 0x...>, [x^5, log(y), 3])
|
|
335
|
+
|
|
336
|
+
We get a sensible error message if conversion fails::
|
|
337
|
+
|
|
338
|
+
sage: SR(int)
|
|
339
|
+
Traceback (most recent call last):
|
|
340
|
+
...
|
|
341
|
+
TypeError: unable to convert <... 'int'> to a symbolic expression
|
|
342
|
+
sage: r^(1/2) # needs R
|
|
343
|
+
Traceback (most recent call last):
|
|
344
|
+
...
|
|
345
|
+
TypeError: unsupported operand type(s) for ** or pow(): 'R' and 'sage.rings.rational.Rational'
|
|
346
|
+
|
|
347
|
+
Check that :issue:`22068` is fixed::
|
|
348
|
+
|
|
349
|
+
sage: _ = var('x')
|
|
350
|
+
sage: sin(x).subs(x=RR('NaN'))
|
|
351
|
+
sin(NaN)
|
|
352
|
+
sage: SR(RR('NaN')).is_real()
|
|
353
|
+
False
|
|
354
|
+
sage: sin(x).subs(x=float('NaN'))
|
|
355
|
+
sin(NaN)
|
|
356
|
+
sage: SR(float('NaN')).is_real()
|
|
357
|
+
False
|
|
358
|
+
sage: sin(x).subs(x=complex('NaN'))
|
|
359
|
+
sin(NaN)
|
|
360
|
+
|
|
361
|
+
Check that :issue:`24072` is solved::
|
|
362
|
+
|
|
363
|
+
sage: x = polygen(GF(3))
|
|
364
|
+
sage: a = SR.var('a')
|
|
365
|
+
sage: (2*x + 1) * a
|
|
366
|
+
Traceback (most recent call last):
|
|
367
|
+
...
|
|
368
|
+
TypeError: positive characteristic not allowed in symbolic computations
|
|
369
|
+
|
|
370
|
+
Check support for unicode characters (:issue:`29280`)::
|
|
371
|
+
|
|
372
|
+
sage: SR('λ + 2λ')
|
|
373
|
+
3*λ
|
|
374
|
+
sage: SR('μ') is var('μ')
|
|
375
|
+
True
|
|
376
|
+
sage: SR('λ + * 1')
|
|
377
|
+
Traceback (most recent call last):
|
|
378
|
+
...
|
|
379
|
+
TypeError: Malformed expression: λ + * !!! 1
|
|
380
|
+
"""
|
|
381
|
+
return new_Expression(self, x)
|
|
382
|
+
|
|
383
|
+
def _force_pyobject(self, x, bint force=False, bint recursive=True):
|
|
384
|
+
r"""
|
|
385
|
+
Wrap the given Python object in a symbolic expression even if it
|
|
386
|
+
cannot be coerced to the Symbolic Ring.
|
|
387
|
+
|
|
388
|
+
INPUT:
|
|
389
|
+
|
|
390
|
+
- ``x`` -- a Python object
|
|
391
|
+
|
|
392
|
+
- ``force`` -- boolean (default: ``False``); if ``True``, the Python object
|
|
393
|
+
is taken as is without attempting coercion or list traversal
|
|
394
|
+
|
|
395
|
+
- ``recursive`` -- boolean (default: ``True``); disables recursive
|
|
396
|
+
traversal of lists
|
|
397
|
+
|
|
398
|
+
EXAMPLES::
|
|
399
|
+
|
|
400
|
+
sage: t = SR._force_pyobject(QQ); t
|
|
401
|
+
Rational Field
|
|
402
|
+
sage: type(t)
|
|
403
|
+
<class 'sage.symbolic.expression.Expression'>
|
|
404
|
+
|
|
405
|
+
Testing tuples::
|
|
406
|
+
|
|
407
|
+
sage: t = SR._force_pyobject((1, 2, x, x+1, x+2)); t
|
|
408
|
+
(1, 2, x, x + 1, x + 2)
|
|
409
|
+
sage: t.subs(x = 2*x^2)
|
|
410
|
+
(1, 2, 2*x^2, 2*x^2 + 1, 2*x^2 + 2)
|
|
411
|
+
sage: t.op[0]
|
|
412
|
+
1
|
|
413
|
+
sage: t.op[2]
|
|
414
|
+
x
|
|
415
|
+
|
|
416
|
+
It also works if the argument is a ``list``::
|
|
417
|
+
|
|
418
|
+
sage: t = SR._force_pyobject([1, 2, x, x+1, x+2]); t
|
|
419
|
+
(1, 2, x, x + 1, x + 2)
|
|
420
|
+
sage: t.subs(x = 2*x^2)
|
|
421
|
+
(1, 2, 2*x^2, 2*x^2 + 1, 2*x^2 + 2)
|
|
422
|
+
sage: SR._force_pyobject((QQ, RR, CC))
|
|
423
|
+
(Rational Field, Real Field with 53 bits of precision, Complex Field with 53 bits of precision)
|
|
424
|
+
sage: t = SR._force_pyobject((QQ, (x, x + 1, x + 2), CC)); t
|
|
425
|
+
(Rational Field, (x, x + 1, x + 2), Complex Field with 53 bits of precision)
|
|
426
|
+
sage: t.subs(x=x^2)
|
|
427
|
+
(Rational Field, (x^2, x^2 + 1, x^2 + 2), Complex Field with 53 bits of precision)
|
|
428
|
+
|
|
429
|
+
If ``recursive`` is ``False`` the inner tuple is taken as a Python
|
|
430
|
+
object. This prevents substitution as above::
|
|
431
|
+
|
|
432
|
+
sage: t = SR._force_pyobject((QQ, (x, x + 1, x + 2), CC), recursive=False)
|
|
433
|
+
sage: t
|
|
434
|
+
(Rational Field, (x, x + 1, x + 2), Complex Field with 53 bits
|
|
435
|
+
of precision)
|
|
436
|
+
sage: t.subs(x=x^2)
|
|
437
|
+
(Rational Field, (x, x + 1, x + 2), Complex Field with 53 bits
|
|
438
|
+
of precision)
|
|
439
|
+
"""
|
|
440
|
+
return new_Expression_from_pyobject(self, x, force, recursive)
|
|
441
|
+
|
|
442
|
+
def wild(self, unsigned int n=0):
|
|
443
|
+
r"""
|
|
444
|
+
Return the n-th wild-card for pattern matching and substitution.
|
|
445
|
+
|
|
446
|
+
INPUT:
|
|
447
|
+
|
|
448
|
+
- ``n`` -- nonnegative integer
|
|
449
|
+
|
|
450
|
+
OUTPUT: n-th wildcard expression
|
|
451
|
+
|
|
452
|
+
EXAMPLES::
|
|
453
|
+
|
|
454
|
+
sage: x,y = var('x,y')
|
|
455
|
+
sage: w0 = SR.wild(0); w1 = SR.wild(1)
|
|
456
|
+
sage: pattern = sin(x)*w0*w1^2; pattern
|
|
457
|
+
$1^2*$0*sin(x)
|
|
458
|
+
sage: f = atan(sin(x)*3*x^2); f
|
|
459
|
+
arctan(3*x^2*sin(x))
|
|
460
|
+
sage: f.has(pattern)
|
|
461
|
+
True
|
|
462
|
+
sage: f.subs(pattern == x^2)
|
|
463
|
+
arctan(x^2)
|
|
464
|
+
|
|
465
|
+
TESTS:
|
|
466
|
+
|
|
467
|
+
Check that :issue:`15047` is fixed::
|
|
468
|
+
|
|
469
|
+
sage: latex(SR.wild(0))
|
|
470
|
+
\$0
|
|
471
|
+
|
|
472
|
+
Check that :issue:`21455` is fixed::
|
|
473
|
+
|
|
474
|
+
sage: coth(SR.wild(0))
|
|
475
|
+
coth($0)
|
|
476
|
+
"""
|
|
477
|
+
return new_Expression_wild(self, n)
|
|
478
|
+
|
|
479
|
+
def __contains__(self, x):
|
|
480
|
+
r"""
|
|
481
|
+
``True`` if there is an element of the symbolic ring that is equal to x
|
|
482
|
+
under ``==``.
|
|
483
|
+
|
|
484
|
+
EXAMPLES:
|
|
485
|
+
|
|
486
|
+
The symbolic variable x is in the symbolic ring.::
|
|
487
|
+
|
|
488
|
+
sage: x.parent()
|
|
489
|
+
Symbolic Ring
|
|
490
|
+
sage: x in SR
|
|
491
|
+
True
|
|
492
|
+
|
|
493
|
+
2 is also in the symbolic ring since it is equal to something in
|
|
494
|
+
SR, even though 2's parent is not SR.
|
|
495
|
+
|
|
496
|
+
::
|
|
497
|
+
|
|
498
|
+
sage: 2 in SR
|
|
499
|
+
True
|
|
500
|
+
sage: parent(2)
|
|
501
|
+
Integer Ring
|
|
502
|
+
sage: 1/3 in SR
|
|
503
|
+
True
|
|
504
|
+
"""
|
|
505
|
+
try:
|
|
506
|
+
x2 = self(x)
|
|
507
|
+
return bool(x2 == x)
|
|
508
|
+
except TypeError:
|
|
509
|
+
return False
|
|
510
|
+
|
|
511
|
+
def characteristic(self):
|
|
512
|
+
"""
|
|
513
|
+
Return the characteristic of the symbolic ring, which is 0.
|
|
514
|
+
|
|
515
|
+
OUTPUT: a Sage integer
|
|
516
|
+
|
|
517
|
+
EXAMPLES::
|
|
518
|
+
|
|
519
|
+
sage: c = SR.characteristic(); c
|
|
520
|
+
0
|
|
521
|
+
sage: type(c)
|
|
522
|
+
<class 'sage.rings.integer.Integer'>
|
|
523
|
+
"""
|
|
524
|
+
return Integer(0)
|
|
525
|
+
|
|
526
|
+
def _an_element_(self):
|
|
527
|
+
"""
|
|
528
|
+
Return an element of the symbolic ring, which is used by the
|
|
529
|
+
coercion model.
|
|
530
|
+
|
|
531
|
+
EXAMPLES::
|
|
532
|
+
|
|
533
|
+
sage: SR._an_element_()
|
|
534
|
+
some_variable
|
|
535
|
+
"""
|
|
536
|
+
return self.symbol('some_variable')
|
|
537
|
+
|
|
538
|
+
def is_field(self, proof=True):
|
|
539
|
+
"""
|
|
540
|
+
Return ``True``, since the symbolic expression ring is (for the most
|
|
541
|
+
part) a field.
|
|
542
|
+
|
|
543
|
+
EXAMPLES::
|
|
544
|
+
|
|
545
|
+
sage: SR.is_field()
|
|
546
|
+
True
|
|
547
|
+
"""
|
|
548
|
+
return True
|
|
549
|
+
|
|
550
|
+
def is_finite(self):
|
|
551
|
+
"""
|
|
552
|
+
Return ``False``, since the Symbolic Ring is infinite.
|
|
553
|
+
|
|
554
|
+
EXAMPLES::
|
|
555
|
+
|
|
556
|
+
sage: SR.is_finite()
|
|
557
|
+
False
|
|
558
|
+
"""
|
|
559
|
+
return False
|
|
560
|
+
|
|
561
|
+
cpdef bint is_exact(self) except -2:
|
|
562
|
+
"""
|
|
563
|
+
Return ``False``, because there are approximate elements in the
|
|
564
|
+
symbolic ring.
|
|
565
|
+
|
|
566
|
+
EXAMPLES::
|
|
567
|
+
|
|
568
|
+
sage: SR.is_exact()
|
|
569
|
+
False
|
|
570
|
+
|
|
571
|
+
Here is an inexact element.
|
|
572
|
+
|
|
573
|
+
::
|
|
574
|
+
|
|
575
|
+
sage: SR(1.9393)
|
|
576
|
+
1.93930000000000
|
|
577
|
+
"""
|
|
578
|
+
return False
|
|
579
|
+
|
|
580
|
+
def pi(self):
|
|
581
|
+
"""
|
|
582
|
+
EXAMPLES::
|
|
583
|
+
|
|
584
|
+
sage: SR.pi() is pi
|
|
585
|
+
True
|
|
586
|
+
"""
|
|
587
|
+
from sage.symbolic.constants import pi
|
|
588
|
+
return self(pi)
|
|
589
|
+
|
|
590
|
+
def I(self):
|
|
591
|
+
r"""
|
|
592
|
+
The imaginary unit, viewed as an element of the symbolic ring.
|
|
593
|
+
|
|
594
|
+
EXAMPLES::
|
|
595
|
+
|
|
596
|
+
sage: SR.I()^2
|
|
597
|
+
-1
|
|
598
|
+
sage: SR.I().parent()
|
|
599
|
+
Symbolic Ring
|
|
600
|
+
|
|
601
|
+
TESTS:
|
|
602
|
+
|
|
603
|
+
Test that :issue:`32404` is fixed::
|
|
604
|
+
|
|
605
|
+
sage: SR0 = SR.subring(no_variables=True)
|
|
606
|
+
sage: SR0.I().parent()
|
|
607
|
+
Symbolic Constants Subring
|
|
608
|
+
"""
|
|
609
|
+
from sage.symbolic.constants import I
|
|
610
|
+
return self(I)
|
|
611
|
+
|
|
612
|
+
def symbol(self, name=None, latex_name=None, domain=None):
|
|
613
|
+
"""
|
|
614
|
+
EXAMPLES::
|
|
615
|
+
|
|
616
|
+
sage: t0 = SR.symbol("t0")
|
|
617
|
+
sage: t0.conjugate()
|
|
618
|
+
conjugate(t0)
|
|
619
|
+
|
|
620
|
+
sage: t1 = SR.symbol("t1", domain='real')
|
|
621
|
+
sage: t1.conjugate()
|
|
622
|
+
t1
|
|
623
|
+
|
|
624
|
+
sage: t0.abs()
|
|
625
|
+
abs(t0)
|
|
626
|
+
|
|
627
|
+
sage: t0_2 = SR.symbol("t0", domain='positive')
|
|
628
|
+
sage: t0_2.abs()
|
|
629
|
+
t0
|
|
630
|
+
sage: bool(t0_2 == t0)
|
|
631
|
+
True
|
|
632
|
+
sage: t0.conjugate()
|
|
633
|
+
t0
|
|
634
|
+
|
|
635
|
+
sage: SR.symbol() # temporary variable
|
|
636
|
+
symbol...
|
|
637
|
+
|
|
638
|
+
We propagate the domain to the assumptions database::
|
|
639
|
+
|
|
640
|
+
sage: n = var('n', domain='integer')
|
|
641
|
+
sage: solve([n^2 == 3],n)
|
|
642
|
+
[]
|
|
643
|
+
|
|
644
|
+
TESTS:
|
|
645
|
+
|
|
646
|
+
Test that the parent is set correctly (inheritance)::
|
|
647
|
+
|
|
648
|
+
sage: from sage.symbolic.ring import SymbolicRing
|
|
649
|
+
sage: class MySymbolicRing(SymbolicRing):
|
|
650
|
+
....: def _repr_(self):
|
|
651
|
+
....: return 'My Symbolic Ring'
|
|
652
|
+
sage: MySR = MySymbolicRing()
|
|
653
|
+
sage: MySR.symbol('x').parent()
|
|
654
|
+
My Symbolic Ring
|
|
655
|
+
sage: MySR.var('x').parent() # indirect doctest
|
|
656
|
+
My Symbolic Ring
|
|
657
|
+
sage: MySR.var('blub').parent() # indirect doctest
|
|
658
|
+
My Symbolic Ring
|
|
659
|
+
sage: MySR.an_element().parent()
|
|
660
|
+
My Symbolic Ring
|
|
661
|
+
"""
|
|
662
|
+
return new_Expression_symbol(self, name, latex_name, domain)
|
|
663
|
+
|
|
664
|
+
def temp_var(self, n=None, domain=None):
|
|
665
|
+
"""
|
|
666
|
+
Return one or multiple new unique symbolic variables as an element
|
|
667
|
+
of the symbolic ring. Use this instead of SR.var() if there is a
|
|
668
|
+
possibility of name clashes occuring. Call SR.cleanup_var() once
|
|
669
|
+
the variables are no longer needed or use a `with SR.temp_var()
|
|
670
|
+
as ...` construct.
|
|
671
|
+
|
|
672
|
+
INPUT:
|
|
673
|
+
|
|
674
|
+
- ``n`` -- (optional) positive integer; number of symbolic variables
|
|
675
|
+
|
|
676
|
+
- ``domain`` -- (optional) specify the domain of the variable(s);
|
|
677
|
+
|
|
678
|
+
EXAMPLES:
|
|
679
|
+
|
|
680
|
+
Simple definition of a functional derivative::
|
|
681
|
+
|
|
682
|
+
sage: def functional_derivative(expr, f, x):
|
|
683
|
+
....: with SR.temp_var() as a:
|
|
684
|
+
....: return expr.subs({f(x):a}).diff(a).subs({a:f(x)})
|
|
685
|
+
sage: f = function('f')
|
|
686
|
+
sage: a = var('a')
|
|
687
|
+
sage: functional_derivative(f(a)^2+a,f,a)
|
|
688
|
+
2*f(a)
|
|
689
|
+
|
|
690
|
+
Contrast this to a similar implementation using SR.var(),
|
|
691
|
+
which gives a wrong result in our example::
|
|
692
|
+
|
|
693
|
+
sage: def functional_derivative(expr, f, x):
|
|
694
|
+
....: a = SR.var('a')
|
|
695
|
+
....: return expr.subs({f(x):a}).diff(a).subs({a:f(x)})
|
|
696
|
+
sage: f = function('f')
|
|
697
|
+
sage: a = var('a')
|
|
698
|
+
sage: functional_derivative(f(a)^2+a,f,a)
|
|
699
|
+
2*f(a) + 1
|
|
700
|
+
|
|
701
|
+
TESTS:
|
|
702
|
+
|
|
703
|
+
sage: x = SR.temp_var()
|
|
704
|
+
sage: y = SR.temp_var()
|
|
705
|
+
sage: bool(x == x)
|
|
706
|
+
True
|
|
707
|
+
sage: bool(x == y)
|
|
708
|
+
False
|
|
709
|
+
sage: bool(x.parent()(x._maxima_()) == x)
|
|
710
|
+
True
|
|
711
|
+
"""
|
|
712
|
+
if n is None:
|
|
713
|
+
return self.symbol(None, domain=domain)
|
|
714
|
+
return TemporaryVariables([self.temp_var(domain=domain)
|
|
715
|
+
for i in range(n)])
|
|
716
|
+
|
|
717
|
+
def cleanup_var(self, symbol):
|
|
718
|
+
"""
|
|
719
|
+
Cleans up a variable, removing assumptions about the
|
|
720
|
+
variable and allowing for it to be garbage collected
|
|
721
|
+
|
|
722
|
+
INPUT:
|
|
723
|
+
|
|
724
|
+
- ``symbol`` -- a variable or a list of variables
|
|
725
|
+
|
|
726
|
+
TESTS:
|
|
727
|
+
|
|
728
|
+
sage: from sage.symbolic.assumptions import assumptions
|
|
729
|
+
sage: symbols_copy = SR.symbols.copy()
|
|
730
|
+
sage: assumptions_copy = assumptions().copy()
|
|
731
|
+
sage: x = SR.temp_var(domain='real')
|
|
732
|
+
sage: SR.cleanup_var(x)
|
|
733
|
+
sage: symbols_copy == SR.symbols
|
|
734
|
+
True
|
|
735
|
+
sage: assumptions_copy == assumptions()
|
|
736
|
+
True
|
|
737
|
+
"""
|
|
738
|
+
from sage.symbolic.assumptions import assumptions
|
|
739
|
+
if isinstance(symbol, (list, tuple)):
|
|
740
|
+
for s in symbol:
|
|
741
|
+
self.cleanup_var(s)
|
|
742
|
+
else:
|
|
743
|
+
try:
|
|
744
|
+
name = self._repr_element_(symbol)
|
|
745
|
+
del self.symbols[name]
|
|
746
|
+
except KeyError:
|
|
747
|
+
pass
|
|
748
|
+
for asm in assumptions():
|
|
749
|
+
if asm.has(symbol):
|
|
750
|
+
asm.forget()
|
|
751
|
+
|
|
752
|
+
def var(self, name, latex_name=None, n=None, domain=None):
|
|
753
|
+
r"""
|
|
754
|
+
Return a symbolic variable as an element of the symbolic ring.
|
|
755
|
+
|
|
756
|
+
INPUT:
|
|
757
|
+
|
|
758
|
+
- ``name`` -- string or list of strings with the name(s) of the symbolic variable(s)
|
|
759
|
+
|
|
760
|
+
- ``latex_name`` -- (optional) string used when printing in latex mode, if not specified use ``'name'``
|
|
761
|
+
|
|
762
|
+
- ``n`` -- (optional) positive integer; number of symbolic variables, indexed from `0` to `n-1`
|
|
763
|
+
|
|
764
|
+
- ``domain`` -- (optional) specify the domain of the variable(s); it is None
|
|
765
|
+
by default, and possible options are (non-exhaustive list, see note below):
|
|
766
|
+
``'real'``, ``'complex'``, ``'positive'``, ``'integer'`` and ``'noninteger'``
|
|
767
|
+
|
|
768
|
+
OUTPUT: symbolic expression or tuple of symbolic expressions
|
|
769
|
+
|
|
770
|
+
.. SEEALSO::
|
|
771
|
+
|
|
772
|
+
This function does not inject the variable(s) into the global namespace.
|
|
773
|
+
For that purpose see :meth:`var()<sage.calculus.var.var>`.
|
|
774
|
+
|
|
775
|
+
.. NOTE::
|
|
776
|
+
|
|
777
|
+
For a comprehensive list of acceptable features type ``'maxima('features')'``,
|
|
778
|
+
and see also the documentation of :ref:`sage.symbolic.assumptions`.
|
|
779
|
+
|
|
780
|
+
EXAMPLES:
|
|
781
|
+
|
|
782
|
+
Create a variable `zz`::
|
|
783
|
+
|
|
784
|
+
sage: zz = SR.var('zz'); zz
|
|
785
|
+
zz
|
|
786
|
+
|
|
787
|
+
The return type is a symbolic expression::
|
|
788
|
+
|
|
789
|
+
sage: type(zz)
|
|
790
|
+
<class 'sage.symbolic.expression.Expression'>
|
|
791
|
+
|
|
792
|
+
We can specify the domain as well::
|
|
793
|
+
|
|
794
|
+
sage: zz = SR.var('zz', domain='real')
|
|
795
|
+
sage: zz.is_real()
|
|
796
|
+
True
|
|
797
|
+
|
|
798
|
+
The real domain is also set with the integer domain::
|
|
799
|
+
|
|
800
|
+
sage: SR.var('x', domain='integer').is_real()
|
|
801
|
+
True
|
|
802
|
+
|
|
803
|
+
The ``name`` argument does not have to match the left-hand side variable::
|
|
804
|
+
|
|
805
|
+
sage: t = SR.var('theta2'); t
|
|
806
|
+
theta2
|
|
807
|
+
|
|
808
|
+
Automatic indexing is available as well::
|
|
809
|
+
|
|
810
|
+
sage: x = SR.var('x', 4)
|
|
811
|
+
sage: x[0], x[3]
|
|
812
|
+
(x0, x3)
|
|
813
|
+
sage: sum(x)
|
|
814
|
+
x0 + x1 + x2 + x3
|
|
815
|
+
|
|
816
|
+
TESTS::
|
|
817
|
+
|
|
818
|
+
sage: var(' x y z ')
|
|
819
|
+
(x, y, z)
|
|
820
|
+
sage: var(' x , y , z ')
|
|
821
|
+
(x, y, z)
|
|
822
|
+
sage: var(' ')
|
|
823
|
+
Traceback (most recent call last):
|
|
824
|
+
...
|
|
825
|
+
ValueError: You need to specify the name of the new variable.
|
|
826
|
+
|
|
827
|
+
var(['x', 'y ', ' z '])
|
|
828
|
+
(x, y, z)
|
|
829
|
+
var(['x,y'])
|
|
830
|
+
Traceback (most recent call last):
|
|
831
|
+
...
|
|
832
|
+
ValueError: The name "x,y" is not a valid Python identifier.
|
|
833
|
+
|
|
834
|
+
Check that :issue:`17206` is fixed::
|
|
835
|
+
|
|
836
|
+
sage: var1 = var('var1', latex_name=r'\sigma^2_1'); latex(var1)
|
|
837
|
+
{\sigma^2_1}
|
|
838
|
+
|
|
839
|
+
The number of variables should be an integer greater or equal than 1::
|
|
840
|
+
|
|
841
|
+
sage: SR.var('K', -273)
|
|
842
|
+
Traceback (most recent call last):
|
|
843
|
+
...
|
|
844
|
+
ValueError: the number of variables should be a positive integer
|
|
845
|
+
|
|
846
|
+
The argument ``n`` can only handle a single variable::
|
|
847
|
+
|
|
848
|
+
sage: SR.var('x y', 4)
|
|
849
|
+
Traceback (most recent call last):
|
|
850
|
+
...
|
|
851
|
+
ValueError: cannot specify n for multiple symbol names
|
|
852
|
+
|
|
853
|
+
Check that :issue:`28353` is fixed: Constructions that suggest multiple
|
|
854
|
+
variables but actually only give one variable name return a 1-tuple::
|
|
855
|
+
|
|
856
|
+
sage: SR.var(['x'])
|
|
857
|
+
(x,)
|
|
858
|
+
sage: SR.var('x,')
|
|
859
|
+
(x,)
|
|
860
|
+
sage: SR.var(['x'], n=4)
|
|
861
|
+
Traceback (most recent call last):
|
|
862
|
+
...
|
|
863
|
+
ValueError: cannot specify n for multiple symbol names
|
|
864
|
+
"""
|
|
865
|
+
if isinstance(name, Expression):
|
|
866
|
+
return name
|
|
867
|
+
if not isinstance(name, (str, list, tuple)):
|
|
868
|
+
name = repr(name)
|
|
869
|
+
|
|
870
|
+
is_multiple = False
|
|
871
|
+
|
|
872
|
+
if isinstance(name, (list, tuple)):
|
|
873
|
+
names_list = [s.strip() for s in name]
|
|
874
|
+
is_multiple = True
|
|
875
|
+
else:
|
|
876
|
+
name = name.strip()
|
|
877
|
+
if ',' in name:
|
|
878
|
+
names_list = [s.strip() for s in name.split(',') if s.strip()]
|
|
879
|
+
is_multiple = True
|
|
880
|
+
elif ' ' in name:
|
|
881
|
+
names_list = [s.strip() for s in name.split()]
|
|
882
|
+
is_multiple = True
|
|
883
|
+
else:
|
|
884
|
+
names_list = [name] if name else []
|
|
885
|
+
|
|
886
|
+
for s in names_list:
|
|
887
|
+
if not isidentifier(s):
|
|
888
|
+
raise ValueError(f'The name "{s}" is not a valid Python identifier.')
|
|
889
|
+
# warn on bad symbol names, but only once
|
|
890
|
+
# symbol... names are temporary variables created with
|
|
891
|
+
# SR.temp_var
|
|
892
|
+
# _symbol... names are used in the conversion of
|
|
893
|
+
# derivatives of symbolic functions to maxima and other
|
|
894
|
+
# external libraries
|
|
895
|
+
if self.symbols.get(s) is None and ((s.startswith('symbol') and s[6:].isdigit()) or (s.startswith('_symbol') and s[7:].isdigit())):
|
|
896
|
+
import warnings
|
|
897
|
+
warnings.warn(f'The name "{name}" may clash with names used internally in sagemath. It is recommended to choose a different name for your variable.')
|
|
898
|
+
|
|
899
|
+
formatted_latex_name = None
|
|
900
|
+
if latex_name is not None and n is None:
|
|
901
|
+
try:
|
|
902
|
+
n = operator.index(latex_name)
|
|
903
|
+
latex_name = None
|
|
904
|
+
except TypeError:
|
|
905
|
+
formatted_latex_name = '{{{0}}}'.format(latex_name)
|
|
906
|
+
|
|
907
|
+
if not names_list:
|
|
908
|
+
raise ValueError('You need to specify the name of the new variable.')
|
|
909
|
+
|
|
910
|
+
if is_multiple:
|
|
911
|
+
if latex_name is not None:
|
|
912
|
+
raise ValueError("cannot specify latex_name for multiple symbol names")
|
|
913
|
+
if n is not None:
|
|
914
|
+
raise ValueError("cannot specify n for multiple symbol names")
|
|
915
|
+
return tuple([self.symbol(s, domain=domain) for s in names_list])
|
|
916
|
+
else:
|
|
917
|
+
if n is not None:
|
|
918
|
+
if n > 0:
|
|
919
|
+
name = [name + str(i) for i in range(n)]
|
|
920
|
+
if latex_name is None:
|
|
921
|
+
return tuple([self.symbol(name[i], domain=domain) for i in range(n)])
|
|
922
|
+
else:
|
|
923
|
+
formatted_latex_name = ['{{{}}}_{{{}}}'.format(latex_name, str(i)) for i in range(n)]
|
|
924
|
+
return tuple([self.symbol(name[i], latex_name=formatted_latex_name[i], domain=domain) for i in range(n)])
|
|
925
|
+
else:
|
|
926
|
+
raise ValueError("the number of variables should be a positive integer")
|
|
927
|
+
else:
|
|
928
|
+
return self.symbol(name, latex_name=formatted_latex_name, domain=domain)
|
|
929
|
+
|
|
930
|
+
def _repr_element_(self, x):
|
|
931
|
+
"""
|
|
932
|
+
Return the string representation of the expression ``x``.
|
|
933
|
+
|
|
934
|
+
This is used so that subclasses of :class:`SymbolicRing` (such as a
|
|
935
|
+
:class:`~sage.symbolic.callable.CallableSymbolicExpressionRing`)
|
|
936
|
+
can provide their own implementations of how to print expressions.
|
|
937
|
+
|
|
938
|
+
EXAMPLES::
|
|
939
|
+
|
|
940
|
+
sage: SR._repr_element_(x+2)
|
|
941
|
+
'x + 2'
|
|
942
|
+
"""
|
|
943
|
+
return _repr_Expression(x)
|
|
944
|
+
|
|
945
|
+
def _latex_element_(self, x):
|
|
946
|
+
r"""
|
|
947
|
+
Return the standard LaTeX version of the expression ``x``.
|
|
948
|
+
|
|
949
|
+
EXAMPLES::
|
|
950
|
+
|
|
951
|
+
sage: latex(sin(x+2))
|
|
952
|
+
\sin\left(x + 2\right)
|
|
953
|
+
sage: latex(var('theta') + 2)
|
|
954
|
+
\theta + 2
|
|
955
|
+
"""
|
|
956
|
+
return _latex_Expression(x)
|
|
957
|
+
|
|
958
|
+
def _call_element_(self, _the_element, *args, **kwds):
|
|
959
|
+
"""
|
|
960
|
+
EXAMPLES::
|
|
961
|
+
|
|
962
|
+
sage: x, y = var('x,y')
|
|
963
|
+
sage: f = x+y
|
|
964
|
+
sage: f.variables()
|
|
965
|
+
(x, y)
|
|
966
|
+
sage: f()
|
|
967
|
+
x + y
|
|
968
|
+
sage: f(3)
|
|
969
|
+
Traceback (most recent call last):
|
|
970
|
+
...
|
|
971
|
+
TypeError: Substitution using function-call syntax and unnamed arguments
|
|
972
|
+
has been removed. You can use named arguments instead, like EXPR(x=..., y=...)
|
|
973
|
+
sage: f(x=3)
|
|
974
|
+
y + 3
|
|
975
|
+
sage: f(3, 4)
|
|
976
|
+
Traceback (most recent call last):
|
|
977
|
+
...
|
|
978
|
+
TypeError: Substitution using function-call syntax and unnamed arguments
|
|
979
|
+
has been removed. You can use named arguments instead, like EXPR(x=..., y=...)
|
|
980
|
+
sage: f(x=3, y=4)
|
|
981
|
+
7
|
|
982
|
+
sage: f(2, 3, 4)
|
|
983
|
+
Traceback (most recent call last):
|
|
984
|
+
...
|
|
985
|
+
TypeError: Substitution using function-call syntax and unnamed arguments
|
|
986
|
+
has been removed. You can use named arguments instead, like EXPR(x=..., y=...)
|
|
987
|
+
sage: f(x=2, y=3, z=4)
|
|
988
|
+
5
|
|
989
|
+
|
|
990
|
+
::
|
|
991
|
+
|
|
992
|
+
sage: f({x: 3})
|
|
993
|
+
y + 3
|
|
994
|
+
sage: f({x: 3, y: 4})
|
|
995
|
+
7
|
|
996
|
+
sage: f(x=3)
|
|
997
|
+
y + 3
|
|
998
|
+
sage: f(x=3, y=4)
|
|
999
|
+
7
|
|
1000
|
+
|
|
1001
|
+
::
|
|
1002
|
+
|
|
1003
|
+
sage: a = (2^(8/9))
|
|
1004
|
+
sage: a(4)
|
|
1005
|
+
Traceback (most recent call last):
|
|
1006
|
+
...
|
|
1007
|
+
TypeError: Substitution using function-call syntax and unnamed arguments
|
|
1008
|
+
has been removed. You can use named arguments instead, like EXPR(x=..., y=...)
|
|
1009
|
+
|
|
1010
|
+
Note that the application of arguments to a function defined using `function`
|
|
1011
|
+
creates an ordinary expression, not a callable symbolic expression. Hence,
|
|
1012
|
+
calling this expression using function-call syntax and unnamed arguments
|
|
1013
|
+
leads to an error::
|
|
1014
|
+
|
|
1015
|
+
sage: f = function('Gamma')(var('z'), var('w')); f
|
|
1016
|
+
Gamma(z, w)
|
|
1017
|
+
sage: f(2)
|
|
1018
|
+
Traceback (most recent call last):
|
|
1019
|
+
...
|
|
1020
|
+
TypeError: Substitution using function-call syntax and unnamed arguments
|
|
1021
|
+
has been removed. You can use named arguments instead, like EXPR(x=..., y=...)
|
|
1022
|
+
sage: f(2,5)
|
|
1023
|
+
Traceback (most recent call last):
|
|
1024
|
+
...
|
|
1025
|
+
TypeError: Substitution using function-call syntax and unnamed arguments
|
|
1026
|
+
has been removed. You can use named arguments instead, like EXPR(x=..., y=...)
|
|
1027
|
+
|
|
1028
|
+
Thus, it is better to be explicit::
|
|
1029
|
+
|
|
1030
|
+
sage: f(z=2)
|
|
1031
|
+
Gamma(2, w)
|
|
1032
|
+
"""
|
|
1033
|
+
if not args:
|
|
1034
|
+
d = None
|
|
1035
|
+
elif len(args) == 1 and isinstance(args[0], dict):
|
|
1036
|
+
d = args[0]
|
|
1037
|
+
else:
|
|
1038
|
+
raise TypeError("Substitution using function-call syntax "
|
|
1039
|
+
"and unnamed arguments has been removed. You "
|
|
1040
|
+
"can use named arguments instead, like "
|
|
1041
|
+
"EXPR(x=..., y=...)")
|
|
1042
|
+
return _the_element.subs(d, **kwds)
|
|
1043
|
+
|
|
1044
|
+
def subring(self, *args, **kwds):
|
|
1045
|
+
r"""
|
|
1046
|
+
Create a subring of this symbolic ring.
|
|
1047
|
+
|
|
1048
|
+
INPUT:
|
|
1049
|
+
|
|
1050
|
+
Choose one of the following keywords to create a subring.
|
|
1051
|
+
|
|
1052
|
+
- ``accepting_variables`` -- (default: ``None``) a tuple or other
|
|
1053
|
+
iterable of variables. If specified, then a symbolic subring of
|
|
1054
|
+
expressions in only these variables is created.
|
|
1055
|
+
|
|
1056
|
+
- ``rejecting_variables`` -- (default: ``None``) a tuple or other
|
|
1057
|
+
iterable of variables. If specified, then a symbolic subring of
|
|
1058
|
+
expressions in variables distinct to these variables is
|
|
1059
|
+
created.
|
|
1060
|
+
|
|
1061
|
+
- ``no_variables`` -- boolean (default: ``False``); if set,
|
|
1062
|
+
then a symbolic subring of constant expressions (i.e.,
|
|
1063
|
+
expressions without a variable) is created.
|
|
1064
|
+
|
|
1065
|
+
OUTPUT: a ring
|
|
1066
|
+
|
|
1067
|
+
EXAMPLES:
|
|
1068
|
+
|
|
1069
|
+
Let us create a couple of symbolic variables first::
|
|
1070
|
+
|
|
1071
|
+
sage: V = var('a, b, r, s, x, y')
|
|
1072
|
+
|
|
1073
|
+
Now we create a symbolic subring only accepting expressions in
|
|
1074
|
+
the variables `a` and `b`::
|
|
1075
|
+
|
|
1076
|
+
sage: A = SR.subring(accepting_variables=(a, b)); A
|
|
1077
|
+
Symbolic Subring accepting the variables a, b
|
|
1078
|
+
|
|
1079
|
+
An element is
|
|
1080
|
+
::
|
|
1081
|
+
|
|
1082
|
+
sage: A.an_element()
|
|
1083
|
+
a
|
|
1084
|
+
|
|
1085
|
+
From our variables in `V` the following are valid in `A`::
|
|
1086
|
+
|
|
1087
|
+
sage: tuple(v for v in V if v in A)
|
|
1088
|
+
(a, b)
|
|
1089
|
+
|
|
1090
|
+
Next, we create a symbolic subring rejecting expressions with
|
|
1091
|
+
given variables::
|
|
1092
|
+
|
|
1093
|
+
sage: R = SR.subring(rejecting_variables=(r, s)); R
|
|
1094
|
+
Symbolic Subring rejecting the variables r, s
|
|
1095
|
+
|
|
1096
|
+
An element is
|
|
1097
|
+
::
|
|
1098
|
+
|
|
1099
|
+
sage: R.an_element()
|
|
1100
|
+
some_variable
|
|
1101
|
+
|
|
1102
|
+
From our variables in `V` the following are valid in `R`::
|
|
1103
|
+
|
|
1104
|
+
sage: tuple(v for v in V if v in R)
|
|
1105
|
+
(a, b, x, y)
|
|
1106
|
+
|
|
1107
|
+
We have a third kind of subring, namely the subring of
|
|
1108
|
+
symbolic constants::
|
|
1109
|
+
|
|
1110
|
+
sage: C = SR.subring(no_variables=True); C
|
|
1111
|
+
Symbolic Constants Subring
|
|
1112
|
+
|
|
1113
|
+
Note that this subring can be considered as a special accepting
|
|
1114
|
+
subring; one without any variables.
|
|
1115
|
+
|
|
1116
|
+
An element is
|
|
1117
|
+
::
|
|
1118
|
+
|
|
1119
|
+
sage: C.an_element()
|
|
1120
|
+
I*pi*e
|
|
1121
|
+
|
|
1122
|
+
None of our variables in `V` is valid in `C`::
|
|
1123
|
+
|
|
1124
|
+
sage: tuple(v for v in V if v in C)
|
|
1125
|
+
()
|
|
1126
|
+
|
|
1127
|
+
.. SEEALSO::
|
|
1128
|
+
|
|
1129
|
+
:doc:`subring`
|
|
1130
|
+
"""
|
|
1131
|
+
if self is not SR:
|
|
1132
|
+
raise NotImplementedError('cannot create subring of %s' % (self,))
|
|
1133
|
+
from sage.symbolic.subring import SymbolicSubring
|
|
1134
|
+
return SymbolicSubring(*args, **kwds)
|
|
1135
|
+
|
|
1136
|
+
def _fricas_init_(self):
|
|
1137
|
+
"""
|
|
1138
|
+
Return a FriCAS representation of ``self``.
|
|
1139
|
+
|
|
1140
|
+
EXAMPLES::
|
|
1141
|
+
|
|
1142
|
+
sage: fricas(SR) # indirect doctest, optional - fricas
|
|
1143
|
+
Expression(Integer)
|
|
1144
|
+
"""
|
|
1145
|
+
return 'Expression Integer'
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
SR = SymbolicRing()
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
cdef class NumpyToSRMorphism(Morphism):
|
|
1152
|
+
r"""
|
|
1153
|
+
A morphism from numpy types to the symbolic ring.
|
|
1154
|
+
|
|
1155
|
+
TESTS:
|
|
1156
|
+
|
|
1157
|
+
We check that :issue:`8949` and :issue:`9769` are fixed (see also :issue:`18076`)::
|
|
1158
|
+
|
|
1159
|
+
sage: # needs numpy
|
|
1160
|
+
sage: import numpy
|
|
1161
|
+
sage: if int(numpy.version.short_version[0]) > 1:
|
|
1162
|
+
....: _ = numpy.set_printoptions(legacy="1.25")
|
|
1163
|
+
sage: f(x) = x^2
|
|
1164
|
+
sage: f(numpy.int8('2'))
|
|
1165
|
+
4
|
|
1166
|
+
sage: f(numpy.int32('3'))
|
|
1167
|
+
9
|
|
1168
|
+
|
|
1169
|
+
Note that the answer is a Sage integer and not a numpy type::
|
|
1170
|
+
|
|
1171
|
+
sage: a = f(numpy.int8('2')).pyobject() # needs numpy
|
|
1172
|
+
sage: type(a) # needs numpy
|
|
1173
|
+
<class 'sage.rings.integer.Integer'>
|
|
1174
|
+
|
|
1175
|
+
This behavior also applies to standard functions::
|
|
1176
|
+
|
|
1177
|
+
sage: cos(int('2'))
|
|
1178
|
+
cos(2)
|
|
1179
|
+
sage: numpy.cos(int('2')) # needs numpy
|
|
1180
|
+
-0.4161468365471424
|
|
1181
|
+
"""
|
|
1182
|
+
cdef _intermediate_ring
|
|
1183
|
+
|
|
1184
|
+
def __init__(self, numpy_type):
|
|
1185
|
+
"""
|
|
1186
|
+
A Morphism which constructs Expressions from NumPy floats and
|
|
1187
|
+
complexes by converting them to elements of either RDF or CDF.
|
|
1188
|
+
|
|
1189
|
+
INPUT:
|
|
1190
|
+
|
|
1191
|
+
- ``numpy_type`` -- a numpy number type
|
|
1192
|
+
|
|
1193
|
+
EXAMPLES::
|
|
1194
|
+
|
|
1195
|
+
sage: # needs numpy
|
|
1196
|
+
sage: import numpy
|
|
1197
|
+
sage: from sage.symbolic.ring import NumpyToSRMorphism
|
|
1198
|
+
sage: f = NumpyToSRMorphism(numpy.float64)
|
|
1199
|
+
sage: f(numpy.float64('2.0'))
|
|
1200
|
+
2.0
|
|
1201
|
+
sage: _.parent()
|
|
1202
|
+
Symbolic Ring
|
|
1203
|
+
|
|
1204
|
+
sage: NumpyToSRMorphism(str) # needs numpy
|
|
1205
|
+
Traceback (most recent call last):
|
|
1206
|
+
...
|
|
1207
|
+
TypeError: <... 'str'> is not a numpy number type
|
|
1208
|
+
"""
|
|
1209
|
+
Morphism.__init__(self, numpy_type, SR)
|
|
1210
|
+
|
|
1211
|
+
import numpy
|
|
1212
|
+
if issubclass(numpy_type, numpy.integer):
|
|
1213
|
+
from sage.rings.integer_ring import ZZ
|
|
1214
|
+
self._intermediate_ring = ZZ
|
|
1215
|
+
elif issubclass(numpy_type, numpy.floating):
|
|
1216
|
+
from sage.rings.real_double import RDF
|
|
1217
|
+
self._intermediate_ring = RDF
|
|
1218
|
+
elif issubclass(numpy_type, numpy.complexfloating):
|
|
1219
|
+
from sage.rings.complex_double import CDF
|
|
1220
|
+
self._intermediate_ring = CDF
|
|
1221
|
+
else:
|
|
1222
|
+
raise TypeError("{} is not a numpy number type".format(numpy_type))
|
|
1223
|
+
|
|
1224
|
+
cpdef Element _call_(self, a):
|
|
1225
|
+
"""
|
|
1226
|
+
EXAMPLES:
|
|
1227
|
+
|
|
1228
|
+
This should be called when coercing or converting a NumPy
|
|
1229
|
+
float or complex to the Symbolic Ring::
|
|
1230
|
+
|
|
1231
|
+
sage: # needs numpy
|
|
1232
|
+
sage: import numpy
|
|
1233
|
+
sage: SR(numpy.int32('1')).pyobject().parent()
|
|
1234
|
+
Integer Ring
|
|
1235
|
+
sage: SR(numpy.int64('-2')).pyobject().parent()
|
|
1236
|
+
Integer Ring
|
|
1237
|
+
sage: SR(numpy.float16('1')).pyobject().parent()
|
|
1238
|
+
Real Double Field
|
|
1239
|
+
sage: SR(numpy.float64('2.0')).pyobject().parent()
|
|
1240
|
+
Real Double Field
|
|
1241
|
+
sage: SR(numpy.complex64(1jr)).pyobject().parent()
|
|
1242
|
+
Complex Double Field
|
|
1243
|
+
"""
|
|
1244
|
+
return new_Expression_from_pyobject(self.codomain(), self._intermediate_ring(a), True)
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
cdef class UnderscoreSageMorphism(Morphism):
|
|
1248
|
+
def __init__(self, t, R):
|
|
1249
|
+
"""
|
|
1250
|
+
A Morphism which constructs Expressions from an arbitrary Python
|
|
1251
|
+
object by calling the :meth:`_sage_` method on the object.
|
|
1252
|
+
|
|
1253
|
+
EXAMPLES::
|
|
1254
|
+
|
|
1255
|
+
sage: # needs sympy
|
|
1256
|
+
sage: import sympy
|
|
1257
|
+
sage: from sage.symbolic.ring import UnderscoreSageMorphism
|
|
1258
|
+
sage: b = sympy.var('b')
|
|
1259
|
+
sage: f = UnderscoreSageMorphism(type(b), SR)
|
|
1260
|
+
sage: f(b)
|
|
1261
|
+
b
|
|
1262
|
+
sage: _.parent()
|
|
1263
|
+
Symbolic Ring
|
|
1264
|
+
"""
|
|
1265
|
+
import sage.categories.homset
|
|
1266
|
+
from sage.sets.pythonclass import Set_PythonType
|
|
1267
|
+
Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(t), R))
|
|
1268
|
+
from sage.interfaces.sympy import sympy_init
|
|
1269
|
+
sympy_init()
|
|
1270
|
+
|
|
1271
|
+
cpdef Element _call_(self, a):
|
|
1272
|
+
"""
|
|
1273
|
+
EXAMPLES:
|
|
1274
|
+
|
|
1275
|
+
This should be called when coercing or converting a SymPy
|
|
1276
|
+
object to the Symbolic Ring::
|
|
1277
|
+
|
|
1278
|
+
sage: import sympy # needs sympy
|
|
1279
|
+
sage: b = sympy.var('b') # needs sympy
|
|
1280
|
+
sage: bool(SR(b) == SR(b._sage_())) # needs sympy
|
|
1281
|
+
True
|
|
1282
|
+
"""
|
|
1283
|
+
return self.codomain()(a._sage_())
|
|
1284
|
+
|
|
1285
|
+
|
|
1286
|
+
def the_SymbolicRing():
|
|
1287
|
+
"""
|
|
1288
|
+
Return the unique symbolic ring object.
|
|
1289
|
+
|
|
1290
|
+
(This is mainly used for unpickling.)
|
|
1291
|
+
|
|
1292
|
+
EXAMPLES::
|
|
1293
|
+
|
|
1294
|
+
sage: sage.symbolic.ring.the_SymbolicRing()
|
|
1295
|
+
Symbolic Ring
|
|
1296
|
+
sage: sage.symbolic.ring.the_SymbolicRing() is sage.symbolic.ring.the_SymbolicRing()
|
|
1297
|
+
True
|
|
1298
|
+
sage: sage.symbolic.ring.the_SymbolicRing() is SR
|
|
1299
|
+
True
|
|
1300
|
+
"""
|
|
1301
|
+
return SR
|
|
1302
|
+
|
|
1303
|
+
|
|
1304
|
+
def var(name, **kwds):
|
|
1305
|
+
"""
|
|
1306
|
+
EXAMPLES::
|
|
1307
|
+
|
|
1308
|
+
sage: from sage.symbolic.ring import var
|
|
1309
|
+
sage: var("x y z")
|
|
1310
|
+
(x, y, z)
|
|
1311
|
+
sage: var("x,y,z")
|
|
1312
|
+
(x, y, z)
|
|
1313
|
+
sage: var("x , y , z")
|
|
1314
|
+
(x, y, z)
|
|
1315
|
+
sage: var("z")
|
|
1316
|
+
z
|
|
1317
|
+
|
|
1318
|
+
TESTS:
|
|
1319
|
+
|
|
1320
|
+
These examples test that variables can only be made from valid
|
|
1321
|
+
identifiers. See :issue:`7496` (and :issue:`9724`) for details::
|
|
1322
|
+
|
|
1323
|
+
sage: var(' ')
|
|
1324
|
+
Traceback (most recent call last):
|
|
1325
|
+
...
|
|
1326
|
+
ValueError: You need to specify the name of the new variable.
|
|
1327
|
+
sage: var('3')
|
|
1328
|
+
Traceback (most recent call last):
|
|
1329
|
+
...
|
|
1330
|
+
ValueError: The name "3" is not a valid Python identifier.
|
|
1331
|
+
"""
|
|
1332
|
+
return SR.var(name, **kwds)
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
def isidentifier(x):
|
|
1336
|
+
"""
|
|
1337
|
+
Return whether ``x`` is a valid identifier.
|
|
1338
|
+
|
|
1339
|
+
INPUT:
|
|
1340
|
+
|
|
1341
|
+
- ``x`` -- string
|
|
1342
|
+
|
|
1343
|
+
OUTPUT: boolean; whether the string ``x`` can be used as a variable name
|
|
1344
|
+
|
|
1345
|
+
This function should return ``False`` for keywords, so we can not
|
|
1346
|
+
just use the ``isidentifier`` method of strings,
|
|
1347
|
+
because, for example, it returns ``True`` for "def" and for "None".
|
|
1348
|
+
|
|
1349
|
+
EXAMPLES::
|
|
1350
|
+
|
|
1351
|
+
sage: from sage.symbolic.ring import isidentifier
|
|
1352
|
+
sage: isidentifier('x')
|
|
1353
|
+
True
|
|
1354
|
+
sage: isidentifier(' x') # can't start with space
|
|
1355
|
+
False
|
|
1356
|
+
sage: isidentifier('ceci_n_est_pas_une_pipe')
|
|
1357
|
+
True
|
|
1358
|
+
sage: isidentifier('1 + x')
|
|
1359
|
+
False
|
|
1360
|
+
sage: isidentifier('2good')
|
|
1361
|
+
False
|
|
1362
|
+
sage: isidentifier('good2')
|
|
1363
|
+
True
|
|
1364
|
+
sage: isidentifier('lambda s:s+1')
|
|
1365
|
+
False
|
|
1366
|
+
sage: isidentifier('None')
|
|
1367
|
+
False
|
|
1368
|
+
sage: isidentifier('lambda')
|
|
1369
|
+
False
|
|
1370
|
+
sage: isidentifier('def')
|
|
1371
|
+
False
|
|
1372
|
+
"""
|
|
1373
|
+
if x in KEYWORDS:
|
|
1374
|
+
return False
|
|
1375
|
+
return x.isidentifier()
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
class TemporaryVariables(tuple):
|
|
1379
|
+
"""
|
|
1380
|
+
Instances of this class can be used with Python `with` to
|
|
1381
|
+
automatically clean up after themselves.
|
|
1382
|
+
"""
|
|
1383
|
+
def __enter__(self):
|
|
1384
|
+
return self
|
|
1385
|
+
|
|
1386
|
+
def __exit__(self, *args):
|
|
1387
|
+
"""
|
|
1388
|
+
TESTS::
|
|
1389
|
+
|
|
1390
|
+
sage: symbols_copy = SR.symbols.copy()
|
|
1391
|
+
sage: with SR.temp_var(n=2) as temp_vars: pass
|
|
1392
|
+
sage: symbols_copy == SR.symbols
|
|
1393
|
+
True
|
|
1394
|
+
"""
|
|
1395
|
+
SR.cleanup_var(self)
|
|
1396
|
+
return False
|