Elements of Infinite Polynomial Rings¶
AUTHORS:
Simon King <simon.king@nuigalway.ie>
Mike Hansen <mhansen@gmail.com>
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
, ori==j
andm>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 Ringp
– a classical polynomial that can be interpreted inA
ASSUMPTIONS:
In the dense implementation, it must be ensured that the argument
p
coerces intoA._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 inA
.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
andX._P
(the underlying polynomial ring ofX
) 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
toX._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 indicesD[s]
is a list[i_1,...,i_n]
, wherei_j
gives the exponent ofself.parent().gen(j)[s]
in the leading term ofself
.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
ifself
is nilpotent, i.e., some power ofself
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 ifself
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
inself
.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 ofself
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 asself * self.denominator()
.Warning
This is not the numerator of the rational function defined by
self
, which would always beself
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
– aSymmetricIdeal
or a list of Infinite Polynomialstailreduce
– boolean (default:False
); tail reduction is performed if this parameter isTrue
.report
– object (default:None
); if notNone
, 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 toI
, possibly with tail reductionTHEORY:
Reducing an element \(p\) of an Infinite Polynomial Ring \(X\) by some other element \(q\) means the following:
Let \(M\) and \(N\) be the leading terms of \(p\) and \(q\).
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\)
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 monomialy[2]*x[3]^3
ofp
, then it interchanges the variable indices 1 and 2; this is not allowed in a symmetric reduction. However, reduction byy[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 ofself
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
andkwargs
, any conflicts will defer tofixed
: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)
, wherec = -1,0,1, or None if the leading monomial of
self
is smaller, equal, greater, or incomparable with respect toother
in the monomial ordering of the Infinite Polynomial Ringsigma is a permutation witnessing
self
\(<_{sc}\)other
(resp.self
\(>_{sc}\)other
) or is 1 ifself.lm()==other.lm()
w is 1 or is a term so that
w*self.lt()^sigma == other.lt()
if \(c\le 0\), andw*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 isself
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 implementationp
– a classical polynomial that can be interpreted inA
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 implementationp
– a classical polynomial that can be interpreted inA
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()