passagemath-symbolics 10.8.1a1__cp311-cp311-macosx_13_0_arm64.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 (182) hide show
  1. passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_symbolics/__init__.py +3 -0
  3. passagemath_symbolics-10.8.1a1.dist-info/METADATA +186 -0
  4. passagemath_symbolics-10.8.1a1.dist-info/RECORD +182 -0
  5. passagemath_symbolics-10.8.1a1.dist-info/WHEEL +6 -0
  6. passagemath_symbolics-10.8.1a1.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 +2838 -0
  10. sage/calculus/desolvers.py +1864 -0
  11. sage/calculus/predefined.py +51 -0
  12. sage/calculus/tests.py +225 -0
  13. sage/calculus/var.cpython-311-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-311-darwin.so +0 -0
  19. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1034 -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 +755 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2419 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1083 -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 +2991 -0
  45. sage/interfaces/magma_free.py +90 -0
  46. sage/interfaces/maple.py +1402 -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 +553 -0
  55. sage/manifolds/catalog.py +437 -0
  56. sage/manifolds/chart.py +4010 -0
  57. sage/manifolds/chart_func.py +3416 -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 +1668 -0
  71. sage/manifolds/differentiable/diff_form.py +1660 -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 +1522 -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 +912 -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 +1725 -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 +2721 -0
  119. sage/manifolds/subsets/all.py +1 -0
  120. sage/manifolds/subsets/closure.py +131 -0
  121. sage/manifolds/subsets/pullback.py +883 -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 +1347 -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-311-darwin.so +0 -0
  130. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  131. sage/matrix/matrix_symbolic_dense.pyx +1030 -0
  132. sage/matrix/matrix_symbolic_sparse.cpython-311-darwin.so +0 -0
  133. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  134. sage/matrix/matrix_symbolic_sparse.pyx +1038 -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 +4106 -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 +5205 -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 +987 -0
  151. sage/symbolic/benchmark.py +93 -0
  152. sage/symbolic/callable.py +456 -0
  153. sage/symbolic/callable.pyi +66 -0
  154. sage/symbolic/comparison_impl.pyi +38 -0
  155. sage/symbolic/complexity_measures.py +35 -0
  156. sage/symbolic/constants.py +1286 -0
  157. sage/symbolic/constants_c_impl.pyi +10 -0
  158. sage/symbolic/expression_conversion_algebraic.py +310 -0
  159. sage/symbolic/expression_conversion_sympy.py +317 -0
  160. sage/symbolic/expression_conversions.py +1727 -0
  161. sage/symbolic/function_factory.py +355 -0
  162. sage/symbolic/function_factory.pyi +41 -0
  163. sage/symbolic/getitem_impl.pyi +24 -0
  164. sage/symbolic/integration/all.py +1 -0
  165. sage/symbolic/integration/external.py +271 -0
  166. sage/symbolic/integration/integral.py +1075 -0
  167. sage/symbolic/maxima_wrapper.py +162 -0
  168. sage/symbolic/operators.py +267 -0
  169. sage/symbolic/operators.pyi +61 -0
  170. sage/symbolic/pynac_constant_impl.pyi +13 -0
  171. sage/symbolic/pynac_function_impl.pyi +8 -0
  172. sage/symbolic/random_tests.py +461 -0
  173. sage/symbolic/relation.py +2062 -0
  174. sage/symbolic/ring.cpython-311-darwin.so +0 -0
  175. sage/symbolic/ring.pxd +5 -0
  176. sage/symbolic/ring.pyi +110 -0
  177. sage/symbolic/ring.pyx +1393 -0
  178. sage/symbolic/series_impl.pyi +10 -0
  179. sage/symbolic/subring.py +1025 -0
  180. sage/symbolic/symengine.py +19 -0
  181. sage/symbolic/tests.py +40 -0
  182. sage/symbolic/units.py +1468 -0
@@ -0,0 +1,461 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ """
3
+ Randomized tests of GiNaC / PyNaC
4
+ """
5
+
6
+ ###############################################################################
7
+ # Sage: Open Source Mathematical Software
8
+ # Copyright (C) 2008 William Stein <wstein@gmail.com>
9
+ # Copyright (C) 2008 Burcin Erocal <burcin@erocal.org>
10
+ # Distributed under the terms of the GNU General Public License (GPL),
11
+ # version 2 or any later version. The full text of the GPL is available at:
12
+ # https://www.gnu.org/licenses/
13
+ ###############################################################################
14
+
15
+
16
+ from sage.misc.prandom import randint, random
17
+ import operator
18
+ from sage.rings.rational_field import QQ
19
+ from sage.symbolic.ring import SR
20
+ from sage.symbolic.expression import symbol_table, mixed_order
21
+ from sage.symbolic.constants import (pi, e, golden_ratio, log2, euler_gamma,
22
+ catalan, khinchin, twinprime, mertens)
23
+ from sage.functions.hypergeometric import hypergeometric
24
+ from sage.functions.other import (cases, element_of)
25
+
26
+
27
+ ##############################################################
28
+ # Generate random expressions for doctests #
29
+ ##############################################################
30
+
31
+ def _mk_full_functions():
32
+ r"""
33
+ A simple function that returns a list of all Pynac functions of known
34
+ arity, sorted by name.
35
+
36
+ EXAMPLES::
37
+
38
+ sage: from sage.symbolic.random_tests import _mk_full_functions
39
+ sage: [f for (one,f,arity) in _mk_full_functions()] # random
40
+ [Ei, abs, arccos, arccosh, arccot, arccoth, arccsc, arccsch,
41
+ arcsec, arcsech, arcsin, arcsinh, arctan, arctan2, arctanh,
42
+ arg, beta, binomial, ceil, conjugate, cos, cosh, cot, coth,
43
+ csc, csch, dickman_rho, dilog, dirac_delta, elliptic_e,
44
+ elliptic_ec, elliptic_eu, elliptic_f, elliptic_kc,
45
+ elliptic_pi, erf, exp, factorial, floor, heaviside, imag_part,
46
+ integrate, kronecker_delta, log, polylog, real_part, sec,
47
+ sech, sgn, sin, sinh, tan, tanh, unit_step, zeta, zetaderiv]
48
+
49
+ Note that this doctest will produce different output whenever a
50
+ symbolic function is added or removed.
51
+ """
52
+ excluded = [hypergeometric, cases, element_of]
53
+ items = sorted(symbol_table['functions'].items())
54
+ return [(1.0, f, f.number_of_arguments())
55
+ for (name, f) in items
56
+ if hasattr(f, 'number_of_arguments') and
57
+ f.number_of_arguments() > 0 and
58
+ f not in excluded]
59
+
60
+
61
+ # For creating simple expressions
62
+
63
+ fast_binary = [(0.4, operator.add), (0.1, operator.sub), (0.5, operator.mul)]
64
+ fast_unary = [(0.8, operator.neg), (0.2, operator.abs)]
65
+ fast_nodes = [(0.9, fast_binary, 2), (0.1, fast_unary, 1)]
66
+
67
+ # For creating expressions with the full power of Pynac's simple expression
68
+ # subset (with no quantifiers/operators; that is, no derivatives, integrals,
69
+ # etc.)
70
+ full_binary = [(0.3, operator.add), (0.1, operator.sub), (0.3, operator.mul), (0.2, operator.truediv), (0.1, operator.pow)]
71
+ full_unary = [(0.8, operator.neg), (0.2, operator.inv)]
72
+ full_functions = _mk_full_functions()
73
+ full_nullary = [(1.0, c) for c in [pi, e]] + [(0.05, c) for c in
74
+ [golden_ratio, log2, euler_gamma, catalan, khinchin, twinprime,
75
+ mertens]]
76
+ full_internal = [(0.6, full_binary, 2), (0.2, full_unary, 1),
77
+ (0.2, full_functions)]
78
+
79
+
80
+ def normalize_prob_list(pl, extra=()):
81
+ r"""
82
+ INPUT:
83
+
84
+ - ``pl`` -- list of tuples, where the first element of each tuple is
85
+ a floating-point number (representing a relative probability). The
86
+ second element of each tuple may be a list or any other kind of object.
87
+
88
+ - ``extra`` -- tuple which is to be appended to every tuple in ``pl``
89
+
90
+ This function takes such a list of tuples (a "probability list") and
91
+ normalizes the probabilities so that they sum to one. If any of the
92
+ values are lists, then those lists are first normalized; then
93
+ the probabilities in the list are multiplied by the main probability
94
+ and the sublist is merged with the main list.
95
+
96
+ For example, suppose we want to select between group A and group B with
97
+ 50% probability each. Then within group A, we select A1 or A2 with 50%
98
+ probability each (so the overall probability of selecting A1 is 25%);
99
+ and within group B, we select B1, B2, or B3 with probabilities in
100
+ a 1:2:2 ratio.
101
+
102
+ EXAMPLES::
103
+
104
+ sage: from sage.symbolic.random_tests import *
105
+ sage: A = [(0.5, 'A1'), (0.5, 'A2')]
106
+ sage: B = [(1, 'B1'), (2, 'B2'), (2, 'B3')]
107
+ sage: top = [(50, A, 'Group A'), (50, B, 'Group B')]
108
+ sage: normalize_prob_list(top)
109
+ [(0.250000000000000, 'A1', 'Group A'), (0.250000000000000, 'A2', 'Group A'), (0.1, 'B1', 'Group B'), (0.2, 'B2', 'Group B'), (0.2, 'B3', 'Group B')]
110
+ """
111
+ if len(pl) == 0:
112
+ return pl
113
+ result = []
114
+ total = sum(float(p[0]) for p in pl)
115
+ for p in pl:
116
+ prob = p[0]
117
+ val = p[1]
118
+ if len(p) > 2:
119
+ p_extra = p[2:]
120
+ else:
121
+ p_extra = extra
122
+ if isinstance(val, list):
123
+ norm_val = normalize_prob_list(val, extra=p_extra)
124
+ result.extend(((prob / total) * np[0], np[1]) + np[2:]
125
+ for np in norm_val)
126
+ else:
127
+ result.append(((prob / total), val) + p_extra)
128
+ return result
129
+
130
+
131
+ def choose_from_prob_list(lst):
132
+ r"""
133
+ INPUT:
134
+
135
+ - ``lst`` -- list of tuples, where the first element of each tuple
136
+ is a nonnegative float (a probability), and the probabilities sum
137
+ to one
138
+
139
+ OUTPUT:
140
+
141
+ A tuple randomly selected from the list according to the given
142
+ probabilities.
143
+
144
+ EXAMPLES::
145
+
146
+ sage: from sage.symbolic.random_tests import *
147
+ sage: v = [(0.1, False), (0.9, True)]
148
+ sage: choose_from_prob_list(v) # random
149
+ (0.900000000000000, True)
150
+ sage: true_count = 0
151
+ sage: total_count = 0
152
+ sage: def more_samples():
153
+ ....: global true_count, total_count
154
+ ....: for _ in range(10000):
155
+ ....: total_count += 1.0
156
+ ....: if choose_from_prob_list(v)[1]:
157
+ ....: true_count += 1.0
158
+ sage: more_samples()
159
+ sage: while abs(true_count/total_count - 0.9) > 0.01:
160
+ ....: more_samples()
161
+ """
162
+ r = random()
163
+ for i in range(len(lst) - 1):
164
+ if r < lst[i][0]:
165
+ return lst[i]
166
+ r -= lst[i][0]
167
+ return lst[-1]
168
+
169
+
170
+ def random_integer_vector(n, length):
171
+ r"""
172
+ Give a random list of length *length*, consisting of nonnegative
173
+ integers that sum to *n*.
174
+
175
+ This is an approximation to IntegerVectors(n, length).random_element().
176
+ That gives values uniformly at random, but might be slow; this
177
+ routine is not uniform, but should always be fast.
178
+
179
+ (This routine is uniform if ``length`` is 1 or 2; for longer vectors,
180
+ we prefer approximately balanced vectors, where all the values
181
+ are around `n/{length}`.)
182
+
183
+ EXAMPLES::
184
+
185
+ sage: from sage.symbolic.random_tests import *
186
+ sage: a = random_integer_vector(100, 2); a # random
187
+ [11, 89]
188
+ sage: len(a)
189
+ 2
190
+ sage: sum(a)
191
+ 100
192
+
193
+ sage: b = random_integer_vector(10000, 20)
194
+ sage: len(b)
195
+ 20
196
+ sage: sum(b)
197
+ 10000
198
+
199
+ The routine is uniform if ``length`` is 2::
200
+
201
+ sage: true_count = 0
202
+ sage: total_count = 0
203
+ sage: def more_samples():
204
+ ....: global true_count, total_count
205
+ ....: for _ in range(1000):
206
+ ....: total_count += 1.0
207
+ ....: if a == random_integer_vector(100, 2):
208
+ ....: true_count += 1.0
209
+ sage: more_samples()
210
+ sage: while abs(true_count/total_count - 0.01) > 0.01:
211
+ ....: more_samples()
212
+ """
213
+ if length == 0:
214
+ return []
215
+ elif length == 1:
216
+ return [n]
217
+ elif length == 2:
218
+ v = randint(0, n)
219
+ return [v, n - v]
220
+ else:
221
+ v = randint(0, 2 * n // length)
222
+ return [v] + random_integer_vector(n - v, length - 1)
223
+
224
+
225
+ def random_expr_helper(n_nodes, internal, leaves, verbose):
226
+ r"""
227
+ Produce a random symbolic expression of size *n_nodes* (or slightly
228
+ larger). Internal nodes are selected from the *internal* probability
229
+ list; leaves are selected from *leaves*. If *verbose* is True,
230
+ then a message is printed before creating an internal node.
231
+
232
+ EXAMPLES::
233
+
234
+ sage: from sage.symbolic.random_tests import *
235
+ sage: a = random_expr_helper(9, [(0.5, operator.add, 2),
236
+ ....: (0.5, operator.neg, 1)], [(0.5, 1), (0.5, x)], True)
237
+ About to apply <built-in function ...
238
+
239
+ In small cases we will see all cases quickly::
240
+
241
+ sage: def next_expr():
242
+ ....: return random_expr_helper(
243
+ ....: 6, [(0.5, operator.add, 2), (0.5, operator.neg, 1)],
244
+ ....: [(0.5, 1), (0.5, x)], False)
245
+ sage: all_exprs = set()
246
+ sage: for a in range(-4, 5):
247
+ ....: for b in range(-4+abs(a), 5-abs(a)):
248
+ ....: if a % 2 and abs(a) + abs(b) == 4 and sign(a) != sign(b):
249
+ ....: continue
250
+ ....: all_exprs.add(a*x + b)
251
+ sage: our_exprs = set()
252
+ sage: while our_exprs != all_exprs:
253
+ ....: our_exprs.add(next_expr())
254
+ """
255
+ if n_nodes == 1:
256
+ return choose_from_prob_list(leaves)[1]
257
+ else:
258
+ r = choose_from_prob_list(internal)
259
+ n_nodes -= 1
260
+ n_children = r[2]
261
+ n_spare_nodes = n_nodes - n_children
262
+ n_spare_nodes = max(0, n_spare_nodes)
263
+ nodes_per_child = random_integer_vector(n_spare_nodes, n_children)
264
+ children = [random_expr_helper(n + 1, internal, leaves, verbose)
265
+ for n in nodes_per_child]
266
+ if verbose:
267
+ print("About to apply %r to %r" % (r[1], children))
268
+ return r[1](*children)
269
+
270
+
271
+ def random_expr(size, nvars=1, ncoeffs=None, var_frac=0.5,
272
+ internal=full_internal,
273
+ nullary=full_nullary, nullary_frac=0.2,
274
+ coeff_generator=QQ.random_element, verbose=False):
275
+ r"""
276
+ Produce a random symbolic expression of the given size. By
277
+ default, the expression involves (at most) one variable, an arbitrary
278
+ number of coefficients, and all of the symbolic functions and constants
279
+ (from the probability lists full_internal and full_nullary). It is
280
+ possible to adjust the ratio of leaves between symbolic constants,
281
+ variables, and coefficients (var_frac gives the fraction of variables,
282
+ and nullary_frac the fraction of symbolic constants; the remaining
283
+ leaves are coefficients).
284
+
285
+ The actual mix of symbolic constants and internal nodes can be modified
286
+ by specifying different probability lists.
287
+
288
+ To use a different type for coefficients, you can specify
289
+ coeff_generator, which should be a function that will return
290
+ a random coefficient every time it is called.
291
+
292
+ This function will often raise an error because it tries to create
293
+ an erroneous expression (such as a division by zero).
294
+
295
+ EXAMPLES::
296
+
297
+ sage: from sage.symbolic.random_tests import *
298
+ sage: some_functions = [arcsinh, arctan, arctan2, arctanh,
299
+ ....: arg, beta, binomial, ceil, conjugate, cos, cosh, cot, coth,
300
+ ....: elliptic_pi, erf, exp, factorial, floor, heaviside, imag_part,
301
+ ....: sech, sgn, sin, sinh, tan, tanh, unit_step, zeta, zetaderiv]
302
+ sage: my_internal = [(0.6, full_binary, 2), (0.2, full_unary, 1),
303
+ ....: (0.2, [(1.0,f,f.number_of_arguments()) for f in some_functions])]
304
+ sage: set_random_seed(1)
305
+ sage: random_expr(50, nvars=3, internal=my_internal, # not tested # known bug
306
+ ....: coeff_generator=CDF.random_element)
307
+ (v1^(0.9713408427702117 + 0.195868299334218*I)/cot(-pi + v1^2 + v3) + tan(arctan(v2 + arctan2(-0.35859061674557324 + 0.9407509502498164*I, v3) - 0.8419115504372718 + 0.30375717982404615*I) + arctan2((0.2275357305882964 - 0.8258002386106038*I)/factorial(v2), -v3 - 0.7604559947718565 - 0.5543672548552057*I) + ceil(1/arctan2(v1, v1))))/v2
308
+ sage: random_expr(5, verbose=True) # not tested # known bug
309
+ About to apply <built-in function inv> to [31]
310
+ About to apply sgn to [v1]
311
+ About to apply <built-in function add> to [1/31, sgn(v1)]
312
+ sgn(v1) + 1/31
313
+ """
314
+ vars = [(1.0, SR.var('v%d' % (n + 1))) for n in range(nvars)]
315
+ if ncoeffs is None:
316
+ ncoeffs = size
317
+ coeffs = [(1.0, coeff_generator()) for _ in range(ncoeffs)]
318
+ leaves = [(var_frac, vars), (1.0 - var_frac - nullary_frac, coeffs), (nullary_frac, nullary)]
319
+ leaves = normalize_prob_list(leaves)
320
+
321
+ internal = normalize_prob_list(internal)
322
+
323
+ return random_expr_helper(size, internal, leaves, verbose)
324
+
325
+
326
+ #####################################
327
+ # Test the ordering of operands #
328
+ #####################################
329
+
330
+ def assert_strict_weak_order(a, b, c, cmp_func):
331
+ r"""
332
+ Check that ``cmp_func`` is a strict weak order on the elements a,b,c.
333
+
334
+ A strict weak order is a binary relation ``<`` such that
335
+
336
+ * For all `x`, it is not the case that `x < x` (irreflexivity).
337
+
338
+ * For all `x\not=y`, if `x < y` then it is not the case that `y <
339
+ x` (asymmetry).
340
+
341
+ * For all `x`, `y`, and `z`, if `x < y` and `y < z` then `x < z`
342
+ (transitivity).
343
+
344
+ * For all `x`, `y`, and `z`, if x is incomparable with `y`, and
345
+ `y` is incomparable with `z`, then `x` is incomparable with `z`
346
+ (transitivity of incomparability).
347
+
348
+ INPUT:
349
+
350
+ - ``a``, ``b``, ``c`` -- anything that can be compared by ``cmp_func``
351
+
352
+ - ``cmp_func`` -- function of two arguments that returns their
353
+ comparison (i.e. either ``True`` or ``False``)
354
+
355
+ OUTPUT:
356
+
357
+ Nothing. Raises a :exc:`ValueError` if ``cmp_func``
358
+ is not a strict weak order on the three given elements.
359
+
360
+ REFERENCES:
361
+
362
+ :wikipedia:`Strict_weak_ordering`
363
+
364
+ EXAMPLES:
365
+
366
+ The usual ordering of integers is a strict weak order::
367
+
368
+ sage: from sage.symbolic.random_tests import assert_strict_weak_order
369
+ sage: a, b, c = [randint(-10, 10) for i in range(3)]
370
+ sage: assert_strict_weak_order(a, b, c, lambda x, y: x < y)
371
+
372
+ sage: x = [-SR(oo), SR(0), SR(oo)]
373
+ sage: cmp_M = matrix(3, 3, 0)
374
+ sage: for i in range(3):
375
+ ....: for j in range(3):
376
+ ....: if x[i] < x[j]:
377
+ ....: cmp_M[i, j] = -1
378
+ ....: elif x[i] > x[j]:
379
+ ....: cmp_M[i, j] = 1
380
+ sage: cmp_M
381
+ [ 0 -1 -1]
382
+ [ 1 0 -1]
383
+ [ 1 1 0]
384
+ """
385
+ from sage.matrix.constructor import matrix
386
+ from sage.combinat.permutation import Permutations
387
+ x = (a, b, c)
388
+
389
+ cmp_M = matrix(3, 3)
390
+ for i in range(3):
391
+ for j in range(3):
392
+ cmp_M[i, j] = (cmp_func(x[i], x[j]) == 1) # or -1, doesn't matter
393
+
394
+ msg = 'the binary relation failed to be a strict weak order on the elements \n'
395
+ msg += ' a = {}\n b = {}\n c = {}\n'.format(a, b, c)
396
+ msg += str(cmp_M)
397
+
398
+ for i in range(3):
399
+ # irreflexivity
400
+ if cmp_M[i, i]:
401
+ raise ValueError(msg)
402
+
403
+ # asymmetric
404
+ for j in range(i):
405
+ if cmp_M[i, j] and cmp_M[j, i]:
406
+ raise ValueError(msg)
407
+
408
+ def incomparable(i, j):
409
+ return not (cmp_M[i, j] or cmp_M[j, i])
410
+
411
+ for i, j, k in Permutations([0, 1, 2]):
412
+ # transitivity
413
+ if cmp_M[i, j] and cmp_M[j, k] and not cmp_M[i, k]:
414
+ raise ValueError(msg)
415
+
416
+ # transitivity of incomparability
417
+ if (incomparable(i, j) and incomparable(j, k) and
418
+ not incomparable(i, k)):
419
+ raise ValueError(msg)
420
+
421
+
422
+ def check_symbolic_expression_order(repetitions=100):
423
+ r"""
424
+ Test whether the comparison of random symbolic expressions
425
+ satisfies the strict weak order axioms.
426
+
427
+ This is important because the C++ extension class uses
428
+ ``std::sort()`` which requires a strict weak order. See also
429
+ :issue:`9880`.
430
+
431
+ EXAMPLES::
432
+
433
+ sage: from sage.symbolic.random_tests import check_symbolic_expression_order
434
+ sage: check_symbolic_expression_order(500) # long time
435
+ """
436
+ rnd_length = 50
437
+ nvars = 10
438
+ ncoeffs = 10
439
+ var_frac = 0.5
440
+ nullary_frac = 0.05
441
+
442
+ def coeff_generator():
443
+ return randint(-100, 100) / randint(1, 100)
444
+
445
+ def make_random_expr():
446
+ while True:
447
+ try:
448
+ return random_expr(
449
+ rnd_length, nvars=nvars, ncoeffs=ncoeffs, var_frac=var_frac,
450
+ nullary_frac=nullary_frac, coeff_generator=coeff_generator,
451
+ internal=fast_nodes)
452
+ except (ZeroDivisionError, ValueError):
453
+ pass
454
+
455
+ for rep in range(repetitions):
456
+ a = make_random_expr()
457
+ b = make_random_expr()
458
+ c = make_random_expr()
459
+ assert_strict_weak_order(a, b, c, mixed_order)
460
+ assert_strict_weak_order(a, b, c, lambda x, y: x._cmp_add(y))
461
+ assert_strict_weak_order(a, b, c, lambda x, y: x._cmp_mul(y))