Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Cartesian Products of Growth Groups
See :doc:`growth_group` for a description.
AUTHORS:
- Benjamin Hackl (2015) - Daniel Krenn (2015) - Clemens Heuberger (2016)
ACKNOWLEDGEMENT:
- Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P 24644-N26.
- Benjamin Hackl is supported by the Google Summer of Code 2015.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: A = GrowthGroup('QQ^x * x^ZZ'); A Growth Group QQ^x * x^ZZ sage: A.construction() (The cartesian_product functorial construction, (Growth Group QQ^x, Growth Group x^ZZ)) sage: A.construction()[1][0].construction() (ExponentialGrowthGroup[x], Rational Field) sage: A.construction()[1][1].construction() (MonomialGrowthGroup[x], Integer Ring) sage: B = GrowthGroup('x^ZZ * y^ZZ'); B Growth Group x^ZZ * y^ZZ sage: B.construction() (The cartesian_product functorial construction, (Growth Group x^ZZ, Growth Group y^ZZ)) sage: C = GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ'); C Growth Group x^ZZ * log(x)^ZZ * y^ZZ sage: C.construction() (The cartesian_product functorial construction, (Growth Group x^ZZ * log(x)^ZZ, Growth Group y^ZZ)) sage: C.construction()[1][0].construction() (The cartesian_product functorial construction, (Growth Group x^ZZ, Growth Group log(x)^ZZ)) sage: C.construction()[1][1].construction() (MonomialGrowthGroup[y], Integer Ring)
::
sage: cm = sage.structure.element.get_coercion_model() sage: D = GrowthGroup('QQ^x * x^QQ') sage: cm.common_parent(A, D) Growth Group QQ^x * x^QQ sage: E = GrowthGroup('ZZ^x * x^QQ') sage: cm.record_exceptions() # not tested, see #19411 sage: cm.common_parent(A, E) Growth Group QQ^x * x^QQ sage: for t in cm.exception_stack(): # not tested, see #19411 ....: print(t)
::
sage: A.an_element() (1/2)^x*x sage: tuple(E.an_element()) (1, x^(1/2))
Classes and Methods =================== """
#***************************************************************************** # Copyright (C) 2014--2015 Benjamin Hackl <benjamin.hackl@aau.at> # 2014--2015 Daniel Krenn <dev@danielkrenn.at> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
r""" Create various types of Cartesian products depending on its input.
INPUT:
- ``growth_groups`` -- a tuple (or other iterable) of growth groups.
- ``order`` -- (default: ``None``) if specified, then this order is taken for comparing two Cartesian product elements. If ``order`` is ``None`` this is determined automatically.
.. NOTE::
The Cartesian product of growth groups is again a growth group. In particular, the resulting structure is partially ordered.
The order on the product is determined as follows:
- Cartesian factors with respect to the same variable are ordered lexicographically. This causes ``GrowthGroup('x^ZZ * log(x)^ZZ')`` and ``GrowthGroup('log(x)^ZZ * x^ZZ')`` to produce two different growth groups.
- Factors over different variables are equipped with the product order (i.e. the comparison is component-wise).
Also, note that the sets of variables of the Cartesian factors have to be either equal or disjoint.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: A = GrowthGroup('x^ZZ'); A Growth Group x^ZZ sage: B = GrowthGroup('log(x)^ZZ'); B Growth Group log(x)^ZZ sage: C = cartesian_product([A, B]); C # indirect doctest Growth Group x^ZZ * log(x)^ZZ sage: C._le_ == C.le_lex True sage: D = GrowthGroup('y^ZZ'); D Growth Group y^ZZ sage: E = cartesian_product([A, D]); E # indirect doctest Growth Group x^ZZ * y^ZZ sage: E._le_ == E.le_product True sage: F = cartesian_product([C, D]); F # indirect doctest Growth Group x^ZZ * log(x)^ZZ * y^ZZ sage: F._le_ == F.le_product True sage: cartesian_product([A, E]); G # indirect doctest Traceback (most recent call last): ... ValueError: The growth groups (Growth Group x^ZZ, Growth Group x^ZZ * y^ZZ) need to have pairwise disjoint or equal variables. sage: cartesian_product([A, B, D]) # indirect doctest Growth Group x^ZZ * log(x)^ZZ * y^ZZ
TESTS::
sage: from sage.rings.asymptotic.growth_group_cartesian import CartesianProductFactory sage: CartesianProductFactory('factory')([A, B], category=Groups() & Posets()) Growth Group x^ZZ * log(x)^ZZ sage: CartesianProductFactory('factory')([], category=Sets()) Traceback (most recent call last): ... TypeError: Cannot create Cartesian product without factors. """ r""" Given the arguments and keywords, create a key that uniquely determines this object.
TESTS::
sage: from sage.rings.asymptotic.growth_group_cartesian import CartesianProductFactory sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: A = GrowthGroup('x^ZZ') sage: CartesianProductFactory('factory').create_key_and_extra_args( ....: [A], category=Sets(), order='blub') (((Growth Group x^ZZ,), Category of sets), {'order': 'blub'}) """
r""" Create an object from the given arguments.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: cartesian_product([GrowthGroup('x^ZZ')]) # indirect doctest Growth Group x^ZZ """
# check if all groups have a variable raise NotImplementedError('Growth groups %s have no variable.' % tuple(g for g in growth_groups if not g.variable_names()))
# sort by variables groupby(sorted(vg, key=lambda k: k[0]), key=lambda k: k[0]))
# check whether variables are pairwise disjoint 'disjoint or equal variables.' % (growth_groups,))
# build Cartesian products else:
else:
r""" A Cartesian product of growth groups.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: P = GrowthGroup('x^QQ') sage: L = GrowthGroup('log(x)^ZZ') sage: C = cartesian_product([P, L], order='lex'); C # indirect doctest Growth Group x^QQ * log(x)^ZZ sage: C.an_element() x^(1/2)*log(x)
::
sage: Px = GrowthGroup('x^QQ') sage: Lx = GrowthGroup('log(x)^ZZ') sage: Cx = cartesian_product([Px, Lx], order='lex') # indirect doctest sage: Py = GrowthGroup('y^QQ') sage: C = cartesian_product([Cx, Py], order='product'); C # indirect doctest Growth Group x^QQ * log(x)^ZZ * y^QQ sage: C.an_element() x^(1/2)*log(x)*y^(1/2)
.. SEEALSO::
:class:`~sage.sets.cartesian_product.CartesianProduct`, :class:`~sage.combinat.posets.cartesian_product.CartesianProductPoset`. """
r""" See :class:`GenericProduct` for details.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: GrowthGroup('x^ZZ * y^ZZ') # indirect doctest Growth Group x^ZZ * y^ZZ """
for factor in self.cartesian_factors()), tuple())
r""" Return some elements of this Cartesian product of growth groups.
See :class:`TestSuite` for a typical use case.
INPUT:
Nothing.
OUTPUT:
An iterator.
EXAMPLES::
sage: from itertools import islice sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('QQ^y * x^QQ * log(x)^ZZ') sage: tuple(islice(G.some_elements(), 10)) (x^(1/2)*(1/2)^y, x^(-1/2)*log(x)*(-1/2)^y, x^2*log(x)^(-1)*2^y, x^(-2)*log(x)^2*(-2)^y, log(x)^(-2), x*log(x)^3*(-1)^y, x^(-1)*log(x)^(-3)*42^y, x^42*log(x)^4*(2/3)^y, x^(2/3)*log(x)^(-4)*(-2/3)^y, x^(-2/3)*log(x)^5*(3/2)^y) """ self(c) for c in zip(*tuple(F.some_elements() for F in self.cartesian_factors())))
r""" Create an element in an extension of this Cartesian product of growth groups which is chosen according to the input ``element``.
INPUT:
- ``element`` -- a tuple.
OUTPUT:
An element.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('z^ZZ * log(z)^ZZ') sage: z = G('z')[0] sage: lz = G('log(z)')[1] sage: G._create_element_in_extension_((z^3, lz)).parent() Growth Group z^ZZ * log(z)^ZZ sage: G._create_element_in_extension_((z^(1/2), lz)).parent() Growth Group z^QQ * log(z)^ZZ
::
sage: G._create_element_in_extension_((3, 3, 3)) Traceback (most recent call last): ... ValueError: Cannot create (3, 3, 3) as a Cartesian product like Growth Group z^ZZ * log(z)^ZZ. """ (element, self))
else: category=self.category())
r""" Converts the given object to an element of this Cartesian product.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * y^ZZ') sage: G_log = GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ')
Conversion from the symbolic ring works::
sage: x,y = var('x y') sage: G(x^-3*y^2) x^(-3)*y^2 sage: G(x^4), G(y^2) (x^4, y^2) sage: G(1) 1
Even more complex expressions can be parsed::
sage: G_log(x^42*log(x)^-42*y^42) x^42*log(x)^(-42)*y^42
TESTS::
sage: G = GrowthGroup('x^ZZ * y^ZZ') sage: G('x'), G('y') (x, y)
::
sage: G_log(log(x)) log(x)
::
sage: G(G.cartesian_factors()[0].gen()) x
::
sage: GrowthGroup('QQ^x * x^QQ')(['x^(1/2)']) x^(1/2) sage: l = GrowthGroup('x^ZZ * log(x)^ZZ')(['x', 'log(x)']); l x*log(x) sage: type(l) <class 'sage.rings.asymptotic.growth_group_cartesian.UnivariateProduct_with_category.element_class'> sage: GrowthGroup('QQ^x * x^QQ')(['2^log(x)']) Traceback (most recent call last): ... ValueError: ['2^log(x)'] is not in Growth Group QQ^x * x^QQ. > *previous* ValueError: 2^log(x) is not in any of the factors of Growth Group QQ^x * x^QQ sage: GrowthGroup('QQ^x * x^QQ')(['2^log(x)', 'x^55']) Traceback (most recent call last): ... ValueError: ['2^log(x)', 'x^55'] is not in Growth Group QQ^x * x^QQ. > *previous* ValueError: 2^log(x) is not in any of the factors of Growth Group QQ^x * x^QQ
::
sage: n = GrowthGroup('n^ZZ * log(n)^ZZ')('n') sage: G = GrowthGroup('QQ^n * n^ZZ * log(n)^ZZ') sage: G(n).value (1, n, 1) """
ValueError('%s is not in %s.' % (raw_data, self)), e)
raise ValueError('%s cannot be converted.' % (data,))
return data
return data
# room for other parents (e.g. polynomial ring et al.)
r""" A short (shorter than :meth:`._repr_`) representation string for this Cartesian product of growth groups.
INPUT:
Nothing.
OUTPUT:
A string.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: P = GrowthGroup('x^QQ') sage: L = GrowthGroup('log(x)^ZZ') sage: cartesian_product([P, L], order='lex')._repr_short_() 'x^QQ * log(x)^ZZ' """
r""" Helper method. Try to convert some ``factors`` to an element of one of the Cartesian factors and return the product of all these factors.
INPUT:
- ``factors`` -- a tuple or other iterable.
OUTPUT:
An element of this Cartesian product.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * log(x)^QQ * y^QQ') sage: e1 = G._convert_factors_([x^2]) sage: (e1, e1.parent()) (x^2, Growth Group x^ZZ * log(x)^QQ * y^QQ) """
for f in factors)
r""" Inject the given element into this Cartesian product at the given factor.
INPUT:
- ``factor`` -- a growth group (a factor of this Cartesian product).
- ``element`` -- an element of ``factor``.
OUTPUT:
An element of this Cartesian product.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * y^QQ') sage: G.cartesian_injection(G.cartesian_factors()[1], 'y^7') y^7 """ for f in self.cartesian_factors()))
r""" Return whether ``S`` coerces into this growth group.
INPUT:
- ``S`` -- a parent.
OUTPUT:
A boolean.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: A = GrowthGroup('QQ^x * x^QQ') sage: B = GrowthGroup('QQ^x * x^ZZ') sage: A.has_coerce_map_from(B) # indirect doctest True sage: B.has_coerce_map_from(A) # indirect doctest False """ return True
else:
for f in factors):
r""" Construct the pushout of this and the other growth group. This is called by :func:`sage.categories.pushout.pushout`.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: from sage.categories.pushout import pushout sage: cm = sage.structure.element.get_coercion_model() sage: A = GrowthGroup('QQ^x * x^ZZ') sage: B = GrowthGroup('x^ZZ * log(x)^ZZ') sage: A._pushout_(B) Growth Group QQ^x * x^ZZ * log(x)^ZZ sage: pushout(A, B) Growth Group QQ^x * x^ZZ * log(x)^ZZ sage: cm.discover_coercion(A, B) ((map internal to coercion system -- copy before use) Coercion map: From: Growth Group QQ^x * x^ZZ To: Growth Group QQ^x * x^ZZ * log(x)^ZZ, (map internal to coercion system -- copy before use) Coercion map: From: Growth Group x^ZZ * log(x)^ZZ To: Growth Group QQ^x * x^ZZ * log(x)^ZZ) sage: cm.common_parent(A, B) Growth Group QQ^x * x^ZZ * log(x)^ZZ
::
sage: C = GrowthGroup('QQ^x * x^QQ * y^ZZ') sage: D = GrowthGroup('x^ZZ * log(x)^QQ * QQ^z') sage: C._pushout_(D) Growth Group QQ^x * x^QQ * log(x)^QQ * y^ZZ * QQ^z sage: cm.common_parent(C, D) Growth Group QQ^x * x^QQ * log(x)^QQ * y^ZZ * QQ^z sage: A._pushout_(D) Growth Group QQ^x * x^ZZ * log(x)^QQ * QQ^z sage: cm.common_parent(A, D) Growth Group QQ^x * x^ZZ * log(x)^QQ * QQ^z sage: cm.common_parent(B, D) Growth Group x^ZZ * log(x)^QQ * QQ^z sage: cm.common_parent(A, C) Growth Group QQ^x * x^QQ * y^ZZ sage: E = GrowthGroup('log(x)^ZZ * y^ZZ') sage: cm.common_parent(A, E) Traceback (most recent call last): ... TypeError: no common canonical parent for objects with parents: 'Growth Group QQ^x * x^ZZ' and 'Growth Group log(x)^ZZ * y^ZZ'
::
sage: F = GrowthGroup('z^QQ') sage: pushout(C, F) Growth Group QQ^x * x^QQ * y^ZZ * z^QQ
::
sage: pushout(GrowthGroup('QQ^x * x^ZZ'), GrowthGroup('ZZ^x * x^QQ')) Growth Group QQ^x * x^QQ sage: cm.common_parent(GrowthGroup('QQ^x * x^ZZ'), GrowthGroup('ZZ^x * x^QQ')) Growth Group QQ^x * x^QQ
::
sage: pushout(GrowthGroup('QQ^n * n^QQ'), GrowthGroup('SR^n')) Growth Group SR^n * n^QQ """
elif (other.construction() is not None and isinstance(other.construction()[0], AbstractGrowthGroupFunctor)): Ofactors = (other,) else: return
Sfactors, Ofactors, lambda f: (f._underlying_class(), f._var_.var_repr))
else:
tuple(subfactors(Sfactors)), tuple(subfactors(Ofactors)), lambda f: (f._underlying_class(), f._var_.var_repr))
'Cannot construct the pushout of %s and %s: The factors ' 'with variables %s are not overlapping, ' 'no common parent was found, and ' 'splitting the factors was unsuccessful.' % (self, other, var))
# A wrapper around an iterator that stores additional intermediate data. # This deviates slightly from the iterator protocol: # At the end of the iteration the data is reset to None instead # of raising a StopIteration.
else: S.factors, O.factors)
len(Ofactors) == len(newO)): # We had already all factors in each of self and # other, thus splitting it in subproblems (one for # each factor) is the strategy to use. If a pushout is # possible :func:`sage.categories.pushout.pushout` # will manage this by itself.
r""" Return a tuple containing monomial generators of this growth group.
INPUT:
Nothing.
OUTPUT:
A tuple containing elements of this growth group.
.. NOTE::
This method calls the ``gens_monomial()`` method on the individual factors of this Cartesian product and concatenates the respective outputs.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ') sage: G.gens_monomial() (x, y)
TESTS::
sage: all(g.parent() == G for g in G.gens_monomial()) True """ tuple(self.cartesian_injection(factor, g) for g in factor.gens_monomial()) for factor in self.cartesian_factors()), tuple())
r""" Return the names of the variables.
OUTPUT:
A tuple of strings.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: GrowthGroup('x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ').variable_names() ('x', 'y', 'z') """ for factor in self.cartesian_factors()), tuple())
r""" A representation string for this Cartesian product element.
INPUT:
- ``latex`` -- (default: ``False``) a boolean. If set, then LaTeX-output is returned.
OUTPUT:
A string.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: P = GrowthGroup('x^QQ') sage: L = GrowthGroup('log(x)^ZZ') sage: cartesian_product([P, L], order='lex').an_element()._repr_() 'x^(1/2)*log(x)' """ else:
r""" A representation string for this Cartesian product element.
OUTPUT:
A string.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: P = GrowthGroup('x^QQ') sage: L = GrowthGroup('log(x)^ZZ') sage: latex(cartesian_product([P, L], order='lex').an_element()) # indirect doctest x^{\frac{1}{2}} \log\left(x\right) sage: latex(GrowthGroup('QQ^n * n^QQ').an_element()) # indirect doctest \left(\frac{1}{2}\right)^{n} n^{\frac{1}{2}} """
r""" Calculate the power of this growth element to the given ``exponent``.
INPUT:
- ``exponent`` -- a number.
OUTPUT:
A growth element.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * y^QQ * z^ZZ') sage: x, y, z = G.gens_monomial() sage: (x^5 * y * z^5)^(1/5) # indirect doctest x*y^(1/5)*z
::
sage: G = GrowthGroup('x^QQ * log(x)^QQ'); x = G('x') sage: (x^(21/5) * log(x)^7)^(1/42) # indirect doctest x^(1/10)*log(x)^(1/6) """ tuple(x ** exponent for x in self.cartesian_factors()))
r""" Return the atomic factors of this growth element. An atomic factor cannot be split further and is not the identity (`1`).
INPUT:
Nothing.
OUTPUT:
A tuple of growth elements.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ') sage: x, y = G.gens_monomial() sage: x.factors() (x,) sage: f = (x * y).factors(); f (x, y) sage: tuple(factor.parent() for factor in f) (Growth Group x^ZZ, Growth Group y^ZZ) sage: f = (x * log(x)).factors(); f (x, log(x)) sage: tuple(factor.parent() for factor in f) (Growth Group x^ZZ, Growth Group log(x)^ZZ)
::
sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * log(log(x))^ZZ * y^QQ') sage: x, y = G.gens_monomial() sage: f = (x * log(x) * y).factors(); f (x, log(x), y) sage: tuple(factor.parent() for factor in f) (Growth Group x^ZZ, Growth Group log(x)^ZZ, Growth Group y^QQ)
::
sage: G.one().factors() () """ for f in self.cartesian_factors() if not f.is_one()), tuple())
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)) """
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)
r""" Return an element which is the power of ``base`` to this element.
INPUT:
- ``base`` -- an element.
OUTPUT:
A growth element.
.. NOTE::
The parent of the result can be different from the parent of this element.
A ``ValueError`` is raised if the calculation is not possible within this method. (Then the calling method should take care of the calculation.)
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('QQ^x * x^ZZ * log(x)^ZZ') sage: lx = log(G('x')) sage: rp = lx._rpow_element_('e'); rp x sage: rp.parent() Growth Group x^ZZ """ raise ValueError # calling method has to deal with it...
r""" The exponential of this element.
INPUT:
Nothing.
OUTPUT:
A growth element.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^ZZ * log(x)^ZZ * log(log(x))^ZZ') sage: x = G('x') sage: exp(log(x)) x sage: exp(log(log(x))) log(x)
::
sage: exp(x) Traceback (most recent call last): ... ArithmeticError: Cannot construct e^x in Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ > *previous* TypeError: unsupported operand parent(s) for *: 'Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ' and 'Growth Group (e^x)^ZZ'
TESTS::
sage: E = GrowthGroup("(e^y)^QQ * y^QQ * log(y)^QQ") sage: y = E('y') sage: log(exp(y)) y sage: exp(log(y)) y """
r""" Return the multiplicative inverse of this Cartesian product.
OUTPUT:
An growth element.
.. NOTE::
The result may live in a larger parent than we started with.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('ZZ^x * x^ZZ') sage: g = G('2^x * x^3') sage: (~g).parent() Growth Group QQ^x * x^ZZ """ tuple(~x for x in self.cartesian_factors()))
r""" Substitute the given ``rules`` in this Cartesian product growth element.
INPUT:
- ``rules`` -- a dictionary. The neutral element of the group is replaced by the value to key ``'_one_'``.
OUTPUT:
An object.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('x^QQ * log(x)^QQ') sage: G(x^3 * log(x)^5)._substitute_({'x': SR.var('z')}) z^3*log(z)^5 sage: _.parent() Symbolic Ring sage: G(x^3 * log(x)^5)._substitute_({'x': 2.2}) # rel tol 1e-6 3.24458458945 sage: _.parent() Real Field with 53 bits of precision sage: G(1 / x)._substitute_({'x': 0}) Traceback (most recent call last): ... ZeroDivisionError: Cannot substitute in x^(-1) in Growth Group x^QQ * log(x)^QQ. > *previous* ZeroDivisionError: Cannot substitute in x^(-1) in Growth Group x^QQ. >> *previous* ZeroDivisionError: rational division by zero sage: G(1)._substitute_({'_one_': 'one'}) 'one' """ *tuple(x._substitute_(rules) for x in self.cartesian_factors()))
r""" Perform singularity analysis on this growth element.
INPUT:
- ``var`` -- a string denoting the variable
- ``zeta`` -- a number
- ``precision`` -- an integer
OUTPUT:
An asymptotic expansion for `[z^n] f` where `n` is ``var`` and `f` has this growth element as a singular expansion in `T=\frac{1}{1-\frac{z}{\zeta}}\to \infty` where this element is a growth element in `T`.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('exp(x)^QQ * x^QQ * log(x)^QQ') sage: G(x^(1/2))._singularity_analysis_('n', 2, precision=2) 1/sqrt(pi)*(1/2)^n*n^(-1/2) - 1/8/sqrt(pi)*(1/2)^n*n^(-3/2) + O((1/2)^n*n^(-5/2)) sage: G(log(x))._singularity_analysis_('n', 1, precision=5) n^(-1) + O(n^(-3)) sage: G(x*log(x))._singularity_analysis_('n', 1, precision=5) log(n) + euler_gamma + 1/2*n^(-1) + O(n^(-2))
TESTS::
sage: G('exp(x)*log(x)')._singularity_analysis_('n', 1, precision=5) Traceback (most recent call last): ... NotImplementedError: singularity analysis of exp(x)*log(x) not implemented sage: G('exp(x)*x*log(x)')._singularity_analysis_('n', 1, precision=5) Traceback (most recent call last): ... NotImplementedError: singularity analysis of exp(x)*x*log(x) not yet implemented since it has more than two factors sage: G(1)._singularity_analysis_('n', 2, precision=3) Traceback (most recent call last): ... NotImplementedOZero: The error term in the result is O(0) which means 0 for sufficiently large n. sage: G('exp(x)')._singularity_analysis_('n', 2, precision=3) Traceback (most recent call last): ... NotImplementedError: singularity analysis of exp(x) not implemented """ var=var, zeta=zeta, precision=precision)
for f in factors) \ and a.parent().gens_monomial() \ and b.parent().gens_logarithmic() \ and a.parent().variable_name() == \ b.parent().variable_name(): raise NotImplementedError( 'singularity analysis of {} not implemented ' 'since exponent {} of {} is not an integer'.format( self, b.exponent, b.parent().gen()))
asymptotic_expansions var=var, zeta=zeta, alpha=a.exponent, beta=ZZ(b.exponent), delta=0, precision=precision, normalized=False) else: 'singularity analysis of {} not implemented'.format(self)) else: 'singularity analysis of {} not yet implemented ' 'since it has more than two factors'.format(self))
r""" Return the names of the variables of this growth element.
OUTPUT:
A tuple of strings.
EXAMPLES::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: G = GrowthGroup('QQ^m * m^QQ * log(n)^ZZ') sage: G('2^m * m^4 * log(n)').variable_names() ('m', 'n') sage: G('2^m * m^4').variable_names() ('m',) sage: G('log(n)').variable_names() ('n',) sage: G('m^3').variable_names() ('m',) sage: G('m^0').variable_names() () """ for factor in self.factors()), tuple())
r""" A Cartesian product of growth groups with the same variables.
.. NOTE::
A univariate product of growth groups is ordered lexicographically. This is motivated by the assumption that univariate growth groups can be ordered in a chain with respect to the growth they model (e.g. ``x^ZZ * log(x)^ZZ``: polynomial growth dominates logarithmic growth).
.. SEEALSO::
:class:`MultivariateProduct`, :class:`GenericProduct`. """
r""" See :class:`UnivariateProduct` for details.
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: type(GrowthGroup('x^ZZ * log(x)^ZZ')) # indirect doctest <class 'sage.rings.asymptotic.growth_group_cartesian.UnivariateProduct_with_category'> """ sets, category, order='lex', **kwargs)
r""" A Cartesian product of growth groups with pairwise disjoint (or equal) variable sets.
.. NOTE::
A multivariate product of growth groups is ordered by means of the product order, i.e. component-wise. This is motivated by the assumption that different variables are considered to be independent (e.g. ``x^ZZ * y^ZZ``).
.. SEEALSO::
:class:`UnivariateProduct`, :class:`GenericProduct`. """ r"""
TESTS::
sage: from sage.rings.asymptotic.growth_group import GrowthGroup sage: type(GrowthGroup('x^ZZ * y^ZZ')) # indirect doctest <class 'sage.rings.asymptotic.growth_group_cartesian.MultivariateProduct_with_category'> """ sets, category, order='product', **kwargs)
|