(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:
OTerm
– \(O\)-terms at infinity, see Wikipedia article Big_O_notation.TermWithCoefficient
– abstract base class for asymptotic terms with coefficients.ExactTerm
– this class represents a growth element multiplied with some non-zero coefficient from a coefficient ring.
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 thatOTerm
is able to absorb otherOTerm
, as well asExactTerm
, 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 anotherExactTerm
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
andTermWithCoefficient
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 whethert1
has a growth that is strictly weaker than the growth oft2
. If so, we returnTrue
. If the terms have equal growth, then we returnTrue
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
andcoefficient
for the parameters given byvalid_from
. For example, we have terms that represent functionsbounded 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 termgrowth
– an asymptotic growth element of the parent’s growth groupcoefficient
– an element of the parent’s coefficient ringvalid_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 tovalid_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 anotherBTerm
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 thatcls(**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 groupcoefficient_ring
– the ring which contains the coefficients of the elementscategory
– The category of the parent can be specified in order to broaden the base structure. It has to be a subcategory ofJoin of Category of monoids and Category of posets
. This is also the default category ifNone
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
- 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 fromparent.growth_group
.coefficient
– an element fromparent.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. IfNone
(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 usuallog
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
- 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 ofJoin of Category of monoids and Category of posets
. This is also the default category ifNone
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
- 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. Ifcheck
isTrue
(default), thencan_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
toFalse
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 anotherExactTerm
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 thatcls(**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. IfNone
(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 usuallog
is taken.
OUTPUT:
A tuple of terms.
Note
This abstract method raises a NotImplementedError. See
ExactTerm
andOTerm
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.
See also
- 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 ofGenericGrowthGroup
).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 ofJoin of Category of Monoids and Category of posets
. This is also the default category ifNone
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
orOTerm
). Basically, asymptotic terms consist of agrowth
(which is an asymptotic growth group element, for exampleMonomialGrowthElement
); additional structure and properties are added by the classes inherited fromGenericTermMonoid
.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 termright
.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. SeeTermMonoidFactory
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. IfNone
(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 usuallog
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)))
See also
- 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 ifbase
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 ofJoin of Category of monoids and Category of posets
. This is also the default category ifNone
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
- 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 letterO
) 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, thengrowth_group
andcoefficient_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 thatcls(**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 ofJoin of Category of monoids and Category of posets
. This is also the default category ifNone
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