passagemath-symbolics 10.6.43__cp314-cp314t-musllinux_1_2_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 (171) hide show
  1. passagemath_symbolics/__init__.py +3 -0
  2. passagemath_symbolics-10.6.43.dist-info/METADATA +187 -0
  3. passagemath_symbolics-10.6.43.dist-info/RECORD +171 -0
  4. passagemath_symbolics-10.6.43.dist-info/WHEEL +5 -0
  5. passagemath_symbolics-10.6.43.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 +2826 -0
  9. sage/calculus/desolvers.py +1866 -0
  10. sage/calculus/predefined.py +51 -0
  11. sage/calculus/tests.py +225 -0
  12. sage/calculus/var.cpython-314t-x86_64-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-x86_64-linux-musl.so +0 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -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 +743 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -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 +3017 -0
  44. sage/interfaces/magma_free.py +92 -0
  45. sage/interfaces/maple.py +1397 -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 +555 -0
  54. sage/manifolds/catalog.py +437 -0
  55. sage/manifolds/chart.py +4019 -0
  56. sage/manifolds/chart_func.py +3419 -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 +1671 -0
  70. sage/manifolds/differentiable/diff_form.py +1658 -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 +1520 -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 +910 -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 +1728 -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 +2764 -0
  118. sage/manifolds/subsets/all.py +1 -0
  119. sage/manifolds/subsets/closure.py +131 -0
  120. sage/manifolds/subsets/pullback.py +885 -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 +1342 -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-x86_64-linux-musl.so +0 -0
  129. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  130. sage/matrix/matrix_symbolic_dense.pyx +1022 -0
  131. sage/matrix/matrix_symbolic_sparse.cpython-314t-x86_64-linux-musl.so +0 -0
  132. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  133. sage/matrix/matrix_symbolic_sparse.pyx +1029 -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 +4153 -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 +5237 -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 +985 -0
  150. sage/symbolic/benchmark.py +93 -0
  151. sage/symbolic/callable.py +459 -0
  152. sage/symbolic/complexity_measures.py +35 -0
  153. sage/symbolic/constants.py +1287 -0
  154. sage/symbolic/expression_conversion_algebraic.py +310 -0
  155. sage/symbolic/expression_conversion_sympy.py +317 -0
  156. sage/symbolic/expression_conversions.py +1713 -0
  157. sage/symbolic/function_factory.py +355 -0
  158. sage/symbolic/integration/all.py +1 -0
  159. sage/symbolic/integration/external.py +270 -0
  160. sage/symbolic/integration/integral.py +1115 -0
  161. sage/symbolic/maxima_wrapper.py +162 -0
  162. sage/symbolic/operators.py +267 -0
  163. sage/symbolic/random_tests.py +462 -0
  164. sage/symbolic/relation.py +1907 -0
  165. sage/symbolic/ring.cpython-314t-x86_64-linux-musl.so +0 -0
  166. sage/symbolic/ring.pxd +5 -0
  167. sage/symbolic/ring.pyx +1396 -0
  168. sage/symbolic/subring.py +1025 -0
  169. sage/symbolic/symengine.py +19 -0
  170. sage/symbolic/tests.py +40 -0
  171. sage/symbolic/units.py +1470 -0
@@ -0,0 +1,1485 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ # sage.doctest: needs sage.graphs
3
+ r"""
4
+ Common Asymptotic Expansions
5
+
6
+ Asymptotic expansions in SageMath can be built through the
7
+ ``asymptotic_expansions`` object. It contains generators for common
8
+ asymptotic expressions. For example,
9
+ ::
10
+
11
+ sage: asymptotic_expansions.Stirling('n', precision=5)
12
+ sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +
13
+ 1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +
14
+ 1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +
15
+ O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))
16
+
17
+ generates the first 5 summands of Stirling's approximation formula for
18
+ factorials.
19
+
20
+ To construct an asymptotic expression manually, you can use the class
21
+ :class:`~sage.rings.asymptotic.asymptotic_ring.AsymptoticRing`. See
22
+ :doc:`asymptotic ring <asymptotic_ring>` for more details and a lot of
23
+ examples.
24
+
25
+
26
+ **Asymptotic Expansions**
27
+
28
+ .. list-table::
29
+ :class: contentstable
30
+ :widths: 4 12
31
+ :header-rows: 0
32
+
33
+ * - :meth:`~AsymptoticExpansionGenerators.HarmonicNumber`
34
+ - harmonic numbers
35
+
36
+ * - :meth:`~AsymptoticExpansionGenerators.Stirling`
37
+ - Stirling's approximation formula for factorials
38
+
39
+ * - :meth:`~AsymptoticExpansionGenerators.log_Stirling`
40
+ - the logarithm of Stirling's approximation formula for factorials
41
+
42
+ * - :meth:`~AsymptoticExpansionGenerators.Binomial_kn_over_n`
43
+ - an asymptotic expansion of the binomial coefficient
44
+
45
+ * - :meth:`~AsymptoticExpansionGenerators.SingularityAnalysis`
46
+ - an asymptotic expansion obtained by singularity analysis
47
+
48
+ * - :meth:`~AsymptoticExpansionGenerators.ImplicitExpansion`
49
+ - the singular expansion of a function `y(z)` satisfying `y(z) = z \Phi(y(z))`
50
+
51
+ * - :meth:`~AsymptoticExpansionGenerators.ImplicitExpansionPeriodicPart`
52
+ - the singular expansion of the periodic part of a function `y(z)` satisfying `y(z) = z\Phi(y(z))`
53
+
54
+ * - :meth:`~AsymptoticExpansionGenerators.InverseFunctionAnalysis`
55
+ - coefficient growth of a function `y(z)` defined implicitly by `y(z) = z \Phi(y(z))`
56
+
57
+
58
+ AUTHORS:
59
+
60
+ - Daniel Krenn (2015)
61
+ - Clemens Heuberger (2016)
62
+ - Benjamin Hackl (2016)
63
+
64
+ ACKNOWLEDGEMENT:
65
+
66
+ - Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the
67
+ Austrian Science Fund (FWF): P 24644-N26.
68
+
69
+ Classes and Methods
70
+ ===================
71
+ """
72
+
73
+ # ****************************************************************************
74
+ # Copyright (C) 2015 Daniel Krenn <dev@danielkrenn.at>
75
+ # Copyright (C) 2016 Clemens Heuberger <clemens.heuberger@aau.at>
76
+ #
77
+ # This program is free software: you can redistribute it and/or modify
78
+ # it under the terms of the GNU General Public License as published by
79
+ # the Free Software Foundation, either version 2 of the License, or
80
+ # (at your option) any later version.
81
+ # https://www.gnu.org/licenses/
82
+ # ****************************************************************************
83
+
84
+ from sage.misc.superseded import experimental
85
+ from sage.structure.sage_object import SageObject
86
+ from sage.misc.defaults import series_precision
87
+
88
+
89
+ class AsymptoticExpansionGenerators(SageObject):
90
+ r"""
91
+ A collection of constructors for several common asymptotic expansions.
92
+
93
+ A list of all asymptotic expansions in this database is available via tab
94
+ completion. Type "``asymptotic_expansions.``" and then hit tab to see which
95
+ expansions are available.
96
+
97
+ The asymptotic expansions currently in this class include:
98
+
99
+ - :meth:`~HarmonicNumber`
100
+ - :meth:`~Stirling`
101
+ - :meth:`~log_Stirling`
102
+ - :meth:`~Binomial_kn_over_n`
103
+ - :meth:`~SingularityAnalysis`
104
+ - :meth:`~ImplicitExpansion`
105
+ - :meth:`~ImplicitExpansionPeriodicPart`
106
+ - :meth:`~InverseFunctionAnalysis`
107
+ """
108
+
109
+ @staticmethod
110
+ def Stirling(var, precision=None, skip_constant_factor=False):
111
+ r"""
112
+ Return Stirling's approximation formula for factorials.
113
+
114
+ INPUT:
115
+
116
+ - ``var`` -- string for the variable name
117
+
118
+ - ``precision`` -- (default: ``None``) integer `\ge 3`. If ``None``, then
119
+ the default precision of the asymptotic ring is used.
120
+
121
+ - ``skip_constant_factor`` -- boolean (default: ``False``); if set,
122
+ then the constant factor `\sqrt{2\pi}` is left out.
123
+ As a consequence, the coefficient ring of the output changes
124
+ from ``Symbolic Constants Subring`` (if ``False``) to
125
+ ``Rational Field`` (if ``True``).
126
+
127
+ OUTPUT: an asymptotic expansion
128
+
129
+ EXAMPLES::
130
+
131
+ sage: asymptotic_expansions.Stirling('n', precision=5)
132
+ sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +
133
+ 1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +
134
+ 1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +
135
+ O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))
136
+ sage: _.parent()
137
+ Asymptotic Ring <(e^(n*log(n)))^QQ * (e^n)^QQ * n^QQ * log(n)^QQ>
138
+ over Symbolic Constants Subring
139
+
140
+ .. SEEALSO::
141
+
142
+ :meth:`log_Stirling`,
143
+ :meth:`~sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion.factorial`.
144
+
145
+ TESTS::
146
+
147
+ sage: expansion = asymptotic_expansions.Stirling('n', precision=5)
148
+ sage: n = expansion.parent().gen()
149
+ sage: expansion.compare_with_values(n, lambda x: x.factorial(), [5, 10, 20]) # rel tol 1e-6
150
+ [(5, 0.00675841118?), (10, 0.0067589306?), (20, 0.006744925?)]
151
+ sage: asymptotic_expansions.Stirling('n', precision=5,
152
+ ....: skip_constant_factor=True)
153
+ e^(n*log(n))*(e^n)^(-1)*n^(1/2) +
154
+ 1/12*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +
155
+ 1/288*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +
156
+ O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))
157
+ sage: _.parent()
158
+ Asymptotic Ring <(e^(n*log(n)))^QQ * (e^n)^QQ * n^QQ * log(n)^QQ>
159
+ over Rational Field
160
+ sage: asymptotic_expansions.Stirling('m', precision=4)
161
+ sqrt(2)*sqrt(pi)*e^(m*log(m))*(e^m)^(-1)*m^(1/2) +
162
+ O(e^(m*log(m))*(e^m)^(-1)*m^(-1/2))
163
+ sage: asymptotic_expansions.Stirling('m', precision=3)
164
+ O(e^(m*log(m))*(e^m)^(-1)*m^(1/2))
165
+ sage: asymptotic_expansions.Stirling('m', precision=2)
166
+ Traceback (most recent call last):
167
+ ...
168
+ ValueError: precision must be at least 3
169
+
170
+ Check that :issue:`20066` is resolved::
171
+
172
+ sage: set_series_precision(5)
173
+ sage: asymptotic_expansions.Stirling('n')
174
+ sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +
175
+ ... + O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))
176
+ sage: set_series_precision(20) # restore series precision default
177
+ """
178
+ if precision is None:
179
+ precision = series_precision()
180
+
181
+ if precision < 3:
182
+ raise ValueError("precision must be at least 3")
183
+ log_Stirling = AsymptoticExpansionGenerators.log_Stirling(
184
+ var, precision=precision, skip_constant_summand=True)
185
+
186
+ P = log_Stirling.parent().change_parameter(
187
+ growth_group='(e^({n}*log({n})))^QQ * (e^{n})^QQ * {n}^QQ * log({n})^QQ'.format(n=var))
188
+ from sage.functions.log import exp
189
+ result = exp(P(log_Stirling))
190
+
191
+ if not skip_constant_factor:
192
+ from sage.symbolic.ring import SR
193
+ SCR = SR.subring(no_variables=True)
194
+ result *= (2*SCR('pi')).sqrt()
195
+
196
+ return result
197
+
198
+ @staticmethod
199
+ def log_Stirling(var, precision=None, skip_constant_summand=False):
200
+ r"""
201
+ Return the logarithm of Stirling's approximation formula
202
+ for factorials.
203
+
204
+ INPUT:
205
+
206
+ - ``var`` -- string for the variable name
207
+
208
+ - ``precision`` -- (default: ``None``) integer. If ``None``, then
209
+ the default precision of the asymptotic ring is used.
210
+
211
+ - ``skip_constant_summand`` -- boolean (default: ``False``); if set,
212
+ then the constant summand `\log(2\pi)/2` is left out.
213
+ As a consequence, the coefficient ring of the output changes
214
+ from ``Symbolic Constants Subring`` (if ``False``) to
215
+ ``Rational Field`` (if ``True``).
216
+
217
+ OUTPUT: an asymptotic expansion
218
+
219
+ EXAMPLES::
220
+
221
+ sage: asymptotic_expansions.log_Stirling('n', precision=7)
222
+ n*log(n) - n + 1/2*log(n) + 1/2*log(2*pi) + 1/12*n^(-1)
223
+ - 1/360*n^(-3) + 1/1260*n^(-5) + O(n^(-7))
224
+
225
+ .. SEEALSO::
226
+
227
+ :meth:`Stirling`,
228
+ :meth:`~sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion.factorial`.
229
+
230
+ TESTS::
231
+
232
+ sage: expansion = asymptotic_expansions.log_Stirling('n', precision=7)
233
+ sage: n = expansion.parent().gen()
234
+ sage: expansion.compare_with_values(n, lambda x: x.factorial().log(), [5, 10, 20]) # rel tol 1e-6
235
+ [(5, 0.000564287?), (10, 0.0005870?), (20, 0.0006?)]
236
+ sage: asymptotic_expansions.log_Stirling('n')
237
+ n*log(n) - n + 1/2*log(n) + 1/2*log(2*pi) + 1/12*n^(-1)
238
+ - 1/360*n^(-3) + 1/1260*n^(-5) - 1/1680*n^(-7) + 1/1188*n^(-9)
239
+ - 691/360360*n^(-11) + 1/156*n^(-13) - 3617/122400*n^(-15)
240
+ + 43867/244188*n^(-17) - 174611/125400*n^(-19) + 77683/5796*n^(-21)
241
+ - 236364091/1506960*n^(-23) + 657931/300*n^(-25)
242
+ - 3392780147/93960*n^(-27) + 1723168255201/2492028*n^(-29)
243
+ - 7709321041217/505920*n^(-31) + O(n^(-33))
244
+ sage: _.parent()
245
+ Asymptotic Ring <n^ZZ * log(n)^ZZ> over Symbolic Constants Subring
246
+
247
+ ::
248
+
249
+ sage: asymptotic_expansions.log_Stirling(
250
+ ....: 'n', precision=7, skip_constant_summand=True)
251
+ n*log(n) - n + 1/2*log(n) + 1/12*n^(-1) - 1/360*n^(-3) +
252
+ 1/1260*n^(-5) + O(n^(-7))
253
+ sage: _.parent()
254
+ Asymptotic Ring <n^ZZ * log(n)^ZZ> over Rational Field
255
+ sage: asymptotic_expansions.log_Stirling(
256
+ ....: 'n', precision=0)
257
+ O(n*log(n))
258
+ sage: asymptotic_expansions.log_Stirling(
259
+ ....: 'n', precision=1)
260
+ n*log(n) + O(n)
261
+ sage: asymptotic_expansions.log_Stirling(
262
+ ....: 'n', precision=2)
263
+ n*log(n) - n + O(log(n))
264
+ sage: asymptotic_expansions.log_Stirling(
265
+ ....: 'n', precision=3)
266
+ n*log(n) - n + 1/2*log(n) + O(1)
267
+ sage: asymptotic_expansions.log_Stirling(
268
+ ....: 'n', precision=4)
269
+ n*log(n) - n + 1/2*log(n) + 1/2*log(2*pi) + O(n^(-1))
270
+ sage: asymptotic_expansions.log_Stirling(
271
+ ....: 'n', precision=5)
272
+ n*log(n) - n + 1/2*log(n) + 1/2*log(2*pi) + 1/12*n^(-1)
273
+ + O(n^(-3))
274
+ sage: asymptotic_expansions.log_Stirling(
275
+ ....: 'm', precision=7, skip_constant_summand=True)
276
+ m*log(m) - m + 1/2*log(m) + 1/12*m^(-1) - 1/360*m^(-3) +
277
+ 1/1260*m^(-5) + O(m^(-7))
278
+ """
279
+ if not skip_constant_summand:
280
+ from sage.symbolic.ring import SR
281
+ coefficient_ring = SR.subring(no_variables=True)
282
+ else:
283
+ from sage.rings.rational_field import QQ
284
+ coefficient_ring = QQ
285
+
286
+ from .asymptotic_ring import AsymptoticRing
287
+ A = AsymptoticRing(growth_group='{n}^ZZ * log({n})^ZZ'.format(n=var),
288
+ coefficient_ring=coefficient_ring)
289
+ n = A.gen()
290
+
291
+ if precision is None:
292
+ precision = series_precision()
293
+
294
+ log = A.locals()['log']
295
+ result = A.zero()
296
+ if precision >= 1:
297
+ result += n * log(n)
298
+ if precision >= 2:
299
+ result += -n
300
+ if precision >= 3:
301
+ result += log(n) / 2
302
+ if precision >= 4 and not skip_constant_summand:
303
+ result += log(2*coefficient_ring('pi')) / 2
304
+
305
+ result += AsymptoticExpansionGenerators._log_StirlingNegativePowers_(
306
+ var, precision - 4)
307
+
308
+ if precision < 1:
309
+ result += (n * log(n)).O()
310
+ elif precision == 1:
311
+ result += n.O()
312
+ elif precision == 2:
313
+ result += log(n).O()
314
+ elif precision == 3:
315
+ result += A(1).O()
316
+
317
+ return result
318
+
319
+ @staticmethod
320
+ def _log_StirlingNegativePowers_(var, precision):
321
+ r"""
322
+ Helper function to calculate the logarithm of Stirling's approximation
323
+ formula from the negative powers of ``var`` on, i.e., it skips the
324
+ summands `n \log n - n + (\log n)/2 + \log(2\pi)/2`.
325
+
326
+ INPUT:
327
+
328
+ - ``var`` -- string for the variable name
329
+
330
+ - ``precision`` -- integer specifying the number of exact summands;
331
+ if this is negative, then the result is `0`
332
+
333
+ OUTPUT: an asymptotic expansion
334
+
335
+ TESTS::
336
+
337
+ sage: asymptotic_expansions._log_StirlingNegativePowers_(
338
+ ....: 'm', precision=-1)
339
+ 0
340
+ sage: asymptotic_expansions._log_StirlingNegativePowers_(
341
+ ....: 'm', precision=0)
342
+ O(m^(-1))
343
+ sage: asymptotic_expansions._log_StirlingNegativePowers_(
344
+ ....: 'm', precision=3)
345
+ 1/12*m^(-1) - 1/360*m^(-3) + 1/1260*m^(-5) + O(m^(-7))
346
+ sage: _.parent()
347
+ Asymptotic Ring <m^ZZ> over Rational Field
348
+ """
349
+ from .asymptotic_ring import AsymptoticRing
350
+ from sage.rings.rational_field import QQ
351
+
352
+ A = AsymptoticRing(growth_group='{n}^ZZ'.format(n=var),
353
+ coefficient_ring=QQ)
354
+ if precision < 0:
355
+ return A.zero()
356
+ n = A.gen()
357
+
358
+ from sage.arith.misc import bernoulli
359
+ from sage.arith.srange import srange
360
+
361
+ result = sum((bernoulli(k) / k / (k-1) / n**(k-1)
362
+ for k in srange(2, 2*precision + 2, 2)),
363
+ A.zero())
364
+ return result + (1 / n**(2*precision + 1)).O()
365
+
366
+ @staticmethod
367
+ def HarmonicNumber(var, precision=None, skip_constant_summand=False):
368
+ r"""
369
+ Return the asymptotic expansion of a harmonic number.
370
+
371
+ INPUT:
372
+
373
+ - ``var`` -- string for the variable name
374
+
375
+ - ``precision`` -- (default: ``None``) integer. If ``None``, then
376
+ the default precision of the asymptotic ring is used.
377
+
378
+ - ``skip_constant_summand`` -- boolean (default: ``False``); if set,
379
+ then the constant summand ``euler_gamma`` is left out.
380
+ As a consequence, the coefficient ring of the output changes
381
+ from ``Symbolic Constants Subring`` (if ``False``) to
382
+ ``Rational Field`` (if ``True``).
383
+
384
+ OUTPUT: an asymptotic expansion
385
+
386
+ EXAMPLES::
387
+
388
+ sage: asymptotic_expansions.HarmonicNumber('n', precision=5)
389
+ log(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4) + O(n^(-6))
390
+
391
+ TESTS::
392
+
393
+ sage: ex = asymptotic_expansions.HarmonicNumber('n', precision=5)
394
+ sage: n = ex.parent().gen()
395
+ sage: ex.compare_with_values(n, # rel tol 1e-6
396
+ ....: lambda x: sum(1/k for k in srange(1, x+1)), [5, 10, 20])
397
+ [(5, 0.0038125360?), (10, 0.00392733?), (20, 0.0039579?)]
398
+ sage: asymptotic_expansions.HarmonicNumber('n')
399
+ log(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4)
400
+ - 1/252*n^(-6) + 1/240*n^(-8) - 1/132*n^(-10)
401
+ + 691/32760*n^(-12) - 1/12*n^(-14) + 3617/8160*n^(-16)
402
+ - 43867/14364*n^(-18) + 174611/6600*n^(-20) - 77683/276*n^(-22)
403
+ + 236364091/65520*n^(-24) - 657931/12*n^(-26)
404
+ + 3392780147/3480*n^(-28) - 1723168255201/85932*n^(-30)
405
+ + 7709321041217/16320*n^(-32)
406
+ - 151628697551/12*n^(-34) + O(n^(-36))
407
+ sage: _.parent()
408
+ Asymptotic Ring <n^ZZ * log(n)^ZZ> over Symbolic Constants Subring
409
+
410
+ ::
411
+
412
+ sage: asymptotic_expansions.HarmonicNumber(
413
+ ....: 'n', precision=5, skip_constant_summand=True)
414
+ log(n) + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4) + O(n^(-6))
415
+ sage: _.parent()
416
+ Asymptotic Ring <n^ZZ * log(n)^ZZ> over Rational Field
417
+ sage: for p in range(5):
418
+ ....: print(asymptotic_expansions.HarmonicNumber(
419
+ ....: 'n', precision=p))
420
+ O(log(n))
421
+ log(n) + O(1)
422
+ log(n) + euler_gamma + O(n^(-1))
423
+ log(n) + euler_gamma + 1/2*n^(-1) + O(n^(-2))
424
+ log(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + O(n^(-4))
425
+ sage: asymptotic_expansions.HarmonicNumber('m', precision=5)
426
+ log(m) + euler_gamma + 1/2*m^(-1) - 1/12*m^(-2) + 1/120*m^(-4) + O(m^(-6))
427
+ """
428
+ if not skip_constant_summand:
429
+ from sage.symbolic.ring import SR
430
+ coefficient_ring = SR.subring(no_variables=True)
431
+ else:
432
+ from sage.rings.rational_field import QQ
433
+ coefficient_ring = QQ
434
+
435
+ from .asymptotic_ring import AsymptoticRing
436
+ A = AsymptoticRing(growth_group='{n}^ZZ * log({n})^ZZ'.format(n=var),
437
+ coefficient_ring=coefficient_ring)
438
+ n = A.gen()
439
+
440
+ if precision is None:
441
+ precision = series_precision()
442
+
443
+ log = A.locals()['log']
444
+ result = A.zero()
445
+ if precision >= 1:
446
+ result += log(n)
447
+ if precision >= 2 and not skip_constant_summand:
448
+ from sage.symbolic.constants import euler_gamma
449
+ result += coefficient_ring(euler_gamma)
450
+ if precision >= 3:
451
+ result += 1 / (2 * n)
452
+
453
+ from sage.arith.srange import srange
454
+ from sage.arith.misc import bernoulli
455
+ for k in srange(2, 2*precision - 4, 2):
456
+ result += -bernoulli(k) / k / n**k
457
+
458
+ if precision < 1:
459
+ result += (log(n)).O()
460
+ elif precision == 1:
461
+ result += A(1).O()
462
+ elif precision == 2:
463
+ result += (1 / n).O()
464
+ else:
465
+ result += (1 / n**(2*precision - 4)).O()
466
+
467
+ return result
468
+
469
+ @staticmethod
470
+ def Binomial_kn_over_n(var, k, precision=None, skip_constant_factor=False):
471
+ r"""
472
+ Return the asymptotic expansion of the binomial coefficient
473
+ `kn` choose `n`.
474
+
475
+ INPUT:
476
+
477
+ - ``var`` -- string for the variable name
478
+
479
+ - ``k`` -- a number or symbolic constant
480
+
481
+ - ``precision`` -- (default: ``None``) integer. If ``None``, then
482
+ the default precision of the asymptotic ring is used.
483
+
484
+ - ``skip_constant_factor`` -- boolean (default: ``False``); if set,
485
+ then the constant factor `\sqrt{k/(2\pi(k-1))}` is left out.
486
+ As a consequence, the coefficient ring of the output changes
487
+ from ``Symbolic Constants Subring`` (if ``False``) to
488
+ ``Rational Field`` (if ``True``).
489
+
490
+ OUTPUT: an asymptotic expansion
491
+
492
+ EXAMPLES::
493
+
494
+ sage: asymptotic_expansions.Binomial_kn_over_n('n', k=2, precision=3)
495
+ 1/sqrt(pi)*4^n*n^(-1/2)
496
+ - 1/8/sqrt(pi)*4^n*n^(-3/2)
497
+ + 1/128/sqrt(pi)*4^n*n^(-5/2)
498
+ + O(4^n*n^(-7/2))
499
+ sage: _.parent()
500
+ Asymptotic Ring <QQ^n * n^QQ> over Symbolic Constants Subring
501
+
502
+ ::
503
+
504
+ sage: asymptotic_expansions.Binomial_kn_over_n('n', k=3, precision=3)
505
+ 1/2*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-1/2)
506
+ - 7/144*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-3/2)
507
+ + 49/20736*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-5/2)
508
+ + O((27/4)^n*n^(-7/2))
509
+
510
+ ::
511
+
512
+ sage: asymptotic_expansions.Binomial_kn_over_n('n', k=7/5, precision=3)
513
+ 1/2*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-1/2)
514
+ - 13/112*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-3/2)
515
+ + 169/12544*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-5/2)
516
+ + O((7/10*7^(2/5)*2^(3/5))^n*n^(-7/2))
517
+ sage: _.parent()
518
+ Asymptotic Ring <(Symbolic Constants Subring)^n * n^QQ>
519
+ over Symbolic Constants Subring
520
+
521
+ TESTS::
522
+
523
+ sage: expansion = asymptotic_expansions.Binomial_kn_over_n('n', k=7/5, precision=3)
524
+ sage: n = expansion.parent().gen()
525
+ sage: expansion.compare_with_values(n, lambda x: binomial(7/5*x, x), [5, 10, 20]) # rel tol 1e-6
526
+ [(5, -0.0287383845047?), (10, -0.030845971026?), (20, -0.03162833549?)]
527
+ sage: asymptotic_expansions.Binomial_kn_over_n(
528
+ ....: 'n', k=5, precision=3, skip_constant_factor=True)
529
+ (3125/256)^n*n^(-1/2)
530
+ - 7/80*(3125/256)^n*n^(-3/2)
531
+ + 49/12800*(3125/256)^n*n^(-5/2)
532
+ + O((3125/256)^n*n^(-7/2))
533
+ sage: _.parent()
534
+ Asymptotic Ring <QQ^n * n^QQ> over Rational Field
535
+ sage: asymptotic_expansions.Binomial_kn_over_n(
536
+ ....: 'n', k=4, precision=1, skip_constant_factor=True)
537
+ (256/27)^n*n^(-1/2) + O((256/27)^n*n^(-3/2))
538
+
539
+ ::
540
+
541
+ sage: S = asymptotic_expansions.Stirling('n', precision=5)
542
+ sage: n = S.parent().gen()
543
+ sage: all( # long time
544
+ ....: SR(asymptotic_expansions.Binomial_kn_over_n(
545
+ ....: 'n', k=k, precision=3)).canonicalize_radical() ==
546
+ ....: SR(S.subs(n=k*n) / (S.subs(n=(k-1)*n) * S)).canonicalize_radical()
547
+ ....: for k in [2, 3, 4])
548
+ True
549
+
550
+ Check that :issue:`20066` is resolved::
551
+
552
+ sage: set_series_precision(3)
553
+ sage: asymptotic_expansions.Binomial_kn_over_n('n', k=2)
554
+ 1/sqrt(pi)*4^n*n^(-1/2) - 1/8/sqrt(pi)*4^n*n^(-3/2) + ... + O(4^n*n^(-7/2))
555
+ sage: set_series_precision(20) # restore series precision default
556
+ """
557
+ from sage.symbolic.ring import SR
558
+ SCR = SR.subring(no_variables=True)
559
+ try:
560
+ SCR.coerce(k)
561
+ except TypeError as e:
562
+ from .misc import combine_exceptions
563
+ raise combine_exceptions(
564
+ TypeError('Cannot use k={}.'.format(k)), e)
565
+
566
+ if precision is None:
567
+ precision = series_precision()
568
+
569
+ S = AsymptoticExpansionGenerators._log_StirlingNegativePowers_(
570
+ var, precision=max(precision - 2,0))
571
+ n = S.parent().gen()
572
+ result = (S.subs(n=k*n) - S.subs(n=(k-1)*n) - S).exp()
573
+
574
+ from sage.rings.rational_field import QQ
575
+
576
+ P = S.parent().change_parameter(
577
+ growth_group='(QQ_+)^{n} * {n}^QQ'.format(n=var),
578
+ coefficient_ring=QQ)
579
+ n = P.gen()
580
+
581
+ b = k**k / (k-1)**(k-1)
582
+ if b.parent() is SR:
583
+ b = SCR(b).canonicalize_radical()
584
+ result *= n.rpow(b)
585
+ result *= n**(-QQ((1, 2)))
586
+ if not skip_constant_factor:
587
+ result *= (k/((k-1)*2*SCR('pi'))).sqrt()
588
+
589
+ return result
590
+
591
+ @staticmethod
592
+ def SingularityAnalysis(var, zeta=1, alpha=0, beta=0, delta=0,
593
+ precision=None, normalized=True):
594
+ r"""
595
+ Return the asymptotic expansion of the coefficients of
596
+ a power series with specified pole and logarithmic singularity.
597
+
598
+ More precisely, this extracts the `n`-th coefficient
599
+
600
+ .. MATH::
601
+
602
+ [z^n] \left(\frac{1}{1-z/\zeta}\right)^\alpha
603
+ \left(\frac{1}{z/\zeta} \log \frac{1}{1-z/\zeta}\right)^\beta
604
+ \left(\frac{1}{z/\zeta} \log
605
+ \left(\frac{1}{z/\zeta} \log \frac{1}{1-z/\zeta}\right)\right)^\delta
606
+
607
+ (if ``normalized=True``, the default) or
608
+
609
+ .. MATH::
610
+
611
+ [z^n] \left(\frac{1}{1-z/\zeta}\right)^\alpha
612
+ \left(\log \frac{1}{1-z/\zeta}\right)^\beta
613
+ \left(\log
614
+ \left(\frac{1}{z/\zeta} \log \frac{1}{1-z/\zeta}\right)\right)^\delta
615
+
616
+ (if ``normalized=False``).
617
+
618
+ INPUT:
619
+
620
+ - ``var`` -- string for the variable name
621
+
622
+ - ``zeta`` -- (default: `1`) the location of the singularity
623
+
624
+ - ``alpha`` -- (default: `0`) the pole order of the singularity
625
+
626
+ - ``beta`` -- (default: `0`) the order of the logarithmic singularity
627
+
628
+ - ``delta`` -- (default: `0`) the order of the log-log singularity;
629
+ not yet implemented for ``delta != 0``
630
+
631
+ - ``precision`` -- (default: ``None``) integer. If ``None``, then
632
+ the default precision of the asymptotic ring is used.
633
+
634
+ - ``normalized`` -- boolean (default: ``True``); see above
635
+
636
+ OUTPUT: an asymptotic expansion
637
+
638
+ EXAMPLES::
639
+
640
+ sage: asymptotic_expansions.SingularityAnalysis('n', alpha=1)
641
+ 1
642
+ sage: asymptotic_expansions.SingularityAnalysis('n', alpha=2)
643
+ n + 1
644
+ sage: asymptotic_expansions.SingularityAnalysis('n', alpha=3)
645
+ 1/2*n^2 + 3/2*n + 1
646
+ sage: _.parent()
647
+ Asymptotic Ring <n^ZZ> over Rational Field
648
+
649
+ ::
650
+
651
+ sage: asymptotic_expansions.SingularityAnalysis('n', alpha=-3/2,
652
+ ....: precision=3)
653
+ 3/4/sqrt(pi)*n^(-5/2)
654
+ + 45/32/sqrt(pi)*n^(-7/2)
655
+ + 1155/512/sqrt(pi)*n^(-9/2)
656
+ + O(n^(-11/2))
657
+ sage: asymptotic_expansions.SingularityAnalysis('n', alpha=-1/2,
658
+ ....: precision=3)
659
+ -1/2/sqrt(pi)*n^(-3/2)
660
+ - 3/16/sqrt(pi)*n^(-5/2)
661
+ - 25/256/sqrt(pi)*n^(-7/2)
662
+ + O(n^(-9/2))
663
+ sage: asymptotic_expansions.SingularityAnalysis('n', alpha=1/2,
664
+ ....: precision=4)
665
+ 1/sqrt(pi)*n^(-1/2)
666
+ - 1/8/sqrt(pi)*n^(-3/2)
667
+ + 1/128/sqrt(pi)*n^(-5/2)
668
+ + 5/1024/sqrt(pi)*n^(-7/2)
669
+ + O(n^(-9/2))
670
+ sage: _.parent()
671
+ Asymptotic Ring <n^QQ> over Symbolic Constants Subring
672
+
673
+ ::
674
+
675
+ sage: S = SR.subring(rejecting_variables=('n',))
676
+ sage: asymptotic_expansions.SingularityAnalysis(
677
+ ....: 'n', alpha=S.var('a'),
678
+ ....: precision=4).map_coefficients(lambda c: c.factor())
679
+ 1/gamma(a)*n^(a - 1)
680
+ + (1/2*(a - 1)*a/gamma(a))*n^(a - 2)
681
+ + (1/24*(3*a - 1)*(a - 1)*(a - 2)*a/gamma(a))*n^(a - 3)
682
+ + (1/48*(a - 1)^2*(a - 2)*(a - 3)*a^2/gamma(a))*n^(a - 4)
683
+ + O(n^(a - 5))
684
+ sage: _.parent()
685
+ Asymptotic Ring <n^(Symbolic Subring rejecting the variable n)>
686
+ over Symbolic Subring rejecting the variable n
687
+
688
+ ::
689
+
690
+ sage: ae = asymptotic_expansions.SingularityAnalysis('n',
691
+ ....: alpha=1/2, beta=1, precision=4); ae
692
+ 1/sqrt(pi)*n^(-1/2)*log(n) + ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2)
693
+ - 5/8/sqrt(pi)*n^(-3/2)*log(n) + (1/8*(3*euler_gamma + 6*log(2) - 8)/sqrt(pi)
694
+ - (euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n))
695
+ sage: n = ae.parent().gen()
696
+ sage: ae.subs(n=n-1).map_coefficients(lambda x: x.canonicalize_radical())
697
+ 1/sqrt(pi)*n^(-1/2)*log(n)
698
+ + ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2)
699
+ - 1/8/sqrt(pi)*n^(-3/2)*log(n)
700
+ + (-1/8*(euler_gamma + 2*log(2))/sqrt(pi))*n^(-3/2)
701
+ + O(n^(-5/2)*log(n))
702
+
703
+ ::
704
+
705
+ sage: asymptotic_expansions.SingularityAnalysis('n',
706
+ ....: alpha=1, beta=1/2, precision=4)
707
+ log(n)^(1/2) + 1/2*euler_gamma*log(n)^(-1/2)
708
+ + (-1/8*euler_gamma^2 + 1/48*pi^2)*log(n)^(-3/2)
709
+ + (1/16*euler_gamma^3 - 1/32*euler_gamma*pi^2 + 1/8*zeta(3))*log(n)^(-5/2)
710
+ + O(log(n)^(-7/2))
711
+
712
+ ::
713
+
714
+ sage: ae = asymptotic_expansions.SingularityAnalysis('n',
715
+ ....: alpha=0, beta=2, precision=14)
716
+ sage: n = ae.parent().gen()
717
+ sage: ae.subs(n=n-2)
718
+ 2*n^(-1)*log(n) + 2*euler_gamma*n^(-1) - n^(-2) - 1/6*n^(-3) + O(n^(-5))
719
+
720
+ ::
721
+
722
+ sage: asymptotic_expansions.SingularityAnalysis(
723
+ ....: 'n', 1, alpha=-1/2, beta=1, precision=2, normalized=False)
724
+ -1/2/sqrt(pi)*n^(-3/2)*log(n)
725
+ + (-1/2*(euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2)
726
+ + O(n^(-5/2)*log(n))
727
+ sage: asymptotic_expansions.SingularityAnalysis(
728
+ ....: 'n', 1/2, alpha=0, beta=1, precision=3, normalized=False)
729
+ 2^n*n^(-1) + O(2^n*n^(-2))
730
+
731
+
732
+ ALGORITHM:
733
+
734
+ See [FS2009]_.
735
+
736
+
737
+ TESTS::
738
+
739
+ sage: ex = asymptotic_expansions.SingularityAnalysis('n', alpha=-1/2,
740
+ ....: precision=4)
741
+ sage: n = ex.parent().gen()
742
+ sage: coefficients = ((1-x)^(1/2)).series(
743
+ ....: x, 21).truncate().coefficients(x, sparse=False)
744
+ sage: ex.compare_with_values(n, # rel tol 1e-6
745
+ ....: lambda k: coefficients[k], [5, 10, 20])
746
+ [(5, 0.015778873294?), (10, 0.01498952777?), (20, 0.0146264622?)]
747
+ sage: asymptotic_expansions.SingularityAnalysis(
748
+ ....: 'n', alpha=3, precision=2)
749
+ 1/2*n^2 + 3/2*n + O(1)
750
+ sage: asymptotic_expansions.SingularityAnalysis(
751
+ ....: 'n', alpha=3, precision=3)
752
+ 1/2*n^2 + 3/2*n + 1
753
+ sage: asymptotic_expansions.SingularityAnalysis(
754
+ ....: 'n', alpha=3, precision=4)
755
+ 1/2*n^2 + 3/2*n + 1
756
+
757
+ ::
758
+
759
+ sage: asymptotic_expansions.SingularityAnalysis(
760
+ ....: 'n', alpha=0)
761
+ Traceback (most recent call last):
762
+ ...
763
+ NotImplementedOZero: got O(0)
764
+ The error term O(0) means 0 for sufficiently large n.
765
+ sage: asymptotic_expansions.SingularityAnalysis(
766
+ ....: 'n', alpha=-1)
767
+ Traceback (most recent call last):
768
+ ...
769
+ NotImplementedOZero: got O(0)
770
+ The error term O(0) means 0 for sufficiently large n.
771
+
772
+ ::
773
+
774
+ sage: asymptotic_expansions.SingularityAnalysis(
775
+ ....: 'm', alpha=-1/2, precision=3)
776
+ -1/2/sqrt(pi)*m^(-3/2)
777
+ - 3/16/sqrt(pi)*m^(-5/2)
778
+ - 25/256/sqrt(pi)*m^(-7/2)
779
+ + O(m^(-9/2))
780
+ sage: _.parent()
781
+ Asymptotic Ring <m^QQ> over Symbolic Constants Subring
782
+
783
+ Location of the singularity::
784
+
785
+ sage: asymptotic_expansions.SingularityAnalysis(
786
+ ....: 'n', alpha=1, zeta=2, precision=3)
787
+ (1/2)^n
788
+ sage: asymptotic_expansions.SingularityAnalysis(
789
+ ....: 'n', alpha=1, zeta=1/2, precision=3)
790
+ 2^n
791
+ sage: asymptotic_expansions.SingularityAnalysis(
792
+ ....: 'n', alpha=1, zeta=CyclotomicField(3).gen(),
793
+ ....: precision=3)
794
+ (e^(I*arg(-zeta3 - 1)))^n
795
+ sage: asymptotic_expansions.SingularityAnalysis(
796
+ ....: 'n', alpha=4, zeta=2, precision=3)
797
+ 1/6*(1/2)^n*n^3 + (1/2)^n*n^2 + 11/6*(1/2)^n*n + O((1/2)^n)
798
+ sage: asymptotic_expansions.SingularityAnalysis(
799
+ ....: 'n', alpha=-1, zeta=2, precision=3)
800
+ Traceback (most recent call last):
801
+ ...
802
+ NotImplementedOZero: got O(0)
803
+ The error term O(0) means 0 for sufficiently large n.
804
+ sage: asymptotic_expansions.SingularityAnalysis(
805
+ ....: 'n', alpha=1/2, zeta=2, precision=3)
806
+ 1/sqrt(pi)*(1/2)^n*n^(-1/2) - 1/8/sqrt(pi)*(1/2)^n*n^(-3/2)
807
+ + 1/128/sqrt(pi)*(1/2)^n*n^(-5/2) + O((1/2)^n*n^(-7/2))
808
+
809
+ The following tests correspond to Table VI.5 in [FS2009]_. ::
810
+
811
+ sage: A.<n> = AsymptoticRing('n^QQ * log(n)^QQ', QQ)
812
+ sage: asymptotic_expansions.SingularityAnalysis(
813
+ ....: 'n', 1, alpha=-1/2, beta=1, precision=2,
814
+ ....: normalized=False) * (- sqrt(pi*n^3))
815
+ 1/2*log(n) + 1/2*euler_gamma + log(2) - 1 + O(n^(-1)*log(n))
816
+ sage: asymptotic_expansions.SingularityAnalysis(
817
+ ....: 'n', 1, alpha=0, beta=1, precision=3,
818
+ ....: normalized=False)
819
+ n^(-1) + O(n^(-2))
820
+ sage: asymptotic_expansions.SingularityAnalysis(
821
+ ....: 'n', 1, alpha=0, beta=2, precision=14,
822
+ ....: normalized=False) * n
823
+ 2*log(n) + 2*euler_gamma - n^(-1) - 1/6*n^(-2) + O(n^(-4))
824
+ sage: (asymptotic_expansions.SingularityAnalysis(
825
+ ....: 'n', 1, alpha=1/2, beta=1, precision=4,
826
+ ....: normalized=False) * sqrt(pi*n)).\
827
+ ....: map_coefficients(lambda x: x.expand())
828
+ log(n) + euler_gamma + 2*log(2) - 1/8*n^(-1)*log(n) +
829
+ (-1/8*euler_gamma - 1/4*log(2))*n^(-1) + O(n^(-2)*log(n))
830
+ sage: asymptotic_expansions.SingularityAnalysis(
831
+ ....: 'n', 1, alpha=1, beta=1, precision=13,
832
+ ....: normalized=False)
833
+ log(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4)
834
+ + O(n^(-6))
835
+ sage: asymptotic_expansions.SingularityAnalysis(
836
+ ....: 'n', 1, alpha=1, beta=2, precision=4,
837
+ ....: normalized=False)
838
+ log(n)^2 + 2*euler_gamma*log(n) + euler_gamma^2 - 1/6*pi^2
839
+ + O(n^(-1)*log(n))
840
+ sage: asymptotic_expansions.SingularityAnalysis(
841
+ ....: 'n', 1, alpha=3/2, beta=1, precision=3,
842
+ ....: normalized=False) * sqrt(pi/n)
843
+ 2*log(n) + 2*euler_gamma + 4*log(2) - 4 + 3/4*n^(-1)*log(n)
844
+ + O(n^(-1))
845
+ sage: asymptotic_expansions.SingularityAnalysis(
846
+ ....: 'n', 1, alpha=2, beta=1, precision=5,
847
+ ....: normalized=False)
848
+ n*log(n) + (euler_gamma - 1)*n + log(n) + euler_gamma + 1/2
849
+ + O(n^(-1))
850
+ sage: asymptotic_expansions.SingularityAnalysis(
851
+ ....: 'n', 1, alpha=2, beta=2, precision=4,
852
+ ....: normalized=False) / n
853
+ log(n)^2 + (2*euler_gamma - 2)*log(n)
854
+ - 2*euler_gamma + euler_gamma^2 - 1/6*pi^2 + 2
855
+ + n^(-1)*log(n)^2 + O(n^(-1)*log(n))
856
+
857
+ Be aware that the last result does *not* coincide with [FS2009]_,
858
+ they do have a different error term.
859
+
860
+ Checking parameters::
861
+
862
+ sage: asymptotic_expansions.SingularityAnalysis(
863
+ ....: 'n', 1, 1, 1/2, precision=0, normalized=False)
864
+ Traceback (most recent call last):
865
+ ...
866
+ ValueError: beta and delta must be integers
867
+ sage: asymptotic_expansions.SingularityAnalysis(
868
+ ....: 'n', 1, 1, 1, 1/2, normalized=False)
869
+ Traceback (most recent call last):
870
+ ...
871
+ ValueError: beta and delta must be integers
872
+
873
+ ::
874
+
875
+ sage: asymptotic_expansions.SingularityAnalysis(
876
+ ....: 'n', alpha=0, beta=0, delta=1, precision=3)
877
+ Traceback (most recent call last):
878
+ ...
879
+ NotImplementedError: not implemented for delta!=0
880
+
881
+ ::
882
+
883
+ sage: from sage.groups.misc_gps.argument_groups import SignGroup
884
+ sage: Signs = SignGroup()
885
+ sage: asymptotic_expansions.SingularityAnalysis(
886
+ ....: 'n', Signs(-1), alpha=2, beta=1, precision=5,
887
+ ....: normalized=False)
888
+ n*log(n)*(-1)^n + (euler_gamma - 1)*n*(-1)^n + log(n)*(-1)^n
889
+ + (euler_gamma + 1/2)*(-1)^n + O(n^(-1)*(-1)^n)
890
+ sage: _.parent()
891
+ Asymptotic Ring <n^ZZ * log(n)^ZZ * Signs^n> over Symbolic Constants Subring
892
+ """
893
+ from itertools import islice, count
894
+ from .asymptotic_ring import AsymptoticRing
895
+ from .growth_group import ExponentialGrowthGroup, \
896
+ MonomialGrowthGroup, GenericNonGrowthGroup
897
+ from sage.arith.misc import falling_factorial
898
+ from sage.categories.cartesian_product import cartesian_product
899
+ from sage.functions.other import binomial
900
+ from sage.functions.gamma import gamma
901
+ from sage.calculus.calculus import limit
902
+ from sage.misc.cachefunc import cached_function
903
+ from sage.arith.srange import srange
904
+ from sage.rings.integer_ring import ZZ
905
+ from sage.symbolic.ring import SR
906
+
907
+ SCR = SR.subring(no_variables=True)
908
+ s = SR.var('s')
909
+ iga = 1/gamma(alpha)
910
+ if iga.parent() is SR:
911
+ try:
912
+ iga = SCR(iga)
913
+ except TypeError:
914
+ pass
915
+
916
+ coefficient_ring = iga.parent()
917
+ if beta != 0:
918
+ coefficient_ring = SCR
919
+
920
+ @cached_function
921
+ def inverse_gamma_derivative(shift, r):
922
+ """
923
+ Return value of `r`-th derivative of 1/Gamma
924
+ at alpha-shift.
925
+ """
926
+ if r == 0:
927
+ result = iga*falling_factorial(alpha-1, shift)
928
+ else:
929
+ result = limit((1/gamma(s)).diff(s, r), s=alpha-shift)
930
+
931
+ try:
932
+ return coefficient_ring(result)
933
+ except TypeError:
934
+ return result
935
+
936
+ if isinstance(alpha, int):
937
+ alpha = ZZ(alpha)
938
+ if isinstance(beta, int):
939
+ beta = ZZ(beta)
940
+ if isinstance(delta, int):
941
+ delta = ZZ(delta)
942
+
943
+ if precision is None:
944
+ precision = series_precision()
945
+
946
+ if not normalized and not (beta in ZZ and delta in ZZ):
947
+ raise ValueError("beta and delta must be integers")
948
+ if delta != 0:
949
+ raise NotImplementedError("not implemented for delta!=0")
950
+
951
+ groups = []
952
+ non_growth_groups = []
953
+ if zeta != 1:
954
+ E = ExponentialGrowthGroup.factory((~zeta).parent(), var,
955
+ return_factors=True)
956
+ for factor in E:
957
+ if isinstance(factor, GenericNonGrowthGroup):
958
+ non_growth_groups.append(factor)
959
+ else:
960
+ groups.append(factor)
961
+ groups.append(MonomialGrowthGroup(alpha.parent(), var))
962
+ if beta != 0:
963
+ groups.append(MonomialGrowthGroup(beta.parent(), 'log({})'.format(var)))
964
+ groups.extend(non_growth_groups)
965
+ group = cartesian_product(groups)
966
+ A = AsymptoticRing(growth_group=group, coefficient_ring=coefficient_ring,
967
+ default_prec=precision)
968
+ n = A.gen()
969
+
970
+ if zeta == 1:
971
+ exponential_factor = 1
972
+ else:
973
+ exponential_factor = A(n.rpow(~zeta))
974
+
975
+ polynomial_factor = A(n**(alpha-1))
976
+
977
+ if beta != 0:
978
+ log_n = n.log()
979
+ logarithmic_factor = log_n**beta
980
+ else:
981
+ # avoid construction of log(n)
982
+ # because it does not exist in growth group.
983
+ log_n = 1
984
+ logarithmic_factor = 1
985
+
986
+ if beta in ZZ and beta >= 0:
987
+ it = ((k, r)
988
+ for k in count()
989
+ for r in srange(beta+1))
990
+ k_max = precision
991
+ else:
992
+ it = ((0, r)
993
+ for r in count())
994
+ k_max = 0
995
+
996
+ it = reversed(list(islice(it, int(precision) + 1)))
997
+ if normalized:
998
+ beta_denominator = beta
999
+ else:
1000
+ beta_denominator = 0
1001
+ L = _sa_coefficients_lambda_(max(1, k_max), beta=beta_denominator)
1002
+ k, r = next(it)
1003
+ result = (n**(-k) * log_n**(-r)).O()
1004
+
1005
+ if alpha in ZZ and beta == 0:
1006
+ if alpha > 0 and alpha <= precision:
1007
+ result = A(0)
1008
+ elif alpha <= 0 and precision > 0:
1009
+ from .misc import NotImplementedOZero
1010
+ raise NotImplementedOZero(A, exact_part=A.zero())
1011
+
1012
+ for k, r in it:
1013
+ result += binomial(beta, r) * \
1014
+ sum(L[(k, ell)] * (-1)**ell *
1015
+ inverse_gamma_derivative(ell, r)
1016
+ for ell in srange(k, 2*k+1)
1017
+ if (k, ell) in L) * \
1018
+ n**(-k) * log_n**(-r)
1019
+
1020
+ result *= exponential_factor * polynomial_factor * logarithmic_factor
1021
+
1022
+ return result
1023
+
1024
+ @staticmethod
1025
+ @experimental(20050)
1026
+ def ImplicitExpansion(var, phi, tau=None, precision=None):
1027
+ r"""
1028
+ Return the singular expansion for a function `y(z)` defined
1029
+ implicitly by `y(z) = z \Phi(y(z))`.
1030
+
1031
+ The function `\Phi` is assumed to be analytic around `0`. Furthermore,
1032
+ `\Phi` is not allowed to be an affine-linear function and we require
1033
+ `\Phi(0) \neq 0`.
1034
+
1035
+ Furthermore, it is assumed that there is a unique positive solution `\tau`
1036
+ of `\Phi(\tau) - \tau\Phi'(\tau) = 0`.
1037
+
1038
+ All details are given in Chapter VI.7 of [FS2009]_.
1039
+
1040
+ INPUT:
1041
+
1042
+ - ``var`` -- string for the variable name
1043
+
1044
+ - ``phi`` -- the function `\Phi`; see the extended description for
1045
+ assumptions on `\Phi`
1046
+
1047
+ - ``tau`` -- (default: ``None``) the fundamental constant described
1048
+ in the extended description. If ``None``, then `\tau` is determined
1049
+ automatically if possible.
1050
+
1051
+ - ``precision`` -- (default: ``None``) integer. If ``None``, then
1052
+ the default precision of the asymptotic ring is used.
1053
+
1054
+ OUTPUT: an asymptotic expansion
1055
+
1056
+
1057
+ .. NOTE::
1058
+
1059
+ In the given case, the radius of convergence of the function of
1060
+ interest is known to be `\rho = \tau/\Phi(\tau)`. Until :issue:`20050`
1061
+ is implemented, the variable in the returned asymptotic expansion
1062
+ represents a singular element of the form `(1 - z/\rho)^{-1}`,
1063
+ for the variable `z\to\rho`.
1064
+
1065
+ EXAMPLES:
1066
+
1067
+ We can, for example, determine the singular expansion of the well-known
1068
+ tree function `T` (which satisfies `T(z) = z \exp(T(z))`)::
1069
+
1070
+ sage: asymptotic_expansions.ImplicitExpansion('Z', phi=exp, precision=8)
1071
+ doctest:warning
1072
+ ...
1073
+ FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation.
1074
+ See https://github.com/sagemath/sage/issues/20050 for details.
1075
+ 1 - sqrt(2)*Z^(-1/2) + 2/3*Z^(-1) - 11/36*sqrt(2)*Z^(-3/2) +
1076
+ 43/135*Z^(-2) - 769/4320*sqrt(2)*Z^(-5/2) + 1768/8505*Z^(-3) + O(Z^(-7/2))
1077
+
1078
+ Another classical example in this context is the generating function `B(z)`
1079
+ enumerating binary trees with respect to the number of inner nodes. The
1080
+ function satisfies `B(z) = z (1 + 2B(z) + B(z)^2)`, which can also be
1081
+ solved explicitly, yielding `B(z) = \frac{1 - \sqrt{1 - 4z}}{2z} - 1`. We
1082
+ compare the expansions from both approaches::
1083
+
1084
+ sage: def B(z):
1085
+ ....: return (1 - sqrt(1 - 4*z))/(2*z) - 1
1086
+ sage: A.<Z> = AsymptoticRing('Z^QQ', QQ, default_prec=3)
1087
+ sage: B((1-1/Z)/4)
1088
+ 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2)
1089
+ - 2*Z^(-5/2) + O(Z^(-3))
1090
+ sage: asymptotic_expansions.ImplicitExpansion(Z, phi=lambda u: 1 + 2*u + u^2, precision=7)
1091
+ 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2)
1092
+ - 2*Z^(-5/2) + O(Z^(-3))
1093
+
1094
+ Neither `\tau` nor `\Phi` have to be known explicitly, they can
1095
+ also be passed symbolically::
1096
+
1097
+ sage: tau = var('tau')
1098
+ sage: phi = function('phi')
1099
+ sage: asymptotic_expansions.ImplicitExpansion('Z', phi=phi, tau=tau, precision=3) # long time
1100
+ tau + (-sqrt(2)*sqrt(-tau*phi(tau)^2/(2*tau*diff(phi(tau), tau)^2
1101
+ - tau*phi(tau)*diff(phi(tau), tau, tau)
1102
+ - 2*phi(tau)*diff(phi(tau), tau))))*Z^(-1/2) + O(Z^(-1))
1103
+
1104
+ Note that we do not check whether a passed `\tau` actually
1105
+ satisfies the requirements. Only the first of the following
1106
+ expansions is correct::
1107
+
1108
+ sage: asymptotic_expansions.ImplicitExpansion('Z',
1109
+ ....: phi=lambda u: 1 + 2*u + u^2, precision=5) # correct expansion
1110
+ 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + O(Z^(-2))
1111
+ sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 1 + 2*u + u^2, tau=2, precision=5)
1112
+ Traceback (most recent call last):
1113
+ ...
1114
+ ZeroDivisionError: symbolic division by zero
1115
+ sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 1 + 2*u + u^2, tau=3, precision=5)
1116
+ 3 - 4*I*sqrt(3)*Z^(-1/2) + 6*I*sqrt(3)*Z^(-3/2) + O(Z^(-2))
1117
+
1118
+ .. SEEALSO::
1119
+
1120
+ :meth:`~AsymptoticExpansionGenerators.ImplicitExpansionPeriodicPart`,
1121
+ :meth:`~AsymptoticExpansionGenerators.InverseFunctionAnalysis`.
1122
+
1123
+ TESTS::
1124
+
1125
+ sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 1 + 42*u, precision=5)
1126
+ Traceback (most recent call last):
1127
+ ...
1128
+ ValueError: the function phi does not satisfy the requirements
1129
+ sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 42*u + u^2, precision=5)
1130
+ Traceback (most recent call last):
1131
+ ...
1132
+ ValueError: the function phi does not satisfy the requirements
1133
+ sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 1 + u^2 + u^42, precision=5)
1134
+ Traceback (most recent call last):
1135
+ ...
1136
+ ValueError: fundamental constant tau could not be determined
1137
+ """
1138
+ from sage.symbolic.ring import SR
1139
+ from sage.rings.rational_field import QQ
1140
+ from sage.rings.integer_ring import ZZ
1141
+ from sage.rings.asymptotic.asymptotic_ring import AsymptoticRing
1142
+ from sage.arith.srange import srange
1143
+ y, u = SR.var('y'), SR.var('u')
1144
+ one_half = QQ((1, 2))
1145
+
1146
+ if phi(QQ.zero()).is_zero() or phi(u) == phi(0) + u*phi(u).diff(u)(u=0):
1147
+ raise ValueError('the function phi does not satisfy the requirements')
1148
+
1149
+ if tau is None:
1150
+ tau = _fundamental_constant_implicit_function_(phi=phi)
1151
+
1152
+ def H(y):
1153
+ return tau/phi(tau) - y/phi(y)
1154
+
1155
+ A = AsymptoticRing(growth_group='{Z}^QQ'.format(Z=var),
1156
+ coefficient_ring=SR,
1157
+ default_prec=precision)
1158
+ if precision is None:
1159
+ precision = ZZ(A.default_prec)
1160
+ Z = A.gen()
1161
+
1162
+ def ansatz(prec=precision):
1163
+ if prec < 1:
1164
+ return A.one().O()
1165
+ if prec == 1:
1166
+ return ((1/Z)**one_half).O()
1167
+ return (-(2*tau/phi(tau)/H(y).diff(y, 2)(y=tau)).sqrt() * (1/Z)**one_half
1168
+ + sum(SR("d{}".format(j)) * (1/Z)**(j * one_half) for j in srange(2, prec))
1169
+ + ((1/Z)**(prec * one_half)).O())
1170
+
1171
+ # we compare coefficients between a "single" Z and the
1172
+ # following expansion, this allows us to compute the constants d_j
1173
+ z = SR.var('z')
1174
+ z_expansion = sum(H(z).diff(z, k)(z=tau)/k.factorial() *
1175
+ ansatz(prec=precision+2-k)**k
1176
+ for k in srange(2, precision)) + ((1/Z)**(precision * one_half)).O()
1177
+
1178
+ solution_dict = dict()
1179
+ for k in srange(2, precision-1):
1180
+ coef = z_expansion.monomial_coefficient((1/Z)**((k+1) * one_half))
1181
+ current_var = SR.var('d{k}'.format(k=k))
1182
+ solution_dict[current_var] = coef.subs(solution_dict).simplify_rational().solve(current_var)[0].rhs()
1183
+
1184
+ return A(tau) + ansatz(prec=precision-1).map_coefficients(lambda term: term.subs(solution_dict).simplify_rational())
1185
+
1186
+ @staticmethod
1187
+ @experimental(20050)
1188
+ def ImplicitExpansionPeriodicPart(var, phi, period, tau=None, precision=None):
1189
+ r"""
1190
+ Return the singular expansion for the periodic part of a function `y(z)`
1191
+ defined implicitly by `y(z) = z \Phi(y(z))`.
1192
+
1193
+ The function `\Phi` is assumed to be analytic around `0`. Furthermore,
1194
+ `\Phi` is not allowed to be an affine-linear function and we require
1195
+ `\Phi(0) \neq 0`. For an integer `p`, `\Phi` is called `p`-periodic
1196
+ if we have `\Psi(u^p) = \Phi(u)` for a power series `\Psi`
1197
+ where `p` is maximal.
1198
+
1199
+ Furthermore, it is assumed that there is a unique positive solution `\tau`
1200
+ of `\Phi(\tau) - \tau\Phi'(\tau) = 0`.
1201
+
1202
+ If `\Phi` is `p`-periodic, then we have `y(z) = z g(z^p)`. This method
1203
+ returns the singular expansion of `g(z)`.
1204
+
1205
+ INPUT:
1206
+
1207
+ - ``var`` -- string for the variable name
1208
+
1209
+ - ``phi`` -- the function `\Phi`; see the extended description for
1210
+ assumptions on `\Phi`
1211
+
1212
+ - ``period`` -- the period of the function `\Phi`; see the
1213
+ extended description for details
1214
+
1215
+ - ``tau`` -- (default: ``None``) the fundamental constant described
1216
+ in the extended description. If ``None``, then `\tau` is determined
1217
+ automatically if possible.
1218
+
1219
+ - ``precision`` -- (default: ``None``) integer. If ``None``, then
1220
+ the default precision of the asymptotic ring is used.
1221
+
1222
+ OUTPUT: an asymptotic expansion
1223
+
1224
+
1225
+ .. NOTE::
1226
+
1227
+ In the given case, the radius of convergence of the function of
1228
+ interest is known to be `\rho = \tau/\Phi(\tau)`. Until :issue:`20050`
1229
+ is implemented, the variable in the returned asymptotic expansion
1230
+ represents a singular element of the form `(1 - z/\rho)^{-1}`,
1231
+ for the variable `z\to\rho`.
1232
+
1233
+ .. SEEALSO::
1234
+
1235
+ :meth:`~AsymptoticExpansionGenerators.ImplicitExpansion`,
1236
+ :meth:`~AsymptoticExpansionGenerators.InverseFunctionAnalysis`.
1237
+
1238
+ EXAMPLES:
1239
+
1240
+ The generating function enumerating binary trees with respect to
1241
+ tree size satisfies `B(z) = z (1 + B(z)^2)`. This function can be
1242
+ written as `B(z) = z g(z^2)`, and as `B(z)` can be determined
1243
+ explicitly we have `g(z) = \frac{1 - \sqrt{1 - 4z}}{2z}`. We
1244
+ compare the corresponding expansions::
1245
+
1246
+ sage: asymptotic_expansions.ImplicitExpansionPeriodicPart('Z', phi=lambda u: 1 + u^2,
1247
+ ....: period=2, precision=7)
1248
+ doctest:warning
1249
+ ...
1250
+ FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation.
1251
+ See https://github.com/sagemath/sage/issues/20050 for details.
1252
+ 2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))
1253
+ sage: def g(z):
1254
+ ....: return (1 - sqrt(1 - 4*z))/(2*z)
1255
+ sage: A.<Z> = AsymptoticRing('Z^QQ', QQ, default_prec=3)
1256
+ sage: g((1 - 1/Z)/4)
1257
+ 2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))
1258
+ """
1259
+ if tau is None:
1260
+ tau = _fundamental_constant_implicit_function_(phi=phi)
1261
+
1262
+ tau_p = tau**period
1263
+ aperiodic_expansion = asymptotic_expansions.ImplicitExpansion(var,
1264
+ phi=lambda u: phi(u**(1/period))**period,
1265
+ tau=tau_p, precision=precision)
1266
+
1267
+ rho = tau / phi(tau)
1268
+ Z = aperiodic_expansion.parent().gen()
1269
+ return 1/rho * (aperiodic_expansion/(1 - 1/Z))**(1/period)
1270
+
1271
+ @staticmethod
1272
+ def InverseFunctionAnalysis(var, phi, tau=None, period=1, precision=None):
1273
+ r"""
1274
+ Return the coefficient growth of a function `y(z)` defined implicitly
1275
+ by `y(z) = z \Phi(y(z))`.
1276
+
1277
+ The function `\Phi` is assumed to be analytic around `0`. Furthermore,
1278
+ `\Phi` is not allowed to be an affine-linear function and we require
1279
+ `\Phi(0) \neq 0`. For an integer `p`, `\Phi` is called `p`-periodic
1280
+ if we have `\Psi(u^p) = \Phi(u)` for a power series `\Psi`
1281
+ where `p` is maximal.
1282
+
1283
+ Furthermore, it is assumed that there is a unique positive solution `\tau`
1284
+ of `\Phi(\tau) - \tau\Phi'(\tau) = 0`.
1285
+
1286
+ INPUT:
1287
+
1288
+ - ``var`` -- string for the variable name
1289
+
1290
+ - ``phi`` -- the function `\Phi`; see the extended description for
1291
+ assumptions on `\Phi`
1292
+
1293
+ - ``tau`` -- (default: ``None``) the fundamental constant described
1294
+ in the extended description. If ``None``, then `\tau` is determined
1295
+ automatically if possible.
1296
+
1297
+ - ``period`` -- (default: `1`) the period of the function `\Phi`. See
1298
+ the extended description for details
1299
+
1300
+ - ``precision`` -- (default: ``None``) integer. If ``None``, then
1301
+ the default precision of the asymptotic ring is used.
1302
+
1303
+ OUTPUT: an asymptotic expansion
1304
+
1305
+
1306
+ .. NOTE::
1307
+
1308
+ It is not checked that the passed period actually fits to
1309
+ the passed function `\Phi`.
1310
+
1311
+ The resulting asymptotic expansion is only valid
1312
+ for `n \equiv 1 \mod p`, where `p` is the period. All other
1313
+ coefficients are `0`.
1314
+
1315
+ EXAMPLES:
1316
+
1317
+ There are `C_n` (the `n`-th Catalan number) different binary trees
1318
+ of size `2n+1`, and there are no binary trees with an even number of
1319
+ nodes. The corresponding generating function satisfies
1320
+ `B(z) = z (1 + B(z)^2)`, which allows us to compare the asymptotic
1321
+ expansions for the number of binary trees of size `n` obtained via
1322
+ `C_n` and obtained via the analysis of `B(z)`::
1323
+
1324
+ sage: assume(SR.an_element() > 0)
1325
+ sage: A.<n> = AsymptoticRing('QQ^n * n^QQ', SR)
1326
+ sage: binomial_expansion = asymptotic_expansions.Binomial_kn_over_n(n, k=2, precision=3)
1327
+ sage: catalan_expansion = binomial_expansion / (n+1)
1328
+ sage: catalan_expansion.subs(n=(n-1)/2)
1329
+ 2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2)
1330
+ + 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2))
1331
+ sage: asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: 1 + u^2, period=2,
1332
+ ....: tau=1, precision=8)
1333
+ 2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2)
1334
+ + 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2))
1335
+
1336
+ The code in the aperiodic case is more efficient, however. Therefore,
1337
+ it is recommended to use combinatorial identities to reduce to the
1338
+ aperiodic case. In the example above, this is well-known: we now count
1339
+ binary trees with `n` internal nodes. The corresponding generating function
1340
+ satisfies `B(z) = z (1 + 2B(z) + B(z)^2)`::
1341
+
1342
+ sage: catalan_expansion
1343
+ 1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2)
1344
+ + 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2))
1345
+ sage: asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: 1 + 2*u + u^2,
1346
+ ....: tau=1, precision=8)
1347
+ 1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2)
1348
+ + 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2))
1349
+
1350
+ sage: forget()
1351
+
1352
+ .. SEEALSO::
1353
+
1354
+ :meth:`~AsymptoticExpansionGenerators.ImplicitExpansion`,
1355
+ :meth:`~AsymptoticExpansionGenerators.ImplicitExpansionPeriodicPart`.
1356
+
1357
+
1358
+ TESTS:
1359
+
1360
+ Omitting the precision parameter does not lead to an error (per default,
1361
+ the default series precision is a python integer, which led to an error
1362
+ in an earlier version of the code)::
1363
+
1364
+ sage: set_series_precision(int(5))
1365
+ sage: asymptotic_expansions.InverseFunctionAnalysis('n', phi=lambda u: 1 + 2*u + u^2,
1366
+ ....: tau=1)
1367
+ 1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2) + O(4^n*n^(-3))
1368
+ """
1369
+ if tau is None:
1370
+ tau = _fundamental_constant_implicit_function_(phi=phi)
1371
+
1372
+ rho = tau / phi(tau)
1373
+
1374
+ if period == 1:
1375
+ expansion = asymptotic_expansions.ImplicitExpansion(var=var, phi=phi,
1376
+ tau=tau, precision=precision)
1377
+ return expansion._singularity_analysis_(var, zeta=rho, precision=precision)
1378
+ expansion = asymptotic_expansions.ImplicitExpansionPeriodicPart(var=var, phi=phi,
1379
+ period=period, tau=tau, precision=precision)
1380
+ growth = expansion._singularity_analysis_(var, zeta=rho**period, precision=precision)
1381
+ n = growth.parent().gen()
1382
+ return growth.subs({n: (n-1)/period})
1383
+
1384
+
1385
+ def _fundamental_constant_implicit_function_(phi):
1386
+ r"""
1387
+ Return the fundamental constant `\tau` occurring in the analysis of
1388
+ implicitly defined functions.
1389
+
1390
+ For a function `y(z)` satisfying `y(z) = z \Phi(y(z))`, the fundamental
1391
+ constant `\tau` is the unique positive solution of the equation
1392
+ `\Phi(\tau) - \tau \Phi'(\tau) = 0`.
1393
+
1394
+ INPUT:
1395
+
1396
+ - ``phi`` -- the function `\Phi`
1397
+
1398
+ .. SEEALSO::
1399
+
1400
+ :meth:`~AsymptoticExpansionGenerators.ImplicitExpansion`,
1401
+ :meth:`~AsymptoticExpansionGenerators.ImplicitExpansionPeriodicPart`.
1402
+
1403
+ TESTS::
1404
+
1405
+ sage: from sage.rings.asymptotic.asymptotic_expansion_generators \
1406
+ ....: import _fundamental_constant_implicit_function_
1407
+ sage: _fundamental_constant_implicit_function_(phi=exp)
1408
+ 1
1409
+ sage: _fundamental_constant_implicit_function_(phi=lambda u: 1 + u^2)
1410
+ 1
1411
+ sage: _fundamental_constant_implicit_function_(phi=lambda u: 1 + 2*u + 2*u^2)
1412
+ 1/2*sqrt(2)
1413
+ """
1414
+ from sage.symbolic.ring import SR
1415
+ u = SR.var('u')
1416
+ positive_solution = [s for s in (phi(u) - u*phi(u).diff(u)).solve(u)
1417
+ if s.rhs() > 0]
1418
+ if len(positive_solution) == 1:
1419
+ return positive_solution[0].rhs()
1420
+ raise ValueError('fundamental constant tau could not be determined')
1421
+
1422
+
1423
+ def _sa_coefficients_lambda_(K, beta=0):
1424
+ r"""
1425
+ Return the coefficients `\lambda_{k, \ell}(\beta)` used in singularity analysis.
1426
+
1427
+ INPUT:
1428
+
1429
+ - ``K`` -- integer
1430
+
1431
+ - ``beta`` -- (default: `0`) the order of the logarithmic singularity
1432
+
1433
+ OUTPUT: a dictionary mapping pairs of indices to rationals
1434
+
1435
+ .. SEEALSO::
1436
+
1437
+ :meth:`~AsymptoticExpansionGenerators.SingularityAnalysis`
1438
+
1439
+ TESTS::
1440
+
1441
+ sage: from sage.rings.asymptotic.asymptotic_expansion_generators \
1442
+ ....: import _sa_coefficients_lambda_
1443
+ sage: _sa_coefficients_lambda_(3)
1444
+ {(0, 0): 1,
1445
+ (1, 1): -1,
1446
+ (1, 2): 1/2,
1447
+ (2, 2): 1,
1448
+ (2, 3): -5/6,
1449
+ (2, 4): 1/8,
1450
+ (3, 3): -1,
1451
+ (3, 4): 13/12,
1452
+ (4, 4): 1}
1453
+ sage: _sa_coefficients_lambda_(3, beta=1)
1454
+ {(0, 0): 1,
1455
+ (1, 1): -2,
1456
+ (1, 2): 1/2,
1457
+ (2, 2): 3,
1458
+ (2, 3): -4/3,
1459
+ (2, 4): 1/8,
1460
+ (3, 3): -4,
1461
+ (3, 4): 29/12,
1462
+ (4, 4): 5}
1463
+ """
1464
+ from sage.rings.laurent_series_ring import LaurentSeriesRing
1465
+ from sage.rings.lazy_series_ring import LazyPowerSeriesRing
1466
+ from sage.rings.rational_field import QQ
1467
+
1468
+ V = LaurentSeriesRing(QQ, names='v', default_prec=K)
1469
+ v = V.gen()
1470
+ t = LazyPowerSeriesRing(V, names='t').gen()
1471
+
1472
+ S = (t - (1 + 1/v + beta) * (1 + v*t).log()).exp()
1473
+ return {(k + L.valuation(), ell): c
1474
+ for ell, L in enumerate(S[:2 * K - 1])
1475
+ for k, c in enumerate(L.list())}
1476
+
1477
+
1478
+ # Easy access to the asymptotic expansions generators from the command line:
1479
+ asymptotic_expansions = AsymptoticExpansionGenerators()
1480
+ r"""
1481
+ A collection of several common asymptotic expansions.
1482
+
1483
+ This is an instance of :class:`AsymptoticExpansionGenerators` whose documentation
1484
+ provides more details.
1485
+ """