(Asymptotic) Term Monoids#

This module implements asymptotic term monoids. The elements of these monoids are used behind the scenes when performing calculations in an asymptotic ring.

The monoids build upon the (asymptotic) growth groups. While growth elements only model the growth of a function as it tends towards infinity (or tends towards another fixed point; see (Asymptotic) Growth Groups for more details), an asymptotic term additionally specifies its “type” and performs the actual arithmetic operations (multiplication and partial addition/absorption of terms).

Besides an abstract base term GenericTerm, this module implements the following types of terms:

A characteristic property of asymptotic terms is that some terms are able to “absorb” other terms (see absorb()). For instance, \(O(x^2)\) is able to absorb \(O(x)\) (with result \(O(x^2)\)), and \(3\cdot x^5\) is able to absorb \(-2\cdot x^5\) (with result \(x^5\)). Essentially, absorption can be interpreted as the addition of “compatible” terms (partial addition).

Absorption of Asymptotic Terms#

A characteristic property of asymptotic terms is that some terms are able to “absorb” other terms. This is realized with the method absorb().

For instance, \(O(x^2)\) is able to absorb \(O(x)\) (with result \(O(x^2)\)). This is because the functions bounded by linear growth are bounded by quadratic growth as well. Another example would be that \(3x^5\) is able to absorb \(-2x^5\) (with result \(x^5\)), which simply corresponds to addition.

Essentially, absorption can be interpreted as the addition of “compatible” terms (partial addition).

We want to show step by step which terms can be absorbed by which other terms. We start by defining the necessary term monoids and some terms:

sage: from sage.rings.asymptotic.term_monoid import OTermMonoid, ExactTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: G = GrowthGroup('x^ZZ'); x = G.gen()
sage: OT = OTermMonoid(TermMonoid, growth_group=G, coefficient_ring=QQ)
sage: ET = ExactTermMonoid(TermMonoid, growth_group=G, coefficient_ring=QQ)
sage: ot1 = OT(x); ot2 = OT(x^2)
sage: et1 = ET(x^2, coefficient=2)
>>> from sage.all import *
>>> from sage.rings.asymptotic.term_monoid import OTermMonoid, ExactTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> G = GrowthGroup('x^ZZ'); x = G.gen()
>>> OT = OTermMonoid(TermMonoid, growth_group=G, coefficient_ring=QQ)
>>> ET = ExactTermMonoid(TermMonoid, growth_group=G, coefficient_ring=QQ)
>>> ot1 = OT(x); ot2 = OT(x**Integer(2))
>>> et1 = ET(x**Integer(2), coefficient=Integer(2))
  • Because of the definition of \(O\)-terms (see Wikipedia article Big_O_notation), OTerm are able to absorb all other asymptotic terms with weaker or equal growth. In our implementation, this means that OTerm is able to absorb other OTerm, as well as ExactTerm, as long as the growth of the other term is less than or equal to the growth of this element:

    sage: ot1, ot2
    (O(x), O(x^2))
    sage: ot1.can_absorb(ot2), ot2.can_absorb(ot1)
    (False, True)
    sage: et1
    2*x^2
    sage: ot1.can_absorb(et1)
    False
    sage: ot2.can_absorb(et1)
    True
    
    >>> from sage.all import *
    >>> ot1, ot2
    (O(x), O(x^2))
    >>> ot1.can_absorb(ot2), ot2.can_absorb(ot1)
    (False, True)
    >>> et1
    2*x^2
    >>> ot1.can_absorb(et1)
    False
    >>> ot2.can_absorb(et1)
    True
    

    The result of this absorption always is the dominant (absorbing) OTerm:

    sage: ot1.absorb(ot1)
    O(x)
    sage: ot2.absorb(ot1)
    O(x^2)
    sage: ot2.absorb(et1)
    O(x^2)
    
    >>> from sage.all import *
    >>> ot1.absorb(ot1)
    O(x)
    >>> ot2.absorb(ot1)
    O(x^2)
    >>> ot2.absorb(et1)
    O(x^2)
    

    These examples correspond to \(O(x) + O(x) = O(x)\), \(O(x^2) + O(x) = O(x^2)\), and \(O(x^2) + 2x^2 = O(x^2)\).

  • ExactTerm can only absorb another ExactTerm if the growth coincides with the growth of this element:

    sage: et1.can_absorb(ET(x^2, coefficient=5))
    True
    sage: any(et1.can_absorb(t) for t in [ot1, ot2])
    False
    
    >>> from sage.all import *
    >>> et1.can_absorb(ET(x**Integer(2), coefficient=Integer(5)))
    True
    >>> any(et1.can_absorb(t) for t in [ot1, ot2])
    False
    

    As mentioned above, absorption directly corresponds to addition in this case:

    sage: et1.absorb(ET(x^2, coefficient=5))
    7*x^2
    
    >>> from sage.all import *
    >>> et1.absorb(ET(x**Integer(2), coefficient=Integer(5)))
    7*x^2
    

    When adding two exact terms, they might cancel out. For technical reasons, None is returned in this case:

    sage: ET(x^2, coefficient=5).can_absorb(ET(x^2, coefficient=-5))
    True
    sage: ET(x^2, coefficient=5).absorb(ET(x^2, coefficient=-5)) is None
    True
    
    >>> from sage.all import *
    >>> ET(x**Integer(2), coefficient=Integer(5)).can_absorb(ET(x**Integer(2), coefficient=-Integer(5)))
    True
    >>> ET(x**Integer(2), coefficient=Integer(5)).absorb(ET(x**Integer(2), coefficient=-Integer(5))) is None
    True
    
  • The abstract base terms GenericTerm and TermWithCoefficient can neither absorb any other term, nor be absorbed by any other term.

If absorb is called on a term that cannot be absorbed, an ArithmeticError is raised:

sage: ot1.absorb(ot2)
Traceback (most recent call last):
...
ArithmeticError: O(x) cannot absorb O(x^2)
>>> from sage.all import *
>>> ot1.absorb(ot2)
Traceback (most recent call last):
...
ArithmeticError: O(x) cannot absorb O(x^2)

This would only work the other way around:

sage: ot2.absorb(ot1)
O(x^2)
>>> from sage.all import *
>>> ot2.absorb(ot1)
O(x^2)

Comparison#

The comparison of asymptotic terms with \(\leq\) is implemented as follows:

  • When comparing t1 <= t2, the coercion framework first tries to find a common parent for both terms. If this fails, False is returned.

  • In case the coerced terms do not have a coefficient in their common parent (e.g. OTerm), the growth of the two terms is compared.

  • Otherwise, if the coerced terms have a coefficient (e.g. ExactTerm), we compare whether t1 has a growth that is strictly weaker than the growth of t2. If so, we return True. If the terms have equal growth, then we return True if and only if the coefficients coincide as well.

    In all other cases, we return False.

Long story short: we consider terms with different coefficients that have equal growth to be incomparable.

Various#

Warning

The code for B-Terms is experimental, so a warning is thrown when a BTerm is created for the first time in a session (see sage.misc.superseded.experimental).

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('B', growth_group=GrowthGroup('x^ZZ'), coefficient_ring=QQ)
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/31922 for details.
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('B', growth_group=GrowthGroup('x^ZZ'), coefficient_ring=QQ)
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/31922 for details.

Todo

  • Implementation of more term types (e.g. \(\Omega\) terms, \(o\) terms, \(\Theta\) terms).

AUTHORS:

  • Benjamin Hackl (2015)

  • Daniel Krenn (2015)

  • Clemens Heuberger (2016)

  • Thomas Hagelmayer (2021)

ACKNOWLEDGEMENT:

  • Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P 24644-N26.

  • Benjamin Hackl is supported by Google Summer of Code 2015.

  • Thomas Hagelmayer is supported by Google Summer of Code 2021.

Classes and Methods#

class sage.rings.asymptotic.term_monoid.BTerm(parent, growth, valid_from, **kwds)[source]#

Bases: TermWithCoefficient

Class for asymptotic B-terms.

A B-term represents all functions which (in absolute value) are bounded by the given growth and coefficient for the parameters given by valid_from. For example, we have terms that represent functions

  • bounded by \(5|x|^2\) for \(|x| \ge 3\),

  • bounded by \(42|x|^3\) for \(|x| \ge 15\) and \(|y| \ge 15\), or

  • bounded by \(42 |x|^3 |y|^2\) for \(|x| \ge 10\) and \(|y| \ge 20\) (see below for the actual examples).

INPUT:

  • parent – the parent of the asymptotic term

  • growth – an asymptotic growth element of the parent’s growth group

  • coefficient – an element of the parent’s coefficient ring

  • valid_from – dictionary mapping variable names to lower bounds for the corresponding variable. The bound implied by this term is valid when all variables are at least their corresponding lower bound. If a number is passed to valid_from, then the lower bounds for all variables of the asymptotic expansion are set to this number

EXAMPLES:

We revisit the examples from the introduction:

sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: G = GrowthGroup('x^ZZ * y^ZZ')
sage: T = TermMonoid('B', growth_group=G, coefficient_ring=ZZ)
sage: x, y = G('x'), G('y')
>>> from sage.all import *
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> G = GrowthGroup('x^ZZ * y^ZZ')
>>> T = TermMonoid('B', growth_group=G, coefficient_ring=ZZ)
>>> x, y = G('x'), G('y')

This is a term bounded by \(5|x|^2\) for \(|x| \ge 3\):

sage: T(x^2, coefficient=5, valid_from={'x': 3})
B(5*x^2, x >= 3)
>>> from sage.all import *
>>> T(x**Integer(2), coefficient=Integer(5), valid_from={'x': Integer(3)})
B(5*x^2, x >= 3)

This is a term bounded by \(42|x|^3\) for \(|x| \ge 15\) and \(|y| \ge 15\):

sage: T(x^3, coefficient=42, valid_from={'x': 15, 'y': 15})
B(42*x^3, x >= 15, y >= 15)
>>> from sage.all import *
>>> T(x**Integer(3), coefficient=Integer(42), valid_from={'x': Integer(15), 'y': Integer(15)})
B(42*x^3, x >= 15, y >= 15)

This is a term bounded by \(42 |x|^3 |y|^2\) for \(|x| \ge 10\) and \(|y| \ge 20\):

sage: T(x^3*y^2, coefficient=42, valid_from={'x': 10, 'y': 20})
B(42*x^3*y^2, x >= 10, y >= 20)
>>> from sage.all import *
>>> T(x**Integer(3)*y**Integer(2), coefficient=Integer(42), valid_from={'x': Integer(10), 'y': Integer(20)})
B(42*x^3*y^2, x >= 10, y >= 20)
can_absorb(other)[source]#

Check whether this B-term can absorb other.

INPUT:

  • other – an asymptotic term

OUTPUT:

A boolean

Note

A BTerm can absorb another BTerm with weaker or equal growth.

See the module description for a detailed explanation of absorption.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: BT = TermMonoid('B', GrowthGroup('x^ZZ'), QQ)
sage: t1 = BT(x^3, coefficient=3, valid_from={'x': 20})
sage: t2 = BT(x^2, coefficient=1, valid_from={'x': 10})
sage: t3 = BT(x^3, coefficient=10, valid_from={'x': 10})
sage: t1.can_absorb(t2)
True
sage: t2.can_absorb(t1)
False
sage: t1.can_absorb(t3)
True
sage: t3.can_absorb(t1)
True
sage: ET = TermMonoid('exact', GrowthGroup('x^ZZ'), QQ)
sage: t4 = ET(x^3, coefficient=5)
sage: t1.can_absorb(t4)
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> BT = TermMonoid('B', GrowthGroup('x^ZZ'), QQ)
>>> t1 = BT(x**Integer(3), coefficient=Integer(3), valid_from={'x': Integer(20)})
>>> t2 = BT(x**Integer(2), coefficient=Integer(1), valid_from={'x': Integer(10)})
>>> t3 = BT(x**Integer(3), coefficient=Integer(10), valid_from={'x': Integer(10)})
>>> t1.can_absorb(t2)
True
>>> t2.can_absorb(t1)
False
>>> t1.can_absorb(t3)
True
>>> t3.can_absorb(t1)
True
>>> ET = TermMonoid('exact', GrowthGroup('x^ZZ'), QQ)
>>> t4 = ET(x**Integer(3), coefficient=Integer(5))
>>> t1.can_absorb(t4)
True
construction()[source]#

Return a construction of this term.

INPUT:

Nothing.

OUTPUT:

A pair (cls, kwds) such that cls(**kwds) equals this term.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import TermMonoidFactory
sage: TermMonoid = TermMonoidFactory('__main__.TermMonoid')

sage: T = TermMonoid('B', GrowthGroup('x^ZZ'), QQ)
sage: a = T.an_element(); a
B(1/2*x, x >= 42)
sage: cls, kwds = a.construction(); cls, kwds
(<class 'sage.rings.asymptotic.term_monoid.BTermMonoid_with_category.element_class'>,
 {'coefficient': 1/2,
  'growth': x,
  'parent': B-Term Monoid x^ZZ with coefficients in Rational Field,
  'valid_from': {'x': 42}})
sage: cls(**kwds) == a
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import TermMonoidFactory
>>> TermMonoid = TermMonoidFactory('__main__.TermMonoid')

>>> T = TermMonoid('B', GrowthGroup('x^ZZ'), QQ)
>>> a = T.an_element(); a
B(1/2*x, x >= 42)
>>> cls, kwds = a.construction(); cls, kwds
(<class 'sage.rings.asymptotic.term_monoid.BTermMonoid_with_category.element_class'>,
 {'coefficient': 1/2,
  'growth': x,
  'parent': B-Term Monoid x^ZZ with coefficients in Rational Field,
  'valid_from': {'x': 42}})
>>> cls(**kwds) == a
True
class sage.rings.asymptotic.term_monoid.BTermMonoid(term_monoid_factory, growth_group, coefficient_ring, category)[source]#

Bases: TermWithCoefficientMonoid

Parent for asymptotic B-terms.

INPUT:

  • growth_group – a growth group

  • coefficient_ring – the ring which contains the coefficients of the elements

  • category – The category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of Join of Category of monoids and Category of posets. This is also the default category if None is specified

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import MonomialGrowthGroup
sage: from sage.rings.asymptotic.term_monoid import BTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G = MonomialGrowthGroup(ZZ, 'x')
sage: BT = TermMonoid('B', G, QQ)
sage: BT
B-Term Monoid x^ZZ with coefficients in Rational Field
sage: BT is BTermMonoid(TermMonoid, G, QQ)
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import MonomialGrowthGroup
>>> from sage.rings.asymptotic.term_monoid import BTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G = MonomialGrowthGroup(ZZ, 'x')
>>> BT = TermMonoid('B', G, QQ)
>>> BT
B-Term Monoid x^ZZ with coefficients in Rational Field
>>> BT is BTermMonoid(TermMonoid, G, QQ)
True
Element[source]#

alias of BTerm

some_elements()[source]#

Return some elements of this B-term monoid.

See TestSuite for a typical use case.

INPUT:

Nothing.

OUTPUT:

An iterator.

EXAMPLES:

sage: from itertools import islice
sage: from sage.rings.asymptotic.term_monoid import TermMonoidFactory
sage: TermMonoid = TermMonoidFactory('__main__.TermMonoid')
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: G = GrowthGroup('z^QQ')
sage: T = TermMonoid('B', G, ZZ)
sage: tuple(islice(T.some_elements(), int(10)))
(B(z^(1/2), z >= 0),
 B(z^(-1/2), z >= 1),
 B(z^(1/2), z >= 3),
 B(z^2, z >= 42),
 B(z^(-1/2), z >= 0),
 B(2*z^(1/2), z >= 1),
 B(z^(-2), z >= 3),
 B(z^2, z >= 42),
 B(2*z^(-1/2), z >= 0),
 B(2*z^(1/2), z >= 1))
>>> from sage.all import *
>>> from itertools import islice
>>> from sage.rings.asymptotic.term_monoid import TermMonoidFactory
>>> TermMonoid = TermMonoidFactory('__main__.TermMonoid')
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> G = GrowthGroup('z^QQ')
>>> T = TermMonoid('B', G, ZZ)
>>> tuple(islice(T.some_elements(), int(Integer(10))))
(B(z^(1/2), z >= 0),
 B(z^(-1/2), z >= 1),
 B(z^(1/2), z >= 3),
 B(z^2, z >= 42),
 B(z^(-1/2), z >= 0),
 B(2*z^(1/2), z >= 1),
 B(z^(-2), z >= 3),
 B(z^2, z >= 42),
 B(2*z^(-1/2), z >= 0),
 B(2*z^(1/2), z >= 1))
sage.rings.asymptotic.term_monoid.DefaultTermMonoidFactory = Term Monoid Factory 'sage.rings.asymptotic.term_monoid.DefaultTermMonoidFactory'[source]#

A factory for asymptotic term monoids. This is an instance of TermMonoidFactory whose documentation provides more details.

class sage.rings.asymptotic.term_monoid.ExactTerm(parent, growth, coefficient)[source]#

Bases: TermWithCoefficient

Class for asymptotic exact terms. These terms primarily consist of an asymptotic growth element as well as a coefficient.

INPUT:

  • parent – the parent of the asymptotic term.

  • growth – an asymptotic growth element from parent.growth_group.

  • coefficient – an element from parent.coefficient_ring.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: from sage.rings.asymptotic.term_monoid import ExactTermMonoid
sage: G = GrowthGroup('x^ZZ'); x = G.gen()
sage: ET = ExactTermMonoid(TermMonoid, G, QQ)
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> from sage.rings.asymptotic.term_monoid import ExactTermMonoid
>>> G = GrowthGroup('x^ZZ'); x = G.gen()
>>> ET = ExactTermMonoid(TermMonoid, G, QQ)

Asymptotic exact terms may be multiplied (with the usual rules applying):

sage: ET(x^2, coefficient=3) * ET(x, coefficient=-1)
-3*x^3
sage: ET(x^0, coefficient=4) * ET(x^5, coefficient=2)
8*x^5
>>> from sage.all import *
>>> ET(x**Integer(2), coefficient=Integer(3)) * ET(x, coefficient=-Integer(1))
-3*x^3
>>> ET(x**Integer(0), coefficient=Integer(4)) * ET(x**Integer(5), coefficient=Integer(2))
8*x^5

They may also be multiplied with \(O\)-terms:

sage: OT = TermMonoid('O', G, QQ)
sage: ET(x^2, coefficient=42) * OT(x)
O(x^3)
>>> from sage.all import *
>>> OT = TermMonoid('O', G, QQ)
>>> ET(x**Integer(2), coefficient=Integer(42)) * OT(x)
O(x^3)

Absorption for asymptotic exact terms relates to addition:

sage: ET(x^2, coefficient=5).can_absorb(ET(x^5, coefficient=12))
False
sage: ET(x^2, coefficient=5).can_absorb(ET(x^2, coefficient=1))
True
sage: ET(x^2, coefficient=5).absorb(ET(x^2, coefficient=1))
6*x^2
>>> from sage.all import *
>>> ET(x**Integer(2), coefficient=Integer(5)).can_absorb(ET(x**Integer(5), coefficient=Integer(12)))
False
>>> ET(x**Integer(2), coefficient=Integer(5)).can_absorb(ET(x**Integer(2), coefficient=Integer(1)))
True
>>> ET(x**Integer(2), coefficient=Integer(5)).absorb(ET(x**Integer(2), coefficient=Integer(1)))
6*x^2

Note that, as for technical reasons, \(0\) is not allowed as a coefficient for an asymptotic term with coefficient. Instead None is returned if two asymptotic exact terms cancel out each other during absorption:

sage: ET(x^2, coefficient=42).can_absorb(ET(x^2, coefficient=-42))
True
sage: ET(x^2, coefficient=42).absorb(ET(x^2, coefficient=-42)) is None
True
>>> from sage.all import *
>>> ET(x**Integer(2), coefficient=Integer(42)).can_absorb(ET(x**Integer(2), coefficient=-Integer(42)))
True
>>> ET(x**Integer(2), coefficient=Integer(42)).absorb(ET(x**Integer(2), coefficient=-Integer(42))) is None
True

Exact terms can also be created by converting monomials with coefficient from the symbolic ring, or a suitable polynomial or power series ring:

sage: x = var('x'); x.parent()
Symbolic Ring
sage: ET(5*x^2)
5*x^2
>>> from sage.all import *
>>> x = var('x'); x.parent()
Symbolic Ring
>>> ET(Integer(5)*x**Integer(2))
5*x^2
can_absorb(other)[source]#

Check whether this exact term can absorb other.

INPUT:

  • other – an asymptotic term.

OUTPUT:

A boolean.

Note

For ExactTerm, absorption corresponds to addition. This means that an exact term can absorb only other exact terms with the same growth.

See the module description for a detailed explanation of absorption.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: ET = TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ)
sage: t1 = ET(x^21, coefficient=1); t2 = ET(x^21, coefficient=2); t3 = ET(x^42, coefficient=1)
sage: t1.can_absorb(t2)
True
sage: t2.can_absorb(t1)
True
sage: t1.can_absorb(t3) or t3.can_absorb(t1)
False
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> ET = TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ)
>>> t1 = ET(x**Integer(21), coefficient=Integer(1)); t2 = ET(x**Integer(21), coefficient=Integer(2)); t3 = ET(x**Integer(42), coefficient=Integer(1))
>>> t1.can_absorb(t2)
True
>>> t2.can_absorb(t1)
True
>>> t1.can_absorb(t3) or t3.can_absorb(t1)
False
is_constant()[source]#

Return whether this term is an (exact) constant.

INPUT:

Nothing.

OUTPUT:

A boolean.

Note

Only ExactTerm with constant growth (\(1\)) are constant.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('exact', GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
sage: T('x * log(x)').is_constant()
False
sage: T('3*x').is_constant()
False
sage: T(1/2).is_constant()
True
sage: T(42).is_constant()
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('exact', GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
>>> T('x * log(x)').is_constant()
False
>>> T('3*x').is_constant()
False
>>> T(Integer(1)/Integer(2)).is_constant()
True
>>> T(Integer(42)).is_constant()
True
is_exact()[source]#

Return whether this term is an exact term.

OUTPUT:

A boolean.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('exact', GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
sage: T('x * log(x)').is_exact()
True
sage: T('3 * x^2').is_exact()
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('exact', GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
>>> T('x * log(x)').is_exact()
True
>>> T('3 * x^2').is_exact()
True
is_little_o_of_one()[source]#

Return whether this exact term is of order \(o(1)\).

INPUT:

Nothing.

OUTPUT:

A boolean.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('exact', GrowthGroup('x^ZZ'), QQ)
sage: T(x).is_little_o_of_one()
False
sage: T(1).is_little_o_of_one()
False
sage: T(x^(-1)).is_little_o_of_one()
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('exact', GrowthGroup('x^ZZ'), QQ)
>>> T(x).is_little_o_of_one()
False
>>> T(Integer(1)).is_little_o_of_one()
False
>>> T(x**(-Integer(1))).is_little_o_of_one()
True
sage: T = TermMonoid('exact', GrowthGroup('x^ZZ * y^ZZ'), QQ)
sage: T('x * y^(-1)').is_little_o_of_one()
False
sage: T('x^(-1) * y').is_little_o_of_one()
False
sage: T('x^(-2) * y^(-3)').is_little_o_of_one()
True
>>> from sage.all import *
>>> T = TermMonoid('exact', GrowthGroup('x^ZZ * y^ZZ'), QQ)
>>> T('x * y^(-1)').is_little_o_of_one()
False
>>> T('x^(-1) * y').is_little_o_of_one()
False
>>> T('x^(-2) * y^(-3)').is_little_o_of_one()
True
sage: T = TermMonoid('exact', GrowthGroup('x^QQ * log(x)^QQ'), QQ)
sage: T('x * log(x)^2').is_little_o_of_one()
False
sage: T('x^2 * log(x)^(-1234)').is_little_o_of_one()
False
sage: T('x^(-1) * log(x)^4242').is_little_o_of_one()
True
sage: T('x^(-1/100) * log(x)^(1000/7)').is_little_o_of_one()
True
>>> from sage.all import *
>>> T = TermMonoid('exact', GrowthGroup('x^QQ * log(x)^QQ'), QQ)
>>> T('x * log(x)^2').is_little_o_of_one()
False
>>> T('x^2 * log(x)^(-1234)').is_little_o_of_one()
False
>>> T('x^(-1) * log(x)^4242').is_little_o_of_one()
True
>>> T('x^(-1/100) * log(x)^(1000/7)').is_little_o_of_one()
True
log_term(base=None, locals=None)[source]#

Determine the logarithm of this exact term.

INPUT:

  • base – the base of the logarithm. If None (default value) is used, the natural logarithm is taken.

  • locals – a dictionary which may contain the following keys and values:

    • 'log' – value: a function. If not used, then the usual log is taken.

OUTPUT:

A tuple of terms.

Note

This method returns a tuple with the summands that come from applying the rule \(\log(x\cdot y) = \log(x) + \log(y)\).

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('exact', GrowthGroup('x^ZZ * log(x)^ZZ'), SR)
sage: T(3*x^2).log_term()
(log(3), 2*log(x))
sage: T(x^1234).log_term()
(1234*log(x),)
sage: T(49*x^7).log_term(base=7)
(2, 7/log(7)*log(x))
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('exact', GrowthGroup('x^ZZ * log(x)^ZZ'), SR)
>>> T(Integer(3)*x**Integer(2)).log_term()
(log(3), 2*log(x))
>>> T(x**Integer(1234)).log_term()
(1234*log(x),)
>>> T(Integer(49)*x**Integer(7)).log_term(base=Integer(7))
(2, 7/log(7)*log(x))
sage: T = TermMonoid('exact', GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ'), SR)
sage: T('x * y').log_term()
(log(x), log(y))
sage: T('4 * x * y').log_term(base=2)
(2, 1/log(2)*log(x), 1/log(2)*log(y))
>>> from sage.all import *
>>> T = TermMonoid('exact', GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ'), SR)
>>> T('x * y').log_term()
(log(x), log(y))
>>> T('4 * x * y').log_term(base=Integer(2))
(2, 1/log(2)*log(x), 1/log(2)*log(y))

See also

OTerm.log_term().

rpow(base)[source]#

Return the power of base to this exact term.

INPUT:

  • base – an element or 'e'.

OUTPUT:

A term.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('exact', GrowthGroup('QQ^x * x^ZZ * log(x)^ZZ'), QQ)
sage: T('x').rpow(2)
2^x
sage: T('log(x)').rpow('e')
x
sage: T('42*log(x)').rpow('e')
x^42
sage: T('3*x').rpow(2)
8^x
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('exact', GrowthGroup('QQ^x * x^ZZ * log(x)^ZZ'), QQ)
>>> T('x').rpow(Integer(2))
2^x
>>> T('log(x)').rpow('e')
x
>>> T('42*log(x)').rpow('e')
x^42
>>> T('3*x').rpow(Integer(2))
8^x
sage: T('3*x^2').rpow(2)
Traceback (most recent call last):
...
ArithmeticError: Cannot construct 2^(x^2) in
Growth Group QQ^x * x^ZZ * log(x)^ZZ * Signs^x
> *previous* TypeError: unsupported operand parent(s) for *:
'Growth Group QQ^x * x^ZZ * log(x)^ZZ * Signs^x' and
'Growth Group ZZ^(x^2)'
>>> from sage.all import *
>>> T('3*x^2').rpow(Integer(2))
Traceback (most recent call last):
...
ArithmeticError: Cannot construct 2^(x^2) in
Growth Group QQ^x * x^ZZ * log(x)^ZZ * Signs^x
> *previous* TypeError: unsupported operand parent(s) for *:
'Growth Group QQ^x * x^ZZ * log(x)^ZZ * Signs^x' and
'Growth Group ZZ^(x^2)'
sage: T = TermMonoid('exact', GrowthGroup('(QQ_+)^n * n^QQ'), SR)
sage: n = T('n')
sage: n.rpow(2)
2^n
sage: _.parent()
Exact Term Monoid QQ^n * n^QQ with coefficients in Symbolic Ring
>>> from sage.all import *
>>> T = TermMonoid('exact', GrowthGroup('(QQ_+)^n * n^QQ'), SR)
>>> n = T('n')
>>> n.rpow(Integer(2))
2^n
>>> _.parent()
Exact Term Monoid QQ^n * n^QQ with coefficients in Symbolic Ring
class sage.rings.asymptotic.term_monoid.ExactTermMonoid(term_monoid_factory, growth_group, coefficient_ring, category)[source]#

Bases: TermWithCoefficientMonoid

Parent for asymptotic exact terms, implemented in ExactTerm.

INPUT:

  • growth_group – a growth group.

  • category – The category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of Join of Category of monoids and Category of posets. This is also the default category if None is specified.

  • coefficient_ring – the ring which contains the coefficients of the elements.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import ExactTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G_ZZ = GrowthGroup('x^ZZ'); x_ZZ = G_ZZ.gen()
sage: G_QQ = GrowthGroup('x^QQ'); x_QQ = G_QQ.gen()
sage: ET_ZZ = ExactTermMonoid(TermMonoid, G_ZZ, ZZ); ET_ZZ
Exact Term Monoid x^ZZ with coefficients in Integer Ring
sage: ET_QQ = ExactTermMonoid(TermMonoid, G_QQ, QQ); ET_QQ
Exact Term Monoid x^QQ with coefficients in Rational Field
sage: ET_QQ.coerce_map_from(ET_ZZ)
Coercion map:
  From: Exact Term Monoid x^ZZ with coefficients in Integer Ring
  To:   Exact Term Monoid x^QQ with coefficients in Rational Field
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import ExactTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G_ZZ = GrowthGroup('x^ZZ'); x_ZZ = G_ZZ.gen()
>>> G_QQ = GrowthGroup('x^QQ'); x_QQ = G_QQ.gen()
>>> ET_ZZ = ExactTermMonoid(TermMonoid, G_ZZ, ZZ); ET_ZZ
Exact Term Monoid x^ZZ with coefficients in Integer Ring
>>> ET_QQ = ExactTermMonoid(TermMonoid, G_QQ, QQ); ET_QQ
Exact Term Monoid x^QQ with coefficients in Rational Field
>>> ET_QQ.coerce_map_from(ET_ZZ)
Coercion map:
  From: Exact Term Monoid x^ZZ with coefficients in Integer Ring
  To:   Exact Term Monoid x^QQ with coefficients in Rational Field

Exact term monoids can also be created using the term factory:

sage: TermMonoid('exact', G_ZZ, ZZ) is ET_ZZ
True
sage: TermMonoid('exact', GrowthGroup('x^ZZ'), QQ)
Exact Term Monoid x^ZZ with coefficients in Rational Field
>>> from sage.all import *
>>> TermMonoid('exact', G_ZZ, ZZ) is ET_ZZ
True
>>> TermMonoid('exact', GrowthGroup('x^ZZ'), QQ)
Exact Term Monoid x^ZZ with coefficients in Rational Field
Element[source]#

alias of ExactTerm

class sage.rings.asymptotic.term_monoid.GenericTerm(parent, growth)[source]#

Bases: MultiplicativeGroupElement

Base class for asymptotic terms. Mainly the structure and several properties of asymptotic terms are handled here.

INPUT:

  • parent – the parent of the asymptotic term.

  • growth – an asymptotic growth element.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G = GrowthGroup('x^ZZ'); x = G.gen()
sage: T = GenericTermMonoid(TermMonoid, G, QQ)
sage: t1 = T(x); t2 = T(x^2); (t1, t2)
(Generic Term with growth x, Generic Term with growth x^2)
sage: t1 * t2
Generic Term with growth x^3
sage: t1.can_absorb(t2)
False
sage: t1.absorb(t2)
Traceback (most recent call last):
...
ArithmeticError: Generic Term with growth x cannot absorb Generic Term with growth x^2
sage: t1.can_absorb(t1)
False
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G = GrowthGroup('x^ZZ'); x = G.gen()
>>> T = GenericTermMonoid(TermMonoid, G, QQ)
>>> t1 = T(x); t2 = T(x**Integer(2)); (t1, t2)
(Generic Term with growth x, Generic Term with growth x^2)
>>> t1 * t2
Generic Term with growth x^3
>>> t1.can_absorb(t2)
False
>>> t1.absorb(t2)
Traceback (most recent call last):
...
ArithmeticError: Generic Term with growth x cannot absorb Generic Term with growth x^2
>>> t1.can_absorb(t1)
False
absorb(other, check=True)[source]#

Absorb the asymptotic term other and return the resulting asymptotic term.

INPUT:

  • other – an asymptotic term.

  • check – a boolean. If check is True (default), then can_absorb is called before absorption.

OUTPUT:

An asymptotic term or None if a cancellation occurs. If no absorption can be performed, an ArithmeticError is raised.

Note

Setting check to False is meant to be used in cases where the respective comparison is done externally (in order to avoid duplicate checking).

For a more detailed explanation of the absorption of asymptotic terms see the module description.

EXAMPLES:

We want to demonstrate in which cases an asymptotic term is able to absorb another term, as well as explain the output of this operation. We start by defining some parents and elements:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: G_QQ = GrowthGroup('x^QQ'); x = G_QQ.gen()
sage: OT = TermMonoid('O', G_QQ, coefficient_ring=QQ)
sage: ET = TermMonoid('exact', G_QQ, coefficient_ring=QQ)
sage: ot1 = OT(x); ot2 = OT(x^2)
sage: et1 = ET(x, coefficient=100); et2 = ET(x^2, coefficient=2)
sage: et3 = ET(x^2, coefficient=1); et4 = ET(x^2, coefficient=-2)
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> G_QQ = GrowthGroup('x^QQ'); x = G_QQ.gen()
>>> OT = TermMonoid('O', G_QQ, coefficient_ring=QQ)
>>> ET = TermMonoid('exact', G_QQ, coefficient_ring=QQ)
>>> ot1 = OT(x); ot2 = OT(x**Integer(2))
>>> et1 = ET(x, coefficient=Integer(100)); et2 = ET(x**Integer(2), coefficient=Integer(2))
>>> et3 = ET(x**Integer(2), coefficient=Integer(1)); et4 = ET(x**Integer(2), coefficient=-Integer(2))

\(O\)-Terms are able to absorb other \(O\)-terms and exact terms with weaker or equal growth.

sage: ot1.absorb(ot1)
O(x)
sage: ot1.absorb(et1)
O(x)
sage: ot1.absorb(et1) is ot1
True
>>> from sage.all import *
>>> ot1.absorb(ot1)
O(x)
>>> ot1.absorb(et1)
O(x)
>>> ot1.absorb(et1) is ot1
True

ExactTerm is able to absorb another ExactTerm if the terms have the same growth. In this case, absorption is nothing else than an addition of the respective coefficients:

sage: et2.absorb(et3)
3*x^2
sage: et3.absorb(et2)
3*x^2
sage: et3.absorb(et4)
-x^2
>>> from sage.all import *
>>> et2.absorb(et3)
3*x^2
>>> et3.absorb(et2)
3*x^2
>>> et3.absorb(et4)
-x^2

Note that, for technical reasons, the coefficient \(0\) is not allowed, and thus None is returned if two exact terms cancel each other out:

sage: et2.absorb(et4)
sage: et4.absorb(et2) is None
True
>>> from sage.all import *
>>> et2.absorb(et4)
>>> et4.absorb(et2) is None
True
can_absorb(other)[source]#

Check whether this asymptotic term is able to absorb the asymptotic term other.

INPUT:

  • other – an asymptotic term.

OUTPUT:

A boolean.

Note

A GenericTerm cannot absorb any other term.

See the module description for a detailed explanation of absorption.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GenericGrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G = GenericGrowthGroup(ZZ)
sage: T = GenericTermMonoid(TermMonoid, G, QQ)
sage: g1 = G(raw_element=21); g2 = G(raw_element=42)
sage: t1 = T(g1); t2 = T(g2)
sage: t1.can_absorb(t2)  # indirect doctest
False
sage: t2.can_absorb(t1)  # indirect doctest
False
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GenericGrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G = GenericGrowthGroup(ZZ)
>>> T = GenericTermMonoid(TermMonoid, G, QQ)
>>> g1 = G(raw_element=Integer(21)); g2 = G(raw_element=Integer(42))
>>> t1 = T(g1); t2 = T(g2)
>>> t1.can_absorb(t2)  # indirect doctest
False
>>> t2.can_absorb(t1)  # indirect doctest
False
construction()[source]#

Return a construction of this term.

INPUT:

Nothing.

OUTPUT:

A pair (cls, kwds) such that cls(**kwds) equals this term.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: T = TermMonoid('O', GrowthGroup('x^ZZ'), QQ)
sage: a = T.an_element(); a
O(x)
sage: cls, kwds = a.construction(); cls, kwds
(<class 'sage.rings.asymptotic.term_monoid.OTermMonoid_with_category.element_class'>,
{'growth': x,
 'parent': O-Term Monoid x^ZZ with implicit coefficients in Rational Field})
sage: cls(**kwds) == a
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> T = TermMonoid('O', GrowthGroup('x^ZZ'), QQ)
>>> a = T.an_element(); a
O(x)
>>> cls, kwds = a.construction(); cls, kwds
(<class 'sage.rings.asymptotic.term_monoid.OTermMonoid_with_category.element_class'>,
{'growth': x,
 'parent': O-Term Monoid x^ZZ with implicit coefficients in Rational Field})
>>> cls(**kwds) == a
True
is_constant()[source]#

Return whether this term is an (exact) constant.

INPUT:

Nothing.

OUTPUT:

A boolean.

Note

Only ExactTerm with constant growth (\(1\)) are constant.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
sage: t = T.an_element(); t
Generic Term with growth x*log(x)
sage: t.is_constant()
False
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
>>> t = T.an_element(); t
Generic Term with growth x*log(x)
>>> t.is_constant()
False
sage: T = TermMonoid('O', GrowthGroup('x^ZZ'), QQ)
sage: T('x').is_constant()
False
sage: T(1).is_constant()
False
>>> from sage.all import *
>>> T = TermMonoid('O', GrowthGroup('x^ZZ'), QQ)
>>> T('x').is_constant()
False
>>> T(Integer(1)).is_constant()
False
is_exact()[source]#

Return whether this term is an exact term.

OUTPUT:

A boolean.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
sage: T.an_element().is_exact()
False
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
>>> T.an_element().is_exact()
False
is_little_o_of_one()[source]#

Return whether this generic term is of order \(o(1)\).

INPUT:

Nothing.

OUTPUT:

A boolean.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import (GenericTermMonoid,
....:                                                TermWithCoefficientMonoid)
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ'), QQ)
sage: T.an_element().is_little_o_of_one()
Traceback (most recent call last):
...
NotImplementedError: Cannot check whether Generic Term with growth x is o(1)
in the abstract base class
GenericTerm Monoid x^ZZ with (implicit) coefficients in Rational Field.
sage: T = TermWithCoefficientMonoid(TermMonoid, GrowthGroup('x^ZZ'), QQ)
sage: T.an_element().is_little_o_of_one()
Traceback (most recent call last):
...
NotImplementedError: Cannot check whether Term with coefficient 1/2 and growth x
is o(1) in the abstract base class
TermWithCoefficient Monoid x^ZZ with coefficients in Rational Field.
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import (GenericTermMonoid,
...                                                TermWithCoefficientMonoid)
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ'), QQ)
>>> T.an_element().is_little_o_of_one()
Traceback (most recent call last):
...
NotImplementedError: Cannot check whether Generic Term with growth x is o(1)
in the abstract base class
GenericTerm Monoid x^ZZ with (implicit) coefficients in Rational Field.
>>> T = TermWithCoefficientMonoid(TermMonoid, GrowthGroup('x^ZZ'), QQ)
>>> T.an_element().is_little_o_of_one()
Traceback (most recent call last):
...
NotImplementedError: Cannot check whether Term with coefficient 1/2 and growth x
is o(1) in the abstract base class
TermWithCoefficient Monoid x^ZZ with coefficients in Rational Field.
log_term(base=None, locals=None)[source]#

Determine the logarithm of this term.

INPUT:

  • base – the base of the logarithm. If None (default value) is used, the natural logarithm is taken.

  • locals – a dictionary which may contain the following keys and values:

    • 'log' – value: a function. If not used, then the usual log is taken.

OUTPUT:

A tuple of terms.

Note

This abstract method raises a NotImplementedError. See ExactTerm and OTerm for a concrete implementation.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ'), QQ)
sage: T.an_element().log_term()
Traceback (most recent call last):
...
NotImplementedError: This method is not implemented in
this abstract base class.
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ'), QQ)
>>> T.an_element().log_term()
Traceback (most recent call last):
...
NotImplementedError: This method is not implemented in
this abstract base class.
sage: from sage.rings.asymptotic.term_monoid import TermWithCoefficientMonoid
sage: T = TermWithCoefficientMonoid(TermMonoid, GrowthGroup('x^ZZ'), QQ)
sage: T.an_element().log_term()
Traceback (most recent call last):
...
NotImplementedError: This method is not implemented in
this abstract base class.
>>> from sage.all import *
>>> from sage.rings.asymptotic.term_monoid import TermWithCoefficientMonoid
>>> T = TermWithCoefficientMonoid(TermMonoid, GrowthGroup('x^ZZ'), QQ)
>>> T.an_element().log_term()
Traceback (most recent call last):
...
NotImplementedError: This method is not implemented in
this abstract base class.
rpow(base)[source]#

Return the power of base to this generic term.

INPUT:

  • base – an element or 'e'.

OUTPUT:

A term.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
sage: T.an_element().rpow('e')
Traceback (most recent call last):
...
NotImplementedError: Cannot take e to the exponent
Generic Term with growth x*log(x) in the abstract base class
GenericTerm Monoid x^ZZ * log(x)^ZZ with (implicit) coefficients in Rational Field.
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> T = GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
>>> T.an_element().rpow('e')
Traceback (most recent call last):
...
NotImplementedError: Cannot take e to the exponent
Generic Term with growth x*log(x) in the abstract base class
GenericTerm Monoid x^ZZ * log(x)^ZZ with (implicit) coefficients in Rational Field.
variable_names()[source]#

Return the names of the variables of this term.

OUTPUT:

A tuple of strings.

EXAMPLES:

sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('exact', 'QQ^m * m^QQ * log(n)^ZZ', QQ)
sage: T('4 * 2^m * m^4 * log(n)').variable_names()
('m', 'n')
sage: T('4 * 2^m * m^4').variable_names()
('m',)
sage: T('4 * log(n)').variable_names()
('n',)
sage: T('4 * m^3').variable_names()
('m',)
sage: T('4 * m^0').variable_names()
()
>>> from sage.all import *
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('exact', 'QQ^m * m^QQ * log(n)^ZZ', QQ)
>>> T('4 * 2^m * m^4 * log(n)').variable_names()
('m', 'n')
>>> T('4 * 2^m * m^4').variable_names()
('m',)
>>> T('4 * log(n)').variable_names()
('n',)
>>> T('4 * m^3').variable_names()
('m',)
>>> T('4 * m^0').variable_names()
()
class sage.rings.asymptotic.term_monoid.GenericTermMonoid(term_monoid_factory, growth_group, coefficient_ring, category)[source]#

Bases: UniqueRepresentation, Parent, WithLocals

Parent for generic asymptotic terms.

INPUT:

  • growth_group – a growth group (i.e. an instance of GenericGrowthGroup).

  • coefficient_ring – a ring which contains the (maybe implicit) coefficients of the elements.

  • category – The category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of Join of Category of Monoids and Category of posets. This is also the default category if None is specified.

In this class the base structure for asymptotic term monoids will be handled. These monoids are the parents of asymptotic terms (for example, see GenericTerm or OTerm). Basically, asymptotic terms consist of a growth (which is an asymptotic growth group element, for example MonomialGrowthElement); additional structure and properties are added by the classes inherited from GenericTermMonoid.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G_x = GrowthGroup('x^ZZ'); x = G_x.gen()
sage: G_y = GrowthGroup('y^QQ'); y = G_y.gen()
sage: T_x_ZZ = GenericTermMonoid(TermMonoid, G_x, QQ)
sage: T_y_QQ = GenericTermMonoid(TermMonoid, G_y, QQ)
sage: T_x_ZZ
GenericTerm Monoid x^ZZ with (implicit) coefficients in Rational Field
sage: T_y_QQ
GenericTerm Monoid y^QQ with (implicit) coefficients in Rational Field
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G_x = GrowthGroup('x^ZZ'); x = G_x.gen()
>>> G_y = GrowthGroup('y^QQ'); y = G_y.gen()
>>> T_x_ZZ = GenericTermMonoid(TermMonoid, G_x, QQ)
>>> T_y_QQ = GenericTermMonoid(TermMonoid, G_y, QQ)
>>> T_x_ZZ
GenericTerm Monoid x^ZZ with (implicit) coefficients in Rational Field
>>> T_y_QQ
GenericTerm Monoid y^QQ with (implicit) coefficients in Rational Field
Element[source]#

alias of GenericTerm

change_parameter(growth_group=None, coefficient_ring=None)[source]#

Return a term monoid with a change in one or more of the given parameters.

INPUT:

  • growth_group – (default: None) the new growth group.

  • coefficient_ring – (default: None) the new coefficient ring.

OUTPUT:

A term monoid.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: E = TermMonoid('exact', GrowthGroup('n^ZZ'), ZZ)
sage: E.change_parameter(coefficient_ring=QQ)
Exact Term Monoid n^ZZ with coefficients in Rational Field
sage: E.change_parameter(growth_group=GrowthGroup('n^QQ'))
Exact Term Monoid n^QQ with coefficients in Integer Ring
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> E = TermMonoid('exact', GrowthGroup('n^ZZ'), ZZ)
>>> E.change_parameter(coefficient_ring=QQ)
Exact Term Monoid n^ZZ with coefficients in Rational Field
>>> E.change_parameter(growth_group=GrowthGroup('n^QQ'))
Exact Term Monoid n^QQ with coefficients in Integer Ring
property coefficient_ring#

The coefficient ring of this term monoid, i.e. the ring where the coefficients are from.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ'), ZZ).coefficient_ring
Integer Ring
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> GenericTermMonoid(TermMonoid, GrowthGroup('x^ZZ'), ZZ).coefficient_ring
Integer Ring
from_construction(construction, **kwds_overrides)[source]#

Create a term from the construction of another term.

INPUT:

  • construction – a pair (cls, kwds_construction)

  • kwds_overrides – a dictionary

OUTPUT:

A term.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: G = GrowthGroup('x^ZZ')
sage: x = G.gen()
sage: T = TermMonoid('O', G, QQ)
sage: o = T.an_element()
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> G = GrowthGroup('x^ZZ')
>>> x = G.gen()
>>> T = TermMonoid('O', G, QQ)
>>> o = T.an_element()

We use a construction directly as input:

sage: T.from_construction(o.construction())
O(x)
>>> from sage.all import *
>>> T.from_construction(o.construction())
O(x)

We can override the given data:

sage: T.from_construction(o.construction(), growth=x^2)
O(x^2)
>>> from sage.all import *
>>> T.from_construction(o.construction(), growth=x**Integer(2))
O(x^2)

A minimalistic example:

sage: T.from_construction((None, {'growth': x}))
O(x)
>>> from sage.all import *
>>> T.from_construction((None, {'growth': x}))
O(x)
property growth_group#

The growth group underlying this term monoid.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ).growth_group
Growth Group x^ZZ
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ).growth_group
Growth Group x^ZZ
le(left, right)[source]#

Return whether the term left is at most (less than or equal to) the term right.

INPUT:

  • left – an element.

  • right – an element.

OUTPUT:

A boolean.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G = GrowthGroup('x^ZZ'); x = G.gen()
sage: T = GenericTermMonoid(TermMonoid, G, QQ)
sage: t1 = T(x); t2 = T(x^2)
sage: T.le(t1, t2)
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import GenericTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G = GrowthGroup('x^ZZ'); x = G.gen()
>>> T = GenericTermMonoid(TermMonoid, G, QQ)
>>> t1 = T(x); t2 = T(x**Integer(2))
>>> T.le(t1, t2)
True
some_elements()[source]#

Return some elements of this term monoid.

See TestSuite for a typical use case.

INPUT:

Nothing.

OUTPUT:

An iterator.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: G = GrowthGroup('x^ZZ')
sage: tuple(TermMonoid('O', G, QQ).some_elements())
(O(1), O(x), O(x^(-1)), O(x^2), O(x^(-2)), O(x^3), ...)
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> G = GrowthGroup('x^ZZ')
>>> tuple(TermMonoid('O', G, QQ).some_elements())
(O(1), O(x), O(x^(-1)), O(x^2), O(x^(-2)), O(x^3), ...)
term_monoid(type)[source]#

Return the term monoid of specified type.

INPUT:

  • type – ‘O’ or ‘exact’, or an instance of an existing term monoid. See TermMonoidFactory for more details.

OUTPUT:

A term monoid object derived from GenericTermMonoid.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: E = TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ); E
Exact Term Monoid x^ZZ with coefficients in Integer Ring
sage: E.term_monoid('O')
O-Term Monoid x^ZZ with implicit coefficients in Integer Ring
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> E = TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ); E
Exact Term Monoid x^ZZ with coefficients in Integer Ring
>>> E.term_monoid('O')
O-Term Monoid x^ZZ with implicit coefficients in Integer Ring
property term_monoid_factory#

The term monoid factory capable of creating this term monoid.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup

sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory
sage: DefaultTermMonoidFactory('exact', GrowthGroup('x^ZZ'), ZZ).term_monoid_factory
Term Monoid Factory 'sage.rings.asymptotic.term_monoid.DefaultTermMonoidFactory'

sage: from sage.rings.asymptotic.term_monoid import TermMonoidFactory
sage: TermMonoid = TermMonoidFactory('__main__.TermMonoid')

sage: TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ).term_monoid_factory
Term Monoid Factory '__main__.TermMonoid'
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup

>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory
>>> DefaultTermMonoidFactory('exact', GrowthGroup('x^ZZ'), ZZ).term_monoid_factory
Term Monoid Factory 'sage.rings.asymptotic.term_monoid.DefaultTermMonoidFactory'

>>> from sage.rings.asymptotic.term_monoid import TermMonoidFactory
>>> TermMonoid = TermMonoidFactory('__main__.TermMonoid')

>>> TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ).term_monoid_factory
Term Monoid Factory '__main__.TermMonoid'
class sage.rings.asymptotic.term_monoid.OTerm(parent, growth)[source]#

Bases: GenericTerm

Class for an asymptotic term representing an \(O\)-term with specified growth. For the mathematical properties of \(O\)-terms see Wikipedia article Big_O_Notation.

\(O\)-terms can absorb terms of weaker or equal growth.

INPUT:

  • parent – the parent of the asymptotic term.

  • growth – a growth element.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import OTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G = GrowthGroup('x^ZZ'); x = G.gen()
sage: OT = OTermMonoid(TermMonoid, G, QQ)
sage: t1 = OT(x^-7); t2 = OT(x^5); t3 = OT(x^42)
sage: t1, t2, t3
(O(x^(-7)), O(x^5), O(x^42))
sage: t1.can_absorb(t2)
False
sage: t2.can_absorb(t1)
True
sage: t2.absorb(t1)
O(x^5)
sage: t1 <= t2 and t2 <= t3
True
sage: t3 <= t1
False
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import OTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G = GrowthGroup('x^ZZ'); x = G.gen()
>>> OT = OTermMonoid(TermMonoid, G, QQ)
>>> t1 = OT(x**-Integer(7)); t2 = OT(x**Integer(5)); t3 = OT(x**Integer(42))
>>> t1, t2, t3
(O(x^(-7)), O(x^5), O(x^42))
>>> t1.can_absorb(t2)
False
>>> t2.can_absorb(t1)
True
>>> t2.absorb(t1)
O(x^5)
>>> t1 <= t2 and t2 <= t3
True
>>> t3 <= t1
False

The conversion of growth elements also works for the creation of \(O\)-terms:

sage: x = SR('x'); x.parent()
Symbolic Ring
sage: OT(x^17)
O(x^17)
>>> from sage.all import *
>>> x = SR('x'); x.parent()
Symbolic Ring
>>> OT(x**Integer(17))
O(x^17)
can_absorb(other)[source]#

Check whether this \(O\)-term can absorb other.

INPUT:

  • other – an asymptotic term.

OUTPUT:

A boolean.

Note

An OTerm can absorb any other asymptotic term with weaker or equal growth.

See the module description for a detailed explanation of absorption.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: OT = TermMonoid('O', GrowthGroup('x^ZZ'), QQ)
sage: t1 = OT(x^21); t2 = OT(x^42)
sage: t1.can_absorb(t2)
False
sage: t2.can_absorb(t1)
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> OT = TermMonoid('O', GrowthGroup('x^ZZ'), QQ)
>>> t1 = OT(x**Integer(21)); t2 = OT(x**Integer(42))
>>> t1.can_absorb(t2)
False
>>> t2.can_absorb(t1)
True
is_little_o_of_one()[source]#

Return whether this O-term is of order \(o(1)\).

INPUT:

Nothing.

OUTPUT:

A boolean.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('O', GrowthGroup('x^ZZ'), QQ)
sage: T(x).is_little_o_of_one()
False
sage: T(1).is_little_o_of_one()
False
sage: T(x^(-1)).is_little_o_of_one()
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('O', GrowthGroup('x^ZZ'), QQ)
>>> T(x).is_little_o_of_one()
False
>>> T(Integer(1)).is_little_o_of_one()
False
>>> T(x**(-Integer(1))).is_little_o_of_one()
True
sage: T = TermMonoid('O', GrowthGroup('x^ZZ * y^ZZ'), QQ)
sage: T('x * y^(-1)').is_little_o_of_one()
False
sage: T('x^(-1) * y').is_little_o_of_one()
False
sage: T('x^(-2) * y^(-3)').is_little_o_of_one()
True
>>> from sage.all import *
>>> T = TermMonoid('O', GrowthGroup('x^ZZ * y^ZZ'), QQ)
>>> T('x * y^(-1)').is_little_o_of_one()
False
>>> T('x^(-1) * y').is_little_o_of_one()
False
>>> T('x^(-2) * y^(-3)').is_little_o_of_one()
True
sage: T = TermMonoid('O', GrowthGroup('x^QQ * log(x)^QQ'), QQ)
sage: T('x * log(x)^2').is_little_o_of_one()
False
sage: T('x^2 * log(x)^(-1234)').is_little_o_of_one()
False
sage: T('x^(-1) * log(x)^4242').is_little_o_of_one()
True
sage: T('x^(-1/100) * log(x)^(1000/7)').is_little_o_of_one()
True
>>> from sage.all import *
>>> T = TermMonoid('O', GrowthGroup('x^QQ * log(x)^QQ'), QQ)
>>> T('x * log(x)^2').is_little_o_of_one()
False
>>> T('x^2 * log(x)^(-1234)').is_little_o_of_one()
False
>>> T('x^(-1) * log(x)^4242').is_little_o_of_one()
True
>>> T('x^(-1/100) * log(x)^(1000/7)').is_little_o_of_one()
True
log_term(base=None, locals=None)[source]#

Determine the logarithm of this O-term.

INPUT:

  • base – the base of the logarithm. If None (default value) is used, the natural logarithm is taken.

  • locals – a dictionary which may contain the following keys and values:

    • 'log' – value: a function. If not used, then the usual log is taken.

OUTPUT:

A tuple of terms.

Note

This method returns a tuple with the summands that come from applying the rule \(\log(x\cdot y) = \log(x) + \log(y)\).

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('O', GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
sage: T(x^2).log_term()
(O(log(x)),)
sage: T(x^1234).log_term()
(O(log(x)),)
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('O', GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
>>> T(x**Integer(2)).log_term()
(O(log(x)),)
>>> T(x**Integer(1234)).log_term()
(O(log(x)),)
sage: from sage.rings.asymptotic.term_monoid import TermWithCoefficientMonoid
sage: T = TermMonoid('O', GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ'), QQ)
sage: T('x * y').log_term()
(O(log(x)), O(log(y)))
>>> from sage.all import *
>>> from sage.rings.asymptotic.term_monoid import TermWithCoefficientMonoid
>>> T = TermMonoid('O', GrowthGroup('x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ'), QQ)
>>> T('x * y').log_term()
(O(log(x)), O(log(y)))
rpow(base)[source]#

Return the power of base to this O-term.

INPUT:

  • base – an element or 'e'.

OUTPUT:

A term.

Note

For OTerm, the powers can only be constructed for exponents \(O(1)\) or if base is \(1\).

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: T = TermMonoid('O', GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
sage: T(1).rpow('e')
O(1)
sage: T(1).rpow(2)
O(1)
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> T = TermMonoid('O', GrowthGroup('x^ZZ * log(x)^ZZ'), QQ)
>>> T(Integer(1)).rpow('e')
O(1)
>>> T(Integer(1)).rpow(Integer(2))
O(1)
sage: T.an_element().rpow(1)
1
sage: T('x^2').rpow(1)
1
>>> from sage.all import *
>>> T.an_element().rpow(Integer(1))
1
>>> T('x^2').rpow(Integer(1))
1
sage: T.an_element().rpow('e')
Traceback (most recent call last):
...
ValueError: Cannot take e to the exponent O(x*log(x)) in
O-Term Monoid x^ZZ * log(x)^ZZ with implicit coefficients in Rational Field
sage: T('log(x)').rpow('e')
Traceback (most recent call last):
...
ValueError: Cannot take e to the exponent O(log(x)) in
O-Term Monoid x^ZZ * log(x)^ZZ with implicit coefficients in Rational Field
>>> from sage.all import *
>>> T.an_element().rpow('e')
Traceback (most recent call last):
...
ValueError: Cannot take e to the exponent O(x*log(x)) in
O-Term Monoid x^ZZ * log(x)^ZZ with implicit coefficients in Rational Field
>>> T('log(x)').rpow('e')
Traceback (most recent call last):
...
ValueError: Cannot take e to the exponent O(log(x)) in
O-Term Monoid x^ZZ * log(x)^ZZ with implicit coefficients in Rational Field
class sage.rings.asymptotic.term_monoid.OTermMonoid(term_monoid_factory, growth_group, coefficient_ring, category)[source]#

Bases: GenericTermMonoid

Parent for asymptotic big \(O\)-terms.

INPUT:

  • growth_group – a growth group.

  • category – The category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of Join of Category of monoids and Category of posets. This is also the default category if None is specified.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import OTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: G_x_ZZ = GrowthGroup('x^ZZ')
sage: G_y_QQ = GrowthGroup('y^QQ')
sage: OT_x_ZZ = OTermMonoid(TermMonoid, G_x_ZZ, QQ); OT_x_ZZ
O-Term Monoid x^ZZ with implicit coefficients in Rational Field
sage: OT_y_QQ = OTermMonoid(TermMonoid, G_y_QQ, QQ); OT_y_QQ
O-Term Monoid y^QQ with implicit coefficients in Rational Field
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import OTermMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> G_x_ZZ = GrowthGroup('x^ZZ')
>>> G_y_QQ = GrowthGroup('y^QQ')
>>> OT_x_ZZ = OTermMonoid(TermMonoid, G_x_ZZ, QQ); OT_x_ZZ
O-Term Monoid x^ZZ with implicit coefficients in Rational Field
>>> OT_y_QQ = OTermMonoid(TermMonoid, G_y_QQ, QQ); OT_y_QQ
O-Term Monoid y^QQ with implicit coefficients in Rational Field

\(O\)-term monoids can also be created by using the term factory:

sage: TermMonoid('O', G_x_ZZ, QQ) is OT_x_ZZ
True
sage: TermMonoid('O', GrowthGroup('x^QQ'), QQ)
O-Term Monoid x^QQ with implicit coefficients in Rational Field
>>> from sage.all import *
>>> TermMonoid('O', G_x_ZZ, QQ) is OT_x_ZZ
True
>>> TermMonoid('O', GrowthGroup('x^QQ'), QQ)
O-Term Monoid x^QQ with implicit coefficients in Rational Field
Element[source]#

alias of OTerm

class sage.rings.asymptotic.term_monoid.TermMonoidFactory(name, exact_term_monoid_class=None, O_term_monoid_class=None, B_term_monoid_class=None)[source]#

Bases: UniqueRepresentation, UniqueFactory

Factory for asymptotic term monoids. It can generate the following term monoids:

Note

An instance of this factory is available as DefaultTermMonoidFactory.

INPUT:

  • term_monoid – the kind of terms held in the new term monoid. Either a string 'exact', 'O' (capital letter O) or 'B' or an existing instance of a term monoid.

  • growth_group – a growth group or a string describing a growth group.

  • coefficient_ring – a ring.

  • asymptotic_ring – if specified, then growth_group and coefficient_ring are taken from this asymptotic ring.

OUTPUT:

An asymptotic term monoid.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: G = GrowthGroup('x^ZZ')
sage: TermMonoid('O', G, QQ)
O-Term Monoid x^ZZ with implicit coefficients in Rational Field
sage: TermMonoid('exact', G, ZZ)
Exact Term Monoid x^ZZ with coefficients in Integer Ring
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> G = GrowthGroup('x^ZZ')
>>> TermMonoid('O', G, QQ)
O-Term Monoid x^ZZ with implicit coefficients in Rational Field
>>> TermMonoid('exact', G, ZZ)
Exact Term Monoid x^ZZ with coefficients in Integer Ring
sage: R = AsymptoticRing(growth_group=G, coefficient_ring=QQ)
sage: TermMonoid('exact', asymptotic_ring=R)
Exact Term Monoid x^ZZ with coefficients in Rational Field
sage: TermMonoid('O', asymptotic_ring=R)
O-Term Monoid x^ZZ with implicit coefficients in Rational Field

sage: TermMonoid('exact', 'QQ^m * m^QQ * log(n)^ZZ', ZZ)
Exact Term Monoid QQ^m * m^QQ * Signs^m * log(n)^ZZ
with coefficients in Integer Ring
>>> from sage.all import *
>>> R = AsymptoticRing(growth_group=G, coefficient_ring=QQ)
>>> TermMonoid('exact', asymptotic_ring=R)
Exact Term Monoid x^ZZ with coefficients in Rational Field
>>> TermMonoid('O', asymptotic_ring=R)
O-Term Monoid x^ZZ with implicit coefficients in Rational Field

>>> TermMonoid('exact', 'QQ^m * m^QQ * log(n)^ZZ', ZZ)
Exact Term Monoid QQ^m * m^QQ * Signs^m * log(n)^ZZ
with coefficients in Integer Ring
create_key_and_extra_args(term_monoid, growth_group=None, coefficient_ring=None, asymptotic_ring=None, **kwds)[source]#

Given the arguments and keyword, create a key that uniquely determines this object.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: G = GrowthGroup('x^ZZ')
sage: TermMonoid.create_key_and_extra_args('O', G, QQ)
((<class 'sage.rings.asymptotic.term_monoid.OTermMonoid'>,
  Growth Group x^ZZ, Rational Field), {})
sage: TermMonoid.create_key_and_extra_args('exact', G, ZZ)
((<class 'sage.rings.asymptotic.term_monoid.ExactTermMonoid'>,
  Growth Group x^ZZ, Integer Ring), {})
sage: TermMonoid.create_key_and_extra_args('exact', G)
Traceback (most recent call last):
...
ValueError: A coefficient ring has to be specified
to create a term monoid of type 'exact'
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> G = GrowthGroup('x^ZZ')
>>> TermMonoid.create_key_and_extra_args('O', G, QQ)
((<class 'sage.rings.asymptotic.term_monoid.OTermMonoid'>,
  Growth Group x^ZZ, Rational Field), {})
>>> TermMonoid.create_key_and_extra_args('exact', G, ZZ)
((<class 'sage.rings.asymptotic.term_monoid.ExactTermMonoid'>,
  Growth Group x^ZZ, Integer Ring), {})
>>> TermMonoid.create_key_and_extra_args('exact', G)
Traceback (most recent call last):
...
ValueError: A coefficient ring has to be specified
to create a term monoid of type 'exact'
create_object(version, key, **kwds)[source]#

Create a object from the given arguments.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: G = GrowthGroup('x^ZZ')
sage: TermMonoid('O', G, QQ)  # indirect doctest
O-Term Monoid x^ZZ with implicit coefficients in Rational Field
sage: TermMonoid('exact', G, ZZ)  # indirect doctest
Exact Term Monoid x^ZZ with coefficients in Integer Ring
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> G = GrowthGroup('x^ZZ')
>>> TermMonoid('O', G, QQ)  # indirect doctest
O-Term Monoid x^ZZ with implicit coefficients in Rational Field
>>> TermMonoid('exact', G, ZZ)  # indirect doctest
Exact Term Monoid x^ZZ with coefficients in Integer Ring
class sage.rings.asymptotic.term_monoid.TermWithCoefficient(parent, growth, coefficient)[source]#

Bases: GenericTerm

Base class for asymptotic terms possessing a coefficient. For example, ExactTerm directly inherits from this class.

INPUT:

  • parent – the parent of the asymptotic term.

  • growth – an asymptotic growth element of the parent’s growth group.

  • coefficient – an element of the parent’s coefficient ring.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import TermWithCoefficientMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G = GrowthGroup('x^ZZ'); x = G.gen()
sage: CT_ZZ = TermWithCoefficientMonoid(TermMonoid, G, ZZ)
sage: CT_QQ = TermWithCoefficientMonoid(TermMonoid, G, QQ)
sage: CT_ZZ(x^2, coefficient=5)
Term with coefficient 5 and growth x^2
sage: CT_QQ(x^3, coefficient=3/8)
Term with coefficient 3/8 and growth x^3
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import TermWithCoefficientMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G = GrowthGroup('x^ZZ'); x = G.gen()
>>> CT_ZZ = TermWithCoefficientMonoid(TermMonoid, G, ZZ)
>>> CT_QQ = TermWithCoefficientMonoid(TermMonoid, G, QQ)
>>> CT_ZZ(x**Integer(2), coefficient=Integer(5))
Term with coefficient 5 and growth x^2
>>> CT_QQ(x**Integer(3), coefficient=Integer(3)/Integer(8))
Term with coefficient 3/8 and growth x^3
construction()[source]#

Return a construction of this term.

INPUT:

Nothing.

OUTPUT:

A pair (cls, kwds) such that cls(**kwds) equals this term.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: T = TermMonoid('exact', GrowthGroup('x^ZZ'), QQ)
sage: a = T.an_element(); a
1/2*x
sage: cls, kwds = a.construction(); cls, kwds
(<class 'sage.rings.asymptotic.term_monoid.ExactTermMonoid_with_category.element_class'>,
 {'coefficient': 1/2,
  'growth': x,
  'parent': Exact Term Monoid x^ZZ with coefficients in Rational Field})
sage: cls(**kwds) == a
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> T = TermMonoid('exact', GrowthGroup('x^ZZ'), QQ)
>>> a = T.an_element(); a
1/2*x
>>> cls, kwds = a.construction(); cls, kwds
(<class 'sage.rings.asymptotic.term_monoid.ExactTermMonoid_with_category.element_class'>,
 {'coefficient': 1/2,
  'growth': x,
  'parent': Exact Term Monoid x^ZZ with coefficients in Rational Field})
>>> cls(**kwds) == a
True
class sage.rings.asymptotic.term_monoid.TermWithCoefficientMonoid(term_monoid_factory, growth_group, coefficient_ring, category)[source]#

Bases: GenericTermMonoid

This class implements the base structure for parents of asymptotic terms possessing a coefficient from some coefficient ring. In particular, this is also the parent for TermWithCoefficient.

INPUT:

  • growth_group – a growth group.

  • category – The category of the parent can be specified in order to broaden the base structure. It has to be a subcategory of Join of Category of monoids and Category of posets. This is also the default category if None is specified.

  • coefficient_ring – the ring which contains the coefficients of the elements.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import TermWithCoefficientMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

sage: G_ZZ = GrowthGroup('x^ZZ'); x_ZZ = G_ZZ.gen()
sage: G_QQ = GrowthGroup('x^QQ'); x_QQ = G_QQ.gen()
sage: TC_ZZ = TermWithCoefficientMonoid(TermMonoid, G_ZZ, QQ); TC_ZZ
TermWithCoefficient Monoid x^ZZ with coefficients in Rational Field
sage: TC_QQ = TermWithCoefficientMonoid(TermMonoid, G_QQ, QQ); TC_QQ
TermWithCoefficient Monoid x^QQ with coefficients in Rational Field
sage: TC_ZZ == TC_QQ or TC_ZZ is TC_QQ
False
sage: TC_QQ.coerce_map_from(TC_ZZ)
Coercion map:
  From: TermWithCoefficient Monoid x^ZZ with coefficients in Rational Field
  To:   TermWithCoefficient Monoid x^QQ with coefficients in Rational Field
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import TermWithCoefficientMonoid
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid

>>> G_ZZ = GrowthGroup('x^ZZ'); x_ZZ = G_ZZ.gen()
>>> G_QQ = GrowthGroup('x^QQ'); x_QQ = G_QQ.gen()
>>> TC_ZZ = TermWithCoefficientMonoid(TermMonoid, G_ZZ, QQ); TC_ZZ
TermWithCoefficient Monoid x^ZZ with coefficients in Rational Field
>>> TC_QQ = TermWithCoefficientMonoid(TermMonoid, G_QQ, QQ); TC_QQ
TermWithCoefficient Monoid x^QQ with coefficients in Rational Field
>>> TC_ZZ == TC_QQ or TC_ZZ is TC_QQ
False
>>> TC_QQ.coerce_map_from(TC_ZZ)
Coercion map:
  From: TermWithCoefficient Monoid x^ZZ with coefficients in Rational Field
  To:   TermWithCoefficient Monoid x^QQ with coefficients in Rational Field
Element[source]#

alias of TermWithCoefficient

some_elements()[source]#

Return some elements of this term with coefficient monoid.

See TestSuite for a typical use case.

INPUT:

Nothing.

OUTPUT:

An iterator.

EXAMPLES:

sage: from itertools import islice
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: G = GrowthGroup('z^QQ')
sage: T = TermMonoid('exact', G, ZZ)
sage: tuple(islice(T.some_elements(), int(10)))
(z^(1/2), z^(-1/2), -z^(1/2), z^2, -z^(-1/2), 2*z^(1/2),
 z^(-2), -z^2, 2*z^(-1/2), -2*z^(1/2))
>>> from sage.all import *
>>> from itertools import islice
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> G = GrowthGroup('z^QQ')
>>> T = TermMonoid('exact', G, ZZ)
>>> tuple(islice(T.some_elements(), int(Integer(10))))
(z^(1/2), z^(-1/2), -z^(1/2), z^2, -z^(-1/2), 2*z^(1/2),
 z^(-2), -z^2, 2*z^(-1/2), -2*z^(1/2))
exception sage.rings.asymptotic.term_monoid.ZeroCoefficientError[source]#

Bases: ValueError

sage.rings.asymptotic.term_monoid.absorption(left, right)[source]#

Let one of the two passed terms absorb the other.

Helper function used by AsymptoticExpansion.

Note

If neither of the terms can absorb the other, an ArithmeticError is raised.

See the module description for a detailed explanation of absorption.

INPUT:

  • left – an asymptotic term.

  • right – an asymptotic term.

OUTPUT:

An asymptotic term or None.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: from sage.rings.asymptotic.term_monoid import absorption
sage: T = TermMonoid('O', GrowthGroup('x^ZZ'), ZZ)
sage: absorption(T(x^2), T(x^3))
O(x^3)
sage: absorption(T(x^3), T(x^2))
O(x^3)
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> from sage.rings.asymptotic.term_monoid import absorption
>>> T = TermMonoid('O', GrowthGroup('x^ZZ'), ZZ)
>>> absorption(T(x**Integer(2)), T(x**Integer(3)))
O(x^3)
>>> absorption(T(x**Integer(3)), T(x**Integer(2)))
O(x^3)
sage: T = TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ)
sage: absorption(T(x^2), T(x^3))
Traceback (most recent call last):
...
ArithmeticError: Absorption between x^2 and x^3 is not possible.
>>> from sage.all import *
>>> T = TermMonoid('exact', GrowthGroup('x^ZZ'), ZZ)
>>> absorption(T(x**Integer(2)), T(x**Integer(3)))
Traceback (most recent call last):
...
ArithmeticError: Absorption between x^2 and x^3 is not possible.
sage.rings.asymptotic.term_monoid.can_absorb(left, right)[source]#

Return whether one of the two input terms is able to absorb the other.

Helper function used by AsymptoticExpansion.

INPUT:

  • left – an asymptotic term.

  • right – an asymptotic term.

OUTPUT:

A boolean.

Note

See the module description for a detailed explanation of absorption.

EXAMPLES:

sage: from sage.rings.asymptotic.growth_group import GrowthGroup
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
sage: from sage.rings.asymptotic.term_monoid import can_absorb
sage: T = TermMonoid('O', GrowthGroup('x^ZZ'), ZZ)
sage: can_absorb(T(x^2), T(x^3))
True
sage: can_absorb(T(x^3), T(x^2))
True
>>> from sage.all import *
>>> from sage.rings.asymptotic.growth_group import GrowthGroup
>>> from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory as TermMonoid
>>> from sage.rings.asymptotic.term_monoid import can_absorb
>>> T = TermMonoid('O', GrowthGroup('x^ZZ'), ZZ)
>>> can_absorb(T(x**Integer(2)), T(x**Integer(3)))
True
>>> can_absorb(T(x**Integer(3)), T(x**Integer(2)))
True