passagemath-symbolics 10.6.37__cp310-cp310-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.
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.37.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.37.dist-info/RECORD +171 -0
- passagemath_symbolics-10.6.37.dist-info/WHEEL +5 -0
- passagemath_symbolics-10.6.37.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2826 -0
- sage/calculus/desolvers.py +1866 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/calculus/var.pyx +401 -0
- sage/dynamics/all__sagemath_symbolics.py +6 -0
- sage/dynamics/complex_dynamics/all.py +5 -0
- sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
- sage/ext/all__sagemath_symbolics.py +1 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/magma/latex/latex.m +1021 -0
- sage/ext_data/magma/latex/latex.spec +1 -0
- sage/ext_data/magma/sage/basic.m +356 -0
- sage/ext_data/magma/sage/sage.spec +1 -0
- sage/ext_data/magma/spec +9 -0
- sage/geometry/all__sagemath_symbolics.py +8 -0
- sage/geometry/hyperbolic_space/all.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
- sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
- sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
- sage/geometry/riemannian_manifolds/all.py +7 -0
- sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
- sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
- sage/interfaces/all__sagemath_symbolics.py +1 -0
- sage/interfaces/magma.py +3017 -0
- sage/interfaces/magma_free.py +92 -0
- sage/interfaces/maple.py +1397 -0
- sage/interfaces/mathematica.py +1345 -0
- sage/interfaces/mathics.py +1312 -0
- sage/interfaces/sympy.py +1398 -0
- sage/interfaces/sympy_wrapper.py +197 -0
- sage/interfaces/tides.py +938 -0
- sage/libs/all__sagemath_symbolics.py +6 -0
- sage/manifolds/all.py +7 -0
- sage/manifolds/calculus_method.py +555 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4019 -0
- sage/manifolds/chart_func.py +3419 -0
- sage/manifolds/continuous_map.py +2183 -0
- sage/manifolds/continuous_map_image.py +155 -0
- sage/manifolds/differentiable/affine_connection.py +2475 -0
- sage/manifolds/differentiable/all.py +1 -0
- sage/manifolds/differentiable/automorphismfield.py +1383 -0
- sage/manifolds/differentiable/automorphismfield_group.py +604 -0
- sage/manifolds/differentiable/bundle_connection.py +1445 -0
- sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
- sage/manifolds/differentiable/chart.py +1241 -0
- sage/manifolds/differentiable/curve.py +1028 -0
- sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
- sage/manifolds/differentiable/degenerate.py +559 -0
- sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
- sage/manifolds/differentiable/diff_form.py +1658 -0
- sage/manifolds/differentiable/diff_form_module.py +1062 -0
- sage/manifolds/differentiable/diff_map.py +1315 -0
- sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
- sage/manifolds/differentiable/examples/all.py +1 -0
- sage/manifolds/differentiable/examples/euclidean.py +2517 -0
- sage/manifolds/differentiable/examples/real_line.py +897 -0
- sage/manifolds/differentiable/examples/sphere.py +1186 -0
- sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
- sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
- sage/manifolds/differentiable/integrated_curve.py +4035 -0
- sage/manifolds/differentiable/levi_civita_connection.py +841 -0
- sage/manifolds/differentiable/manifold.py +4254 -0
- sage/manifolds/differentiable/manifold_homset.py +1826 -0
- sage/manifolds/differentiable/metric.py +3032 -0
- sage/manifolds/differentiable/mixed_form.py +1507 -0
- sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
- sage/manifolds/differentiable/multivector_module.py +800 -0
- sage/manifolds/differentiable/multivectorfield.py +1520 -0
- sage/manifolds/differentiable/poisson_tensor.py +268 -0
- sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
- sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
- sage/manifolds/differentiable/scalarfield.py +1343 -0
- sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
- sage/manifolds/differentiable/symplectic_form.py +910 -0
- sage/manifolds/differentiable/symplectic_form_test.py +220 -0
- sage/manifolds/differentiable/tangent_space.py +412 -0
- sage/manifolds/differentiable/tangent_vector.py +616 -0
- sage/manifolds/differentiable/tensorfield.py +4665 -0
- sage/manifolds/differentiable/tensorfield_module.py +963 -0
- sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
- sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
- sage/manifolds/differentiable/vector_bundle.py +1728 -0
- sage/manifolds/differentiable/vectorfield.py +1717 -0
- sage/manifolds/differentiable/vectorfield_module.py +2445 -0
- sage/manifolds/differentiable/vectorframe.py +1832 -0
- sage/manifolds/family.py +270 -0
- sage/manifolds/local_frame.py +1490 -0
- sage/manifolds/manifold.py +3090 -0
- sage/manifolds/manifold_homset.py +452 -0
- sage/manifolds/operators.py +359 -0
- sage/manifolds/point.py +994 -0
- sage/manifolds/scalarfield.py +3718 -0
- sage/manifolds/scalarfield_algebra.py +629 -0
- sage/manifolds/section.py +3111 -0
- sage/manifolds/section_module.py +831 -0
- sage/manifolds/structure.py +229 -0
- sage/manifolds/subset.py +2764 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +885 -0
- sage/manifolds/topological_submanifold.py +891 -0
- sage/manifolds/trivialization.py +733 -0
- sage/manifolds/utilities.py +1348 -0
- sage/manifolds/vector_bundle.py +1342 -0
- sage/manifolds/vector_bundle_fiber.py +332 -0
- sage/manifolds/vector_bundle_fiber_element.py +111 -0
- sage/matrix/all__sagemath_symbolics.py +1 -0
- sage/matrix/matrix_symbolic_dense.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1022 -0
- sage/matrix/matrix_symbolic_sparse.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
- sage/modules/all__sagemath_symbolics.py +1 -0
- sage/modules/vector_callable_symbolic_dense.py +105 -0
- sage/modules/vector_symbolic_dense.py +116 -0
- sage/modules/vector_symbolic_sparse.py +118 -0
- sage/rings/all__sagemath_symbolics.py +4 -0
- sage/rings/asymptotic/all.py +6 -0
- sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
- sage/rings/asymptotic/asymptotic_ring.py +4858 -0
- sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5237 -0
- sage/rings/function_field/all__sagemath_symbolics.py +2 -0
- sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
- sage/symbolic/all.py +15 -0
- sage/symbolic/assumptions.py +985 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +459 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1287 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1713 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +270 -0
- sage/symbolic/integration/integral.py +1115 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/random_tests.py +462 -0
- sage/symbolic/relation.py +1907 -0
- sage/symbolic/ring.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyx +1396 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1470 -0
|
@@ -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
|
+
"""
|