Asymptotic Expansions
Release 10.4

The Sage Development TeamJul 23, 2024

CONTENTS

1

The Asymptotic Ring

1

2

Asymptotic Expansion Generators

3

3

Supplements
3.1 Growth Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Term Monoids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5
5
5
5

4

Asymptotic Expansions — Table of Contents
4.1 Asymptotic Ring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Common Asymptotic Expansions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 (Asymptotic) Growth Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.4 Cartesian Products of Growth Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.5 (Asymptotic) Term Monoids . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.6 Asymptotic Expansions — Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.7 Asymptotics of Multivariate Generating Series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7
7
54
67
104
117
163
173

5

Indices and Tables

231

Python Module Index

233

Index

235

i

ii

CHAPTERONE

THE ASYMPTOTIC RING

The asymptotic ring, as well as its main documentation is contained in the module• Asymptotic Ring.

1

Asymptotic Expansions, Release 10.4

2

Chapter 1. The Asymptotic Ring

CHAPTERTWOASYMPTOTIC EXPANSION GENERATORS

Some common asymptotic expansions can be generated in• Common Asymptotic Expansions.

3Asymptotic Expansions, Release 10.4

4Chapter 2. Asymptotic Expansion Generators

CHAPTER

THREE

SUPPLEMENTS

Behind the scenes of working with asymptotic expressions a couple of additional classes and tools turn up. For instancethe growth of each summand is managed in growth groups, see below.

3.1 Growth Groups
The growth of a summand of an asymptotic expression is managed in• (Asymptotic) Growth Groups and• Cartesian Products of Growth Groups.

3.2 Term Monoids
A summand of an asymptotic expression is basically a term out of the following monoid:• (Asymptotic) Term Monoids.

3.3 Miscellaneous
Various useful functions and tools are collected in• Asymptotic Expansions — Miscellaneous.

5

Asymptotic Expansions, Release 10.4

6

Chapter 3. Supplements

CHAPTERFOUR

ASYMPTOTIC EXPANSIONS — TABLE OF CONTENTS

4.1 Asymptotic Ring
This module provides a ring (called AsymptoticRing) for computations with asymptotic expansions.

4.1.1 (Informal) Definition
An asymptotic expansion is a sum such as
5𝑧 3 + 4𝑧 2 + 𝑂(𝑧)as 𝑧 → ∞ or
3𝑥42 𝑦 2 + 7𝑥3 𝑦 3 + 𝑂(𝑥2 ) + 𝑂(𝑦)as 𝑥 and 𝑦 tend to ∞. It is a truncated series (after a finite number of terms), which approximates a function.
The summands of the asymptotic expansions are partially ordered. In this module these summands are the following:• Exact terms 𝑐 · 𝑔 with a coefficient 𝑐 and an element 𝑔 of a growth group (see below).
• 𝑂-terms 𝑂(𝑔) (see Big O notation; also called Bachmann–Landau notation) for a growth group element 𝑔 (again
see below).
See the Wikipedia article on asymptotic expansions for more details. Further examples of such elements can be found
here.
Growth Groups and Elements
The elements of a growth group are equipped with a partial order and usually contain a variable. Examples—the order is
described below these examples—are• elements of the form 𝑧 𝑞 for some integer or rational 𝑞 (growth groups with description strings z^ZZ or z^QQ),• elements of the form log(𝑧)𝑞 for some integer or rational 𝑞 (growth groups log(z)^ZZ or log(z)^QQ),• elements of the form 𝑎𝑧 for some rational 𝑎 (growth group QQ^z), or• more sophisticated constructions like products 𝑥𝑟 · log(𝑥)𝑠 · 𝑎𝑦 · 𝑦 𝑞 (this corresponds to an element of the growthgroup x^QQ * log(x)^ZZ * QQ^y * y^QQ).
The order in all these examples is induced by the magnitude of the elements as 𝑥, 𝑦, or 𝑧 (independently) tend to ∞. For
elements only using the variable 𝑧 this means that 𝑔1 ≤ 𝑔2 iflim

𝑔1𝑧→∞ 𝑔2≤ 1.
7

Asymptotic Expansions, Release 10.4

Note: Asymptotic rings where the variable tend to some value distinct from ∞ are not yet implemented.
To find out more about• growth groups,• on how they are created and• about the above used descriptions strings
see the top of the module growth group.

4.1.2 Introductory Examples
We start this series of examples by defining two asymptotic rings.
Two Rings
A Univariate Asymptotic Ring
First, we construct the following (very simple) asymptotic ring in the variable 𝑧:
sage: A.<z> = AsymptoticRing(growth_group= z^QQ , coefficient_ring=ZZ); A
Asymptotic Ring <z^QQ> over Integer Ring>>> from sage.all import *>>> A = AsymptoticRing(growth_group= z^QQ , coefficient_ring=ZZ, names=( z ,)); (z,)␣
˓→= A._first_ngens(1); A
Asymptotic Ring <z^QQ> over Integer Ring

A typical element of this ring is
sage: A.an_element()z^(3/2) + O(z^(1/2))>>> from sage.all import *>>> A.an_element()z^(3/2) + O(z^(1/2))

This element consists of two summands: the exact term with coefficient 1 and growth 𝑧 3/2 and the 𝑂-term 𝑂(𝑧 1/2 ).
Note that the growth of 𝑧 3/2 is larger than the growth of 𝑧 1/2 as 𝑧 → ∞, thus this expansion cannot be simplified (which
would be done automatically, see below).
Elements can be constructed via the generator 𝑧 and the function O(), for example
sage: 4*z^2 + O(z)4*z^2 + O(z)>>> from sage.all import *>>> Integer(4)*z**Integer(2) + O(z)4*z^2 + O(z)8Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

A Multivariate Asymptotic Ring
Next, we construct a more sophisticated asymptotic ring in the variables 𝑥 and 𝑦 bysage: B.<x, y> = AsymptoticRing(growth_group= x^QQ * log(x)^ZZ * (QQ_+)^y * y^QQ ,␣˓→coefficient_ring=QQ); B
Asymptotic Ring <x^QQ * log(x)^ZZ * QQ^y * y^QQ> over Rational Field>>> from sage.all import *>>> B = AsymptoticRing(growth_group= x^QQ * log(x)^ZZ * (QQ_+)^y * y^QQ , coefficient_
˓→ring=QQ, names=( x ,y ,)); (x, y,) = B._first_ngens(2); B
Asymptotic Ring <x^QQ * log(x)^ZZ * QQ^y * y^QQ> over Rational Field

Again, we can look at a typical (nontrivial) element:
sage: B.an_element()
1/8*x^(3/2)*log(x)^3*(1/8)^y*y^(3/2) + O(x^(1/2)*log(x)*(1/2)^y*y^(1/2))>>> from sage.all import *>>> B.an_element()
1/8*x^(3/2)*log(x)^3*(1/8)^y*y^(3/2) + O(x^(1/2)*log(x)*(1/2)^y*y^(1/2))

Again, elements can be created using the generators 𝑥 and 𝑦, as well as the function O():
sage: log(x)*y/42 + O(1/2^y)
1/42*log(x)*y + O((1/2)^y)>>> from sage.all import *>>> log(x)*y/Integer(42) + O(Integer(1)/Integer(2)**y)
1/42*log(x)*y + O((1/2)^y)Arithmetical Operations
In this section we explain how to perform various arithmetical operations with the elements of the asymptotic rings
constructed above.
The Ring Operations Plus and Times
We start our calculations in the ringsage: A
Asymptotic Ring <z^QQ> over Integer Ring>>> from sage.all import *>>> A
Asymptotic Ring <z^QQ> over Integer Ring

Of course, we can perform the usual ring operations + and *:sage: z^2 + 3*z*(1-z)-2*z^2 + 3*z
sage: (3*z + 2)^3
27*z^3 + 54*z^2 + 36*z + 8

4.1. Asymptotic Ring

9

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> z**Integer(2) + Integer(3)*z*(Integer(1)-z)-2*z^2 + 3*z>>> (Integer(3)*z + Integer(2))**Integer(3)27*z^3 + 54*z^2 + 36*z + 8

In addition to that, special powers—our growth group z^QQ allows the exponents to be out of —can also be computed:
sage: (z^(5/2)+z^(1/7)) * z^(-1/5)
z^(23/10) + z^(-2/35)>>> from sage.all import *>>> (z**(Integer(5)/Integer(2))+z**(Integer(1)/Integer(7))) * z**(-Integer(1)/˓→Integer(5))
z^(23/10) + z^(-2/35)

The central concepts of computations with asymptotic expansions is that the 𝑂-notation can be used. For example, wehave
sage: z^3 + z^2 + z + O(z^2)
z^3 + O(z^2)>>> from sage.all import *>>> z**Integer(3) + z**Integer(2) + z + O(z**Integer(2))
z^3 + O(z^2)

where the result is simplified automatically. A more sophisticated example issage: (z+2*z^2+3*z^3+4*z^4) * (O(z)+z^2)
4*z^6 + O(z^5)>>> from sage.all import *>>> (z+Integer(2)*z**Integer(2)+Integer(3)*z**Integer(3)+Integer(4)*z**Integer(4)) *␣˓→(O(z)+z**Integer(2))
4*z^6 + O(z^5)

Division
The asymptotic expansions support division. For example, we can expand 1/(𝑧 − 1) to a geometric series:
sage: 1 / (z-1)
z^(-1) + z^(-2) + z^(-3) + z^(-4) + ... + z^(-20) + O(z^(-21))>>> from sage.all import *>>> Integer(1) / (z-Integer(1))
z^(-1) + z^(-2) + z^(-3) + z^(-4) + ... + z^(-20) + O(z^(-21))

A default precision (parameter default_prec of AsymptoticRing) is predefined. Thus, only the first 20 summands are calculated. However, if we only want the first 5 exact terms, we cut of the rest by using
sage: (1 / (z-1)).truncate(5)z^(-1) + z^(-2) + z^(-3) + z^(-4) + z^(-5) + O(z^(-6))

10Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> (Integer(1) / (z-Integer(1))).truncate(Integer(5))
z^(-1) + z^(-2) + z^(-3) + z^(-4) + z^(-5) + O(z^(-6))

orsage: 1 / (z-1) + O(z^(-6))
z^(-1) + z^(-2) + z^(-3) + z^(-4) + z^(-5) + O(z^(-6))>>> from sage.all import *>>> Integer(1) / (z-Integer(1)) + O(z**(-Integer(6)))
z^(-1) + z^(-2) + z^(-3) + z^(-4) + z^(-5) + O(z^(-6))

Of course, we can work with more complicated expansions as well:sage: (4*z+1) / (z^3+z^2+z+O(z^0))
4*z^(-2) - 3*z^(-3) - z^(-4) + O(z^(-5))>>> from sage.all import *>>> (Integer(4)*z+Integer(1)) / (z**Integer(3)+z**Integer(2)+z+O(z**Integer(0)))
4*z^(-2) - 3*z^(-3) - z^(-4) + O(z^(-5))

Not all elements are invertible, for instance,
sage: 1 / O(z)Traceback (most recent call last):...
ZeroDivisionError: Cannot invert O(z).
>>> from sage.all import *>>> Integer(1) / O(z)Traceback (most recent call last):...
ZeroDivisionError: Cannot invert O(z).

is not invertible, since it includes 0.
Powers, Exponentials and Logarithms
It works as simple as it can be; just use the usual operators ^, exp and log. For example, we obtain the usual series
expansion of the logarithm
sage: -log(1-1/z)z^(-1) + 1/2*z^(-2) + 1/3*z^(-3) + ... + O(z^(-21))>>> from sage.all import *>>> -log(Integer(1)-Integer(1)/z)z^(-1) + 1/2*z^(-2) + 1/3*z^(-3) + ... + O(z^(-21))

as 𝑧 → ∞.
Similarly, we can apply the exponential function of an asymptotic expansion:
sage: exp(1/z)
1 + z^(-1) + 1/2*z^(-2) + 1/6*z^(-3) + 1/24*z^(-4) + ... + O(z^(-20))

4.1. Asymptotic Ring

11

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> exp(Integer(1)/z)
1 + z^(-1) + 1/2*z^(-2) + 1/6*z^(-3) + 1/24*z^(-4) + ... + O(z^(-20))

Arbitrary powers work as well; for example, we havesage: (1 + 1/z + O(1/z^5))^(1 + 1/z)
1 + z^(-1) + z^(-2) + 1/2*z^(-3) + 1/3*z^(-4) + O(z^(-5))>>> from sage.all import *>>> (Integer(1) + Integer(1)/z + O(Integer(1)/z**Integer(5)))**(Integer(1) +␣˓→Integer(1)/z)
1 + z^(-1) + z^(-2) + 1/2*z^(-3) + 1/3*z^(-4) + O(z^(-5))

Multivariate Arithmetic
Now let us move on to arithmetic in the multivariate ringsage: B
Asymptotic Ring <x^QQ * log(x)^ZZ * QQ^y * y^QQ> over Rational Field>>> from sage.all import *>>> B
Asymptotic Ring <x^QQ * log(x)^ZZ * QQ^y * y^QQ> over Rational Field

Todo: write this part4.1.3 More Examples
The mathematical constant e as a limit
The base of the natural logarithm 𝑒 satisfies the equation(︂)︂𝑛1
𝑒 = lim 1 +𝑛→∞𝑛
By using asymptotic expansions, we obtain the more precise result
sage: E.<n> = AsymptoticRing(growth_group= n^ZZ , coefficient_ring=SR, default_
˓→prec=5); E
Asymptotic Ring <n^ZZ> over Symbolic Ringsage: (1 + 1/n)^n
e - 1/2*e*n^(-1) + 11/24*e*n^(-2) - 7/16*e*n^(-3) + 2447/5760*e*n^(-4) + O(n^(-5))>>> from sage.all import *>>> E = AsymptoticRing(growth_group= n^ZZ , coefficient_ring=SR, default_
˓→prec=Integer(5), names=( n ,)); (n,) = E._first_ngens(1); E
Asymptotic Ring <n^ZZ> over Symbolic Ring>>> (Integer(1) + Integer(1)/n)**n
e - 1/2*e*n^(-1) + 11/24*e*n^(-2) - 7/16*e*n^(-3) + 2447/5760*e*n^(-4) + O(n^(-5))

12Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

4.1.4 Selected Technical Details
Coercions and Functorial Constructions
The AsymptoticRing fully supports coercion. For example, the coefficient ring is automatically extended whenneeded:sage: A
Asymptotic Ring <z^QQ> over Integer Ringsage: (z + 1/2).parent()
Asymptotic Ring <z^QQ> over Rational Field>>> from sage.all import *>>> A
Asymptotic Ring <z^QQ> over Integer Ring>>> (z + Integer(1)/Integer(2)).parent()
Asymptotic Ring <z^QQ> over Rational Field

Here, the coefficient ring was extended to allow 1/2 as a coefficient. Another example issage: C.<c> = AsymptoticRing(growth_group= c^ZZ , coefficient_ring=ZZ[ e ])sage: C.an_element()e^3*c^3 + O(c)sage: C.an_element() / 7
1/7*e^3*c^3 + O(c)>>> from sage.all import *>>> C = AsymptoticRing(growth_group= c^ZZ , coefficient_ring=ZZ[ e ], names=( c ,));␣
˓→(c,) = C._first_ngens(1)>>> C.an_element()e^3*c^3 + O(c)>>> C.an_element() / Integer(7)1/7*e^3*c^3 + O(c)Here the result’s coefficient ring is the newly foundsage: (C.an_element() / 7).parent()
Asymptotic Ring <c^ZZ> over
Univariate Polynomial Ring in e over Rational Field>>> from sage.all import *>>> (C.an_element() / Integer(7)).parent()
Asymptotic Ring <c^ZZ> over
Univariate Polynomial Ring in e over Rational Field

Not only the coefficient ring can be extended, but the growth group as well. For example, we can add/multiply elementsof the asymptotic rings A and C to get an expansion of new asymptotic ring:sage: r = c*z + c/2 + O(z); r
c*z + 1/2*c + O(z)sage: r.parent()
Asymptotic Ring <c^ZZ * z^QQ> over
Univariate Polynomial Ring in e over Rational Field

4.1. Asymptotic Ring

13

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> r = c*z + c/Integer(2) + O(z); r
c*z + 1/2*c + O(z)>>> r.parent()
Asymptotic Ring <c^ZZ * z^QQ> over
Univariate Polynomial Ring in e over Rational Field

Data Structures
The summands of an asymptotic expansion are wrapped growth group elements. This wrapping is done by theterm monoid module. However, inside an asymptotic expansion these summands (terms) are stored together with
their growth-relationship, i.e., each summand knows its direct predecessors and successors. As a data structure a special
poset (namely a mutable poset) is used. We can have a look at this:sage: b = x^3*y + x^2*y + x*y^2 + O(x) + O(y)sage: print(b.summands.repr_full(reverse=True))poset(x*y^2, x^3*y, x^2*y, O(x), O(y))+-- oo|+-- no successors|+-- predecessors:x*y^2, x^3*y+-- x*y^2|+-- successors:oo|+-- predecessors:
O(x), O(y)+-- x^3*y|+-- successors:oo|+-- predecessors:x^2*y+-- x^2*y|+-- successors:x^3*y|+-- predecessors:
O(x), O(y)+-- O(x)|+-- successors:x*y^2, x^2*y|+-- predecessors:null+-- O(y)|+-- successors:x*y^2, x^2*y|+-- predecessors:null+-- null|+-- successors:
O(x), O(y)|+-- no predecessors>>> from sage.all import *>>> b = x**Integer(3)*y + x**Integer(2)*y + x*y**Integer(2) + O(x) + O(y)>>> print(b.summands.repr_full(reverse=True))poset(x*y^2, x^3*y, x^2*y, O(x), O(y))+-- oo|+-- no successors|+-- predecessors:x*y^2, x^3*y+-- x*y^2|+-- successors:oo|+-- predecessors:
O(x), O(y)+-- x^3*y|+-- successors:oo|+-- predecessors:x^2*y+-- x^2*y|+-- successors:x^3*y|+-- predecessors:
O(x), O(y)(continues on next page)

14

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)+-- O(x)|+-- successors:x*y^2, x^2*y|+-- predecessors:null+-- O(y)|+-- successors:x*y^2, x^2*y|+-- predecessors:null+-- null|+-- successors:
O(x), O(y)|+-- no predecessors

4.1.5 Various
AUTHORS:• Benjamin Hackl (2015)• Daniel Krenn (2015)• Clemens Heuberger (2016)
ACKNOWLEDGEMENT:• Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P
24644-N26.
• Benjamin Hackl is supported by the Google Summer of Code 2015.

4.1.6 Classes and Methods
class sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion(parent, summands,
simplify=True,
convert=True)
Bases: CommutativeAlgebraElement
Class for asymptotic expansions, i.e., the elements of an AsymptoticRing.
INPUT:• parent – the parent of the asymptotic expansion.
• summands – the summands as a MutablePoset, which represents the underlying structure.
• simplify – a boolean (default: True). It controls automatic simplification (absorption) of the asymptotic
expansion.
• convert – a boolean (default: True). If set, then the summands are converted to the asymptotic ring(the parent of this expansion). If not, then the summands are taken as they are. In that case, the caller mustensure that the parent of the terms is set correctly.
EXAMPLES:
There are several ways to create asymptotic expansions; usually this is done by using the corresponding asymptotic rings:
sage: R_x.<x> = AsymptoticRing(growth_group= x^QQ , coefficient_ring=QQ); R_x
Asymptotic Ring <x^QQ> over Rational Field
sage: R_y.<y> = AsymptoticRing(growth_group= y^ZZ , coefficient_ring=ZZ); R_y
Asymptotic Ring <y^ZZ> over Integer Ring

4.1. Asymptotic Ring

15

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> R_x = AsymptoticRing(growth_group= x^QQ , coefficient_ring=QQ, names=( x ,));␣
˓→(x,) = R_x._first_ngens(1); R_x
Asymptotic Ring <x^QQ> over Rational Field>>> R_y = AsymptoticRing(growth_group= y^ZZ , coefficient_ring=ZZ, names=( y ,));␣
˓→(y,) = R_y._first_ngens(1); R_y
Asymptotic Ring <y^ZZ> over Integer Ring

At this point, 𝑥 and 𝑦 are already asymptotic expansions:sage: type(x)<class sage.rings.asymptotic.asymptotic_ring.AsymptoticRing_with_category.
˓→element_class >>>> from sage.all import *>>> type(x)<class sage.rings.asymptotic.asymptotic_ring.AsymptoticRing_with_category.
˓→element_class >The usual ring operations, but allowing rational exponents (growth group x^QQ) can be performed:
sage: x^2 + 3*(x - x^(2/5))x^2 + 3*x - 3*x^(2/5)
sage: (3*x^(1/3) + 2)^3
27*x + 54*x^(2/3) + 36*x^(1/3) + 8>>> from sage.all import *>>> x**Integer(2) + Integer(3)*(x - x**(Integer(2)/Integer(5)))
x^2 + 3*x - 3*x^(2/5)>>> (Integer(3)*x**(Integer(1)/Integer(3)) + Integer(2))**Integer(3)27*x + 54*x^(2/3) + 36*x^(1/3) + 8

One of the central ideas behind computing with asymptotic expansions is that the 𝑂-notation (see Wikipedia article
Big_O_notation) can be used. For example, we have:sage: (x+2*x^2+3*x^3+4*x^4) * (O(x)+x^2)
4*x^6 + O(x^5)>>> from sage.all import *>>>␣˓→(x+Integer(2)*x**Integer(2)+Integer(3)*x**Integer(3)+Integer(4)*x**Integer(4))␣
˓→* (O(x)+x**Integer(2))
4*x^6 + O(x^5)

In particular, O() can be used to construct the asymptotic expansions. With the help of the summands(), we
can also have a look at the inner structure of an asymptotic expansion:
sage: expr1 = x + 2*x^2 + 3*x^3 + 4*x^4; expr2 = O(x) + x^2
sage: print(expr1.summands.repr_full())
poset(x, 2*x^2, 3*x^3, 4*x^4)+-- null|+-- no predecessors|+-- successors:
x
+-- x
|
+-- predecessors:null|+-- successors:
2*x^2(continues on next page)

16

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)+-- 2*x^2|+-- predecessors:x|+-- successors:
3*x^3+-- 3*x^3|+-- predecessors:
2*x^2|+-- successors:
4*x^4+-- 4*x^4|+-- predecessors:
3*x^3|+-- successors:oo+-- oo|+-- predecessors:
4*x^4|+-- no successors
sage: print(expr2.summands.repr_full())
poset(O(x), x^2)+-- null|+-- no predecessors|+-- successors:O(x)+-- O(x)|+-- predecessors:null|+-- successors:x^2+-- x^2|+-- predecessors:O(x)|+-- successors:oo+-- oo|+-- predecessors:x^2|+-- no successors
sage: print((expr1 * expr2).summands.repr_full())
poset(O(x^5), 4*x^6)+-- null|+-- no predecessors|+-- successors:O(x^5)+-- O(x^5)|+-- predecessors:null|+-- successors:
4*x^6+-- 4*x^6|+-- predecessors:O(x^5)|+-- successors:oo+-- oo|+-- predecessors:
4*x^6|+-- no successors>>> from sage.all import *>>> expr1 = x + Integer(2)*x**Integer(2) + Integer(3)*x**Integer(3) +␣˓→Integer(4)*x**Integer(4); expr2 = O(x) + x**Integer(2)>>> print(expr1.summands.repr_full())
poset(x, 2*x^2, 3*x^3, 4*x^4)+-- null|+-- no predecessors|+-- successors:
x
+-- x
|
+-- predecessors:null|+-- successors:
2*x^2+-- 2*x^2|+-- predecessors:x|+-- successors:
3*x^3+-- 3*x^3(continues on next page)

4.1. Asymptotic Ring

17

Asymptotic Expansions, Release 10.4

(continued from previous page)|+-- predecessors:
2*x^2|+-- successors:
4*x^4+-- 4*x^4|+-- predecessors:
3*x^3|+-- successors:oo+-- oo|+-- predecessors:
4*x^4|+-- no successors>>> print(expr2.summands.repr_full())
poset(O(x), x^2)+-- null|+-- no predecessors|+-- successors:O(x)+-- O(x)|+-- predecessors:null|+-- successors:x^2+-- x^2|+-- predecessors:O(x)|+-- successors:oo+-- oo|+-- predecessors:x^2|+-- no successors>>> print((expr1 * expr2).summands.repr_full())
poset(O(x^5), 4*x^6)+-- null|+-- no predecessors|+-- successors:O(x^5)+-- O(x^5)|+-- predecessors:null|+-- successors:
4*x^6+-- 4*x^6|+-- predecessors:O(x^5)|+-- successors:oo+-- oo|+-- predecessors:
4*x^6|+-- no successors

In addition to the monomial growth elements from above, we can also compute with logarithmic terms (simply by
constructing the appropriate growth group):
sage: R_log = AsymptoticRing(growth_group= log(x)^QQ , coefficient_ring=QQ)
sage: lx = R_log(log(SR.var( x )))sage: (O(lx) + lx^3)^4
log(x)^12 + O(log(x)^10)>>> from sage.all import *>>> R_log = AsymptoticRing(growth_group= log(x)^QQ , coefficient_ring=QQ)>>> lx = R_log(log(SR.var( x )))>>> (O(lx) + lx**Integer(3))**Integer(4)log(x)^12 + O(log(x)^10)

See also:(Asymptotic) Growth Groups, (Asymptotic) Term Monoids, mutable_poset.
B(valid_from=0)
Convert all terms in this asymptotic expansion to 𝐵-terms.

18

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

INPUT:• 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 anumber is passed to valid_from, then the lower bounds for all variables of the asymptotic expansion
are set to this number
OUTPUT:
An asymptotic expansion
EXAMPLES:
sage: AR.<x, z> = AsymptoticRing(growth_group= x^ZZ * z^ZZ , coefficient_
˓→ring=ZZ)
sage: AR.B(2*x^2, {x: 10}) # indirect doctest
B(2*x^2, x >= 10)
sage: expr = 42*x^42 + x^10 + AR.B(x^2, 20); expr # indirect doctest
42*x^42 + x^10 + B(x^2, x >= 20, z >= 20)
sage: type(AR.B(x, 10)) # indirect doctest<class sage.rings.asymptotic.asymptotic_ring.AsymptoticRing_with_category.
˓→element_class >sage: 2*z^3 + AR.B(5*z^2, {z: 20}) # indirect doctest
2*z^3 + B(5*z^2, z >= 20)
sage: (2*x).B({x: 20})B(2*x, x >= 20)
sage: AR.B(4*x^2*z^3, valid_from=10) # indirect doctest
B(4*x^2*z^3, x >= 10, z >= 10)
sage: AR.B(42*x^2) # indirect doctest
B(42*x^2, x >= 0, z >= 0)>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ * z^ZZ , coefficient_ring=ZZ,␣
˓→names=( x ,z ,)); (x, z,) = AR._first_ngens(2)>>> AR.B(Integer(2)*x**Integer(2), {x: Integer(10)}) # indirect doctest
B(2*x^2, x >= 10)>>> expr = Integer(42)*x**Integer(42) + x**Integer(10) + AR.B(x**Integer(2),␣
˓→Integer(20)); expr # indirect doctest
42*x^42 + x^10 + B(x^2, x >= 20, z >= 20)>>> type(AR.B(x, Integer(10))) # indirect doctest<class sage.rings.asymptotic.asymptotic_ring.AsymptoticRing_with_category.
˓→element_class >>>> Integer(2)*z**Integer(3) + AR.B(Integer(5)*z**Integer(2), {z: Integer(20)}˓→) # indirect doctest
2*z^3 + B(5*z^2, z >= 20)>>> (Integer(2)*x).B({x: Integer(20)})B(2*x, x >= 20)>>> AR.B(Integer(4)*x**Integer(2)*z**Integer(3), valid_from=Integer(10)) #␣˓→indirect doctest
B(4*x^2*z^3, x >= 10, z >= 10)>>> AR.B(Integer(42)*x**Integer(2)) # indirect doctest
B(42*x^2, x >= 0, z >= 0)O()
Convert all terms in this asymptotic expansion to 𝑂-terms.
OUTPUT:
An asymptotic expansion.

4.1. Asymptotic Ring

19

Asymptotic Expansions, Release 10.4

EXAMPLES:
sage: AR.<x> = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: O(x)O(x)
sage: type(O(x))<class sage.rings.asymptotic.asymptotic_ring.AsymptoticRing_with_category.
˓→element_class >sage: expr = 42*x^42 + x^10 + O(x^2); expr
42*x^42 + x^10 + O(x^2)
sage: expr.O()O(x^42)sage: (2*x).O()O(x)>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ, names=( x ,˓→)); (x,) = AR._first_ngens(1)>>> O(x)O(x)>>> type(O(x))<class sage.rings.asymptotic.asymptotic_ring.AsymptoticRing_with_category.
˓→element_class >>>> expr = Integer(42)*x**Integer(42) + x**Integer(10) + O(x**Integer(2));␣
˓→expr42*x^42 + x^10 + O(x^2)>>> expr.O()O(x^42)>>> (Integer(2)*x).O()O(x)

See also:
sage.rings.power_series_ring.PowerSeriesRing(),laurent_series_ring.LaurentSeriesRing().

sage.rings.

compare_with_values(variable, function, values, rescaled=True, ring=Real Interval Field with 53 bits ofprecision)Compute the (rescaled) difference between this asymptotic expansion and the given values.
INPUT:• variable – an asymptotic expansion or a string.
• function – a callable or symbolic expression giving the comparison values.
• values – a list or iterable of values where the comparison shall be carried out.
• rescaled – (default: True) determines whether the difference is divided by the error term of theasymptotic expansion.
• ring – (default: RIF) the parent into which the difference is converted.
OUTPUT:
A list of pairs containing comparison points and (rescaled) difference values.
EXAMPLES:
sage: assume(SR.an_element() > 0)sage: A.<n> = AsymptoticRing( QQ^n * n^ZZ , SR)(continues on next page)

20

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: catalan = binomial(2*x, x)/(x+1)
sage: expansion = 4^n*(1/sqrt(pi)*n^(-3/2)....:- 9/8/sqrt(pi)*n^(-5/2)....:+ 145/128/sqrt(pi)*n^(-7/2) + O(n^(-9/2)))
sage: expansion.compare_with_values(n, catalan, srange(5, 10))[(5, 0.5303924444775?),(6, 0.5455279498787?),(7, 0.556880411050?),(8, 0.565710587724?),(9, 0.572775029098?)]
sage: expansion.exact_part().compare_with_values(n, catalan, [5, 10, 20])
Traceback (most recent call last):...
NotImplementedError: exactly one error term required
sage: expansion.exact_part().compare_with_values(n, catalan, [5, 10, 20],␣
˓→rescaled=False)[(5, 0.3886263699387?), (10, 19.1842458318?), (20, 931314.63637?)]
sage: expansion.compare_with_values(n, catalan, [5, 10, 20], rescaled=False,␣
˓→ring=SR)[(5, 168/5*sqrt(5)/sqrt(pi) - 42),
(10, 1178112/125*sqrt(10)/sqrt(pi) - 16796),(20, 650486218752/125*sqrt(5)/sqrt(pi) - 6564120420)]>>> from sage.all import *>>> assume(SR.an_element() > Integer(0))>>> A = AsymptoticRing( QQ^n * n^ZZ , SR, names=( n ,)); (n,) = A._first_
˓→ngens(1)>>> catalan = binomial(Integer(2)*x, x)/(x+Integer(1))>>> expansion = Integer(4)**n*(Integer(1)/sqrt(pi)*n**(-Integer(3)/Integer(2))...
- Integer(9)/Integer(8)/sqrt(pi)*n**(-Integer(5)/Integer(2))...
+ Integer(145)/Integer(128)/sqrt(pi)*n**(-Integer(7)/Integer(2)) +␣˓→O(n**(-Integer(9)/Integer(2))))>>> expansion.compare_with_values(n, catalan, srange(Integer(5), Integer(10)))[(5, 0.5303924444775?),(6, 0.5455279498787?),(7, 0.556880411050?),(8, 0.565710587724?),(9, 0.572775029098?)]>>> expansion.exact_part().compare_with_values(n, catalan, [Integer(5),␣
˓→Integer(10), Integer(20)])
Traceback (most recent call last):...
NotImplementedError: exactly one error term required>>> expansion.exact_part().compare_with_values(n, catalan, [Integer(5),␣
˓→Integer(10), Integer(20)], rescaled=False)[(5, 0.3886263699387?), (10, 19.1842458318?), (20, 931314.63637?)]>>> expansion.compare_with_values(n, catalan, [Integer(5), Integer(10),␣
˓→Integer(20)], rescaled=False, ring=SR)[(5, 168/5*sqrt(5)/sqrt(pi) - 42),
(10, 1178112/125*sqrt(10)/sqrt(pi) - 16796),(20, 650486218752/125*sqrt(5)/sqrt(pi) - 6564120420)]

Instead of a symbolic expression, a callable function can be specified as well:sage: A.<n> = AsymptoticRing( n^ZZ * log(n)^ZZ , SR)
sage: def H(n):(continues on next page)

4.1. Asymptotic Ring

21

Asymptotic Expansions, Release 10.4

(continued from previous page)....:
return sum(1/k for k in srange(1, n+1))
sage: H_expansion = (log(n) + euler_gamma + 1/(2*n)....:- 1/(12*n^2) + O(n^-4))sage: H_expansion.compare_with_values(n, H, srange(25, 30)) # rel tol 1e-6[(25, -0.008326995?),(26, -0.008327472?),(27, -0.008327898?),(28, -0.00832828?),(29, -0.00832862?)]
sage: forget()>>> from sage.all import *>>> A = AsymptoticRing( n^ZZ * log(n)^ZZ , SR, names=( n ,)); (n,) = A._first_
˓→ngens(1)>>> def H(n):...
return sum(Integer(1)/k for k in srange(Integer(1), n+Integer(1)))>>> H_expansion = (log(n) + euler_gamma + Integer(1)/(Integer(2)*n)...
- Integer(1)/(Integer(12)*n**Integer(2)) + O(n**˓→Integer(4)))>>> H_expansion.compare_with_values(n, H, srange(Integer(25), Integer(30))) #␣˓→rel tol 1e-6[(25, -0.008326995?),(26, -0.008327472?),(27, -0.008327898?),(28, -0.00832828?),(29, -0.00832862?)]>>> forget()See also:
plot_comparison()error_part()
Return the expansion consisting of all error terms of this expansion.
OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: R.<x,y> = AsymptoticRing( x^QQ * log(x)^QQ * y^QQ , QQ)
sage: (x*log(x) + y^2 + O(x) + O(y)).error_part()
O(x) + O(y)>>> from sage.all import *>>> R = AsymptoticRing( x^QQ * log(x)^QQ * y^QQ , QQ, names=( x ,˓→y,) = R._first_ngens(2)>>> (x*log(x) + y**Integer(2) + O(x) + O(y)).error_part()
O(x) + O(y)y ,)); (x,␣exact_part()
Return the expansion consisting of all exact terms of this expansion.
OUTPUT:
An asymptotic expansion.
EXAMPLES:
22

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: R.<x> = AsymptoticRing( x^QQ * log(x)^QQ , QQ)
sage: (x^2 + O(x)).exact_part()x^2
sage: (x + log(x)/2 + O(log(x)/x)).exact_part()
x + 1/2*log(x)>>> from sage.all import *>>> R = AsymptoticRing( x^QQ * log(x)^QQ , QQ, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> (x**Integer(2) + O(x)).exact_part()x^2>>> (x + log(x)/Integer(2) + O(log(x)/x)).exact_part()
x + 1/2*log(x)exp(precision=None)
Return the exponential of (i.e., the power of 𝑒 to) this asymptotic expansion.
INPUT:• precision – the precision used for truncating the expansion. If None (default value) is used, thedefault precision of the parent is used.
OUTPUT:
An asymptotic expansion.
Note: The exponential function of this expansion can only be computed exactly if the respective growthelement can be constructed in the underlying growth group.
ALGORITHM:
If the corresponding growth can be constructed, return the exact exponential function. Otherwise, if this termis 𝑜(1), try to expand the series and truncate according to the given precision.
Todo: As soon as 𝐿-terms are implemented, this implementation has to be adapted as well in order to yieldcorrect results.
EXAMPLES:
sage: A.<x> = AsymptoticRing( (e^x)^ZZ * x^ZZ * log(x)^ZZ , SR)
sage: exp(x)e^xsage: exp(2*x)(e^x)^2sage: exp(x + log(x))
e^x*x>>> from sage.all import *>>> A = AsymptoticRing( (e^x)^ZZ * x^ZZ * log(x)^ZZ , SR, names=( x ,)); (x,)␣
˓→= A._first_ngens(1)>>> exp(x)e^x>>> exp(Integer(2)*x)(e^x)^2(continues on next page)

4.1. Asymptotic Ring

23

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> exp(x + log(x))
e^x*xsage: (x^(-1)).exp(precision=7)
1 + x^(-1) + 1/2*x^(-2) + 1/6*x^(-3) + ... + O(x^(-7))>>> from sage.all import *>>> (x**(-Integer(1))).exp(precision=Integer(7))
1 + x^(-1) + 1/2*x^(-2) + 1/6*x^(-3) + ... + O(x^(-7))

factorial()
Return the factorial of this asymptotic expansion.
OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: A.<n> = AsymptoticRing(growth_group= n^ZZ * log(n)^ZZ , coefficient_
˓→ring=ZZ, default_prec=5)
sage: n.factorial()sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2)+ 1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2)+ 1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2)+ O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))
sage: _.parent()
Asymptotic Ring <(e^(n*log(n)))^QQ * (e^n)^QQ * n^QQ * log(n)^QQ>
over Symbolic Constants Subring>>> from sage.all import *>>> A = AsymptoticRing(growth_group= n^ZZ * log(n)^ZZ , coefficient_ring=ZZ,␣
˓→default_prec=Integer(5), names=( n ,)); (n,) = A._first_ngens(1)>>> n.factorial()sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2)+ 1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2)+ 1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2)+ O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))>>> _.parent()
Asymptotic Ring <(e^(n*log(n)))^QQ * (e^n)^QQ * n^QQ * log(n)^QQ>
over Symbolic Constants Subring(︀2𝑛)︀
1
Catalan numbers 𝑛+1𝑛 :sage: (2*n).factorial() / n.factorial()^2 / (n+1)
1/sqrt(pi)*(e^n)^(2*log(2))*n^(-3/2)- 9/8/sqrt(pi)*(e^n)^(2*log(2))*n^(-5/2)+ 145/128/sqrt(pi)*(e^n)^(2*log(2))*n^(-7/2)+ O((e^n)^(2*log(2))*n^(-9/2))# long time>>> from sage.all import *>>> (Integer(2)*n).factorial() / n.factorial()**Integer(2) / (n+Integer(1))˓→# long time
1/sqrt(pi)*(e^n)^(2*log(2))*n^(-3/2)- 9/8/sqrt(pi)*(e^n)^(2*log(2))*n^(-5/2)(continues on next page)

24

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)+ 145/128/sqrt(pi)*(e^n)^(2*log(2))*n^(-7/2)+ O((e^n)^(2*log(2))*n^(-9/2))

Note that this method substitutes the asymptotic expansion into Stirling’s formula. This substitution has to bepossible which is not always guaranteed:sage: S.
 = AsymptoticRing(growth_group= s^QQ * log(s)^QQ , coefficient_
˓→ring=QQ, default_prec=4)
sage: log(s).factorial()
Traceback (most recent call last):...
TypeError: Cannot apply the substitution rules {s: log(s)} on
sqrt(2)*sqrt(pi)*e^(s*log(s))*(e^s)^(-1)*s^(1/2)+ O(e^(s*log(s))*(e^s)^(-1)*s^(-1/2)) in
Asymptotic Ring <(e^(s*log(s)))^QQ * (e^s)^QQ * s^QQ * log(s)^QQ>
over Symbolic Constants Subring.
...
>>> from sage.all import *>>> S = AsymptoticRing(growth_group= s^QQ * log(s)^QQ , coefficient_ring=QQ,␣
˓→default_prec=Integer(4), names=( s ,)); (s,) = S._first_ngens(1)>>> log(s).factorial()
Traceback (most recent call last):...
TypeError: Cannot apply the substitution rules {s: log(s)} on
sqrt(2)*sqrt(pi)*e^(s*log(s))*(e^s)^(-1)*s^(1/2)+ O(e^(s*log(s))*(e^s)^(-1)*s^(-1/2)) in
Asymptotic Ring <(e^(s*log(s)))^QQ * (e^s)^QQ * s^QQ * log(s)^QQ>
over Symbolic Constants Subring.
...

See also:
Stirling()
has_same_summands(other)
Return whether this asymptotic expansion and other have the same summands.
INPUT:• other – an asymptotic expansion.
OUTPUT:
A boolean.
Note: While for example O(x) == O(x) yields False, these expansions do have the same summands
and this method returns True.
Moreover, this method uses the coercion model in order to find a common parent for this asymptotic expansion
and other.
EXAMPLES:
sage: R_ZZ.<x_ZZ> = AsymptoticRing( x^ZZ , ZZ)
sage: R_QQ.<x_QQ> = AsymptoticRing( x^ZZ , QQ)
sage: sum(x_ZZ^k for k in range(5)) == sum(x_QQ^k for k in range(5))#␣(continues on next page)

4.1. Asymptotic Ring

25

Asymptotic Expansions, Release 10.4

(continued from previous page)

indirect doctest
True
sage: O(x_ZZ) == O(x_QQ)
False
˓→

>>> from sage.all import *>>> R_ZZ = AsymptoticRing( x^ZZ , ZZ, names=( x_ZZ ,)); (x_ZZ,) = R_ZZ._first_
˓→ngens(1)>>> R_QQ = AsymptoticRing( x^ZZ , QQ, names=( x_QQ ,)); (x_QQ,) = R_QQ._first_
˓→ngens(1)>>> sum(x_ZZ**k for k in range(Integer(5))) == sum(x_QQ**k for k in␣˓→range(Integer(5)))# indirect doctest
True>>> O(x_ZZ) == O(x_QQ)
False

invert(precision=None)
Return the multiplicative inverse of this element.
INPUT:• precision – the precision used for truncating the expansion. If None (default value) is used, thedefault precision of the parent is used.
OUTPUT:
An asymptotic expansion.
Warning: Due to truncation of infinite expansions, the element returned by this method might not fulfill
el * ~el == 1.

Todo: As soon as 𝐿-terms are implemented, this implementation has to be adapted as well in order to yieldcorrect results.
EXAMPLES:
sage: R.<x> = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=QQ,␣
˓→default_prec=4)
sage: ~xx^(-1)
sage: ~(x^42)x^(-42)sage: ex = ~(1 + x); exx^(-1) - x^(-2) + x^(-3) - x^(-4) + O(x^(-5))
sage: ex * (1+x)
1 + O(x^(-4))
sage: ~(1 + O(1/x))
1 + O(x^(-1))>>> from sage.all import *>>> R = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=QQ, default_
˓→prec=Integer(4), names=( x ,)); (x,) = R._first_ngens(1)>>> ~x(continues on next page)

26

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)x^(-1)>>> ~(x**Integer(42))
x^(-42)>>> ex = ~(Integer(1) + x); exx^(-1) - x^(-2) + x^(-3) - x^(-4) + O(x^(-5))>>> ex * (Integer(1)+x)
1 + O(x^(-4))>>> ~(Integer(1) + O(Integer(1)/x))
1 + O(x^(-1))

is_exact()
Return whether all terms of this expansion are exact.
OUTPUT:
A boolean.
EXAMPLES:
sage: A.<x> = AsymptoticRing( x^QQ * log(x)^QQ , QQ)
sage: (x^2 + O(x)).is_exact()
False
sage: (x^2 - x).is_exact()
True>>> from sage.all import *>>> A = AsymptoticRing( x^QQ * log(x)^QQ , QQ, names=( x ,)); (x,) = A._first_
˓→ngens(1)>>> (x**Integer(2) + O(x)).is_exact()
False>>> (x**Integer(2) - x).is_exact()
True

is_little_o_of_one()
Return whether this expansion is of order 𝑜(1).
OUTPUT:
A boolean.
EXAMPLES:
sage: A.<x> = AsymptoticRing( x^ZZ * log(x)^ZZ , QQ)
sage: (x^4 * log(x)^(-2) + x^(-4) * log(x)^2).is_little_o_of_one()False
sage: (x^(-1) * log(x)^1234 + x^(-2) + O(x^(-3))).is_little_o_of_one()True
sage: (log(x) - log(x-1)).is_little_o_of_one()True>>> from sage.all import *>>> A = AsymptoticRing( x^ZZ * log(x)^ZZ , QQ, names=( x ,)); (x,) = A._first_
˓→ngens(1)>>> (x**Integer(4) * log(x)**(-Integer(2)) + x**(-Integer(4)) *␣˓→log(x)**Integer(2)).is_little_o_of_one()
False>>> (x**(-Integer(1)) * log(x)**Integer(1234) + x**(-Integer(2)) + O(x**((continues on next page)

4.1. Asymptotic Ring

27

Asymptotic Expansions, Release 10.4

(continued from previous page)

Integer(3)))).is_little_o_of_one()True>>> (log(x) - log(x-Integer(1))).is_little_o_of_one()True˓→sage: A.<x, y> = AsymptoticRing( x^QQ * y^QQ * log(y)^ZZ , QQ)
sage: (x^(-1/16) * y^32 + x^32 * y^(-1/16)).is_little_o_of_one()False
sage: (x^(-1) * y^(-3) + x^(-3) * y^(-1)).is_little_o_of_one()True
sage: (x^(-1) * y / log(y)).is_little_o_of_one()False
sage: (log(y-1)/log(y) - 1).is_little_o_of_one()True>>> from sage.all import *>>> A = AsymptoticRing( x^QQ * y^QQ * log(y)^ZZ , QQ, names=( x , y ,)); (x,␣˓→y,) = A._first_ngens(2)>>> (x**(-Integer(1)/Integer(16)) * y**Integer(32) + x**Integer(32) * y**(˓→Integer(1)/Integer(16))).is_little_o_of_one()
False>>> (x**(-Integer(1)) * y**(-Integer(3)) + x**(-Integer(3)) * y**(˓→Integer(1))).is_little_o_of_one()True>>> (x**(-Integer(1)) * y / log(y)).is_little_o_of_one()
False>>> (log(y-Integer(1))/log(y) - Integer(1)).is_little_o_of_one()
True

See also:
limit()
limit()
Compute the limit of this asymptotic expansion.
OUTPUT:An element of the coefficient ring.
EXAMPLES:
sage: A.
 = AsymptoticRing("s^ZZ", SR, default_prec=3)
sage: (3 + 1/s + O(1/s^2)).limit()3
sage: ((1+1/s)^s).limit()esage: (1/s).limit()
0sage: (s + 3 + 1/s + O(1/s^2)).limit()
Traceback (most recent call last):...
ValueError: Cannot determine limit of s + 3 + s^(-1) + O(s^(-2))
sage: (O(s^0)).limit()
Traceback (most recent call last):...
ValueError: Cannot determine limit of O(1)28

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> A = AsymptoticRing("s^ZZ", SR, default_prec=Integer(3), names=( s ,)); (s,˓→) = A._first_ngens(1)>>> (Integer(3) + Integer(1)/s + O(Integer(1)/s**Integer(2))).limit()3>>> ((Integer(1)+Integer(1)/s)**s).limit()e>>> (Integer(1)/s).limit()0>>> (s + Integer(3) + Integer(1)/s + O(Integer(1)/s**Integer(2))).limit()
Traceback (most recent call last):...
ValueError: Cannot determine limit of s + 3 + s^(-1) + O(s^(-2))>>> (O(s**Integer(0))).limit()
Traceback (most recent call last):...
ValueError: Cannot determine limit of O(1)See also:
is_little_o_of_one()log(base=None, precision=None, locals=None)
The logarithm of this asymptotic expansion.
INPUT:• base – the base of the logarithm. If None (default value) is used, the natural logarithm is taken.
• precision – the precision used for truncating the expansion. If None (default value) is used, thedefault precision of the parent is used.
• 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:
An asymptotic expansion.
Note: Computing the logarithm of an asymptotic expansion is possible if and only if there is exactly one
maximal summand in the expansion.
ALGORITHM:
If the expansion has more than one summand, the asymptotic expansion for log(1 + 𝑡) as 𝑡 tends to 0 is used.
Todo: As soon as 𝐿-terms are implemented, this implementation has to be adapted as well in order to yieldcorrect results.
EXAMPLES:
sage: R.<x> = AsymptoticRing(growth_group= x^ZZ * log(x)^ZZ , coefficient_
˓→ring=QQ)
sage: log(x)log(x)
sage: log(x^2)(continues on next page)

4.1. Asymptotic Ring

29

Asymptotic Expansions, Release 10.4

(continued from previous page)

2*log(x)sage: log(x-1)
log(x) - x^(-1) - 1/2*x^(-2) - 1/3*x^(-3) - ... + O(x^(-21))>>> from sage.all import *>>> R = AsymptoticRing(growth_group= x^ZZ * log(x)^ZZ , coefficient_ring=QQ,␣
˓→names=( x ,)); (x,) = R._first_ngens(1)>>> log(x)log(x)>>> log(x**Integer(2))
2*log(x)>>> log(x-Integer(1))
log(x) - x^(-1) - 1/2*x^(-2) - 1/3*x^(-3) - ... + O(x^(-21))

The coefficient ring is automatically extended if needed:sage: R.<x> = AsymptoticRing(growth_group= x^ZZ * log(x)^ZZ , coefficient_
˓→ring=ZZ, default_prec=3)
sage: (49*x^3-1).log()
3*log(x) + 2*log(7) - 1/49*x^(-3) - 1/4802*x^(-6) ... + O(x^(-12))
sage: _.parent()
Asymptotic Ring <x^ZZ * log(x)^ZZ> over Symbolic Ring>>> from sage.all import *>>> R = AsymptoticRing(growth_group= x^ZZ * log(x)^ZZ , coefficient_ring=ZZ,␣
˓→default_prec=Integer(3), names=( x ,)); (x,) = R._first_ngens(1)>>> (Integer(49)*x**Integer(3)-Integer(1)).log()
3*log(x) + 2*log(7) - 1/49*x^(-3) - 1/4802*x^(-6) ... + O(x^(-12))>>> _.parent()
Asymptotic Ring <x^ZZ * log(x)^ZZ> over Symbolic Ring

If one wants to avoid this extending to the Symbolic Ring, then the following helps:
sage: L.<log7> = ZZ[]
sage: def mylog(z, base=None):
....:
try:
....:
if ZZ(z).is_power_of(7):....:return log(ZZ(z), 7) * log7....:
except (TypeError, ValueError):
....:
pass
....:
return log(z, base)sage: R.<x> = AsymptoticRing(growth_group= x^ZZ * log(x)^ZZ , coefficient_
˓→ring=L, default_prec=3)
sage: (49*x^3-1).log(locals={ log : mylog})
3*log(x) + 2*log7 - 1/49*x^(-3) - 1/4802*x^(-6) ... + O(x^(-12))>>> from sage.all import *>>> L = ZZ[ log7 ]; (log7,) = L._first_ngens(1)>>> def mylog(z, base=None):
...
try:
...
if ZZ(z).is_power_of(Integer(7)):...
return log(ZZ(z), Integer(7)) * log7...
except (TypeError, ValueError):
...
pass
...
return log(z, base)(continues on next page)

30

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> R = AsymptoticRing(growth_group= x^ZZ * log(x)^ZZ , coefficient_ring=L,␣
˓→default_prec=Integer(3), names=( x ,)); (x,) = R._first_ngens(1)>>> (Integer(49)*x**Integer(3)-Integer(1)).log(locals={ log : mylog})
3*log(x) + 2*log7 - 1/49*x^(-3) - 1/4802*x^(-6) ... + O(x^(-12))

A log-function can also be specified to always be used with the asymptotic ring:sage: R.<x> = AsymptoticRing(growth_group= x^ZZ * log(x)^ZZ , coefficient_
˓→ring=L, default_prec=3, locals={ log : mylog})
sage: log(49*x^3-1)
3*log(x) + 2*log7 - 1/49*x^(-3) - 1/4802*x^(-6) - 1/352947*x^(-9) + O(x^(-12))>>> from sage.all import *>>> R = AsymptoticRing(growth_group= x^ZZ * log(x)^ZZ , coefficient_ring=L,␣
˓→default_prec=Integer(3), locals={ log : mylog}, names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> log(Integer(49)*x**Integer(3)-Integer(1))
3*log(x) + 2*log7 - 1/49*x^(-3) - 1/4802*x^(-6) - 1/352947*x^(-9) + O(x^(-12))

map_coefficients(f, new_coefficient_ring=None)
Return the asymptotic expansion obtained by applying f to each coefficient of this asymptotic expansion.
INPUT:• f – a callable. A coefficient 𝑐 will be mapped to 𝑓 (𝑐).
• new_coefficient_ring – (default: None) a ring.
OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: A.<n> = AsymptoticRing(growth_group= n^ZZ , coefficient_ring=ZZ)
sage: a = n^4 + 2*n^3 + 3*n^2 + O(n)sage: a.map_coefficients(lambda c: c+1)
2*n^4 + 3*n^3 + 4*n^2 + O(n)sage: a.map_coefficients(lambda c: c-2)-n^4 + n^2 + O(n)>>> from sage.all import *>>> A = AsymptoticRing(growth_group= n^ZZ , coefficient_ring=ZZ, names=( n ,˓→)); (n,) = A._first_ngens(1)>>> a = n**Integer(4) + Integer(2)*n**Integer(3) + Integer(3)*n**Integer(2) +␣˓→O(n)>>> a.map_coefficients(lambda c: c+Integer(1))
2*n^4 + 3*n^3 + 4*n^2 + O(n)>>> a.map_coefficients(lambda c: c-Integer(2))-n^4 + n^2 + O(n)monomial_coefficient(monomial)
Return the coefficient in the base ring of the given monomial in this expansion.
INPUT:• monomial – a monomial element which can be converted into the asymptotic ring of this element

4.1. Asymptotic Ring

31

Asymptotic Expansions, Release 10.4

OUTPUT:An element of the coefficient ring.
EXAMPLES:
sage: R.<m, n> = AsymptoticRing("m^QQ*n^QQ", QQ)
sage: ae = 13 + 42/n + 2/n/m + O(n^-2)
sage: ae.monomial_coefficient(1/n)
42
sage: ae.monomial_coefficient(1/n^3)0sage: R.<n> = AsymptoticRing("n^QQ", ZZ)
sage: ae.monomial_coefficient(1/n)
42
sage: ae.monomial_coefficient(1)13>>> from sage.all import *>>> R = AsymptoticRing("m^QQ*n^QQ", QQ, names=( m , n ,)); (m, n,) = R._
˓→first_ngens(2)>>> ae = Integer(13) + Integer(42)/n + Integer(2)/n/m + O(n**-Integer(2))>>> ae.monomial_coefficient(Integer(1)/n)42>>> ae.monomial_coefficient(Integer(1)/n**Integer(3))
0>>> R = AsymptoticRing("n^QQ", ZZ, names=( n ,)); (n,) = R._first_ngens(1)>>> ae.monomial_coefficient(Integer(1)/n)42>>> ae.monomial_coefficient(Integer(1))
13plot_comparison(variable, function, values, rescaled=True, ring=Real Interval Field with 53 bits ofprecision, relative_tolerance=0.025, **kwargs)
Plot the (rescaled) difference between this asymptotic expansion and the given values.
INPUT:• variable – an asymptotic expansion or a string.
• function – a callable or symbolic expression giving the comparison values.
• values – a list or iterable of values where the comparison shall be carried out.
• rescaled – (default: True) determines whether the difference is divided by the error term of theasymptotic expansion.
• ring – (default: RIF) the parent into which the difference is converted.
• relative_tolerance – (default: 0.025). Raise error when relative error exceeds this tolerance.
Other keyword arguments are passed to list_plot().
OUTPUT:
A graphics object.
Note: If rescaled (i.e. divided by the error term), the output should be bounded.
This method is mainly meant to have an easily usable plausibility check for asymptotic expansion created insome way.

32

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

EXAMPLES:
We want to check the quality of the asymptotic expansion of the harmonic numbers:
sage: A.<n> = AsymptoticRing( n^ZZ * log(n)^ZZ , SR)
sage: def H(n):....:return sum(1/k for k in srange(1, n+1))
sage: H_expansion = (log(n) + euler_gamma + 1/(2*n)....:- 1/(12*n^2) + O(n^-4))sage: H_expansion.plot_comparison(n, H, srange(1, 30))
Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> A = AsymptoticRing( n^ZZ * log(n)^ZZ , SR, names=( n ,)); (n,) = A._first_
˓→ngens(1)>>> def H(n):...
return sum(Integer(1)/k for k in srange(Integer(1), n+Integer(1)))>>> H_expansion = (log(n) + euler_gamma + Integer(1)/(Integer(2)*n)...
- Integer(1)/(Integer(12)*n**Integer(2)) + O(n**˓→Integer(4)))>>> H_expansion.plot_comparison(n, H, srange(Integer(1), Integer(30)))
Graphics object consisting of 1 graphics primitive

Alternatively, the unscaled (absolute) difference can be plotted as well:sage: H_expansion.plot_comparison(n, H, srange(1, 30),....:
rescaled=False)
Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> H_expansion.plot_comparison(n, H, srange(Integer(1), Integer(30)),...
rescaled=False)
Graphics object consisting of 1 graphics primitive

Additional keywords are passed to list_plot():
sage: H_expansion.plot_comparison(n, H, srange(1, 30),....:
plotjoined=True, marker= o ,....:color= green )Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> H_expansion.plot_comparison(n, H, srange(Integer(1), Integer(30)),...
plotjoined=True, marker= o ,...
color= green )Graphics object consisting of 1 graphics primitive

See also:
compare_with_values()
pow(exponent, precision=None)
Calculate the power of this asymptotic expansion to the given exponent.
INPUT:• exponent – an element.
• precision – the precision used for truncating the expansion. If None (default value) is used, thedefault precision of the parent is used.
4.1. Asymptotic Ring

33

Asymptotic Expansions, Release 10.4

OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: Q.<x> = AsymptoticRing(growth_group= x^QQ , coefficient_ring=QQ)
sage: x^(1/7)
x^(1/7)sage: (x^(1/2) + O(x^0))^15x^(15/2) + O(x^7)>>> from sage.all import *>>> Q = AsymptoticRing(growth_group= x^QQ , coefficient_ring=QQ, names=( x ,˓→)); (x,) = Q._first_ngens(1)>>> x**(Integer(1)/Integer(7))
x^(1/7)>>> (x**(Integer(1)/Integer(2)) + O(x**Integer(0)))**Integer(15)x^(15/2) + O(x^7)
sage: Z.<y> = AsymptoticRing(growth_group= y^ZZ , coefficient_ring=ZZ)
sage: y^(1/7)
y^(1/7)sage: _.parent()
Asymptotic Ring <y^QQ> over Rational Field
sage: (y^2 + O(y))^(1/2)
y + O(1)sage: (y^2 + O(y))^(-2)
y^(-4) + O(y^(-5))
sage: (1 + 1/y + O(1/y^3))^pi
1 + pi*y^(-1) + (1/2*pi*(pi - 1))*y^(-2) + O(y^(-3))>>> from sage.all import *>>> Z = AsymptoticRing(growth_group= y^ZZ , coefficient_ring=ZZ, names=( y ,˓→)); (y,) = Z._first_ngens(1)>>> y**(Integer(1)/Integer(7))
y^(1/7)>>> _.parent()
Asymptotic Ring <y^QQ> over Rational Field>>> (y**Integer(2) + O(y))**(Integer(1)/Integer(2))
y + O(1)>>> (y**Integer(2) + O(y))**(-Integer(2))
y^(-4) + O(y^(-5))>>> (Integer(1) + Integer(1)/y + O(Integer(1)/y**Integer(3)))**pi
1 + pi*y^(-1) + (1/2*pi*(pi - 1))*y^(-2) + O(y^(-3))
sage: B.<z> = AsymptoticRing(growth_group= z^QQ * log(z)^QQ , coefficient_
˓→ring=QQ)
sage: (z^2 + O(z))^(1/2)
z + O(1)>>> from sage.all import *>>> B = AsymptoticRing(growth_group= z^QQ * log(z)^QQ , coefficient_ring=QQ,␣
˓→names=( z ,)); (z,) = B._first_ngens(1)>>> (z**Integer(2) + O(z))**(Integer(1)/Integer(2))
z + O(1)34

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: A.<x> = AsymptoticRing( QQ^x * x^SR * log(x)^ZZ , QQ)
sage: x * 2^x2^x*x
sage: 5^x * 2^x
10^x
sage: 2^log(x)x^(log(2))
sage: 2^(x + 1/x)
2^x + log(2)*2^x*x^(-1) + 1/2*log(2)^2*2^x*x^(-2) + ... + O(2^x*x^(-20))
sage: _.parent()
Asymptotic Ring <QQ^x * x^SR * log(x)^QQ * Signs^x> over Symbolic Ring>>> from sage.all import *>>> A = AsymptoticRing( QQ^x * x^SR * log(x)^ZZ , QQ, names=( x ,)); (x,) = A.
˓→_first_ngens(1)>>> x * Integer(2)**x2^x*x>>> Integer(5)**x * Integer(2)**x
10^x>>> Integer(2)**log(x)x^(log(2))>>> Integer(2)**(x + Integer(1)/x)2^x + log(2)*2^x*x^(-1) + 1/2*log(2)^2*2^x*x^(-2) + ... + O(2^x*x^(-20))>>> _.parent()
Asymptotic Ring <QQ^x * x^SR * log(x)^QQ * Signs^x> over Symbolic Ringsage: C.<c> = AsymptoticRing(growth_group= QQ^c * c^QQ , coefficient_ring=QQ,␣
˓→default_prec=5)
sage: (3 + 1/c^2)^c
3^c + 1/3*3^c*c^(-1) + 1/18*3^c*c^(-2) - 4/81*3^c*c^(-3)- 35/1944*3^c*c^(-4) + O(3^c*c^(-5))
sage: _.parent()
Asymptotic Ring <QQ^c * c^QQ * Signs^c> over Rational Field
sage: (2 + (1/3)^c)^c2^c + 1/2*(2/3)^c*c + 1/8*(2/9)^c*c^2 - 1/8*(2/9)^c*c+ 1/48*(2/27)^c*c^3 + O((2/27)^c*c^2)
sage: _.parent()
Asymptotic Ring <QQ^c * c^QQ * Signs^c> over Rational Field>>> from sage.all import *>>> C = AsymptoticRing(growth_group= QQ^c * c^QQ , coefficient_ring=QQ,␣
˓→default_prec=Integer(5), names=( c ,)); (c,) = C._first_ngens(1)>>> (Integer(3) + Integer(1)/c**Integer(2))**c3^c + 1/3*3^c*c^(-1) + 1/18*3^c*c^(-2) - 4/81*3^c*c^(-3)- 35/1944*3^c*c^(-4) + O(3^c*c^(-5))>>> _.parent()
Asymptotic Ring <QQ^c * c^QQ * Signs^c> over Rational Field>>> (Integer(2) + (Integer(1)/Integer(3))**c)**c2^c + 1/2*(2/3)^c*c + 1/8*(2/9)^c*c^2 - 1/8*(2/9)^c*c+ 1/48*(2/27)^c*c^3 + O((2/27)^c*c^2)>>> _.parent()
Asymptotic Ring <QQ^c * c^QQ * Signs^c> over Rational Fieldrpow(base, precision=None, locals=None)
Return the power of base to this asymptotic expansion.
INPUT:
4.1. Asymptotic Ring

35

Asymptotic Expansions, Release 10.4

• base – an element or e .
• precision – the precision used for truncating the expansion. If None (default value) is used, thedefault precision of the parent is used.
• 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:
An asymptotic expansion.
EXAMPLES:
sage: A.<x> = AsymptoticRing( x^ZZ , QQ)
sage: (1/x).rpow( e , precision=5)
1 + x^(-1) + 1/2*x^(-2) + 1/6*x^(-3) + 1/24*x^(-4) + O(x^(-5))>>> from sage.all import *>>> A = AsymptoticRing( x^ZZ , QQ, names=( x ,)); (x,) = A._first_ngens(1)>>> (Integer(1)/x).rpow( e , precision=Integer(5))
1 + x^(-1) + 1/2*x^(-2) + 1/6*x^(-3) + 1/24*x^(-4) + O(x^(-5))

show()
Pretty-print this asymptotic expansion.
OUTPUT:
Nothing, the representation is printed directly on the screen.
EXAMPLES:
sage: A.<x> = AsymptoticRing( QQ^x * x^QQ * log(x)^QQ , SR.subring(no_˓→variables=True))sage: (pi/2 * 5^x * x^(42/17) - sqrt(euler_gamma) * log(x)^(-7/8)).show()
1/2*pi*5^x*x^(42/17) - sqrt(euler_gamma)*log(x)^(-7/8)>>> from sage.all import *>>> A = AsymptoticRing( QQ^x * x^QQ * log(x)^QQ , SR.subring(no_˓→variables=True), names=( x ,)); (x,) = A._first_ngens(1)>>> (pi/Integer(2) * Integer(5)**x * x**(Integer(42)/Integer(17)) -␣˓→sqrt(euler_gamma) * log(x)**(-Integer(7)/Integer(8))).show()
1/2*pi*5^x*x^(42/17) - sqrt(euler_gamma)*log(x)^(-7/8)

sqrt(precision=None)
Return the square root of this asymptotic expansion.
INPUT:• precision – the precision used for truncating the expansion. If None (default value) is used, thedefault precision of the parent is used.
OUTPUT:
An asymptotic expansion.
EXAMPLES:

36

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: A.
 = AsymptoticRing(growth_group= s^QQ , coefficient_ring=QQ)
sage: s.sqrt()s^(1/2)sage: a = (1 + 1/s).sqrt(precision=6); a
1 + 1/2*s^(-1) - 1/8*s^(-2) + 1/16*s^(-3)- 5/128*s^(-4) + 7/256*s^(-5) + O(s^(-6))>>> from sage.all import *>>> A = AsymptoticRing(growth_group= s^QQ , coefficient_ring=QQ, names=( s ,˓→)); (s,) = A._first_ngens(1)>>> s.sqrt()s^(1/2)>>> a = (Integer(1) + Integer(1)/s).sqrt(precision=Integer(6)); a
1 + 1/2*s^(-1) - 1/8*s^(-2) + 1/16*s^(-3)- 5/128*s^(-4) + 7/256*s^(-5) + O(s^(-6))

See also:
pow(), rpow(), exp().
subs(rules=None, domain=None, **kwds)
Substitute the given rules in this asymptotic expansion.
INPUT:• rules – a dictionary.
• kwds – keyword arguments will be added to the substitution rules.
• domain – (default: None) a parent. The neutral elements 0 and 1 (rules for the keys _zero_
and _one_ , see note box below) are taken out of this domain. If None, then this is determined
automatically.
OUTPUT:An object.
Note: The neutral element of the asymptotic ring is replaced by the value to the key _zero_ ; the neutral
element of the growth group is replaced by the value to the key _one_ .
EXAMPLES:
sage: A.<x> = AsymptoticRing(growth_group= (e^x)^QQ * x^ZZ * log(x)^ZZ ,␣˓→coefficient_ring=QQ, default_prec=5)>>> from sage.all import *>>> A = AsymptoticRing(growth_group= (e^x)^QQ * x^ZZ * log(x)^ZZ ,␣˓→coefficient_ring=QQ, default_prec=Integer(5), names=( x ,)); (x,) = A._˓→first_ngens(1)sage: (e^x * x^2 + log(x)).subs(x=SR( s ))s^2*e^s + log(s)sage: _.parent()
Symbolic Ring

4.1. Asymptotic Ring

37

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> (e**x * x**Integer(2) + log(x)).subs(x=SR( s ))s^2*e^s + log(s)>>> _.parent()
Symbolic Ringsage: (x^3 + x + log(x)).subs(x=x+5).truncate(5)x^3 + 15*x^2 + 76*x + log(x) + 130 + O(x^(-1))
sage: _.parent()
Asymptotic Ring <(e^x)^QQ * x^ZZ * log(x)^ZZ> over Rational Field>>> from sage.all import *>>> (x**Integer(3) + x + log(x)).subs(x=x+Integer(5)).truncate(Integer(5))
x^3 + 15*x^2 + 76*x + log(x) + 130 + O(x^(-1))>>> _.parent()
Asymptotic Ring <(e^x)^QQ * x^ZZ * log(x)^ZZ> over Rational Field
sage: (e^x * x^2 + log(x)).subs(x=2*x)4*(e^x)^2*x^2 + log(x) + log(2)sage: _.parent()
Asymptotic Ring <(e^x)^QQ * x^QQ * log(x)^QQ> over Symbolic Ring>>> from sage.all import *>>> (e**x * x**Integer(2) + log(x)).subs(x=Integer(2)*x)
4*(e^x)^2*x^2 + log(x) + log(2)>>> _.parent()
Asymptotic Ring <(e^x)^QQ * x^QQ * log(x)^QQ> over Symbolic Ringsage: (x^2 + log(x)).subs(x=4*x+2).truncate(5)16*x^2 + 16*x + log(x) + 2*log(2) + 4 + 1/2*x^(-1) + O(x^(-2))
sage: _.parent()
Asymptotic Ring <(e^x)^QQ * x^ZZ * log(x)^ZZ> over Symbolic Ring>>> from sage.all import *>>> (x**Integer(2) + log(x)).subs(x=Integer(4)*x+Integer(2)).
˓→truncate(Integer(5))
16*x^2 + 16*x + log(x) + 2*log(2) + 4 + 1/2*x^(-1) + O(x^(-2))>>> _.parent()
Asymptotic Ring <(e^x)^QQ * x^ZZ * log(x)^ZZ> over Symbolic Ringsage: (e^x * x^2 + log(x)).subs(x=RIF(pi))
229.534211738584?
sage: _.parent()
Real Interval Field with 53 bits of precision>>> from sage.all import *>>> (e**x * x**Integer(2) + log(x)).subs(x=RIF(pi))
229.534211738584?
>>> _.parent()
Real Interval Field with 53 bits of precision

See also:
sage.symbolic.expression.Expression.subs()

38

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

property summands
The summands of this asymptotic expansion stored in the underlying data structure (a MutablePoset).
EXAMPLES:
sage: R.<x> = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: expr = 7*x^12 + x^5 + O(x^3)
sage: expr.summands
poset(O(x^3), x^5, 7*x^12)>>> from sage.all import *>>> R = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ, names=( x ,˓→)); (x,) = R._first_ngens(1)>>> expr = Integer(7)*x**Integer(12) + x**Integer(5) + O(x**Integer(3))>>> expr.summands
poset(O(x^3), x^5, 7*x^12)

See also:
sage.data_structures.mutable_poset.MutablePoset
symbolic_expression(R=None)
Return this asymptotic expansion as a symbolic expression.
INPUT:• R – (a subring of) the symbolic ring or None. The output will be an element of R. If None, then thesymbolic ring is used.
OUTPUT:
A symbolic expression.
EXAMPLES:
sage: A.<x, y, z> = AsymptoticRing(growth_group= x^ZZ * y^QQ * log(y)^QQ *␣˓→(QQ_+)^z * z^QQ , coefficient_ring=QQ)
sage: SR(A.an_element()) # indirect doctest
1/8*(1/8)^z*x^3*y^(3/2)*z^(3/2)*log(y)^(3/2) +Order((1/2)^z*x*sqrt(y)*sqrt(z)*sqrt(log(y)))
sage: A.<x, y, z> = AsymptoticRing(growth_group= x^ZZ * y^QQ * log(y)^QQ *␣˓→(QQ_+)^z * z^QQ , coefficient_ring=QQ)
sage: SR(A.an_element()) # indirect doctest
1/8*(1/8)^z*x^3*y^(3/2)*z^(3/2)*log(y)^(3/2) +Order((1/2)^z*x*sqrt(y)*sqrt(z)*sqrt(log(y)))>>> from sage.all import *>>> A = AsymptoticRing(growth_group= x^ZZ * y^QQ * log(y)^QQ * (QQ_+)^z * z^QQ˓→ , coefficient_ring=QQ, names=( x ,y , z ,)); (x, y, z,) = A._first_
˓→ngens(3)>>> SR(A.an_element()) # indirect doctest
1/8*(1/8)^z*x^3*y^(3/2)*z^(3/2)*log(y)^(3/2) +Order((1/2)^z*x*sqrt(y)*sqrt(z)*sqrt(log(y)))>>> A = AsymptoticRing(growth_group= x^ZZ * y^QQ * log(y)^QQ * (QQ_+)^z * z^QQ˓→ , coefficient_ring=QQ, names=( x ,y , z ,)); (x, y, z,) = A._first_
˓→ngens(3)>>> SR(A.an_element()) # indirect doctest(continues on next page)

4.1. Asymptotic Ring

39

Asymptotic Expansions, Release 10.4

(continued from previous page)

1/8*(1/8)^z*x^3*y^(3/2)*z^(3/2)*log(y)^(3/2) +Order((1/2)^z*x*sqrt(y)*sqrt(z)*sqrt(log(y)))

truncate(precision=None)
Truncate this asymptotic expansion.
INPUT:• precision – a positive integer or None. Number of summands that are kept. If None (default value)
is given, then default_prec from the parent is used.
OUTPUT:
An asymptotic expansion.
Note: For example, truncating an asymptotic expansion with precision=20 does not yield an expansion
with exactly 20 summands! Rather than that, it keeps the 20 summands with the largest growth, and adds
appropriate 𝑂-Terms.
EXAMPLES:
sage: R.<x> = AsymptoticRing( x^ZZ , QQ)
sage: ex = sum(x^k for k in range(5)); exx^4 + x^3 + x^2 + x + 1
sage: ex.truncate(precision=2)x^4 + x^3 + O(x^2)
sage: ex.truncate(precision=0)O(x^4)
sage: ex.truncate()x^4 + x^3 + x^2 + x + 1>>> from sage.all import *>>> R = AsymptoticRing( x^ZZ , QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> ex = sum(x**k for k in range(Integer(5))); exx^4 + x^3 + x^2 + x + 1>>> ex.truncate(precision=Integer(2))
x^4 + x^3 + O(x^2)>>> ex.truncate(precision=Integer(0))
O(x^4)>>> ex.truncate()x^4 + x^3 + x^2 + x + 1

variable_names()
Return the names of the variables of this asymptotic expansion.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: A.<m, n> = AsymptoticRing( QQ^m * m^QQ * n^ZZ * log(n)^ZZ , QQ)
sage: (4*2^m*m^4*log(n)).variable_names()( m , n )sage: (4*2^m*m^4).variable_names()( m ,)(continues on next page)

40

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: (4*log(n)).variable_names()( n ,)
sage: (4*m^3).variable_names()( m ,)
sage: (4*m^0).variable_names()()
sage: (4*2^m*m^4 + log(n)).variable_names()( m , n )sage: (2^m + m^4 + log(n)).variable_names()( m , n )sage: (2^m + m^4).variable_names()( m ,)>>> from sage.all import *>>> A = AsymptoticRing( QQ^m * m^QQ * n^ZZ * log(n)^ZZ , QQ, names=( m ,˓→)); (m, n,) = A._first_ngens(2)>>> (Integer(4)*Integer(2)**m*m**Integer(4)*log(n)).variable_names()( m , n )>>> (Integer(4)*Integer(2)**m*m**Integer(4)).variable_names()( m ,)>>> (Integer(4)*log(n)).variable_names()( n ,)>>> (Integer(4)*m**Integer(3)).variable_names()( m ,)>>> (Integer(4)*m**Integer(0)).variable_names()()>>> (Integer(4)*Integer(2)**m*m**Integer(4) + log(n)).variable_names()( m , n )>>> (Integer(2)**m + m**Integer(4) + log(n)).variable_names()( m , n )>>> (Integer(2)**m + m**Integer(4)).variable_names()( m ,)n ,class sage.rings.asymptotic.asymptotic_ring.AsymptoticRing(growth_group,coefficient_ring, category,default_prec,
term_monoid_factory,
locals)Bases: Parent, UniqueRepresentation, WithLocals
A ring consisting of asymptotic expansions.
INPUT:• growth_group – either a partially ordered group (see (Asymptotic) Growth Groups) or a string describing
such a growth group (see GrowthGroupFactory).
• coefficient_ring – the ring which contains the coefficients of the expansions.
• default_prec – a positive integer. This is the number of summands that are kept before truncating an
infinite series.
• category – the category of the parent can be specified in order to broaden the base structure. It has to bea subcategory of Category of rings. This is also the default category if None is specified.
• term_monoid_factory – a TermMonoidFactory. If None, then DefaultTermMonoidFactory is used.
• locals – a dictionary which may contain the following keys and values:
4.1. Asymptotic Ring

41

Asymptotic Expansions, Release 10.4–

log – value: a function.
If not given, then the usual log is taken.
AsymptoticExpansion.log().)(See also

EXAMPLES:
We begin with the construction of an asymptotic ring in various ways. First, we simply pass a string specifying theunderlying growth group:sage: R1_x.<x> = AsymptoticRing(growth_group= x^QQ , coefficient_ring=QQ); R1_x
Asymptotic Ring <x^QQ> over Rational Field
sage: xx>>> from sage.all import *>>> R1_x = AsymptoticRing(growth_group= x^QQ , coefficient_ring=QQ, names=( x ,));
˓→ (x,) = R1_x._first_ngens(1); R1_x
Asymptotic Ring <x^QQ> over Rational Field>>> xxThis is equivalent to the following code, which explicitly specifies the underlying growth group:sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G_QQ = GrowthGroup( x^QQ )sage: R2_x.<x> = AsymptoticRing(growth_group=G_QQ, coefficient_ring=QQ); R2_x
Asymptotic Ring <x^QQ> over Rational Field>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G_QQ = GrowthGroup( x^QQ )>>> R2_x = AsymptoticRing(growth_group=G_QQ, coefficient_ring=QQ, names=( x ,));␣
˓→(x,) = R2_x._first_ngens(1); R2_x
Asymptotic Ring <x^QQ> over Rational Field

Of course, the coefficient ring of the asymptotic ring and the base ring of the underlying growth group do not needto coincide:sage: R_ZZ_x.<x> = AsymptoticRing(growth_group= x^QQ , coefficient_ring=ZZ); R_ZZ_
˓→xAsymptotic Ring <x^QQ> over Integer Ring>>> from sage.all import *>>> R_ZZ_x = AsymptoticRing(growth_group= x^QQ , coefficient_ring=ZZ, names=( x ,˓→)); (x,) = R_ZZ_x._first_ngens(1); R_ZZ_x
Asymptotic Ring <x^QQ> over Integer Ring

Note, we can also create and use logarithmic growth groups:
sage: R_log = AsymptoticRing(growth_group= log(x)^ZZ , coefficient_ring=QQ); R_log
Asymptotic Ring <log(x)^ZZ> over Rational Field>>> from sage.all import *>>> R_log = AsymptoticRing(growth_group= log(x)^ZZ , coefficient_ring=QQ); R_log
Asymptotic Ring <log(x)^ZZ> over Rational Field

Other growth groups are available. See Asymptotic Ring for more examples.
Below there are some technical details.
42

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

According to the conventions for parents, uniqueness is ensured:
sage: R1_x is R2_x
True>>> from sage.all import *>>> R1_x is R2_x
True

Furthermore, the coercion framework is also involved. Coercion between two asymptotic rings is possible (giventhat the underlying growth groups and coefficient rings are chosen appropriately):
sage: R1_x.has_coerce_map_from(R_ZZ_x)
True>>> from sage.all import *>>> R1_x.has_coerce_map_from(R_ZZ_x)
True

Additionally, for the sake of convenience, the coefficient ring also coerces into the asymptotic ring (representing
constant quantities):
sage: R1_x.has_coerce_map_from(QQ)
True>>> from sage.all import *>>> R1_x.has_coerce_map_from(QQ)
True

It is possible to customize the terms in an asymptotic expansion:
sage: from sage.rings.asymptotic.term_monoid import ExactTermMonoid, OTermMonoid
sage: from sage.rings.asymptotic.term_monoid import TermMonoidFactory
sage: class MyExactTermMonoid(ExactTermMonoid):
....:
pass
sage: class MyOTermMonoid(OTermMonoid):
....:
pass
sage: MyTermMonoid = TermMonoidFactory( MyTermMonoid ,....:exact_term_monoid_class=MyExactTermMonoid,....:
O_term_monoid_class=MyOTermMonoid)
sage: G = GrowthGroup( x^ZZ )sage: A.<n> = AsymptoticRing(growth_group=G, coefficient_ring=QQ, term_monoid_
˓→factory=MyTermMonoid)
sage: a = A.an_element(); a1/8*x^3 + O(x)sage: for t in a.summands.elements_topological(reverse=True):....:
print(t, type(t))
1/8*x^3 <class __main__.MyExactTermMonoid_with_category.element_class >O(x) <class __main__.MyOTermMonoid_with_category.element_class >>>> from sage.all import *>>> from sage.rings.asymptotic.term_monoid import ExactTermMonoid, OTermMonoid>>> from sage.rings.asymptotic.term_monoid import TermMonoidFactory>>> class MyExactTermMonoid(ExactTermMonoid):...
pass>>> class MyOTermMonoid(OTermMonoid):(continues on next page)

4.1. Asymptotic Ring

43

Asymptotic Expansions, Release 10.4

(continued from previous page)

...
pass
>>> MyTermMonoid = TermMonoidFactory( MyTermMonoid ,...
exact_term_monoid_class=MyExactTermMonoid,...
O_term_monoid_class=MyOTermMonoid)>>> G = GrowthGroup( x^ZZ )>>> A = AsymptoticRing(growth_group=G, coefficient_ring=QQ, term_monoid_
˓→factory=MyTermMonoid, names=( n ,)); (n,) = A._first_ngens(1)>>> a = A.an_element(); a1/8*x^3 + O(x)>>> for t in a.summands.elements_topological(reverse=True):...
print(t, type(t))
1/8*x^3 <class __main__.MyExactTermMonoid_with_category.element_class >O(x) <class __main__.MyOTermMonoid_with_category.element_class >static B(expression, valid_from=0)
Create a B-term.
INPUT:• 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 anumber is passed to valid_from, then the lower bounds for all variables of the asymptotic expansion
are set to this number
OUTPUT:A B-term
EXAMPLES:
sage: A.<x> = AsymptoticRing(growth_group= x^ZZ * QQ^y , coefficient_ring=QQ)
sage: A.B(2*x^3, {x: 5})B(2*x^3, x >= 5)>>> from sage.all import *>>> A = AsymptoticRing(growth_group= x^ZZ * QQ^y , coefficient_ring=QQ,␣
˓→names=( x ,)); (x,) = A._first_ngens(1)>>> A.B(Integer(2)*x**Integer(3), {x: Integer(5)})
B(2*x^3, x >= 5)Element
alias of AsymptoticExpansion
change_parameter(**kwds)
Return an asymptotic ring 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.
• category – (default: None) the new category.
• default_prec – (default: None) the new default precision.
OUTPUT:
An asymptotic ring.
EXAMPLES:
44

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: A = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: A.change_parameter(coefficient_ring=QQ)
Asymptotic Ring <x^ZZ> over Rational Field>>> from sage.all import *>>> A = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)>>> A.change_parameter(coefficient_ring=QQ)
Asymptotic Ring <x^ZZ> over Rational Field

property coefficient_ring
The coefficient ring of this asymptotic ring.
EXAMPLES:
sage: AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: AR.coefficient_ring
Integer Ring>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)>>> AR.coefficient_ring
Integer Ring

coefficients_of_generating_function(function, singularities, precision=None,
return_singular_expansions=False, error_term=None)
Return the asymptotic growth of the coefficients of some generating function by means of Singularity Analysis.
INPUT:• function – a callable function in one variable.
• singularities – list of dominant singularities of the function.
• precision – (default: None) an integer. If None, then the default precision of the asymptotic ringis used.
• return_singular_expansions – (default: False) a boolean. If set, the singular expansions
are also returned.
• error_term – (default: None) an asymptotic expansion. If None, then this is interpreted as zero.
The contributions of the coefficients are added to error_term during Singularity Analysis.
OUTPUT:• If return_singular_expansions=False: An asymptotic expansion from this ring.
• If return_singular_expansions=True: A named tuple with components asymptotic_expansion and singular_expansions. The former contains an asymptotic expansion
from this ring, the latter is a dictionary which contains the singular expansions around the singularities.
Todo: Make this method more usable by implementing the processing of symbolic expressions.
EXAMPLES:
Catalan numbers:

4.1. Asymptotic Ring

45

Asymptotic Expansions, Release 10.4

sage: def catalan(z):....:return (1-(1-4*z)^(1/2))/(2*z)
sage: B.<n> = AsymptoticRing( QQ^n * n^QQ , QQ)
sage: B.coefficients_of_generating_function(catalan, (1/4,), precision=3)
1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2)+ 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-4))
sage: B.coefficients_of_generating_function(catalan, (1/4,), precision=2,....:
return_singular_expansions=True)
SingularityAnalysisResult(asymptotic_expansion=1/sqrt(pi)*4^n*n^(-3/2)- 9/8/sqrt(pi)*4^n*n^(-5/2) + O(4^n*n^(-3)),
singular_expansions={1/4: 2 - 2*T^(-1/2)+ 2*T^(-1) - 2*T^(-3/2) + O(T^(-2))})>>> from sage.all import *>>> def catalan(z):...
return (Integer(1)-(Integer(1)-Integer(4)*z)**(Integer(1)/˓→Integer(2)))/(Integer(2)*z)>>> B = AsymptoticRing( QQ^n * n^QQ , QQ, names=( n ,)); (n,) = B._first_
˓→ngens(1)>>> B.coefficients_of_generating_function(catalan, (Integer(1)/Integer(4),),␣
˓→precision=Integer(3))
1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2)+ 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-4))>>> B.coefficients_of_generating_function(catalan, (Integer(1)/Integer(4),),␣
˓→precision=Integer(2),...
return_singular_expansions=True)
SingularityAnalysisResult(asymptotic_expansion=1/sqrt(pi)*4^n*n^(-3/2)- 9/8/sqrt(pi)*4^n*n^(-5/2) + O(4^n*n^(-3)),
singular_expansions={1/4: 2 - 2*T^(-1/2)+ 2*T^(-1) - 2*T^(-3/2) + O(T^(-2))})

Unit fractions:sage: def logarithmic(z):....:return -log(1-z)
sage: B.coefficients_of_generating_function(logarithmic, (1,), precision=5)n^(-1) + O(n^(-3))>>> from sage.all import *>>> def logarithmic(z):...
return -log(Integer(1)-z)>>> B.coefficients_of_generating_function(logarithmic, (Integer(1),),␣
˓→precision=Integer(5))
n^(-1) + O(n^(-3))

Harmonic numbers:
sage: def harmonic(z):....:return -log(1-z)/(1-z)
sage: B.<n> = AsymptoticRing( QQ^n * n^QQ * log(n)^QQ , QQ)
sage: ex = B.coefficients_of_generating_function(harmonic, (1,),␣
˓→precision=13); exlog(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4)+ O(n^(-6))
sage: ex.has_same_summands(asymptotic_expansions.HarmonicNumber(....:n , precision=5))
True

46

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> def harmonic(z):...
return -log(Integer(1)-z)/(Integer(1)-z)>>> B = AsymptoticRing( QQ^n * n^QQ * log(n)^QQ , QQ, names=( n ,)); (n,) = B.
˓→_first_ngens(1)>>> ex = B.coefficients_of_generating_function(harmonic, (Integer(1),),␣
˓→precision=Integer(13)); exlog(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4)+ O(n^(-6))>>> ex.has_same_summands(asymptotic_expansions.HarmonicNumber(...
n , precision=Integer(5)))
True

Warning: Once singular expansions around points other than infinity are implemented (Issue #20050),
the output in the case return_singular_expansions will change to return singular expansions
around the singularities.
In the following example, the result is an exact asymptotic expression for sufficiently large 𝑛 (i.e., there might
be finitely many exceptional values). This is encoded by an 𝑂(0) error term:
sage: def f(z):....:return z/(1-z)
sage: B.coefficients_of_generating_function(f, (1,), precision=3)
Traceback (most recent call last):...
NotImplementedOZero: got 1 + O(0)The error term O(0) means 0 for sufficiently large n.
>>> from sage.all import *>>> def f(z):...
return z/(Integer(1)-z)>>> B.coefficients_of_generating_function(f, (Integer(1),),␣
˓→precision=Integer(3))
Traceback (most recent call last):...
NotImplementedOZero: got 1 + O(0)The error term O(0) means 0 for sufficiently large n.

In this case, we can manually intervene by adding an error term that suits us:
sage: B.coefficients_of_generating_function(f, (1,), precision=3,....:
error_term=O(n^-100))
1 + O(n^(-100))>>> from sage.all import *>>> B.coefficients_of_generating_function(f, (Integer(1),),␣
˓→precision=Integer(3),...
error_term=O(n**-Integer(100)))
1 + O(n^(-100))

construction()
Return the construction of this asymptotic ring.
OUTPUT:4.1. Asymptotic Ring

47

Asymptotic Expansions, Release 10.4

A pair whose first entry is an asymptotic ring construction functor and its second entry thecoefficient ring.
EXAMPLES:
sage: A = AsymptoticRing(growth_group= x^ZZ * QQ^y , coefficient_ring=QQ)
sage: A.construction()(AsymptoticRing<x^ZZ * QQ^y * Signs^y>, Rational Field)>>> from sage.all import *>>> A = AsymptoticRing(growth_group= x^ZZ * QQ^y , coefficient_ring=QQ)>>> A.construction()(AsymptoticRing<x^ZZ * QQ^y * Signs^y>, Rational Field)

See also:
Asymptotic Ring, AsymptoticRing, AsymptoticRingFunctor.
create_summand(type, data=None, **kwds)
Create a simple asymptotic expansion consisting of a single summand.
INPUT:• type – ‘O’ or ‘exact’.
• data – the element out of which a summand has to be created.
• growth – an element of the growth_group().
• coefficient – an element of the coefficient_ring().
Note: Either growth and coefficient or data have to be specified.
OUTPUT:
An asymptotic expansion.
Note: This method calls the factory TermMonoid with the appropriate arguments.
EXAMPLES:
sage: R = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: R.create_summand( O , x^2)O(x^2)
sage: R.create_summand( exact , growth=x^456, coefficient=123)
123*x^456
sage: R.create_summand( exact , data=12*x^13)
12*x^13>>> from sage.all import *>>> R = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)>>> R.create_summand( O , x**Integer(2))
O(x^2)>>> R.create_summand( exact , growth=x**Integer(456),␣
˓→coefficient=Integer(123))
123*x^456>>> R.create_summand( exact , data=Integer(12)*x**Integer(13))
12*x^1348

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

property default_prec
The default precision of this asymptotic ring.
This is the parameter used to determine how many summands are kept before truncating an infinite series(which occur when inverting asymptotic expansions).
EXAMPLES:
sage: AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: AR.default_prec
20
sage: AR = AsymptoticRing( x^ZZ , ZZ, default_prec=123)
sage: AR.default_prec
123>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)>>> AR.default_prec
20>>> AR = AsymptoticRing( x^ZZ , ZZ, default_prec=Integer(123))>>> AR.default_prec
123

gen(n=0)
Return the n-th generator of this asymptotic ring.
INPUT:• n – (default: 0) a non-negative integer.
OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: R.<x> = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: R.gen()x>>> from sage.all import *>>> R = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ, names=( x ,˓→)); (x,) = R._first_ngens(1)>>> R.gen()xgens()
Return a tuple with generators of this asymptotic ring.
OUTPUT:
A tuple of asymptotic expansions.
Note: Generators do not necessarily exist. This depends on the underlying growth group. For example,
monomial growth groups have a generator, and exponential growth groups do not.
EXAMPLES:

4.1. Asymptotic Ring

49

Asymptotic Expansions, Release 10.4

sage: AR.<x> = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: AR.gens()(x,)
sage: B.<y,z> = AsymptoticRing(growth_group= y^ZZ * z^ZZ , coefficient_
˓→ring=QQ)
sage: B.gens()(y, z)>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ, names=( x ,˓→)); (x,) = AR._first_ngens(1)>>> AR.gens()(x,)>>> B = AsymptoticRing(growth_group= y^ZZ * z^ZZ , coefficient_ring=QQ,␣
˓→names=( y ,z ,)); (y, z,) = B._first_ngens(2)>>> B.gens()(y, z)

property growth_group
The growth group of this asymptotic ring.
EXAMPLES:
sage: AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: AR.growth_group
Growth Group x^ZZ>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)>>> AR.growth_group
Growth Group x^ZZ

See also:(Asymptotic) Growth Groups
ngens()
Return the number of generators of this asymptotic ring.
OUTPUT:
An integer.
EXAMPLES:
sage: AR.<x> = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: AR.ngens()
1>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ, names=( x ,˓→)); (x,) = AR._first_ngens(1)>>> AR.ngens()
1

some_elements()
Return some elements of this term monoid.

50

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

See TestSuite for a typical use case.
OUTPUT:
An iterator.
EXAMPLES:
sage: from itertools import islice
sage: A = AsymptoticRing(growth_group= z^QQ , coefficient_ring=ZZ)
sage: tuple(islice(A.some_elements(), int(10)))(z^(3/2) + O(z^(1/2)),O(z^(1/2)),z^(3/2) + O(z^(-1/2)),-z^(3/2) + O(z^(1/2)),O(z^(-1/2)),O(z^2),z^6 + O(z^(1/2)),-z^(3/2) + O(z^(-1/2)),O(z^2),z^(3/2) + O(z^(-2)))>>> from sage.all import *>>> from itertools import islice>>> A = AsymptoticRing(growth_group= z^QQ , coefficient_ring=ZZ)>>> tuple(islice(A.some_elements(), int(Integer(10))))(z^(3/2) + O(z^(1/2)),O(z^(1/2)),z^(3/2) + O(z^(-1/2)),-z^(3/2) + O(z^(1/2)),O(z^(-1/2)),O(z^2),z^6 + O(z^(1/2)),-z^(3/2) + O(z^(-1/2)),O(z^2),z^(3/2) + O(z^(-2)))

term_monoid(type)
Return the term monoid of this asymptotic ring of specified type.
INPUT:• type – ‘O’ or ‘exact’, or an instance of an existing term monoid. See TermMonoidFactory formore details.
OUTPUT:
A term monoid object derived from GenericTermMonoid.
EXAMPLES:
sage: AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: AR.term_monoid( exact )Exact Term Monoid x^ZZ with coefficients in Integer Ringsage: AR.term_monoid( O )O-Term Monoid x^ZZ with implicit coefficients in Integer Ringsage: AR.term_monoid(AR.term_monoid( exact ))Exact Term Monoid x^ZZ with coefficients in Integer Ring

4.1. Asymptotic Ring

51

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)>>> AR.term_monoid( exact )Exact Term Monoid x^ZZ with coefficients in Integer Ring>>> AR.term_monoid( O )O-Term Monoid x^ZZ with implicit coefficients in Integer Ring>>> AR.term_monoid(AR.term_monoid( exact ))Exact Term Monoid x^ZZ with coefficients in Integer Ring

property term_monoid_factory
The term monoid factory of this asymptotic ring.
EXAMPLES:
sage: AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)
sage: AR.term_monoid_factoryTerm Monoid Factory sage.rings.asymptotic.term_monoid.
˓→DefaultTermMonoidFactory>>> from sage.all import *>>> AR = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=ZZ)>>> AR.term_monoid_factoryTerm Monoid Factory sage.rings.asymptotic.term_monoid.
˓→DefaultTermMonoidFactory

See also:(Asymptotic) Term Monoids
variable_names()
Return the names of the variables.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: A = AsymptoticRing(growth_group= x^ZZ * QQ^y , coefficient_ring=QQ)
sage: A.variable_names()( x , y )>>> from sage.all import *>>> A = AsymptoticRing(growth_group= x^ZZ * QQ^y , coefficient_ring=QQ)>>> A.variable_names()( x , y )class sage.rings.asymptotic.asymptotic_ring.AsymptoticRingFunctor(growth_group, default_prec=None,
category=None,term_monoid_factory=None,
locals=None,
cls=None)Bases: ConstructionFunctor
A construction functor for asymptotic rings.
INPUT:
52

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

• growth_group – a partially ordered group (see AsymptoticRing or (Asymptotic) Growth Groups fordetails).
• default_prec – None (default) or an integer.
• category – None (default) or a category.
• cls – AsymptoticRing (default) or a derived class.
EXAMPLES:
sage: AsymptoticRing(growth_group= x^ZZ , coefficient_ring=QQ).construction()
˓→indirect doctest(AsymptoticRing<x^ZZ>, Rational Field)>>> from sage.all import *>>> AsymptoticRing(growth_group= x^ZZ , coefficient_ring=QQ).construction()
˓→indirect doctest(AsymptoticRing<x^ZZ>, Rational Field)#␣#␣

See also:
Asymptotic
Ring,
AsymptoticRing,
sage.rings.asymptotic.growth_group.
AbstractGrowthGroupFunctor,
sage.rings.asymptotic.growth_group.
ExponentialGrowthGroupFunctor,
sage.rings.asymptotic.growth_group.
MonomialGrowthGroupFunctor, sage.categories.pushout.ConstructionFunctor.
merge(other)Merge this functor with other if possible.
INPUT:• other – a functor.
OUTPUT:
A functor or None.
EXAMPLES:
sage: X = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=QQ)
sage: Y = AsymptoticRing(growth_group= y^ZZ , coefficient_ring=QQ)
sage: F_X = X.construction()[0]sage: F_Y = Y.construction()[0]sage: F_X.merge(F_X)
AsymptoticRing<x^ZZ>
sage: F_X.merge(F_Y)
AsymptoticRing<x^ZZ * y^ZZ>>>> from sage.all import *>>> X = AsymptoticRing(growth_group= x^ZZ , coefficient_ring=QQ)>>> Y = AsymptoticRing(growth_group= y^ZZ , coefficient_ring=QQ)>>> F_X = X.construction()[Integer(0)]>>> F_Y = Y.construction()[Integer(0)]>>> F_X.merge(F_X)
AsymptoticRing<x^ZZ>>>> F_X.merge(F_Y)
AsymptoticRing<x^ZZ * y^ZZ>rank = 13

4.1. Asymptotic Ring

53

Asymptotic Expansions, Release 10.4

exception sage.rings.asymptotic.asymptotic_ring.NoConvergenceError
Bases: RuntimeError
A special RuntimeError which is raised when an algorithm does not converge/stop.

4.2 Common Asymptotic Expansions
Asymptotic expansions in SageMath can be built through the asymptotic_expansions object. It contains generators for common asymptotic expressions. For example,
sage: asymptotic_expansions.Stirling( n , precision=5)
sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))>>> from sage.all import *>>> asymptotic_expansions.Stirling( n , precision=Integer(5))
sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))

generates the first 5 summands of Stirling’s approximation formula for factorials.
To construct an asymptotic expression manually, you can use the class AsymptoticRing. See asymptotic ring for
more details and a lot of examples.
Asymptotic Expansions
HarmonicNumber()Stirling()
log_Stirling()
Binomial_kn_over_n()
SingularityAnalysis()
ImplicitExpansion()
ImplicitExpansionPeriodicPart()
InverseFunctionAnalysis()

harmonic numbers
Stirling’s approximation formula for factorials
the logarithm of Stirling’s approximation formula for factorials
an asymptotic expansion of the binomial coefficientan asymptotic expansion obtained by singularity analysis
the singular expansion of a function 𝑦(𝑧) satisfying 𝑦(𝑧) = 𝑧Φ(𝑦(𝑧))the singular expansion of the periodic part of a function 𝑦(𝑧) satisfying 𝑦(𝑧) =𝑧Φ(𝑦(𝑧))coefficient growth of a function 𝑦(𝑧) defined implicitly by 𝑦(𝑧) = 𝑧Φ(𝑦(𝑧))AUTHORS:• Daniel Krenn (2015)• Clemens Heuberger (2016)• Benjamin Hackl (2016)
ACKNOWLEDGEMENT:

54

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

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

4.2.1 Classes and Methods
class sage.rings.asymptotic.asymptotic_expansion_generators.
AsymptoticExpansionGenerators
Bases: SageObject
A collection of constructors for several common asymptotic expansions.
A list of all asymptotic expansions in this database is available via tab completion.
“asymptotic_expansions.” and then hit tab to see which expansions are available.

Type

The asymptotic expansions currently in this class include:• HarmonicNumber()• Stirling()• log_Stirling()• Binomial_kn_over_n()• SingularityAnalysis()• ImplicitExpansion()• ImplicitExpansionPeriodicPart()• InverseFunctionAnalysis()static Binomial_kn_over_n(var, k, precision=None, skip_constant_factor=False)
Return the asymptotic expansion of the binomial coefficient 𝑘𝑛 choose 𝑛.
INPUT:• var – a string for the variable name.
• k – a number or symbolic constant.
• precision – (default: None) an integer. If None, then the default precision of the asymptotic ringis used.
• skip_constant_factor– (default: False) a boolean. If set, then the constant factor√︀𝑘/(2𝜋(𝑘 − 1)) is left out. As a consequence, the coefficient ring of the output changes from Symbolic Constants Subring (if False) to Rational Field (if True).
OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: asymptotic_expansions.Binomial_kn_over_n( n , k=2, precision=3)
1/sqrt(pi)*4^n*n^(-1/2)- 1/8/sqrt(pi)*4^n*n^(-3/2)+ 1/128/sqrt(pi)*4^n*n^(-5/2)+ O(4^n*n^(-7/2))
sage: _.parent()
Asymptotic Ring <QQ^n * n^QQ> over Symbolic Constants Subring

4.2. Common Asymptotic Expansions

55

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> asymptotic_expansions.Binomial_kn_over_n( n , k=Integer(2),␣
˓→precision=Integer(3))
1/sqrt(pi)*4^n*n^(-1/2)- 1/8/sqrt(pi)*4^n*n^(-3/2)+ 1/128/sqrt(pi)*4^n*n^(-5/2)+ O(4^n*n^(-7/2))>>> _.parent()
Asymptotic Ring <QQ^n * n^QQ> over Symbolic Constants Subringsage: asymptotic_expansions.Binomial_kn_over_n( n , k=3, precision=3)
1/2*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-1/2)- 7/144*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-3/2)+ 49/20736*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-5/2)+ O((27/4)^n*n^(-7/2))>>> from sage.all import *>>> asymptotic_expansions.Binomial_kn_over_n( n , k=Integer(3),␣
˓→precision=Integer(3))
1/2*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-1/2)- 7/144*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-3/2)+ 49/20736*sqrt(3)/sqrt(pi)*(27/4)^n*n^(-5/2)+ O((27/4)^n*n^(-7/2))
sage: asymptotic_expansions.Binomial_kn_over_n( n , k=7/5, precision=3)
1/2*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-1/2)- 13/112*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-3/2)+ 169/12544*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-5/2)+ O((7/10*7^(2/5)*2^(3/5))^n*n^(-7/2))
sage: _.parent()
Asymptotic Ring <(Symbolic Constants Subring)^n * n^QQ>
over Symbolic Constants Subring>>> from sage.all import *>>> asymptotic_expansions.Binomial_kn_over_n( n , k=Integer(7)/Integer(5),␣
˓→precision=Integer(3))
1/2*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-1/2)- 13/112*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-3/2)+ 169/12544*sqrt(7)/sqrt(pi)*(7/10*7^(2/5)*2^(3/5))^n*n^(-5/2)+ O((7/10*7^(2/5)*2^(3/5))^n*n^(-7/2))>>> _.parent()
Asymptotic Ring <(Symbolic Constants Subring)^n * n^QQ>
over Symbolic Constants Subringstatic HarmonicNumber(var, precision=None, skip_constant_summand=False)
Return the asymptotic expansion of a harmonic number.
INPUT:• var – a string for the variable name.
• precision – (default: None) an integer. If None, then the default precision of the asymptotic ringis used.
• skip_constant_summand – (default: False) a boolean. If set, then the constant summand euler_gamma is left out. As a consequence, the coefficient ring of the output changes from Symbolic
Constants Subring (if False) to Rational Field (if True).

56

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: asymptotic_expansions.HarmonicNumber( n , precision=5)log(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4) + O(n^(-6))>>> from sage.all import *>>> asymptotic_expansions.HarmonicNumber( n , precision=Integer(5))
log(n) + euler_gamma + 1/2*n^(-1) - 1/12*n^(-2) + 1/120*n^(-4) + O(n^(-6))

static ImplicitExpansion(var, phi, tau=None, precision=None)
Return the singular expansion for a function 𝑦(𝑧) defined implicitly by 𝑦(𝑧) = 𝑧Φ(𝑦(𝑧)).
The function Φ is assumed to be analytic around 0. Furthermore, Φ is not allowed to be an affine-linear
function and we require Φ(0) ̸= 0.
Furthermore, it is assumed that there is a unique positive solution 𝜏 of Φ(𝜏 ) − 𝜏 Φ′ (𝜏 ) = 0.
All details are given in Chapter VI.7 of [FS2009].
INPUT:• var – a string for the variable name.
• phi – the function Φ. See the extended description for assumptions on Φ.
• tau – (default: None) the fundamental constant described in the extended description. If None, then
𝜏 is determined automatically if possible.
• precision – (default: None) an integer. If None, then the default precision of the asymptotic ringis used.
OUTPUT:
An asymptotic expansion.
Note: In the given case, the radius of convergence of the function of interest is known to be 𝜌 = 𝜏 /Φ(𝜏 ).
Until Issue #20050 is implemented, the variable in the returned asymptotic expansion represents a singularelement of the form (1 − 𝑧/𝜌)−1 , for the variable 𝑧 → 𝜌.
EXAMPLES:
We can, for example, determine the singular expansion of the well-known tree function 𝑇 (which satisfies
𝑇 (𝑧) = 𝑧 exp(𝑇 (𝑧))):sage: asymptotic_expansions.ImplicitExpansion( Z , phi=exp, precision=8)
doctest:warning...
FutureWarning: This class/method/function is marked as experimental. It, its␣˓→functionality or its interface might change without a formal deprecation.
See https://github.com/sagemath/sage/issues/20050 for details.
1 - sqrt(2)*Z^(-1/2) + 2/3*Z^(-1) - 11/36*sqrt(2)*Z^(-3/2) +43/135*Z^(-2) - 769/4320*sqrt(2)*Z^(-5/2) + 1768/8505*Z^(-3) + O(Z^(-7/2))>>> from sage.all import *>>> asymptotic_expansions.ImplicitExpansion( Z , phi=exp,␣
(continues on next page)

4.2. Common Asymptotic Expansions

57

Asymptotic Expansions, Release 10.4

(continued from previous page)

precision=Integer(8))
doctest:warning...
FutureWarning: This class/method/function is marked as experimental. It, its␣˓→functionality or its interface might change without a formal deprecation.
See https://github.com/sagemath/sage/issues/20050 for details.
1 - sqrt(2)*Z^(-1/2) + 2/3*Z^(-1) - 11/36*sqrt(2)*Z^(-3/2) +43/135*Z^(-2) - 769/4320*sqrt(2)*Z^(-5/2) + 1768/8505*Z^(-3) + O(Z^(-7/2))˓→Another classical example in this context is the generating function 𝐵(𝑧) enumerating binary trees with respect
to the number of inner nodes. The
function satisfies 𝐵(𝑧) = 𝑧(1+2𝐵(𝑧)+𝐵(𝑧)2 ), which can also be solved√
1− 1−4𝑧
explicitly, yielding 𝐵(𝑧) =− 1. We compare the expansions from both approaches:2𝑧
sage: def B(z):....:return (1 - sqrt(1 - 4*z))/(2*z) - 1
sage: A.<Z> = AsymptoticRing( Z^QQ , QQ, default_prec=3)
sage: B((1-1/Z)/4)
1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2)- 2*Z^(-5/2) + O(Z^(-3))
sage: asymptotic_expansions.ImplicitExpansion(Z, phi=lambda u: 1 + 2*u + u^2,␣˓→precision=7)
1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2)- 2*Z^(-5/2) + O(Z^(-3))>>> from sage.all import *>>> def B(z):...
return (Integer(1) - sqrt(Integer(1) - Integer(4)*z))/(Integer(2)*z) ˓→ Integer(1)>>> A = AsymptoticRing( Z^QQ , QQ, default_prec=Integer(3), names=( Z ,)); (Z,˓→) = A._first_ngens(1)>>> B((Integer(1)-Integer(1)/Z)/Integer(4))
1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2)- 2*Z^(-5/2) + O(Z^(-3))>>> asymptotic_expansions.ImplicitExpansion(Z, phi=lambda u: Integer(1) +␣˓→Integer(2)*u + u**Integer(2), precision=Integer(7))
1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2)- 2*Z^(-5/2) + O(Z^(-3))

Neither 𝜏 nor Φ have to be known explicitly, they can also be passed symbolically:
sage: tau = var( tau )sage: phi = function( phi )sage: asymptotic_expansions.ImplicitExpansion( Z , phi=phi, tau=tau,␣
˓→precision=3)# long time
tau + (-sqrt(2)*sqrt(-tau*phi(tau)^2/(2*tau*diff(phi(tau), tau)^2- tau*phi(tau)*diff(phi(tau), tau, tau)
- 2*phi(tau)*diff(phi(tau), tau))))*Z^(-1/2) + O(Z^(-1))>>> from sage.all import *>>> tau = var( tau )>>> phi = function( phi )>>> asymptotic_expansions.ImplicitExpansion( Z , phi=phi, tau=tau,␣
˓→precision=Integer(3))# long time
tau + (-sqrt(2)*sqrt(-tau*phi(tau)^2/(2*tau*diff(phi(tau), tau)^2- tau*phi(tau)*diff(phi(tau), tau, tau)
- 2*phi(tau)*diff(phi(tau), tau))))*Z^(-1/2) + O(Z^(-1))

58

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Note that we do not check whether a passed 𝜏 actually satisfies the requirements. Only the first of the following
expansions is correct:
sage: asymptotic_expansions.ImplicitExpansion( Z ,....:phi=lambda u: 1 + 2*u + u^2, precision=5) # correct expansion
1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + O(Z^(-2))
sage: asymptotic_expansions.ImplicitExpansion( Z , phi=lambda u: 1 + 2*u + u^
˓→2, tau=2, precision=5)
Traceback (most recent call last):...
ZeroDivisionError: symbolic division by zerosage: asymptotic_expansions.ImplicitExpansion( Z , phi=lambda u: 1 + 2*u + u^
˓→2, tau=3, precision=5)
3 - 4*I*sqrt(3)*Z^(-1/2) + 6*I*sqrt(3)*Z^(-3/2) + O(Z^(-2))>>> from sage.all import *>>> asymptotic_expansions.ImplicitExpansion( Z ,...
phi=lambda u: Integer(1) + Integer(2)*u + u**Integer(2),␣
˓→precision=Integer(5)) # correct expansion
1 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + O(Z^(-2))>>> asymptotic_expansions.ImplicitExpansion( Z , phi=lambda u: Integer(1) +␣˓→Integer(2)*u + u**Integer(2), tau=Integer(2), precision=Integer(5))
Traceback (most recent call last):...
ZeroDivisionError: symbolic division by zero>>> asymptotic_expansions.ImplicitExpansion( Z , phi=lambda u: Integer(1) +␣˓→Integer(2)*u + u**Integer(2), tau=Integer(3), precision=Integer(5))
3 - 4*I*sqrt(3)*Z^(-1/2) + 6*I*sqrt(3)*Z^(-3/2) + O(Z^(-2))

See also:
ImplicitExpansionPeriodicPart(), InverseFunctionAnalysis().
static ImplicitExpansionPeriodicPart(var, phi, period, tau=None, precision=None)
Return the singular expansion for the periodic part of a function 𝑦(𝑧) defined implicitly by 𝑦(𝑧) = 𝑧Φ(𝑦(𝑧)).
The function Φ is assumed to be analytic around 0. Furthermore, Φ is not allowed to be an affine-linear
function and we require Φ(0) ̸= 0. For an integer 𝑝, Φ is called 𝑝-periodic if we have Ψ(𝑢𝑝 ) = Φ(𝑢) for a
power series Ψ where 𝑝 is maximal.
Furthermore, it is assumed that there is a unique positive solution 𝜏 of Φ(𝜏 ) − 𝜏 Φ′ (𝜏 ) = 0.
If Φ is 𝑝-periodic, then we have 𝑦(𝑧) = 𝑧𝑔(𝑧 𝑝 ). This method returns the singular expansion of 𝑔(𝑧).
INPUT:• var – a string for the variable name.
• phi – the function Φ. See the extended description for assumptions on Φ.
• period – the period of the function Φ. See the extended description for details.
• tau – (default: None) the fundamental constant described in the extended description. If None, then
𝜏 is determined automatically if possible.
• precision – (default: None) an integer. If None, then the default precision of the asymptotic ringis used.
OUTPUT:
An asymptotic expansion.

4.2. Common Asymptotic Expansions

59

Asymptotic Expansions, Release 10.4

Note: In the given case, the radius of convergence of the function of interest is known to be 𝜌 = 𝜏 /Φ(𝜏 ).
Until Issue #20050 is implemented, the variable in the returned asymptotic expansion represents a singularelement of the form (1 − 𝑧/𝜌)−1 , for the variable 𝑧 → 𝜌.
See also:
ImplicitExpansion(), InverseFunctionAnalysis().
EXAMPLES:
The generating function enumerating binary trees with respect to tree size satisfies 𝐵(𝑧) = 𝑧(1 + 𝐵(𝑧)2 ).
Thisfunction can be written as 𝐵(𝑧) = 𝑧𝑔(𝑧 2 ), and as 𝐵(𝑧) can be determined explicitly we have 𝑔(𝑧) =√1− 1−4𝑧. We compare the corresponding expansions:2𝑧
sage: asymptotic_expansions.ImplicitExpansionPeriodicPart( Z , phi=lambda u:␣
˓→1 + u^2,....:
period=2,␣˓→precision=7)
doctest:warning...
FutureWarning: This class/method/function is marked as experimental. It, its␣˓→functionality or its interface might change without a formal deprecation.
See https://github.com/sagemath/sage/issues/20050 for details.
2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))
sage: def g(z):....:return (1 - sqrt(1 - 4*z))/(2*z)
sage: A.<Z> = AsymptoticRing( Z^QQ , QQ, default_prec=3)
sage: g((1 - 1/Z)/4)
2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))>>> from sage.all import *>>> asymptotic_expansions.ImplicitExpansionPeriodicPart( Z , phi=lambda u:␣
˓→Integer(1) + u**Integer(2),...
period=Integer(2),␣
˓→precision=Integer(7))
doctest:warning...
FutureWarning: This class/method/function is marked as experimental. It, its␣˓→functionality or its interface might change without a formal deprecation.
See https://github.com/sagemath/sage/issues/20050 for details.
2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))>>> def g(z):...
return (Integer(1) - sqrt(Integer(1) - Integer(4)*z))/(Integer(2)*z)>>> A = AsymptoticRing( Z^QQ , QQ, default_prec=Integer(3), names=( Z ,)); (Z,˓→) = A._first_ngens(1)>>> g((Integer(1) - Integer(1)/Z)/Integer(4))
2 - 2*Z^(-1/2) + 2*Z^(-1) - 2*Z^(-3/2) + 2*Z^(-2) - 2*Z^(-5/2) + O(Z^(-3))

static InverseFunctionAnalysis(var, phi, tau=None, period=1, precision=None)
Return the coefficient growth of a function 𝑦(𝑧) defined implicitly by 𝑦(𝑧) = 𝑧Φ(𝑦(𝑧)).
The function Φ is assumed to be analytic around 0. Furthermore, Φ is not allowed to be an affine-linear
function and we require Φ(0) ̸= 0. For an integer 𝑝, Φ is called 𝑝-periodic if we have Ψ(𝑢𝑝 ) = Φ(𝑢) for a
power series Ψ where 𝑝 is maximal.
Furthermore, it is assumed that there is a unique positive solution 𝜏 of Φ(𝜏 ) − 𝜏 Φ′ (𝜏 ) = 0.
INPUT:
60

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

• var – a string for the variable name.
• phi – the function Φ. See the extended description for assumptions on Φ.
• tau – (default: None) the fundamental constant described in the extended description. If None, then
𝜏 is determined automatically if possible.
• period – (default: 1) the period of the function Φ. See the extended description for details.
• precision – (default: None) an integer. If None, then the default precision of the asymptotic ringis used.
OUTPUT:
An asymptotic expansion.
Note: It is not checked that the passed period actually fits to the passed function Φ.
The resulting asymptotic expansion is only valid for 𝑛 ≡ 1 mod 𝑝, where 𝑝 is the period. All other coefficients are 0.
EXAMPLES:
There are 𝐶𝑛 (the 𝑛-th Catalan number) different binary trees of size 2𝑛 + 1, and there are no binary trees
with an even number of nodes. The corresponding generating function satisfies 𝐵(𝑧) = 𝑧(1 + 𝐵(𝑧)2 ), whichallows us to compare the asymptotic expansions for the number of binary trees of size 𝑛 obtained via 𝐶𝑛 andobtained via the analysis of 𝐵(𝑧):sage: assume(SR.an_element() > 0)sage: A.<n> = AsymptoticRing( QQ^n * n^QQ , SR)
sage: binomial_expansion = asymptotic_expansions.Binomial_kn_over_n(n, k=2,␣˓→precision=3)
sage: catalan_expansion = binomial_expansion / (n+1)
sage: catalan_expansion.subs(n=(n-1)/2)
2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2)+ 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2))
sage: asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: 1 + u^2,␣˓→period=2,....:
tau=1, precision=8)
2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2)+ 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2))>>> from sage.all import *>>> assume(SR.an_element() > Integer(0))>>> A = AsymptoticRing( QQ^n * n^QQ , SR, names=( n ,)); (n,) = A._first_
˓→ngens(1)>>> binomial_expansion = asymptotic_expansions.Binomial_kn_over_n(n,␣˓→k=Integer(2), precision=Integer(3))>>> catalan_expansion = binomial_expansion / (n+Integer(1))>>> catalan_expansion.subs(n=(n-Integer(1))/Integer(2))
2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2)+ 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2))>>> asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: Integer(1)␣
˓→+ u**Integer(2), period=Integer(2),...
tau=Integer(1),␣
˓→precision=Integer(8))
2*sqrt(1/2)/sqrt(pi)*2^n*n^(-3/2) - 3/2*sqrt(1/2)/sqrt(pi)*2^n*n^(-5/2)+ 25/16*sqrt(1/2)/sqrt(pi)*2^n*n^(-7/2) + O(2^n*n^(-9/2))

4.2. Common Asymptotic Expansions

61

Asymptotic Expansions, Release 10.4

The code in the aperiodic case is more efficient, however. Therefore, it is recommended to use combinatorial
identities to reduce to the aperiodic case. In the example above, this is well-known: we now count binary
trees with 𝑛 internal nodes. The corresponding generating function satisfies 𝐵(𝑧) = 𝑧(1 + 2𝐵(𝑧) + 𝐵(𝑧)2 ):sage: catalan_expansion
1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2)+ 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2))
sage: asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: 1 + 2*u␣
˓→+ u^2,....:
tau=1, precision=8)
1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2)+ 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2))
sage: forget()>>> from sage.all import *>>> catalan_expansion
1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2)+ 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2))>>> asymptotic_expansions.InverseFunctionAnalysis(n, phi=lambda u: Integer(1)␣
˓→+ Integer(2)*u + u**Integer(2),...
tau=Integer(1),␣
˓→precision=Integer(8))
1/sqrt(pi)*4^n*n^(-3/2) - 9/8/sqrt(pi)*4^n*n^(-5/2)+ 145/128/sqrt(pi)*4^n*n^(-7/2) + O(4^n*n^(-9/2))>>> forget()See also:
ImplicitExpansion(), ImplicitExpansionPeriodicPart().
static SingularityAnalysis(var, zeta=1, alpha=0, beta=0, delta=0, precision=None,
normalized=True)
Return the asymptotic expansion of the coefficients of a power series with specified pole and logarithmic
singularity.
More precisely, this extracts the 𝑛-th coefficient[𝑧 𝑛 ](︂1
1 − 𝑧/𝜁)︂𝛼 (︂

11log𝑧/𝜁
1 − 𝑧/𝜁)︂𝛽 (︂

1log𝑧/𝜁

)︂𝛽 (︂

(︂

(︂

1
1
log
𝑧/𝜁
1 − 𝑧/𝜁)︂)︂𝛿

(if normalized=True, the default) or
𝑛

[𝑧 ]

(︂

1
1 − 𝑧/𝜁)︂𝛼 (︂

1log
1 − 𝑧/𝜁

log

1
1
log
𝑧/𝜁
1 − 𝑧/𝜁)︂)︂𝛿

(if normalized=False).
INPUT:• var – a string for the variable name.
• zeta – (default: 1) the location of the singularity.
• alpha – (default: 0) the pole order of the singularity.
• beta – (default: 0) the order of the logarithmic singularity.
• delta – (default: 0) the order of the log-log singularity. Not yet implemented for delta != 0.

62

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

• precision – (default: None) an integer. If None, then the default precision of the asymptotic ringis used.
• normalized – (default: True) a boolean, see above.
OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: asymptotic_expansions.SingularityAnalysis( n , alpha=1)
1
sage: asymptotic_expansions.SingularityAnalysis( n , alpha=2)
n + 1
sage: asymptotic_expansions.SingularityAnalysis( n , alpha=3)
1/2*n^2 + 3/2*n + 1
sage: _.parent()
Asymptotic Ring <n^ZZ> over Rational Field>>> from sage.all import *>>> asymptotic_expansions.SingularityAnalysis( n , alpha=Integer(1))
1>>> asymptotic_expansions.SingularityAnalysis( n , alpha=Integer(2))
n + 1>>> asymptotic_expansions.SingularityAnalysis( n , alpha=Integer(3))
1/2*n^2 + 3/2*n + 1>>> _.parent()
Asymptotic Ring <n^ZZ> over Rational Field
sage: asymptotic_expansions.SingularityAnalysis( n , alpha=-3/2,....:
precision=3)
3/4/sqrt(pi)*n^(-5/2)+ 45/32/sqrt(pi)*n^(-7/2)+ 1155/512/sqrt(pi)*n^(-9/2)+ O(n^(-11/2))
sage: asymptotic_expansions.SingularityAnalysis( n , alpha=-1/2,....:
precision=3)-1/2/sqrt(pi)*n^(-3/2)- 3/16/sqrt(pi)*n^(-5/2)- 25/256/sqrt(pi)*n^(-7/2)+ O(n^(-9/2))
sage: asymptotic_expansions.SingularityAnalysis( n , alpha=1/2,....:
precision=4)
1/sqrt(pi)*n^(-1/2)- 1/8/sqrt(pi)*n^(-3/2)+ 1/128/sqrt(pi)*n^(-5/2)+ 5/1024/sqrt(pi)*n^(-7/2)+ O(n^(-9/2))
sage: _.parent()
Asymptotic Ring <n^QQ> over Symbolic Constants Subring>>> from sage.all import *>>> asymptotic_expansions.SingularityAnalysis( n , alpha=-Integer(3)/˓→Integer(2),...
precision=Integer(3))
3/4/sqrt(pi)*n^(-5/2)+ 45/32/sqrt(pi)*n^(-7/2)(continues on next page)

4.2. Common Asymptotic Expansions

63

Asymptotic Expansions, Release 10.4

(continued from previous page)+ 1155/512/sqrt(pi)*n^(-9/2)+ O(n^(-11/2))>>> asymptotic_expansions.SingularityAnalysis( n , alpha=-Integer(1)/˓→Integer(2),...
precision=Integer(3))-1/2/sqrt(pi)*n^(-3/2)- 3/16/sqrt(pi)*n^(-5/2)- 25/256/sqrt(pi)*n^(-7/2)+ O(n^(-9/2))>>> asymptotic_expansions.SingularityAnalysis( n , alpha=Integer(1)/˓→Integer(2),...
precision=Integer(4))
1/sqrt(pi)*n^(-1/2)- 1/8/sqrt(pi)*n^(-3/2)+ 1/128/sqrt(pi)*n^(-5/2)+ 5/1024/sqrt(pi)*n^(-7/2)+ O(n^(-9/2))>>> _.parent()
Asymptotic Ring <n^QQ> over Symbolic Constants Subringsage: S = SR.subring(rejecting_variables=( n ,))sage: asymptotic_expansions.SingularityAnalysis(....:n , alpha=S.var( a ),....:precision=4).map_coefficients(lambda c: c.factor())
1/gamma(a)*n^(a - 1)
+ (1/2*(a - 1)*a/gamma(a))*n^(a - 2)
+ (1/24*(3*a - 1)*(a - 1)*(a - 2)*a/gamma(a))*n^(a - 3)
+ (1/48*(a - 1)^2*(a - 2)*(a - 3)*a^2/gamma(a))*n^(a - 4)
+ O(n^(a - 5))sage: _.parent()
Asymptotic Ring <n^(Symbolic Subring rejecting the variable n)>over Symbolic Subring rejecting the variable n>>> from sage.all import *>>> S = SR.subring(rejecting_variables=( n ,))>>> asymptotic_expansions.SingularityAnalysis(...
n , alpha=S.var( a ),...
precision=Integer(4)).map_coefficients(lambda c: c.factor())
1/gamma(a)*n^(a - 1)
+ (1/2*(a - 1)*a/gamma(a))*n^(a - 2)
+ (1/24*(3*a - 1)*(a - 1)*(a - 2)*a/gamma(a))*n^(a - 3)
+ (1/48*(a - 1)^2*(a - 2)*(a - 3)*a^2/gamma(a))*n^(a - 4)
+ O(n^(a - 5))>>> _.parent()
Asymptotic Ring <n^(Symbolic Subring rejecting the variable n)>over Symbolic Subring rejecting the variable nsage: ae = asymptotic_expansions.SingularityAnalysis( n ,....:alpha=1/2, beta=1, precision=4); ae
1/sqrt(pi)*n^(-1/2)*log(n) + ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2)- 5/8/sqrt(pi)*n^(-3/2)*log(n) + (1/8*(3*euler_gamma + 6*log(2) - 8)/sqrt(pi)- (euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n))
sage: n = ae.parent().gen()sage: ae.subs(n=n-1).map_coefficients(lambda x: x.canonicalize_radical())
1/sqrt(pi)*n^(-1/2)*log(n)+ ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2)(continues on next page)

64

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)- 1/8/sqrt(pi)*n^(-3/2)*log(n)+ (-1/8*(euler_gamma + 2*log(2))/sqrt(pi))*n^(-3/2)+ O(n^(-5/2)*log(n))>>> from sage.all import *>>> ae = asymptotic_expansions.SingularityAnalysis( n ,...
alpha=Integer(1)/Integer(2), beta=Integer(1),␣
˓→precision=Integer(4)); ae
1/sqrt(pi)*n^(-1/2)*log(n) + ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2)- 5/8/sqrt(pi)*n^(-3/2)*log(n) + (1/8*(3*euler_gamma + 6*log(2) - 8)/sqrt(pi)- (euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2) + O(n^(-5/2)*log(n))>>> n = ae.parent().gen()>>> ae.subs(n=n-Integer(1)).map_coefficients(lambda x: x.canonicalize_
˓→radical())
1/sqrt(pi)*n^(-1/2)*log(n)+ ((euler_gamma + 2*log(2))/sqrt(pi))*n^(-1/2)- 1/8/sqrt(pi)*n^(-3/2)*log(n)+ (-1/8*(euler_gamma + 2*log(2))/sqrt(pi))*n^(-3/2)+ O(n^(-5/2)*log(n))
sage: asymptotic_expansions.SingularityAnalysis( n ,....:alpha=1, beta=1/2, precision=4)log(n)^(1/2) + 1/2*euler_gamma*log(n)^(-1/2)+ (-1/8*euler_gamma^2 + 1/48*pi^2)*log(n)^(-3/2)+ (1/16*euler_gamma^3 - 1/32*euler_gamma*pi^2 + 1/8*zeta(3))*log(n)^(-5/2)+ O(log(n)^(-7/2))>>> from sage.all import *>>> asymptotic_expansions.SingularityAnalysis( n ,...
alpha=Integer(1), beta=Integer(1)/Integer(2), precision=Integer(4))
log(n)^(1/2) + 1/2*euler_gamma*log(n)^(-1/2)+ (-1/8*euler_gamma^2 + 1/48*pi^2)*log(n)^(-3/2)+ (1/16*euler_gamma^3 - 1/32*euler_gamma*pi^2 + 1/8*zeta(3))*log(n)^(-5/2)+ O(log(n)^(-7/2))
sage: ae = asymptotic_expansions.SingularityAnalysis( n ,....:alpha=0, beta=2, precision=14)
sage: n = ae.parent().gen()sage: ae.subs(n=n-2)2*n^(-1)*log(n) + 2*euler_gamma*n^(-1) - n^(-2) - 1/6*n^(-3) + O(n^(-5))>>> from sage.all import *>>> ae = asymptotic_expansions.SingularityAnalysis( n ,...
alpha=Integer(0), beta=Integer(2), precision=Integer(14))>>> n = ae.parent().gen()>>> ae.subs(n=n-Integer(2))
2*n^(-1)*log(n) + 2*euler_gamma*n^(-1) - n^(-2) - 1/6*n^(-3) + O(n^(-5))
sage: asymptotic_expansions.SingularityAnalysis(....:n , 1, alpha=-1/2, beta=1, precision=2, normalized=False)-1/2/sqrt(pi)*n^(-3/2)*log(n)+ (-1/2*(euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2)+ O(n^(-5/2)*log(n))
sage: asymptotic_expansions.SingularityAnalysis((continues on next page)

4.2. Common Asymptotic Expansions

65

Asymptotic Expansions, Release 10.4

(continued from previous page)....:n , 1/2, alpha=0, beta=1, precision=3, normalized=False)2^n*n^(-1) + O(2^n*n^(-2))>>> from sage.all import *>>> asymptotic_expansions.SingularityAnalysis(...
n , Integer(1), alpha=-Integer(1)/Integer(2), beta=Integer(1),␣
˓→precision=Integer(2), normalized=False)-1/2/sqrt(pi)*n^(-3/2)*log(n)+ (-1/2*(euler_gamma + 2*log(2) - 2)/sqrt(pi))*n^(-3/2)+ O(n^(-5/2)*log(n))>>> asymptotic_expansions.SingularityAnalysis(...
n , Integer(1)/Integer(2), alpha=Integer(0), beta=Integer(1),␣
˓→precision=Integer(3), normalized=False)2^n*n^(-1) + O(2^n*n^(-2))

ALGORITHM:
See [FS2009].
static Stirling(var, precision=None, skip_constant_factor=False)
Return Stirling’s approximation formula for factorials.
INPUT:• var – a string for the variable name.
• precision – (default: None) an integer ≥ 3. If None, then the default precision of the asymptotic
ring is used.
√• skip_constant_factor – (default: False) a boolean. If set, then the constant factor 2𝜋 isleft out. As a consequence, the coefficient ring of the output changes from Symbolic Constants
Subring (if False) to Rational Field (if True).
OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: asymptotic_expansions.Stirling( n , precision=5)
sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))
sage: _.parent()
Asymptotic Ring <(e^(n*log(n)))^QQ * (e^n)^QQ * n^QQ * log(n)^QQ>
over Symbolic Constants Subring>>> from sage.all import *>>> asymptotic_expansions.Stirling( n , precision=Integer(5))
sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(1/2) +1/12*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-1/2) +1/288*sqrt(2)*sqrt(pi)*e^(n*log(n))*(e^n)^(-1)*n^(-3/2) +O(e^(n*log(n))*(e^n)^(-1)*n^(-5/2))>>> _.parent()
Asymptotic Ring <(e^(n*log(n)))^QQ * (e^n)^QQ * n^QQ * log(n)^QQ>
over Symbolic Constants Subring66

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

See also:
log_Stirling(), factorial().
static log_Stirling(var, precision=None, skip_constant_summand=False)
Return the logarithm of Stirling’s approximation formula for factorials.
INPUT:• var – a string for the variable name.
• precision – (default: None) an integer. If None, then the default precision of the asymptotic ringis used.
• skip_constant_summand – (default: False) a boolean. If set, then the constant summandlog(2𝜋)/2 is left out. As a consequence, the coefficient ring of the output changes from Symbolic
Constants Subring (if False) to Rational Field (if True).
OUTPUT:
An asymptotic expansion.
EXAMPLES:
sage: asymptotic_expansions.log_Stirling( n , precision=7)n*log(n) - n + 1/2*log(n) + 1/2*log(2*pi) + 1/12*n^(-1)- 1/360*n^(-3) + 1/1260*n^(-5) + O(n^(-7))>>> from sage.all import *>>> asymptotic_expansions.log_Stirling( n , precision=Integer(7))
n*log(n) - n + 1/2*log(n) + 1/2*log(2*pi) + 1/12*n^(-1)- 1/360*n^(-3) + 1/1260*n^(-5) + O(n^(-7))

See also:
Stirling(), factorial().
sage.rings.asymptotic.asymptotic_expansion_generators.asymptotic_expansions =<sage.rings.asymptotic.asymptotic_expansion_generators.
AsymptoticExpansionGenerators object>
A collection of several common asymptotic expansions.
This is an instance of AsymptoticExpansionGenerators whose documentation provides more details.

4.3 (Asymptotic) Growth Groups
This module provides support for (asymptotic) growth groups.
Such groups are equipped with a partial order: the elements can be seen as functions, and the behavior as their argument(or arguments) gets large (tend to ∞) is compared.
Growth groups are used for the calculations done in the asymptotic ring. There, take a look at the informal definition,
where examples of growth groups and elements are given as well.

4.3. (Asymptotic) Growth Groups

67

Asymptotic Expansions, Release 10.4

4.3.1 Description of Growth Groups
Many growth groups can be described by a string, which can also be used to create them. For example, the string x^QQ
* log(x)^ZZ * QQ^y * y^QQ represents a growth group with the following properties:• It is a growth group in the two variables 𝑥 and 𝑦.
• Its elements are of the form
𝑥𝑟 · log(𝑥)𝑠 · 𝑎𝑦 · 𝑦 𝑞
for 𝑟 ∈,𝑠∈ ,𝑎∈and 𝑞 ∈.

• The order is with respect to 𝑥 → ∞ and 𝑦 → ∞ independently of each other.
• To compare such elements, they are split into parts belonging to only one variable. In the example above,
𝑥𝑟1 · log(𝑥)𝑠1 ≤ 𝑥𝑟2 · log(𝑥)𝑠2
if (𝑟1 , 𝑠1 ) ≤ (𝑟2 , 𝑠2 ) lexicographically. This reflects the fact that elements 𝑥𝑟 are larger than elements log(𝑥)𝑠 as
𝑥 → ∞. The factors belonging to the variable 𝑦 are compared analogously.
The results of these comparisons are then put together using the product order, i.e., ≤ if each component satisfies≤.
Each description string consists of ordered factors—yes, this means * is noncommutative—of strings describing “elementary” growth groups (see the examples below). As stated in the example above, these factors are split by theirvariable; factors with the same variable are grouped. Reading such factors from left to right determines the order: Comparing elements of two factors (growth groups) 𝐿 and 𝑅, then all elements of 𝐿 are considered to be larger than eachelement of 𝑅.

4.3.2 Creating a Growth GroupFor many purposes the factory GrowthGroup (see GrowthGroupFactory) is the most convenient way to generatea growth group.
sage: from sage.rings.asymptotic.growth_group import GrowthGroup>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup

Here are some examples:sage: GrowthGroup( z^ZZ )Growth Group z^ZZ
sage: M = GrowthGroup( z^QQ ); M
Growth Group z^QQ>>> from sage.all import *>>> GrowthGroup( z^ZZ )Growth Group z^ZZ>>> M = GrowthGroup( z^QQ ); M
Growth Group z^QQ

Each of these two generated groups is a MonomialGrowthGroup, whose elements are powers of a fixed symbol(above z ). For the order of the elements it is assumed that 𝑧 → ∞.

68

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Note: Growth groups where the variable tend to some value distinct from ∞ are not yet implemented.
To create elements of 𝑀 , a generator can be used:
sage: z = M.gen()sage: z^(3/5)
z^(3/5)>>> from sage.all import *>>> z = M.gen()>>> z**(Integer(3)/Integer(5))
z^(3/5)Strings can also be parsed:
sage: M( z^7 )z^7>>> from sage.all import *>>> M( z^7 )z^7Similarly, we can construct logarithmic factors by:sage: GrowthGroup( log(z)^QQ )Growth Group log(z)^QQ>>> from sage.all import *>>> GrowthGroup( log(z)^QQ )Growth Group log(z)^QQ

which again creates a MonomialGrowthGroup. An ExponentialGrowthGroup is generated in the same way.
Our factory gives
sage: E = GrowthGroup( (QQ_+)^z ); E
Growth Group QQ^z>>> from sage.all import *>>> E = GrowthGroup( (QQ_+)^z ); E
Growth Group QQ^z

and a typical element looks like this:sage: E.an_element()(1/2)^z>>> from sage.all import *>>> E.an_element()(1/2)^zMore complex groups are created in a similar fashion. For example
sage: C = GrowthGroup( (QQ_+)^z * z^QQ * log(z)^QQ ); C
Growth Group QQ^z * z^QQ * log(z)^QQ

4.3. (Asymptotic) Growth Groups

69

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> C = GrowthGroup( (QQ_+)^z * z^QQ * log(z)^QQ ); C
Growth Group QQ^z * z^QQ * log(z)^QQ

This contains elements of the form
sage: C.an_element()(1/2)^z*z^(1/2)*log(z)^(1/2)>>> from sage.all import *>>> C.an_element()(1/2)^z*z^(1/2)*log(z)^(1/2)

The group 𝐶 itself is a Cartesian product; to be precise a UnivariateProduct. We can see its factors:
sage: C.cartesian_factors()(Growth Group QQ^z, Growth Group z^QQ, Growth Group log(z)^QQ)>>> from sage.all import *>>> C.cartesian_factors()(Growth Group QQ^z, Growth Group z^QQ, Growth Group log(z)^QQ)

Multivariate constructions are also possible:
sage: GrowthGroup( x^QQ * y^QQ )Growth Group x^QQ * y^QQ>>> from sage.all import *>>> GrowthGroup( x^QQ * y^QQ )Growth Group x^QQ * y^QQThis gives a MultivariateProduct.
Both these Cartesian products are derived from the class GenericProduct. Moreover all growth groups have theabstract base class GenericGrowthGroup in common.
Some Examples
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G_x = GrowthGroup( x^ZZ ); G_x
Growth Group x^ZZ
sage: G_xy = GrowthGroup( x^ZZ * y^ZZ ); G_xy
Growth Group x^ZZ * y^ZZ
sage: G_xy.an_element()
x*ysage: x = G_xy( x ); y = G_xy( y )sage: x^2
x^2
sage: elem = x^21*y^21; elem^2x^42*y^42>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G_x = GrowthGroup( x^ZZ ); G_x(continues on next page)

70

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

Growth Group x^ZZ>>> G_xy = GrowthGroup( x^ZZ * y^ZZ ); G_xy
Growth Group x^ZZ * y^ZZ>>> G_xy.an_element()
x*y>>> x = G_xy( x ); y = G_xy( y )>>> x**Integer(2)x^2>>> elem = x**Integer(21)*y**Integer(21); elem**Integer(2)x^42*y^42

A monomial growth group itself is totally ordered, all elements are comparable. However, this does not hold for Cartesian
products:
sage: e1 = x^2*y; e2 = x*y^2
sage: e1 <= e2 or e2 <= e1
False>>> from sage.all import *>>> e1 = x**Integer(2)*y; e2 = x*y**Integer(2)>>> e1 <= e2 or e2 <= e1
False

In terms of uniqueness, we have the following behaviour:sage: GrowthGroup( x^ZZ * y^ZZ ) is GrowthGroup( y^ZZ * x^ZZ )True>>> from sage.all import *>>> GrowthGroup( x^ZZ * y^ZZ ) is GrowthGroup( y^ZZ * x^ZZ )True

The above is True since the order of the factors does not play a role here; they use different variables. But when using
the same variable, it plays a role:sage: GrowthGroup( x^ZZ * log(x)^ZZ ) is GrowthGroup( log(x)^ZZ * x^ZZ )False>>> from sage.all import *>>> GrowthGroup( x^ZZ * log(x)^ZZ ) is GrowthGroup( log(x)^ZZ * x^ZZ )False

In this case the components are ordered lexicographically, which means that in the second growth group, log(x) is
assumed to grow faster than x (which is nonsense, mathematically). See CartesianProduct for more details or see
above for a more extensive description.
Short notation also allows the construction of more complicated growth groups:
sage: G = GrowthGroup( (QQ_+)^x * x^ZZ * log(x)^QQ * y^QQ )sage: G.an_element()(1/2)^x*x*log(x)^(1/2)*y^(1/2)
sage: x, y = var( x y )sage: G(2^x * log(x) * y^(1/2)) * G(x^(-5) * 5^x * y^(1/3))
10^x*x^(-5)*log(x)*y^(5/6)

4.3. (Asymptotic) Growth Groups

71

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> G = GrowthGroup( (QQ_+)^x * x^ZZ * log(x)^QQ * y^QQ )>>> G.an_element()(1/2)^x*x*log(x)^(1/2)*y^(1/2)>>> x, y = var( x y )>>> G(Integer(2)**x * log(x) * y**(Integer(1)/Integer(2))) * G(x**(-Integer(5)) *␣˓→Integer(5)**x * y**(Integer(1)/Integer(3)))
10^x*x^(-5)*log(x)*y^(5/6)

AUTHORS:• Benjamin Hackl (2015)• Daniel Krenn (2015)• Clemens Heuberger (2016)
ACKNOWLEDGEMENT:• Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P
24644-N26.
• Benjamin Hackl is supported by the Google Summer of Code 2015.

4.3.3 Classes and Methods
class sage.rings.asymptotic.growth_group.AbstractGrowthGroupFunctor(var, domain)
Bases: ConstructionFunctor
A base class for the functors constructing growth groups.
INPUT:• var – a string or list of strings (or anything else Variable accepts).
• domain – a category.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( z^QQ ).construction()[0] # indirect doctest
MonomialGrowthGroup[z]>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( z^QQ ).construction()[Integer(0)] # indirect doctest
MonomialGrowthGroup[z]See also:
Asymptotic Ring, ExponentialGrowthGroupFunctor, MonomialGrowthGroupFunctor, sage.
rings.asymptotic.asymptotic_ring.AsymptoticRingFunctor,
sage.categories.
pushout.ConstructionFunctor.
merge(other)Merge this functor with other of possible.
INPUT:• other – a functor.

72

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

OUTPUT:
A functor or None.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: F = GrowthGroup( (QQ_+)^t ).construction()[0]sage: G = GrowthGroup( t^QQ ).construction()[0]sage: F.merge(F)ExponentialGrowthGroup[t]sage: F.merge(G) is None
True>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> F = GrowthGroup( (QQ_+)^t ).construction()[Integer(0)]>>> G = GrowthGroup( t^QQ ).construction()[Integer(0)]>>> F.merge(F)ExponentialGrowthGroup[t]>>> F.merge(G) is None
Truerank = 13
exception sage.rings.asymptotic.growth_group.DecreasingGrowthElementError(element,*args,**kwds)Bases: ValueError
A special ValueError which is raised when a growth element is less than one.
INPUT:• element – a GenericGrowthElement
The remaining arguments are passed on to ValueError.
class sage.rings.asymptotic.growth_group.ExponentialGrowthElement(parent,
raw_element)
Bases: GenericGrowthElement
An implementation of exponential growth elements.
INPUT:• parent – an ExponentialGrowthGroup.
• raw_element – an element from the base ring of the parent.
This raw_element is the base of the created exponential growth element.
An exponential growth element represents a term of the type basevariable . The multiplication corresponds to themultiplication of the bases.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: P = GrowthGroup( (ZZ_+)^x )sage: e1 = P(1); e1(continues on next page)

4.3. (Asymptotic) Growth Groups

73

Asymptotic Expansions, Release 10.4

(continued from previous page)1
sage: e2 = P(raw_element=2); e22^x
sage: e1 == e2
False
sage: P.le(e1, e2)
True
sage: P.le(e1, P(1)) and P.le(P(1), e2)
True>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> P = GrowthGroup( (ZZ_+)^x )>>> e1 = P(Integer(1)); e1
1>>> e2 = P(raw_element=Integer(2)); e22^x>>> e1 == e2
False>>> P.le(e1, e2)
True>>> P.le(e1, P(Integer(1))) and P.le(P(Integer(1)), e2)
Trueproperty base
The base of this exponential growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: P = GrowthGroup( (ZZ_+)^x )sage: P(42^x).base42>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> P = GrowthGroup( (ZZ_+)^x )>>> P(Integer(42)**x).base42class sage.rings.asymptotic.growth_group.ExponentialGrowthGroup(base, *args, **kwds)
Bases: GenericGrowthGroupA growth group dealing with expressions involving a fixed variable/symbol as the exponent.
The elements ExponentialGrowthElement of this group represent exponential functions with bases from afixed base ring; the group law is the multiplication.
INPUT:• base – one of SageMath’s parents, out of which the elements get their data (raw_element).
As exponential expressions are represented by this group, the elements in base are the bases of these exponentials.
• var – an object.
The string representation of var acts as an exponent of the elements represented by this group.

74

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

• category – (default: None) the category of the newly created growth group. It has to be a subcategory ofJoin of Category of groups and Category of posets. This is also the default category
if None is specified.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import ExponentialGrowthGroupsage: P = ExponentialGrowthGroup(QQ, x ); P
Growth Group QQ^x>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import ExponentialGrowthGroup>>> P = ExponentialGrowthGroup(QQ, x ); P
Growth Group QQ^x

See also:
GenericGrowthGroup
DivisionRings
alias of DivisionRings
Element
alias of ExponentialGrowthElement
Groupsalias of Groups
Magmasalias of Magmas
Posetsalias of Posets
Sets
alias of Sets
construction()
Return the construction of this growth group.
OUTPUT:
A pair whose first entry is an exponential construction functor and its second entry the base.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( (QQ_+)^x ).construction()(ExponentialGrowthGroup[x], Rational Field)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( (QQ_+)^x ).construction()(ExponentialGrowthGroup[x], Rational Field)

classmethod factory(base, var, extend_by_non_growth_group=True, return_factors=False, **kwds)
Create an exponential growth group.
This factory takes care of the splitting of the bases into their absolute values and arguments.
INPUT:
4.3. (Asymptotic) Growth Groups

75

Asymptotic Expansions, Release 10.4

• base, var, keywords – use in the initialization of the exponential growth group; see ExponentialGrowthGroup for details.
• extend_by_non_growth_group – a boolean (default True). If set, then the growth group consists of two parts, one part dealing with the absolute values of the bases and one for their arguments.
• return_factors – a boolean (default: False). If set, then a tuple of the (cartesian) factors of thisgrowth group is returned.
OUTPUT:
A growth group or tuple of growth groups.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import ExponentialGrowthGroupsage: ExponentialGrowthGroup.factory(QQ, n )Growth Group QQ^n * Signs^n>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import ExponentialGrowthGroup>>> ExponentialGrowthGroup.factory(QQ, n )Growth Group QQ^n * Signs^ngens()
Return a tuple of all generators of this exponential growth group.
INPUT:
Nothing.
OUTPUT:An empty tuple.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: E = GrowthGroup( (ZZ_+)^x )sage: E.gens()()>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> E = GrowthGroup( (ZZ_+)^x )>>> E.gens()()

non_growth_group()
Return a non-growth group (with an argument group, e.g. roots of unity, as base) compatible with thisexponential growth group.
OUTPUT:
A group group.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( (QQ_+)^x ).non_growth_group()
Growth Group Signs^x(continues on next page)

76

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: GrowthGroup( (RR_+)^x ).non_growth_group()
Growth Group Signs^x
sage: GrowthGroup( (RIF_+)^x ).non_growth_group()
Growth Group Signs^x
sage: GrowthGroup( (RBF_+)^x ).non_growth_group()
Growth Group Signs^x
sage: GrowthGroup( (CC_+)^x ).non_growth_group()
Growth Group UU_RR^xsage: GrowthGroup( (CIF_+)^x ).non_growth_group()
Growth Group UU_RIF^x
sage: GrowthGroup( (CBF_+)^x ).non_growth_group()
Growth Group UU_RBF^x>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( (QQ_+)^x ).non_growth_group()
Growth Group Signs^x>>> GrowthGroup( (RR_+)^x ).non_growth_group()
Growth Group Signs^x>>> GrowthGroup( (RIF_+)^x ).non_growth_group()
Growth Group Signs^x>>> GrowthGroup( (RBF_+)^x ).non_growth_group()
Growth Group Signs^x>>> GrowthGroup( (CC_+)^x ).non_growth_group()
Growth Group UU_RR^x>>> GrowthGroup( (CIF_+)^x ).non_growth_group()
Growth Group UU_RIF^x>>> GrowthGroup( (CBF_+)^x ).non_growth_group()
Growth Group UU_RBF^xsome_elements()
Return some elements of this exponential growth group.
See TestSuite for a typical use case.
INPUT:
Nothing.
OUTPUT:
An iterator.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: tuple(GrowthGroup( (QQ_+)^z ).some_elements())((1/2)^z, 2^z, 1, 42^z, (2/3)^z, (3/2)^z, ...)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> tuple(GrowthGroup( (QQ_+)^z ).some_elements())((1/2)^z, 2^z, 1, 42^z, (2/3)^z, (3/2)^z, ...)

class sage.rings.asymptotic.growth_group.ExponentialGrowthGroupFunctor(var)
Bases: AbstractGrowthGroupFunctor
A construction functor for exponential growth groups.

4.3. (Asymptotic) Growth Groups

77

Asymptotic Expansions, Release 10.4

INPUT:• var – a string or list of strings (or anything else Variable accepts).
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup,␣
˓→ExponentialGrowthGroupFunctor
sage: GrowthGroup( (QQ_+)^z ).construction()[0]ExponentialGrowthGroup[z]>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup,␣
˓→ExponentialGrowthGroupFunctor>>> GrowthGroup( (QQ_+)^z ).construction()[Integer(0)]ExponentialGrowthGroup[z]See also:
Asymptotic Ring, AbstractGrowthGroupFunctor, MonomialGrowthGroupFunctor, sage.
rings.asymptotic.asymptotic_ring.AsymptoticRingFunctor,
sage.categories.
pushout.ConstructionFunctor.
class sage.rings.asymptotic.growth_group.ExponentialNonGrowthElement(parent,
raw_element)
Bases: GenericNonGrowthElement, ExponentialGrowthElement
An element of ExponentialNonGrowthGroup.
class sage.rings.asymptotic.growth_group.ExponentialNonGrowthGroup(base, *args,**kwds)Bases: GenericNonGrowthGroup, ExponentialGrowthGroupA growth group whose base is an argument group.
EXAMPLES:
sage: from sage.groups.misc_gps.argument_groups import RootsOfUnityGroupsage: from sage.rings.asymptotic.growth_group import ExponentialNonGrowthGroupsage: UU = ExponentialNonGrowthGroup(RootsOfUnityGroup(), n )sage: UU(raw_element=-1)(-1)^n>>> from sage.all import *>>> from sage.groups.misc_gps.argument_groups import RootsOfUnityGroup>>> from sage.rings.asymptotic.growth_group import ExponentialNonGrowthGroup>>> UU = ExponentialNonGrowthGroup(RootsOfUnityGroup(), n )>>> UU(raw_element=-Integer(1))(-1)^nElement
alias of ExponentialNonGrowthElement
construction()
Return the construction of this growth group.
OUTPUT:
A pair whose first entry is an ExponentialNonGrowthGroupFunctor and its second entry the base.
78

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( UU^x ).construction()(ExponentialNonGrowthGroup[x], Group of Roots of Unity)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( UU^x ).construction()(ExponentialNonGrowthGroup[x], Group of Roots of Unity)

class sage.rings.asymptotic.growth_group.ExponentialNonGrowthGroupFunctor(var)
Bases: ExponentialGrowthGroupFunctor
A construction functor for ExponentialNonGrowthGroup.
class sage.rings.asymptotic.growth_group.GenericGrowthElement(parent, raw_element)
Bases: MultiplicativeGroupElement
A basic implementation of a generic growth element.
Growth elements form a group by multiplication, and (some of) the elements can be compared to each other, i.e.,
all elements form a poset.
INPUT:• parent – a GenericGrowthGroup.
• raw_element – an element from the base of the parent.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import (GenericGrowthGroup,....:
GenericGrowthElement)
sage: G = GenericGrowthGroup(ZZ)
sage: g = GenericGrowthElement(G, 42); g
GenericGrowthElement(42)sage: g.parent()
Growth Group Generic(ZZ)
sage: G(raw_element=42) == g
True>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import (GenericGrowthGroup,...
GenericGrowthElement)>>> G = GenericGrowthGroup(ZZ)>>> g = GenericGrowthElement(G, Integer(42)); g
GenericGrowthElement(42)>>> g.parent()
Growth Group Generic(ZZ)>>> G(raw_element=Integer(42)) == gTruefactors()
Return the atomic factors of this growth element. An atomic factor cannot be split further.
INPUT:
Nothing.
OUTPUT:4.3. (Asymptotic) Growth Groups

79

Asymptotic Expansions, Release 10.4

A tuple of growth elements.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ )sage: G.an_element().factors()(x,)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ )>>> G.an_element().factors()(x,)

is_lt_one()
Return whether this element is less than 1.
INPUT:
Nothing.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ ); x = G(x)sage: (x^42).is_lt_one() # indirect doctest
False
sage: (x^(-42)).is_lt_one() # indirect doctest
True>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ ); x = G(x)>>> (x**Integer(42)).is_lt_one() # indirect doctest
False>>> (x**(-Integer(42))).is_lt_one() # indirect doctest
Truelog(base=None)
Return the logarithm of this element.
INPUT:• base – the base of the logarithm. If None (default value) is used, the natural logarithm is taken.
OUTPUT:
A growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ * log(x)^ZZ )sage: x, = G.gens_monomial()
sage: log(x) # indirect doctest(continues on next page)

80

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)log(x)
sage: log(x^5) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: When calculating log(x^5) a factor 5 != 1 appeared,
which is not contained in Growth Group x^ZZ * log(x)^ZZ.
>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ * log(x)^ZZ )>>> x, = G.gens_monomial()>>> log(x) # indirect doctest
log(x)>>> log(x**Integer(5)) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: When calculating log(x^5) a factor 5 != 1 appeared,
which is not contained in Growth Group x^ZZ * log(x)^ZZ.
sage: G = GrowthGroup( (QQ_+)^x * x^ZZ )sage: x, = G.gens_monomial()
sage: el = x.rpow(2); el2^x
sage: log(el) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: When calculating log(2^x) a factor log(2) != 1
appeared, which is not contained in Growth Group QQ^x * x^ZZ.
sage: log(el, base=2) # indirect doctestx>>> from sage.all import *>>> G = GrowthGroup( (QQ_+)^x * x^ZZ )>>> x, = G.gens_monomial()>>> el = x.rpow(Integer(2)); el
2^x>>> log(el) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: When calculating log(2^x) a factor log(2) != 1
appeared, which is not contained in Growth Group QQ^x * x^ZZ.
>>> log(el, base=Integer(2)) # indirect doctestxsage: from sage.rings.asymptotic.growth_group import GenericGrowthGroupsage: x = GenericGrowthGroup(ZZ).an_element()
sage: log(x) # indirect doctest
Traceback (most recent call last):...
NotImplementedError: Cannot determine logarithmized factorization ofGenericGrowthElement(1) in abstract base class.
>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GenericGrowthGroup>>> x = GenericGrowthGroup(ZZ).an_element()(continues on next page)

4.3. (Asymptotic) Growth Groups

81Asymptotic Expansions, Release 10.4

(continued from previous page)>>> log(x) # indirect doctest
Traceback (most recent call last):...
NotImplementedError: Cannot determine logarithmized factorization ofGenericGrowthElement(1) in abstract base class.
sage: x = GrowthGroup( x^ZZ ).an_element()
sage: log(x) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot build log(x) since log(x) is not in
Growth Group x^ZZ.
>>> from sage.all import *>>> x = GrowthGroup( x^ZZ ).an_element()>>> log(x) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot build log(x) since log(x) is not in
Growth Group x^ZZ.

log_factor(base=None, locals=None)
Return the logarithm of the factorization of this element.
INPUT:• base – the base of the logarithm. If None (default value) is used, the natural logarithm is taken.
• 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 pairs, where the first entry is a growth element and the second a multiplicative coefficient.
ALGORITHM:
This function factors the given element and calculates the logarithm of each of these factors.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( (QQ_+)^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ )sage: x, y = G.gens_monomial()
sage: (x * y).log_factor() # indirect doctest((log(x), 1), (log(y), 1))
sage: (x^123).log_factor() # indirect doctest((log(x), 123),)
sage: (G( 2^x ) * x^2).log_factor(base=2) # indirect doctest((x, 1), (log(x), 2/log(2)))>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( (QQ_+)^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ )>>> x, y = G.gens_monomial()>>> (x * y).log_factor() # indirect doctest((log(x), 1), (log(y), 1))(continues on next page)

82

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> (x**Integer(123)).log_factor() # indirect doctest((log(x), 123),)>>> (G( 2^x ) * x**Integer(2)).log_factor(base=Integer(2))((x, 1), (log(x), 2/log(2)))# indirect doctest

sage: G(1).log_factor()()>>> from sage.all import *>>> G(Integer(1)).log_factor()()
sage: log(x).log_factor() # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot build log(log(x)) since log(log(x)) is
not in Growth Group QQ^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ.
>>> from sage.all import *>>> log(x).log_factor() # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot build log(log(x)) since log(log(x)) is
not in Growth Group QQ^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ.

See also:
factors(), log().
rpow(base)Calculate the power of base to this element.
INPUT:• base – an element.
OUTPUT:
A growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( (QQ_+)^x * x^ZZ )sage: x = G( x )sage: x.rpow(2) # indirect doctest
2^x
sage: x.rpow(1/2) # indirect doctest(1/2)^x>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( (QQ_+)^x * x^ZZ )>>> x = G( x )>>> x.rpow(Integer(2)) # indirect doctest
2^x(continues on next page)

4.3. (Asymptotic) Growth Groups

83

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> x.rpow(Integer(1)/Integer(2))(1/2)^x# indirect doctest

sage: x.rpow(0) # indirect doctest
Traceback (most recent call last):...
ValueError: 0 is not an allowed base for calculating the power to x.
sage: (x^2).rpow(2) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot construct 2^(x^2) in Growth Group QQ^x * x^ZZ
> *previous* TypeError: unsupported operand parent(s) for *:Growth Group QQ^x * x^ZZ and Growth Group ZZ^(x^2)>>> from sage.all import *>>> x.rpow(Integer(0)) # indirect doctest
Traceback (most recent call last):...
ValueError: 0 is not an allowed base for calculating the power to x.
>>> (x**Integer(2)).rpow(Integer(2)) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot construct 2^(x^2) in Growth Group QQ^x * x^ZZ
> *previous* TypeError: unsupported operand parent(s) for *:Growth Group QQ^x * x^ZZ and Growth Group ZZ^(x^2)
sage: G = GrowthGroup( QQ^(x*log(x)) * x^ZZ * log(x)^ZZ )sage: x = G( x )sage: (x * log(x)).rpow(2) # indirect doctest
2^(x*log(x))>>> from sage.all import *>>> G = GrowthGroup( QQ^(x*log(x)) * x^ZZ * log(x)^ZZ )>>> x = G( x )>>> (x * log(x)).rpow(Integer(2)) # indirect doctest
2^(x*log(x))
sage: n = GrowthGroup( (QQ_+)^n * n^QQ )( n )sage: n.rpow(2)2^nsage: _.parent()
Growth Group QQ^n * n^QQ>>> from sage.all import *>>> n = GrowthGroup( (QQ_+)^n * n^QQ )( n )>>> n.rpow(Integer(2))
2^n>>> _.parent()
Growth Group QQ^n * n^QQ
sage: n = GrowthGroup( QQ^n * n^QQ )( n )sage: n.rpow(-2)
2^n*(-1)^n84

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> n = GrowthGroup( QQ^n * n^QQ )( n )>>> n.rpow(-Integer(2))
2^n*(-1)^nvariable_names()
Return the names of the variables of this growth element.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( m^QQ )sage: G( m^2 ).variable_names()( m ,)
sage: G( m^0 ).variable_names()()>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( m^QQ )>>> G( m^2 ).variable_names()( m ,)>>> G( m^0 ).variable_names()()
sage: G = GrowthGroup( QQ^m )sage: G( 2^m ).variable_names()( m ,)
sage: G( 1^m ).variable_names()()>>> from sage.all import *>>> G = GrowthGroup( QQ^m )>>> G( 2^m ).variable_names()( m ,)>>> G( 1^m ).variable_names()()

class sage.rings.asymptotic.growth_group.GenericGrowthGroup(base, var, category)Bases: UniqueRepresentation, Parent, WithLocals
A basic implementation for growth groups.
INPUT:• base – one of SageMath’s parents, out of which the elements get their data (raw_element).
• category – (default: None) the category of the newly created growth group. It has to be a subcategory ofJoin of Category of groups and Category of posets. This is also the default category
if None is specified.
• ignore_variables – (default: None) a tuple (or other iterable) of strings. The specified names are notconsidered as variables.

4.3. (Asymptotic) Growth Groups

85

Asymptotic Expansions, Release 10.4

Note: This class should be derived for concrete implementations.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GenericGrowthGroupsage: G = GenericGrowthGroup(ZZ); G
Growth Group Generic(ZZ)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GenericGrowthGroup>>> G = GenericGrowthGroup(ZZ); G
Growth Group Generic(ZZ)

See also:
MonomialGrowthGroup, ExponentialGrowthGroup
AdditiveMagmas
alias of AdditiveMagmas
CartesianProduct =<sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory
object>Element
alias of GenericGrowthElement
Magmasalias of Magmas
Posetsalias of Posets
Sets
alias of Sets
extended_by_non_growth_group()
Extend to a cartesian product of this growth group and a suitable non growth group.
OUTPUT:
A group group.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( (QQ_+)^x ).extended_by_non_growth_group()
Growth Group QQ^x * Signs^x
sage: GrowthGroup( (RR_+)^x ).extended_by_non_growth_group()
Growth Group RR^x * Signs^x
sage: GrowthGroup( (RIF_+)^x ).extended_by_non_growth_group()
Growth Group RIF^x * Signs^x
sage: GrowthGroup( (RBF_+)^x ).extended_by_non_growth_group()
Growth Group RBF^x * Signs^x
sage: GrowthGroup( (CC_+)^x ).extended_by_non_growth_group()
Growth Group CC^x * UU_RR^xsage: GrowthGroup( (CIF_+)^x ).extended_by_non_growth_group()(continues on next page)

86

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

Growth Group CIF^x * UU_RIF^x
sage: GrowthGroup( (CBF_+)^x ).extended_by_non_growth_group()
Growth Group CBF^x * UU_RBF^x>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( (QQ_+)^x ).extended_by_non_growth_group()
Growth Group QQ^x * Signs^x>>> GrowthGroup( (RR_+)^x ).extended_by_non_growth_group()
Growth Group RR^x * Signs^x>>> GrowthGroup( (RIF_+)^x ).extended_by_non_growth_group()
Growth Group RIF^x * Signs^x>>> GrowthGroup( (RBF_+)^x ).extended_by_non_growth_group()
Growth Group RBF^x * Signs^x>>> GrowthGroup( (CC_+)^x ).extended_by_non_growth_group()
Growth Group CC^x * UU_RR^x>>> GrowthGroup( (CIF_+)^x ).extended_by_non_growth_group()
Growth Group CIF^x * UU_RIF^x>>> GrowthGroup( (CBF_+)^x ).extended_by_non_growth_group()
Growth Group CBF^x * UU_RBF^xgen(n=0)
Return the 𝑛-th generator (as a group) of this growth group.
INPUT:• n – default: 0.
OUTPUT:
A MonomialGrowthElement.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: P = GrowthGroup( x^ZZ )sage: P.gen()x>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> P = GrowthGroup( x^ZZ )>>> P.gen()x
sage: P = GrowthGroup( (QQ_+)^x )sage: P.gen()Traceback (most recent call last):...
IndexError: tuple index out of range>>> from sage.all import *>>> P = GrowthGroup( (QQ_+)^x )>>> P.gen()Traceback (most recent call last):...
IndexError: tuple index out of range

4.3. (Asymptotic) Growth Groups

87

Asymptotic Expansions, Release 10.4

gens()
Return a tuple of all generators of this growth group.
INPUT:
Nothing.
OUTPUT:
A tuple whose entries are growth elements.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: P = GrowthGroup( x^ZZ )sage: P.gens()(x,)
sage: GrowthGroup( log(x)^ZZ ).gens()(log(x),)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> P = GrowthGroup( x^ZZ )>>> P.gens()(x,)>>> GrowthGroup( log(x)^ZZ ).gens()(log(x),)gens_monomial()
Return a tuple containing monomial generators of this growth group.
INPUT:
Nothing.
OUTPUT:An empty tuple.
Note: A generator is called monomial generator if the variable of the underlying growth group is a valid
identifier. For example, x^ZZ has x as a monomial generator, while log(x)^ZZ or icecream(x)^ZZ
do not have monomial generators.
is_compatible(other)
Return whether this growth group is compatible with other meaning that both are of the same type andhave the same variables, but maybe a different base.
INPUT:• other – a growth group
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import ExponentialGrowthGroup,␣
˓→ExponentialNonGrowthGroupsage: from sage.groups.misc_gps.argument_groups import RootsOfUnityGroupsage: EQ = ExponentialGrowthGroup(QQ, n )sage: EZ = ExponentialGrowthGroup(ZZ, n )sage: UU = ExponentialNonGrowthGroup(RootsOfUnityGroup(), n )(continues on next page)

88

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: for a in (EQ, EZ, UU):....:
for b in (EQ, EZ, UU):....:
print( {} is {}compatible with {} .format(....:a,if a.is_compatible(b) else not , b))
Growth Group QQ^n is compatible with Growth Group QQ^n
Growth Group QQ^n is compatible with Growth Group ZZ^n
Growth Group QQ^n is compatible with Growth Group UU^n
Growth Group ZZ^n is compatible with Growth Group QQ^n
Growth Group ZZ^n is compatible with Growth Group ZZ^n
Growth Group ZZ^n is compatible with Growth Group UU^n
Growth Group UU^n is not compatible with Growth Group QQ^n
Growth Group UU^n is not compatible with Growth Group ZZ^n
Growth Group UU^n is compatible with Growth Group UU^n>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import ExponentialGrowthGroup,␣
˓→ExponentialNonGrowthGroup>>> from sage.groups.misc_gps.argument_groups import RootsOfUnityGroup>>> EQ = ExponentialGrowthGroup(QQ, n )>>> EZ = ExponentialGrowthGroup(ZZ, n )>>> UU = ExponentialNonGrowthGroup(RootsOfUnityGroup(), n )>>> for a in (EQ, EZ, UU):...
for b in (EQ, EZ, UU):...
print( {} is {}compatible with {} .format(...
a,if a.is_compatible(b) else not , b))
Growth Group QQ^n is compatible with Growth Group QQ^n
Growth Group QQ^n is compatible with Growth Group ZZ^n
Growth Group QQ^n is compatible with Growth Group UU^n
Growth Group ZZ^n is compatible with Growth Group QQ^n
Growth Group ZZ^n is compatible with Growth Group ZZ^n
Growth Group ZZ^n is compatible with Growth Group UU^n
Growth Group UU^n is not compatible with Growth Group QQ^n
Growth Group UU^n is not compatible with Growth Group ZZ^n
Growth Group UU^n is compatible with Growth Group UU^nle(left, right)
Return whether the growth of left is at most (less than or equal to) the growth of right.
INPUT:• left – an element.
• right – an element.
OUTPUT:
A boolean.
Note: This function uses the coercion model to find a common parent for the two operands.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ )sage: x = G.gen()sage: G.le(x, x^2)
(continues on next page)

4.3. (Asymptotic) Growth Groups

89

Asymptotic Expansions, Release 10.4

(continued from previous page)True
sage: G.le(x^2, x)
False
sage: G.le(x^0, 1)
True>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ )>>> x = G.gen()>>> G.le(x, x**Integer(2))
True>>> G.le(x**Integer(2), x)
False>>> G.le(x**Integer(0), Integer(1))
Truengens()
Return the number of generators (as a group) of this growth group.
INPUT:
Nothing.
OUTPUT:A Python integer.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: P = GrowthGroup( x^ZZ )sage: P.ngens()
1
sage: GrowthGroup( log(x)^ZZ ).ngens()
1>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> P = GrowthGroup( x^ZZ )>>> P.ngens()
1>>> GrowthGroup( log(x)^ZZ ).ngens()
1
sage: P = GrowthGroup( (QQ_+)^x )sage: P.ngens()0>>> from sage.all import *>>> P = GrowthGroup( (QQ_+)^x )>>> P.ngens()0

non_growth_group()
Return a non-growth group compatible with this growth group.

90

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

OUTPUT:
A group group.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GenericGrowthGroupsage: GenericGrowthGroup(ZZ, n ).non_growth_group()
Traceback (most recent call last):...
NotImplementedError: only implemented in concrete realizations>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GenericGrowthGroup>>> GenericGrowthGroup(ZZ, n ).non_growth_group()
Traceback (most recent call last):...
NotImplementedError: only implemented in concrete realizations

some_elements()
Return some elements of this growth group.
See TestSuite for a typical use case.
INPUT:
Nothing.
OUTPUT:
An iterator.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: tuple(GrowthGroup( z^ZZ ).some_elements())(1, z, z^(-1), z^2, z^(-2), z^3, z^(-3),
z^4, z^(-4), z^5, z^(-5), ...)
sage: tuple(GrowthGroup( z^QQ ).some_elements())(z^(1/2), z^(-1/2), z^2, z^(-2),
1, z, z^(-1), z^42,z^(2/3), z^(-2/3), z^(3/2), z^(-3/2),
z^(4/5), z^(-4/5), z^(5/4), z^(-5/4), ...)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> tuple(GrowthGroup( z^ZZ ).some_elements())(1, z, z^(-1), z^2, z^(-2), z^3, z^(-3),
z^4, z^(-4), z^5, z^(-5), ...)>>> tuple(GrowthGroup( z^QQ ).some_elements())(z^(1/2), z^(-1/2), z^2, z^(-2),
1, z, z^(-1), z^42,z^(2/3), z^(-2/3), z^(3/2), z^(-3/2),
z^(4/5), z^(-4/5), z^(5/4), z^(-5/4), ...)

variable_names()
Return the names of the variables of this growth group.
OUTPUT:
A tuple of strings.
4.3. (Asymptotic) Growth Groups

91

Asymptotic Expansions, Release 10.4

EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GenericGrowthGroupsage: GenericGrowthGroup(ZZ).variable_names()()>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GenericGrowthGroup>>> GenericGrowthGroup(ZZ).variable_names()()
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( x^ZZ ).variable_names()( x ,)
sage: GrowthGroup( log(x)^ZZ ).variable_names()( x ,)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( x^ZZ ).variable_names()( x ,)>>> GrowthGroup( log(x)^ZZ ).variable_names()( x ,)
sage: GrowthGroup( (QQ_+)^x ).variable_names()( x ,)
sage: GrowthGroup( (QQ_+)^(x*log(x)) ).variable_names()( x ,)>>> from sage.all import *>>> GrowthGroup( (QQ_+)^x ).variable_names()( x ,)>>> GrowthGroup( (QQ_+)^(x*log(x)) ).variable_names()( x ,)

class sage.rings.asymptotic.growth_group.GenericNonGrowthElement(parent,
raw_element)
Bases: GenericGrowthElement
An element of GenericNonGrowthGroup.
class sage.rings.asymptotic.growth_group.GenericNonGrowthGroup(base, var, category)Bases: GenericGrowthGroupA (abstract) growth group whose elements are all of the same growth 1.
See ExponentialNonGrowthGroup for a concrete realization.
sage.rings.asymptotic.growth_group.GrowthGroup =<sage.rings.asymptotic.growth_group.GrowthGroupFactory object>
A factory for growth groups. This is an instance of GrowthGroupFactory whose documentation provides
more details.
class sage.rings.asymptotic.growth_group.GrowthGroupFactor(cls, base, var, extend_by_non_growth_group)
Bases: tuple

92

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

base
Alias for field number 1
cls
Alias for field number 0
extend_by_non_growth_group
Alias for field number 3
varAlias for field number 2class sage.rings.asymptotic.growth_group.GrowthGroupFactory
Bases: UniqueFactory
A factory creating asymptotic growth groups.
INPUT:• specification – a string.
• keyword arguments are passed on to the growth group constructor. If the keyword ignore_variables
is not specified, then ignore_variables=( e ,) (to ignore e as a variable name) is used.
OUTPUT:
An asymptotic growth group.
Note: An instance of this factory is available as GrowthGroup.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( x^ZZ )Growth Group x^ZZ
sage: GrowthGroup( log(x)^QQ )Growth Group log(x)^QQ>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( x^ZZ )Growth Group x^ZZ>>> GrowthGroup( log(x)^QQ )Growth Group log(x)^QQ

This factory can also be used to construct Cartesian products of growth groups:
sage: GrowthGroup( x^ZZ * y^ZZ )Growth Group x^ZZ * y^ZZ
sage: GrowthGroup( x^ZZ * log(x)^ZZ )Growth Group x^ZZ * log(x)^ZZ
sage: GrowthGroup( x^ZZ * log(x)^ZZ * y^QQ )Growth Group x^ZZ * log(x)^ZZ * y^QQ
sage: GrowthGroup( (QQ_+)^x * x^ZZ * y^QQ * (QQ_+)^z )Growth Group QQ^x * x^ZZ * y^QQ * QQ^z
sage: GrowthGroup( QQ^x * x^ZZ * y^QQ * QQ^z )Growth Group QQ^x * x^ZZ * Signs^x * y^QQ * QQ^z * Signs^zsage: GrowthGroup( exp(x)^ZZ * x^ZZ )(continues on next page)

4.3. (Asymptotic) Growth Groups

93

Asymptotic Expansions, Release 10.4

(continued from previous page)

Growth Group exp(x)^ZZ * x^ZZ
sage: GrowthGroup( (e^x)^ZZ * x^ZZ )Growth Group (e^x)^ZZ * x^ZZ>>> from sage.all import *>>> GrowthGroup( x^ZZ * y^ZZ )Growth Group x^ZZ * y^ZZ>>> GrowthGroup( x^ZZ * log(x)^ZZ )Growth Group x^ZZ * log(x)^ZZ>>> GrowthGroup( x^ZZ * log(x)^ZZ * y^QQ )Growth Group x^ZZ * log(x)^ZZ * y^QQ>>> GrowthGroup( (QQ_+)^x * x^ZZ * y^QQ * (QQ_+)^z )Growth Group QQ^x * x^ZZ * y^QQ * QQ^z>>> GrowthGroup( QQ^x * x^ZZ * y^QQ * QQ^z )Growth Group QQ^x * x^ZZ * Signs^x * y^QQ * QQ^z * Signs^z>>> GrowthGroup( exp(x)^ZZ * x^ZZ )Growth Group exp(x)^ZZ * x^ZZ>>> GrowthGroup( (e^x)^ZZ * x^ZZ )Growth Group (e^x)^ZZ * x^ZZ
sage: GrowthGroup( QQ^n * n^ZZ )Growth Group QQ^n * n^ZZ * Signs^nsage: GrowthGroup( (QQ_+)^n * n^ZZ * UU^n )Growth Group QQ^n * n^ZZ * UU^nsage: GrowthGroup( (QQ_+)^n * n^ZZ )Growth Group QQ^n * n^ZZ>>> from sage.all import *>>> GrowthGroup( QQ^n * n^ZZ )Growth Group QQ^n * n^ZZ * Signs^n>>> GrowthGroup( (QQ_+)^n * n^ZZ * UU^n )Growth Group QQ^n * n^ZZ * UU^n>>> GrowthGroup( (QQ_+)^n * n^ZZ )Growth Group QQ^n * n^ZZsage: GrowthGroup( n^(ZZ) )Growth Group n^ZZsage: GrowthGroup( n^(ZZ[I]) )Growth Group n^ZZ * n^(ZZ*I)
sage: GrowthGroup( n^(I*ZZ) )Growth Group n^(ZZ*I)
sage: GrowthGroup( n^(ZZ*I) )Growth Group n^(ZZ*I)>>> from sage.all import *>>> GrowthGroup( n^(ZZ) )Growth Group n^ZZ>>> GrowthGroup( n^(ZZ[I]) )Growth Group n^ZZ * n^(ZZ*I)>>> GrowthGroup( n^(I*ZZ) )Growth Group n^(ZZ*I)>>> GrowthGroup( n^(ZZ*I) )Growth Group n^(ZZ*I)

create_key_and_extra_args(specification, **kwds)

94

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Given the arguments and keyword, create a key that uniquely determines this object.
create_object(version, factors, **kwds)
Create an object from the given arguments.
class sage.rings.asymptotic.growth_group.MonomialGrowthElement(parent, raw_element)
Bases: GenericGrowthElement
An implementation of monomial growth elements.
INPUT:• parent – a MonomialGrowthGroup.
• raw_element – an element from the base ring of the parent.
This raw_element is the exponent of the created monomial growth element.
A monomial growth element represents a term of the type variableexponent . The multiplication corresponds to theaddition of the exponents.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import MonomialGrowthGroupsage: P = MonomialGrowthGroup(ZZ, x )sage: e1 = P(1); e1
1
sage: e2 = P(raw_element=2); e2x^2
sage: e1 == e2
False
sage: P.le(e1, e2)
True
sage: P.le(e1, P.gen()) and P.le(P.gen(), e2)
True>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import MonomialGrowthGroup>>> P = MonomialGrowthGroup(ZZ, x )>>> e1 = P(Integer(1)); e1
1>>> e2 = P(raw_element=Integer(2)); e2
x^2>>> e1 == e2
False>>> P.le(e1, e2)
True>>> P.le(e1, P.gen()) and P.le(P.gen(), e2)
Trueproperty exponent
The exponent of this growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: P = GrowthGroup( x^ZZ )sage: P(x^42).exponent
42

4.3. (Asymptotic) Growth Groups

95

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> P = GrowthGroup( x^ZZ )>>> P(x**Integer(42)).exponent
42

class sage.rings.asymptotic.growth_group.MonomialGrowthGroup(base, var, category)Bases: GenericGrowthGroupA growth group dealing with powers of a fixed object/symbol.
The elements MonomialGrowthElement of this group represent powers of a fixed base; the group law is themultiplication, which corresponds to the addition of the exponents of the monomials.
INPUT:• base – one of SageMath’s parents, out of which the elements get their data (raw_element).
As monomials are represented by this group, the elements in base are the exponents of these monomials.
• var – an object.
The string representation of var acts as a base of the monomials represented by this group.
• category – (default: None) the category of the newly created growth group. It has to be a subcategory ofJoin of Category of groups and Category of posets. This is also the default category
if None is specified.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import MonomialGrowthGroupsage: P = MonomialGrowthGroup(ZZ, x ); P
Growth Group x^ZZ
sage: MonomialGrowthGroup(ZZ, log(SR.var( y )))Growth Group log(y)^ZZ>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import MonomialGrowthGroup>>> P = MonomialGrowthGroup(ZZ, x ); P
Growth Group x^ZZ>>> MonomialGrowthGroup(ZZ, log(SR.var( y )))Growth Group log(y)^ZZ

See also:
GenericGrowthGroup
AdditiveMagmas
alias of AdditiveMagmas
Element
alias of MonomialGrowthElement
Magmasalias of Magmas
Posetsalias of Posets

96

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Sets
alias of Sets
construction()
Return the construction of this growth group.
OUTPUT:
A pair whose first entry is a monomial construction functor and its second entry the base.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( x^ZZ ).construction()(MonomialGrowthGroup[x], Integer Ring)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( x^ZZ ).construction()(MonomialGrowthGroup[x], Integer Ring)classmethod factory(base, var, extend_by_non_growth_group=False, return_factors=False, **kwds)
Create a monomial growth group.
INPUT:• base, var, keywords – use in the initialization of the exponential growth group; see MonomialGrowthGroup for details.
• extend_by_non_growth_group – a boolean (default False). If set, then the growth groupconsists of two parts, one part dealing with the absolute values of the bases and one for their arguments.
• return_factors – a boolean (default: False). If set, then a tuple of the (cartesian) factors of thisgrowth group is returned.
OUTPUT:
A growth group or tuple of growth groups.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import MonomialGrowthGroupsage: from sage.groups.misc_gps.imaginary_groups import ImaginaryGroupsage: MonomialGrowthGroup.factory(ZZ, n )Growth Group n^ZZsage: MonomialGrowthGroup.factory(ImaginaryGroup(ZZ), n )Growth Group n^(ZZ*I)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import MonomialGrowthGroup>>> from sage.groups.misc_gps.imaginary_groups import ImaginaryGroup>>> MonomialGrowthGroup.factory(ZZ, n )Growth Group n^ZZ>>> MonomialGrowthGroup.factory(ImaginaryGroup(ZZ), n )Growth Group n^(ZZ*I)

gens_logarithmic()
Return a tuple containing logarithmic generators of this growth group.
INPUT:

4.3. (Asymptotic) Growth Groups

97

Asymptotic Expansions, Release 10.4

Nothing.
OUTPUT:
A tuple containing elements of this growth group.
Note: A generator is called logarithmic generator if the variable of the underlying growth group is thelogarithm of a valid identifier. For example, x^ZZ has no logarithmic generator, while log(x)^ZZ haslog(x) as logarithmic generator.
gens_monomial()
Return a tuple containing monomial generators of this growth group.
INPUT:
Nothing.
OUTPUT:
A tuple containing elements of this growth group.
Note: A generator is called monomial generator if the variable of the underlying growth group is a valid
identifier. For example, x^ZZ has x as a monomial generator, while log(x)^ZZ or icecream(x)^ZZ
do not have monomial generators.
non_growth_group()
Return a non-growth group (with an imaginary group as base) compatible with this monomial growth group.
OUTPUT:
A group group.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( n^ZZ ).non_growth_group()
Growth Group n^(ZZ*I)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( n^ZZ ).non_growth_group()
Growth Group n^(ZZ*I)

class sage.rings.asymptotic.growth_group.MonomialGrowthGroupFunctor(var)
Bases: AbstractGrowthGroupFunctor
A construction functor for monomial growth groups.
INPUT:• var – a string or list of strings (or anything else Variable accepts).
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroup,␣
˓→MonomialGrowthGroupFunctor
sage: GrowthGroup( z^QQ ).construction()[0]MonomialGrowthGroup[z]98

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup,␣
˓→MonomialGrowthGroupFunctor>>> GrowthGroup( z^QQ ).construction()[Integer(0)]MonomialGrowthGroup[z]See also:
Asymptotic Ring, AbstractGrowthGroupFunctor, ExponentialGrowthGroupFunctor, sage.
rings.asymptotic.asymptotic_ring.AsymptoticRingFunctor,
sage.categories.
pushout.ConstructionFunctor.
class sage.rings.asymptotic.growth_group.MonomialNonGrowthElement(parent,
raw_element)
Bases: GenericNonGrowthElement, MonomialGrowthElement
An element of MonomialNonGrowthGroup.
class sage.rings.asymptotic.growth_group.MonomialNonGrowthGroup(base, var, category)Bases: GenericNonGrowthGroup, MonomialGrowthGroupA growth group whose base is an imaginary group.
EXAMPLES:
sage: from sage.groups.misc_gps.imaginary_groups import ImaginaryGroupsage: from sage.rings.asymptotic.growth_group import MonomialNonGrowthGroupsage: J = MonomialNonGrowthGroup(ImaginaryGroup(ZZ), n )sage: J.an_element()n^I>>> from sage.all import *>>> from sage.groups.misc_gps.imaginary_groups import ImaginaryGroup>>> from sage.rings.asymptotic.growth_group import MonomialNonGrowthGroup>>> J = MonomialNonGrowthGroup(ImaginaryGroup(ZZ), n )>>> J.an_element()n^I

Element
alias of MonomialNonGrowthElement
construction()
Return the construction of this growth group.
OUTPUT:
A pair whose first entry is an MonomialNonGrowthGroupFunctor and its second entry the base.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( x^(QQ*I) ).construction()(MonomialNonGrowthGroup[x], Imaginary Group over Rational Field)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( x^(QQ*I) ).construction()(MonomialNonGrowthGroup[x], Imaginary Group over Rational Field)

4.3. (Asymptotic) Growth Groups

99

Asymptotic Expansions, Release 10.4class sage.rings.asymptotic.growth_group.MonomialNonGrowthGroupFunctor(var)
Bases: MonomialGrowthGroupFunctor
A construction functor for MonomialNonGrowthGroup.
class sage.rings.asymptotic.growth_group.PartialConversionElement(growth_group,
raw_element)
Bases: SageObject
A not converted element of a growth group.
INPUT:• growth_group – a group group• raw_element – an object
A PartialConversionElement is an element growth_group(raw_element) which usually appears
in conjunction with PartialConversionValueError. In this case, it was to possible to create that element,
although the conversion went partially well in the sense that a 𝑟𝑎𝑤𝑒 𝑙𝑒𝑚𝑒𝑛𝑡 (e.g. an exponent for MonomialGrowthElement or a base for ExponentialGrowthElement) could be extracted.
Its main purpose is to carry data used during the creation of elements of cartesian products of growthgroups.
is_compatible(other)
Wrapper to GenericGrowthGroup.is_compatible().
split()
Split the contained raw_element_split_raw_element_().

accordingtothegrowthgroup’s

GrowthGroup.

EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import ExponentialGrowthGroup,␣˓→PartialConversionValueError
sage: E = ExponentialGrowthGroup(ZZ, x )sage: try:....:E((-2)^x)....: except PartialConversionValueError as e:....:e.element.split()(2^x, element with parameter -1 (<class int >) in Growth Group ZZ^x)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import ExponentialGrowthGroup,␣˓→PartialConversionValueError>>> E = ExponentialGrowthGroup(ZZ, x )>>> try:...
E((-Integer(2))**x)... except PartialConversionValueError as e:...
e.element.split()(2^x, element with parameter -1 (<class int >) in Growth Group ZZ^x)

exception sage.rings.asymptotic.growth_group.PartialConversionValueError(element,*args,**kwds)Bases: ValueError
A special ValueError which is raised when (partial) conversion fails.
100

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

INPUT:• element – a PartialConversionElement
The remaining argument passed on to ValueError.
class sage.rings.asymptotic.growth_group.Variable(var, repr=None, latex_name=None,
ignore=None)
Bases: CachedRepresentation, SageObject
A class managing the variable of a growth group.
INPUT:• var – an object whose representation string is used as the variable. It has to be a valid Python identifier. var
can also be a tuple (or other iterable) of such objects.
• repr – (default: None) if specified, then this string will be displayed instead of var. Use this to get e.g.
log(x)^ZZ: var is then used to specify the variable 𝑥.
• latex_name – (default: None) if specified, then this string will be used as LaTeX-representation of var.
• ignore – (default: None) a tuple (or other iterable) of strings which are not variables.
static extract_variable_names(s)Determine the name of the variable for the given string.
INPUT:• s – a string.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import Variable
sage: Variable.extract_variable_names( )()sage: Variable.extract_variable_names( x )( x ,)
sage: Variable.extract_variable_names( exp(x) )( x ,)
sage: Variable.extract_variable_names( sin(cos(ln(x))) )( x ,)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import Variable>>> Variable.extract_variable_names( )()>>> Variable.extract_variable_names( x )( x ,)>>> Variable.extract_variable_names( exp(x) )( x ,)>>> Variable.extract_variable_names( sin(cos(ln(x))) )( x ,)
sage: Variable.extract_variable_names( log(77w) )( w ,)
sage: Variable.extract_variable_names( log(x )Traceback (most recent call last):(continues on next page)

4.3. (Asymptotic) Growth Groups

101

Asymptotic Expansions, Release 10.4

(continued from previous page)...
TypeError: Bad function call: log(x !!!
sage: Variable.extract_variable_names( x) )Traceback (most recent call last):...
TypeError: Malformed expression: x) !!!
sage: Variable.extract_variable_names( log)x( )Traceback (most recent call last):...
TypeError: Malformed expression: log) !!! x(
sage: Variable.extract_variable_names( log(x)+y )( x , y )sage: Variable.extract_variable_names( icecream(summer) )( summer ,)>>> from sage.all import *>>> Variable.extract_variable_names( log(77w) )( w ,)>>> Variable.extract_variable_names( log(x )Traceback (most recent call last):...
TypeError: Bad function call: log(x !!!
>>> Variable.extract_variable_names( x) )Traceback (most recent call last):...
TypeError: Malformed expression: x) !!!
>>> Variable.extract_variable_names( log)x( )Traceback (most recent call last):...
TypeError: Malformed expression: log) !!! x(>>> Variable.extract_variable_names( log(x)+y )( x , y )>>> Variable.extract_variable_names( icecream(summer) )( summer ,)sage: Variable.extract_variable_names( a + b )( a , b )sage: Variable.extract_variable_names( a+b )( a , b )sage: Variable.extract_variable_names( a +b )( a , b )sage: Variable.extract_variable_names( +a )( a ,)
sage: Variable.extract_variable_names( a+ )Traceback (most recent call last):...
TypeError: Malformed expression: a+ !!!
sage: Variable.extract_variable_names( b! )( b ,)
sage: Variable.extract_variable_names( -a )( a ,)
sage: Variable.extract_variable_names( a*b )( a , b )sage: Variable.extract_variable_names( 2^q )( q ,)
sage: Variable.extract_variable_names( 77 )(continues on next page)

102

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)()>>> from sage.all import *>>> Variable.extract_variable_names( a + b )( a , b )>>> Variable.extract_variable_names( a+b )( a , b )>>> Variable.extract_variable_names( a +b )( a , b )>>> Variable.extract_variable_names( +a )( a ,)>>> Variable.extract_variable_names( a+ )Traceback (most recent call last):...
TypeError: Malformed expression: a+ !!!
>>> Variable.extract_variable_names( b! )( b ,)>>> Variable.extract_variable_names( -a )( a ,)>>> Variable.extract_variable_names( a*b )( a , b )>>> Variable.extract_variable_names( 2^q )( q ,)>>> Variable.extract_variable_names( 77 )()sage: Variable.extract_variable_names( a + (b + c) + d )( a , b , c , d )>>> from sage.all import *>>> Variable.extract_variable_names( a + (b + c) + d )( a , b , c , d )is_monomial()
Return whether this is a monomial variable.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import Variable
sage: Variable( x ).is_monomial()
True
sage: Variable( log(x) ).is_monomial()
False>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import Variable>>> Variable( x ).is_monomial()
True>>> Variable( log(x) ).is_monomial()
False

variable_names()

4.3. (Asymptotic) Growth Groups

103

Asymptotic Expansions, Release 10.4

Return the names of the variables.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import Variable
sage: Variable( x ).variable_names()( x ,)
sage: Variable( log(x) ).variable_names()( x ,)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import Variable>>> Variable( x ).variable_names()( x ,)>>> Variable( log(x) ).variable_names()( x ,)

4.4 Cartesian Products of Growth Groups
See (Asymptotic) Growth Groups for a description.
AUTHORS:• Benjamin Hackl (2015)• Daniel Krenn (2015)• Clemens Heuberger (2016)
ACKNOWLEDGEMENT:• Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P
24644-N26.
• Benjamin Hackl is supported by the Google Summer of Code 2015.

4.4.1 Classes and Methods
class sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory
Bases: UniqueFactory
Create various types of Cartesian products depending on its input.
INPUT:• growth_groups – a tuple (or other iterable) of growth groups.
• order – (default: None) if specified, then this order is taken for comparing two Cartesian product elements.
If order is None this is determined automatically.
Note: The Cartesian product of growth groups is again a growth group. In particular, the resulting structure ispartially ordered.

104

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

The order on the product is determined as follows:• Cartesian factors with respect to the same variable are ordered lexicographically.
This causes
GrowthGroup( x^ZZ * log(x)^ZZ ) and GrowthGroup( log(x)^ZZ * x^ZZ ) to produce two different growth groups.
• Factors over different variables are equipped with the product order (i.e. the comparison is component-wise).
Also, note that the sets of variables of the Cartesian factors have to be either equal or disjoint.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: A = GrowthGroup( x^ZZ ); A
Growth Group x^ZZ
sage: B = GrowthGroup( log(x)^ZZ ); B
Growth Group log(x)^ZZ
sage: C = cartesian_product([A, B]); C # indirect doctest
Growth Group x^ZZ * log(x)^ZZ
sage: C._le_ == C.le_lex
True
sage: D = GrowthGroup( y^ZZ ); D
Growth Group y^ZZ
sage: E = cartesian_product([A, D]); E # indirect doctest
Growth Group x^ZZ * y^ZZ
sage: E._le_ == E.le_productTruesage: F = cartesian_product([C, D]); F # indirect doctest
Growth Group x^ZZ * log(x)^ZZ * y^ZZ
sage: F._le_ == F.le_productTruesage: cartesian_product([A, E]); G # indirect doctest
Traceback (most recent call last):...
ValueError: The growth groups (Growth Group x^ZZ, Growth Group x^ZZ * y^ZZ)need to have pairwise disjoint or equal variables.
sage: cartesian_product([A, B, D]) # indirect doctest
Growth Group x^ZZ * log(x)^ZZ * y^ZZ>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> A = GrowthGroup( x^ZZ ); A
Growth Group x^ZZ>>> B = GrowthGroup( log(x)^ZZ ); B
Growth Group log(x)^ZZ>>> C = cartesian_product([A, B]); C # indirect doctest
Growth Group x^ZZ * log(x)^ZZ>>> C._le_ == C.le_lex
True>>> D = GrowthGroup( y^ZZ ); D
Growth Group y^ZZ>>> E = cartesian_product([A, D]); E # indirect doctest
Growth Group x^ZZ * y^ZZ>>> E._le_ == E.le_product
True>>> F = cartesian_product([C, D]); F # indirect doctest
Growth Group x^ZZ * log(x)^ZZ * y^ZZ>>> F._le_ == F.le_product(continues on next page)

4.4. Cartesian Products of Growth Groups

105

Asymptotic Expansions, Release 10.4

(continued from previous page)True>>> cartesian_product([A, E]); G # indirect doctest
Traceback (most recent call last):...
ValueError: The growth groups (Growth Group x^ZZ, Growth Group x^ZZ * y^ZZ)need to have pairwise disjoint or equal variables.
>>> cartesian_product([A, B, D]) # indirect doctest
Growth Group x^ZZ * log(x)^ZZ * y^ZZcreate_key_and_extra_args(growth_groups, category, **kwds)
Given the arguments and keywords, create a key that uniquely determines this object.
create_object(version, args, **kwds)
Create an object from the given arguments.
class sage.rings.asymptotic.growth_group_cartesian.GenericProduct(sets, category,**kwds)Bases: CartesianProductPoset, GenericGrowthGroupA Cartesian product of growth groups.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: P = GrowthGroup( x^QQ )sage: L = GrowthGroup( log(x)^ZZ )sage: C = cartesian_product([P, L], order= lex ); C # indirect doctest
Growth Group x^QQ * log(x)^ZZ
sage: C.an_element()x^(1/2)*log(x)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> P = GrowthGroup( x^QQ )>>> L = GrowthGroup( log(x)^ZZ )>>> C = cartesian_product([P, L], order= lex ); C # indirect doctest
Growth Group x^QQ * log(x)^ZZ>>> C.an_element()x^(1/2)*log(x)sage: Px = GrowthGroup( x^QQ )sage: Lx = GrowthGroup( log(x)^ZZ )sage: Cx = cartesian_product([Px, Lx], order= lex ) # indirect doctest
sage: Py = GrowthGroup( y^QQ )sage: C = cartesian_product([Cx, Py], order= product ); C # indirect doctest
Growth Group x^QQ * log(x)^ZZ * y^QQ
sage: C.an_element()x^(1/2)*log(x)*y^(1/2)>>> from sage.all import *>>> Px = GrowthGroup( x^QQ )>>> Lx = GrowthGroup( log(x)^ZZ )>>> Cx = cartesian_product([Px, Lx], order= lex ) # indirect doctest>>> Py = GrowthGroup( y^QQ )>>> C = cartesian_product([Cx, Py], order= product ); C # indirect doctest
Growth Group x^QQ * log(x)^ZZ * y^QQ(continues on next page)

106

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> C.an_element()x^(1/2)*log(x)*y^(1/2)

See also:
CartesianProduct, CartesianProductPoset.
CartesianProduct =<sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory
object>class Element
Bases: Element
exp()
The exponential of this element.
INPUT:
Nothing.
OUTPUT:
A growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ * log(x)^ZZ * log(log(x))^ZZ )sage: x = G( x )sage: exp(log(x))
xsage: exp(log(log(x)))
log(x)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ * log(x)^ZZ * log(log(x))^ZZ )>>> x = G( x )>>> exp(log(x))
x>>> exp(log(log(x)))
log(x)
sage: exp(x)Traceback (most recent call last):...
ArithmeticError: Cannot construct e^x in
Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ> *previous* TypeError: unsupported operand parent(s) for *:Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ and
Growth Group (e^x)^ZZ>>> from sage.all import *>>> exp(x)Traceback (most recent call last):...
(continues on next page)

4.4. Cartesian Products of Growth Groups

107

Asymptotic Expansions, Release 10.4

(continued from previous page)

ArithmeticError: Cannot construct e^x in
Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ> *previous* TypeError: unsupported operand parent(s) for *:Growth Group x^ZZ * log(x)^ZZ * log(log(x))^ZZ and
Growth Group (e^x)^ZZ

factors()
Return the atomic factors of this growth element. An atomic factor cannot be split further and is not theidentity (1).
INPUT:
Nothing.
OUTPUT:
A tuple of growth elements.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ * log(x)^ZZ * y^ZZ )sage: x, y = G.gens_monomial()
sage: x.factors()(x,)
sage: f = (x * y).factors(); f(x, y)
sage: tuple(factor.parent() for factor in f)(Growth Group x^ZZ, Growth Group y^ZZ)
sage: f = (x * log(x)).factors(); f(x, log(x))
sage: tuple(factor.parent() for factor in f)(Growth Group x^ZZ, Growth Group log(x)^ZZ)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ * log(x)^ZZ * y^ZZ )>>> x, y = G.gens_monomial()>>> x.factors()(x,)>>> f = (x * y).factors(); f(x, y)>>> tuple(factor.parent() for factor in f)(Growth Group x^ZZ, Growth Group y^ZZ)>>> f = (x * log(x)).factors(); f(x, log(x))>>> tuple(factor.parent() for factor in f)(Growth Group x^ZZ, Growth Group log(x)^ZZ)
sage: G = GrowthGroup( x^ZZ * log(x)^ZZ * log(log(x))^ZZ * y^QQ )sage: x, y = G.gens_monomial()
sage: f = (x * log(x) * y).factors(); f(x, log(x), y)
sage: tuple(factor.parent() for factor in f)(Growth Group x^ZZ, Growth Group log(x)^ZZ, Growth Group y^QQ)

108

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> G = GrowthGroup( x^ZZ * log(x)^ZZ * log(log(x))^ZZ * y^QQ )>>> x, y = G.gens_monomial()>>> f = (x * log(x) * y).factors(); f(x, log(x), y)>>> tuple(factor.parent() for factor in f)(Growth Group x^ZZ, Growth Group log(x)^ZZ, Growth Group y^QQ)
sage: G.one().factors()()>>> from sage.all import *>>> G.one().factors()()

is_lt_one()
Return whether this element is less than 1.
INPUT:
Nothing.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ ); x = G(x)sage: (x^42).is_lt_one() # indirect doctest
False
sage: (x^(-42)).is_lt_one() # indirect doctest
True>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ ); x = G(x)>>> (x**Integer(42)).is_lt_one() # indirect doctest
False>>> (x**(-Integer(42))).is_lt_one() # indirect doctest
Truelog(base=None)
Return the logarithm of this element.
INPUT:• base – the base of the logarithm. If None (default value) is used, the natural logarithm is taken.
OUTPUT:
A growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ * log(x)^ZZ )sage: x, = G.gens_monomial()
sage: log(x) # indirect doctest(continues on next page)

4.4. Cartesian Products of Growth Groups

109

Asymptotic Expansions, Release 10.4

(continued from previous page)log(x)
sage: log(x^5) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: When calculating log(x^5) a factor 5 != 1 appeared,
which is not contained in Growth Group x^ZZ * log(x)^ZZ.
>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ * log(x)^ZZ )>>> x, = G.gens_monomial()>>> log(x) # indirect doctest
log(x)>>> log(x**Integer(5)) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: When calculating log(x^5) a factor 5 != 1 appeared,
which is not contained in Growth Group x^ZZ * log(x)^ZZ.
sage: G = GrowthGroup( (QQ_+)^x * x^ZZ )sage: x, = G.gens_monomial()
sage: el = x.rpow(2); el2^x
sage: log(el) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: When calculating log(2^x) a factor log(2) != 1
appeared, which is not contained in Growth Group QQ^x * x^ZZ.
sage: log(el, base=2) # indirect doctestx>>> from sage.all import *>>> G = GrowthGroup( (QQ_+)^x * x^ZZ )>>> x, = G.gens_monomial()>>> el = x.rpow(Integer(2)); el
2^x>>> log(el) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: When calculating log(2^x) a factor log(2) != 1
appeared, which is not contained in Growth Group QQ^x * x^ZZ.
>>> log(el, base=Integer(2)) # indirect doctestxsage: from sage.rings.asymptotic.growth_group import GenericGrowthGroupsage: x = GenericGrowthGroup(ZZ).an_element()
sage: log(x) # indirect doctest
Traceback (most recent call last):...
NotImplementedError: Cannot determine logarithmized factorization ofGenericGrowthElement(1) in abstract base class.
>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GenericGrowthGroup>>> x = GenericGrowthGroup(ZZ).an_element()(continues on next page)

110

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> log(x) # indirect doctest
Traceback (most recent call last):...
NotImplementedError: Cannot determine logarithmized factorization ofGenericGrowthElement(1) in abstract base class.
sage: x = GrowthGroup( x^ZZ ).an_element()
sage: log(x) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot build log(x) since log(x) is not in
Growth Group x^ZZ.
>>> from sage.all import *>>> x = GrowthGroup( x^ZZ ).an_element()>>> log(x) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot build log(x) since log(x) is not in
Growth Group x^ZZ.

log_factor(base=None, locals=None)
Return the logarithm of the factorization of this element.
INPUT:• base – the base of the logarithm. If None (default value) is used, the natural logarithm is taken.
• 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 pairs, where the first entry is a growth element and the second a multiplicative coefficient.
ALGORITHM:
This function factors the given element and calculates the logarithm of each of these factors.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( (QQ_+)^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ )sage: x, y = G.gens_monomial()
sage: (x * y).log_factor() # indirect doctest((log(x), 1), (log(y), 1))
sage: (x^123).log_factor() # indirect doctest((log(x), 123),)
sage: (G( 2^x ) * x^2).log_factor(base=2) # indirect doctest((x, 1), (log(x), 2/log(2)))>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( (QQ_+)^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ )>>> x, y = G.gens_monomial()>>> (x * y).log_factor() # indirect doctest((log(x), 1), (log(y), 1))>>> (x**Integer(123)).log_factor() # indirect doctest((log(x), 123),)>>> (G( 2^x ) * x**Integer(2)).log_factor(base=Integer(2)) # indirect␣
(continues on next page)

4.4. Cartesian Products of Growth Groups

111

Asymptotic Expansions, Release 10.4

(continued from previous page)

doctest((x, 1), (log(x), 2/log(2)))˓→

sage: G(1).log_factor()()>>> from sage.all import *>>> G(Integer(1)).log_factor()()
sage: log(x).log_factor() # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot build log(log(x)) since log(log(x)) is
not in Growth Group QQ^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ.
>>> from sage.all import *>>> log(x).log_factor() # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot build log(log(x)) since log(log(x)) is
not in Growth Group QQ^x * x^ZZ * log(x)^ZZ * y^ZZ * log(y)^ZZ.

See also:
factors(), log().
rpow(base)Calculate the power of base to this element.
INPUT:• base – an element.
OUTPUT:
A growth element.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( (QQ_+)^x * x^ZZ )sage: x = G( x )sage: x.rpow(2) # indirect doctest
2^x
sage: x.rpow(1/2) # indirect doctest(1/2)^x>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( (QQ_+)^x * x^ZZ )>>> x = G( x )>>> x.rpow(Integer(2)) # indirect doctest
2^x>>> x.rpow(Integer(1)/Integer(2)) # indirect doctest(1/2)^x112

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: x.rpow(0) # indirect doctest
Traceback (most recent call last):...
ValueError: 0 is not an allowed base for calculating the power to x.
sage: (x^2).rpow(2) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot construct 2^(x^2) in Growth Group QQ^x * x^ZZ
> *previous* TypeError: unsupported operand parent(s) for *:Growth Group QQ^x * x^ZZ and Growth Group ZZ^(x^2)>>> from sage.all import *>>> x.rpow(Integer(0)) # indirect doctest
Traceback (most recent call last):...
ValueError: 0 is not an allowed base for calculating the power to x.
>>> (x**Integer(2)).rpow(Integer(2)) # indirect doctest
Traceback (most recent call last):...
ArithmeticError: Cannot construct 2^(x^2) in Growth Group QQ^x * x^ZZ
> *previous* TypeError: unsupported operand parent(s) for *:Growth Group QQ^x * x^ZZ and Growth Group ZZ^(x^2)
sage: G = GrowthGroup( QQ^(x*log(x)) * x^ZZ * log(x)^ZZ )sage: x = G( x )sage: (x * log(x)).rpow(2) # indirect doctest
2^(x*log(x))>>> from sage.all import *>>> G = GrowthGroup( QQ^(x*log(x)) * x^ZZ * log(x)^ZZ )>>> x = G( x )>>> (x * log(x)).rpow(Integer(2)) # indirect doctest
2^(x*log(x))
sage: n = GrowthGroup( (QQ_+)^n * n^QQ )( n )sage: n.rpow(2)2^nsage: _.parent()
Growth Group QQ^n * n^QQ>>> from sage.all import *>>> n = GrowthGroup( (QQ_+)^n * n^QQ )( n )>>> n.rpow(Integer(2))
2^n>>> _.parent()
Growth Group QQ^n * n^QQ
sage: n = GrowthGroup( QQ^n * n^QQ )( n )sage: n.rpow(-2)
2^n*(-1)^n>>> from sage.all import *>>> n = GrowthGroup( QQ^n * n^QQ )( n )>>> n.rpow(-Integer(2))
2^n*(-1)^n

4.4. Cartesian Products of Growth Groups

113

Asymptotic Expansions, Release 10.4

variable_names()
Return the names of the variables of this growth element.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( QQ^m * m^QQ * log(n)^ZZ )sage: G( 2^m * m^4 * log(n) ).variable_names()( m , n )sage: G( 2^m * m^4 ).variable_names()( m ,)
sage: G( log(n) ).variable_names()( n ,)
sage: G( m^3 ).variable_names()( m ,)
sage: G( m^0 ).variable_names()()>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( QQ^m * m^QQ * log(n)^ZZ )>>> G( 2^m * m^4 * log(n) ).variable_names()( m , n )>>> G( 2^m * m^4 ).variable_names()( m ,)>>> G( log(n) ).variable_names()( n ,)>>> G( m^3 ).variable_names()( m ,)>>> G( m^0 ).variable_names()()

cartesian_injection(factor, element)
Inject the given element into this Cartesian product at the given factor.
INPUT:• factor – a growth group (a factor of this Cartesian product).
• element – an element of factor.
OUTPUT:An element of this Cartesian product.
gens_monomial()
Return a tuple containing monomial generators of this growth group.
INPUT:
Nothing.
OUTPUT:
A tuple containing elements of this growth group.

114

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Note: This method calls the gens_monomial() method on the individual factors of this Cartesian
product and concatenates the respective outputs.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ )sage: G.gens_monomial()(x, y)>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ )>>> G.gens_monomial()(x, y)

some_elements()
Return some elements of this Cartesian product of growth groups.
See TestSuite for a typical use case.
OUTPUT:
An iterator.
EXAMPLES:
sage: from itertools import islice
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: G = GrowthGroup( (QQ_+)^y * x^QQ * log(x)^ZZ )sage: tuple(islice(G.some_elements(), 10r))(x^(1/2)*(1/2)^y,x^(-1/2)*log(x)*2^y,x^2*log(x)^(-1),
x^(-2)*log(x)^2*42^y,log(x)^(-2)*(2/3)^y,
x*log(x)^3*(3/2)^y,x^(-1)*log(x)^(-3)*(4/5)^y,x^42*log(x)^4*(5/4)^y,x^(2/3)*log(x)^(-4)*(6/7)^y,x^(-2/3)*log(x)^5*(7/6)^y)>>> from sage.all import *>>> from itertools import islice>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> G = GrowthGroup( (QQ_+)^y * x^QQ * log(x)^ZZ )>>> tuple(islice(G.some_elements(), 10))(x^(1/2)*(1/2)^y,x^(-1/2)*log(x)*2^y,x^2*log(x)^(-1),
x^(-2)*log(x)^2*42^y,log(x)^(-2)*(2/3)^y,
x*log(x)^3*(3/2)^y,x^(-1)*log(x)^(-3)*(4/5)^y,x^42*log(x)^4*(5/4)^y,x^(2/3)*log(x)^(-4)*(6/7)^y,x^(-2/3)*log(x)^5*(7/6)^y)

4.4. Cartesian Products of Growth Groups

115

Asymptotic Expansions, Release 10.4

variable_names()
Return the names of the variables.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: GrowthGroup( x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ ).variable_names()( x , y , z )>>> from sage.all import *>>> from sage.rings.asymptotic.growth_group import GrowthGroup>>> GrowthGroup( x^ZZ * log(x)^ZZ * y^QQ * log(z)^ZZ ).variable_names()( x , y , z )class sage.rings.asymptotic.growth_group_cartesian.MultivariateProduct(sets,
category,**kwargs)
Bases: GenericProduct
A Cartesian product of growth groups with pairwise disjoint (or equal) variable sets.
Note: A multivariate product of growth groups is ordered by means of the product order, i.e. component-wise.
This is motivated by the assumption that different variables are considered to be independent (e.g. x^ZZ * y^ZZ).
See also:
UnivariateProduct, GenericProduct.
CartesianProduct =<sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory
object>class sage.rings.asymptotic.growth_group_cartesian.UnivariateProduct(sets, category,**kwargs)
Bases: GenericProduct
A Cartesian product of growth groups with the same variables.
Note: A univariate product of growth groups is ordered lexicographically. This is motivated by the assumptionthat univariate growth groups can be ordered in a chain with respect to the growth they model (e.g. x^ZZ *log(x)^ZZ: polynomial growth dominates logarithmic growth).
See also:
MultivariateProduct, GenericProduct.
CartesianProduct =<sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory
object>116

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

4.5 (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 – 𝑂-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 coefficientring.
A characteristic property of asymptotic terms is that some terms are able to “absorb” other terms (see absorb()). For
instance, 𝑂(𝑥2 ) is able to absorb 𝑂(𝑥) (with result 𝑂(𝑥2 )), and 3·𝑥5 is able to absorb −2·𝑥5 (with result 𝑥5 ). Essentially,
absorption can be interpreted as the addition of “compatible” terms (partial addition).

4.5.1 Absorption of Asymptotic Terms
A characteristic property of asymptotic terms is that some terms are able to “absorb” other terms. This is realized withthe method absorb().
For instance, 𝑂(𝑥2 ) is able to absorb 𝑂(𝑥) (with result 𝑂(𝑥2 )). This is because the functions bounded by linear growth
are bounded by quadratic growth as well. Another example would be that 3𝑥5 is able to absorb −2𝑥5 (with result 𝑥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 termmonoids 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 GrowthGroupsage: 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))

4.5. (Asymptotic) Term Monoids

117

Asymptotic Expansions, Release 10.4

• Because of the definition of 𝑂-terms (see Wikipedia article Big_O_notation), OTerm are able to absorb all otherasymptotic 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 growthof 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 𝑂(𝑥) + 𝑂(𝑥) = 𝑂(𝑥), 𝑂(𝑥2 ) + 𝑂(𝑥) = 𝑂(𝑥2 ), and 𝑂(𝑥2 ) + 2𝑥2 = 𝑂(𝑥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(continues on next page)

118

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> 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^2When 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, norbe 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)

4.5. (Asymptotic) Term Monoids

119

Asymptotic Expansions, Release 10.4

4.5.2 Comparison
The comparison of asymptotic terms with ≤ is implemented as follows:• When comparing t1 <= t2, the coercion framework first tries to find a common parent for both terms. If thisfails, False is returned.
• In case the coerced terms do not have a coefficient in their common parent (e.g. OTerm), the growth of the twoterms is compared.
• Otherwise, if the coerced terms have a coefficient (e.g. ExactTerm), we compare whether t1 has a growth thatis 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.

4.5.3 Various
Warning: The code for B-Terms is experimental, so a warning is thrown when a BTerm is created for the firsttime in a session (see sage.misc.superseded.experimental).
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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. Ω terms, 𝑜 terms, Θ terms).
AUTHORS:• Benjamin Hackl (2015)• Daniel Krenn (2015)• Clemens Heuberger (2016)

120

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

• 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.

4.5.4 Classes and Methods
class sage.rings.asymptotic.term_monoid.BTerm(parent, growth, valid_from, **kwds)
Bases: TermWithCoefficientClass for asymptotic B-terms.
A B-term represents all functions which (in absolute value) are bounded by the given growth and coefficientfor the parameters given by valid_from. For example, we have terms that represent functions• bounded by 5|𝑥|2 for |𝑥| ≥ 3,
• bounded by 42|𝑥|3 for |𝑥| ≥ 15 and |𝑦| ≥ 15, or• bounded by 42|𝑥|3 |𝑦|2 for |𝑥| ≥ 10 and |𝑦| ≥ 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 anumber 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 GrowthGroupsage: 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|𝑥|2 for |𝑥| ≥ 3:

4.5. (Asymptotic) Term Monoids

121

Asymptotic Expansions, Release 10.4

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|𝑥|3 for |𝑥| ≥ 15 and |𝑦| ≥ 15:
sage: T(x^3, coefficient=42, valid_from={ x : 15,
B(42*x^3, x >= 15, y >= 15)

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

y :␣

This is a term bounded by 42|𝑥|3 |𝑦|2 for |𝑥| ≥ 10 and |𝑦| ≥ 20:
sage: T(x^3*y^2, coefficient=42, valid_from={ x : 10,
B(42*x^3*y^2, x >= 10, y >= 20)

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)
Check whether this B-term can absorb other.
INPUT:• other – an asymptotic term
OUTPUT:
A booleanNote: 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 GrowthGroupsage: 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)(continues on next page)

122

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)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)Trueconstruction()
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 GrowthGroupsage: 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(); aB(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,(continues on next page)

4.5. (Asymptotic) Term Monoids

123

Asymptotic Expansions, Release 10.4

(continued from previous page)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(); aB(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

See also:
GenericTerm.construction(),
TermWithCoefficient.construction(),GenericTermMonoid.from_construction()class sage.rings.asymptotic.term_monoid.BTermMonoid(term_monoid_factory, growth_group,coefficient_ring, category)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 bea 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 MonomialGrowthGroupsage: 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

124

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> 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
alias of BTermsome_elements()
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 GrowthGroupsage: 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),(continues on next page)

4.5. (Asymptotic) Term Monoids

125

Asymptotic Expansions, Release 10.4

(continued from previous page)

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
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)
Bases: TermWithCoefficientClass for asymptotic exact terms. These terms primarily consist of an asymptotic growth element as well as acoefficient.
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 GrowthGroupsage: 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^3sage: 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

126

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

They may also be multiplied with 𝑂-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^2Note 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 Ringsage: ET(5*x^2)
5*x^2

4.5. (Asymptotic) Term Monoids

127

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> x = var( x ); x.parent()
Symbolic Ring>>> ET(Integer(5)*x**Integer(2))
5*x^2can_absorb(other)
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 GrowthGroupsage: 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()
Return whether this term is an (exact) constant.
INPUT:
Nothing.

128

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

OUTPUT:
A boolean.
Note: Only ExactTerm with constant growth (1) are constant.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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()
Return whether this term is an exact term.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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(continues on next page)

4.5. (Asymptotic) Term Monoids

129

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> 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()
Return whether this exact term is of order 𝑜(1).
INPUT:
Nothing.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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(continues on next page)

130

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> 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)
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(𝑥 · 𝑦) =log(𝑥) + log(𝑦).
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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))

4.5. (Asymptotic) Term Monoids

131

Asymptotic Expansions, Release 10.4>>> 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)
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 GrowthGroupsage: 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^xsage: T( log(x) ).rpow( e )xsage: T( 42*log(x) ).rpow( e )x^42sage: T( 3*x ).rpow(2)
8^x

132

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> 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^xsage: 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^nsage: _.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 Ringclass sage.rings.asymptotic.term_monoid.ExactTermMonoid(term_monoid_factory,
growth_group, coefficient_ring,
category)
Bases: TermWithCoefficientMonoid
Parent for asymptotic exact terms, implemented in ExactTerm.
INPUT:

4.5. (Asymptotic) Term Monoids

133

Asymptotic Expansions, Release 10.4

• growth_group – a growth group.
• category – The category of the parent can be specified in order to broaden the base structure. It has to bea 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 GrowthGroupsage: 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 Ringsage: 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 RingTo:
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 RingTo:
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
alias of ExactTerm

134

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4class sage.rings.asymptotic.term_monoid.GenericTerm(parent, growth)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 GrowthGroupsage: 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)
Absorb the asymptotic term other and return the resulting asymptotic term.
INPUT:
4.5. (Asymptotic) Term Monoids

135

Asymptotic Expansions, Release 10.4

• 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 GrowthGroupsage: 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))

𝑂-Terms are able to absorb other 𝑂-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

136

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

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^2Note 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)
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 GenericGrowthGroupsage: 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(continues on next page)

4.5. (Asymptotic) Term Monoids

137

Asymptotic Expansions, Release 10.4

(continued from previous page)

False
sage: t2.can_absorb(t1)
False# indirect doctest>>> 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()
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 GrowthGroupsage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory␣
˓→as TermMonoid
sage: T = TermMonoid( O , GrowthGroup( x^ZZ ), QQ)
sage: a = T.an_element(); aO(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(); aO(x)>>> cls, kwds = a.construction(); cls, kwds(<class sage.rings.asymptotic.term_monoid.OTermMonoid_with_category.element_(continues on next page)

138

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)class >,{ growth : x,
parent : O-Term Monoid x^ZZ with implicit coefficients in Rational Field})>>> cls(**kwds) == aTrue
˓→See also:
TermWithCoefficient.construction(),from_construction()

GenericTermMonoid.

is_constant()
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 GrowthGroupsage: 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(); tGeneric 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(); tGeneric 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()(continues on next page)

4.5. (Asymptotic) Term Monoids

139

Asymptotic Expansions, Release 10.4

(continued from previous page)

False>>> T(Integer(1)).is_constant()
False

is_exact()
Return whether this term is an exact term.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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()
Return whether this generic term is of order 𝑜(1).
INPUT:
Nothing.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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)(continues on next page)

140

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

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)
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 GrowthGroupsage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory␣
˓→as TermMonoid(continues on next page)

4.5. (Asymptotic) Term Monoids141

Asymptotic Expansions, Release 10.4

(continued from previous page)

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 inthis 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 inthis 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 inthis 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 inthis abstract base class.

See also:
ExactTerm.log_term(), OTerm.log_term().
rpow(base)
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 GrowthGroupsage: from sage.rings.asymptotic.term_monoid import GenericTermMonoid
sage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory␣
˓→as TermMonoid(continues on next page)

142

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

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()
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()(continues on next page)

4.5. (Asymptotic) Term Monoids

143

Asymptotic Expansions, Release 10.4

(continued from previous page)( 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)
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 bea 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 ofasymptotic 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 GrowthGroupsage: 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

144

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Element
alias of GenericTermchange_parameter(growth_group=None, coefficient_ring=None)
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 GrowthGroupsage: 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 GrowthGroupsage: 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

4.5. (Asymptotic) Term Monoids

145

Asymptotic Expansions, Release 10.4

from_construction(construction, **kwds_overrides)
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 GrowthGroupsage: 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)

146

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

See also:
GenericTerm.construction(), TermWithCoefficient.construction()
property growth_group
The growth group underlying this term monoid.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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)
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 GrowthGroupsage: 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

4.5. (Asymptotic) Term Monoids

147

Asymptotic Expansions, Release 10.4

some_elements()
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 GrowthGroupsage: 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)
Return the term monoid of specified type.
INPUT:• type – ‘O’ or ‘exact’, or an instance of an existing term monoid. See TermMonoidFactory formore details.
OUTPUT:
A term monoid object derived from GenericTermMonoid.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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 Ringsage: 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

148

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

property term_monoid_factory
The term monoid factory capable of creating this term monoid.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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_factoryTerm 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_factoryTerm Monoid Factory __main__.TermMonoid

class sage.rings.asymptotic.term_monoid.OTerm(parent, growth)Bases: GenericTerm
Class for an asymptotic term representing an 𝑂-term with specified growth. For the mathematical properties of
𝑂-terms see Wikipedia article Big_O_Notation.
𝑂-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 GrowthGroupsage: 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(continues on next page)

4.5. (Asymptotic) Term Monoids

149

Asymptotic Expansions, Release 10.4

(continued from previous page)(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 𝑂-terms:
sage: x = SR( x ); x.parent()
Symbolic Ringsage: 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)
Check whether this 𝑂-term can absorb other.
INPUT:• other – an asymptotic term.
OUTPUT:
A boolean.

150

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

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 GrowthGroupsage: 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()
Return whether this O-term is of order 𝑜(1).
INPUT:
Nothing.
OUTPUT:
A boolean.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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()(continues on next page)

4.5. (Asymptotic) Term Monoids151

Asymptotic Expansions, Release 10.4

(continued from previous page)

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)
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.
152

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Note: This method returns a tuple with the summands that come from applying the rule log(𝑥 · 𝑦) =log(𝑥) + log(𝑦).
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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:
ExactTerm.log_term().
rpow(base)
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 𝑂(1) or if base is 1.
EXAMPLES:

4.5. (Asymptotic) Term Monoids

153

Asymptotic Expansions, Release 10.4

sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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)1sage: T( x^2 ).rpow(1)1>>> from sage.all import *>>> T.an_element().rpow(Integer(1))
1>>> T( x^2 ).rpow(Integer(1))
1sage: 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)Bases: GenericTermMonoid
154

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Parent for asymptotic big 𝑂-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 bea 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 GrowthGroupsage: 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

𝑂-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
alias of OTermclass sage.rings.asymptotic.term_monoid.TermMonoidFactory(name, exact_term_monoid_class=None,
O_term_monoid_class=None,
B_term_monoid_class=None)
Bases: UniqueRepresentation, UniqueFactory
Factory for asymptotic term monoids. It can generate the following term monoids:

4.5. (Asymptotic) Term Monoids

155

Asymptotic Expansions, Release 10.4

• OTermMonoid,• ExactTermMonoid,• BTermMonoid.
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 (capitalletter 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 fromthis asymptotic ring.
OUTPUT:
An asymptotic term monoid.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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 Ringsage: 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)(continues on next page)

156

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

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)
Given the arguments and keyword, create a key that uniquely determines this object.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: 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)
Create a object from the given arguments.
EXAMPLES:
sage: from sage.rings.asymptotic.growth_group import GrowthGroupsage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory␣
˓→as TermMonoid
sage: G = GrowthGroup( x^ZZ )(continues on next page)

4.5. (Asymptotic) Term Monoids

157

Asymptotic Expansions, Release 10.4

(continued from previous page)

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 Ringclass sage.rings.asymptotic.term_monoid.TermWithCoefficient(parent, growth, coefficient)
Bases: GenericTerm
Base class for asymptotic terms possessing a coefficient. For example, ExactTerm directly inherits from thisclass.
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 GrowthGroupsage: 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

158

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

construction()
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 GrowthGroupsage: from sage.rings.asymptotic.term_monoid import DefaultTermMonoidFactory␣
˓→as TermMonoid
sage: T = TermMonoid( exact , GrowthGroup( x^ZZ ), QQ)
sage: a = T.an_element(); a1/2*xsage: 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(); a1/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

See also:
GenericTerm.construction(), GenericTermMonoid.from_construction()class sage.rings.asymptotic.term_monoid.TermWithCoefficientMonoid(term_monoid_factory,
growth_group,coefficient_ring,
category)
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:
4.5. (Asymptotic) Term Monoids

159

Asymptotic Expansions, Release 10.4

• growth_group – a growth group.
• category – The category of the parent can be specified in order to broaden the base structure. It has to bea 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 GrowthGroupsage: 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
alias of TermWithCoefficient
some_elements()
Return some elements of this term with coefficient monoid.
See TestSuite for a typical use case.
INPUT:
Nothing.
OUTPUT:

160

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

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 GrowthGroupsage: 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
Bases: ValueError
sage.rings.asymptotic.term_monoid.absorption(left, right)
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 GrowthGroupsage: 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)

4.5. (Asymptotic) Term Monoids

161

Asymptotic Expansions, Release 10.4>>> 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)
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 GrowthGroupsage: 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␣
(continues on next page)

162

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

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˓→

4.6 Asymptotic Expansions — Miscellaneous
AUTHORS:• Daniel Krenn (2015)
ACKNOWLEDGEMENT:• Benjamin Hackl, Clemens Heuberger and Daniel Krenn are supported by the Austrian Science Fund (FWF): P
24644-N26.
• Benjamin Hackl is supported by the Google Summer of Code 2015.

4.6.1 Functions, Classes and Methods
class sage.rings.asymptotic.misc.Locals
Bases: dict
A frozen dictionary-like class for storing locals of an AsymptoticRing.
EXAMPLES:
sage: from sage.rings.asymptotic.misc import Locals
sage: locals = Locals({ a : 42})
sage: locals[ a ]42>>> from sage.all import *>>> from sage.rings.asymptotic.misc import Locals>>> locals = Locals({ a : Integer(42)})>>> locals[ a ]42The object contains default values (see default_locals()) for some keys:
sage: locals[ log ]<function log at 0x...>>>> from sage.all import *>>> locals[ log ]<function log at 0x...>default_locals()
Return the default locals used in the AsymptoticRing.
OUTPUT:4.6. Asymptotic Expansions — Miscellaneous163

Asymptotic Expansions, Release 10.4

A dictionary.
EXAMPLES:
sage: from sage.rings.asymptotic.misc import Locals
sage: locals = Locals({ a : 2, b : 1})sage: locals{ a : 2, b : 1}sage: locals.default_locals(){ log : <function log at 0x...>}
sage: locals[ log ]<function log at 0x...>>>> from sage.all import *>>> from sage.rings.asymptotic.misc import Locals>>> locals = Locals({ a : Integer(2), b : Integer(1)})>>> locals{ a : 2, b : 1}>>> locals.default_locals(){ log : <function log at 0x...>}>>> locals[ log ]<function log at 0x...>exception sage.rings.asymptotic.misc.NotImplementedBZero(asymptotic_ring=None,
var=None, exact_part=0)
Bases: NotImplementedError
A special NotImplementedError which is raised when the result is B(0) which means 0 for sufficiently large valuesof the variable.
exception sage.rings.asymptotic.misc.NotImplementedOZero(asymptotic_ring=None,
var=None, exact_part=0)
Bases: NotImplementedError
A special NotImplementedError which is raised when the result is O(0) which means 0 for sufficiently large valuesof the variable.
class sage.rings.asymptotic.misc.WithLocals
Bases: SageObject
A class extensions for handling local values; see also Locals.
This is used in the AsymptoticRing.
EXAMPLES:
sage: A.<n> = AsymptoticRing( n^ZZ , QQ, locals={ a : 42})
sage: A.locals(){ a : 42}>>> from sage.all import *>>> A = AsymptoticRing( n^ZZ , QQ, locals={ a : Integer(42)}, names=( n ,)); (n,)␣
˓→= A._first_ngens(1)>>> A.locals(){ a : 42}

locals(locals=None)
Return the actual Locals object to be used.
INPUT:
164

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

• locals – an object
If locals is not None, then a Locals object is created and returned. If locals is None, then astored Locals object, if any, is returned. Otherwise, an empty (i.e. no values except the default values)
Locals object is created and returned.
OUTPUT:
A Locals object.
sage.rings.asymptotic.misc.bidirectional_merge_overlapping(A, B, key=None)
Merge the two overlapping tuples/lists.
INPUT:• A – a list or tuple (type has to coincide with type of B).
• B – a list or tuple (type has to coincide with type of A).
• key – (default: None) a function. If None, then the identity is used. This key-function applied on anelement of the list/tuple is used for comparison. Thus elements with the same key are considered as equal.
OUTPUT:
A pair of lists or tuples (depending on the type of A and B).
Note: Suppose we can decompose the list 𝐴 = 𝑎𝑐 and 𝐵 = 𝑐𝑏 with lists 𝑎, 𝑏, 𝑐, where 𝑐 is nonempty. Thenbidirectional_merge_overlapping() returns the pair (𝑎𝑐𝑏, 𝑎𝑐𝑏).
Suppose a key-function is specified and 𝐴 = 𝑎𝑐𝐴 and 𝐵 = 𝑐𝐵 𝑏, where the list of keys of the elements of 𝑐𝐴
equals the list of keys of the elements of 𝑐𝐵 . Then bidirectional_merge_overlapping() returns thepair (𝑎𝑐𝐴 𝑏, 𝑎𝑐𝐵 𝑏).
After unsuccessfully merging 𝐴 = 𝑎𝑐 and 𝐵 = 𝑐𝑏, a merge of 𝐴 = 𝑐𝑎 and 𝐵 = 𝑏𝑐 is tried.
sage.rings.asymptotic.misc.bidirectional_merge_sorted(A, B, key=None)
Merge the two tuples/lists, keeping the orders provided by them.
INPUT:• A – a list or tuple (type has to coincide with type of B).
• B – a list or tuple (type has to coincide with type of A).
• key – (default: None) a function. If None, then the identity is used. This key-function applied on anelement of the list/tuple is used for comparison. Thus elements with the same key are considered as equal.
Note: The two tuples/list need to overlap, i.e. need at least one key in common.
OUTPUT:
A pair of lists containing all elements totally ordered. (The first component uses A as a merge base, the second
component B.)
If merging fails, then a RuntimeError is raised.
sage.rings.asymptotic.misc.combine_exceptions(e, *f)Helper function which combines the messages of the given exceptions.
INPUT:• e – an exception.
4.6. Asymptotic Expansions — Miscellaneous165

Asymptotic Expansions, Release 10.4

• *f – exceptions.
OUTPUT:
An exception.
EXAMPLES:
sage: from sage.rings.asymptotic.misc import combine_exceptions
sage: raise combine_exceptions(ValueError( Outer. ), TypeError( Inner. ))Traceback (most recent call last):...
ValueError: Outer.
> *previous* TypeError: Inner.
sage: raise combine_exceptions(ValueError( Outer. ),....:TypeError( Inner1. ), TypeError( Inner2. ))Traceback (most recent call last):...
ValueError: Outer.
> *previous* TypeError: Inner1.
> *and* TypeError: Inner2.
sage: raise combine_exceptions(ValueError( Outer. ),....:combine_exceptions(TypeError( Middle. ),....:TypeError( Inner. )))Traceback (most recent call last):...
ValueError: Outer.
> *previous* TypeError: Middle.
>> *previous* TypeError: Inner.
>>> from sage.all import *>>> from sage.rings.asymptotic.misc import combine_exceptions>>> raise combine_exceptions(ValueError( Outer. ), TypeError( Inner. ))Traceback (most recent call last):...
ValueError: Outer.
> *previous* TypeError: Inner.
>>> raise combine_exceptions(ValueError( Outer. ),...
TypeError( Inner1. ), TypeError( Inner2. ))Traceback (most recent call last):...
ValueError: Outer.
> *previous* TypeError: Inner1.
> *and* TypeError: Inner2.
>>> raise combine_exceptions(ValueError( Outer. ),...
combine_exceptions(TypeError( Middle. ),...
TypeError( Inner. )))Traceback (most recent call last):...
ValueError: Outer.
> *previous* TypeError: Middle.
>> *previous* TypeError: Inner.

sage.rings.asymptotic.misc.log_string(element, base=None)
Return a representation of the log of the given element to the given base.
INPUT:• element – an object.

166

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

• base – an object or None.
OUTPUT:A string.
EXAMPLES:
sage: from sage.rings.asymptotic.misc import log_string
sage: log_string(3)log(3)
sage: log_string(3, base=42)
log(3, base=42)>>> from sage.all import *>>> from sage.rings.asymptotic.misc import log_string>>> log_string(Integer(3))
log(3)>>> log_string(Integer(3), base=Integer(42))
log(3, base=42)

sage.rings.asymptotic.misc.parent_to_repr_short(P)Helper method which generates a short(er) representation string out of a parent.
INPUT:• P – a parent.
OUTPUT:A string.
EXAMPLES:
sage: from sage.rings.asymptotic.misc import parent_to_repr_shortsage: parent_to_repr_short(ZZ)
ZZ
sage: parent_to_repr_short(QQ)
QQ
sage: parent_to_repr_short(SR)SR
sage: parent_to_repr_short(RR)
RR
sage: parent_to_repr_short(CC)CC
sage: parent_to_repr_short(ZZ[ x ])ZZ[x]sage: parent_to_repr_short(QQ[ d, k ])QQ[d, k]sage: parent_to_repr_short(QQ[ e ])QQ[e]sage: parent_to_repr_short(SR[[ a, r ]])SR[[a, r]]
sage: parent_to_repr_short(Zmod(3))
Ring of integers modulo 3
sage: parent_to_repr_short(Zmod(3)[ g ])Univariate Polynomial Ring in g over Ring of integers modulo 3>>> from sage.all import *>>> from sage.rings.asymptotic.misc import parent_to_repr_short(continues on next page)

4.6. Asymptotic Expansions — Miscellaneous167

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> parent_to_repr_short(ZZ)
ZZ>>> parent_to_repr_short(QQ)
QQ>>> parent_to_repr_short(SR)SR>>> parent_to_repr_short(RR)
RR>>> parent_to_repr_short(CC)CC>>> parent_to_repr_short(ZZ[ x ])ZZ[x]>>> parent_to_repr_short(QQ[ d, k ])QQ[d, k]>>> parent_to_repr_short(QQ[ e ])QQ[e]>>> parent_to_repr_short(SR[[ a, r ]])SR[[a, r]]>>> parent_to_repr_short(Zmod(Integer(3)))
Ring of integers modulo 3>>> parent_to_repr_short(Zmod(Integer(3))[ g ])Univariate Polynomial Ring in g over Ring of integers modulo 3

sage.rings.asymptotic.misc.repr_op(left, op, right=None, latex=False)
Create a string left op right with taking care of parentheses in its operands.
INPUT:• left – an element.
• op – a string.
• right – an element.
• latex – (default: False) a boolean. If set, then LaTeX-output is returned.
OUTPUT:A string.
EXAMPLES:
sage: from sage.rings.asymptotic.misc import repr_op
sage: repr_op( a^b , ^ , c )(a^b)^c>>> from sage.all import *>>> from sage.rings.asymptotic.misc import repr_op>>> repr_op( a^b , ^ , c )(a^b)^csage.rings.asymptotic.misc.repr_short_to_parent(s)Helper method for the growth group factory, which converts a short representation string to a parent.
INPUT:• s – a string, short representation of a parent.
OUTPUT:
A parent.
168

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

The possible short representations are shown in the examples below.
EXAMPLES:
sage: from sage.rings.asymptotic.misc import repr_short_to_parent
sage: repr_short_to_parent( ZZ )Integer Ringsage: repr_short_to_parent( QQ )Rational Field
sage: repr_short_to_parent( SR )Symbolic Ringsage: repr_short_to_parent( NN )Non negative integer semiring
sage: repr_short_to_parent( UU )Group of Roots of Unity>>> from sage.all import *>>> from sage.rings.asymptotic.misc import repr_short_to_parent>>> repr_short_to_parent( ZZ )Integer Ring>>> repr_short_to_parent( QQ )Rational Field>>> repr_short_to_parent( SR )Symbolic Ring>>> repr_short_to_parent( NN )Non negative integer semiring>>> repr_short_to_parent( UU )Group of Roots of Unity

sage.rings.asymptotic.misc.split_str_by_op(string, op, strip_parentheses=True)
Split the given string into a tuple of substrings arising by splitting by op and taking care of parentheses.
INPUT:• string – a string.
• op – a string. This is used by str.split. Thus, if this is None, then any whitespace string is a separator andempty strings are removed from the result.
• strip_parentheses – (default: True) a boolean.
OUTPUT:
A tuple of strings.
sage.rings.asymptotic.misc.strip_symbolic(expression)
Return, if possible, the underlying (numeric) object of the symbolic expression.
If expression is not symbolic, then expression is returned.
INPUT:• expression – an object
OUTPUT:An object.
EXAMPLES:

4.6. Asymptotic Expansions — Miscellaneous169

Asymptotic Expansions, Release 10.4

sage: from sage.rings.asymptotic.misc import strip_symbolic
sage: strip_symbolic(SR(2)); _.parent()
2
Integer Ringsage: strip_symbolic(SR(2/3)); _.parent()
2/3
Rational Field
sage: strip_symbolic(SR( x )); _.parent()x
Symbolic Ringsage: strip_symbolic(pi); _.parent()pi
Symbolic Ring>>> from sage.all import *>>> from sage.rings.asymptotic.misc import strip_symbolic>>> strip_symbolic(SR(Integer(2))); _.parent()
2
Integer Ring>>> strip_symbolic(SR(Integer(2)/Integer(3))); _.parent()
2/3
Rational Field>>> strip_symbolic(SR( x )); _.parent()x
Symbolic Ring>>> strip_symbolic(pi); _.parent()pi
Symbolic Ring

sage.rings.asymptotic.misc.substitute_raise_exception(element, e)Raise an error describing what went wrong with the substitution.
INPUT:• element – an element.
• e – an exception which is included in the raised error message.
OUTPUT:
Raise an exception of the same type as e.
sage.rings.asymptotic.misc.transform_category(category, subcategory_mapping, axiom_mapping,
initial_category=None)
Transform category to a new category according to the given mappings.
INPUT:• category – a category.
• subcategory_mapping – a list (or other iterable) of triples (from, to, mandatory), where– from and to are categories and– mandatory is a boolean.
• axiom_mapping – a list (or other iterable) of triples (from, to, mandatory), where– from and to are strings describing axioms and– mandatory is a boolean.

170

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

• initial_category – (default: None) a category. When transforming the given category, this initial_category is used as a starting point of the result. This means the resulting category will be a
subcategory of initial_category. If initial_category is None, then the category ofobjects is used.
OUTPUT:
A category.
Note: Consider a subcategory mapping (from, to, mandatory). If category is a subcategory of
from, then the returned category will be a subcategory of to. Otherwise and if mandatory is set, then an error
is raised.
Consider an axiom mapping (from, to, mandatory). If category is has axiom from, then the returned
category will have axiom to. Otherwise and if mandatory is set, then an error is raised.
EXAMPLES:
sage: from sage.rings.asymptotic.misc import transform_category
sage: from sage.categories.additive_semigroups import AdditiveSemigroups
sage: from sage.categories.additive_monoids import AdditiveMonoids
sage: from sage.categories.additive_groups import AdditiveGroups
sage: S = [....:(Sets(), Sets(), True),....:(Posets(), Posets(), False),....:(AdditiveMagmas(), Magmas(), False)]
sage: A = [....:( AdditiveAssociative , Associative , False),....:( AdditiveUnital , Unital , False),....:( AdditiveInverse , Inverse , False),....:( AdditiveCommutative , Commutative , False)]
sage: transform_category(Objects(), S, A)
Traceback (most recent call last):...
ValueError: Category of objects is nota subcategory of Category of sets.
sage: transform_category(Sets(), S, A)
Category of sets
sage: transform_category(Posets(), S, A)
Category of posets
sage: transform_category(AdditiveSemigroups(), S, A)
Category of semigroups
sage: transform_category(AdditiveMonoids(), S, A)
Category of monoids
sage: transform_category(AdditiveGroups(), S, A)
Category of groups
sage: transform_category(AdditiveGroups().AdditiveCommutative(), S, A)
Category of commutative groups>>> from sage.all import *>>> from sage.rings.asymptotic.misc import transform_category>>> from sage.categories.additive_semigroups import AdditiveSemigroups>>> from sage.categories.additive_monoids import AdditiveMonoids>>> from sage.categories.additive_groups import AdditiveGroups>>> S = [...
(Sets(), Sets(), True),...
(Posets(), Posets(), False),(continues on next page)

4.6. Asymptotic Expansions — Miscellaneous171

Asymptotic Expansions, Release 10.4

(continued from previous page)...
(AdditiveMagmas(), Magmas(), False)]>>> A = [...
( AdditiveAssociative , Associative , False),...
( AdditiveUnital , Unital , False),...
( AdditiveInverse , Inverse , False),...
( AdditiveCommutative , Commutative , False)]>>> transform_category(Objects(), S, A)
Traceback (most recent call last):...
ValueError: Category of objects is nota subcategory of Category of sets.
>>> transform_category(Sets(), S, A)
Category of sets>>> transform_category(Posets(), S, A)
Category of posets>>> transform_category(AdditiveSemigroups(), S, A)
Category of semigroups>>> transform_category(AdditiveMonoids(), S, A)
Category of monoids>>> transform_category(AdditiveGroups(), S, A)
Category of groups>>> transform_category(AdditiveGroups().AdditiveCommutative(), S, A)
Category of commutative groups
sage: transform_category(AdditiveGroups().AdditiveCommutative(), S, A,....:
initial_category=Posets())
Join of Category of commutative groups
and Category of posets>>> from sage.all import *>>> transform_category(AdditiveGroups().AdditiveCommutative(), S, A,...
initial_category=Posets())
Join of Category of commutative groups
and Category of posets
sage: transform_category(ZZ.category(), S, A)
Category of commutative groups
sage: transform_category(QQ.category(), S, A)
Category of commutative groups
sage: transform_category(SR.category(), S, A)
Category of commutative groups
sage: transform_category(Fields(), S, A)
Category of commutative groups
sage: transform_category(ZZ[ t ].category(), S, A)
Category of commutative groups>>> from sage.all import *>>> transform_category(ZZ.category(), S, A)
Category of commutative groups>>> transform_category(QQ.category(), S, A)
Category of commutative groups>>> transform_category(SR.category(), S, A)
Category of commutative groups>>> transform_category(Fields(), S, A)
Category of commutative groups(continues on next page)

172

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> transform_category(ZZ[ t ].category(), S, A)
Category of commutative groups
sage: A[-1] = ( Commutative , AdditiveCommutative , True)
sage: transform_category(Groups(), S, A)
Traceback (most recent call last):...
ValueError: Category of groups does not haveaxiom Commutative.
>>> from sage.all import *>>> A[-Integer(1)] = ( Commutative , AdditiveCommutative , True)>>> transform_category(Groups(), S, A)
Traceback (most recent call last):...
ValueError: Category of groups does not haveaxiom Commutative.

4.7 Asymptotics of Multivariate Generating Series∑︀
Let 𝐹 (𝑥) = 𝜈∈N𝑑 𝐹𝜈 𝑥𝜈 be a multivariate power series with complex coefficients that converges in a neighborhood of
the origin. Assume that 𝐹 = 𝐺/𝐻 for some functions 𝐺 and 𝐻 holomorphic in a neighborhood of the origin. Assume
also that 𝐻 is a polynomial.
This computes asymptotics for the coefficients 𝐹𝑟𝛼 as 𝑟 → ∞ with 𝑟𝛼 ∈ N𝑑 for 𝛼 in a permissible subset of 𝑑-tuples of
positive reals. More specifically, it computes arbitrary terms of the asymptotic expansion for 𝐹𝑟𝛼 when the asymptotics
are controlled by a strictly minimal multiple point of the algebraic variety 𝐻 = 0.
The algorithms and formulas implemented here come from [RW2008] and [RW2012]. For a general reference take alook in the book [PW2013].

4.7.1 Introductory Examples
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions import␣
˓→FractionWithFactoredDenominatorRing>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions import␣
˓→FractionWithFactoredDenominatorRing

A univariate smooth point example:
sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (x - 1/2)^3
sage: Hfac = H.factor()sage: G = -1/(x + 3)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F(-1/(x + 3), [(x - 1/2, 3)])sage: alpha = [1](continues on next page)

4.7. Asymptotics of Multivariate Generating Series

173

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: decomp = F.asymptotic_decomposition(alpha)sage: decomp(0, []) +(-1/2*r^2*(x^2/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)+ 6*x/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)+ 9/(x^5 + 9*x^4 + 27*x^3 + 27*x^2))- 1/2*r*(5*x^2/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)+ 24*x/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)+ 27/(x^5 + 9*x^4 + 27*x^3 + 27*x^2))- 3*x^2/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)- 9*x/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)- 9/(x^5 + 9*x^4 + 27*x^3 + 27*x^2),[(x - 1/2, 1)])
sage: F1 = decomp[1]sage: p = {x: 1/2}
sage: asy = F1.asymptotics(p, alpha, 3)
sage: asy
(8/343*(49*r^2 + 161*r + 114)*2^r, 2, 8/7*r^2 + 184/49*r + 912/343)
sage: F.relative_error(asy[0], alpha, [1, 2, 4, 8, 16], asy[1])[((1,), 7.555555556, [7.556851312], [-0.0001714971672]),((2,), 14.74074074, [14.74052478], [0.00001465051901]),((4,), 35.96502058, [35.96501458], [1.667911934e-7]),((8,), 105.8425656, [105.8425656], [4.399565380e-11]),((16,), 355.3119534, [355.3119534], [0.0000000000])]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (x - Integer(1)/Integer(2))**Integer(3)>>> Hfac = H.factor()>>> G = -Integer(1)/(x + Integer(3))/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(-1/(x + 3), [(x - 1/2, 3)])>>> alpha = [Integer(1)]>>> decomp = F.asymptotic_decomposition(alpha)>>> decomp(0, []) +(-1/2*r^2*(x^2/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)+ 6*x/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)+ 9/(x^5 + 9*x^4 + 27*x^3 + 27*x^2))- 1/2*r*(5*x^2/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)+ 24*x/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)+ 27/(x^5 + 9*x^4 + 27*x^3 + 27*x^2))- 3*x^2/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)- 9*x/(x^5 + 9*x^4 + 27*x^3 + 27*x^2)- 9/(x^5 + 9*x^4 + 27*x^3 + 27*x^2),[(x - 1/2, 1)])>>> F1 = decomp[Integer(1)]>>> p = {x: Integer(1)/Integer(2)}>>> asy = F1.asymptotics(p, alpha, Integer(3))>>> asy(8/343*(49*r^2 + 161*r + 114)*2^r, 2, 8/7*r^2 + 184/49*r + 912/343)>>> F.relative_error(asy[Integer(0)], alpha, [Integer(1), Integer(2), Integer(4),␣
˓→Integer(8), Integer(16)], asy[Integer(1)])[((1,), 7.555555556, [7.556851312], [-0.0001714971672]),(continues on next page)

174

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)((2,), 14.74074074, [14.74052478], [0.00001465051901]),((4,), 35.96502058, [35.96501458], [1.667911934e-7]),((8,), 105.8425656, [105.8425656], [4.399565380e-11]),((16,), 355.3119534, [355.3119534], [0.0000000000])]

Another smooth point example (Example 5.4 of [RW2008]):
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: q = 1/2
sage: qq = q.denominator()sage: H = 1 - q*x + q*x*y - x^2*ysage: Hfac = H.factor()sage: G = (1 - q*x)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: alpha = list(qq*vector([2, 1 - q]))sage: alpha[4, 1]
sage: I = F.smooth_critical_ideal(alpha)sage: I
Ideal (y^2 - 2*y + 1, x + 1/4*y - 5/4) of
Multivariate Polynomial Ring in x, y over Rational Field
sage: s = solve([SR(z) for z in I.gens()],....:[SR(z) for z in R.gens()], solution_dict=true)
sage: s == [{SR(x): 1, SR(y): 1}]Truesage: p = s[0]sage: asy = F.asymptotics(p, alpha, 1, verbose=True)
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second order differential operator actions...
sage: asy
(1/24*2^(2/3)*(sqrt(3) + 4/(sqrt(3) + I) + I)*gamma(1/3)/(pi*r^(1/3)),
1,
1/24*2^(2/3)*(sqrt(3) + 4/(sqrt(3) + I) + I)*gamma(1/3)/(pi*r^(1/3)))
sage: r = SR( r )sage: tuple((a*r^(1/3)).full_simplify() / r^(1/3) for a in asy) # make nicer␣
˓→coefficients(1/12*sqrt(3)*2^(2/3)*gamma(1/3)/(pi*r^(1/3)),
1,
1/12*sqrt(3)*2^(2/3)*gamma(1/3)/(pi*r^(1/3)))
sage: F.relative_error(asy[0], alpha, [1, 2, 4, 8, 16], asy[1])[((4, 1), 0.1875000000, [0.1953794675...], [-0.042023826...]),((8, 2), 0.1523437500, [0.1550727862...], [-0.017913673...]),((16, 4), 0.1221771240, [0.1230813519...], [-0.0074009592...]),((32, 8), 0.09739671811, [0.09768973377...], [-0.0030084757...]),((64, 16), 0.07744253816, [0.07753639308...], [-0.0012119297...])]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> q = Integer(1)/Integer(2)>>> qq = q.denominator()>>> H = Integer(1) - q*x + q*x*y - x**Integer(2)*y>>> Hfac = H.factor()(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

175

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> G = (Integer(1) - q*x)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> alpha = list(qq*vector([Integer(2), Integer(1) - q]))>>> alpha[4, 1]>>> I = F.smooth_critical_ideal(alpha)>>> I
Ideal (y^2 - 2*y + 1, x + 1/4*y - 5/4) of
Multivariate Polynomial Ring in x, y over Rational Field>>> s = solve([SR(z) for z in I.gens()],...
[SR(z) for z in R.gens()], solution_dict=true)>>> s == [{SR(x): Integer(1), SR(y): Integer(1)}]True>>> p = s[Integer(0)]>>> asy = F.asymptotics(p, alpha, Integer(1), verbose=True)
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second order differential operator actions...
>>> asy(1/24*2^(2/3)*(sqrt(3) + 4/(sqrt(3) + I) + I)*gamma(1/3)/(pi*r^(1/3)),
1,
1/24*2^(2/3)*(sqrt(3) + 4/(sqrt(3) + I) + I)*gamma(1/3)/(pi*r^(1/3)))>>> r = SR( r )>>> tuple((a*r**(Integer(1)/Integer(3))).full_simplify() / r**(Integer(1)/Integer(3))␣
˓→for a in asy)
# make nicer coefficients(1/12*sqrt(3)*2^(2/3)*gamma(1/3)/(pi*r^(1/3)),
1,
1/12*sqrt(3)*2^(2/3)*gamma(1/3)/(pi*r^(1/3)))>>> F.relative_error(asy[Integer(0)], alpha, [Integer(1), Integer(2), Integer(4),␣
˓→Integer(8), Integer(16)], asy[Integer(1)])[((4, 1), 0.1875000000, [0.1953794675...], [-0.042023826...]),((8, 2), 0.1523437500, [0.1550727862...], [-0.017913673...]),((16, 4), 0.1221771240, [0.1230813519...], [-0.0074009592...]),((32, 8), 0.09739671811, [0.09768973377...], [-0.0030084757...]),((64, 16), 0.07744253816, [0.07753639308...], [-0.0012119297...])]A multiple point example (Example 6.5 of [RW2012]):sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - 2*x - y)**2 * (1 - x - 2*y)**2
sage: Hfac = H.factor()sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F
(1, [(x + 2*y - 1, 2), (2*x + y - 1, 2)])sage: I = F.singular_ideal()
sage: I
Ideal (x - 1/3, y - 1/3) ofMultivariate Polynomial Ring in x, y over Rational Field
sage: p = {x: 1/3, y: 1/3}
sage: F.is_convenient_multiple_point(p)(True, convenient in variables [x, y] )sage: alpha = (var( a ), var( b ))sage: decomp = F.asymptotic_decomposition(alpha); decomp(0, []) +(continues on next page)

176

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)(-1/9*r^2*(2*a^2/x^2 + 2*b^2/y^2 - 5*a*b/(x*y))- 1/9*r*(6*a/x^2 + 6*b/y^2 - 5*a/(x*y) - 5*b/(x*y))- 4/9/x^2 - 4/9/y^2 + 5/9/(x*y),[(x + 2*y - 1, 1), (2*x + y - 1, 1)])
sage: F1 = decomp[1]sage: F1.asymptotics(p, alpha, 2)(-3*((2*a^2 - 5*a*b + 2*b^2)*r^2 + (a + b)*r + 3)*(1/((1/3)^a*(1/3)^b))^r,
1/((1/3)^a*(1/3)^b), -3*(2*a^2 - 5*a*b + 2*b^2)*r^2 - 3*(a + b)*r - 9)sage: alpha = [4, 3]
sage: decomp = F.asymptotic_decomposition(alpha)sage: F1 = decomp[1]sage: asy = F1.asymptotics(p, alpha, 2)
sage: asy
(3*(10*r^2 - 7*r - 3)*2187^r, 2187, 30*r^2 - 21*r - 9)sage: F.relative_error(asy[0], alpha, [1, 2, 4, 8], asy[1])[((4, 3), 30.72702332, [0.0000000000], [1.000000000]),((8, 6), 111.9315678, [69.00000000], [0.3835519207]),((16, 12), 442.7813138, [387.0000000], [0.1259793763]),((32, 24), 1799.879232, [1743.000000], [0.03160169385])]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - Integer(2)*x - y)**Integer(2) * (Integer(1) - x -␣˓→Integer(2)*y)**Integer(2)>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(1, [(x + 2*y - 1, 2), (2*x + y - 1, 2)])>>> I = F.singular_ideal()>>> I
Ideal (x - 1/3, y - 1/3) ofMultivariate Polynomial Ring in x, y over Rational Field>>> p = {x: Integer(1)/Integer(3), y: Integer(1)/Integer(3)}>>> F.is_convenient_multiple_point(p)(True, convenient in variables [x, y] )>>> alpha = (var( a ), var( b ))>>> decomp = F.asymptotic_decomposition(alpha); decomp(0, []) +(-1/9*r^2*(2*a^2/x^2 + 2*b^2/y^2 - 5*a*b/(x*y))- 1/9*r*(6*a/x^2 + 6*b/y^2 - 5*a/(x*y) - 5*b/(x*y))- 4/9/x^2 - 4/9/y^2 + 5/9/(x*y),[(x + 2*y - 1, 1), (2*x + y - 1, 1)])>>> F1 = decomp[Integer(1)]>>> F1.asymptotics(p, alpha, Integer(2))(-3*((2*a^2 - 5*a*b + 2*b^2)*r^2 + (a + b)*r + 3)*(1/((1/3)^a*(1/3)^b))^r,
1/((1/3)^a*(1/3)^b), -3*(2*a^2 - 5*a*b + 2*b^2)*r^2 - 3*(a + b)*r - 9)>>> alpha = [Integer(4), Integer(3)]>>> decomp = F.asymptotic_decomposition(alpha)>>> F1 = decomp[Integer(1)]>>> asy = F1.asymptotics(p, alpha, Integer(2))>>> asy(3*(10*r^2 - 7*r - 3)*2187^r, 2187, 30*r^2 - 21*r - 9)>>> F.relative_error(asy[Integer(0)], alpha, [Integer(1), Integer(2), Integer(4),␣
˓→Integer(8)], asy[Integer(1)])(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

177

Asymptotic Expansions, Release 10.4

(continued from previous page)[((4, 3), 30.72702332, [0.0000000000], [1.000000000]),((8, 6), 111.9315678, [69.00000000], [0.3835519207]),((16, 12), 442.7813138, [387.0000000], [0.1259793763]),((32, 24), 1799.879232, [1743.000000], [0.03160169385])]

4.7.2 Various
AUTHORS:• Alexander Raichev (2008)• Daniel Krenn (2014, 2016)

4.7.3 Classes and Methods

class sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFacto

Bases: RingElement
This element represents a fraction with a factored polynomial denominator. See also its parent FractionWithFactoredDenominatorRing for details.
Represents a fraction with factored polynomial denominator (FFPD) 𝑝/(𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛 ) by storing the parts 𝑝 and[(𝑞1 , 𝑒1 ), . . . , (𝑞𝑛 , 𝑒𝑛 )]. Here 𝑞1 , . . . , 𝑞𝑛 are elements of a 0- or multi-variate factorial polynomial ring 𝑅 ,𝑞1 , . . . , 𝑞𝑛 are distinct irreducible elements of 𝑅 , 𝑒1 , . . . , 𝑒𝑛 are positive integers, and 𝑝 is a function of the indeterminates of 𝑅 (e.g., a Sage symbolic expression). An element 𝑟 with no polynomial denominator is represented
as (r, []).
INPUT:• numerator – an element 𝑝; this can be of any ring from which parent’s base has coercion in• denominator_factored – a list of the form [(𝑞1 , 𝑒1 ), . . . , (𝑞𝑛 , 𝑒𝑛 )], where the 𝑞1 , . . . , 𝑞𝑛 are distinct
irreducible elements of 𝑅 and the 𝑒𝑖 are positive integers• reduce – (optional) if True, then represent 𝑝/(𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛 ) in lowest terms, otherwise this won’t attempt
to divide 𝑝 by any of the 𝑞𝑖
OUTPUT:An element representing the rational expression 𝑝/(𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛 ).
EXAMPLES:

178

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: df = [x, 1], [y, 1], [x*y+1, 1]
sage: f = FFPD(x, df)
sage: f(1, [(y, 1), (x*y + 1, 1)])
sage: ff = FFPD(x, df, reduce=False)
sage: ff(x, [(y, 1), (x, 1), (x*y + 1, 1)])
sage: f = FFPD(x + y, [(x + y, 1)])
sage: f(1, [])>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> df = [x, Integer(1)], [y, Integer(1)], [x*y+Integer(1), Integer(1)]>>> f = FFPD(x, df)>>> f(1, [(y, 1), (x*y + 1, 1)])>>> ff = FFPD(x, df, reduce=False)>>> ff(x, [(y, 1), (x, 1), (x*y + 1, 1)])>>> f = FFPD(x + y, [(x + y, Integer(1))])>>> f(1, [])
sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 5*x^3 + 1/x + 1/(x-1) + 1/(3*x^2 + 1)
sage: FFPD(f)(5*x^7 - 5*x^6 + 5/3*x^5 - 5/3*x^4 + 2*x^3 - 2/3*x^2 + 1/3*x - 1/3,[(x - 1, 1), (x, 1), (x^2 + 1/3, 1)])>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(5)*x**Integer(3) + Integer(1)/x + Integer(1)/(x-Integer(1)) +␣˓→Integer(1)/(Integer(3)*x**Integer(2) + Integer(1))>>> FFPD(f)(5*x^7 - 5*x^6 + 5/3*x^5 - 5/3*x^4 + 2*x^3 - 2/3*x^2 + 1/3*x - 1/3,[(x - 1, 1), (x, 1), (x^2 + 1/3, 1)])
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: f = 2*y/(5*(x^3 - 1)*(y + 1))
sage: FFPD(f)(2/5*y, [(y + 1, 1), (x - 1, 1), (x^2 + x + 1, 1)])
sage: p = 1/x^2(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

179

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: q = 3*x**2*ysage: qs = q.factor()sage: f = FFPD(p/qs.unit(), qs)
sage: f
(1/3/x^2, [(y, 1), (x, 2)])sage: f = FFPD(cos(x)*x*y^2, [(x, 2), (y, 1)])
sage: f(x*y^2*cos(x), [(y, 1), (x, 2)])sage: G = exp(x + y)sage: H = (1 - 2*x - y) * (1 - x - 2*y)sage: a = FFPD(G/H)
sage: a(e^(x + y), [(x + 2*y - 1, 1), (2*x + y - 1, 1)])
sage: a.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field
sage: b = FFPD(G, H.factor())
sage: b(e^(x + y), [(x + 2*y - 1, 1), (2*x + y - 1, 1)])
sage: b.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> f = Integer(2)*y/(Integer(5)*(x**Integer(3) - Integer(1))*(y + Integer(1)))>>> FFPD(f)(2/5*y, [(y + 1, 1), (x - 1, 1), (x^2 + x + 1, 1)])>>> p = Integer(1)/x**Integer(2)>>> q = Integer(3)*x**Integer(2)*y>>> qs = q.factor()>>> f = FFPD(p/qs.unit(), qs)>>> f(1/3/x^2, [(y, 1), (x, 2)])>>> f = FFPD(cos(x)*x*y**Integer(2), [(x, Integer(2)), (y, Integer(1))])>>> f(x*y^2*cos(x), [(y, 1), (x, 2)])>>> G = exp(x + y)>>> H = (Integer(1) - Integer(2)*x - y) * (Integer(1) - x - Integer(2)*y)>>> a = FFPD(G/H)>>> a(e^(x + y), [(x + 2*y - 1, 1), (2*x + y - 1, 1)])>>> a.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field>>> b = FFPD(G, H.factor())>>> b(e^(x + y), [(x + 2*y - 1, 1), (2*x + y - 1, 1)])>>> b.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field

Singular throws a ‘not implemented’ error when trying to factor in a multivariate polynomial ring over an inexact
field:

180

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: R.<x,y> = PolynomialRing(CC)sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = (x + 1)/(x*y*(x*y + 1)^2)
sage: FFPD(f)Traceback (most recent call last):...
TypeError: Singular error:? not implemented? error occurred in or before STDIN line ...:
def sage...=factorize(sage...);>>> from sage.all import *>>> R = PolynomialRing(CC, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = (x + Integer(1))/(x*y*(x*y + Integer(1))**Integer(2))>>> FFPD(f)Traceback (most recent call last):...
TypeError: Singular error:? not implemented? error occurred in or before STDIN line ...:
def sage...=factorize(sage...);AUTHORS:• Alexander Raichev (2012-07-26)• Daniel Krenn (2014-12-01)
algebraic_dependence_certificate()
Return the algebraic dependence certificate of self.
The algebraic dependence certificate is the ideal 𝐽 of annihilating polynomials for the set of polynomials[q^e for (q, e) in self.denominator_factored()], which could be the zero ideal. The
ideal 𝐽 lies in a polynomial ring over the field self.denominator_ring.base_ring() that has m= len(self.denominator_factored()) indeterminates.
OUTPUT:
An ideal.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 1/(x^2 * (x*y + 1) * y^3)
sage: ff = FFPD(f)sage: J = ff.algebraic_dependence_certificate(); J
Ideal (1 - 6*T2 + 15*T2^2 - 20*T2^3 + 15*T2^4 - T0^2*T1^3 6*T2^5 + T2^6) of Multivariate Polynomial Ring in
T0, T1, T2 over Rational Field
sage: g = J.gens()[0]sage: df = ff.denominator_factored()sage: g(*(q**e for q, e in df)) == 0
True

4.7. Asymptotics of Multivariate Generating Series

181

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(1)/(x**Integer(2) * (x*y + Integer(1)) * y**Integer(3))>>> ff = FFPD(f)>>> J = ff.algebraic_dependence_certificate(); J
Ideal (1 - 6*T2 + 15*T2^2 - 20*T2^3 + 15*T2^4 - T0^2*T1^3 6*T2^5 + T2^6) of Multivariate Polynomial Ring in
T0, T1, T2 over Rational Field>>> g = J.gens()[Integer(0)]>>> df = ff.denominator_factored()>>> g(*(q**e for q, e in df)) == Integer(0)Truesage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: G = exp(x + y)sage: H = x^2 * (x*y + 1) * y^3
sage: ff = FFPD(G, H.factor())
sage: J = ff.algebraic_dependence_certificate(); J
Ideal (1 - 6*T2 + 15*T2^2 - 20*T2^3 + 15*T2^4 - T0^2*T1^3 6*T2^5 + T2^6) of Multivariate Polynomial Ring in
T0, T1, T2 over Rational Field
sage: g = J.gens()[0]sage: df = ff.denominator_factored()sage: g(*(q**e for q, e in df)) == 0
True>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> G = exp(x + y)>>> H = x**Integer(2) * (x*y + Integer(1)) * y**Integer(3)>>> ff = FFPD(G, H.factor())>>> J = ff.algebraic_dependence_certificate(); J
Ideal (1 - 6*T2 + 15*T2^2 - 20*T2^3 + 15*T2^4 - T0^2*T1^3 6*T2^5 + T2^6) of Multivariate Polynomial Ring in
T0, T1, T2 over Rational Field>>> g = J.gens()[Integer(0)]>>> df = ff.denominator_factored()>>> g(*(q**e for q, e in df)) == Integer(0)Truesage: f = 1/(x^3 * y^2)
sage: J = FFPD(f).algebraic_dependence_certificate()sage: J
Ideal (0) of Multivariate Polynomial Ring in T0, T1 over Rational Field>>> from sage.all import *>>> f = Integer(1)/(x**Integer(3) * y**Integer(2))>>> J = FFPD(f).algebraic_dependence_certificate()>>> J
Ideal (0) of Multivariate Polynomial Ring in T0, T1 over Rational Field

182

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: f = sin(1)/(x^3 * y^2)
sage: J = FFPD(f).algebraic_dependence_certificate()sage: J
Ideal (0) of Multivariate Polynomial Ring in T0, T1 over Rational Field>>> from sage.all import *>>> f = sin(Integer(1))/(x**Integer(3) * y**Integer(2))>>> J = FFPD(f).algebraic_dependence_certificate()>>> J
Ideal (0) of Multivariate Polynomial Ring in T0, T1 over Rational Field

algebraic_dependence_decomposition(whole_and_parts=True)
Return an algebraic dependence decomposition of self.
Let 𝑓 = 𝑝/𝑞 where 𝑞 lies in a 𝑑-variate polynomial ring 𝐾[𝑋] for some field 𝐾. Let 𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛 be the uniquefactorization of 𝑞 in 𝐾[𝑋] into irreducible factors and let 𝑉𝑖 be the algebraic variety {𝑥 ∈ 𝐿𝑑 | 𝑞𝑖 (𝑥) = 0}of 𝑞𝑖 over the algebraic closure 𝐿 of 𝐾. By [Rai2012], 𝑓 can be written as
∑︁
𝑝𝐴
(*)
,
∏︀
𝑏𝑖
𝑖∈𝐴 𝑞𝑖𝐴
where the 𝑏𝑖 are positive integers, each 𝑝𝐴 is a products of 𝑝 and an element in 𝐾[𝑋], and the sum is takenover all subsets 𝐴 ⊆ {1, . . . , 𝑚} such that |𝐴| ≤ 𝑑 and {𝑞𝑖 | 𝑖 ∈ 𝐴} is algebraically independent.
We call (*) an algebraic dependence decomposition of 𝑓 . Algebraic dependence decompositions are notunique.
The algorithm used comes from [Rai2012].
OUTPUT:
An instance of FractionWithFactoredDenominatorSum.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 1/(x^2 * (x*y + 1) * y^3)
sage: ff = FFPD(f)sage: decomp = ff.algebraic_dependence_decomposition()sage: decomp(0, []) + (-x, [(x*y + 1, 1)]) +(x^2*y^2 - x*y + 1, [(y, 3), (x, 2)])sage: decomp.sum().quotient() == f
True
sage: for r in decomp:....:J = r.algebraic_dependence_certificate()....:
J is None or J == J.ring().ideal() # The zero ideal
True
True
True
>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

183

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(1)/(x**Integer(2) * (x*y + Integer(1)) * y**Integer(3))>>> ff = FFPD(f)>>> decomp = ff.algebraic_dependence_decomposition()>>> decomp(0, []) + (-x, [(x*y + 1, 1)]) +(x^2*y^2 - x*y + 1, [(y, 3), (x, 2)])>>> decomp.sum().quotient() == f
True>>> for r in decomp:...
J = r.algebraic_dependence_certificate()...
J is None or J == J.ring().ideal() # The zero ideal
True
True
True
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: G = sin(x)sage: H = x^2 * (x*y + 1) * y^3
sage: f = FFPD(G, H.factor())
sage: decomp = f.algebraic_dependence_decomposition()sage: decomp(0, []) + (x^4*y^3*sin(x), [(x*y + 1, 1)]) +(-(x^5*y^5 - x^4*y^4 + x^3*y^3 - x^2*y^2 + x*y - 1)*sin(x),[(y, 3), (x, 2)])sage: bool(decomp.sum().quotient() == G/H)
True
sage: for r in decomp:....:J = r.algebraic_dependence_certificate()....:
J is None or J == J.ring().ideal()
True
True
True
>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> G = sin(x)>>> H = x**Integer(2) * (x*y + Integer(1)) * y**Integer(3)>>> f = FFPD(G, H.factor())>>> decomp = f.algebraic_dependence_decomposition()>>> decomp(0, []) + (x^4*y^3*sin(x), [(x*y + 1, 1)]) +(-(x^5*y^5 - x^4*y^4 + x^3*y^3 - x^2*y^2 + x*y - 1)*sin(x),[(y, 3), (x, 2)])>>> bool(decomp.sum().quotient() == G/H)
True>>> for r in decomp:...
J = r.algebraic_dependence_certificate()...
J is None or J == J.ring().ideal()
True
True
True

asymptotic_decomposition(alpha, asy_var=None)

184

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Return the asymptotic decomposition of self.
The asymptotic decomposition of 𝐹 is a sum that has the same asymptotic expansion as 𝑓 in the directionalpha but each summand has a denominator factorization of the form [(𝑞1 , 1), . . . , (𝑞𝑛 , 1)], where 𝑛 is at
most the dimension() of 𝐹 .
INPUT:• alpha – a 𝑑-tuple of positive integers or symbolic variables• asy_var – (default: None) a symbolic variable with respect to which to compute asymptotics; if None
is given, we set asy_var = var( r )OUTPUT:
An instance of FractionWithFactoredDenominatorSum.
The output results from a Leinartas decomposition followed by a cohomology decomposition.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: f = (x^2 + 1)/((x - 1)^3*(x + 2))
sage: F = FFPD(f)sage: alpha = [var( a )]sage: F.asymptotic_decomposition(alpha)(0, []) +(1/54*(5*a^2 + 2*a^2/x + 11*a^2/x^2)*r^2- 1/54*(5*a - 2*a/x - 33*a/x^2)*r + 11/27/x^2,[(x - 1, 1)]) + (-5/27, [(x + 2, 1)])>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> f = (x**Integer(2) + Integer(1))/((x - Integer(1))**Integer(3)*(x +␣˓→Integer(2)))>>> F = FFPD(f)>>> alpha = [var( a )]>>> F.asymptotic_decomposition(alpha)(0, []) +(1/54*(5*a^2 + 2*a^2/x + 11*a^2/x^2)*r^2- 1/54*(5*a - 2*a/x - 33*a/x^2)*r + 11/27/x^2,[(x - 1, 1)]) + (-5/27, [(x + 2, 1)])
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - 2*x -y)*(1 - x -2*y)**2
sage: Hfac = H.factor()sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: alpha = var( a, b )sage: F.asymptotic_decomposition(alpha)(0, []) +(-1/3*r*(a/x - 2*b/y) - 1/3/x + 2/3/y,[(x + 2*y - 1, 1), (2*x + y - 1, 1)])4.7. Asymptotics of Multivariate Generating Series

185

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - Integer(2)*x -y)*(Integer(1) - x ˓→Integer(2)*y)**Integer(2)>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> alpha = var( a, b )>>> F.asymptotic_decomposition(alpha)(0, []) +(-1/3*r*(a/x - 2*b/y) - 1/3/x + 2/3/y,[(x + 2*y - 1, 1), (2*x + y - 1, 1)])

asymptotics(p, alpha, N, asy_var=None, numerical=0, verbose=False)
Return the asymptotics in the given direction.
This function returns the first 𝑁 terms (some of which could be zero) of the asymptotic expansion of the
Maclaurin ray coefficients 𝐹𝑟𝛼 of the function 𝐹 represented by self as 𝑟 → ∞, where 𝑟 is asy_var andalpha is a tuple of positive integers of length 𝑑 which is self.dimension(). Assume that
• 𝐹 is holomorphic in a neighborhood of the origin;• the unique factorization of the denominator 𝐻 of 𝐹 in the local algebraic ring at 𝑝 equals its uniquefactorization in the local analytic ring at 𝑝;• the unique factorization of 𝐻 in the local algebraic ring at 𝑝 has at most d irreducible factors, none ofwhich are repeated (one can reduce to this case via asymptotic_decomposition());• 𝑝 is a convenient strictly minimal smooth or multiple point with all nonzero coordinates that is criticaland nondegenerate for alpha.
The algorithms used here come from [RW2008] and [RW2012].
INPUT:• p – a dictionary with keys that can be coerced to equal self.denominator_ring.gens()• alpha – a tuple of length self.dimension() of positive integers or, if 𝑝 is a smooth point, possiblyof symbolic variables• N – a positive integer• asy_var – (default: None) a symbolic variable for the asymptotic expansion; if none is given, thenvar( r ) will be assigned• numerical – (default: 0) a natural number; if numerical is greater than 0, then return a numericalapproximation of 𝐹𝑟𝛼 with numerical digits of precision; otherwise return exact values• verbose – (default: False) print the current state of the algorithm
OUTPUT:
The tuple (asy, exp_scale, subexp_part). Here asy is the sum of the first 𝑁 terms (some ofwhich might be 0) of the asymptotic expansion of 𝐹𝑟𝛼 as 𝑟 → ∞; exp_scale**r is the exponential factorof asy; subexp_part is the subexponential factor of asy.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing

186

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing

A smooth point example:
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - x - y - x*y)**2
sage: Hfac = H.factor()sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac); print(F)(1, [(x*y + x + y - 1, 2)])sage: alpha = [4, 3]
sage: decomp = F.asymptotic_decomposition(alpha); decomp(0, []) + (... - 1/2, [(x*y + x + y - 1, 1)])
sage: F1 = decomp[1]sage: p = {y: 1/3, x: 1/2}
sage: asy = F1.asymptotics(p, alpha, 2, verbose=True)
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second order differential operator actions...
sage: asy
(1/6000*(3600*sqrt(5)*sqrt(3)*sqrt(2)*sqrt(r)/sqrt(pi)+ 463*sqrt(5)*sqrt(3)*sqrt(2)/(sqrt(pi)*sqrt(r)))*432^r,
432,
3/5*sqrt(5)*sqrt(3)*sqrt(2)*sqrt(r)/sqrt(pi)+ 463/6000*sqrt(5)*sqrt(3)*sqrt(2)/(sqrt(pi)*sqrt(r)))
sage: F.relative_error(asy[0], alpha, [1, 2, 4, 8, 16], asy[1])˓→10# long time[((4, 3), 2.083333333, [2.092576110], [-0.004436533009]),((8, 6), 2.787374614, [2.790732875], [-0.001204811281]),((16, 12), 3.826259447, [3.827462310], [-0.0003143703383]),((32, 24), 5.328112821, [5.328540787], [-0.00008032230388]),((64, 48), 7.475927885, [7.476079664], [-0.00002030232879])]# abs tol 1e->>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - x - y - x*y)**Integer(2)>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac); print(F)(1, [(x*y + x + y - 1, 2)])>>> alpha = [Integer(4), Integer(3)]>>> decomp = F.asymptotic_decomposition(alpha); decomp(0, []) + (... - 1/2, [(x*y + x + y - 1, 1)])>>> F1 = decomp[Integer(1)]>>> p = {y: Integer(1)/Integer(3), x: Integer(1)/Integer(2)}>>> asy = F1.asymptotics(p, alpha, Integer(2), verbose=True)
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second order differential operator actions...
>>> asy(1/6000*(3600*sqrt(5)*sqrt(3)*sqrt(2)*sqrt(r)/sqrt(pi)(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

187

Asymptotic Expansions, Release 10.4

(continued from previous page)+ 463*sqrt(5)*sqrt(3)*sqrt(2)/(sqrt(pi)*sqrt(r)))*432^r,
432,
3/5*sqrt(5)*sqrt(3)*sqrt(2)*sqrt(r)/sqrt(pi)+ 463/6000*sqrt(5)*sqrt(3)*sqrt(2)/(sqrt(pi)*sqrt(r)))>>> F.relative_error(asy[Integer(0)], alpha, [Integer(1), Integer(2),␣
˓→Integer(4), Integer(8), Integer(16)], asy[Integer(1)])# abs tol 1e-10
˓→long time[((4, 3), 2.083333333, [2.092576110], [-0.004436533009]),((8, 6), 2.787374614, [2.790732875], [-0.001204811281]),((16, 12), 3.826259447, [3.827462310], [-0.0003143703383]),((32, 24), 5.328112821, [5.328540787], [-0.00008032230388]),((64, 48), 7.475927885, [7.476079664], [-0.00002030232879])]#␣

A multiple point example:
sage: R.<x,y,z>= PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (4 - 2*x - y - z)**2*(4 - x - 2*y - z)sage: Hfac = H.factor()sage: G = 16/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F(-16, [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 2)])sage: alpha = [3, 3, 2]
sage: decomp = F.asymptotic_decomposition(alpha); decomp(0, []) + (..., [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 1)])
sage: F1 = decomp[1]sage: p = {x: 1, y: 1, z: 1}
sage: asy = F1.asymptotics(p, alpha, 2, verbose=True) # long time
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second-order differential operator actions...
sage: asy # long time
(4/3*sqrt(3)*sqrt(r)/sqrt(pi) + 47/216*sqrt(3)/(sqrt(pi)*sqrt(r)),
1, 4/3*sqrt(3)*sqrt(r)/sqrt(pi) + 47/216*sqrt(3)/(sqrt(pi)*sqrt(r)))
sage: F.relative_error(asy[0], alpha, [1, 2, 4, 8], asy[1]) # long time[((3, 3, 2), 0.9812164307, [1.515572606], [-0.54458543...]),((6, 6, 4), 1.576181132, [1.992989399], [-0.26444185...]),((12, 12, 8), 2.485286378, [2.712196351], [-0.091301338...]),((24, 24, 16), 3.700576827, [3.760447895], [-0.016178847...])]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(4) - Integer(2)*x - y - z)**Integer(2)*(Integer(4) - x -␣˓→Integer(2)*y - z)>>> Hfac = H.factor()>>> G = Integer(16)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(-16, [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 2)])>>> alpha = [Integer(3), Integer(3), Integer(2)]>>> decomp = F.asymptotic_decomposition(alpha); decomp(0, []) + (..., [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 1)])
(continues on next page)

188

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> F1 = decomp[Integer(1)]>>> p = {x: Integer(1), y: Integer(1), z: Integer(1)}>>> asy = F1.asymptotics(p, alpha, Integer(2), verbose=True) # long time
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second-order differential operator actions...
>>> asy # long time
(4/3*sqrt(3)*sqrt(r)/sqrt(pi) + 47/216*sqrt(3)/(sqrt(pi)*sqrt(r)),
1, 4/3*sqrt(3)*sqrt(r)/sqrt(pi) + 47/216*sqrt(3)/(sqrt(pi)*sqrt(r)))>>> F.relative_error(asy[Integer(0)], alpha, [Integer(1), Integer(2),␣
˓→Integer(4), Integer(8)], asy[Integer(1)]) # long time[((3, 3, 2), 0.9812164307, [1.515572606], [-0.54458543...]),((6, 6, 4), 1.576181132, [1.992989399], [-0.26444185...]),((12, 12, 8), 2.485286378, [2.712196351], [-0.091301338...]),((24, 24, 16), 3.700576827, [3.760447895], [-0.016178847...])]

asymptotics_multiple(p, alpha, N, asy_var, coordinate=None, numerical=0, verbose=False)
Return the asymptotics in the given direction of a multiple point nondegenerate for alpha.
This is the same as asymptotics(), but only in the case of a convenient multiple point nondegenerate
for alpha. Assume also that self.dimension >= 2 and that the p.values() are not symbolic
variables.
The formulas used for computing the asymptotic expansion are Theorem 3.4 and Theorem 3.7 of [RW2012].
INPUT:• p – a dictionary with keys that can be coerced to equal self.denominator_ring.gens()• alpha – a tuple of length d = self.dimension() of positive integers or, if 𝑝 is a smooth point,
possibly of symbolic variables• N – a positive integer• asy_var – (optional; default: None) a symbolic variable; the variable of the asymptotic expansion, if
none is given, var( r ) will be assigned• coordinate – (optional; default: None) an integer in {0, . . . , 𝑑 − 1} indicating a convenient coordinate to base the asymptotic calculations on; if None is assigned, then choose coordinate=d-1• numerical – (optional; default: 0) a natural number; if numerical is greater than 0, then return a numerical approximation of the Maclaurin ray coefficients of self with numerical digits of precision;otherwise return exact values• verbose – (default: False) print the current state of the algorithm
OUTPUT:
The asymptotic expansion.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y,z>= PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = (4 - 2*x - y - z)*(4 - x -2*y - z)sage: Hfac = H.factor()sage: G = 16/Hfac.unit()(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

189

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: F = FFPD(G, Hfac)
sage: F
(16, [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 1)])
sage: p = {x: 1, y: 1, z: 1}
sage: alpha = [3, 3, 2]
sage: F.asymptotics_multiple(p, alpha, 2, var( r ), verbose=True) # long time
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second-order differential operator actions...
(4/3*sqrt(3)/(sqrt(pi)*sqrt(r)) - 25/216*sqrt(3)/(sqrt(pi)*r^(3/2)),
1,
4/3*sqrt(3)/(sqrt(pi)*sqrt(r)) - 25/216*sqrt(3)/(sqrt(pi)*r^(3/2)))
sage: H = (1 - x*(1 + y))*(1 - z*x**2*(1 + 2*y))sage: Hfac = H.factor()sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F
(1, [(x*y + x - 1, 1), (2*x^2*y*z + x^2*z - 1, 1)])
sage: p = {x: 1/2, z: 4/3, y: 1}
sage: alpha = [8, 3, 3]
sage: F.asymptotics_multiple(p, alpha, 2, var( r ), coordinate=1,␣˓→verbose=True) # long time
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second-order differential operator actions...
(1/172872*108^r*(24696*sqrt(7)*sqrt(3)/(sqrt(pi)*sqrt(r))- 1231*sqrt(7)*sqrt(3)/(sqrt(pi)*r^(3/2))),108,
1/7*sqrt(7)*sqrt(3)/(sqrt(pi)*sqrt(r))- 1231/172872*sqrt(7)*sqrt(3)/(sqrt(pi)*r^(3/2)))>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = (Integer(4) - Integer(2)*x - y - z)*(Integer(4) - x -Integer(2)*y - z)>>> Hfac = H.factor()>>> G = Integer(16)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(16, [(x + 2*y + z - 4, 1), (2*x + y + z - 4, 1)])>>> p = {x: Integer(1), y: Integer(1), z: Integer(1)}>>> alpha = [Integer(3), Integer(3), Integer(2)]>>> F.asymptotics_multiple(p, alpha, Integer(2), var( r ), verbose=True) #␣
˓→long time
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second-order differential operator actions...
(4/3*sqrt(3)/(sqrt(pi)*sqrt(r)) - 25/216*sqrt(3)/(sqrt(pi)*r^(3/2)),
1,(continues on next page)

190

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

4/3*sqrt(3)/(sqrt(pi)*sqrt(r)) - 25/216*sqrt(3)/(sqrt(pi)*r^(3/2)))>>> H = (Integer(1) - x*(Integer(1) + y))*(Integer(1) -␣˓→z*x**Integer(2)*(Integer(1) + Integer(2)*y))>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(1, [(x*y + x - 1, 1), (2*x^2*y*z + x^2*z - 1, 1)])>>> p = {x: Integer(1)/Integer(2), z: Integer(4)/Integer(3), y: Integer(1)}>>> alpha = [Integer(8), Integer(3), Integer(3)]>>> F.asymptotics_multiple(p, alpha, Integer(2), var( r ),␣
˓→coordinate=Integer(1), verbose=True) # long time
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second-order differential operator actions...
(1/172872*108^r*(24696*sqrt(7)*sqrt(3)/(sqrt(pi)*sqrt(r))- 1231*sqrt(7)*sqrt(3)/(sqrt(pi)*r^(3/2))),108,
1/7*sqrt(7)*sqrt(3)/(sqrt(pi)*sqrt(r))- 1231/172872*sqrt(7)*sqrt(3)/(sqrt(pi)*r^(3/2)))
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - 2*x - y) * (1 - x - 2*y)sage: Hfac = H.factor()sage: G = exp(x + y)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F(e^(x + y), [(x + 2*y - 1, 1), (2*x + y - 1, 1)])
sage: p = {x: 1/3, y: 1/3}
sage: alpha = (var( a ), var( b ))sage: F.asymptotics_multiple(p, alpha, 2, var( r )) # long time
(3*(1/((1/3)^a*(1/3)^b))^r*e^(2/3), 1/((1/3)^a*(1/3)^b), 3*e^(2/3))>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - Integer(2)*x - y) * (Integer(1) - x - Integer(2)*y)>>> Hfac = H.factor()>>> G = exp(x + y)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(e^(x + y), [(x + 2*y - 1, 1), (2*x + y - 1, 1)])>>> p = {x: Integer(1)/Integer(3), y: Integer(1)/Integer(3)}>>> alpha = (var( a ), var( b ))>>> F.asymptotics_multiple(p, alpha, Integer(2), var( r )) # long time
(3*(1/((1/3)^a*(1/3)^b))^r*e^(2/3), 1/((1/3)^a*(1/3)^b), 3*e^(2/3))

asymptotics_smooth(p, alpha, N, asy_var, coordinate=None, numerical=0, verbose=False)
Return the asymptotics in the given direction of a smooth point.
This is the same as asymptotics(), but only in the case of a convenient smooth point.
The formulas used for computing the asymptotic expansions are Theorems 3.2 and 3.3 [RW2008] with theexponent of 𝐻 equal to 1. Theorem 3.2 is a specialization of Theorem 3.4 of [RW2012] with 𝑛 = 1.
4.7. Asymptotics of Multivariate Generating Series

191

Asymptotic Expansions, Release 10.4

INPUT:• p – a dictionary with keys that can be coerced to equal self.denominator_ring.gens()• alpha – a tuple of length d = self.dimension() of positive integers or, if 𝑝 is a smooth point,
possibly of symbolic variables• N – a positive integer• asy_var – (optional; default: None) a symbolic variable; the variable of the asymptotic expansion, if
none is given, var( r ) will be assigned• coordinate – (optional; default: None) an integer in {0, . . . , 𝑑 − 1} indicating a convenient coordinate to base the asymptotic calculations on; if None is assigned, then choose coordinate=d-1• numerical – (optional; default: 0) a natural number; if numerical is greater than 0, then return a numerical approximation of the Maclaurin ray coefficients of self with numerical digits of precision;otherwise return exact values• verbose – (default: False) print the current state of the algorithm
OUTPUT:
The asymptotic expansion.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = 2 - 3*x
sage: Hfac = H.factor()sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F(-1/3, [(x - 2/3, 1)])
sage: alpha = [2]sage: p = {x: 2/3}
sage: asy = F.asymptotics_smooth(p, alpha, 3, asy_var=var( r ))sage: asy
(1/2*(9/4)^r, 9/4, 1/2)>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = Integer(2) - Integer(3)*x>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(-1/3, [(x - 2/3, 1)])>>> alpha = [Integer(2)]>>> p = {x: Integer(2)/Integer(3)}>>> asy = F.asymptotics_smooth(p, alpha, Integer(3), asy_var=var( r ))>>> asy(1/2*(9/4)^r, 9/4, 1/2)

192

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = 1-x-y-x*ysage: Hfac = H.factor()sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: alpha = [3, 2]
sage: p = {y: 1/2*sqrt(13) - 3/2, x: 1/3*sqrt(13) - 2/3}
sage: F.asymptotics_smooth(p, alpha, 2, var( r ), numerical=3, verbose=True)
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second order differential operator actions...
(71.2^r*(0.369/sqrt(r) - 0.018.../r^(3/2)), 71.2, 0.369/sqrt(r) - 0.018.../r^
˓→(3/2))sage: q = 1/2
sage: qq = q.denominator()sage: H = 1 - q*x + q*x*y - x^2*ysage: Hfac = H.factor()sage: G = (1 - q*x)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: alpha = list(qq*vector([2, 1 - q]))sage: alpha[4, 1]
sage: p = {x: 1, y: 1}
sage: F.asymptotics_smooth(p, alpha, 5, var( r ), verbose=True) # not tested␣
˓→(140 seconds)
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second order differential operator actions...
(1/12*sqrt(3)*2^(2/3)*gamma(1/3)/(pi*r^(1/3))- 1/96*sqrt(3)*2^(1/3)*gamma(2/3)/(pi*r^(5/3)),
1,
1/12*sqrt(3)*2^(2/3)*gamma(1/3)/(pi*r^(1/3))- 1/96*sqrt(3)*2^(1/3)*gamma(2/3)/(pi*r^(5/3)))>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = Integer(1)-x-y-x*y>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> alpha = [Integer(3), Integer(2)]>>> p = {y: Integer(1)/Integer(2)*sqrt(Integer(13)) - Integer(3)/Integer(2),␣
˓→x: Integer(1)/Integer(3)*sqrt(Integer(13)) - Integer(2)/Integer(3)}>>> F.asymptotics_smooth(p, alpha, Integer(2), var( r ), numerical=Integer(3),˓→ verbose=True)
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second order differential operator actions...
(71.2^r*(0.369/sqrt(r) - 0.018.../r^(3/2)), 71.2, 0.369/sqrt(r) - 0.018.../r^
˓→(3/2))(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

193

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> q = Integer(1)/Integer(2)>>> qq = q.denominator()>>> H = Integer(1) - q*x + q*x*y - x**Integer(2)*y>>> Hfac = H.factor()>>> G = (Integer(1) - q*x)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> alpha = list(qq*vector([Integer(2), Integer(1) - q]))>>> alpha[4, 1]>>> p = {x: Integer(1), y: Integer(1)}>>> F.asymptotics_smooth(p, alpha, Integer(5), var( r ), verbose=True) # not␣
˓→tested (140 seconds)
Creating auxiliary functions...
Computing derivatives of auxiliary functions...
Computing derivatives of more auxiliary functions...
Computing second order differential operator actions...
(1/12*sqrt(3)*2^(2/3)*gamma(1/3)/(pi*r^(1/3))- 1/96*sqrt(3)*2^(1/3)*gamma(2/3)/(pi*r^(5/3)),
1,
1/12*sqrt(3)*2^(2/3)*gamma(1/3)/(pi*r^(1/3))- 1/96*sqrt(3)*2^(1/3)*gamma(2/3)/(pi*r^(5/3)))

cohomology_decomposition()
Return the cohomology decomposition of self.
Let 𝑝/(𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛 ) be the fraction represented by self and let 𝐾[𝑥1 , . . . , 𝑥𝑑 ] be the polynomial ring inwhich the 𝑞𝑖 lie. Assume that 𝑛 ≤ 𝑑 and that the gradients of the 𝑞𝑖 are linearly independent at all points
in the intersection 𝑉1 ∩ . . . ∩ 𝑉𝑛 of the algebraic varieties 𝑉𝑖 = {𝑥 ∈ 𝐿𝑑 | 𝑞𝑖 (𝑥) = 0}, where 𝐿 is thealgebraic closure of the field 𝐾. Return a FractionWithFactoredDenominatorSum 𝑓 such that thedifferential form 𝑓 𝑑𝑥1 ∧ · · · ∧ 𝑑𝑥𝑑 is de Rham cohomologous to the differential form 𝑝/(𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛 )𝑑𝑥1 ∧· · · ∧ 𝑑𝑥𝑑 and such that the denominator of each summand of 𝑓 contains no repeated irreducible factors.
The algorithm used here comes from the proof of Theorem 17.4 of [AY1983].
OUTPUT:
An instance of FractionWithFactoredDenominatorSum.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 1/(x^2 + x + 1)^3
sage: decomp = FFPD(f).cohomology_decomposition()sage: decomp(0, []) + (2/3, [(x^2 + x + 1, 1)])>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(1)/(x**Integer(2) + x + Integer(1))**Integer(3)>>> decomp = FFPD(f).cohomology_decomposition()>>> decomp(0, []) + (2/3, [(x^2 + x + 1, 1)])

194

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: FFPD(1, [(x, 1), (y, 2)]).cohomology_decomposition()(0, [])>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> FFPD(Integer(1), [(x, Integer(1)), (y, Integer(2))]).cohomology_
˓→decomposition()(0, [])

The following example was fixed in Issue #29465:
sage: p = 1
sage: qs = [(x*y - 1, 1), (x**2 + y**2 - 1, 2)]
sage: f = FFPD(p, qs)
sage: f.cohomology_decomposition()(0, []) + (-4/3*x*y, [(x^2 + y^2 - 1, 1)]) +(1/3, [(x*y - 1, 1), (x^2 + y^2 - 1, 1)])>>> from sage.all import *>>> p = Integer(1)>>> qs = [(x*y - Integer(1), Integer(1)), (x**Integer(2) + y**Integer(2) -␣˓→Integer(1), Integer(2))]>>> f = FFPD(p, qs)>>> f.cohomology_decomposition()(0, []) + (-4/3*x*y, [(x^2 + y^2 - 1, 1)]) +(1/3, [(x*y - 1, 1), (x^2 + y^2 - 1, 1)])

critical_cone(p, coordinate=None)
Return the critical cone of the convenient multiple point p.
INPUT:• p – a dictionary with keys that can be coerced to equal self.denominator_ring.gens() andvalues in a field• coordinate – (optional; default: None) a natural number
OUTPUT:
A list of vectors.
This list of vectors generate the critical cone of p and the cone itself, which is None if the values of p
don’t lie in . Divide logarithmic gradients by their component coordinate entries. If coordinate= None, then search from 𝑑 − 1 down to 0 for the first index j such that for all i we have self.
log_grads()[i][j] != 0 and set coordinate = j.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: G = 1
sage: H = (1 - x*(1 + y)) * (1 - z*x**2*(1 + 2*y))sage: Hfac = H.factor()(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

195

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: p = {x: 1/2, y: 1, z: 4/3}
sage: F.critical_cone(p)([(2, 1, 0), (3, 1, 3/2)], 2-d cone in 3-d lattice N)>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> G = Integer(1)>>> H = (Integer(1) - x*(Integer(1) + y)) * (Integer(1) -␣˓→z*x**Integer(2)*(Integer(1) + Integer(2)*y))>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> p = {x: Integer(1)/Integer(2), y: Integer(1), z: Integer(4)/Integer(3)}>>> F.critical_cone(p)([(2, 1, 0), (3, 1, 3/2)], 2-d cone in 3-d lattice N)

denominator()
Return the denominator of self.
OUTPUT:The denominator (i.e., the product of the factored denominator).
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - x - y - x*y)**2*(1-x)
sage: Hfac = H.factor()sage: G = exp(y)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F.denominator()x^3*y^2 + 2*x^3*y + x^2*y^2 + x^3 - 2*x^2*y - x*y^2 - 3*x^2 - 2*x*y- y^2 + 3*x + 2*y - 1>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - x - y - x*y)**Integer(2)*(Integer(1)-x)>>> Hfac = H.factor()>>> G = exp(y)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F.denominator()x^3*y^2 + 2*x^3*y + x^2*y^2 + x^3 - 2*x^2*y - x*y^2 - 3*x^2 - 2*x*y- y^2 + 3*x + 2*y - 1

denominator_factored()196

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Return the factorization in self.denominator_ring of the denominator of self but without the unit
part.
OUTPUT:
The factored denominator as a list of tuple (f, m), where 𝑓 is a factor and 𝑚 its multiplicity.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - x - y - x*y)**2*(1-x)
sage: Hfac = H.factor()sage: G = exp(y)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F.denominator_factored()[(x - 1, 1), (x*y + x + y - 1, 2)]>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - x - y - x*y)**Integer(2)*(Integer(1)-x)>>> Hfac = H.factor()>>> G = exp(y)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F.denominator_factored()[(x - 1, 1), (x*y + x + y - 1, 2)]property denominator_ring
Return the ring of the denominator.
OUTPUT:
A ring.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - x - y - x*y)**2*(1-x)
sage: Hfac = H.factor()sage: G = exp(y)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field
sage: F = FFPD(G/H)
sage: F(e^y, [(x - 1, 1), (x*y + x + y - 1, 2)])sage: F.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field

4.7. Asymptotics of Multivariate Generating Series

197

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - x - y - x*y)**Integer(2)*(Integer(1)-x)>>> Hfac = H.factor()>>> G = exp(y)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field>>> F = FFPD(G/H)>>> F(e^y, [(x - 1, 1), (x*y + x + y - 1, 2)])>>> F.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field

dimension()
Return the number of indeterminates of self.denominator_ring.
OUTPUT:
An integer.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - x - y - x*y)**2*(1-x)
sage: Hfac = H.factor()sage: G = exp(y)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F.dimension()2>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - x - y - x*y)**Integer(2)*(Integer(1)-x)>>> Hfac = H.factor()>>> G = exp(y)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F.dimension()2

grads(p)Return a list of the gradients of the polynomials [qdenominator_factored()] evaluated at p.

for

(q,

e)

in

self.

INPUT:• p – (optional; default:
denominator_ringNone) a dictionary whose keys are the generators of self.

OUTPUT:
198

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

A list.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: p = exp(x)sage: df = [(x^3 + 3*y^2, 5), (x*y, 2), (y, 1)]
sage: f = FFPD(p, df)
sage: f(e^x, [(y, 1), (x*y, 2), (x^3 + 3*y^2, 5)])sage: R.gens()(x, y)
sage: p = Nonesage: f.grads(p)[(0, 1), (y, x), (3*x^2, 6*y)]sage: p = {x: sqrt(2), y: var( a )}sage: f.grads(p)[(0, 1), (a, sqrt(2)), (6, 6*a)]>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> p = exp(x)>>> df = [(x**Integer(3) + Integer(3)*y**Integer(2), Integer(5)), (x*y,␣
˓→Integer(2)), (y, Integer(1))]>>> f = FFPD(p, df)>>> f(e^x, [(y, 1), (x*y, 2), (x^3 + 3*y^2, 5)])>>> R.gens()(x, y)>>> p = None>>> f.grads(p)[(0, 1), (y, x), (3*x^2, 6*y)]>>> p = {x: sqrt(Integer(2)), y: var( a )}>>> f.grads(p)[(0, 1), (a, sqrt(2)), (6, 6*a)]is_convenient_multiple_point(p)Tests if p is a convenient multiple point of self.
In case p is a convenient multiple point, verdict = True and comment is a string stating which variables
it’s convenient to use. In case p is not, verdict = False and comment is a string explaining why p
fails to be a convenient multiple point.
See [RW2012] for more details.
INPUT:• p – a dictionary with keys that can be coerced to equal self.denominator_ring.gens()
OUTPUT:
A pair (verdict, comment).

4.7. Asymptotics of Multivariate Generating Series

199

Asymptotic Expansions, Release 10.4

EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = (1 - x*(1 + y)) * (1 - z*x**2*(1 + 2*y))sage: df = H.factor()sage: G = 1 / df.unit()
sage: F = FFPD(G, df)
sage: p1 = {x: 1/2, y: 1, z: 4/3}
sage: p2 = {x: 1, y: 2, z: 1/2}
sage: F.is_convenient_multiple_point(p1)(True, convenient in variables [x, y] )sage: F.is_convenient_multiple_point(p2)(False, not a singular point )>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = (Integer(1) - x*(Integer(1) + y)) * (Integer(1) -␣˓→z*x**Integer(2)*(Integer(1) + Integer(2)*y))>>> df = H.factor()>>> G = Integer(1) / df.unit()>>> F = FFPD(G, df)>>> p1 = {x: Integer(1)/Integer(2), y: Integer(1), z: Integer(4)/Integer(3)}>>> p2 = {x: Integer(1), y: Integer(2), z: Integer(1)/Integer(2)}>>> F.is_convenient_multiple_point(p1)(True, convenient in variables [x, y] )>>> F.is_convenient_multiple_point(p2)(False, not a singular point )leinartas_decomposition()
Return a Leinartas decomposition of self.
Let 𝑓 = 𝑝/𝑞 where 𝑞 lies in a 𝑑 -variate polynomial ring 𝐾[𝑋] for some field 𝐾. Let 𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛 be the uniquefactorization of 𝑞 in 𝐾[𝑋] into irreducible factors and let 𝑉𝑖 be the algebraic variety {𝑥 ∈ 𝐿𝑑 | 𝑞𝑖 (𝑥) = 0}of 𝑞𝑖 over the algebraic closure 𝐿 of 𝐾. By [Rai2012], 𝑓 can be written as
∑︁
𝑝𝐴
(*)
,
∏︀
𝑏𝑖
𝑖∈𝐴 𝑞𝑖𝐴
where the 𝑏𝑖 are positive integers, each 𝑝𝐴 is a product of 𝑝 and an element of 𝐾[𝑋], and the sum is takenover all subsets 𝐴 ⊆ {1, . . . , 𝑚} such that
1. |𝐴| ≤ 𝑑,⋂︀
2. 𝑖∈𝐴 𝑇𝑖 ̸= ∅, and3. {𝑞𝑖 | 𝑖 ∈ 𝐴} is algebraically independent.
In particular, any rational expression in 𝑑 variables can be represented as a sum of rational expressions whose
denominators each contain at most 𝑑 distinct irreducible factors.
We call (*) a Leinartas decomposition of 𝑓 . Leinartas decompositions are not unique.
The algorithm used comes from [Rai2012].
200

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

OUTPUT:
An instance of FractionWithFactoredDenominatorSum.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = (x^2 + 1)/((x + 2)*(x - 1)*(x^2 + x + 1))
sage: decomp = FFPD(f).leinartas_decomposition()sage: decomp(0, []) + (2/9, [(x - 1, 1)]) +(-5/9, [(x + 2, 1)]) + (1/3*x, [(x^2 + x + 1, 1)])
sage: decomp.sum().quotient() == f
True>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = (x**Integer(2) + Integer(1))/((x + Integer(2))*(x -␣˓→Integer(1))*(x**Integer(2) + x + Integer(1)))>>> decomp = FFPD(f).leinartas_decomposition()>>> decomp(0, []) + (2/9, [(x - 1, 1)]) +(-5/9, [(x + 2, 1)]) + (1/3*x, [(x^2 + x + 1, 1)])>>> decomp.sum().quotient() == f
True
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 1/x + 1/y + 1/(x*y + 1)
sage: decomp = FFPD(f).leinartas_decomposition()sage: decomp(0, []) + (1, [(x*y + 1, 1)]) + (x + y, [(y, 1), (x, 1)])
sage: decomp.sum().quotient() == f
True
sage: def check_decomp(r):....:L = r.nullstellensatz_certificate()....:
J = r.algebraic_dependence_certificate()....:
return L is None and (J is None or J == J.ring().ideal())
sage: all(check_decomp(r) for r in decomp)True>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(1)/x + Integer(1)/y + Integer(1)/(x*y + Integer(1))>>> decomp = FFPD(f).leinartas_decomposition()>>> decomp(0, []) + (1, [(x*y + 1, 1)]) + (x + y, [(y, 1), (x, 1)])>>> decomp.sum().quotient() == f
True>>> def check_decomp(r):...
L = r.nullstellensatz_certificate()(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

201

Asymptotic Expansions, Release 10.4

(continued from previous page)...
J = r.algebraic_dependence_certificate()...
return L is None and (J is None or J == J.ring().ideal())>>> all(check_decomp(r) for r in decomp)True
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: f = sin(x)/x + 1/y + 1/(x*y + 1)
sage: G = f.numerator()sage: H = R(f.denominator())
sage: ff = FFPD(G, H.factor())
sage: decomp = ff.leinartas_decomposition()sage: decomp # random - non canonical depends on singular version(0, []) +(-(x*y^2*sin(x) + x^2*y + x*y + y*sin(x) + x)*y, [(y, 1)]) +((x*y^2*sin(x) + x^2*y + x*y + y*sin(x) + x)*x*y, [(x*y + 1, 1)]) +(x*y^2*sin(x) + x^2*y + x*y + y*sin(x) + x, [(y, 1), (x, 1)])
sage: bool(decomp.sum().quotient() == f)
True
sage: all(check_decomp(r) for r in decomp)True>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> f = sin(x)/x + Integer(1)/y + Integer(1)/(x*y + Integer(1))>>> G = f.numerator()>>> H = R(f.denominator())>>> ff = FFPD(G, H.factor())>>> decomp = ff.leinartas_decomposition()>>> decomp # random - non canonical depends on singular version(0, []) +(-(x*y^2*sin(x) + x^2*y + x*y + y*sin(x) + x)*y, [(y, 1)]) +((x*y^2*sin(x) + x^2*y + x*y + y*sin(x) + x)*x*y, [(x*y + 1, 1)]) +(x*y^2*sin(x) + x^2*y + x*y + y*sin(x) + x, [(y, 1), (x, 1)])>>> bool(decomp.sum().quotient() == f)
True>>> all(check_decomp(r) for r in decomp)True
sage: R.<x,y,z>= PolynomialRing(GF(2, a ))sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 1/(x * y * z * (x*y + z))
sage: decomp = FFPD(f).leinartas_decomposition()sage: decomp(0, []) + (1, [(z, 2), (x*y + z, 1)]) +(1, [(z, 2), (y, 1), (x, 1)])
sage: decomp.sum().quotient() == f
True>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(2), a ), names=( x ,˓→) = R._first_ngens(3)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(1)/(x * y * z * (x*y + z))y ,z ,)); (x, y, z,(continues on next page)

202

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> decomp = FFPD(f).leinartas_decomposition()>>> decomp(0, []) + (1, [(z, 2), (x*y + z, 1)]) +(1, [(z, 2), (y, 1), (x, 1)])>>> decomp.sum().quotient() == fTrue

log_grads(p)Return a list of the logarithmic gradients of the polynomials [qdenominator_factored()] evaluated at p.

for

(q,

e)

in

self.

The logarithmic gradient of a function 𝑓 at point 𝑝 is the vector (𝑥1 𝜕1 𝑓 (𝑥), . . . , 𝑥𝑑 𝜕𝑑 𝑓 (𝑥)) evaluated at 𝑝.
INPUT:• p – (optional; default:
denominator_ringNone) a dictionary whose keys are the generators of self.

OUTPUT:
A list.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: p = exp(x)sage: df = [(x^3 + 3*y^2, 5), (x*y, 2), (y, 1)]
sage: f = FFPD(p, df)
sage: f(e^x, [(y, 1), (x*y, 2), (x^3 + 3*y^2, 5)])sage: R.gens()(x, y)
sage: p = Nonesage: f.log_grads(p)[(0, y), (x*y, x*y), (3*x^3, 6*y^2)]
sage: p = {x: sqrt(2), y: var( a )}sage: f.log_grads(p)[(0, a), (sqrt(2)*a, sqrt(2)*a), (6*sqrt(2), 6*a^2)]>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> p = exp(x)>>> df = [(x**Integer(3) + Integer(3)*y**Integer(2), Integer(5)), (x*y,␣
˓→Integer(2)), (y, Integer(1))]>>> f = FFPD(p, df)>>> f(e^x, [(y, 1), (x*y, 2), (x^3 + 3*y^2, 5)])>>> R.gens()(x, y)>>> p = None>>> f.log_grads(p)(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

203

Asymptotic Expansions, Release 10.4

(continued from previous page)[(0, y), (x*y, x*y), (3*x^3, 6*y^2)]>>> p = {x: sqrt(Integer(2)), y: var( a )}>>> f.log_grads(p)[(0, a), (sqrt(2)*a, sqrt(2)*a), (6*sqrt(2), 6*a^2)]

maclaurin_coefficients(multi_indices, numerical=0)
Return the Maclaurin coefficients of self with given multi_indices.
INPUT:• multi_indices – a list of tuples of positive integers, where each tuple has length self.
dimension()• numerical – (optional; default: 0) a natural number; if positive, return numerical approximations ofcoefficients with numerical digits of accuracy
OUTPUT:
A dictionary whose value of the key nu are the Maclaurin coefficient of index nu of self.
Note: Uses iterated univariate Maclaurin expansions. Slow.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = 2 - 3*x
sage: Hfac = H.factor()sage: G = 1 / Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F(-1/3, [(x - 2/3, 1)])
sage: F.maclaurin_coefficients([(2*k,) for k in range(6)]){(0,): 1/2,
(2,): 9/8,
(4,): 81/32,(6,): 729/128,(8,): 6561/512,(10,): 59049/2048}>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = Integer(2) - Integer(3)*x>>> Hfac = H.factor()>>> G = Integer(1) / Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(-1/3, [(x - 2/3, 1)])>>> F.maclaurin_coefficients([(Integer(2)*k,) for k in range(Integer(6))]){(0,): 1/2,
(continues on next page)

204

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)(2,): 9/8,
(4,): 81/32,(6,): 729/128,(8,): 6561/512,(10,): 59049/2048}
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = (4 - 2*x - y - z) * (4 - x - 2*y - z)sage: Hfac = H.factor()sage: G = 16 / Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: alpha = vector([3, 3, 2])
sage: interval = [1, 2, 4]
sage: S = [r*alpha for r in interval]
sage: F.maclaurin_coefficients(S, numerical=10) # long time{(3, 3, 2): 0.7849731445,(6, 6, 4): 0.7005249476,(12, 12, 8): 0.5847732654}>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = (Integer(4) - Integer(2)*x - y - z) * (Integer(4) - x - Integer(2)*y ˓→ z)>>> Hfac = H.factor()>>> G = Integer(16) / Hfac.unit()>>> F = FFPD(G, Hfac)>>> alpha = vector([Integer(3), Integer(3), Integer(2)])>>> interval = [Integer(1), Integer(2), Integer(4)]>>> S = [r*alpha for r in interval]>>> F.maclaurin_coefficients(S, numerical=Integer(10)) # long time{(3, 3, 2): 0.7849731445,(6, 6, 4): 0.7005249476,(12, 12, 8): 0.5847732654}

nullstellensatz_certificate()
Return a Nullstellensatz certificate of self if it exists.
Let [(𝑞1 , 𝑒1 ), . . . , (𝑞𝑛 , 𝑒𝑛 )] be the denominator factorization of self. The Nullstellensatz certificate is a listof polynomials ℎ1 , . . . , ℎ𝑚 in self.denominator_ring that satisfies ℎ1 𝑞1 + · · · + ℎ𝑚 𝑞𝑛 = 1 if itexists.
Note: Only works for multivariate base rings.
OUTPUT:
A list of polynomials or None if no Nullstellensatz certificate exists.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

205

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: G = sin(x)sage: H = x^2 * (x*y + 1)
sage: f = FFPD(G, H.factor())
sage: L = f.nullstellensatz_certificate()sage: L[y^2, -x*y + 1]
sage: df = f.denominator_factored()sage: sum(L[i]*df[i][0]**df[i][1] for i in range(len(df))) == 1
True>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> G = sin(x)>>> H = x**Integer(2) * (x*y + Integer(1))>>> f = FFPD(G, H.factor())>>> L = f.nullstellensatz_certificate()>>> L[y^2, -x*y + 1]>>> df = f.denominator_factored()>>> sum(L[i]*df[i][Integer(0)]**df[i][Integer(1)] for i in range(len(df))) ==␣
˓→Integer(1)True
sage: f = 1/(x*y)
sage: L = FFPD(f).nullstellensatz_certificate()sage: L is None
True>>> from sage.all import *>>> f = Integer(1)/(x*y)>>> L = FFPD(f).nullstellensatz_certificate()>>> L is None
True

nullstellensatz_decomposition()
Return a Nullstellensatz decomposition of self.
Let 𝑓 = 𝑝/𝑞 where 𝑞 lies in a 𝑑 -variate polynomial ring 𝐾[𝑋] for some field 𝐾 and 𝑑 ≥ 1. Let 𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛
be the unique factorization of 𝑞 in 𝐾[𝑋] into irreducible factors and let 𝑉𝑖 be the algebraic variety {𝑥 ∈ 𝐿𝑑 |𝑞𝑖 (𝑥) = 0} of 𝑞𝑖 over the algebraic closure 𝐿 of 𝐾. By [Rai2012], 𝑓 can be written as∑︁𝑝∏︀ 𝐴 𝑒𝑖 ,(*)
𝑖∈𝐴 𝑞𝑖𝐴

where the⋂︀
𝑝𝐴 are products of 𝑝 and elements in 𝐾[𝑋] and the sum is taken over all subsets 𝐴 ⊆ {1, . . . , 𝑚}such that 𝑖∈𝐴 𝑇𝑖 ̸= ∅.
We call (*) a Nullstellensatz decomposition of 𝑓 . Nullstellensatz decompositions are not unique.
The algorithm used comes from [Rai2012].
Note: Recursive. Only works for multivariate self.

206

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

OUTPUT:
An instance of FractionWithFactoredDenominatorSum.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import *sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 1/(x*(x*y + 1))
sage: decomp = FFPD(f).nullstellensatz_decomposition()sage: decomp(0, []) + (1, [(x, 1)]) + (-y, [(x*y + 1, 1)])
sage: decomp.sum().quotient() == f
True
sage: [r.nullstellensatz_certificate() is None for r in decomp][True, True, True]>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(1)/(x*(x*y + Integer(1)))>>> decomp = FFPD(f).nullstellensatz_decomposition()>>> decomp(0, []) + (1, [(x, 1)]) + (-y, [(x*y + 1, 1)])>>> decomp.sum().quotient() == fTrue>>> [r.nullstellensatz_certificate() is None for r in decomp][True, True, True]
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: G = sin(y)sage: H = x*(x*y + 1)
sage: f = FFPD(G, H.factor())
sage: decomp = f.nullstellensatz_decomposition()sage: decomp(0, []) + (sin(y), [(x, 1)]) + (-y*sin(y), [(x*y + 1, 1)])
sage: bool(decomp.sum().quotient() == G/H)
True
sage: [r.nullstellensatz_certificate() is None for r in decomp][True, True, True]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> G = sin(y)>>> H = x*(x*y + Integer(1))>>> f = FFPD(G, H.factor())>>> decomp = f.nullstellensatz_decomposition()>>> decomp(0, []) + (sin(y), [(x, 1)]) + (-y*sin(y), [(x*y + 1, 1)])>>> bool(decomp.sum().quotient() == G/H)
True>>> [r.nullstellensatz_certificate() is None for r in decomp](continues on next page)

4.7. Asymptotics of Multivariate Generating Series

207

Asymptotic Expansions, Release 10.4

(continued from previous page)[True, True, True]

numerator()
Return the numerator of self.
OUTPUT:
The numerator.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - x - y - x*y)**2*(1-x)
sage: Hfac = H.factor()sage: G = exp(y)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F.numerator()-e^y>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - x - y - x*y)**Integer(2)*(Integer(1)-x)>>> Hfac = H.factor()>>> G = exp(y)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F.numerator()-e^yproperty numerator_ring
Return the ring of the numerator.
OUTPUT:
A ring.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - x - y - x*y)**2*(1-x)
sage: Hfac = H.factor()sage: G = exp(y)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F.numerator_ring
Symbolic Ringsage: F = FFPD(G/H)
sage: F(e^y, [(x - 1, 1), (x*y + x + y - 1, 2)])sage: F.numerator_ring
Symbolic Ring

208

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - x - y - x*y)**Integer(2)*(Integer(1)-x)>>> Hfac = H.factor()>>> G = exp(y)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F.numerator_ring
Symbolic Ring>>> F = FFPD(G/H)>>> F(e^y, [(x - 1, 1), (x*y + x + y - 1, 2)])>>> F.numerator_ring
Symbolic Ring

quotient()
Convert self into a quotient.
OUTPUT:An element.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: H = (1 - x - y - x*y)**2*(1-x)
sage: Hfac = H.factor()sage: G = exp(y)/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: F(-e^y, [(x - 1, 1), (x*y + x + y - 1, 2)])sage: F.quotient()-e^y/(x^3*y^2 + 2*x^3*y + x^2*y^2 + x^3 - 2*x^2*y - x*y^2 - 3*x^2 2*x*y - y^2 + 3*x + 2*y - 1)>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> H = (Integer(1) - x - y - x*y)**Integer(2)*(Integer(1)-x)>>> Hfac = H.factor()>>> G = exp(y)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> F(-e^y, [(x - 1, 1), (x*y + x + y - 1, 2)])>>> F.quotient()-e^y/(x^3*y^2 + 2*x^3*y + x^2*y^2 + x^3 - 2*x^2*y - x*y^2 - 3*x^2 2*x*y - y^2 + 3*x + 2*y - 1)

relative_error(approx, alpha, interval, exp_scale=1, digits=10)
Return the relative error between the values of the Maclaurin coefficients of self with multi-indices ralpha for r in interval and the values of the functions (of the variable r) in approx.
4.7. Asymptotics of Multivariate Generating Series

209

Asymptotic Expansions, Release 10.4

INPUT:• approx – an individual or list of symbolic expressions in one variable• alpha – a list of positive integers of length self.denominator_ring.ngens()• interval – a list of positive integers• exp_scale – (optional; default: 1) a number
OUTPUT:
A list of tuples with properties described below.
This outputs a list whose entries are a tuple (r*alpha, a_r, b_r, err_r) for r in interval.
Here r*alpha is a tuple; a_r is the r*alpha (multi-index) coefficient of the Maclaurin series for self
divided by exp_scale**r; b_r is a list of the values of the functions in approx evaluated at r anddivided by exp_scale**m; err_r is the list of relative errors (a_r - f)/a_r for f in b_r. All
outputs are decimal approximations.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = 1 - x - y - x*y
sage: Hfac = H.factor()sage: G = 1 / Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: alpha = [1, 1]
sage: r = var( r )sage: a1 = (0.573/sqrt(r))*5.83^rsage: a2 = (0.573/sqrt(r) - 0.0674/r^(3/2))*5.83^rsage: es = 5.83
sage: F.relative_error([a1, a2], alpha, [1, 2, 4, 8], es) # long time[((1, 1), 0.5145797599,[0.5730000000, 0.5056000000], [-0.1135300000, 0.01745066667]),((2, 2), 0.3824778089,[0.4051721856, 0.3813426871], [-0.05933514614, 0.002967810973]),((4, 4), 0.2778630595,[0.2865000000, 0.2780750000], [-0.03108344267, -0.0007627515584]),((8, 8), 0.1991088276,[0.2025860928, 0.1996074055], [-0.01746414394, -0.002504047242])]>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = Integer(1) - x - y - x*y>>> Hfac = H.factor()>>> G = Integer(1) / Hfac.unit()>>> F = FFPD(G, Hfac)>>> alpha = [Integer(1), Integer(1)]>>> r = var( r )>>> a1 = (RealNumber( 0.573 )/sqrt(r))*RealNumber( 5.83 )**r>>> a2 = (RealNumber( 0.573 )/sqrt(r) - RealNumber( 0.0674 )/r**(Integer(3)/˓→Integer(2)))*RealNumber( 5.83 )**r>>> es = RealNumber( 5.83 )(continues on next page)

210

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> F.relative_error([a1, a2], alpha, [Integer(1), Integer(2), Integer(4),␣
˓→Integer(8)], es) # long time[((1, 1), 0.5145797599,[0.5730000000, 0.5056000000], [-0.1135300000, 0.01745066667]),((2, 2), 0.3824778089,[0.4051721856, 0.3813426871], [-0.05933514614, 0.002967810973]),((4, 4), 0.2778630595,[0.2865000000, 0.2780750000], [-0.03108344267, -0.0007627515584]),((8, 8), 0.1991088276,[0.2025860928, 0.1996074055], [-0.01746414394, -0.002504047242])]

singular_ideal()
Return the singular ideal of self.
Let 𝑅 be the ring of self and 𝐻 its denominator. Let 𝐻𝑟𝑒𝑑 be the reduction (square-free part) of 𝐻. Returnthe ideal in 𝑅 generated by 𝐻𝑟𝑒𝑑 and its partial derivatives. If the coefficient field of 𝑅 is algebraically closed,
then the output is the ideal of the singular locus (which is a variety) of the variety of 𝐻.
OUTPUT:
An ideal.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = (1 - x*(1 + y))^3 * (1 - z*x**2*(1 + 2*y))sage: df = H.factor()sage: G = 1 / df.unit()
sage: F = FFPD(G, df)
sage: F.singular_ideal()
Ideal (x*y + x - 1, y^2 - 2*y*z + 2*y - z + 1, x*z + y - 2*z + 1) of
Multivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = (Integer(1) - x*(Integer(1) + y))**Integer(3) * (Integer(1) -␣˓→z*x**Integer(2)*(Integer(1) + Integer(2)*y))>>> df = H.factor()>>> G = Integer(1) / df.unit()>>> F = FFPD(G, df)>>> F.singular_ideal()
Ideal (x*y + x - 1, y^2 - 2*y*z + 2*y - z + 1, x*z + y - 2*z + 1) of
Multivariate Polynomial Ring in x, y, z over Rational Fieldsmooth_critical_ideal(alpha)
Return the smooth critical ideal of self.
Let 𝑅 be the ring of self and 𝐻 its denominator. Return the ideal in 𝑅 of smooth critical points of thevariety of 𝐻 for the direction alpha. If the variety 𝑉 of 𝐻 has no smooth points, then return the ideal in
𝑅 of 𝑉 .

4.7. Asymptotics of Multivariate Generating Series

211

Asymptotic Expansions, Release 10.4

See [RW2012] for more details.
INPUT:• alpha – a tuple of positive integers and/or symbolic entries of length self.denominator_ring.
ngens()OUTPUT:
An ideal.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: H = (1 - x - y - x*y)^2
sage: Hfac = H.factor()sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: alpha = var( a1, a2 )sage: F.smooth_critical_ideal(alpha)
Ideal (y^2 + (2*a1)/a2*y - 1, x + (-a2)/a1*y + (-a1 + a2)/a1) of
Multivariate Polynomial Ring in x, y over Fraction Field ofMultivariate Polynomial Ring in a1, a2 over Rational Field
sage: H = (1-x-y-x*y)^2
sage: Hfac = H.factor()sage: G = 1/Hfac.unit()
sage: F = FFPD(G, Hfac)
sage: alpha = [7/3, var( a )]sage: F.smooth_critical_ideal(alpha)
Ideal (y^2 + 14/(3*a)*y - 1, x + (-3*a)/7*y + (3*a - 7)/7) of Multivariate␣˓→Polynomial Ring in x, y over Fraction Field of Univariate Polynomial Ring␣˓→in a over Rational Field>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> H = (Integer(1) - x - y - x*y)**Integer(2)>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> alpha = var( a1, a2 )>>> F.smooth_critical_ideal(alpha)
Ideal (y^2 + (2*a1)/a2*y - 1, x + (-a2)/a1*y + (-a1 + a2)/a1) of
Multivariate Polynomial Ring in x, y over Fraction Field ofMultivariate Polynomial Ring in a1, a2 over Rational Field>>> H = (Integer(1)-x-y-x*y)**Integer(2)>>> Hfac = H.factor()>>> G = Integer(1)/Hfac.unit()>>> F = FFPD(G, Hfac)>>> alpha = [Integer(7)/Integer(3), var( a )]>>> F.smooth_critical_ideal(alpha)
Ideal (y^2 + 14/(3*a)*y - 1, x + (-3*a)/7*y + (3*a - 7)/7) of Multivariate␣(continues on next page)212

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

Polynomial Ring in x, y over Fraction Field of Univariate Polynomial Ring␣˓→in a over Rational Field˓→

univariate_decomposition()
Return the usual univariate partial fraction decomposition of self.
Assume that the numerator of self lies in the same univariate factorial polynomial ring as the factors of thedenominator.
Let 𝑓 = 𝑝/𝑞 be a rational expression where 𝑝 and 𝑞 lie in a univariate factorial polynomial ring 𝑅. Let
𝑞1𝑒1 · · · 𝑞𝑛𝑒𝑛 be the unique factorization of 𝑞 in 𝑅 into irreducible factors. Then 𝑓 can be written uniquely as:(*) 𝑝0 +

𝑚
∑︁
𝑝𝑖
𝑖=1

𝑞𝑖𝑒𝑖

,

for some 𝑝𝑗 ∈ 𝑅. We call (*) the usual partial fraction decomposition of 𝑓 .
Note: This partial fraction decomposition can be computed using partial_fraction() or partial_fraction_decomposition() as well. However, here we use the already obtained/cached factorization of the denominator. This gives a speed up for non-small instances.
OUTPUT:
An instance of FractionWithFactoredDenominatorSum.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing

One variable:
sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 5*x^3 + 1/x + 1/(x-1) + 1/(3*x^2 + 1)
sage: f(5*x^7 - 5*x^6 + 5/3*x^5 - 5/3*x^4 + 2*x^3 - 2/3*x^2 + 1/3*x - 1/3)/(x^4 - x^
˓→3 + 1/3*x^2 - 1/3*x)
sage: decomp = FFPD(f).univariate_decomposition()sage: decomp(5*x^3, []) +(1, [(x - 1, 1)]) +(1, [(x, 1)]) +(1/3, [(x^2 + 1/3, 1)])
sage: decomp.sum().quotient() == f
True>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(5)*x**Integer(3) + Integer(1)/x + Integer(1)/(x-Integer(1)) +␣(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

213

Asymptotic Expansions, Release 10.4

(continued from previous page)

Integer(1)/(Integer(3)*x**Integer(2) + Integer(1))>>> f(5*x^7 - 5*x^6 + 5/3*x^5 - 5/3*x^4 + 2*x^3 - 2/3*x^2 + 1/3*x - 1/3)/(x^4 - x^
˓→3 + 1/3*x^2 - 1/3*x)>>> decomp = FFPD(f).univariate_decomposition()>>> decomp(5*x^3, []) +(1, [(x - 1, 1)]) +(1, [(x, 1)]) +(1/3, [(x^2 + 1/3, 1)])>>> decomp.sum().quotient() == fTrue˓→One variable with numerator in symbolic ring:sage: R.<x> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: f = 5*x^3 + 1/x + 1/(x-1) + exp(x)/(3*x^2 + 1)
sage: f(5*x^5 - 5*x^4 + 2*x - 1)/(x^2 - x) + e^x/(3*x^2 + 1)
sage: decomp = FFPD(f).univariate_decomposition()sage: decomp(0, []) +(15/4*x^7 - 15/4*x^6 + 5/4*x^5 - 5/4*x^4 + 3/2*x^3 + 1/4*x^2*e^x 3/4*x^2 - 1/4*x*e^x + 1/2*x - 1/4, [(x - 1, 1)]) +(-15*x^7 + 15*x^6 - 5*x^5 + 5*x^4 - 6*x^3 x^2*e^x + 3*x^2 + x*e^x - 2*x + 1, [(x, 1)]) +(1/4*(15*x^7 - 15*x^6 + 5*x^5 - 5*x^4 + 6*x^3 + x^2*e^x 3*x^2 - x*e^x + 2*x - 1)*(3*x - 1), [(x^2 + 1/3, 1)])>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> f = Integer(5)*x**Integer(3) + Integer(1)/x + Integer(1)/(x-Integer(1)) +␣˓→exp(x)/(Integer(3)*x**Integer(2) + Integer(1))>>> f(5*x^5 - 5*x^4 + 2*x - 1)/(x^2 - x) + e^x/(3*x^2 + 1)>>> decomp = FFPD(f).univariate_decomposition()>>> decomp(0, []) +(15/4*x^7 - 15/4*x^6 + 5/4*x^5 - 5/4*x^4 + 3/2*x^3 + 1/4*x^2*e^x 3/4*x^2 - 1/4*x*e^x + 1/2*x - 1/4, [(x - 1, 1)]) +(-15*x^7 + 15*x^6 - 5*x^5 + 5*x^4 - 6*x^3 x^2*e^x + 3*x^2 + x*e^x - 2*x + 1, [(x, 1)]) +(1/4*(15*x^7 - 15*x^6 + 5*x^5 - 5*x^4 + 6*x^3 + x^2*e^x 3*x^2 - x*e^x + 2*x - 1)*(3*x - 1), [(x^2 + 1/3, 1)])One variable over a finite field:
sage: R.<x> = PolynomialRing(GF(2))
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 5*x^3 + 1/x + 1/(x-1) + 1/(3*x^2 + 1)
sage: f(x^6 + x^4 + 1)/(x^3 + x)
sage: decomp = FFPD(f).univariate_decomposition()sage: decomp(continues on next page)

214

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)(x^3, []) + (1, [(x, 1)]) + (x, [(x + 1, 2)])sage: decomp.sum().quotient() == f
True>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(2)), names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(5)*x**Integer(3) + Integer(1)/x + Integer(1)/(x-Integer(1)) +␣˓→Integer(1)/(Integer(3)*x**Integer(2) + Integer(1))>>> f(x^6 + x^4 + 1)/(x^3 + x)>>> decomp = FFPD(f).univariate_decomposition()>>> decomp(x^3, []) + (1, [(x, 1)]) + (x, [(x + 1, 2)])>>> decomp.sum().quotient() == fTrue

One variable over an inexact field:
sage: R.<x> = PolynomialRing(CC)sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = 5*x^3 + 1/x + 1/(x-1) + 1/(3*x^2 + 1)
sage: f(5.00000000000000*x^7 - 5.00000000000000*x^6 + 1.66666666666667*x^5 - 1.
˓→66666666666667*x^4 + 2.00000000000000*x^3 - 0.666666666666667*x^2 + 0.
˓→333333333333333*x - 0.333333333333333)/(x^4 - x^3 + 0.333333333333333*x^2 -␣
˓→0.333333333333333*x)
sage: decomp = FFPD(f).univariate_decomposition()sage: decomp(5.00000000000000*x^3, []) +(1.00000000000000, [(x - 1.00000000000000, 1)]) +(-0.288675134594813*I, [(x - 0.577350269189626*I, 1)]) +(1.00000000000000, [(x, 1)]) +(0.288675134594813*I, [(x + 0.577350269189626*I, 1)])
sage: decomp.sum().quotient() == f # Rounding error coming
False>>> from sage.all import *>>> R = PolynomialRing(CC, names=( x ,)); (x,) = R._first_ngens(1)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = Integer(5)*x**Integer(3) + Integer(1)/x + Integer(1)/(x-Integer(1)) +␣˓→Integer(1)/(Integer(3)*x**Integer(2) + Integer(1))>>> f(5.00000000000000*x^7 - 5.00000000000000*x^6 + 1.66666666666667*x^5 - 1.
˓→66666666666667*x^4 + 2.00000000000000*x^3 - 0.666666666666667*x^2 + 0.
˓→333333333333333*x - 0.333333333333333)/(x^4 - x^3 + 0.333333333333333*x^2 -␣
˓→0.333333333333333*x)>>> decomp = FFPD(f).univariate_decomposition()>>> decomp(5.00000000000000*x^3, []) +(1.00000000000000, [(x - 1.00000000000000, 1)]) +(-0.288675134594813*I, [(x - 0.577350269189626*I, 1)]) +(1.00000000000000, [(x, 1)]) +(0.288675134594813*I, [(x + 0.577350269189626*I, 1)])>>> decomp.sum().quotient() == f # Rounding error coming
False

4.7. Asymptotics of Multivariate Generating Series

215

Asymptotic Expansions, Release 10.4

AUTHORS:• Robert Bradshaw (2007-05-31)• Alexander Raichev (2012-06-25)• Daniel Krenn (2014-12-01)

class sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFacto

Bases: UniqueRepresentation, Parent
This is the ring of fractions with factored denominator.
INPUT:• denominator_ring – the base ring (a polynomial ring)• numerator_ring – (optional) the numerator ring; the default is the denominator_ring• category – (default: Rings) the category
See also:
FractionWithFactoredDenominator, asymptotics_multivariate_generating_functions
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: df = [x, 1], [y, 1], [x*y+1, 1]
sage: f = FFPD(x, df) # indirect doctest
sage: f(1, [(y, 1), (x*y + 1, 1)])>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> df = [x, Integer(1)], [y, Integer(1)], [x*y+Integer(1), Integer(1)]>>> f = FFPD(x, df) # indirect doctest>>> f(1, [(y, 1), (x*y + 1, 1)])AUTHORS:• Daniel Krenn (2014-12-01)

216

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

Element
alias of FractionWithFactoredDenominator
base_ring()
Returns the base ring.
OUTPUT:
A ring.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing
sage: P.<X, Y> = ZZ[]
sage: F = FractionWithFactoredDenominatorRing(P); F
Ring of fractions with factored denominator
over Multivariate Polynomial Ring in X, Y over Integer Ringsage: F.base_ring()
Integer Ringsage: F.base()
Multivariate Polynomial Ring in X, Y over Integer Ring>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing>>> P = ZZ[ X, Y ]; (X, Y,) = P._first_ngens(2)>>> F = FractionWithFactoredDenominatorRing(P); F
Ring of fractions with factored denominator
over Multivariate Polynomial Ring in X, Y over Integer Ring>>> F.base_ring()
Integer Ring>>> F.base()
Multivariate Polynomial Ring in X, Y over Integer Ringclass sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFacto

Bases: list
A list representing the sum of FractionWithFactoredDenominator objects with distinct denominatorfactorizations.
AUTHORS:• Alexander Raichev (2012-06-25)• Daniel Krenn (2014-12-01)
property denominator_ring
Return the polynomial ring of the denominators of self.
OUTPUT:
A ring or None if the list is empty.
EXAMPLES:

4.7. Asymptotics of Multivariate Generating Series

217

Asymptotic Expansions, Release 10.4

sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing,␣
˓→FractionWithFactoredDenominatorSum
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = FFPD(x + y, [(y, 1), (x, 1)])
sage: s = FractionWithFactoredDenominatorSum([f])
sage: s.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field
sage: g = FFPD(x + y, [])sage: t = FractionWithFactoredDenominatorSum([g])
sage: t.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing,␣
˓→FractionWithFactoredDenominatorSum>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = FFPD(x + y, [(y, Integer(1)), (x, Integer(1))])>>> s = FractionWithFactoredDenominatorSum([f])>>> s.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field>>> g = FFPD(x + y, [])>>> t = FractionWithFactoredDenominatorSum([g])>>> t.denominator_ring
Multivariate Polynomial Ring in x, y over Rational Field

sum()
Return the sum of the elements in self.
OUTPUT:
An instance of FractionWithFactoredDenominator.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing,␣
˓→FractionWithFactoredDenominatorSum
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: df = (x, 1), (y, 1), (x*y + 1, 1)
sage: f = FFPD(2, df)
sage: g = FFPD(2*x*y, df)
sage: FractionWithFactoredDenominatorSum([f, g])(2, [(y, 1), (x, 1), (x*y + 1, 1)]) + (2, [(x*y + 1, 1)])
sage: FractionWithFactoredDenominatorSum([f, g]).sum()(2, [(y, 1), (x, 1)])
sage: f = FFPD(cos(x), [(x, 2)])sage: g = FFPD(cos(y), [(x, 1), (y, 2)])sage: FractionWithFactoredDenominatorSum([f, g])(cos(x), [(x, 2)]) + (cos(y), [(y, 2), (x, 1)])
sage: FractionWithFactoredDenominatorSum([f, g]).sum()(y^2*cos(x) + x*cos(y), [(y, 2), (x, 2)])218

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing,␣
˓→FractionWithFactoredDenominatorSum>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)>>> df = (x, Integer(1)), (y, Integer(1)), (x*y + Integer(1), Integer(1))>>> f = FFPD(Integer(2), df)>>> g = FFPD(Integer(2)*x*y, df)>>> FractionWithFactoredDenominatorSum([f, g])(2, [(y, 1), (x, 1), (x*y + 1, 1)]) + (2, [(x*y + 1, 1)])>>> FractionWithFactoredDenominatorSum([f, g]).sum()(2, [(y, 1), (x, 1)])>>> f = FFPD(cos(x), [(x, Integer(2))])>>> g = FFPD(cos(y), [(x, Integer(1)), (y, Integer(2))])>>> FractionWithFactoredDenominatorSum([f, g])(cos(x), [(x, 2)]) + (cos(y), [(y, 2), (x, 1)])>>> FractionWithFactoredDenominatorSum([f, g]).sum()(y^2*cos(x) + x*cos(y), [(y, 2), (x, 2)])whole_and_parts()
Rewrite self as a sum of a (possibly zero) polynomial followed by reduced rational expressions.
OUTPUT:
An instance of FractionWithFactoredDenominatorSum.
Only useful for multivariate decompositions.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_˓→functions import FractionWithFactoredDenominatorRing,␣
˓→FractionWithFactoredDenominatorSum
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R, SR)
sage: f = x**2 + 3*y + 1/x + 1/y
sage: f = FFPD(f); f(x^3*y + 3*x*y^2 + x + y, [(y, 1), (x, 1)])
sage: FractionWithFactoredDenominatorSum([f]).whole_and_parts()(x^2 + 3*y, []) + (x + y, [(y, 1), (x, 1)])
sage: f = cos(x)**2 + 3*y + 1/x + 1/y; fcos(x)^2 + 3*y + 1/x + 1/y
sage: G = f.numerator()sage: H = R(f.denominator())
sage: f = FFPD(G, H.factor()); f(x*y*cos(x)^2 + 3*x*y^2 + x + y, [(y, 1), (x, 1)])
sage: FractionWithFactoredDenominatorSum([f]).whole_and_parts()(0, []) + (x*y*cos(x)^2 + 3*x*y^2 + x + y, [(y, 1), (x, 1)])>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing,␣
˓→FractionWithFactoredDenominatorSum>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R, SR)(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

219

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> f = x**Integer(2) + Integer(3)*y + Integer(1)/x + Integer(1)/y>>> f = FFPD(f); f(x^3*y + 3*x*y^2 + x + y, [(y, 1), (x, 1)])>>> FractionWithFactoredDenominatorSum([f]).whole_and_parts()(x^2 + 3*y, []) + (x + y, [(y, 1), (x, 1)])>>> f = cos(x)**Integer(2) + Integer(3)*y + Integer(1)/x + Integer(1)/y; fcos(x)^2 + 3*y + 1/x + 1/y>>> G = f.numerator()>>> H = R(f.denominator())>>> f = FFPD(G, H.factor()); f(x*y*cos(x)^2 + 3*x*y^2 + x + y, [(y, 1), (x, 1)])>>> FractionWithFactoredDenominatorSum([f]).whole_and_parts()(0, []) + (x*y*cos(x)^2 + 3*x*y^2 + x + y, [(y, 1), (x, 1)])sage.rings.asymptotic.asymptotics_multivariate_generating_functions.coerce_point(R,p)
Coerce the keys of the dictionary p into the ring R.
Warning: This method assumes that it is possible.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing, coerce_point
sage: R.<x,y> = PolynomialRing(QQ)
sage: FFPD = FractionWithFactoredDenominatorRing(R)sage: f = FFPD()
sage: p = {SR(x): 1, SR(y): 7/8}
sage: for k in sorted(p, key=str):....:
print("{} {} {}".format(k, k.parent(), p[k]))x Symbolic Ring 1
y Symbolic Ring 7/8
sage: q = coerce_point(R, p)
sage: for k in sorted(q, key=str):....:
print("{} {} {}".format(k, k.parent(), q[k]))x Multivariate Polynomial Ring in x, y over Rational Field 1
y Multivariate Polynomial Ring in x, y over Rational Field 7/8>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import FractionWithFactoredDenominatorRing, coerce_point>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> FFPD = FractionWithFactoredDenominatorRing(R)>>> f = FFPD()>>> p = {SR(x): Integer(1), SR(y): Integer(7)/Integer(8)}>>> for k in sorted(p, key=str):...
print("{} {} {}".format(k, k.parent(), p[k]))x Symbolic Ring 1
y Symbolic Ring 7/8>>> q = coerce_point(R, p)>>> for k in sorted(q, key=str):...
print("{} {} {}".format(k, k.parent(), q[k]))x Multivariate Polynomial Ring in x, y over Rational Field 1(continues on next page)

220

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)y Multivariate Polynomial Ring in x, y over Rational Field 7/8

sage.rings.asymptotic.asymptotics_multivariate_generating_functions.diff_all(f,V,n,ending=[],sub=None,
sub_final=None,zero_order=0,
rekey=None)
Return a dictionary of representative mixed partial derivatives of 𝑓 from order 1 up to order 𝑛 with respect to thevariables in 𝑉 .
The default is to key the dictionary by all nondecreasing sequences in 𝑉 of length 1 up to length 𝑛.
INPUT:• f – an individual or list of 𝒞 𝑛+1 functions• V – a list of variables occurring in 𝑓
• n – a natural number• ending – a list of variables in 𝑉
• sub – an individual or list of dictionaries• sub_final – an individual or list of dictionaries• rekey – a callable symbolic function in 𝑉 or list thereof• zero_order – a natural number
OUTPUT:The dictionary {s_1:deriv_1, ..., sr:deriv_r}.
Here s_1, ..., s_r is a listing of all nondecreasing sequences of length 1 up to length 𝑛 over the alphabet
𝑉 , where 𝑤 > 𝑣 in 𝑋 if and only if str(w) > str(v), and deriv_j is the derivative of 𝑓 with respect tothe derivative sequence s_j and simplified with respect to the substitutions in sub and evaluated at sub_final.
Moreover, all derivatives with respect to sequences of length less than zero_order (derivatives of order lessthan zero_order ) will be made zero.
If rekey is nonempty, then s_1, ..., s_r will be replaced by the symbolic derivatives of the functions inrekey.
If ending is nonempty, then every derivative sequence s_j will be suffixed by ending.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_all
sage: f = function( f )(x)sage: dd = diff_all(f, [x], 3)
sage: dd[(x, x, x)]diff(f(x), x, x, x)(continues on next page)

4.7. Asymptotics of Multivariate Generating Series

221

Asymptotic Expansions, Release 10.4

(continued from previous page)

sage: d1 = {diff(f, x): 4*x^3}
sage: dd = diff_all(f, [x], 3, sub=d1)
sage: dd[(x, x, x)]
24*x
sage: dd = diff_all(f, [x], 3, sub=d1, rekey=f)
sage: dd[diff(f, x, 3)]
24*x
sage: a = {x:1}
sage: dd = diff_all(f, [x], 3, sub=d1, rekey=f, sub_final=a)sage: dd[diff(f, x, 3)]24>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_all>>> f = function( f )(x)>>> dd = diff_all(f, [x], Integer(3))>>> dd[(x, x, x)]diff(f(x), x, x, x)>>> d1 = {diff(f, x): Integer(4)*x**Integer(3)}>>> dd = diff_all(f, [x], Integer(3), sub=d1)>>> dd[(x, x, x)]
24*x>>> dd = diff_all(f, [x], Integer(3), sub=d1, rekey=f)>>> dd[diff(f, x, Integer(3))]
24*x>>> a = {x:Integer(1)}>>> dd = diff_all(f, [x], Integer(3), sub=d1, rekey=f, sub_final=a)>>> dd[diff(f, x, Integer(3))]
24sage: X = var( x, y, z )sage: f = function( f )(*X)
sage: dd = diff_all(f, X, 2, ending=[y, y, y])sage: dd[(z, y, y, y)]diff(f(x, y, z), y, y, y, z)>>> from sage.all import *>>> X = var( x, y, z )>>> f = function( f )(*X)>>> dd = diff_all(f, X, Integer(2), ending=[y, y, y])>>> dd[(z, y, y, y)]diff(f(x, y, z), y, y, y, z)
sage: g = function( g )(*X)
sage: dd = diff_all([f, g], X, 2)
sage: dd[(0, y, z)]diff(f(x, y, z), y, z)
sage: dd[(1, z, z)](continues on next page)

222

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)diff(g(x, y, z), z, z)
sage: f = exp(x*y*z)
sage: ff = function( ff )(*X)
sage: dd = diff_all(f, X, 2, rekey=ff)
sage: dd[diff(ff, x, z)]x*y^2*z*e^(x*y*z) + y*e^(x*y*z)>>> from sage.all import *>>> g = function( g )(*X)>>> dd = diff_all([f, g], X, Integer(2))>>> dd[(Integer(0), y, z)]diff(f(x, y, z), y, z)>>> dd[(Integer(1), z, z)]diff(g(x, y, z), z, z)>>> f = exp(x*y*z)>>> ff = function( ff )(*X)>>> dd = diff_all(f, X, Integer(2), rekey=ff)>>> dd[diff(ff, x, z)]x*y^2*z*e^(x*y*z) + y*e^(x*y*z)

sage.rings.asymptotic.asymptotics_multivariate_generating_functions.diff_op(A,B,
AB_derivs,
V,
M,
r,
N)
Return the derivatives 𝐷𝐷(𝑙+𝑘) (𝐴[𝑗]𝐵 𝑙 ) evaluated at a point 𝑝 for various natural numbers 𝑗, 𝑘, 𝑙 which depend
on 𝑟 and 𝑁 .
Here 𝐷𝐷 is a specific second-order linear differential operator that depends on 𝑀 , 𝐴 is a list of symbolic functions,
𝐵 is symbolic function, and AB_derivs contains all the derivatives of 𝐴 and 𝐵 evaluated at 𝑝 that are necessary
for the computation.
INPUT:• A – a single or length r list of symbolic functions in the variables V• B – a symbolic function in the variables V.
• AB_derivs – a dictionary whose keys are the (symbolic) derivatives of A[0], ..., A[r-1] up toorder 2 * N-2 and the (symbolic) derivatives of B up to order 2 * N; the values of the dictionary arecomplex numbers that are the keys evaluated at a common point 𝑝• V – the variables of the A[j] and B• M – a symmetric 𝑙 × 𝑙 matrix, where 𝑙 is the length of V
• r, N – natural numbers
OUTPUT:
A dictionary.

4.7. Asymptotics of Multivariate Generating Series

223

Asymptotic Expansions, Release 10.4

The output is a dictionary whose keys are natural number tuples of the form (𝑗, 𝑘, 𝑙), where 𝑙 ≤ 2𝑘, 𝑗 ≤ 𝑟 − 1,and 𝑗 + 𝑘 ≤ 𝑁 − 1, and whose values are 𝐷𝐷( 𝑙 + 𝑘)(𝐴[𝑗]𝐵 𝑙 ) evaluated at a point 𝑝, where 𝐷𝐷 is the linear∑︀𝑙−1 ∑︀𝑙−1
second-order differential operator − 𝑖=0 𝑗=0 𝑀 [𝑖][𝑗]𝜕 2 /(𝜕𝑉 [𝑗]𝜕𝑉 [𝑖]).
Note: For internal use by FractionWithFactoredDenominator.asymptotics_smooth() andFractionWithFactoredDenominator.asymptotics_multiple().
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_op
sage: T = var( x, y )sage: A = function( A )(*tuple(T))
sage: B = function( B )(*tuple(T))
sage: AB_derivs = {}sage: M = matrix([[1, 2],[2, 1]])
sage: DD = diff_op(A, B, AB_derivs, T, M, 1, 2) # long time (see :issue: 35207 )sage: sorted(DD)# long time[(0, 0, 0), (0, 1, 0), (0, 1, 1), (0, 1, 2)]
sage: DD[(0, 1, 2)].number_of_operands()# long time246>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_op>>> T = var( x, y )>>> A = function( A )(*tuple(T))>>> B = function( B )(*tuple(T))>>> AB_derivs = {}>>> M = matrix([[Integer(1), Integer(2)],[Integer(2), Integer(1)]])>>> DD = diff_op(A, B, AB_derivs, T, M, Integer(1), Integer(2)) # long time (see␣˓→:issue: 35207 )>>> sorted(DD)# long time[(0, 0, 0), (0, 1, 0), (0, 1, 1), (0, 1, 2)]>>> DD[(Integer(0), Integer(1), Integer(2))].number_of_operands()# long␣˓→time246

sage.rings.asymptotic.asymptotics_multivariate_generating_functions.diff_op_simple(A,B,
AB_derivs,
x,
v,
a,
N)
Return 𝐷𝐷( 𝑒𝑘 + 𝑣𝑙)(𝐴𝐵 𝑙 ) evaluated at a point 𝑝 for various natural numbers 𝑒, 𝑘, 𝑙 that depend on 𝑣 and 𝑁 .
Here 𝐷𝐷 is a specific linear differential operator that depends on 𝑎 and 𝑣 , 𝐴 and 𝐵 are symbolic functions, and𝐴𝐵𝑑 𝑒𝑟𝑖𝑣𝑠 contains all the derivatives of 𝐴 and 𝐵 evaluated at 𝑝 that are necessary for the computation.
Note:
For internal
asymptotics_smooth().

224

use

by

the

function

FractionWithFactoredDenominator.

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

INPUT:• A, B – Symbolic functions in the variable x• AB_derivs – a dictionary whose keys are the (symbolic) derivatives of A up to order 2 * N if v is evenor N if v is odd and the (symbolic) derivatives of B up to order 2 * N + v if v is even or N + v if v is
odd; the values of the dictionary are complex numbers that are the keys evaluated at a common point 𝑝• x – a symbolic variable• a – a complex number• v, N – natural numbers
OUTPUT:
A dictionary.
The output is a dictionary whose keys are natural number pairs of the form (𝑘, 𝑙), where 𝑘 < 𝑁 and 𝑙 ≤ 2𝑘 andwhose values are 𝐷𝐷( 𝑒𝑘 + 𝑣𝑙)(𝐴𝐵 𝑙 ) evaluated at a point 𝑝. Here 𝑒 = 2 if 𝑣 is even, 𝑒 = 1 if 𝑣 is odd, and 𝐷𝐷
is the linear differential operator (𝑎−1/𝑣 𝑑/𝑑𝑡) if 𝑣 is even and (|𝑎|−1/𝑣 𝑖sgn(𝑎)𝑑/𝑑𝑡) if 𝑣 is odd.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_op_simple
sage: A = function( A )(x)sage: B = function( B )(x)sage: AB_derivs = {}sage: sorted(diff_op_simple(A, B, AB_derivs, x, 3, 2, 2).items())[((0, 0), A(x)),((1, 0), 1/2*I*2^(2/3)*diff(A(x), x)),((1, 1),
1/4*2^(2/3)*(B(x)*diff(A(x), x, x, x, x) + 4*diff(A(x), x, x, x)*diff(B(x), x)␣
˓→+ 6*diff(A(x), x, x)*diff(B(x), x, x) + 4*diff(A(x), x)*diff(B(x), x, x, x) +␣˓→A(x)*diff(B(x), x, x, x, x)))]>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_op_simple>>> A = function( A )(x)>>> B = function( B )(x)>>> AB_derivs = {}>>> sorted(diff_op_simple(A, B, AB_derivs, x, Integer(3), Integer(2), Integer(2)).
˓→items())[((0, 0), A(x)),((1, 0), 1/2*I*2^(2/3)*diff(A(x), x)),((1, 1),
1/4*2^(2/3)*(B(x)*diff(A(x), x, x, x, x) + 4*diff(A(x), x, x, x)*diff(B(x), x)␣
˓→+ 6*diff(A(x), x, x)*diff(B(x), x, x) + 4*diff(A(x), x)*diff(B(x), x, x, x) +␣˓→A(x)*diff(B(x), x, x, x, x)))]4.7. Asymptotics of Multivariate Generating Series

225

Asymptotic Expansions, Release 10.4

sage.rings.asymptotic.asymptotics_multivariate_generating_functions.diff_prod(f_derivs,u,g,X,interval,end,uderivs,atc)
Take various derivatives of the equation 𝑓 = 𝑢𝑔, evaluate them at a point 𝑐, and solve for the derivatives of 𝑢.
INPUT:• f_derivs – a dictionary whose keys are all tuples of the form s + end, where s is a sequence of variablesfrom X whose length lies in interval, and whose values are the derivatives of a function 𝑓 evaluated at 𝑐
• u – a callable symbolic function• g – an expression or callable symbolic function• X – a list of symbolic variables• interval – a list of positive integers Call the first and last values 𝑛 and 𝑛𝑛, respectively• end – a possibly empty list of repetitions of the variable z, where z is the last element of X
• uderivs – a dictionary whose keys are the symbolic derivatives of order 0 to order 𝑛 − 1 of u evaluated at𝑐 and whose values are the corresponding derivatives evaluated at 𝑐
• atc – a dictionary whose keys are the keys of 𝑐 and all the symbolic derivatives of order 0 to order 𝑛𝑛 of gevaluated 𝑐 and whose values are the corresponding derivatives evaluated at 𝑐
OUTPUT:
A dictionary whose keys are the derivatives of u up to order 𝑛𝑛 and whose values are those derivatives evaluatedat 𝑐.
This function works by differentiating the equation 𝑓 = 𝑢𝑔 with respect to the variable sequence s + end, forall tuples s of X of lengths in interval, evaluating at the point 𝑐 , and solving for the remaining derivatives ofu. This function assumes that u never appears in the differentiations of 𝑓 = 𝑢𝑔 after evaluating at 𝑐.
Note: For internal use by FractionWithFactoredDenominator.asymptotics_multiple().
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_prod
sage: u = function( u )(x)sage: g = function( g )(x)sage: fd = {(x,):1,(x, x):1}
sage: ud = {u(x=2): 1}
sage: atc = {x: 2, g(x=2): 3, diff(g, x)(x=2): 5}
sage: atc[diff(g, x, x)(x=2)] = 7
sage: dd = diff_prod(fd, u, g, [x], [1, 2], [], ud, atc)
sage: dd[diff(u, x, 2)(x=2)]
22/9

226

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_prod>>> u = function( u )(x)>>> g = function( g )(x)>>> fd = {(x,):Integer(1),(x, x):Integer(1)}>>> ud = {u(x=Integer(2)): Integer(1)}>>> atc = {x: Integer(2), g(x=Integer(2)): Integer(3), diff(g, x)(x=Integer(2)):␣
˓→Integer(5)}>>> atc[diff(g, x, x)(x=Integer(2))] = Integer(7)>>> dd = diff_prod(fd, u, g, [x], [Integer(1), Integer(2)], [], ud, atc)>>> dd[diff(u, x, Integer(2))(x=Integer(2))]
22/9sage.rings.asymptotic.asymptotics_multivariate_generating_functions.diff_seq(V,s)
Given a list s of tuples of natural numbers, return the list of elements of V with indices the elements of the elements
of s.
INPUT:• V – a list
• s – a list of tuples of natural numbers in the interval range(len(V))
OUTPUT:
The tuple tuple([V[tt] for tt in sorted(t)]), where t is the list of elements of the elements of s.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_seq
sage: V = list(var( x, t, z ))sage: diff_seq(V,([0, 1],[0, 2, 1],[0, 0]))(x, x, x, x, t, t, z)>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import diff_seq>>> V = list(var( x, t, z ))>>> diff_seq(V,([Integer(0), Integer(1)],[Integer(0), Integer(2), Integer(1)],
˓→[Integer(0), Integer(0)]))(x, x, x, x, t, t, z)Note: This function is for internal use by diff_op().
sage.rings.asymptotic.asymptotics_multivariate_generating_functions.direction(v,coordinate=None)
Return [vv/v[coordinate] for vv in v] where coordinate is the last index of v if not specified
otherwise.
INPUT:

4.7. Asymptotics of Multivariate Generating Series

227

Asymptotic Expansions, Release 10.4

• v – a vector• coordinate – (optional; default: None) an index for v
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import direction
sage: direction([2, 3, 5])(2/5, 3/5, 1)
sage: direction([2, 3, 5], 0)(1, 3/2, 5/2)>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import direction>>> direction([Integer(2), Integer(3), Integer(5)])(2/5, 3/5, 1)>>> direction([Integer(2), Integer(3), Integer(5)], Integer(0))(1, 3/2, 5/2)

sage.rings.asymptotic.asymptotics_multivariate_generating_functions.permutation_sign(s,u)
This function returns the sign of the permutation on 1, ..., len(u) that is induced by the sublist s of u.
Note: This function was intended for internal use and is deprecated now (Issue #29465).
INPUT:• s – a sublist of u
• u – a list
OUTPUT:
The sign of the permutation obtained by taking indices within u of the list s + sc, where sc is u with theelements of s removed.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import permutation_sign
sage: u = [ a , b , c , d , e ]sage: s = [ b , d ]sage: permutation_sign(s, u)
doctest:...: DeprecationWarning: the function permutation_sign is deprecated
See https://github.com/sagemath/sage/issues/29465 for details.
-1sage: s = [ d , b ]sage: permutation_sign(s, u)
1>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import permutation_sign>>> u = [ a , b , c , d , e ]>>> s = [ b , d ]>>> permutation_sign(s, u)(continues on next page)

228

Chapter 4. Asymptotic Expansions — Table of Contents

Asymptotic Expansions, Release 10.4

(continued from previous page)

doctest:...: DeprecationWarning: the function permutation_sign is deprecated
See https://github.com/sagemath/sage/issues/29465 for details.
-1>>> s = [ d , b ]>>> permutation_sign(s, u)
1

sage.rings.asymptotic.asymptotics_multivariate_generating_functions.subs_all(f,sub,simplify=False)
Return the items of 𝑓 substituted by the dictionaries of sub in order of their appearance in sub.
INPUT:• f – an individual or list of symbolic expressions or dictionaries• sub – an individual or list of dictionaries• simplify – (default: False) boolean; set to True to simplify the result
OUTPUT:
The items of f substituted by the dictionaries of sub in order of their appearance in sub. The subs() commandis used. If simplify is True, then simplify() is used after substitution.
EXAMPLES:
sage: from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import subs_all
sage: var( x, y, z )(x, y, z)sage: a = {x:1}
sage: b = {y:2}sage: c = {z:3}
sage: subs_all(x + y + z, a)y + z + 1
sage: subs_all(x + y + z, [c, a])y + 4
sage: subs_all([x + y + z, y^2], b)[x + z + 2, 4]
sage: subs_all([x + y + z, y^2], [b, c])[x + 5, 4]>>> from sage.all import *>>> from sage.rings.asymptotic.asymptotics_multivariate_generating_functions␣˓→import subs_all>>> var( x, y, z )(x, y, z)>>> a = {x:Integer(1)}>>> b = {y:Integer(2)}>>> c = {z:Integer(3)}>>> subs_all(x + y + z, a)y + z + 1>>> subs_all(x + y + z, [c, a])y + 4>>> subs_all([x + y + z, y**Integer(2)], b)[x + z + 2, 4](continues on next page)

4.7. Asymptotics of Multivariate Generating Series

229

Asymptotic Expansions, Release 10.4

(continued from previous page)>>> subs_all([x + y + z, y**Integer(2)], [b, c])[x + 5, 4]
sage: var( x, y )(x, y)
sage: a = { foo : x**2 + y**2,
sage: b = {x: 1, y: 2}
sage: subs_all(a, b){ bar : -1, foo : 5}

bar : x - y}>>> from sage.all import *>>> var( x, y )(x, y)>>> a = { foo : x**Integer(2) + y**Integer(2),>>> b = {x: Integer(1), y: Integer(2)}>>> subs_all(a, b){ bar : -1, foo : 5}230

bar : x - y}

Chapter 4. Asymptotic Expansions — Table of Contents

CHAPTERFIVE

INDICES AND TABLES• Index• Module Index• Search Page

231

Asymptotic Expansions, Release 10.4

232

Chapter 5. Indices and Tables

PYTHON MODULE INDEXrsage.rings.asymptotic.asymptotic_expansion_generators, 54
sage.rings.asymptotic.asymptotic_ring,7
sage.rings.asymptotic.asymptotics_multivariate_generating_functions,173
sage.rings.asymptotic.growth_group, 67
sage.rings.asymptotic.growth_group_cartesian,104
sage.rings.asymptotic.misc, 163
sage.rings.asymptotic.term_monoid, 117233

Asymptotic Expansions, Release 10.4

234

Python Module Index

INDEX

A

tions.FractionWithFactoredDenominatormethod), 189
absorb() (sage.rings.asymptotic.term_monoid.Generasymptotics_smooth()(sage.rings.asympicTerm method), 135
totic.asymptotics_multivariate_generating_funcabsorption()(inmodulesage.rings.asymptions.FractionWithFactoredDenominatortotic.term_monoid), 161
method), 191
AbstractGrowthGroupFunctor(classin
sage.rings.asymptotic.growth_group), 72
AdditiveMagmas(sage.rings.asymp- B
totic.growth_group.GenericGrowthGroupat- B() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 18
tribute), 86
B()(sage.rings.asymptotic.asymptotic_ring.AsymptotiAdditiveMagmas(sage.rings.asympcRing static method), 44
totic.growth_group.MonomialGrowthGroupbase(sage.rings.asymptotic.growth_group.Exponentialattribute), 96
GrowthElement property), 74
algebraic_dependence_certificate()base(sage.rings.asymptotic.growth_group.GrowthGroup(sage.rings.asymptotic.asymptotics_multivariFactor attribute), 92
ate_generating_functions.FractionWithFactoredbase_ring()(sage.rings.asymptotic.asymptotics_multiDenominator method), 181
variate_generating_functions.FractionWithFacalgebraic_dependence_decomposition()
toredDenominatorRing method), 217(sage.rings.asymptotic.asymptotics_multivaribidirectional_merge_overlapping()(inate_generating_functions.FractionWithFactoredmodule
sage.rings.asymptotic.misc),165
Denominator method), 183
asymptotic_decomposition() (sage.rings.asymp- bidirectional_merge_sorted() (in module
sage.rings.asymptotic.misc), 165
totic.asymptotics_multivariate_generating_funcBinomial_kn_over_n()(sage.rings.asymptions.FractionWithFactoredDenominatortotic.asymptotic_expansion_generators.Asymptomethod), 184
ticExpansionGenerators static method), 55
asymptotic_expansions(inmoduleBTerm(classin sage.rings.asymptotic.term_monoid), 121
sage.rings.asymptotic.asymptotic_expansion_genBTermMonoid(classin
sage.rings.asymperators), 67
totic.term_monoid),124
AsymptoticExpansion (class in sage.rings.asymptotic.asymptotic_ring), 15
AsymptoticExpansionGenerators (class in C
sage.rings.asymptotic.asymptotic_expansion_gen- can_absorb()(inmodulesage.rings.asymperators), 55
totic.term_monoid), 162
AsymptoticRing(classin
sage.rings.asymp- can_absorb()(sage.rings.asymptotic.asymptotic_ring), 41
totic.term_monoid.BTerm method), 122
AsymptoticRingFunctor (class in sage.rings.asymp- can_absorb() (sage.rings.asymptotic.term_monoid.Extotic.asymptotic_ring), 52
actTerm method), 128
asymptotics()(sage.rings.asymptotic.asymp- can_absorb()(sage.rings.asymptotics_multivariate_generating_functions.Fractotic.term_monoid.GenericTermmethod),tionWithFactoredDenominator method), 186
137
asymptotics_multiple()(sage.rings.asymp- can_absorb()(sage.rings.asymptotic.asymptotics_multivariate_generating_functotic.term_monoid.OTerm method), 150
235

Asymptotic Expansions, Release 10.4

cartesian_injection()(sage.rings.asymptotic.growth_group_cartesian.GenericProductmethod), 114
CartesianProduct(sage.rings.asymptotic.growth_group_cartesian.GenericProductattribute), 107
CartesianProduct(sage.rings.asymptotic.growth_group_cartesian.MultivariateProduct attribute), 116
CartesianProduct(sage.rings.asymptotic.growth_group_cartesian.UnivariateProductattribute), 116
CartesianProduct(sage.rings.asymptotic.growth_group.GenericGrowthGroup
attribute), 86
CartesianProductFactory(classin
sage.rings.asymptotic.growth_group_cartesian),104
change_parameter() (sage.rings.asymptotic.asymptotic_ring.AsymptoticRing method), 44
change_parameter()(sage.rings.asymptotic.term_monoid.GenericTermMonoid method),145
cls (sage.rings.asymptotic.growth_group.GrowthGroupFactor attribute), 93
coefficient_ring(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing property), 45
coefficient_ring(sage.rings.asymptotic.term_monoid.GenericTermMonoid
property), 145coefficients_of_generating_function()(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing method), 45
coerce_point() (in module sage.rings.asymptotic.asymptotics_multivariate_generating_functions), 220
cohomology_decomposition() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatormethod), 194
combine_exceptions()(inmodulesage.rings.asymptotic.misc), 165
compare_with_values()(sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion
method), 20
construction()(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing method), 47
construction()(sage.rings.asymptotic.growth_group.ExponentialGrowthGroupmethod), 75
construction()(sage.rings.asymptotic.growth_group.ExponentialNonGrowthGroup method), 78
construction()(sage.rings.asymp236

totic.growth_group.MonomialGrowthGroupmethod), 97
construction()(sage.rings.asymptotic.growth_group.MonomialNonGrowthGroupmethod), 99
construction()(sage.rings.asymptotic.term_monoid.BTerm method), 123construction()(sage.rings.asymptotic.term_monoid.GenericTermmethod),138
construction()(sage.rings.asymptotic.term_monoid.TermWithCoefficient method),158
create_key_and_extra_args()(sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory method), 106
create_key_and_extra_args()(sage.rings.asymptotic.growth_group.GrowthGroupFactory method), 94
create_key_and_extra_args()(sage.rings.asymptotic.term_monoid.TermMonoidFactory method), 157
create_object()(sage.rings.asymptotic.growth_group_cartesian.CartesianProductFactory method), 106
create_object()(sage.rings.asymptotic.growth_group.GrowthGroupFactory
method), 95
create_object()(sage.rings.asymptotic.term_monoid.TermMonoidFactory method),157
create_summand()(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing method), 48
critical_cone()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 195

D
DecreasingGrowthElementError, 73
default_locals() (sage.rings.asymptotic.misc.Locals
method), 163
default_prec(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing property), 48
DefaultTermMonoidFactory(inmodulesage.rings.asymptotic.term_monoid), 126
denominator()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 196
denominator_factored()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatormethod), 196
denominator_ring(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FracIndex

Asymptotic Expansions, Release 10.4

tionWithFactoredDenominator property), 197
denominator_ring(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatorSum
property),217
diff_all() (in module sage.rings.asymptotic.asymptotics_multivariate_generating_functions), 221
diff_op() (in module sage.rings.asymptotic.asymptotics_multivariate_generating_functions), 223
diff_op_simple() (in module sage.rings.asymptotic.asymptotics_multivariate_generating_functions), 224
diff_prod() (in module sage.rings.asymptotic.asymptotics_multivariate_generating_functions), 225
diff_seq() (in module sage.rings.asymptotic.asymptotics_multivariate_generating_functions), 227
dimension() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 198
direction() (in module sage.rings.asymptotic.asymptotics_multivariate_generating_functions), 227
DivisionRings(sage.rings.asymptotic.growth_group.ExponentialGrowthGroup
attribute), 75

exact_part()(sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 22
ExactTerm (class in sage.rings.asymptotic.term_monoid),
126
ExactTermMonoid (class in sage.rings.asymptotic.term_monoid), 133
exp() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 23
exp()(sage.rings.asymptotic.growth_group_cartesian.GenericProduct.Element method), 107
exponent (sage.rings.asymptotic.growth_group.MonomialGrowthElement property), 95
ExponentialGrowthElement(classin
sage.rings.asymptotic.growth_group), 73
ExponentialGrowthGroup(classin
sage.rings.asymptotic.growth_group), 74
ExponentialGrowthGroupFunctor (class insage.rings.asymptotic.growth_group), 77
ExponentialNonGrowthElement(classin
sage.rings.asymptotic.growth_group), 78
ExponentialNonGrowthGroup(classin
sage.rings.asymptotic.growth_group), 78
ExponentialNonGrowthGroupFunctor (class insage.rings.asymptotic.growth_group), 79
extend_by_non_growth_group (sage.rings.asympE
totic.growth_group.GrowthGroupFactor
attribute), 93
Element (sage.rings.asymptotic.asymptotic_ring.Asympextended_by_non_growth_group()
toticRing attribute), 44(sage.rings.asymptotic.growth_group.GenerElement (sage.rings.asymptotic.asymptotics_multivariicGrowthGroup method), 86
ate_generating_functions.FractionWithFactoredextract_variable_names() (sage.rings.asympDenominatorRing attribute), 216
totic.growth_group.Variable static method),
Element (sage.rings.asymptotic.growth_group.Exponen101
tialGrowthGroup attribute), 75
Element (sage.rings.asymptotic.growth_group.ExponenF
tialNonGrowthGroup attribute), 78(sage.rings.asymptotic.asympElement (sage.rings.asymptotic.growth_group.Generic- factorial()
totic_ring.AsymptoticExpansion method), 24
GrowthGroup attribute), 86
Element (sage.rings.asymptotic.growth_group.Monomial- factors() (sage.rings.asymptotic.growth_group_cartesian.GenericProduct.Element method), 108
GrowthGroup attribute), 96
Element (sage.rings.asymptotic.growth_group.Monomial- factors() (sage.rings.asymptotic.growth_group.GenericGrowthElement method), 79
NonGrowthGroup attribute), 99
Element(sage.rings.asymptotic.term_monoid.BTer- factory() (sage.rings.asymptotic.growth_group.ExponentialGrowthGroup class method), 75
mMonoid attribute), 125
Element (sage.rings.asymptotic.term_monoid.ExactTer- factory() (sage.rings.asymptotic.growth_group.MonomialGrowthGroup class method), 97
mMonoid attribute), 134(classElement(sage.rings.asymptotic.term_monoid.Gener- FractionWithFactoredDenominatorin sage.rings.asymptotic.asymptotics_multivariicTermMonoid attribute), 144
ate_generating_functions), 178
Element(sage.rings.asymptotic.term_monoid.OTerFractionWithFactoredDenominatorRing
mMonoid attribute), 155(class in sage.rings.asymptotic.asymptotics_multiElement (sage.rings.asymptotic.term_monoid.TermWithvariate_generating_functions), 216
CoefficientMonoid attribute), 160
error_part()(sage.rings.asymptotic.asymp- FractionWithFactoredDenominatorSum (classin sage.rings.asymptotic.asymptotics_multivaritotic_ring.AsymptoticExpansion method), 22
ate_generating_functions), 217
Index

237

Asymptotic Expansions, Release 10.4

from_construction()(sage.rings.asymp- GrowthGroup(inmodulesage.rings.asymptotic.term_monoid.GenericTermMonoid method),
totic.growth_group), 92
145
GrowthGroupFactor (class in sage.rings.asymptotic.growth_group), 92
G
GrowthGroupFactory (class in sage.rings.asymptotic.growth_group), 93
gen() (sage.rings.asymptotic.asymptotic_ring.AsymptoticRing method), 49
gen()(sage.rings.asymptotic.growth_group.Generic- H
GrowthGroup method), 87
HarmonicNumber()(sage.rings.asymptotic.asympGenericGrowthElement (class in sage.rings.asymptotic_expansion_generators.AsymptoticExpantotic.growth_group), 79
sionGenerators static method), 56
GenericGrowthGroup (class in sage.rings.asymp- has_same_summands()(sage.rings.asymptotic.growth_group), 85
totic.asymptotic_ring.AsymptoticExpansion
GenericNonGrowthElement(classinmethod), 25
sage.rings.asymptotic.growth_group), 92
GenericNonGrowthGroup (class in sage.rings.asymp- I
totic.growth_group), 92
ImplicitExpansion()(sage.rings.asympGenericProduct(classin
sage.rings.asymptotic.asymptotic_expansion_generators.Asymptototic.growth_group_cartesian), 106
ticExpansionGenerators static method), 57
GenericProduct.Element(classin ImplicitExpansionPeriodicPart()sage.rings.asymptotic.growth_group_cartesian),(sage.rings.asymptotic.asymptotic_expan107
sion_generators.AsymptoticExpansionGenerators
GenericTerm(classin
sage.rings.asympstatic method), 59
totic.term_monoid), 134
InverseFunctionAnalysis() (sage.rings.asympGenericTermMonoid (class in sage.rings.asymptotic.asymptotic_expansion_generators.Asymptototic.term_monoid), 144
ticExpansionGenerators static method), 60
gens() (sage.rings.asymptotic.asymptotic_ring.Asymptoti- invert()(sage.rings.asymptotic.asympcRing method), 49
totic_ring.AsymptoticExpansion method), 26
gens() (sage.rings.asymptotic.growth_group.Exponen- is_compatible()(sage.rings.asymptialGrowthGroup method), 76
totic.growth_group.GenericGrowthGroupgens()(sage.rings.asymptotic.growth_group.Genericmethod), 88
GrowthGroup method), 87
is_compatible()(sage.rings.asympgens_logarithmic()(sage.rings.asymptotic.growth_group.PartialConversionElement
totic.growth_group.MonomialGrowthGroupmethod), 100
method), 97
is_constant()(sage.rings.asympgens_monomial()(sage.rings.asymptotic.term_monoid.ExactTerm method), 128
totic.growth_group_cartesian.GenericProductis_constant()(sage.rings.asympmethod), 114
totic.term_monoid.GenericTermmethod),gens_monomial()(sage.rings.asymp139
totic.growth_group.GenericGrowthGroupis_convenient_multiple_point()
method), 88(sage.rings.asymptotic.asymptotics_multivarigens_monomial()(sage.rings.asympate_generating_functions.FractionWithFactoredtotic.growth_group.MonomialGrowthGroup
Denominator method), 199
method), 98
is_exact()(sage.rings.asymptotic.asympgrads() (sage.rings.asymptotic.asymptotics_multivaritotic_ring.AsymptoticExpansion method), 27
ate_generating_functions.FractionWithFactored- is_exact() (sage.rings.asymptotic.term_monoid.ExactDenominator method), 198
Term method), 129
Groups (sage.rings.asymptotic.growth_group.Exponen- is_exact() (sage.rings.asymptotic.term_monoid.GenertialGrowthGroup attribute), 75
icTerm method), 140
growth_group(sage.rings.asymptotic.asymp- is_little_o_of_one()(sage.rings.asymptotic_ring.AsymptoticRing property), 50
totic.asymptotic_ring.AsymptoticExpansion
growth_group(sage.rings.asympmethod), 27
totic.term_monoid.GenericTermMonoid
prop- is_little_o_of_one()(sage.rings.asymperty), 147
totic.term_monoid.ExactTerm method), 130
238

Index

Asymptotic Expansions, Release 10.4

is_little_o_of_one()(sage.rings.asymptotic.term_monoid.GenericTermmethod),140
is_little_o_of_one()(sage.rings.asymptotic.term_monoid.OTerm method), 151
is_lt_one()(sage.rings.asymptotic.growth_group_cartesian.GenericProduct.Element method), 109
is_lt_one()(sage.rings.asymptotic.growth_group.GenericGrowthElement
method), 80
is_monomial()(sage.rings.asymptotic.growth_group.Variable method), 103LM
maclaurin_coefficients() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatormethod), 204
Magmas (sage.rings.asymptotic.growth_group.ExponentialGrowthGroup attribute), 75
Magmas(sage.rings.asymptotic.growth_group.GenericGrowthGroup attribute), 86
Magmas (sage.rings.asymptotic.growth_group.MonomialGrowthGroup attribute), 96
map_coefficients() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 31
merge() (sage.rings.asymptotic.asymptotic_ring.AsymptoticRingFunctor method), 53
merge() (sage.rings.asymptotic.growth_group.AbstractGrowthGroupFunctor method), 72
modulesage.rings.asymptotic.asymptotic_expansion_generators, 54
sage.rings.asymptotic.asymptotic_ring, 7
sage.rings.asymptotic.asymptotics_multivariate_generating_functions, 173
sage.rings.asymptotic.growth_group,67
sage.rings.asymptotic.growth_group_cartesian,104
sage.rings.asymptotic.misc, 163
sage.rings.asymptotic.term_monoid,
117
monomial_coefficient()(sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion
method), 31
MonomialGrowthElement (class in sage.rings.asymptotic.growth_group), 95
MonomialGrowthGroup (class in sage.rings.asymptotic.growth_group), 96
MonomialGrowthGroupFunctor(classin
sage.rings.asymptotic.growth_group), 98
MonomialNonGrowthElement(classin
sage.rings.asymptotic.growth_group), 99
MonomialNonGrowthGroup(classin
sage.rings.asymptotic.growth_group), 99
MonomialNonGrowthGroupFunctor (class insage.rings.asymptotic.growth_group), 99
MultivariateProduct (class in sage.rings.asymptotic.growth_group_cartesian), 116(sage.rings.asymptotic.growth_group.GenericGrowthGroup method), 89
le()(sage.rings.asymptotic.term_monoid.GenericTermMonoid method), 147
leinartas_decomposition() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatormethod), 200
limit() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 28
Locals (class in sage.rings.asymptotic.misc), 163
locals()(sage.rings.asymptotic.misc.WithLocals
method), 164log() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 29
log()(sage.rings.asymptotic.growth_group_cartesian.GenericProduct.Element method), 109
log()(sage.rings.asymptotic.growth_group.GenericGrowthElement method), 80
log_factor()(sage.rings.asymptotic.growth_group_cartesian.GenericProduct.Element method), 111
log_factor()(sage.rings.asymptotic.growth_group.GenericGrowthElement
method), 82
log_grads() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 203
log_Stirling()(sage.rings.asymptotic.asymptotic_expansion_generators.AsymptoticExpansionGenerators static method), 67
log_string() (in module sage.rings.asymptotic.misc),166
log_term() (sage.rings.asymptotic.term_monoid.ExactTerm method), 131
log_term() (sage.rings.asymptotic.term_monoid.GenerN
icTerm method), 141
log_term() (sage.rings.asymptotic.term_monoid.OTerm ngens() (sage.rings.asymptotic.asymptotic_ring.Asympmethod), 152
toticRing method), 50
le()

Index

239

Asymptotic Expansions, Release 10.4

ngens() (sage.rings.asymptotic.growth_group.GenericGrowthGroup method), 90
NoConvergenceError, 53
non_growth_group()(sage.rings.asymptotic.growth_group.ExponentialGrowthGroupmethod), 76
non_growth_group()(sage.rings.asymptotic.growth_group.GenericGrowthGroupmethod), 90
non_growth_group()(sage.rings.asymptotic.growth_group.MonomialGrowthGroupmethod), 98
NotImplementedBZero, 164
NotImplementedOZero, 164
nullstellensatz_certificate()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 205
nullstellensatz_decomposition()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 206
numerator() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 208
numerator_ring(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator property), 208

pow() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 33

Q
quotient() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 209R(sage.rings.asymptotic.asymptotic_ring.AsymptoticRingFunctor attribute), 53
rank(sage.rings.asymptotic.growth_group.AbstractGrowthGroupFunctor attribute), 73
relative_error()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 209
repr_op() (in module sage.rings.asymptotic.misc), 168
repr_short_to_parent()(inmodulesage.rings.asymptotic.misc), 168
rpow() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 35
rpow()(sage.rings.asymptotic.growth_group_cartesian.GenericProduct.Element method), 112
rpow()(sage.rings.asymptotic.growth_group.GenericGrowthElement method), 83
rpow() (sage.rings.asymptotic.term_monoid.ExactTermmethod), 132
rpow() (sage.rings.asymptotic.term_monoid.GenericTermmethod), 142O
rpow()(sage.rings.asymptotic.term_monoid.OTerm
O() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExmethod), 153
pansion method), 19
OTerm (class in sage.rings.asymptotic.term_monoid), 149 S
OTermMonoid(classin
sage.rings.asymp- sage.rings.asymptotic.asymptotic_extotic.term_monoid), 154pansion_generators
module, 54
Psage.rings.asymptotic.asymptotic_ring
module, 7
parent_to_repr_short()(inmodulesage.rings.asymptotic.asymptotics_mulsage.rings.asymptotic.misc), 167
tivariate_generating_functions
PartialConversionElement(classinmodule, 173
sage.rings.asymptotic.growth_group), 100
sage.rings.asymptotic.growth_group
PartialConversionValueError, 100
module, 67
permutation_sign() (in module sage.rings.asympsage.rings.asymptotic.asymptotics_multivariate_generating_functotic.growth_group_cartesiantions), 228
module, 104
plot_comparison() (sage.rings.asymptotic.asympsage.rings.asymptotic.misc
totic_ring.AsymptoticExpansion method), 32
module, 163
Posets (sage.rings.asymptotic.growth_group.Exponensage.rings.asymptotic.term_monoid
tialGrowthGroup attribute), 75
module, 117
Posets(sage.rings.asymptotic.growth_group.GenericSets (sage.rings.asymptotic.growth_group.ExponentialGrowthGroup attribute), 86
GrowthGroup attribute), 75
Posets (sage.rings.asymptotic.growth_group.MonomialSets(sage.rings.asymptotic.growth_group.GenericGrowthGroup attribute), 96
GrowthGroup attribute), 86
240

rank

Index

Asymptotic Expansions, Release 10.4

(sage.rings.asymptotic.growth_group.MonomialGrowthGroup attribute), 96
show() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 36
singular_ideal()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominator method), 211
SingularityAnalysis()(sage.rings.asymptotic.asymptotic_expansion_generators.AsymptoticExpansionGenerators static method), 62
smooth_critical_ideal()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatormethod), 211
some_elements()(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing method), 50
some_elements()(sage.rings.asymptotic.growth_group_cartesian.GenericProductmethod), 115
some_elements()(sage.rings.asymptotic.growth_group.ExponentialGrowthGroupmethod), 77
some_elements()(sage.rings.asymptotic.growth_group.GenericGrowthGroupmethod), 91
some_elements()(sage.rings.asymptotic.term_monoid.BTermMonoid
method),125
some_elements()(sage.rings.asymptotic.term_monoid.GenericTermMonoid method),147
some_elements()(sage.rings.asymptotic.term_monoid.TermWithCoefficientMonoid
method), 160
split() (sage.rings.asymptotic.growth_group.PartialConversionElement method), 100
split_str_by_op() (in module sage.rings.asymptotic.misc), 169
sqrt() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 36
Stirling() (sage.rings.asymptotic.asymptotic_expansion_generators.AsymptoticExpansionGenerators
static method), 66
strip_symbolic() (in module sage.rings.asymptotic.misc), 169
subs() (sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 37
subs_all() (in module sage.rings.asymptotic.asymptotics_multivariate_generating_functions), 229
substitute_raise_exception() (in module
sage.rings.asymptotic.misc), 170
sum()(sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatorSum method), 218
Sets

Index

summands(sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion
property),
38
symbolic_expression()(sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion
method), 39

T
term_monoid()(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing method), 51
term_monoid()(sage.rings.asymptotic.term_monoid.GenericTermMonoid method),148
term_monoid_factory(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing property),52
term_monoid_factory(sage.rings.asymptotic.term_monoid.GenericTermMonoid
property), 148
TermMonoidFactory (class in sage.rings.asymptotic.term_monoid), 155
TermWithCoefficient (class in sage.rings.asymptotic.term_monoid), 158
TermWithCoefficientMonoid(classin
sage.rings.asymptotic.term_monoid), 159
transform_category()(inmodulesage.rings.asymptotic.misc), 170
truncate()(sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 40

Uunivariate_decomposition() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatormethod), 213
UnivariateProduct (class in sage.rings.asymptotic.growth_group_cartesian), 116V(sage.rings.asymptotic.growth_group.GrowthGroupFactor attribute), 93
Variable (class in sage.rings.asymptotic.growth_group),101
variable_names()(sage.rings.asymptotic.asymptotic_ring.AsymptoticExpansion method), 40
variable_names()(sage.rings.asymptotic.asymptotic_ring.AsymptoticRing method), 52
variable_names()(sage.rings.asymptotic.growth_group_cartesian.GenericProductmethod), 115
variable_names()(sage.rings.asymptotic.growth_group_cartesian.GenericProduct.Element method), 113
var

241

Asymptotic Expansions, Release 10.4

variable_names()(sage.rings.asymptotic.growth_group.GenericGrowthElement
method), 85
variable_names()(sage.rings.asymptotic.growth_group.GenericGrowthGroupmethod), 91
variable_names()(sage.rings.asymptotic.growth_group.Variable method), 103
variable_names()(sage.rings.asymptotic.term_monoid.GenericTermmethod),143

Wwhole_and_parts() (sage.rings.asymptotic.asymptotics_multivariate_generating_functions.FractionWithFactoredDenominatorSum
method),219
WithLocals (class in sage.rings.asymptotic.misc), 164

Z
ZeroCoefficientError, 161

242

Index