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.

Files changed (172) hide show
  1. passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_symbolics/__init__.py +3 -0
  3. passagemath_symbolics-10.6.40.dist-info/METADATA +187 -0
  4. passagemath_symbolics-10.6.40.dist-info/RECORD +172 -0
  5. passagemath_symbolics-10.6.40.dist-info/WHEEL +6 -0
  6. passagemath_symbolics-10.6.40.dist-info/top_level.txt +3 -0
  7. sage/all__sagemath_symbolics.py +17 -0
  8. sage/calculus/all.py +14 -0
  9. sage/calculus/calculus.py +2826 -0
  10. sage/calculus/desolvers.py +1866 -0
  11. sage/calculus/predefined.py +51 -0
  12. sage/calculus/tests.py +225 -0
  13. sage/calculus/var.cpython-314t-darwin.so +0 -0
  14. sage/calculus/var.pyx +401 -0
  15. sage/dynamics/all__sagemath_symbolics.py +6 -0
  16. sage/dynamics/complex_dynamics/all.py +5 -0
  17. sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-darwin.so +0 -0
  19. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
  20. sage/ext/all__sagemath_symbolics.py +1 -0
  21. sage/ext_data/kenzo/CP2.txt +45 -0
  22. sage/ext_data/kenzo/CP3.txt +349 -0
  23. sage/ext_data/kenzo/CP4.txt +4774 -0
  24. sage/ext_data/kenzo/README.txt +49 -0
  25. sage/ext_data/kenzo/S4.txt +20 -0
  26. sage/ext_data/magma/latex/latex.m +1021 -0
  27. sage/ext_data/magma/latex/latex.spec +1 -0
  28. sage/ext_data/magma/sage/basic.m +356 -0
  29. sage/ext_data/magma/sage/sage.spec +1 -0
  30. sage/ext_data/magma/spec +9 -0
  31. sage/geometry/all__sagemath_symbolics.py +8 -0
  32. sage/geometry/hyperbolic_space/all.py +5 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
  38. sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
  39. sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
  40. sage/geometry/riemannian_manifolds/all.py +7 -0
  41. sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
  42. sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
  43. sage/interfaces/all__sagemath_symbolics.py +1 -0
  44. sage/interfaces/magma.py +3017 -0
  45. sage/interfaces/magma_free.py +92 -0
  46. sage/interfaces/maple.py +1397 -0
  47. sage/interfaces/mathematica.py +1345 -0
  48. sage/interfaces/mathics.py +1312 -0
  49. sage/interfaces/sympy.py +1398 -0
  50. sage/interfaces/sympy_wrapper.py +197 -0
  51. sage/interfaces/tides.py +938 -0
  52. sage/libs/all__sagemath_symbolics.py +6 -0
  53. sage/manifolds/all.py +7 -0
  54. sage/manifolds/calculus_method.py +555 -0
  55. sage/manifolds/catalog.py +437 -0
  56. sage/manifolds/chart.py +4019 -0
  57. sage/manifolds/chart_func.py +3419 -0
  58. sage/manifolds/continuous_map.py +2183 -0
  59. sage/manifolds/continuous_map_image.py +155 -0
  60. sage/manifolds/differentiable/affine_connection.py +2475 -0
  61. sage/manifolds/differentiable/all.py +1 -0
  62. sage/manifolds/differentiable/automorphismfield.py +1383 -0
  63. sage/manifolds/differentiable/automorphismfield_group.py +604 -0
  64. sage/manifolds/differentiable/bundle_connection.py +1445 -0
  65. sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
  66. sage/manifolds/differentiable/chart.py +1241 -0
  67. sage/manifolds/differentiable/curve.py +1028 -0
  68. sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
  69. sage/manifolds/differentiable/degenerate.py +559 -0
  70. sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
  71. sage/manifolds/differentiable/diff_form.py +1658 -0
  72. sage/manifolds/differentiable/diff_form_module.py +1062 -0
  73. sage/manifolds/differentiable/diff_map.py +1315 -0
  74. sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
  75. sage/manifolds/differentiable/examples/all.py +1 -0
  76. sage/manifolds/differentiable/examples/euclidean.py +2517 -0
  77. sage/manifolds/differentiable/examples/real_line.py +897 -0
  78. sage/manifolds/differentiable/examples/sphere.py +1186 -0
  79. sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
  80. sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
  81. sage/manifolds/differentiable/integrated_curve.py +4035 -0
  82. sage/manifolds/differentiable/levi_civita_connection.py +841 -0
  83. sage/manifolds/differentiable/manifold.py +4254 -0
  84. sage/manifolds/differentiable/manifold_homset.py +1826 -0
  85. sage/manifolds/differentiable/metric.py +3032 -0
  86. sage/manifolds/differentiable/mixed_form.py +1507 -0
  87. sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
  88. sage/manifolds/differentiable/multivector_module.py +800 -0
  89. sage/manifolds/differentiable/multivectorfield.py +1520 -0
  90. sage/manifolds/differentiable/poisson_tensor.py +268 -0
  91. sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
  92. sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
  93. sage/manifolds/differentiable/scalarfield.py +1343 -0
  94. sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
  95. sage/manifolds/differentiable/symplectic_form.py +910 -0
  96. sage/manifolds/differentiable/symplectic_form_test.py +220 -0
  97. sage/manifolds/differentiable/tangent_space.py +412 -0
  98. sage/manifolds/differentiable/tangent_vector.py +616 -0
  99. sage/manifolds/differentiable/tensorfield.py +4665 -0
  100. sage/manifolds/differentiable/tensorfield_module.py +963 -0
  101. sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
  102. sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
  103. sage/manifolds/differentiable/vector_bundle.py +1728 -0
  104. sage/manifolds/differentiable/vectorfield.py +1717 -0
  105. sage/manifolds/differentiable/vectorfield_module.py +2445 -0
  106. sage/manifolds/differentiable/vectorframe.py +1832 -0
  107. sage/manifolds/family.py +270 -0
  108. sage/manifolds/local_frame.py +1490 -0
  109. sage/manifolds/manifold.py +3090 -0
  110. sage/manifolds/manifold_homset.py +452 -0
  111. sage/manifolds/operators.py +359 -0
  112. sage/manifolds/point.py +994 -0
  113. sage/manifolds/scalarfield.py +3718 -0
  114. sage/manifolds/scalarfield_algebra.py +629 -0
  115. sage/manifolds/section.py +3111 -0
  116. sage/manifolds/section_module.py +831 -0
  117. sage/manifolds/structure.py +229 -0
  118. sage/manifolds/subset.py +2764 -0
  119. sage/manifolds/subsets/all.py +1 -0
  120. sage/manifolds/subsets/closure.py +131 -0
  121. sage/manifolds/subsets/pullback.py +885 -0
  122. sage/manifolds/topological_submanifold.py +891 -0
  123. sage/manifolds/trivialization.py +733 -0
  124. sage/manifolds/utilities.py +1348 -0
  125. sage/manifolds/vector_bundle.py +1342 -0
  126. sage/manifolds/vector_bundle_fiber.py +332 -0
  127. sage/manifolds/vector_bundle_fiber_element.py +111 -0
  128. sage/matrix/all__sagemath_symbolics.py +1 -0
  129. sage/matrix/matrix_symbolic_dense.cpython-314t-darwin.so +0 -0
  130. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  131. sage/matrix/matrix_symbolic_dense.pyx +1022 -0
  132. sage/matrix/matrix_symbolic_sparse.cpython-314t-darwin.so +0 -0
  133. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  134. sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
  135. sage/modules/all__sagemath_symbolics.py +1 -0
  136. sage/modules/vector_callable_symbolic_dense.py +105 -0
  137. sage/modules/vector_symbolic_dense.py +116 -0
  138. sage/modules/vector_symbolic_sparse.py +118 -0
  139. sage/rings/all__sagemath_symbolics.py +4 -0
  140. sage/rings/asymptotic/all.py +6 -0
  141. sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
  142. sage/rings/asymptotic/asymptotic_ring.py +4858 -0
  143. sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
  144. sage/rings/asymptotic/growth_group.py +5373 -0
  145. sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
  146. sage/rings/asymptotic/term_monoid.py +5237 -0
  147. sage/rings/function_field/all__sagemath_symbolics.py +2 -0
  148. sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
  149. sage/symbolic/all.py +15 -0
  150. sage/symbolic/assumptions.py +985 -0
  151. sage/symbolic/benchmark.py +93 -0
  152. sage/symbolic/callable.py +459 -0
  153. sage/symbolic/complexity_measures.py +35 -0
  154. sage/symbolic/constants.py +1287 -0
  155. sage/symbolic/expression_conversion_algebraic.py +310 -0
  156. sage/symbolic/expression_conversion_sympy.py +317 -0
  157. sage/symbolic/expression_conversions.py +1713 -0
  158. sage/symbolic/function_factory.py +355 -0
  159. sage/symbolic/integration/all.py +1 -0
  160. sage/symbolic/integration/external.py +270 -0
  161. sage/symbolic/integration/integral.py +1115 -0
  162. sage/symbolic/maxima_wrapper.py +162 -0
  163. sage/symbolic/operators.py +267 -0
  164. sage/symbolic/random_tests.py +462 -0
  165. sage/symbolic/relation.py +1907 -0
  166. sage/symbolic/ring.cpython-314t-darwin.so +0 -0
  167. sage/symbolic/ring.pxd +5 -0
  168. sage/symbolic/ring.pyx +1396 -0
  169. sage/symbolic/subring.py +1025 -0
  170. sage/symbolic/symengine.py +19 -0
  171. sage/symbolic/tests.py +40 -0
  172. sage/symbolic/units.py +1470 -0
@@ -0,0 +1,310 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ r"""
3
+ Conversion of symbolic expressions to algebraic numbers
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2009-2012 Mike Hansen
7
+ # 2015-2018 Ralf Stephan
8
+ # 2015 Nils Bruin
9
+ # 2017 Jeroen Demeyer
10
+ # 2019-2022 Frédéric Chapoton
11
+ # 2021 Dave Witte Morris
12
+ # 2023 Vincent Delecroix
13
+ #
14
+ # This program is free software: you can redistribute it and/or modify
15
+ # it under the terms of the GNU General Public License as published by
16
+ # the Free Software Foundation, either version 2 of the License, or
17
+ # (at your option) any later version.
18
+ # https://www.gnu.org/licenses/
19
+ # ****************************************************************************
20
+
21
+ from operator import eq, ne, gt, lt, ge, le, mul, pow, neg, add, truediv
22
+ from functools import reduce
23
+
24
+ import sage.rings.abc
25
+
26
+ from sage.functions.all import exp
27
+ from sage.symbolic.expression_conversions import Converter
28
+ from sage.symbolic.operators import add_vararg, mul_vararg
29
+ from sage.symbolic.ring import SR
30
+
31
+
32
+ #############
33
+ # Algebraic #
34
+ #############
35
+ class AlgebraicConverter(Converter):
36
+ def __init__(self, field):
37
+ """
38
+ EXAMPLES::
39
+
40
+ sage: from sage.symbolic.expression_conversions import AlgebraicConverter
41
+ sage: a = AlgebraicConverter(QQbar)
42
+ sage: a.field
43
+ Algebraic Field
44
+ sage: a.reciprocal_trig_functions['cot']
45
+ tan
46
+ """
47
+ self.field = field
48
+
49
+ from sage.functions.all import reciprocal_trig_functions
50
+ self.reciprocal_trig_functions = reciprocal_trig_functions
51
+
52
+ def pyobject(self, ex, obj):
53
+ """
54
+ EXAMPLES::
55
+
56
+ sage: from sage.symbolic.expression_conversions import AlgebraicConverter
57
+ sage: a = AlgebraicConverter(QQbar)
58
+ sage: f = SR(2)
59
+ sage: a.pyobject(f, f.pyobject())
60
+ 2
61
+ sage: _.parent()
62
+ Algebraic Field
63
+ """
64
+ return self.field(obj)
65
+
66
+ def arithmetic(self, ex, operator):
67
+ """
68
+ Convert a symbolic expression to an algebraic number.
69
+
70
+ EXAMPLES::
71
+
72
+ sage: from sage.symbolic.expression_conversions import AlgebraicConverter
73
+ sage: f = 2^(1/2)
74
+ sage: a = AlgebraicConverter(QQbar)
75
+ sage: a.arithmetic(f, f.operator())
76
+ 1.414213562373095?
77
+
78
+ TESTS::
79
+
80
+ sage: f = pi^6
81
+ sage: a = AlgebraicConverter(QQbar)
82
+ sage: a.arithmetic(f, f.operator())
83
+ Traceback (most recent call last):
84
+ ...
85
+ TypeError: unable to convert pi^6 to Algebraic Field
86
+
87
+ Test that :issue:`14602` is fixed::
88
+
89
+ sage: # needs sage.rings.number_field
90
+ sage: K = QuadraticField(3)
91
+ sage: K(sqrt(3)).parent() is K
92
+ True
93
+ sage: sqrt(K(3)).parent() is K
94
+ True
95
+ sage: (K(3)^(1/2)).parent()
96
+ Symbolic Ring
97
+ sage: bool(K.gen() == K(3)^(1/2) == sqrt(K(3)) == K(sqrt(3)) == sqrt(3))
98
+ True
99
+ sage: L = QuadraticField(3, embedding=-AA(3).sqrt())
100
+ sage: bool(L.gen() == -sqrt(3))
101
+ True
102
+ """
103
+ # We try to avoid simplifying, because maxima's simplify command
104
+ # can change the value of a radical expression (by changing which
105
+ # root is selected).
106
+ try:
107
+ if operator is pow:
108
+ from sage.rings.rational import Rational
109
+ base, expt = ex.operands()
110
+ base = self.field(base)
111
+ expt = Rational(expt)
112
+ return self.field(base**expt)
113
+ else:
114
+ if operator is add_vararg:
115
+ operator = add
116
+ elif operator is mul_vararg:
117
+ operator = mul
118
+ return reduce(operator, map(self, ex.operands()))
119
+ except TypeError:
120
+ pass
121
+
122
+ if operator is pow:
123
+ from sage.symbolic.constants import e, pi, I
124
+ from sage.rings.rational_field import QQ
125
+
126
+ base, expt = ex.operands()
127
+ if base == e and expt / (pi * I) in QQ:
128
+ return exp(expt)._algebraic_(self.field)
129
+
130
+ raise TypeError("unable to convert %r to %s" % (ex, self.field))
131
+
132
+ def composition(self, ex, operator):
133
+ """
134
+ Coerce to an algebraic number.
135
+
136
+ EXAMPLES::
137
+
138
+ sage: # needs sage.libs.pari
139
+ sage: from sage.symbolic.expression_conversions import AlgebraicConverter
140
+ sage: a = AlgebraicConverter(QQbar)
141
+ sage: a.composition(exp(I*pi/3, hold=True), exp)
142
+ 0.500000000000000? + 0.866025403784439?*I
143
+ sage: a.composition(sin(pi/7), sin)
144
+ 0.4338837391175581? + 0.?e-18*I
145
+ sage: x = SR.var('x')
146
+ sage: a.composition(complex_root_of(x^3 - x^2 - x - 1, 0), complex_root_of)
147
+ 1.839286755214161?
148
+ sage: a.composition(complex_root_of(x^5 - 1, 3), complex_root_of)
149
+ 0.3090169943749474? - 0.9510565162951536?*I
150
+ sage: a.composition(complex_root_of(x^2 + 1, 0), complex_root_of)
151
+ 1.?e-683 - 0.9999999999999999?*I
152
+ sage: a.composition(complex_root_of(x^2 + 1, 1), complex_root_of)
153
+ 1.?e-683 + 0.9999999999999999?*I
154
+
155
+ TESTS::
156
+
157
+ sage: QQbar(zeta(7))
158
+ Traceback (most recent call last):
159
+ ...
160
+ TypeError: unable to convert zeta(7) to Algebraic Field
161
+
162
+ Test :issue:`22571`::
163
+
164
+ sage: # needs sage.libs.pari
165
+ sage: a.composition(exp(0, hold=True), exp)
166
+ 1
167
+ sage: a.composition(exp(1, hold=True), exp)
168
+ Traceback (most recent call last):
169
+ ...
170
+ ValueError: unable to represent as an algebraic number
171
+ sage: a.composition(exp(pi*I*RR(1), hold=True), exp)
172
+ Traceback (most recent call last):
173
+ ...
174
+ TypeError: unable to convert e^(1.00000000000000*I*pi) to Algebraic Field
175
+ sage: a.composition(exp(pi*CC.gen(), hold=True), exp)
176
+ Traceback (most recent call last):
177
+ ...
178
+ TypeError: unable to convert e^(1.00000000000000*I*pi) to Algebraic Field
179
+ sage: bool(sin(pi*RR("0.7000000000000002")) > 0)
180
+ True
181
+
182
+ Check that :issue:`24440` is fixed::
183
+
184
+ sage: # needs sage.libs.pari
185
+ sage: QQbar(tanh(pi + 0.1))
186
+ Traceback (most recent call last):
187
+ ...
188
+ ValueError: unable to represent as an algebraic number
189
+ sage: QQbar(sin(I*pi/7))
190
+ Traceback (most recent call last):
191
+ ...
192
+ ValueError: unable to represent as an algebraic number
193
+ sage: QQbar(sin(I*pi/7, hold=True))
194
+ Traceback (most recent call last):
195
+ ...
196
+ ValueError: unable to represent as an algebraic number
197
+ """
198
+ func = operator
199
+ operands = ex.operands()
200
+ if len(operands) == 1:
201
+ operand = operands[0]
202
+ else:
203
+ operand = None
204
+
205
+ if isinstance(self.field, sage.rings.abc.UniversalCyclotomicField):
206
+ QQbar = self.field
207
+ hold = True
208
+ else:
209
+ QQbar = self.field.algebraic_closure()
210
+ hold = False
211
+
212
+ zeta = QQbar.zeta
213
+ # Note that comparing functions themselves goes via maxima, and is SLOW
214
+ func_name = repr(func)
215
+ if func_name == 'exp':
216
+ if operand.is_trivial_zero():
217
+ return self.field.one()
218
+ if not (SR(-1).sqrt() * operand).is_real():
219
+ raise ValueError("unable to represent as an algebraic number")
220
+ # Coerce (not convert, see #22571) arg to a rational
221
+ from sage.rings.rational_field import QQ
222
+ arg = operand.imag()/(2*ex.parent().pi())
223
+ try:
224
+ rat_arg = QQ.coerce(arg.pyobject())
225
+ except TypeError:
226
+ raise TypeError("unable to convert %r to %s" % (ex, self.field))
227
+ res = zeta(rat_arg.denom())**rat_arg.numer()
228
+ return self.field(res)
229
+ elif func_name in ['sin', 'cos', 'tan']:
230
+ exp_ia = exp(SR(-1).sqrt() * operand, hold=hold)._algebraic_(QQbar)
231
+ if func_name == 'sin':
232
+ res = (exp_ia - ~exp_ia) / (2 * zeta(4))
233
+ elif func_name == 'cos':
234
+ res = (exp_ia + ~exp_ia) / 2
235
+ else:
236
+ res = -zeta(4) * (exp_ia - ~exp_ia) / (exp_ia + ~exp_ia)
237
+ return self.field(res)
238
+ elif func_name in ['sinh', 'cosh', 'tanh']:
239
+ if not (SR(-1).sqrt()*operand).is_real():
240
+ raise ValueError("unable to represent as an algebraic number")
241
+ exp_a = exp(operand, hold=hold)._algebraic_(QQbar)
242
+ if func_name == 'sinh':
243
+ res = (exp_a - ~exp_a) / 2
244
+ elif func_name == 'cosh':
245
+ res = (exp_a + ~exp_a) / 2
246
+ else:
247
+ res = (exp_a - ~exp_a) / (exp_a + ~exp_a)
248
+ return self.field(res)
249
+ elif func_name in self.reciprocal_trig_functions:
250
+ res = ~self.reciprocal_trig_functions[func_name](operand)._algebraic_(QQbar)
251
+ return self.field(res)
252
+ elif func_name == 'complex_root_of':
253
+ cr = ex._sympy_()
254
+ poly = cr.poly._sage_()
255
+ interval = cr._get_interval()._sage_()
256
+ return self.field.polynomial_root(poly, interval)
257
+ elif operand is not None:
258
+ res = func(operand._algebraic_(self.field))
259
+ # We have to handle the case where we get the same symbolic
260
+ # expression back. For example, QQbar(zeta(7)). See
261
+ # issue #12665.
262
+ if (res - ex).is_trivial_zero():
263
+ raise TypeError("unable to convert %r to %s" % (ex, self.field))
264
+ return self.field(res)
265
+
266
+ raise ValueError("unable to represent as an algebraic number")
267
+
268
+
269
+ def algebraic(ex, field):
270
+ """
271
+ Return the symbolic expression ``ex`` as a element of the algebraic
272
+ field ``field``.
273
+
274
+ EXAMPLES::
275
+
276
+ sage: a = SR(5/6)
277
+ sage: AA(a)
278
+ 5/6
279
+ sage: type(AA(a))
280
+ <class 'sage.rings.qqbar.AlgebraicReal'>
281
+ sage: QQbar(a)
282
+ 5/6
283
+ sage: type(QQbar(a))
284
+ <class 'sage.rings.qqbar.AlgebraicNumber'>
285
+ sage: QQbar(i)
286
+ I
287
+ sage: AA(golden_ratio) # needs sage.libs.pari
288
+ 1.618033988749895?
289
+ sage: QQbar(golden_ratio) # needs sage.libs.pari
290
+ 1.618033988749895?
291
+ sage: QQbar(sin(pi/3)) # needs sage.libs.pari
292
+ 0.866025403784439?
293
+
294
+ sage: QQbar(sqrt(2) + sqrt(8))
295
+ 4.242640687119285?
296
+ sage: AA(sqrt(2) ^ 4) == 4
297
+ True
298
+ sage: AA(-golden_ratio)
299
+ -1.618033988749895?
300
+ sage: QQbar((2*SR(I))^(1/2))
301
+ 1 + 1*I
302
+ sage: QQbar(e^(pi*I/3))
303
+ 0.50000000000000000? + 0.866025403784439?*I
304
+
305
+ sage: AA(x*sin(0))
306
+ 0
307
+ sage: QQbar(x*sin(0))
308
+ 0
309
+ """
310
+ return AlgebraicConverter(field)(ex)
@@ -0,0 +1,317 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ # sage.doctest: needs sympy
3
+ r"""
4
+ Conversion of symbolic expressions to SymPy
5
+ """
6
+ # ****************************************************************************
7
+ # Copyright (C) 2009 Mike Hansen
8
+ # 2011 D. S. McNeil
9
+ # 2011 Francois Bissey
10
+ # 2017 Ralf Stephan
11
+ # 2017 Marco Mancini
12
+ # 2017 Travis Scrimshaw
13
+ #
14
+ # This program is free software: you can redistribute it and/or modify
15
+ # it under the terms of the GNU General Public License as published by
16
+ # the Free Software Foundation, either version 2 of the License, or
17
+ # (at your option) any later version.
18
+ # https://www.gnu.org/licenses/
19
+ # ****************************************************************************
20
+
21
+ from operator import eq, ne, gt, lt, ge, le, mul, pow, neg, add, truediv
22
+
23
+ from sage.structure.element import Expression
24
+ from sage.symbolic.expression_conversions import Converter
25
+ from sage.symbolic.operators import arithmetic_operators
26
+
27
+ #########
28
+ # Sympy #
29
+ #########
30
+
31
+
32
+ class SympyConverter(Converter):
33
+ """
34
+ Convert any expression to SymPy.
35
+
36
+ EXAMPLES::
37
+
38
+ sage: import sympy
39
+ sage: var('x,y')
40
+ (x, y)
41
+ sage: f = exp(x^2) - arcsin(pi+x)/y
42
+ sage: f._sympy_()
43
+ exp(x**2) - asin(x + pi)/y
44
+ sage: _._sage_()
45
+ -arcsin(pi + x)/y + e^(x^2)
46
+
47
+ sage: sympy.sympify(x) # indirect doctest
48
+ x
49
+
50
+ TESTS:
51
+
52
+ Make sure we can convert I (:issue:`6424`)::
53
+
54
+ sage: bool(I._sympy_() == I)
55
+ True
56
+ sage: (x+I)._sympy_()
57
+ x + I
58
+ """
59
+ def __init__(self):
60
+ """
61
+ TESTS::
62
+
63
+ sage: from sage.symbolic.expression_conversions import SympyConverter
64
+ sage: s = SympyConverter() # indirect doctest
65
+ sage: TestSuite(s).run(skip='_test_pickling')
66
+ """
67
+ from sage.interfaces.sympy import sympy_init
68
+ sympy_init()
69
+
70
+ def __call__(self, ex=None):
71
+ """
72
+ EXAMPLES::
73
+
74
+ sage: from sage.symbolic.expression_conversions import SympyConverter
75
+ sage: s = SympyConverter()
76
+ sage: f(x, y) = x^2 + y^2; f
77
+ (x, y) |--> x^2 + y^2
78
+ sage: s(f)
79
+ Lambda((x, y), x**2 + y**2)
80
+ """
81
+ if isinstance(ex, Expression) and ex.is_callable():
82
+ from sympy import Symbol, Lambda
83
+ return Lambda(tuple(Symbol(str(arg)) for arg in ex.arguments()),
84
+ super().__call__(ex))
85
+ return super().__call__(ex)
86
+
87
+ def pyobject(self, ex, obj):
88
+ """
89
+ EXAMPLES::
90
+
91
+ sage: from sage.symbolic.expression_conversions import SympyConverter
92
+ sage: s = SympyConverter()
93
+ sage: f = SR(2)
94
+ sage: s.pyobject(f, f.pyobject())
95
+ 2
96
+ sage: type(_)
97
+ <class 'sympy.core.numbers.Integer'>
98
+ """
99
+ try:
100
+ return obj._sympy_()
101
+ except AttributeError:
102
+ return obj
103
+
104
+ def arithmetic(self, ex, operator):
105
+ """
106
+ EXAMPLES::
107
+
108
+ sage: from sage.symbolic.expression_conversions import SympyConverter
109
+ sage: s = SympyConverter()
110
+ sage: f = x + 2
111
+ sage: s.arithmetic(f, f.operator())
112
+ x + 2
113
+ """
114
+ import sympy
115
+ operator = arithmetic_operators[operator]
116
+ ops = [sympy.sympify(self(a), evaluate=False) for a in ex.operands()]
117
+ if operator == "+":
118
+ return sympy.Add(*ops)
119
+ elif operator == "*":
120
+ return sympy.Mul(*ops)
121
+ elif operator == "-":
122
+ return sympy.Sub(*ops)
123
+ elif operator == "/":
124
+ return sympy.Div(*ops)
125
+ elif operator == "^":
126
+ return sympy.Pow(*ops)
127
+ else:
128
+ raise NotImplementedError
129
+
130
+ def symbol(self, ex):
131
+ """
132
+ EXAMPLES::
133
+
134
+ sage: from sage.symbolic.expression_conversions import SympyConverter
135
+ sage: s = SympyConverter()
136
+ sage: s.symbol(x)
137
+ x
138
+ sage: type(_)
139
+ <class 'sympy.core.symbol.Symbol'>
140
+ """
141
+ import sympy
142
+ return sympy.symbols(repr(ex))
143
+
144
+ def relation(self, ex, op):
145
+ """
146
+ EXAMPLES::
147
+
148
+ sage: import operator
149
+ sage: from sage.symbolic.expression_conversions import SympyConverter
150
+ sage: s = SympyConverter()
151
+ sage: s.relation(x == 3, operator.eq)
152
+ Eq(x, 3)
153
+ sage: s.relation(pi < 3, operator.lt)
154
+ pi < 3
155
+ sage: s.relation(x != pi, operator.ne)
156
+ Ne(x, pi)
157
+ sage: s.relation(x > 0, operator.gt)
158
+ x > 0
159
+ """
160
+ from sympy import Eq, Ne, Gt, Lt, Ge, Le
161
+ ops = {eq: Eq, ne: Ne, gt: Gt, lt: Lt, ge: Ge, le: Le}
162
+ return ops.get(op)(self(ex.lhs()), self(ex.rhs()), evaluate=False)
163
+
164
+ def composition(self, ex, operator):
165
+ """
166
+ EXAMPLES::
167
+
168
+ sage: from sage.symbolic.expression_conversions import SympyConverter
169
+ sage: s = SympyConverter()
170
+ sage: f = sin(2)
171
+ sage: s.composition(f, f.operator())
172
+ sin(2)
173
+ sage: type(_)
174
+ sin
175
+ sage: f = arcsin(2)
176
+ sage: s.composition(f, f.operator())
177
+ asin(2)
178
+ """
179
+ g = ex.operands()
180
+ try:
181
+ return operator._sympy_(*g)
182
+ except (AttributeError, TypeError):
183
+ pass
184
+ f = operator._sympy_init_()
185
+ import sympy
186
+
187
+ f_sympy = getattr(sympy, f, None)
188
+ if f_sympy:
189
+ return f_sympy(*sympy.sympify(g, evaluate=False))
190
+ else:
191
+ return sympy.Function(str(f))(*g, evaluate=False)
192
+
193
+ def tuple(self, ex):
194
+ """
195
+ Conversion of tuples.
196
+
197
+ EXAMPLES::
198
+
199
+ sage: t = SR._force_pyobject((3, 4, e^x))
200
+ sage: t._sympy_()
201
+ (3, 4, e^x)
202
+ sage: t = SR._force_pyobject((cos(x),))
203
+ sage: t._sympy_()
204
+ (cos(x),)
205
+
206
+ TESTS::
207
+
208
+ sage: from sage.symbolic.expression_conversions import sympy_converter
209
+ sage: F = hypergeometric([1/3,2/3],[1,1],x)
210
+ sage: F._sympy_()
211
+ hyper((1/3, 2/3), (1, 1), x)
212
+
213
+ sage: F = hypergeometric([1/3,2/3],[1],x)
214
+ sage: F._sympy_()
215
+ hyper((1/3, 2/3), (1,), x)
216
+
217
+ sage: var('a,b,c,d')
218
+ (a, b, c, d)
219
+ sage: hypergeometric((a,b,),(c,),d)._sympy_()
220
+ hyper((a, b), (c,), d)
221
+ """
222
+ return tuple(ex.operands())
223
+
224
+ def derivative(self, ex, operator):
225
+ """
226
+ Convert the derivative of ``self`` in sympy.
227
+
228
+ INPUT:
229
+
230
+ - ``ex`` -- a symbolic expression
231
+
232
+ - ``operator`` -- operator
233
+
234
+ TESTS::
235
+
236
+ sage: var('x','y')
237
+ (x, y)
238
+
239
+ sage: f_sage = function('f_sage')(x, y)
240
+ sage: f_sympy = f_sage._sympy_()
241
+
242
+ sage: df_sage = f_sage.diff(x, 2, y, 1); df_sage
243
+ diff(f_sage(x, y), x, x, y)
244
+ sage: df_sympy = df_sage._sympy_(); df_sympy
245
+ Derivative(f_sage(x, y), (x, 2), y)
246
+ sage: df_sympy == f_sympy.diff(x, 2, y, 1)
247
+ True
248
+
249
+ Check that :issue:`28964` is fixed::
250
+
251
+ sage: f = function('f')
252
+ sage: _ = var('x,t')
253
+ sage: diff(f(x, t), x)._sympy_(), diff(f(x, t), t)._sympy_()
254
+ (Derivative(f(x, t), x), Derivative(f(x, t), t))
255
+
256
+ Check differentiating by variables with multiple occurrences
257
+ (:issue:`28964`)::
258
+
259
+ sage: f = function('f')
260
+ sage: _ = var('x1,x2,x3,x,t')
261
+ sage: f(x, x, t).diff(x)._sympy_()._sage_()
262
+ D[0](f)(x, x, t) + D[1](f)(x, x, t)
263
+
264
+ sage: g = f(x1, x2, x3, t).diff(x1, 2, x2).subs(x1==x, x2==x, x3==x); g
265
+ D[0, 0, 1](f)(x, x, x, t)
266
+ sage: g._sympy_()
267
+ Subs(Derivative(f(_xi_1, _xi_2, x, t), (_xi_1, 2), _xi_2),
268
+ (_xi_1, _xi_2), (x, x))
269
+ sage: assert g._sympy_()._sage_() == g
270
+
271
+ Check that the use of dummy variables does not cause a collision::
272
+
273
+ sage: f = function('f')
274
+ sage: _ = var('x1,x2,x,xi_1')
275
+ sage: g = f(x1, x2, xi_1).diff(x1).subs(x1==x, x2==x); g
276
+ D[0](f)(x, x, xi_1)
277
+ sage: assert g._sympy_()._sage_() == g
278
+ """
279
+ import sympy
280
+
281
+ # retrieve derivated function
282
+ f = operator.function()
283
+
284
+ # retrieve order
285
+ order = operator._parameter_set
286
+ # arguments
287
+ _args = [a._sympy_() for a in ex.operands()]
288
+
289
+ # when differentiating by a variable that occurs multiple times,
290
+ # substitute it by a dummy variable
291
+ subs_new = []
292
+ subs_old = []
293
+ sympy_arg = []
294
+ for idx in order:
295
+ a = _args[idx]
296
+ if _args.count(a) > 1:
297
+ D = sympy.Dummy('xi_%i' % (idx + 1))
298
+ # to avoid collisions with ordinary symbols when converting
299
+ # back to Sage, we pick an unused variable name for the dummy
300
+ while D._sage_() in ex.variables():
301
+ D = sympy.Dummy(D.name + '_0')
302
+ subs_old.append(a)
303
+ subs_new.append(D)
304
+ _args[idx] = D
305
+ sympy_arg.append(D)
306
+ else:
307
+ sympy_arg.append(a)
308
+
309
+ f_sympy = f._sympy_()(*_args)
310
+ result = f_sympy.diff(*sympy_arg)
311
+ if subs_new:
312
+ return sympy.Subs(result, subs_new, subs_old)
313
+ else:
314
+ return result
315
+
316
+
317
+ sympy_converter = SympyConverter()