Elements of Infinite Polynomial Rings

AUTHORS:

An Infinite Polynomial Ring has generators \(x_\ast, y_\ast,...\), so that the variables are of the form \(x_0, x_1, x_2, ..., y_0, y_1, y_2,...,...\) (see infinite_polynomial_ring). Using the generators, we can create elements as follows:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: a = x[3]
sage: b = y[4]
sage: a
x_3
sage: b
y_4
sage: c = a*b + a^3 - 2*b^4
sage: c
x_3^3 + x_3*y_4 - 2*y_4^4
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> a = x[Integer(3)]
>>> b = y[Integer(4)]
>>> a
x_3
>>> b
y_4
>>> c = a*b + a**Integer(3) - Integer(2)*b**Integer(4)
>>> c
x_3^3 + x_3*y_4 - 2*y_4^4
X.<x,y> = InfinitePolynomialRing(QQ)
a = x[3]
b = y[4]
a
b
c = a*b + a^3 - 2*b^4
c

Any Infinite Polynomial Ring X is equipped with a monomial ordering. We only consider monomial orderings in which:

X.gen(i)[m] > X.gen(j)[n] \(\iff\) i<j, or i==j and m>n

Under this restriction, the monomial ordering can be lexicographic (default), degree lexicographic, or degree reverse lexicographic. Here, the ordering is lexicographic, and elements can be compared as usual:

sage: X._order
'lex'
sage: a > b
True
>>> from sage.all import *
>>> X._order
'lex'
>>> a > b
True
X._order
a > b

Note that, when a method is called that is not directly implemented for ‘InfinitePolynomial’, it is tried to call this method for the underlying classical polynomial. This holds, e.g., when applying the latex function:

sage: latex(c)
x_{3}^{3} + x_{3} y_{4} - 2 y_{4}^{4}
>>> from sage.all import *
>>> latex(c)
x_{3}^{3} + x_{3} y_{4} - 2 y_{4}^{4}
latex(c)

There is a permutation action on Infinite Polynomial Rings by permuting the indices of the variables:

sage: P = Permutation(((4,5),(2,3)))
sage: c^P
x_2^3 + x_2*y_5 - 2*y_5^4
>>> from sage.all import *
>>> P = Permutation(((Integer(4),Integer(5)),(Integer(2),Integer(3))))
>>> c**P
x_2^3 + x_2*y_5 - 2*y_5^4
P = Permutation(((4,5),(2,3)))
c^P

Note that P(0)==0, and thus variables of index zero are invariant under the permutation action. More generally, if P is any callable object that accepts nonnegative integers as input and returns nonnegative integers, then c^P means to apply P to the variable indices occurring in c.

If you want to substitute variables you can use the standard polynomial methods, such as subs():

sage: R.<x,y> = InfinitePolynomialRing(QQ)
sage: f = x[1] + x[1]*x[2]*x[3]
sage: f.subs({x[1]: x[0]})
x_3*x_2*x_0 + x_0
sage: g = x[0] + x[1] + y[0]
sage: g.subs({x[0]: y[0]})
x_1 + 2*y_0
>>> from sage.all import *
>>> R = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
>>> f = x[Integer(1)] + x[Integer(1)]*x[Integer(2)]*x[Integer(3)]
>>> f.subs({x[Integer(1)]: x[Integer(0)]})
x_3*x_2*x_0 + x_0
>>> g = x[Integer(0)] + x[Integer(1)] + y[Integer(0)]
>>> g.subs({x[Integer(0)]: y[Integer(0)]})
x_1 + 2*y_0
R.<x,y> = InfinitePolynomialRing(QQ)
f = x[1] + x[1]*x[2]*x[3]
f.subs({x[1]: x[0]})
g = x[0] + x[1] + y[0]
g.subs({x[0]: y[0]})
class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial(A, p)[source]

Bases: CommutativePolynomial

Create an element of a Polynomial Ring with a Countably Infinite Number of Variables.

Usually, an InfinitePolynomial is obtained by using the generators of an Infinite Polynomial Ring (see infinite_polynomial_ring) or by conversion.

INPUT:

  • A – an Infinite Polynomial Ring

  • p – a classical polynomial that can be interpreted in A

ASSUMPTIONS:

In the dense implementation, it must be ensured that the argument p coerces into A._P by a name preserving conversion map.

In the sparse implementation, in the direct construction of an infinite polynomial, it is not tested whether the argument p makes sense in A.

EXAMPLES:

sage: from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial
sage: X.<alpha> = InfinitePolynomialRing(ZZ)
sage: P.<alpha_1,alpha_2> = ZZ[]
>>> from sage.all import *
>>> from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial
>>> X = InfinitePolynomialRing(ZZ, names=('alpha',)); (alpha,) = X._first_ngens(1)
>>> P = ZZ['alpha_1, alpha_2']; (alpha_1, alpha_2,) = P._first_ngens(2)
from sage.rings.polynomial.infinite_polynomial_element import InfinitePolynomial
X.<alpha> = InfinitePolynomialRing(ZZ)
P.<alpha_1,alpha_2> = ZZ[]

Currently, P and X._P (the underlying polynomial ring of X) both have two variables:

sage: X._P
Multivariate Polynomial Ring in alpha_1, alpha_0 over Integer Ring
>>> from sage.all import *
>>> X._P
Multivariate Polynomial Ring in alpha_1, alpha_0 over Integer Ring
X._P

By default, a coercion from P to X._P would not be name preserving. However, this is taken care for; a name preserving conversion is impossible, and by consequence an error is raised:

sage: InfinitePolynomial(X, (alpha_1+alpha_2)^2)
Traceback (most recent call last):
...
TypeError: Could not find a mapping of the passed element to this ring.
>>> from sage.all import *
>>> InfinitePolynomial(X, (alpha_1+alpha_2)**Integer(2))
Traceback (most recent call last):
...
TypeError: Could not find a mapping of the passed element to this ring.
InfinitePolynomial(X, (alpha_1+alpha_2)^2)

When extending the underlying polynomial ring, the construction of an infinite polynomial works:

sage: alpha[2]
alpha_2
sage: InfinitePolynomial(X, (alpha_1+alpha_2)^2)
alpha_2^2 + 2*alpha_2*alpha_1 + alpha_1^2
>>> from sage.all import *
>>> alpha[Integer(2)]
alpha_2
>>> InfinitePolynomial(X, (alpha_1+alpha_2)**Integer(2))
alpha_2^2 + 2*alpha_2*alpha_1 + alpha_1^2
alpha[2]
InfinitePolynomial(X, (alpha_1+alpha_2)^2)

In the sparse implementation, it is not checked whether the polynomial really belongs to the parent, and when it does not, the results may be unexpected due to coercions:

sage: Y.<alpha,beta> = InfinitePolynomialRing(GF(2), implementation='sparse')
sage: a = (alpha_1+alpha_2)^2
sage: InfinitePolynomial(Y, a)
alpha_0^2 + beta_0^2
>>> from sage.all import *
>>> Y = InfinitePolynomialRing(GF(Integer(2)), implementation='sparse', names=('alpha', 'beta',)); (alpha, beta,) = Y._first_ngens(2)
>>> a = (alpha_1+alpha_2)**Integer(2)
>>> InfinitePolynomial(Y, a)
alpha_0^2 + beta_0^2
Y.<alpha,beta> = InfinitePolynomialRing(GF(2), implementation='sparse')
a = (alpha_1+alpha_2)^2
InfinitePolynomial(Y, a)

However, it is checked when doing a conversion:

sage: Y(a)
alpha_2^2 + alpha_1^2
>>> from sage.all import *
>>> Y(a)
alpha_2^2 + alpha_1^2
Y(a)
coefficient(monomial)[source]

Return the coefficient of a monomial in this polynomial.

INPUT:

  • A monomial (element of the parent of self) or

  • a dictionary that describes a monomial (the keys are variables of the parent of self, the values are the corresponding exponents)

EXAMPLES:

We can get the coefficient in front of monomials:

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: a = 2*x[0]*x[1] + x[1] + x[2]
sage: a.coefficient(x[0])
2*x_1
sage: a.coefficient(x[1])
2*x_0 + 1
sage: a.coefficient(x[2])
1
sage: a.coefficient(x[0]*x[1])
2
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x',)); (x,) = X._first_ngens(1)
>>> a = Integer(2)*x[Integer(0)]*x[Integer(1)] + x[Integer(1)] + x[Integer(2)]
>>> a.coefficient(x[Integer(0)])
2*x_1
>>> a.coefficient(x[Integer(1)])
2*x_0 + 1
>>> a.coefficient(x[Integer(2)])
1
>>> a.coefficient(x[Integer(0)]*x[Integer(1)])
2
X.<x> = InfinitePolynomialRing(QQ)
a = 2*x[0]*x[1] + x[1] + x[2]
a.coefficient(x[0])
a.coefficient(x[1])
a.coefficient(x[2])
a.coefficient(x[0]*x[1])

We can also pass in a dictionary:

sage: a.coefficient({x[0]:1, x[1]:1})
2
>>> from sage.all import *
>>> a.coefficient({x[Integer(0)]:Integer(1), x[Integer(1)]:Integer(1)})
2
a.coefficient({x[0]:1, x[1]:1})
footprint()[source]

Leading exponents sorted by index and generator.

OUTPUT: D; dictionary whose keys are the occurring variable indices

D[s] is a list [i_1,...,i_n], where i_j gives the exponent of self.parent().gen(j)[s] in the leading term of self.

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = x[30]*y[1]^3*x[1]^2 + 2*x[10]*y[30]
sage: sorted(p.footprint().items())
[(1, [2, 3]), (30, [1, 0])]
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = x[Integer(30)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2) + Integer(2)*x[Integer(10)]*y[Integer(30)]
>>> sorted(p.footprint().items())
[(1, [2, 3]), (30, [1, 0])]
X.<x,y> = InfinitePolynomialRing(QQ)
p = x[30]*y[1]^3*x[1]^2 + 2*x[10]*y[30]
sorted(p.footprint().items())
gcd(x)[source]

Compute the greatest common divisor.

EXAMPLES:

sage: R.<x>=InfinitePolynomialRing(QQ)
sage: p1=x[0] + x[1]**2
sage: gcd(p1,p1+3)
1
sage: gcd(p1,p1)==p1
True
>>> from sage.all import *
>>> R = InfinitePolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> p1=x[Integer(0)] + x[Integer(1)]**Integer(2)
>>> gcd(p1,p1+Integer(3))
1
>>> gcd(p1,p1)==p1
True
R.<x>=InfinitePolynomialRing(QQ)
p1=x[0] + x[1]**2
gcd(p1,p1+3)
gcd(p1,p1)==p1
is_nilpotent()[source]

Return True if self is nilpotent, i.e., some power of self is 0.

EXAMPLES:

sage: R.<x> = InfinitePolynomialRing(QQbar)                                 # needs sage.rings.number_field
sage: (x[0] + x[1]).is_nilpotent()                                          # needs sage.rings.number_field
False
sage: R(0).is_nilpotent()                                                   # needs sage.rings.number_field
True
sage: _.<x> = InfinitePolynomialRing(Zmod(4))
sage: (2*x[0]).is_nilpotent()
True
sage: (2+x[4]*x[7]).is_nilpotent()
False
sage: _.<y> = InfinitePolynomialRing(Zmod(100))
sage: (5+2*y[0] + 10*(y[0]^2+y[1]^2)).is_nilpotent()
False
sage: (10*y[2] + 20*y[5] - 30*y[2]*y[5] + 70*(y[2]^2+y[5]^2)).is_nilpotent()
True
>>> from sage.all import *
>>> R = InfinitePolynomialRing(QQbar, names=('x',)); (x,) = R._first_ngens(1)# needs sage.rings.number_field
>>> (x[Integer(0)] + x[Integer(1)]).is_nilpotent()                                          # needs sage.rings.number_field
False
>>> R(Integer(0)).is_nilpotent()                                                   # needs sage.rings.number_field
True
>>> _ = InfinitePolynomialRing(Zmod(Integer(4)), names=('x',)); (x,) = _._first_ngens(1)
>>> (Integer(2)*x[Integer(0)]).is_nilpotent()
True
>>> (Integer(2)+x[Integer(4)]*x[Integer(7)]).is_nilpotent()
False
>>> _ = InfinitePolynomialRing(Zmod(Integer(100)), names=('y',)); (y,) = _._first_ngens(1)
>>> (Integer(5)+Integer(2)*y[Integer(0)] + Integer(10)*(y[Integer(0)]**Integer(2)+y[Integer(1)]**Integer(2))).is_nilpotent()
False
>>> (Integer(10)*y[Integer(2)] + Integer(20)*y[Integer(5)] - Integer(30)*y[Integer(2)]*y[Integer(5)] + Integer(70)*(y[Integer(2)]**Integer(2)+y[Integer(5)]**Integer(2))).is_nilpotent()
True
R.<x> = InfinitePolynomialRing(QQbar)                                 # needs sage.rings.number_field
(x[0] + x[1]).is_nilpotent()                                          # needs sage.rings.number_field
R(0).is_nilpotent()                                                   # needs sage.rings.number_field
_.<x> = InfinitePolynomialRing(Zmod(4))
(2*x[0]).is_nilpotent()
(2+x[4]*x[7]).is_nilpotent()
_.<y> = InfinitePolynomialRing(Zmod(100))
(5+2*y[0] + 10*(y[0]^2+y[1]^2)).is_nilpotent()
(10*y[2] + 20*y[5] - 30*y[2]*y[5] + 70*(y[2]^2+y[5]^2)).is_nilpotent()
is_unit()[source]

Answer whether self is a unit.

EXAMPLES:

sage: R1.<x,y> = InfinitePolynomialRing(ZZ)
sage: R2.<a,b> = InfinitePolynomialRing(QQ)
sage: (1 + x[2]).is_unit()
False
sage: R1(1).is_unit()
True
sage: R1(2).is_unit()
False
sage: R2(2).is_unit()
True
sage: (1 + a[2]).is_unit()
False
>>> from sage.all import *
>>> R1 = InfinitePolynomialRing(ZZ, names=('x', 'y',)); (x, y,) = R1._first_ngens(2)
>>> R2 = InfinitePolynomialRing(QQ, names=('a', 'b',)); (a, b,) = R2._first_ngens(2)
>>> (Integer(1) + x[Integer(2)]).is_unit()
False
>>> R1(Integer(1)).is_unit()
True
>>> R1(Integer(2)).is_unit()
False
>>> R2(Integer(2)).is_unit()
True
>>> (Integer(1) + a[Integer(2)]).is_unit()
False
R1.<x,y> = InfinitePolynomialRing(ZZ)
R2.<a,b> = InfinitePolynomialRing(QQ)
(1 + x[2]).is_unit()
R1(1).is_unit()
R1(2).is_unit()
R2(2).is_unit()
(1 + a[2]).is_unit()

Check that Issue #22454 is fixed:

sage: _.<x> = InfinitePolynomialRing(Zmod(4))
sage: (1 + 2*x[0]).is_unit()
True
sage: (x[0]*x[1]).is_unit()
False
sage: _.<x> = InfinitePolynomialRing(Zmod(900))
sage: (7+150*x[0] + 30*x[1] + 120*x[1]*x[100]).is_unit()
True
>>> from sage.all import *
>>> _ = InfinitePolynomialRing(Zmod(Integer(4)), names=('x',)); (x,) = _._first_ngens(1)
>>> (Integer(1) + Integer(2)*x[Integer(0)]).is_unit()
True
>>> (x[Integer(0)]*x[Integer(1)]).is_unit()
False
>>> _ = InfinitePolynomialRing(Zmod(Integer(900)), names=('x',)); (x,) = _._first_ngens(1)
>>> (Integer(7)+Integer(150)*x[Integer(0)] + Integer(30)*x[Integer(1)] + Integer(120)*x[Integer(1)]*x[Integer(100)]).is_unit()
True
_.<x> = InfinitePolynomialRing(Zmod(4))
(1 + 2*x[0]).is_unit()
(x[0]*x[1]).is_unit()
_.<x> = InfinitePolynomialRing(Zmod(900))
(7+150*x[0] + 30*x[1] + 120*x[1]*x[100]).is_unit()
lc()[source]

The coefficient of the leading term of self.

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
sage: p.lc()
3
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = Integer(2)*x[Integer(10)]*y[Integer(30)] + Integer(3)*x[Integer(10)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2)
>>> p.lc()
3
X.<x,y> = InfinitePolynomialRing(QQ)
p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
p.lc()
lm()[source]

The leading monomial of self.

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = 2*x[10]*y[30] + x[10]*y[1]^3*x[1]^2
sage: p.lm()
x_10*x_1^2*y_1^3
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = Integer(2)*x[Integer(10)]*y[Integer(30)] + x[Integer(10)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2)
>>> p.lm()
x_10*x_1^2*y_1^3
X.<x,y> = InfinitePolynomialRing(QQ)
p = 2*x[10]*y[30] + x[10]*y[1]^3*x[1]^2
p.lm()
lt()[source]

The leading term (= product of coefficient and monomial) of self.

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
sage: p.lt()
3*x_10*x_1^2*y_1^3
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = Integer(2)*x[Integer(10)]*y[Integer(30)] + Integer(3)*x[Integer(10)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2)
>>> p.lt()
3*x_10*x_1^2*y_1^3
X.<x,y> = InfinitePolynomialRing(QQ)
p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
p.lt()
max_index()[source]

Return the maximal index of a variable occurring in self, or -1 if self is scalar.

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4]
sage: p.max_index()
4
sage: x[0].max_index()
0
sage: X(10).max_index()
-1
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = x[Integer(1)]**Integer(2) + y[Integer(2)]**Integer(2) + x[Integer(1)]*x[Integer(2)]*y[Integer(3)] + x[Integer(1)]*y[Integer(4)]
>>> p.max_index()
4
>>> x[Integer(0)].max_index()
0
>>> X(Integer(10)).max_index()
-1
X.<x,y> = InfinitePolynomialRing(QQ)
p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4]
p.max_index()
x[0].max_index()
X(10).max_index()
monomial_coefficient(mon)[source]

Return the base ring element that is the coefficient of mon in self.

This function contrasts with the function coefficient(), which returns the coefficient of a monomial viewing this polynomial in a polynomial ring over a base ring having fewer variables.

INPUT:

  • mon – a monomial in the parent of self

OUTPUT: coefficient in base ring

See also

For coefficients in a base ring of fewer variables, look at coefficient().

EXAMPLES:

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: f = 2*x[0]*x[2] + 3*x[1]^2
sage: c = f.monomial_coefficient(x[1]^2); c
3
sage: c.parent()
Rational Field

sage: c = f.coefficient(x[2]); c
2*x_0
sage: c.parent()
Infinite polynomial ring in x over Rational Field
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x',)); (x,) = X._first_ngens(1)
>>> f = Integer(2)*x[Integer(0)]*x[Integer(2)] + Integer(3)*x[Integer(1)]**Integer(2)
>>> c = f.monomial_coefficient(x[Integer(1)]**Integer(2)); c
3
>>> c.parent()
Rational Field

>>> c = f.coefficient(x[Integer(2)]); c
2*x_0
>>> c.parent()
Infinite polynomial ring in x over Rational Field
X.<x> = InfinitePolynomialRing(QQ)
f = 2*x[0]*x[2] + 3*x[1]^2
c = f.monomial_coefficient(x[1]^2); c
c.parent()
c = f.coefficient(x[2]); c
c.parent()
monomials()[source]

Return the list of monomials in self.

The returned list is decreasingly ordered by the term ordering of self.parent().

EXAMPLES:

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: p = x[1]^3 + x[2] - 2*x[1]*x[3]
sage: p.monomials()
[x_3*x_1, x_2, x_1^3]

sage: X.<x> = InfinitePolynomialRing(QQ, order='deglex')
sage: p = x[1]^3 + x[2] - 2*x[1]*x[3]
sage: p.monomials()
[x_1^3, x_3*x_1, x_2]
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x',)); (x,) = X._first_ngens(1)
>>> p = x[Integer(1)]**Integer(3) + x[Integer(2)] - Integer(2)*x[Integer(1)]*x[Integer(3)]
>>> p.monomials()
[x_3*x_1, x_2, x_1^3]

>>> X = InfinitePolynomialRing(QQ, order='deglex', names=('x',)); (x,) = X._first_ngens(1)
>>> p = x[Integer(1)]**Integer(3) + x[Integer(2)] - Integer(2)*x[Integer(1)]*x[Integer(3)]
>>> p.monomials()
[x_1^3, x_3*x_1, x_2]
X.<x> = InfinitePolynomialRing(QQ)
p = x[1]^3 + x[2] - 2*x[1]*x[3]
p.monomials()
X.<x> = InfinitePolynomialRing(QQ, order='deglex')
p = x[1]^3 + x[2] - 2*x[1]*x[3]
p.monomials()
numerator()[source]

Return a numerator of self, computed as self * self.denominator().

Warning

This is not the numerator of the rational function defined by self, which would always be self since it is a polynomial.

EXAMPLES:

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: p = 2/3*x[1] + 4/9*x[2] - 2*x[1]*x[3]
sage: num = p.numerator(); num
-18*x_3*x_1 + 4*x_2 + 6*x_1
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x',)); (x,) = X._first_ngens(1)
>>> p = Integer(2)/Integer(3)*x[Integer(1)] + Integer(4)/Integer(9)*x[Integer(2)] - Integer(2)*x[Integer(1)]*x[Integer(3)]
>>> num = p.numerator(); num
-18*x_3*x_1 + 4*x_2 + 6*x_1
X.<x> = InfinitePolynomialRing(QQ)
p = 2/3*x[1] + 4/9*x[2] - 2*x[1]*x[3]
num = p.numerator(); num
polynomial()[source]

Return the underlying polynomial.

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(GF(7))
sage: p = x[2]*y[1] + 3*y[0]
sage: p
x_2*y_1 + 3*y_0
sage: p.polynomial()
x_2*y_1 + 3*y_0
sage: p.polynomial().parent()
Multivariate Polynomial Ring in x_2, x_1, x_0, y_2, y_1, y_0
 over Finite Field of size 7
sage: p.parent()
Infinite polynomial ring in x, y over Finite Field of size 7
>>> from sage.all import *
>>> X = InfinitePolynomialRing(GF(Integer(7)), names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = x[Integer(2)]*y[Integer(1)] + Integer(3)*y[Integer(0)]
>>> p
x_2*y_1 + 3*y_0
>>> p.polynomial()
x_2*y_1 + 3*y_0
>>> p.polynomial().parent()
Multivariate Polynomial Ring in x_2, x_1, x_0, y_2, y_1, y_0
 over Finite Field of size 7
>>> p.parent()
Infinite polynomial ring in x, y over Finite Field of size 7
X.<x,y> = InfinitePolynomialRing(GF(7))
p = x[2]*y[1] + 3*y[0]
p
p.polynomial()
p.polynomial().parent()
p.parent()
reduce(I, tailreduce=False, report=None)[source]

Symmetrical reduction of self with respect to a symmetric ideal (or list of Infinite Polynomials).

INPUT:

  • I – a SymmetricIdeal or a list of Infinite Polynomials

  • tailreduce – boolean (default: False); tail reduction is performed if this parameter is True.

  • report – object (default: None); if not None, some information on the progress of computation is printed, since reduction of huge polynomials may take a long time

OUTPUT: symmetrical reduction of self with respect to I, possibly with tail reduction

THEORY:

Reducing an element \(p\) of an Infinite Polynomial Ring \(X\) by some other element \(q\) means the following:

  1. Let \(M\) and \(N\) be the leading terms of \(p\) and \(q\).

  2. Test whether there is a permutation \(P\) that does not does not diminish the variable indices occurring in \(N\) and preserves their order, so that there is some term \(T\in X\) with \(TN^P = M\). If there is no such permutation, return \(p\)

  3. Replace \(p\) by \(p-T q^P\) and continue with step 1.

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = y[1]^2*y[3] + y[2]*x[3]^3
sage: p.reduce([y[2]*x[1]^2])
x_3^3*y_2 + y_3*y_1^2
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = y[Integer(1)]**Integer(2)*y[Integer(3)] + y[Integer(2)]*x[Integer(3)]**Integer(3)
>>> p.reduce([y[Integer(2)]*x[Integer(1)]**Integer(2)])
x_3^3*y_2 + y_3*y_1^2
X.<x,y> = InfinitePolynomialRing(QQ)
p = y[1]^2*y[3] + y[2]*x[3]^3
p.reduce([y[2]*x[1]^2])

The preceding is correct: If a permutation turns y[2]*x[1]^2 into a factor of the leading monomial y[2]*x[3]^3 of p, then it interchanges the variable indices 1 and 2; this is not allowed in a symmetric reduction. However, reduction by y[1]*x[2]^2 works, since one can change variable index 1 into 2 and 2 into 3:

sage: p.reduce([y[1]*x[2]^2])                                               # needs sage.libs.singular
y_3*y_1^2
>>> from sage.all import *
>>> p.reduce([y[Integer(1)]*x[Integer(2)]**Integer(2)])                                               # needs sage.libs.singular
y_3*y_1^2
p.reduce([y[1]*x[2]^2])                                               # needs sage.libs.singular

The next example shows that tail reduction is not done, unless it is explicitly advised. The input can also be a Symmetric Ideal:

sage: I = (y[3])*X
sage: p.reduce(I)
x_3^3*y_2 + y_3*y_1^2
sage: p.reduce(I, tailreduce=True)                                          # needs sage.libs.singular
x_3^3*y_2
>>> from sage.all import *
>>> I = (y[Integer(3)])*X
>>> p.reduce(I)
x_3^3*y_2 + y_3*y_1^2
>>> p.reduce(I, tailreduce=True)                                          # needs sage.libs.singular
x_3^3*y_2
I = (y[3])*X
p.reduce(I)
p.reduce(I, tailreduce=True)                                          # needs sage.libs.singular

Last, we demonstrate the report option:

sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4]
sage: p.reduce(I, tailreduce=True, report=True)                             # needs sage.libs.singular
:T[2]:>
>
x_1^2 + y_2^2
>>> from sage.all import *
>>> p = x[Integer(1)]**Integer(2) + y[Integer(2)]**Integer(2) + x[Integer(1)]*x[Integer(2)]*y[Integer(3)] + x[Integer(1)]*y[Integer(4)]
>>> p.reduce(I, tailreduce=True, report=True)                             # needs sage.libs.singular
:T[2]:>
>
x_1^2 + y_2^2
p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4]
p.reduce(I, tailreduce=True, report=True)                             # needs sage.libs.singular

The output ‘:’ means that there was one reduction of the leading monomial. ‘T[2]’ means that a tail reduction was performed on a polynomial with two terms. At ‘>’, one round of the reduction process is finished (there could only be several non-trivial rounds if \(I\) was generated by more than one polynomial).

ring()[source]

The ring which self belongs to.

This is the same as self.parent().

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(ZZ,implementation='sparse')
sage: p = x[100]*y[1]^3*x[1]^2 + 2*x[10]*y[30]
sage: p.ring()
Infinite polynomial ring in x, y over Integer Ring
>>> from sage.all import *
>>> X = InfinitePolynomialRing(ZZ,implementation='sparse', names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = x[Integer(100)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2) + Integer(2)*x[Integer(10)]*y[Integer(30)]
>>> p.ring()
Infinite polynomial ring in x, y over Integer Ring
X.<x,y> = InfinitePolynomialRing(ZZ,implementation='sparse')
p = x[100]*y[1]^3*x[1]^2 + 2*x[10]*y[30]
p.ring()
squeezed()[source]

Reduce the variable indices occurring in self.

OUTPUT:

Apply a permutation to self that does not change the order of the variable indices of self but squeezes them into the range 1,2,…

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ,implementation='sparse')
sage: p = x[1]*y[100] + x[50]*y[1000]
sage: p.squeezed()
x_2*y_4 + x_1*y_3
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ,implementation='sparse', names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = x[Integer(1)]*y[Integer(100)] + x[Integer(50)]*y[Integer(1000)]
>>> p.squeezed()
x_2*y_4 + x_1*y_3
X.<x,y> = InfinitePolynomialRing(QQ,implementation='sparse')
p = x[1]*y[100] + x[50]*y[1000]
p.squeezed()
stretch(k)[source]

Stretch self by a given factor.

INPUT:

  • k – integer

OUTPUT: replace \(v_n\) with \(v_{n\cdot k}\) for all generators \(v_\ast\) occurring in self

EXAMPLES:

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: a = x[0] + x[1] + x[2]
sage: a.stretch(2)
x_4 + x_2 + x_0

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: a = x[0] + x[1] + y[0]*y[1]; a
x_1 + x_0 + y_1*y_0
sage: a.stretch(2)
x_2 + x_0 + y_2*y_0
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x',)); (x,) = X._first_ngens(1)
>>> a = x[Integer(0)] + x[Integer(1)] + x[Integer(2)]
>>> a.stretch(Integer(2))
x_4 + x_2 + x_0

>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> a = x[Integer(0)] + x[Integer(1)] + y[Integer(0)]*y[Integer(1)]; a
x_1 + x_0 + y_1*y_0
>>> a.stretch(Integer(2))
x_2 + x_0 + y_2*y_0
X.<x> = InfinitePolynomialRing(QQ)
a = x[0] + x[1] + x[2]
a.stretch(2)
X.<x,y> = InfinitePolynomialRing(QQ)
a = x[0] + x[1] + y[0]*y[1]; a
a.stretch(2)
subs(fixed=None, **kwargs)[source]

Substitute variables in self.

INPUT:

  • fixed – (optional) dict with {variable: value} pairs

  • **kwargs – named parameters

OUTPUT: the resulting substitution

EXAMPLES:

sage: R.<x,y> = InfinitePolynomialRing(QQ)
sage: f = x[1] + x[1]*x[2]*x[3]
>>> from sage.all import *
>>> R = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
>>> f = x[Integer(1)] + x[Integer(1)]*x[Integer(2)]*x[Integer(3)]
R.<x,y> = InfinitePolynomialRing(QQ)
f = x[1] + x[1]*x[2]*x[3]

Passing fixed={x[1]: x[0]}. Note that the keys may be given using the generators of the infinite polynomial ring or as a string:

sage: f.subs({x[1]: x[0]})
x_3*x_2*x_0 + x_0
sage: f.subs({'x_1': x[0]})
x_3*x_2*x_0 + x_0
>>> from sage.all import *
>>> f.subs({x[Integer(1)]: x[Integer(0)]})
x_3*x_2*x_0 + x_0
>>> f.subs({'x_1': x[Integer(0)]})
x_3*x_2*x_0 + x_0
f.subs({x[1]: x[0]})
f.subs({'x_1': x[0]})

Passing the variables as names parameters:

sage: f.subs(x_1=y[1])
x_3*x_2*y_1 + y_1
sage: f.subs(x_1=y[1], x_2=2)
2*x_3*y_1 + y_1
>>> from sage.all import *
>>> f.subs(x_1=y[Integer(1)])
x_3*x_2*y_1 + y_1
>>> f.subs(x_1=y[Integer(1)], x_2=Integer(2))
2*x_3*y_1 + y_1
f.subs(x_1=y[1])
f.subs(x_1=y[1], x_2=2)

The substitution returns the original polynomial if you try to substitute a variable not present:

sage: g = x[0] + x[1]
sage: g.subs({y[0]: x[0]})
x_1 + x_0
>>> from sage.all import *
>>> g = x[Integer(0)] + x[Integer(1)]
>>> g.subs({y[Integer(0)]: x[Integer(0)]})
x_1 + x_0
g = x[0] + x[1]
g.subs({y[0]: x[0]})

The substitution can also handle matrices:

sage: # needs sage.modules
sage: M = matrix([[1,0], [0,2]])
sage: N = matrix([[0,3], [4,0]])
sage: g = x[0]^2 + 3*x[1]
sage: g.subs({'x_0': M})
[3*x_1 + 1         0]
[        0 3*x_1 + 4]
sage: g.subs({x[0]: M, x[1]: N})
[ 1  9]
[12  4]
>>> from sage.all import *
>>> # needs sage.modules
>>> M = matrix([[Integer(1),Integer(0)], [Integer(0),Integer(2)]])
>>> N = matrix([[Integer(0),Integer(3)], [Integer(4),Integer(0)]])
>>> g = x[Integer(0)]**Integer(2) + Integer(3)*x[Integer(1)]
>>> g.subs({'x_0': M})
[3*x_1 + 1         0]
[        0 3*x_1 + 4]
>>> g.subs({x[Integer(0)]: M, x[Integer(1)]: N})
[ 1  9]
[12  4]
# needs sage.modules
M = matrix([[1,0], [0,2]])
N = matrix([[0,3], [4,0]])
g = x[0]^2 + 3*x[1]
g.subs({'x_0': M})
g.subs({x[0]: M, x[1]: N})

If you pass both fixed and kwargs, any conflicts will defer to fixed:

sage: R.<x,y> = InfinitePolynomialRing(QQ)
sage: f = x[0]
sage: f.subs({x[0]: 1})
1
sage: f.subs(x_0=5)
5
sage: f.subs({x[0]: 1}, x_0=5)
1
>>> from sage.all import *
>>> R = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
>>> f = x[Integer(0)]
>>> f.subs({x[Integer(0)]: Integer(1)})
1
>>> f.subs(x_0=Integer(5))
5
>>> f.subs({x[Integer(0)]: Integer(1)}, x_0=Integer(5))
1
R.<x,y> = InfinitePolynomialRing(QQ)
f = x[0]
f.subs({x[0]: 1})
f.subs(x_0=5)
f.subs({x[0]: 1}, x_0=5)
symmetric_cancellation_order(other)[source]

Comparison of leading terms by Symmetric Cancellation Order, \(<_{sc}\).

INPUT:

  • self, other – two Infinite Polynomials

ASSUMPTION:

Both Infinite Polynomials are nonzero.

OUTPUT:

(c, sigma, w), where

  • c = -1,0,1, or None if the leading monomial of self is smaller, equal, greater, or incomparable with respect to other in the monomial ordering of the Infinite Polynomial Ring

  • sigma is a permutation witnessing self \(<_{sc}\) other (resp. self \(>_{sc}\) other) or is 1 if self.lm()==other.lm()

  • w is 1 or is a term so that w*self.lt()^sigma == other.lt() if \(c\le 0\), and w*other.lt()^sigma == self.lt() if \(c=1\)

THEORY:

If the Symmetric Cancellation Order is a well-quasi-ordering then computation of Groebner bases always terminates. This is the case, e.g., if the monomial order is lexicographic. For that reason, lexicographic order is our default order.

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]^2)
(None, 1, 1)
sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]*x[3]*y[1])
(-1, [2, 3, 1], y_1)
sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[1])
(None, 1, 1)
sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2])
(-1, [2, 3, 1], 1)
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> (x[Integer(2)]*x[Integer(1)]).symmetric_cancellation_order(x[Integer(2)]**Integer(2))
(None, 1, 1)
>>> (x[Integer(2)]*x[Integer(1)]).symmetric_cancellation_order(x[Integer(2)]*x[Integer(3)]*y[Integer(1)])
(-1, [2, 3, 1], y_1)
>>> (x[Integer(2)]*x[Integer(1)]*y[Integer(1)]).symmetric_cancellation_order(x[Integer(2)]*x[Integer(3)]*y[Integer(1)])
(None, 1, 1)
>>> (x[Integer(2)]*x[Integer(1)]*y[Integer(1)]).symmetric_cancellation_order(x[Integer(2)]*x[Integer(3)]*y[Integer(2)])
(-1, [2, 3, 1], 1)
X.<x,y> = InfinitePolynomialRing(QQ)
(x[2]*x[1]).symmetric_cancellation_order(x[2]^2)
(x[2]*x[1]).symmetric_cancellation_order(x[2]*x[3]*y[1])
(x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[1])
(x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2])
tail()[source]

The tail of self (this is self minus its leading term).

EXAMPLES:

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
sage: p.tail()
2*x_10*y_30
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> p = Integer(2)*x[Integer(10)]*y[Integer(30)] + Integer(3)*x[Integer(10)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2)
>>> p.tail()
2*x_10*y_30
X.<x,y> = InfinitePolynomialRing(QQ)
p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
p.tail()
variables()[source]

Return the variables occurring in self (tuple of elements of some polynomial ring).

EXAMPLES:

sage: X.<x> = InfinitePolynomialRing(QQ)
sage: p = x[1] + x[2] - 2*x[1]*x[3]
sage: p.variables()
(x_3, x_2, x_1)
sage: x[1].variables()
(x_1,)
sage: X(1).variables()
()
>>> from sage.all import *
>>> X = InfinitePolynomialRing(QQ, names=('x',)); (x,) = X._first_ngens(1)
>>> p = x[Integer(1)] + x[Integer(2)] - Integer(2)*x[Integer(1)]*x[Integer(3)]
>>> p.variables()
(x_3, x_2, x_1)
>>> x[Integer(1)].variables()
(x_1,)
>>> X(Integer(1)).variables()
()
X.<x> = InfinitePolynomialRing(QQ)
p = x[1] + x[2] - 2*x[1]*x[3]
p.variables()
x[1].variables()
X(1).variables()
class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense(A, p)[source]

Bases: InfinitePolynomial

Element of a dense Polynomial Ring with a Countably Infinite Number of Variables.

INPUT:

  • A – an Infinite Polynomial Ring in dense implementation

  • p – a classical polynomial that can be interpreted in A

Of course, one should not directly invoke this class, but rather construct elements of A in the usual way.

class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_sparse(A, p)[source]

Bases: InfinitePolynomial

Element of a sparse Polynomial Ring with a Countably Infinite Number of Variables.

INPUT:

  • A – an Infinite Polynomial Ring in sparse implementation

  • p – a classical polynomial that can be interpreted in A

Of course, one should not directly invoke this class, but rather construct elements of A in the usual way.

EXAMPLES:

sage: A.<a> = QQ[]
sage: B.<b,c> = InfinitePolynomialRing(A,implementation='sparse')
sage: p = a*b[100] + 1/2*c[4]
sage: p
a*b_100 + 1/2*c_4
sage: p.parent()
Infinite polynomial ring in b, c
 over Univariate Polynomial Ring in a over Rational Field
sage: p.polynomial().parent()
Multivariate Polynomial Ring in b_100, b_0, c_4, c_0
 over Univariate Polynomial Ring in a over Rational Field
>>> from sage.all import *
>>> A = QQ['a']; (a,) = A._first_ngens(1)
>>> B = InfinitePolynomialRing(A,implementation='sparse', names=('b', 'c',)); (b, c,) = B._first_ngens(2)
>>> p = a*b[Integer(100)] + Integer(1)/Integer(2)*c[Integer(4)]
>>> p
a*b_100 + 1/2*c_4
>>> p.parent()
Infinite polynomial ring in b, c
 over Univariate Polynomial Ring in a over Rational Field
>>> p.polynomial().parent()
Multivariate Polynomial Ring in b_100, b_0, c_4, c_0
 over Univariate Polynomial Ring in a over Rational Field
A.<a> = QQ[]
B.<b,c> = InfinitePolynomialRing(A,implementation='sparse')
p = a*b[100] + 1/2*c[4]
p
p.parent()
p.polynomial().parent()