Common Asymptotic Expansions¶
Asymptotic expansions in SageMath can be built through the
asymptotic_expansions
object. It contains generators for common
asymptotic expressions. For example,
sage: asymptotic_expansions.Stirling('n', precision=5)
sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +
1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +
1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +
O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))
>>> from sage.all import *
>>> asymptotic_expansions.Stirling('n', precision=Integer(5))
sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +
1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +
1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +
O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))
generates the first 5 summands of Stirling’s approximation formula for factorials.
To construct an asymptotic expression manually, you can use the class
AsymptoticRing
. See
asymptotic ring for more details and a lot of
examples.
Asymptotic Expansions
harmonic numbers |
|
Stirling’s approximation formula for factorials |
|
the logarithm of Stirling’s approximation formula for factorials |
|
an asymptotic expansion of the binomial coefficient |
|
an asymptotic expansion obtained by singularity analysis |
|
the singular expansion of a function \(y(z)\) satisfying \(y(z) = z \Phi(y(z))\) |
|
the singular expansion of the periodic part of a function \(y(z)\) satisfying \(y(z) = z\Phi(y(z))\) |
|
coefficient growth of a function \(y(z)\) defined implicitly by \(y(z) = z \Phi(y(z))\) |
AUTHORS:
Daniel Krenn (2015)
Clemens Heuberger (2016)
Benjamin Hackl (2016)
ACKNOWLEDGEMENT:
Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P 24644-N26.
Classes and Methods¶
- class sage.rings.asymptotic.asymptotic_expansion_generators.AsymptoticExpansionGenerators[source]¶
Bases:
SageObject
A collection of constructors for several common asymptotic expansions.
A list of all asymptotic expansions in this database is available via tab completion. Type “
asymptotic_expansions.
” and then hit tab to see which expansions are available.The asymptotic expansions currently in this class include:
- static Binomial_kn_over_n(var, k, precision=None, skip_constant_factor=False)[source]¶
Return the asymptotic expansion of the binomial coefficient \(kn\) choose \(n\).
INPUT:
var
– string for the variable namek
– a number or symbolic constantprecision
– (default:None
) integer. IfNone
, then the default precision of the asymptotic ring is used.skip_constant_factor
– boolean (default:False
); if set, then the constant factor \(\sqrt{k/(2\pi(k-1))}\) is left out. As a consequence, the coefficient ring of the output changes fromSymbolic Constants Subring
(ifFalse
) toRational Field
(ifTrue
).
OUTPUT: an asymptotic expansion
EXAMPLES:
sage: asymptotic_expansions.Binomial_kn_over_n('n', k=2, precision=3) 1/sqrt(pi)*4^n*n^(-1/2) - 1/8/sqrt(pi)*4^n*n^(-3/2) + 1/128/sqrt(pi)*4^n*n^(-5/2) + O(4^n*n^(-7/2)) sage: _.parent() Asymptotic Ring <QQ^n * n^QQ> over Symbolic Constants Subring
>>> from sage.all import * >>> asymptotic_expansions.Binomial_kn_over_n('n', k=Integer(2), precision=Integer(3)) 1/sqrt(pi)*4^n*n^(-1/2) - 1/8/sqrt(pi)*4^n*n^(-3/2) + 1/128/sqrt(pi)*4^n*n^(-5/2) + O(4^n*n^(-7/2)) >>> _.parent() Asymptotic Ring <QQ^n * n^QQ> over Symbolic Constants Subring
sage: asymptotic_expansions.Binomial_kn_over_n('n', k=3, precision=3) 1/2*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-1/2) - 7/144*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-3/2) + 49/20736*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-5/2) + O((27/4)^n*n^(-7/2))
>>> from sage.all import * >>> asymptotic_expansions.Binomial_kn_over_n('n', k=Integer(3), precision=Integer(3)) 1/2*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-1/2) - 7/144*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-3/2) + 49/20736*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-5/2) + O((27/4)^n*n^(-7/2))
sage: asymptotic_expansions.Binomial_kn_over_n('n', k=7/5, precision=3) 1/2*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-1/2) - 13/112*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-3/2) + 169/12544*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-5/2) + O((7/10*7^(2/5)*2^(3/5))^n*n^(-7/2)) sage: _.parent() Asymptotic Ring <(Symbolic Constants Subring)^n * n^QQ> over Symbolic Constants Subring
>>> from sage.all import * >>> asymptotic_expansions.Binomial_kn_over_n('n', k=Integer(7)/Integer(5), precision=Integer(3)) 1/2*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-1/2) - 13/112*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-3/2) + 169/12544*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-5/2) + O((7/10*7^(2/5)*2^(3/5))^n*n^(-7/2)) >>> _.parent() Asymptotic Ring <(Symbolic Constants Subring)^n * n^QQ> over Symbolic Constants Subring
- static HarmonicNumber(var, precision=None, skip_constant_summand=False)[source]¶
Return the asymptotic expansion of a harmonic number.
INPUT:
var
– string for the variable nameprecision
– (default:None
) integer. IfNone
, then the default precision of the asymptotic ring is used.skip_constant_summand
– boolean (default:False
); if set, then the constant summandeuler_gamma
is left out. As a consequence, the coefficient ring of the output changes fromSymbolic Constants Subring
(ifFalse
) toRational Field
(ifTrue
).
OUTPUT: an asymptotic expansion
EXAMPLES:
sage: asymptotic_expansions.HarmonicNumber('n', precision=5) log(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4) + O(n^(-6))
>>> from sage.all import * >>> asymptotic_expansions.HarmonicNumber('n', precision=Integer(5)) log(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4) + O(n^(-6))
- static ImplicitExpansion(var, phi, tau=None, precision=None)[source]¶
Return the singular expansion for a function \(y(z)\) defined implicitly by \(y(z) = z \Phi(y(z))\).
The function \(\Phi\) is assumed to be analytic around \(0\). Furthermore, \(\Phi\) is not allowed to be an affine-linear function and we require \(\Phi(0) \neq 0\).
Furthermore, it is assumed that there is a unique positive solution \(\tau\) of \(\Phi(\tau) - \tau\Phi'(\tau) = 0\).
All details are given in Chapter VI.7 of [FS2009].
INPUT:
var
– string for the variable namephi
– the function \(\Phi\); see the extended description for assumptions on \(\Phi\)tau
– (default:None
) the fundamental constant described in the extended description. IfNone
, then \(\tau\) is determined automatically if possible.precision
– (default:None
) integer. IfNone
, then the default precision of the asymptotic ring is used.
OUTPUT: an asymptotic expansion
Note
In the given case, the radius of convergence of the function of interest is known to be \(\rho = \tau/\Phi(\tau)\). Until Issue #20050 is implemented, the variable in the returned asymptotic expansion represents a singular element of the form \((1 - z/\rho)^{-1}\), for the variable \(z\to\rho\).
EXAMPLES:
We can, for example, determine the singular expansion of the well-known tree function \(T\) (which satisfies \(T(z) = z \exp(T(z))\)):
sage: asymptotic_expansions.ImplicitExpansion('Z', phi=exp, precision=8) doctest:warning ... FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/20050 for details. 1 - sqrt(2)*Z^(-1/2) + 2/3*Z^(-1) - 11/36*sqrt(2)*Z^(-3/2) + 43/135*Z^(-2) - 769/4320*sqrt(2)*Z^(-5/2) + 1768/8505*Z^(-3) + O(Z^(-7/2))
>>> from sage.all import * >>> asymptotic_expansions.ImplicitExpansion('Z', phi=exp, precision=Integer(8)) doctest:warning ... FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/20050 for details. 1 - sqrt(2)*Z^(-1/2) + 2/3*Z^(-1) - 11/36*sqrt(2)*Z^(-3/2) + 43/135*Z^(-2) - 769/4320*sqrt(2)*Z^(-5/2) + 1768/8505*Z^(-3) + O(Z^(-7/2))
Another classical example in this context is the generating function \(B(z)\) enumerating binary trees with respect to the number of inner nodes. The function satisfies \(B(z) = z (1 + 2B(z) + B(z)^2)\), which can also be solved explicitly, yielding \(B(z) = \frac{1 - \sqrt{1 - 4z}}{2z} - 1\). We compare the expansions from both approaches:
sage: def B(z): ....: return (1 - sqrt(1 - 4*z))/(2*z) - 1 sage: A.<Z> = AsymptoticRing('Z^QQ', QQ, default_prec=3) sage: B((1-1/Z)/4) 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3)) sage: asymptotic_expansions.ImplicitExpansion(Z, phi=lambda u: 1 + 2*u + u^2, precision=7) 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))
>>> from sage.all import * >>> def B(z): ... return (Integer(1) - sqrt(Integer(1) - Integer(4)*z))/(Integer(2)*z) - Integer(1) >>> A = AsymptoticRing('Z^QQ', QQ, default_prec=Integer(3), names=('Z',)); (Z,) = A._first_ngens(1) >>> B((Integer(1)-Integer(1)/Z)/Integer(4)) 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3)) >>> asymptotic_expansions.ImplicitExpansion(Z, phi=lambda u: Integer(1) + Integer(2)*u + u**Integer(2), precision=Integer(7)) 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))
Neither \(\tau\) nor \(\Phi\) have to be known explicitly, they can also be passed symbolically:
sage: tau = var('tau') sage: phi = function('phi') sage: asymptotic_expansions.ImplicitExpansion('Z', phi=phi, tau=tau, precision=3) # long time tau + (-sqrt(2)*sqrt(-tau*phi(tau)^2/(2*tau*diff(phi(tau), tau)^2 - tau*phi(tau)*diff(phi(tau), tau, tau) - 2*phi(tau)*diff(phi(tau), tau))))*Z^(-1/2) + O(Z^(-1))
>>> from sage.all import * >>> tau = var('tau') >>> phi = function('phi') >>> asymptotic_expansions.ImplicitExpansion('Z', phi=phi, tau=tau, precision=Integer(3)) # long time tau + (-sqrt(2)*sqrt(-tau*phi(tau)^2/(2*tau*diff(phi(tau), tau)^2 - tau*phi(tau)*diff(phi(tau), tau, tau) - 2*phi(tau)*diff(phi(tau), tau))))*Z^(-1/2) + O(Z^(-1))
Note that we do not check whether a passed \(\tau\) actually satisfies the requirements. Only the first of the following expansions is correct:
sage: asymptotic_expansions.ImplicitExpansion('Z', ....: phi=lambda u: 1 + 2*u + u^2, precision=5) # correct expansion 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + O(Z^(-2)) sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 1 + 2*u + u^2, tau=2, precision=5) Traceback (most recent call last): ... ZeroDivisionError: symbolic division by zero sage: asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: 1 + 2*u + u^2, tau=3, precision=5) 3 - 4*I*sqrt(3)*Z^(-1/2) + 6*I*sqrt(3)*Z^(-3/2) + O(Z^(-2))
>>> from sage.all import * >>> asymptotic_expansions.ImplicitExpansion('Z', ... phi=lambda u: Integer(1) + Integer(2)*u + u**Integer(2), precision=Integer(5)) # correct expansion 1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + O(Z^(-2)) >>> asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: Integer(1) + Integer(2)*u + u**Integer(2), tau=Integer(2), precision=Integer(5)) Traceback (most recent call last): ... ZeroDivisionError: symbolic division by zero >>> asymptotic_expansions.ImplicitExpansion('Z', phi=lambda u: Integer(1) + Integer(2)*u + u**Integer(2), tau=Integer(3), precision=Integer(5)) 3 - 4*I*sqrt(3)*Z^(-1/2) + 6*I*sqrt(3)*Z^(-3/2) + O(Z^(-2))
- static ImplicitExpansionPeriodicPart(var, phi, period, tau=None, precision=None)[source]¶
Return the singular expansion for the periodic part of a function \(y(z)\) defined implicitly by \(y(z) = z \Phi(y(z))\).
The function \(\Phi\) is assumed to be analytic around \(0\). Furthermore, \(\Phi\) is not allowed to be an affine-linear function and we require \(\Phi(0) \neq 0\). For an integer \(p\), \(\Phi\) is called \(p\)-periodic if we have \(\Psi(u^p) = \Phi(u)\) for a power series \(\Psi\) where \(p\) is maximal.
Furthermore, it is assumed that there is a unique positive solution \(\tau\) of \(\Phi(\tau) - \tau\Phi'(\tau) = 0\).
If \(\Phi\) is \(p\)-periodic, then we have \(y(z) = z g(z^p)\). This method returns the singular expansion of \(g(z)\).
INPUT:
var
– string for the variable namephi
– the function \(\Phi\); see the extended description for assumptions on \(\Phi\)period
– the period of the function \(\Phi\); see the extended description for detailstau
– (default:None
) the fundamental constant described in the extended description. IfNone
, then \(\tau\) is determined automatically if possible.precision
– (default:None
) integer. IfNone
, then the default precision of the asymptotic ring is used.
OUTPUT: an asymptotic expansion
Note
In the given case, the radius of convergence of the function of interest is known to be \(\rho = \tau/\Phi(\tau)\). Until Issue #20050 is implemented, the variable in the returned asymptotic expansion represents a singular element of the form \((1 - z/\rho)^{-1}\), for the variable \(z\to\rho\).
See also
EXAMPLES:
The generating function enumerating binary trees with respect to tree size satisfies \(B(z) = z (1 + B(z)^2)\). This function can be written as \(B(z) = z g(z^2)\), and as \(B(z)\) can be determined explicitly we have \(g(z) = \frac{1 - \sqrt{1 - 4z}}{2z}\). We compare the corresponding expansions:
sage: asymptotic_expansions.ImplicitExpansionPeriodicPart('Z', phi=lambda u: 1 + u^2, ....: period=2, precision=7) doctest:warning ... FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/20050 for details. 2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3)) sage: def g(z): ....: return (1 - sqrt(1 - 4*z))/(2*z) sage: A.<Z> = AsymptoticRing('Z^QQ', QQ, default_prec=3) sage: g((1 - 1/Z)/4) 2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))
>>> from sage.all import * >>> asymptotic_expansions.ImplicitExpansionPeriodicPart('Z', phi=lambda u: Integer(1) + u**Integer(2), ... period=Integer(2), precision=Integer(7)) doctest:warning ... FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/20050 for details. 2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3)) >>> def g(z): ... return (Integer(1) - sqrt(Integer(1) - Integer(4)*z))/(Integer(2)*z) >>> A = AsymptoticRing('Z^QQ', QQ, default_prec=Integer(3), names=('Z',)); (Z,) = A._first_ngens(1) >>> g((Integer(1) - Integer(1)/Z)/Integer(4)) 2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))
- static InverseFunctionAnalysis(var, phi, tau=None, period=1, precision=None)[source]¶
Return the coefficient growth of a function \(y(z)\) defined implicitly by \(y(z) = z \Phi(y(z))\).
The function \(\Phi\) is assumed to be analytic around \(0\). Furthermore, \(\Phi\) is not allowed to be an affine-linear function and we require \(\Phi(0) \neq 0\). For an integer \(p\), \(\Phi\) is called \(p\)-periodic if we have \(\Psi(u^p) = \Phi(u)\) for a power series \(\Psi\) where \(p\) is maximal.
Furthermore, it is assumed that there is a unique positive solution \(\tau\) of \(\Phi(\tau) - \tau\Phi'(\tau) = 0\).
INPUT:
var
– string for the variable namephi
– the function \(\Phi\); see the extended description for assumptions on \(\Phi\)tau
– (default:None
) the fundamental constant described in the extended description. IfNone
, then \(\tau\) is determined automatically if possible.period
– (default: \(1\)) the period of the function \(\Phi\). See the extended description for detailsprecision
– (default:None
) integer. IfNone
, then the default precision of the asymptotic ring is used.
OUTPUT: an asymptotic expansion
Note
It is not checked that the passed period actually fits to the passed function \(\Phi\).
The resulting asymptotic expansion is only valid for \(n \equiv 1 \mod p\), where \(p\) is the period. All other coefficients are \(0\).
EXAMPLES:
There are \(C_n\) (the \(n\)-th Catalan number) different binary trees of size \(2n+1\), and there are no binary trees with an even number of nodes. The corresponding generating function satisfies \(B(z) = z (1 + B(z)^2)\), which allows us to compare the asymptotic expansions for the number of binary trees of size \(n\) obtained via \(C_n\) and obtained via the analysis of \(B(z)\):
sage: assume(SR.an_element() > 0) sage: A.<n> = AsymptoticRing('QQ^n * n^QQ', SR) sage: binomial_expansion = asymptotic_expansions.Binomial_kn_over_n(n, k=2, precision=3) sage: catalan_expansion = binomial_expansion / (n+1) sage: catalan_expansion.subs(n=(n-1)/2) 2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2) + 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2)) sage: asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: 1 + u^2, period=2, ....: tau=1, precision=8) 2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2) + 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2))
>>> from sage.all import * >>> assume(SR.an_element() > Integer(0)) >>> A = AsymptoticRing('QQ^n * n^QQ', SR, names=('n',)); (n,) = A._first_ngens(1) >>> binomial_expansion = asymptotic_expansions.Binomial_kn_over_n(n, k=Integer(2), precision=Integer(3)) >>> catalan_expansion = binomial_expansion / (n+Integer(1)) >>> catalan_expansion.subs(n=(n-Integer(1))/Integer(2)) 2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2) + 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2)) >>> asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: Integer(1) + u**Integer(2), period=Integer(2), ... tau=Integer(1), precision=Integer(8)) 2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2) + 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2))
The code in the aperiodic case is more efficient, however. Therefore, it is recommended to use combinatorial identities to reduce to the aperiodic case. In the example above, this is well-known: we now count binary trees with \(n\) internal nodes. The corresponding generating function satisfies \(B(z) = z (1 + 2B(z) + B(z)^2)\):
sage: catalan_expansion 1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2) + 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2)) sage: asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: 1 + 2*u + u^2, ....: tau=1, precision=8) 1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2) + 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2)) sage: forget()
>>> from sage.all import * >>> catalan_expansion 1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2) + 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2)) >>> asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: Integer(1) + Integer(2)*u + u**Integer(2), ... tau=Integer(1), precision=Integer(8)) 1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2) + 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2)) >>> forget()
- static SingularityAnalysis(var, zeta=1, alpha=0, beta=0, delta=0, precision=None, normalized=True)[source]¶
Return the asymptotic expansion of the coefficients of a power series with specified pole and logarithmic singularity.
More precisely, this extracts the \(n\)-th coefficient
\[[z^n] \left(\frac{1}{1-z/\zeta}\right)^\alpha \left(\frac{1}{z/\zeta} \log \frac{1}{1-z/\zeta}\right)^\beta \left(\frac{1}{z/\zeta} \log \left(\frac{1}{z/\zeta} \log \frac{1}{1-z/\zeta}\right)\right)^\delta\](if
normalized=True
, the default) or\[[z^n] \left(\frac{1}{1-z/\zeta}\right)^\alpha \left(\log \frac{1}{1-z/\zeta}\right)^\beta \left(\log \left(\frac{1}{z/\zeta} \log \frac{1}{1-z/\zeta}\right)\right)^\delta\](if
normalized=False
).INPUT:
var
– string for the variable namezeta
– (default: \(1\)) the location of the singularityalpha
– (default: \(0\)) the pole order of the singularitybeta
– (default: \(0\)) the order of the logarithmic singularitydelta
– (default: \(0\)) the order of the log-log singularity; not yet implemented fordelta != 0
precision
– (default:None
) integer. IfNone
, then the default precision of the asymptotic ring is used.normalized
– boolean (default:True
); see above
OUTPUT: an asymptotic expansion
EXAMPLES:
sage: asymptotic_expansions.SingularityAnalysis('n', alpha=1) 1 sage: asymptotic_expansions.SingularityAnalysis('n', alpha=2) n + 1 sage: asymptotic_expansions.SingularityAnalysis('n', alpha=3) 1/2*n^2 + 3/2*n + 1 sage: _.parent() Asymptotic Ring <n^ZZ> over Rational Field
>>> from sage.all import * >>> asymptotic_expansions.SingularityAnalysis('n', alpha=Integer(1)) 1 >>> asymptotic_expansions.SingularityAnalysis('n', alpha=Integer(2)) n + 1 >>> asymptotic_expansions.SingularityAnalysis('n', alpha=Integer(3)) 1/2*n^2 + 3/2*n + 1 >>> _.parent() Asymptotic Ring <n^ZZ> over Rational Field
sage: asymptotic_expansions.SingularityAnalysis('n', alpha=-3/2, ....: precision=3) 3/4/sqrt(pi)*n^(-5/2) + 45/32/sqrt(pi)*n^(-7/2) + 1155/512/sqrt(pi)*n^(-9/2) + O(n^(-11/2)) sage: asymptotic_expansions.SingularityAnalysis('n', alpha=-1/2, ....: precision=3) -1/2/sqrt(pi)*n^(-3/2) - 3/16/sqrt(pi)*n^(-5/2) - 25/256/sqrt(pi)*n^(-7/2) + O(n^(-9/2)) sage: asymptotic_expansions.SingularityAnalysis('n', alpha=1/2, ....: precision=4) 1/sqrt(pi)*n^(-1/2) - 1/8/sqrt(pi)*n^(-3/2) + 1/128/sqrt(pi)*n^(-5/2) + 5/1024/sqrt(pi)*n^(-7/2) + O(n^(-9/2)) sage: _.parent() Asymptotic Ring <n^QQ> over Symbolic Constants Subring
>>> from sage.all import * >>> asymptotic_expansions.SingularityAnalysis('n', alpha=-Integer(3)/Integer(2), ... precision=Integer(3)) 3/4/sqrt(pi)*n^(-5/2) + 45/32/sqrt(pi)*n^(-7/2) + 1155/512/sqrt(pi)*n^(-9/2) + O(n^(-11/2)) >>> asymptotic_expansions.SingularityAnalysis('n', alpha=-Integer(1)/Integer(2), ... precision=Integer(3)) -1/2/sqrt(pi)*n^(-3/2) - 3/16/sqrt(pi)*n^(-5/2) - 25/256/sqrt(pi)*n^(-7/2) + O(n^(-9/2)) >>> asymptotic_expansions.SingularityAnalysis('n', alpha=Integer(1)/Integer(2), ... precision=Integer(4)) 1/sqrt(pi)*n^(-1/2) - 1/8/sqrt(pi)*n^(-3/2) + 1/128/sqrt(pi)*n^(-5/2) + 5/1024/sqrt(pi)*n^(-7/2) + O(n^(-9/2)) >>> _.parent() Asymptotic Ring <n^QQ> over Symbolic Constants Subring
sage: S = SR.subring(rejecting_variables=('n',)) sage: asymptotic_expansions.SingularityAnalysis( ....: 'n', alpha=S.var('a'), ....: precision=4).map_coefficients(lambda c: c.factor()) 1/gamma(a)*n^(a - 1) + (1/2*(a - 1)*a/gamma(a))*n^(a - 2) + (1/24*(3*a - 1)*(a - 1)*(a - 2)*a/gamma(a))*n^(a - 3) + (1/48*(a - 1)^2*(a - 2)*(a - 3)*a^2/gamma(a))*n^(a - 4) + O(n^(a - 5)) sage: _.parent() Asymptotic Ring <n^(Symbolic Subring rejecting the variable n)> over Symbolic Subring rejecting the variable n
>>> from sage.all import * >>> S = SR.subring(rejecting_variables=('n',)) >>> asymptotic_expansions.SingularityAnalysis( ... 'n', alpha=S.var('a'), ... precision=Integer(4)).map_coefficients(lambda c: c.factor()) 1/gamma(a)*n^(a - 1) + (1/2*(a - 1)*a/gamma(a))*n^(a - 2) + (1/24*(3*a - 1)*(a - 1)*(a - 2)*a/gamma(a))*n^(a - 3) + (1/48*(a - 1)^2*(a - 2)*(a - 3)*a^2/gamma(a))*n^(a - 4) + O(n^(a - 5)) >>> _.parent() Asymptotic Ring <n^(Symbolic Subring rejecting the variable n)> over Symbolic Subring rejecting the variable n
sage: ae = asymptotic_expansions.SingularityAnalysis('n', ....: alpha=1/2, beta=1, precision=4); ae 1/sqrt(pi)*n^(-1/2)*log(n) + ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2) - 5/8/sqrt(pi)*n^(-3/2)*log(n) + (1/8*(3*euler_gamma + 6*log(2) - 8)/sqrt(pi) - (euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n)) sage: n = ae.parent().gen() sage: ae.subs(n=n-1).map_coefficients(lambda x: x.canonicalize_radical()) 1/sqrt(pi)*n^(-1/2)*log(n) + ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2) - 1/8/sqrt(pi)*n^(-3/2)*log(n) + (-1/8*(euler_gamma + 2*log(2))/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n))
>>> from sage.all import * >>> ae = asymptotic_expansions.SingularityAnalysis('n', ... alpha=Integer(1)/Integer(2), beta=Integer(1), precision=Integer(4)); ae 1/sqrt(pi)*n^(-1/2)*log(n) + ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2) - 5/8/sqrt(pi)*n^(-3/2)*log(n) + (1/8*(3*euler_gamma + 6*log(2) - 8)/sqrt(pi) - (euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n)) >>> n = ae.parent().gen() >>> ae.subs(n=n-Integer(1)).map_coefficients(lambda x: x.canonicalize_radical()) 1/sqrt(pi)*n^(-1/2)*log(n) + ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2) - 1/8/sqrt(pi)*n^(-3/2)*log(n) + (-1/8*(euler_gamma + 2*log(2))/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n))
sage: asymptotic_expansions.SingularityAnalysis('n', ....: alpha=1, beta=1/2, precision=4) log(n)^(1/2) + 1/2*euler_gamma*log(n)^(-1/2) + (-1/8*euler_gamma^2 + 1/48*pi^2)*log(n)^(-3/2) + (1/16*euler_gamma^3 - 1/32*euler_gamma*pi^2 + 1/8*zeta(3))*log(n)^(-5/2) + O(log(n)^(-7/2))
>>> from sage.all import * >>> asymptotic_expansions.SingularityAnalysis('n', ... alpha=Integer(1), beta=Integer(1)/Integer(2), precision=Integer(4)) log(n)^(1/2) + 1/2*euler_gamma*log(n)^(-1/2) + (-1/8*euler_gamma^2 + 1/48*pi^2)*log(n)^(-3/2) + (1/16*euler_gamma^3 - 1/32*euler_gamma*pi^2 + 1/8*zeta(3))*log(n)^(-5/2) + O(log(n)^(-7/2))
sage: ae = asymptotic_expansions.SingularityAnalysis('n', ....: alpha=0, beta=2, precision=14) sage: n = ae.parent().gen() sage: ae.subs(n=n-2) 2*n^(-1)*log(n) + 2*euler_gamma*n^(-1) - n^(-2) - 1/6*n^(-3) + O(n^(-5))
>>> from sage.all import * >>> ae = asymptotic_expansions.SingularityAnalysis('n', ... alpha=Integer(0), beta=Integer(2), precision=Integer(14)) >>> n = ae.parent().gen() >>> ae.subs(n=n-Integer(2)) 2*n^(-1)*log(n) + 2*euler_gamma*n^(-1) - n^(-2) - 1/6*n^(-3) + O(n^(-5))
sage: asymptotic_expansions.SingularityAnalysis( ....: 'n', 1, alpha=-1/2, beta=1, precision=2, normalized=False) -1/2/sqrt(pi)*n^(-3/2)*log(n) + (-1/2*(euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n)) sage: asymptotic_expansions.SingularityAnalysis( ....: 'n', 1/2, alpha=0, beta=1, precision=3, normalized=False) 2^n*n^(-1) + O(2^n*n^(-2))
>>> from sage.all import * >>> asymptotic_expansions.SingularityAnalysis( ... 'n', Integer(1), alpha=-Integer(1)/Integer(2), beta=Integer(1), precision=Integer(2), normalized=False) -1/2/sqrt(pi)*n^(-3/2)*log(n) + (-1/2*(euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n)) >>> asymptotic_expansions.SingularityAnalysis( ... 'n', Integer(1)/Integer(2), alpha=Integer(0), beta=Integer(1), precision=Integer(3), normalized=False) 2^n*n^(-1) + O(2^n*n^(-2))
ALGORITHM:
See [FS2009].
- static Stirling(var, precision=None, skip_constant_factor=False)[source]¶
Return Stirling’s approximation formula for factorials.
INPUT:
var
– string for the variable nameprecision
– (default:None
) integer \(\ge 3\). IfNone
, then the default precision of the asymptotic ring is used.skip_constant_factor
– boolean (default:False
); if set, then the constant factor \(\sqrt{2\pi}\) is left out. As a consequence, the coefficient ring of the output changes fromSymbolic Constants Subring
(ifFalse
) toRational Field
(ifTrue
).
OUTPUT: an asymptotic expansion
EXAMPLES:
sage: asymptotic_expansions.Stirling('n', precision=5) sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) + 1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) + 1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) + O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2)) sage: _.parent() Asymptotic Ring <(e^(n*log(n)))^QQ * (e^n)^QQ * n^QQ * log(n)^QQ> over Symbolic Constants Subring
>>> from sage.all import * >>> asymptotic_expansions.Stirling('n', precision=Integer(5)) sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) + 1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) + 1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) + O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2)) >>> _.parent() Asymptotic Ring <(e^(n*log(n)))^QQ * (e^n)^QQ * n^QQ * log(n)^QQ> over Symbolic Constants Subring
See also
- static log_Stirling(var, precision=None, skip_constant_summand=False)[source]¶
Return the logarithm of Stirling’s approximation formula for factorials.
INPUT:
var
– string for the variable nameprecision
– (default:None
) integer. IfNone
, then the default precision of the asymptotic ring is used.skip_constant_summand
– boolean (default:False
); if set, then the constant summand \(\log(2\pi)/2\) is left out. As a consequence, the coefficient ring of the output changes fromSymbolic Constants Subring
(ifFalse
) toRational Field
(ifTrue
).
OUTPUT: an asymptotic expansion
EXAMPLES:
sage: asymptotic_expansions.log_Stirling('n', precision=7) n*log(n) - n + 1/2*log(n) + 1/2*log(2*pi) + 1/12*n^(-1) - 1/360*n^(-3) + 1/1260*n^(-5) + O(n^(-7))
>>> from sage.all import * >>> asymptotic_expansions.log_Stirling('n', precision=Integer(7)) n*log(n) - n + 1/2*log(n) + 1/2*log(2*pi) + 1/12*n^(-1) - 1/360*n^(-3) + 1/1260*n^(-5) + O(n^(-7))
See also
- sage.rings.asymptotic.asymptotic_expansion_generators.asymptotic_expansions = <sage.rings.asymptotic.asymptotic_expansion_generators.AsymptoticExpansionGenerators object>[source]¶
A collection of several common asymptotic expansions.
This is an instance of
AsymptoticExpansionGenerators
whose documentation provides more details.