Infinite Polynomial Rings¶
By Infinite Polynomial Rings, we mean polynomial rings in a countably infinite number of variables. The implementation consists of a wrapper around the current finite polynomial rings in Sage.
AUTHORS:
Simon King <simon.king@nuigalway.ie>
Mike Hansen <mhansen@gmail.com>
An Infinite Polynomial Ring has finitely many generators \(x_\ast, y_\ast,...\) and infinitely many variables of the form \(x_0, x_1, x_2, ..., y_0, y_1, y_2,...,...\). We refer to the natural number \(n\) as the index of the variable \(x_n\).
INPUT:
R
– the base ring; it has to be a commutative ring, and in some applications it must even be a fieldnames
– a finite list of generator names; generator names must be alpha-numericorder
– (optional) string; the default order is'lex'
(lexicographic).'deglex'
is degree lexicographic, and'degrevlex'
(degree reverse lexicographic) is possible but discouraged.
Each generator x
produces an infinite sequence of variables
x[1], x[2], ...
which are printed on screen as x_1, x_2, ...
and are latex typeset as \(x_{1}, x_{2}\). Then, the Infinite
Polynomial Ring is formed by polynomials in these variables.
By default, the monomials are ordered lexicographically. Alternatively, degree (reverse) lexicographic ordering is possible as well. However, we do not guarantee that the computation of Groebner bases will terminate in this case.
In either case, the variables of a Infinite Polynomial Ring X are ordered according to the following rule:
X.gen(i)[m] > X.gen(j)[n]
if and only ifi<j or (i==j and m>n)
We provide a ‘dense’ and a ‘sparse’ implementation. In the dense implementation, the Infinite Polynomial Ring carries a finite polynomial ring that comprises all variables up to the maximal index that has been used so far. This is potentially a very big ring and may also comprise many variables that are not used.
In the sparse implementation, we try to keep the underlying finite polynomial rings small, using only those variables that are really needed. By default, we use the dense implementation, since it usually is much faster.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(ZZ, implementation='sparse')
sage: A.<alpha,beta> = InfinitePolynomialRing(QQ, order='deglex')
sage: f = x[5] + 2; f
x_5 + 2
sage: g = 3*y[1]; g
3*y_1
>>> from sage.all import *
>>> X = InfinitePolynomialRing(ZZ, implementation='sparse', names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> A = InfinitePolynomialRing(QQ, order='deglex', names=('alpha', 'beta',)); (alpha, beta,) = A._first_ngens(2)
>>> f = x[Integer(5)] + Integer(2); f
x_5 + 2
>>> g = Integer(3)*y[Integer(1)]; g
3*y_1
X.<x,y> = InfinitePolynomialRing(ZZ, implementation='sparse') A.<alpha,beta> = InfinitePolynomialRing(QQ, order='deglex') f = x[5] + 2; f g = 3*y[1]; g
It has some advantages to have an underlying ring that is not univariate. Hence, we always have at least two variables:
sage: g._p.parent()
Multivariate Polynomial Ring in y_1, y_0 over Integer Ring
sage: f2 = alpha[5] + 2; f2
alpha_5 + 2
sage: g2 = 3*beta[1]; g2
3*beta_1
sage: A.polynomial_ring()
Multivariate Polynomial Ring in alpha_5, alpha_4, alpha_3, alpha_2, alpha_1, alpha_0,
beta_5, beta_4, beta_3, beta_2, beta_1, beta_0 over Rational Field
>>> from sage.all import *
>>> g._p.parent()
Multivariate Polynomial Ring in y_1, y_0 over Integer Ring
>>> f2 = alpha[Integer(5)] + Integer(2); f2
alpha_5 + 2
>>> g2 = Integer(3)*beta[Integer(1)]; g2
3*beta_1
>>> A.polynomial_ring()
Multivariate Polynomial Ring in alpha_5, alpha_4, alpha_3, alpha_2, alpha_1, alpha_0,
beta_5, beta_4, beta_3, beta_2, beta_1, beta_0 over Rational Field
g._p.parent() f2 = alpha[5] + 2; f2 g2 = 3*beta[1]; g2 A.polynomial_ring()
Of course, we provide the usual polynomial arithmetic:
sage: f + g
x_5 + 3*y_1 + 2
sage: p = x[10]^2*(f+g); p
x_10^2*x_5 + 3*x_10^2*y_1 + 2*x_10^2
sage: p2 = alpha[10]^2*(f2+g2); p2
alpha_10^2*alpha_5 + 3*alpha_10^2*beta_1 + 2*alpha_10^2
>>> from sage.all import *
>>> f + g
x_5 + 3*y_1 + 2
>>> p = x[Integer(10)]**Integer(2)*(f+g); p
x_10^2*x_5 + 3*x_10^2*y_1 + 2*x_10^2
>>> p2 = alpha[Integer(10)]**Integer(2)*(f2+g2); p2
alpha_10^2*alpha_5 + 3*alpha_10^2*beta_1 + 2*alpha_10^2
f + g p = x[10]^2*(f+g); p p2 = alpha[10]^2*(f2+g2); p2
There is a permutation action on the variables, by permuting positive variable indices:
sage: P = Permutation(((10,1)))
sage: p^P
x_5*x_1^2 + 3*x_1^2*y_10 + 2*x_1^2
sage: p2^P
alpha_5*alpha_1^2 + 3*alpha_1^2*beta_10 + 2*alpha_1^2
>>> from sage.all import *
>>> P = Permutation(((Integer(10),Integer(1))))
>>> p**P
x_5*x_1^2 + 3*x_1^2*y_10 + 2*x_1^2
>>> p2**P
alpha_5*alpha_1^2 + 3*alpha_1^2*beta_10 + 2*alpha_1^2
P = Permutation(((10,1))) p^P p2^P
Note that \(x_0^P = x_0\), since the permutations only change positive variable indices.
We also implemented ideals of Infinite Polynomial Rings. Here, it is thoroughly assumed that the ideals are set-wise invariant under the permutation action. We therefore refer to these ideals as Symmetric Ideals. Symmetric Ideals are finitely generated modulo addition, multiplication by ring elements and permutation of variables. If the base ring is a field, one can compute Symmetric Groebner Bases:
sage: J = A * (alpha[1]*beta[2])
sage: J.groebner_basis() # needs sage.combinat sage.libs.singular
[alpha_1*beta_2, alpha_2*beta_1]
>>> from sage.all import *
>>> J = A * (alpha[Integer(1)]*beta[Integer(2)])
>>> J.groebner_basis() # needs sage.combinat sage.libs.singular
[alpha_1*beta_2, alpha_2*beta_1]
J = A * (alpha[1]*beta[2]) J.groebner_basis() # needs sage.combinat sage.libs.singular
For more details, see SymmetricIdeal
.
Infinite Polynomial Rings can have any commutative base ring. If the base ring of an Infinite Polynomial Ring is a (classical or infinite) Polynomial Ring, then our implementation tries to merge everything into one ring. The basic requirement is that the monomial orders match. In the case of two Infinite Polynomial Rings, the implementations must match. Moreover, name conflicts should be avoided. An overlap is only accepted if the order of variables can be uniquely inferred, as in the following example:
sage: A.<a,b,c> = InfinitePolynomialRing(ZZ)
sage: B.<b,c,d> = InfinitePolynomialRing(A)
sage: B
Infinite polynomial ring in a, b, c, d over Integer Ring
>>> from sage.all import *
>>> A = InfinitePolynomialRing(ZZ, names=('a', 'b', 'c',)); (a, b, c,) = A._first_ngens(3)
>>> B = InfinitePolynomialRing(A, names=('b', 'c', 'd',)); (b, c, d,) = B._first_ngens(3)
>>> B
Infinite polynomial ring in a, b, c, d over Integer Ring
A.<a,b,c> = InfinitePolynomialRing(ZZ) B.<b,c,d> = InfinitePolynomialRing(A) B
This is also allowed if finite polynomial rings are involved:
sage: A.<a_3,a_1,b_1,c_2,c_0> = ZZ[]
sage: B.<b,c,d> = InfinitePolynomialRing(A, order='degrevlex')
sage: B
Infinite polynomial ring in b, c, d over
Multivariate Polynomial Ring in a_3, a_1 over Integer Ring
>>> from sage.all import *
>>> A = ZZ['a_3, a_1, b_1, c_2, c_0']; (a_3, a_1, b_1, c_2, c_0,) = A._first_ngens(5)
>>> B = InfinitePolynomialRing(A, order='degrevlex', names=('b', 'c', 'd',)); (b, c, d,) = B._first_ngens(3)
>>> B
Infinite polynomial ring in b, c, d over
Multivariate Polynomial Ring in a_3, a_1 over Integer Ring
A.<a_3,a_1,b_1,c_2,c_0> = ZZ[] B.<b,c,d> = InfinitePolynomialRing(A, order='degrevlex') B
It is no problem if one generator of the Infinite Polynomial Ring is
called x
and one variable of the base ring is also called
x
. This is since no variable of the Infinite Polynomial Ring
will be called x
. However, a problem arises if the underlying
classical Polynomial Ring has a variable x_1
, since this can be
confused with a variable of the Infinite Polynomial Ring. In this
case, an error will be raised:
sage: X.<x,y_1> = ZZ[]
sage: Y.<x,z> = InfinitePolynomialRing(X)
>>> from sage.all import *
>>> X = ZZ['x, y_1']; (x, y_1,) = X._first_ngens(2)
>>> Y = InfinitePolynomialRing(X, names=('x', 'z',)); (x, z,) = Y._first_ngens(2)
X.<x,y_1> = ZZ[] Y.<x,z> = InfinitePolynomialRing(X)
Note that X
is not merged into Y
; this is since the monomial
order of X
is ‘degrevlex’, but of Y
is ‘lex’.
sage: Y
Infinite polynomial ring in x, z over
Multivariate Polynomial Ring in x, y_1 over Integer Ring
>>> from sage.all import *
>>> Y
Infinite polynomial ring in x, z over
Multivariate Polynomial Ring in x, y_1 over Integer Ring
Y
The variable x
of X
can still be interpreted in Y
,
although the first generator of Y
is called x
as well:
sage: x
x_*
sage: X('x')
x
sage: Y(X('x'))
x
sage: Y('x')
x
>>> from sage.all import *
>>> x
x_*
>>> X('x')
x
>>> Y(X('x'))
x
>>> Y('x')
x
x X('x') Y(X('x')) Y('x')
But there is only merging if the resulting monomial order is uniquely determined. This is not the case in the following examples, and thus an error is raised:
sage: X.<y_1,x> = ZZ[]
sage: Y.<y,z> = InfinitePolynomialRing(X)
Traceback (most recent call last):
...
CoercionException: Overlapping variables (('y', 'z'),['y_1']) are incompatible
sage: Y.<z,y> = InfinitePolynomialRing(X)
Traceback (most recent call last):
...
CoercionException: Overlapping variables (('z', 'y'),['y_1']) are incompatible
sage: X.<x_3,y_1,y_2> = PolynomialRing(ZZ, order='lex')
sage: # y_1 and y_2 would be in opposite order in an Infinite Polynomial Ring
sage: Y.<y> = InfinitePolynomialRing(X)
Traceback (most recent call last):
...
CoercionException: Overlapping variables (('y',),['y_1', 'y_2']) are incompatible
>>> from sage.all import *
>>> X = ZZ['y_1, x']; (y_1, x,) = X._first_ngens(2)
>>> Y = InfinitePolynomialRing(X, names=('y', 'z',)); (y, z,) = Y._first_ngens(2)
Traceback (most recent call last):
...
CoercionException: Overlapping variables (('y', 'z'),['y_1']) are incompatible
>>> Y = InfinitePolynomialRing(X, names=('z', 'y',)); (z, y,) = Y._first_ngens(2)
Traceback (most recent call last):
...
CoercionException: Overlapping variables (('z', 'y'),['y_1']) are incompatible
>>> X = PolynomialRing(ZZ, order='lex', names=('x_3', 'y_1', 'y_2',)); (x_3, y_1, y_2,) = X._first_ngens(3)
>>> # y_1 and y_2 would be in opposite order in an Infinite Polynomial Ring
>>> Y = InfinitePolynomialRing(X, names=('y',)); (y,) = Y._first_ngens(1)
Traceback (most recent call last):
...
CoercionException: Overlapping variables (('y',),['y_1', 'y_2']) are incompatible
X.<y_1,x> = ZZ[] Y.<y,z> = InfinitePolynomialRing(X) Y.<z,y> = InfinitePolynomialRing(X) X.<x_3,y_1,y_2> = PolynomialRing(ZZ, order='lex') # y_1 and y_2 would be in opposite order in an Infinite Polynomial Ring Y.<y> = InfinitePolynomialRing(X)
If the type of monomial orderings (e.g., ‘degrevlex’ versus ‘lex’) or if the implementations do not match, there is no simplified construction available:
sage: X.<x,y> = InfinitePolynomialRing(ZZ)
sage: Y.<z> = InfinitePolynomialRing(X, order='degrevlex')
sage: Y
Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ring
sage: Y.<z> = InfinitePolynomialRing(X, implementation='sparse')
sage: Y
Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ring
>>> from sage.all import *
>>> X = InfinitePolynomialRing(ZZ, names=('x', 'y',)); (x, y,) = X._first_ngens(2)
>>> Y = InfinitePolynomialRing(X, order='degrevlex', names=('z',)); (z,) = Y._first_ngens(1)
>>> Y
Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ring
>>> Y = InfinitePolynomialRing(X, implementation='sparse', names=('z',)); (z,) = Y._first_ngens(1)
>>> Y
Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ring
X.<x,y> = InfinitePolynomialRing(ZZ) Y.<z> = InfinitePolynomialRing(X, order='degrevlex') Y Y.<z> = InfinitePolynomialRing(X, implementation='sparse') Y
- class sage.rings.polynomial.infinite_polynomial_ring.GenDictWithBasering(parent, start)[source]¶
Bases:
object
A dictionary-like class that is suitable for usage in
sage_eval
.This pseudo-dictionary accepts strings as index, and then walks down a chain of base rings of (infinite) polynomial rings until it finds one ring that has the given string as variable name, which is then returned.
EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(ZZ) sage: D = R.gens_dict() # indirect doctest sage: D GenDict of Infinite polynomial ring in a, b over Integer Ring sage: D['a_15'] a_15 sage: type(_) <class 'sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense'> sage: sage_eval('3*a_3*b_5-1/2*a_7', D) -1/2*a_7 + 3*a_3*b_5
>>> from sage.all import * >>> R = InfinitePolynomialRing(ZZ, names=('a', 'b',)); (a, b,) = R._first_ngens(2) >>> D = R.gens_dict() # indirect doctest >>> D GenDict of Infinite polynomial ring in a, b over Integer Ring >>> D['a_15'] a_15 >>> type(_) <class 'sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense'> >>> sage_eval('3*a_3*b_5-1/2*a_7', D) -1/2*a_7 + 3*a_3*b_5
R.<a,b> = InfinitePolynomialRing(ZZ) D = R.gens_dict() # indirect doctest D D['a_15'] type(_) sage_eval('3*a_3*b_5-1/2*a_7', D)
- next()[source]¶
Return a dictionary that can be used to interpret strings in the base ring of
self
.EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(QQ['t']) sage: D = R.gens_dict() sage: D GenDict of Infinite polynomial ring in a, b over Univariate Polynomial Ring in t over Rational Field sage: next(D) GenDict of Univariate Polynomial Ring in t over Rational Field sage: sage_eval('t^2', next(D)) t^2
>>> from sage.all import * >>> R = InfinitePolynomialRing(QQ['t'], names=('a', 'b',)); (a, b,) = R._first_ngens(2) >>> D = R.gens_dict() >>> D GenDict of Infinite polynomial ring in a, b over Univariate Polynomial Ring in t over Rational Field >>> next(D) GenDict of Univariate Polynomial Ring in t over Rational Field >>> sage_eval('t^2', next(D)) t^2
R.<a,b> = InfinitePolynomialRing(QQ['t']) D = R.gens_dict() D next(D) sage_eval('t^2', next(D))
- class sage.rings.polynomial.infinite_polynomial_ring.InfiniteGenDict(Gens)[source]¶
Bases:
object
A dictionary-like class that is suitable for usage in
sage_eval
.The generators of an Infinite Polynomial Ring are not variables. Variables of an Infinite Polynomial Ring are returned by indexing a generator. The purpose of this class is to return a variable of an Infinite Polynomial Ring, given its string representation.
EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(ZZ) sage: D = R.gens_dict() # indirect doctest sage: D._D [InfiniteGenDict defined by ['a', 'b'], {'1': 1}] sage: D._D[0]['a_15'] a_15 sage: type(_) <class 'sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense'> sage: sage_eval('3*a_3*b_5-1/2*a_7', D._D[0]) -1/2*a_7 + 3*a_3*b_5
>>> from sage.all import * >>> R = InfinitePolynomialRing(ZZ, names=('a', 'b',)); (a, b,) = R._first_ngens(2) >>> D = R.gens_dict() # indirect doctest >>> D._D [InfiniteGenDict defined by ['a', 'b'], {'1': 1}] >>> D._D[Integer(0)]['a_15'] a_15 >>> type(_) <class 'sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense'> >>> sage_eval('3*a_3*b_5-1/2*a_7', D._D[Integer(0)]) -1/2*a_7 + 3*a_3*b_5
R.<a,b> = InfinitePolynomialRing(ZZ) D = R.gens_dict() # indirect doctest D._D D._D[0]['a_15'] type(_) sage_eval('3*a_3*b_5-1/2*a_7', D._D[0])
- class sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialGen(parent, name)[source]¶
Bases:
SageObject
This class provides the object which is responsible for returning variables in an infinite polynomial ring (implemented in
__getitem__()
).EXAMPLES:
sage: X.<x1,x2> = InfinitePolynomialRing(RR) sage: x1 x1_* sage: x1[5] x1_5 sage: x1 == loads(dumps(x1)) True
>>> from sage.all import * >>> X = InfinitePolynomialRing(RR, names=('x1', 'x2',)); (x1, x2,) = X._first_ngens(2) >>> x1 x1_* >>> x1[Integer(5)] x1_5 >>> x1 == loads(dumps(x1)) True
X.<x1,x2> = InfinitePolynomialRing(RR) x1 x1[5] x1 == loads(dumps(x1))
- class sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRingFactory[source]¶
Bases:
UniqueFactory
A factory for creating infinite polynomial ring elements. It makes sure that they are unique as well as handling pickling. For more details, see
UniqueFactory
andinfinite_polynomial_ring
.EXAMPLES:
sage: A.<a> = InfinitePolynomialRing(QQ) sage: B.<b> = InfinitePolynomialRing(A) sage: B.construction() [InfPoly{[a,b], "lex", "dense"}, Rational Field] sage: R.<a,b> = InfinitePolynomialRing(QQ) sage: R is B True sage: X.<x> = InfinitePolynomialRing(QQ) sage: X2.<x> = InfinitePolynomialRing(QQ, implementation='sparse') sage: X is X2 False sage: X is loads(dumps(X)) True
>>> from sage.all import * >>> A = InfinitePolynomialRing(QQ, names=('a',)); (a,) = A._first_ngens(1) >>> B = InfinitePolynomialRing(A, names=('b',)); (b,) = B._first_ngens(1) >>> B.construction() [InfPoly{[a,b], "lex", "dense"}, Rational Field] >>> R = InfinitePolynomialRing(QQ, names=('a', 'b',)); (a, b,) = R._first_ngens(2) >>> R is B True >>> X = InfinitePolynomialRing(QQ, names=('x',)); (x,) = X._first_ngens(1) >>> X2 = InfinitePolynomialRing(QQ, implementation='sparse', names=('x',)); (x,) = X2._first_ngens(1) >>> X is X2 False >>> X is loads(dumps(X)) True
A.<a> = InfinitePolynomialRing(QQ) B.<b> = InfinitePolynomialRing(A) B.construction() R.<a,b> = InfinitePolynomialRing(QQ) R is B X.<x> = InfinitePolynomialRing(QQ) X2.<x> = InfinitePolynomialRing(QQ, implementation='sparse') X is X2 X is loads(dumps(X))
- class sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_dense(R, names, order)[source]¶
Bases:
InfinitePolynomialRing_sparse
Dense implementation of Infinite Polynomial Rings.
Compared with
InfinitePolynomialRing_sparse
, from which this class inherits, it keeps a polynomial ring that comprises all elements that have been created so far.- construction()[source]¶
Return the construction of
self
.OUTPUT:
A pair
F,R
, whereF
is a construction functor andR
is a ring, so thatF(R) is self
.EXAMPLES:
sage: R.<x,y> = InfinitePolynomialRing(GF(5)) sage: R.construction() [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5]
>>> from sage.all import * >>> R = InfinitePolynomialRing(GF(Integer(5)), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> R.construction() [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5]
R.<x,y> = InfinitePolynomialRing(GF(5)) R.construction()
- polynomial_ring()[source]¶
Return the underlying finite polynomial ring.
Note
The ring returned can change over time as more variables are used.
Since the rings are cached, we create here a ring with variable names that do not occur in other doc tests, so that we avoid side effects.
EXAMPLES:
sage: X.<xx, yy> = InfinitePolynomialRing(ZZ) sage: X.polynomial_ring() Multivariate Polynomial Ring in xx_0, yy_0 over Integer Ring sage: a = yy[3] sage: X.polynomial_ring() Multivariate Polynomial Ring in xx_3, xx_2, xx_1, xx_0, yy_3, yy_2, yy_1, yy_0 over Integer Ring
>>> from sage.all import * >>> X = InfinitePolynomialRing(ZZ, names=('xx', 'yy',)); (xx, yy,) = X._first_ngens(2) >>> X.polynomial_ring() Multivariate Polynomial Ring in xx_0, yy_0 over Integer Ring >>> a = yy[Integer(3)] >>> X.polynomial_ring() Multivariate Polynomial Ring in xx_3, xx_2, xx_1, xx_0, yy_3, yy_2, yy_1, yy_0 over Integer Ring
X.<xx, yy> = InfinitePolynomialRing(ZZ) X.polynomial_ring() a = yy[3] X.polynomial_ring()
- tensor_with_ring(R)[source]¶
Return the tensor product of
self
with another ring.INPUT:
R
– a ring
OUTPUT:
An infinite polynomial ring that, mathematically, can be seen as the tensor product of
self
withR
.NOTE:
It is required that the underlying ring of
self
coerces intoR
. Hence, the tensor product is in fact merely an extension of the base ring.EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(ZZ, implementation='sparse') sage: R.tensor_with_ring(QQ) Infinite polynomial ring in a, b over Rational Field sage: R Infinite polynomial ring in a, b over Integer Ring
>>> from sage.all import * >>> R = InfinitePolynomialRing(ZZ, implementation='sparse', names=('a', 'b',)); (a, b,) = R._first_ngens(2) >>> R.tensor_with_ring(QQ) Infinite polynomial ring in a, b over Rational Field >>> R Infinite polynomial ring in a, b over Integer Ring
R.<a,b> = InfinitePolynomialRing(ZZ, implementation='sparse') R.tensor_with_ring(QQ) R
The following tests against a bug that was fixed at Issue #10468:
sage: R.<x,y> = InfinitePolynomialRing(QQ, implementation='sparse') sage: R.tensor_with_ring(QQ) is R True
>>> from sage.all import * >>> R = InfinitePolynomialRing(QQ, implementation='sparse', names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> R.tensor_with_ring(QQ) is R True
R.<x,y> = InfinitePolynomialRing(QQ, implementation='sparse') R.tensor_with_ring(QQ) is R
- class sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse(R, names, order)[source]¶
Bases:
CommutativeRing
Sparse implementation of Infinite Polynomial Rings.
An Infinite Polynomial Ring with generators \(x_\ast, y_\ast, ...\) over a field \(F\) is a free commutative \(F\)-algebra generated by \(x_0, x_1, x_2, ..., y_0, y_1, y_2, ..., ...\) and is equipped with a permutation action on the generators, namely \(x_n^P = x_{P(n)}, y_{n}^P=y_{P(n)}, ...\) for any permutation \(P\) (note that variables of index zero are invariant under such permutation).
It is known that any permutation invariant ideal in an Infinite Polynomial Ring is finitely generated modulo the permutation action – see
SymmetricIdeal
for more details.Usually, an instance of this class is created using
InfinitePolynomialRing
with the optional parameterimplementation='sparse'
. This takes care of uniqueness of parent structures. However, a direct construction is possible, in principle:sage: X.<x,y> = InfinitePolynomialRing(QQ, implementation='sparse') sage: Y.<x,y> = InfinitePolynomialRing(QQ, implementation='sparse') sage: X is Y True sage: from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing_sparse sage: Z = InfinitePolynomialRing_sparse(QQ, ['x','y'], 'lex')
>>> from sage.all import * >>> X = InfinitePolynomialRing(QQ, implementation='sparse', names=('x', 'y',)); (x, y,) = X._first_ngens(2) >>> Y = InfinitePolynomialRing(QQ, implementation='sparse', names=('x', 'y',)); (x, y,) = Y._first_ngens(2) >>> X is Y True >>> from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing_sparse >>> Z = InfinitePolynomialRing_sparse(QQ, ['x','y'], 'lex')
X.<x,y> = InfinitePolynomialRing(QQ, implementation='sparse') Y.<x,y> = InfinitePolynomialRing(QQ, implementation='sparse') X is Y from sage.rings.polynomial.infinite_polynomial_ring import InfinitePolynomialRing_sparse Z = InfinitePolynomialRing_sparse(QQ, ['x','y'], 'lex')
Nevertheless, since infinite polynomial rings are supposed to be unique parent structures, they do not evaluate equal.
sage: Z == X False
>>> from sage.all import * >>> Z == X False
Z == X
The last parameter (‘lex’ in the above example) can also be ‘deglex’ or ‘degrevlex’; this would result in an Infinite Polynomial Ring in degree lexicographic or degree reverse lexicographic order.
See
infinite_polynomial_ring
for more details.- characteristic()[source]¶
Return the characteristic of the base field.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(GF(25,'a')) # needs sage.rings.finite_rings sage: X # needs sage.rings.finite_rings Infinite polynomial ring in x, y over Finite Field in a of size 5^2 sage: X.characteristic() # needs sage.rings.finite_rings 5
>>> from sage.all import * >>> X = InfinitePolynomialRing(GF(Integer(25),'a'), names=('x', 'y',)); (x, y,) = X._first_ngens(2)# needs sage.rings.finite_rings >>> X # needs sage.rings.finite_rings Infinite polynomial ring in x, y over Finite Field in a of size 5^2 >>> X.characteristic() # needs sage.rings.finite_rings 5
X.<x,y> = InfinitePolynomialRing(GF(25,'a')) # needs sage.rings.finite_rings X # needs sage.rings.finite_rings X.characteristic() # needs sage.rings.finite_rings
- construction()[source]¶
Return the construction of
self
.OUTPUT:
A pair
F,R
, whereF
is a construction functor andR
is a ring, so thatF(R) is self
.EXAMPLES:
sage: R.<x,y> = InfinitePolynomialRing(GF(5)) sage: R.construction() [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5]
>>> from sage.all import * >>> R = InfinitePolynomialRing(GF(Integer(5)), names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> R.construction() [InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5]
R.<x,y> = InfinitePolynomialRing(GF(5)) R.construction()
- gen(i=None)[source]¶
Return the \(i\)-th ‘generator’ (see the description in
ngens()
) of this infinite polynomial ring.EXAMPLES:
sage: X = InfinitePolynomialRing(QQ) sage: x = X.gen() sage: x[1] x_1 sage: X.gen() is X.gen(0) True sage: XX = InfinitePolynomialRing(GF(5)) sage: XX.gen(0) is XX.gen() True
>>> from sage.all import * >>> X = InfinitePolynomialRing(QQ) >>> x = X.gen() >>> x[Integer(1)] x_1 >>> X.gen() is X.gen(Integer(0)) True >>> XX = InfinitePolynomialRing(GF(Integer(5))) >>> XX.gen(Integer(0)) is XX.gen() True
X = InfinitePolynomialRing(QQ) x = X.gen() x[1] X.gen() is X.gen(0) XX = InfinitePolynomialRing(GF(5)) XX.gen(0) is XX.gen()
- gens_dict()[source]¶
Return a dictionary-like object containing the infinitely many
{var_name:variable}
pairs.EXAMPLES:
sage: R = InfinitePolynomialRing(ZZ, 'a') sage: D = R.gens_dict() sage: D GenDict of Infinite polynomial ring in a over Integer Ring sage: D['a_5'] a_5
>>> from sage.all import * >>> R = InfinitePolynomialRing(ZZ, 'a') >>> D = R.gens_dict() >>> D GenDict of Infinite polynomial ring in a over Integer Ring >>> D['a_5'] a_5
R = InfinitePolynomialRing(ZZ, 'a') D = R.gens_dict() D D['a_5']
- is_field(*args, **kwds)[source]¶
Return
False
since Infinite Polynomial Rings are never fields.Since Infinite Polynomial Rings must have at least one generator, they have infinitely many variables and thus never are fields.
EXAMPLES:
sage: R.<x, y> = InfinitePolynomialRing(QQ) sage: R.is_field() False
>>> from sage.all import * >>> R = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> R.is_field() False
R.<x, y> = InfinitePolynomialRing(QQ) R.is_field()
- is_integral_domain(*args, **kwds)[source]¶
An infinite polynomial ring is an integral domain if and only if the base ring is. Arguments are passed to is_integral_domain method of base ring.
EXAMPLES:
sage: R.<x, y> = InfinitePolynomialRing(QQ) sage: R.is_integral_domain() True
>>> from sage.all import * >>> R = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> R.is_integral_domain() True
R.<x, y> = InfinitePolynomialRing(QQ) R.is_integral_domain()
- is_noetherian()[source]¶
Return
False
, since polynomial rings in infinitely many variables are never Noetherian rings.Since Infinite Polynomial Rings must have at least one generator, they have infinitely many variables and are thus not Noetherian, as a ring.
Note
Infinite Polynomial Rings over a field \(F\) are Noetherian as \(F(G)\) modules, where \(G\) is the symmetric group of the natural numbers. But this is not what the method
is_noetherian()
is answering.
- key_basis()[source]¶
Return the basis of
self
given by key polynomials.EXAMPLES:
sage: R.<x> = InfinitePolynomialRing(GF(2)) sage: R.key_basis() # needs sage.combinat sage.modules Key polynomial basis over Finite Field of size 2
>>> from sage.all import * >>> R = InfinitePolynomialRing(GF(Integer(2)), names=('x',)); (x,) = R._first_ngens(1) >>> R.key_basis() # needs sage.combinat sage.modules Key polynomial basis over Finite Field of size 2
R.<x> = InfinitePolynomialRing(GF(2)) R.key_basis() # needs sage.combinat sage.modules
- krull_dimension(*args, **kwds)[source]¶
Return
Infinity
, since polynomial rings in infinitely many variables have infinite Krull dimension.EXAMPLES:
sage: R.<x, y> = InfinitePolynomialRing(QQ) sage: R.krull_dimension() +Infinity
>>> from sage.all import * >>> R = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> R.krull_dimension() +Infinity
R.<x, y> = InfinitePolynomialRing(QQ) R.krull_dimension()
- ngens()[source]¶
Return the number of generators for this ring.
Since there are countably infinitely many variables in this polynomial ring, by ‘generators’ we mean the number of infinite families of variables. See
infinite_polynomial_ring
for more details.EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(ZZ) sage: X.ngens() 1 sage: X.<x1,x2> = InfinitePolynomialRing(QQ) sage: X.ngens() 2
>>> from sage.all import * >>> X = InfinitePolynomialRing(ZZ, names=('x',)); (x,) = X._first_ngens(1) >>> X.ngens() 1 >>> X = InfinitePolynomialRing(QQ, names=('x1', 'x2',)); (x1, x2,) = X._first_ngens(2) >>> X.ngens() 2
X.<x> = InfinitePolynomialRing(ZZ) X.ngens() X.<x1,x2> = InfinitePolynomialRing(QQ) X.ngens()
- order()[source]¶
Return
Infinity
, since polynomial rings have infinitely many elements.EXAMPLES:
sage: R.<x> = InfinitePolynomialRing(GF(2)) sage: R.order() +Infinity
>>> from sage.all import * >>> R = InfinitePolynomialRing(GF(Integer(2)), names=('x',)); (x,) = R._first_ngens(1) >>> R.order() +Infinity
R.<x> = InfinitePolynomialRing(GF(2)) R.order()
- tensor_with_ring(R)[source]¶
Return the tensor product of
self
with another ring.INPUT:
R
– a ring
OUTPUT:
An infinite polynomial ring that, mathematically, can be seen as the tensor product of
self
withR
.NOTE:
It is required that the underlying ring of
self
coerces intoR
. Hence, the tensor product is in fact merely an extension of the base ring.EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(ZZ) sage: R.tensor_with_ring(QQ) Infinite polynomial ring in a, b over Rational Field sage: R Infinite polynomial ring in a, b over Integer Ring
>>> from sage.all import * >>> R = InfinitePolynomialRing(ZZ, names=('a', 'b',)); (a, b,) = R._first_ngens(2) >>> R.tensor_with_ring(QQ) Infinite polynomial ring in a, b over Rational Field >>> R Infinite polynomial ring in a, b over Integer Ring
R.<a,b> = InfinitePolynomialRing(ZZ) R.tensor_with_ring(QQ) R
The following tests against a bug that was fixed at Issue #10468:
sage: R.<x,y> = InfinitePolynomialRing(QQ) sage: R.tensor_with_ring(QQ) is R True
>>> from sage.all import * >>> R = InfinitePolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2) >>> R.tensor_with_ring(QQ) is R True
R.<x,y> = InfinitePolynomialRing(QQ) R.tensor_with_ring(QQ) is R
- varname_key(x)[source]¶
Key for comparison of variable names.
INPUT:
x
– string of the forma+'_'+str(n)
, where a is the name of a generator, and n is an integer
OUTPUT: a key used to sort the variables
THEORY:
The order is defined as follows:
x<y \(\iff\) the string
x.split('_')[0]
is later in the list of generator names ofself
thany.split('_')[0]
, or (x.split('_')[0]==y.split('_')[0]
andint(x.split('_')[1])<int(y.split('_')[1])
)EXAMPLES:
sage: X.<alpha,beta> = InfinitePolynomialRing(ZZ) sage: X.varname_key('alpha_1') (0, 1) sage: X.varname_key('beta_10') (-1, 10) sage: X.varname_key('beta_1') (-1, 1) sage: X.varname_key('alpha_10') (0, 10) sage: X.varname_key('alpha_1') (0, 1) sage: X.varname_key('alpha_10') (0, 10)
>>> from sage.all import * >>> X = InfinitePolynomialRing(ZZ, names=('alpha', 'beta',)); (alpha, beta,) = X._first_ngens(2) >>> X.varname_key('alpha_1') (0, 1) >>> X.varname_key('beta_10') (-1, 10) >>> X.varname_key('beta_1') (-1, 1) >>> X.varname_key('alpha_10') (0, 10) >>> X.varname_key('alpha_1') (0, 1) >>> X.varname_key('alpha_10') (0, 10)
X.<alpha,beta> = InfinitePolynomialRing(ZZ) X.varname_key('alpha_1') X.varname_key('beta_10') X.varname_key('beta_1') X.varname_key('alpha_10') X.varname_key('alpha_1') X.varname_key('alpha_10')