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