def convert_factors(data, raw_data): try: return self._convert_factors_(data) except ValueError as e: from misc import combine_exceptions raise combine_exceptions( ValueError('%s is not in %s.' % (raw_data, self)), e)
def convert_factors(data, raw_data): try: return self._convert_factors_(data) except ValueError as e: from misc import combine_exceptions raise combine_exceptions(ValueError("%s is not in %s." % (raw_data, self)), e)
def _log_factor_(self, base=None): r""" Helper method for calculating the logarithm of the factorization of this element. INPUT: - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. OUTPUT: A tuple of pairs, where the first entry is either a growth element or something out of which we can construct a growth element and the second a multiplicative coefficient. TESTS:: sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('QQ^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ') sage: x, y = G.gens_monomial() sage: (x * y).log_factor() # indirect doctest ((log(x), 1), (log(y), 1)) """ if self.is_one(): return tuple() def try_create_growth(g): try: return self.parent()(g) except (TypeError, ValueError): return g try: return sum( iter( tuple((try_create_growth(g), c) for g, c in factor._log_factor_(base=base)) for factor in self.cartesian_factors() if factor != factor.parent().one() ), tuple(), ) except (ArithmeticError, TypeError, ValueError) as e: from misc import combine_exceptions raise combine_exceptions(ArithmeticError("Cannot build log(%s) in %s." % (self, self.parent())), e)
def _log_factor_(self, base=None): r""" Helper method for calculating the logarithm of the factorization of this element. INPUT: - ``base`` -- the base of the logarithm. If ``None`` (default value) is used, the natural logarithm is taken. OUTPUT: A tuple of pairs, where the first entry is either a growth element or something out of which we can construct a growth element and the second a multiplicative coefficient. TESTS:: sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('QQ^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ') sage: x, y = G.gens_monomial() sage: (x * y).log_factor() # indirect doctest ((log(x), 1), (log(y), 1)) """ if self.is_one(): return tuple() def try_create_growth(g): try: return self.parent()(g) except (TypeError, ValueError): return g try: return sum( iter( tuple((try_create_growth(g), c) for g, c in factor._log_factor_(base=base)) for factor in self.cartesian_factors() if factor != factor.parent().one()), tuple()) except (ArithmeticError, TypeError, ValueError) as e: from misc import combine_exceptions raise combine_exceptions( ArithmeticError('Cannot build log(%s) in %s.' % (self, self.parent())), e)
def Binomial_kn_over_n(var, k, precision=None, skip_constant_factor=False): r""" Return the asymptotic expansion of the binomial coefficient `kn` choose `n`. INPUT: - ``var`` -- a string for the variable name. - ``k`` -- a number or symbolic constant. - ``precision`` -- (default: ``None``) an integer. If ``None``, then the default precision of the asymptotic ring is used. - ``skip_constant_factor`` -- (default: ``False``) a boolean. 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 from ``Symbolic Constants Subring`` (if ``False``) to ``Rational Field`` (if ``True``). 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 :: 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)) :: 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 TESTS:: sage: expansion = asymptotic_expansions.Binomial_kn_over_n('n', k=7/5, precision=3) sage: n = expansion.parent().gen() sage: expansion.compare_with_values(n, lambda x: binomial(7/5*x, x), [5, 10, 20]) # rel tol 1e-6 [(5, -0.0287383845047?), (10, -0.030845971026?), (20, -0.03162833549?)] sage: asymptotic_expansions.Binomial_kn_over_n( ....: 'n', k=5, precision=3, skip_constant_factor=True) (3125/256)^n*n^(-1/2) - 7/80*(3125/256)^n*n^(-3/2) + 49/12800*(3125/256)^n*n^(-5/2) + O((3125/256)^n*n^(-7/2)) sage: _.parent() Asymptotic Ring <QQ^n * n^QQ> over Rational Field sage: asymptotic_expansions.Binomial_kn_over_n( ....: 'n', k=4, precision=1, skip_constant_factor=True) (256/27)^n*n^(-1/2) + O((256/27)^n*n^(-3/2)) :: sage: S = asymptotic_expansions.Stirling('n', precision=5) sage: n = S.parent().gen() sage: all( # long time ....: SR(asymptotic_expansions.Binomial_kn_over_n( ....: 'n', k=k, precision=3)).canonicalize_radical() == ....: SR(S.subs(n=k*n) / (S.subs(n=(k-1)*n) * S)).canonicalize_radical() ....: for k in [2, 3, 4]) True """ from sage.symbolic.ring import SR SCR = SR.subring(no_variables=True) try: SCR.coerce(k) except TypeError as e: from misc import combine_exceptions raise combine_exceptions( TypeError('Cannot use k={}.'.format(k)), e) S = AsymptoticExpansionGenerators._log_StirlingNegativePowers_( var, precision=max(precision - 2,0)) n = S.parent().gen() result = (S.subs(n=k*n) - S.subs(n=(k-1)*n) - S).exp() from sage.rings.rational_field import QQ P = S.parent().change_parameter( growth_group='QQ^{n} * {n}^QQ'.format(n=var), coefficient_ring=QQ) n = P.gen() b = k**k / (k-1)**(k-1) if b.parent() is SR: b = SCR(b).canonicalize_radical() result *= n.rpow(b) result *= n**(-QQ(1)/QQ(2)) if not skip_constant_factor: result *= (k/((k-1)*2*SCR('pi'))).sqrt() return result
def Binomial_kn_over_n(var, k, precision=None, skip_constant_factor=False): r""" Return the asymptotic expansion of the binomial coefficient `kn` choose `n`. INPUT: - ``var`` -- a string for the variable name. - ``k`` -- a number or symbolic constant. - ``precision`` -- (default: ``None``) an integer. If ``None``, then the default precision of the asymptotic ring is used. - ``skip_constant_factor`` -- (default: ``False``) a boolean. 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 from ``Symbolic Constants Subring`` (if ``False``) to ``Rational Field`` (if ``True``). 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 :: 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)) :: 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 TESTS:: sage: expansion = asymptotic_expansions.Binomial_kn_over_n('n', k=7/5, precision=3) sage: n = expansion.parent().gen() sage: expansion.compare_with_values(n, lambda x: binomial(7/5*x, x), [5, 10, 20]) # rel tol 1e-6 [(5, -0.0287383845047?), (10, -0.030845971026?), (20, -0.03162833549?)] sage: asymptotic_expansions.Binomial_kn_over_n( ....: 'n', k=5, precision=3, skip_constant_factor=True) (3125/256)^n*n^(-1/2) - 7/80*(3125/256)^n*n^(-3/2) + 49/12800*(3125/256)^n*n^(-5/2) + O((3125/256)^n*n^(-7/2)) sage: _.parent() Asymptotic Ring <QQ^n * n^QQ> over Rational Field sage: asymptotic_expansions.Binomial_kn_over_n( ....: 'n', k=4, precision=1, skip_constant_factor=True) (256/27)^n*n^(-1/2) + O((256/27)^n*n^(-3/2)) :: sage: S = asymptotic_expansions.Stirling('n', precision=5) sage: n = S.parent().gen() sage: all( # long time ....: SR(asymptotic_expansions.Binomial_kn_over_n( ....: 'n', k=k, precision=3)).canonicalize_radical() == ....: SR(S.subs(n=k*n) / (S.subs(n=(k-1)*n) * S)).canonicalize_radical() ....: for k in [2, 3, 4]) True """ from sage.symbolic.ring import SR SCR = SR.subring(no_variables=True) try: SCR.coerce(k) except TypeError as e: from misc import combine_exceptions raise combine_exceptions(TypeError('Cannot use k={}.'.format(k)), e) S = AsymptoticExpansionGenerators._log_StirlingNegativePowers_( var, precision=max(precision - 2, 0)) n = S.parent().gen() result = (S.subs(n=k * n) - S.subs(n=(k - 1) * n) - S).exp() from sage.rings.rational_field import QQ P = S.parent().change_parameter( growth_group='QQ^{n} * {n}^QQ'.format(n=var), coefficient_ring=QQ) n = P.gen() b = k**k / (k - 1)**(k - 1) if b.parent() is SR: b = SCR(b).canonicalize_radical() result *= n.rpow(b) result *= n**(-QQ(1) / QQ(2)) if not skip_constant_factor: result *= (k / ((k - 1) * 2 * SCR('pi'))).sqrt() return result