# Creating Multivariate Rings

In this section, for the convenience of the reader, we recall from the chapters on rings and fields how to create multivariate polynomial rings and their elements, adding illustrating examples. At the same time, we introduce and illustrate a ring type for modelling multivariate polynomial rings with gradings.

## Types

OSCAR provides types for dense univariate and sparse multivariate polynomials. The univariate ring types belong to the abstract type PolyRing{T}, their elements have abstract type PolyRingElem{T}. The multivariate ring types belong to the abstract type MPolyRing{T}, their elements have abstract type MPolyRingElem{T}. Here, T is the element type of the coefficient ring of the polynomial ring.

## Constructors

The basic constructor below allows one to build multivariate polynomial rings:

polynomial_ring(C::Ring, V::Vector{String}; ordering=:lex, cached::Bool = true)

Its return value is a tuple, say R, vars, consisting of a polynomial ring R with coefficient ring C and a vector vars of generators (variables) which print according to the strings in the vector V . The input ordering=:lex refers to the lexicograpical monomial ordering which specifies the default way of storing and displaying polynomials in OSCAR (terms are sorted in descending order). The other possible choices are :deglex and :degrevlex. Gröbner bases, however, can be computed with respect to any monomial ordering. See the section on Gröbner bases.

Note

Caching is used to ensure that a given ring constructed from given parameters is unique in the system. For example, there is only one ring of multivariate polynomials over $\mathbb{Z}$ with variables printing as x, y, z, and with ordering=:lex.

###### Examples
julia> R, (x, y, z) = polynomial_ring(ZZ, ["x", "y", "z"])
(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])

julia> typeof(R)
ZZMPolyRing

julia> typeof(x)
ZZMPolyRingElem

julia> S, (a, b, c) = polynomial_ring(ZZ, ["x", "y", "z"])
(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])

julia> T, _ = polynomial_ring(ZZ, ["x", "y", "z"])
(Multivariate polynomial ring in 3 variables over ZZ, ZZMPolyRingElem[x, y, z])

julia> R === S === T
true
julia> R1, x = polynomial_ring(QQ, ["x"])
(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[x])

julia> typeof(x)
Vector{QQMPolyRingElem} (alias for Array{QQMPolyRingElem, 1})

julia> R2, (x,) = polynomial_ring(QQ, ["x"])
(Multivariate polynomial ring in 1 variable over QQ, QQMPolyRingElem[x])

julia> typeof(x)
QQMPolyRingElem

julia> R3, x = polynomial_ring(QQ, "x")
(Univariate polynomial ring in x over QQ, x)

julia> typeof(x)
QQPolyRingElem

julia> T, x = polynomial_ring(GF(3), ["x", "x"]);

julia> x
2-element Vector{fpMPolyRingElem}:
x
x


The constructor illustrated below allows for the convenient handling of variables with multi-indices:

julia> R, x, y, z = polynomial_ring(QQ, "x" => (1:3, 1:4), "y" => 1:2, "z" => (1:1, 1:1, 1:1));

julia> x
3×4 Matrix{QQMPolyRingElem}:
x[1, 1]  x[1, 2]  x[1, 3]  x[1, 4]
x[2, 1]  x[2, 2]  x[2, 3]  x[2, 4]
x[3, 1]  x[3, 2]  x[3, 3]  x[3, 4]

julia> y
2-element Vector{QQMPolyRingElem}:
y
y

julia> z
1×1×1 Array{QQMPolyRingElem, 3}:
[:, :, 1] =
z[1, 1, 1]


## Coefficient Rings

Gröbner and standard bases are implemented for multivariate polynomial rings over the fields and rings below:

### The field of rational numbers $\mathbb{Q}$

julia> QQ
Rational field


### Finite fields $\mathbb{F_p}$, $p$ a prime

julia> GF(3)
Finite field of characteristic 3

julia> GF(ZZ(2)^127 - 1)
Finite field of characteristic 170141183460469231731687303715884105727


### Finite fields $\mathbb{F}_{p^n}$ with $p^n$ elements, $p$ a prime

julia> FiniteField(2, 70, "a")
(Finite field of degree 70 over GF(2), a)


### Simple algebraic extensions of $\mathbb{Q}$ or $\mathbb{F}_p$

julia> T, t = polynomial_ring(QQ, "t")
(Univariate polynomial ring in t over QQ, t)

julia> K, a = number_field(t^2 + 1, "a")
(Number field of degree 2 over QQ, a)

julia> F = GF(3)
Finite field of characteristic 3

julia> T, t = polynomial_ring(F, "t")
(Univariate polynomial ring in t over GF(3), t)

julia> K, a = FiniteField(t^2 + 1, "a")
(Finite field of degree 2 over GF(3), a)


### Purely transcendental extensions of $\mathbb{Q}$ or $\mathbb{F}_p$

julia> T, t = polynomial_ring(QQ, "t")
(Univariate polynomial ring in t over QQ, t)

julia> QT = fraction_field(T)
Fraction field
of univariate polynomial ring in t over QQ

julia> parent(t)
Univariate polynomial ring in t over QQ

julia> parent(1//t)
Fraction field
of univariate polynomial ring in t over QQ

julia> T, (s, t) = polynomial_ring(GF(3), ["s", "t"]);

julia> QT = fraction_field(T)
Fraction field
of multivariate polynomial ring in 2 variables over GF(3)


### The ring of integers $\mathbb{Z}$

julia> ZZ
Integer Ring


Given a polynomial ring $R = C[x_1, \dots, x_n]$, we may endow $R$ with various gradings. The standard $\mathbb Z$-grading on $R$ is the decomposition $R=\bigoplus_{d\in \mathbb Z} R_d=\bigoplus_{d\geq 0} R_d$ by the usual degree of polynomials. More general $\mathbb Z$-gradings are obtained by assigning integer weights to the variables and considering the corresponding weighted degrees. Even more generally, we may consider multigradings: Given a finitely generated abelian group $G$, a multigrading on $R$ by $G$, or a $G$-grading, or simply a grading, corresponds to a semigroup homomorphism $\phi: \mathbb N^n \to G$: Given $\phi$, the degree of a monomial $x^\alpha$ is the image $\deg(x^\alpha):=\phi(\alpha)\in G$; the induced $G$-grading on $R$ is the decomposition $R = \bigoplus_{g\in G} R_g$ satisfying $R_g\cdot R_h\subset R_{g+h}$, where $R_g$ is the free $C$-module generated by the monomials of degree $g$. This grading is determined by assigning the weights $\deg(x_i)$ to the $x_i$. In other words, it is determined by the weight vector $W = (\deg(x_1), \dots, \deg(x_n))\in G^n.$

We refer to the textbooks Ezra Miller, Bernd Sturmfels (2005) and Martin Kreuzer, Lorenzo Robbiano (2005) for details on multigradings. With respect to notation, we follow the former book.

Note

Given a $G$-grading on $R$, we refer to $G$ as the grading group of $R$. Moreover, we then say that $R$ is $G$-graded, or simply that $R$ is graded. If $R$ is a polynomial ring over a field, we say that a $G$-grading on $R$ is positive if $G$ is free and each graded part $R_g$, $g\in G$, has finite dimension. We then also say that $R$ is positively graded (by $G$). Note that the positivity condition can be equivalently expressed by asking that $G$ is free and that the degree zero part consists of the constants only (see Theorem 8.6 in Ezra Miller, Bernd Sturmfels (2005)).

Note

Given a G-grading on R in OSCAR, we say that R is $\mathbb Z^m$-graded if is_free(G) && ngens(G) == rank(G) == m evaluates to true. In this case, conversion routines allow one to switch back and forth between elements of G and integer vectors of length m. Specifically, if R is $\mathbb Z$-graded, that is, is_free(G) && ngens(G) == rank(G) == 1 evaluates to true, elements of G may be converted to integers and vice versa.

### Types

Multivariate rings with gradings are modelled by objects of type MPolyDecRing{T, S} :< MPolyRing{T}, with elements of type MPolyRingElem_dec{T, S} :< MPolyRingElem{T}. Here, S is the element type of the multivariate ring, and T is the element type of its coefficient ring as above.

Note

The types MPolyDecRing{T, S} and MPolyRingElem_dec{T, S} are also meant to eventually model multivariate rings with filtrations and their elements.

The following function allows one, in particular, to distinguish between graded and filtered rings.

is_gradedMethod
is_graded(R::MPolyRing)

Return true if R is graded, false otherwise.

source

There are two basic ways of creating multivariate rings with gradings: While the grade function allows one to create a graded ring by assigning a grading to a polynomial ring already constructed, the graded_polynomial_ring function is meant to create a graded polynomial ring all at once.

gradeMethod
grade(R::MPolyRing, W::Vector{GrpAbFinGenElem})

Given a vector W of ngens(R) elements of a finitely presented group G, say, create a G-graded ring by assigning the entries of W as weights to the variables of R. Return the new ring as an object of type MPolyDecRing, together with the vector of variables.

Examples

julia> R, (t, x, y) = polynomial_ring(QQ, ["t", "x", "y"])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[t, x, y])

julia> typeof(R)
QQMPolyRing

julia>  typeof(x)
QQMPolyRingElem

julia> G = abelian_group()
GrpAb: Z

julia> g = gen(G, 1)
Element of G with components 

julia> S, (t, x, y) = grade(R, [-g, g, g])
(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[t, x, y])

julia> typeof(S)
MPolyDecRing{QQFieldElem, QQMPolyRing}

julia> S isa MPolyRing
true

julia> typeof(x)
MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}

julia> R, x, y = polynomial_ring(QQ, "x" => 1:2, "y" => 1:3)
(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x, x], QQMPolyRingElem[y, y, y])

julia> G = abelian_group([0, 0])
GrpAb: Z^2

julia> g = gens(G)
2-element Vector{GrpAbFinGenElem}:
Element of G with components [1 0]
Element of G with components [0 1]

julia> W = [g, g, g, g, g];

julia> S, _ = grade(R, W)
(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, x, y, y, y])

julia> typeof(x)
QQMPolyRingElem

julia> x = map(S, x)
2-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
x
x

julia> y = map(S, y)
3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}:
y
y
y

julia> typeof(x)
MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}

julia> R, x = polynomial_ring(QQ, "x" => 1:5)
(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x, x, x, x, x])

julia> G = abelian_group([0, 0, 2, 2])
(General) abelian group with relation matrix
[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]

julia> g = gens(G)
4-element Vector{GrpAbFinGenElem}:
Element of G with components [1 0 0 0]
Element of G with components [0 1 0 0]
Element of G with components [0 0 1 0]
Element of G with components [0 0 0 1]

julia> W = [g+g+g, g+g, g+g, g, g+g];

julia> S, x = grade(R, W)
(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, x, x, x, x])
source
gradeMethod
grade(R::MPolyRing, W::Vector{<:Vector{<:IntegerUnion}})

Given a vector W of ngens(R) integer vectors of the same size m, say, create a free abelian group of type GrpAbFinGen given by m free generators, and convert the vectors in W to elements of that group. Then create a $\mathbb Z^m$-graded ring by assigning the group elements as weights to the variables of R, and return the new ring, together with the vector of variables.

grade(R::MPolyRing, W::Union{ZZMatrix, Matrix{<:IntegerUnion}})

As above, converting the columns of W.

Examples

julia> R, x, y = polynomial_ring(QQ, "x" => 1:2, "y" => 1:3)
(Multivariate polynomial ring in 5 variables over QQ, QQMPolyRingElem[x, x], QQMPolyRingElem[y, y, y])

julia> W = [1 1 0 0 0; 0 0 1 1 1]
2×5 Matrix{Int64}:
1  1  0  0  0
0  0  1  1  1

(Graded multivariate polynomial ring in 5 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, x, y, y, y])
source
gradeMethod
grade(R::MPolyRing, W::Vector{<:IntegerUnion})

Given a vector W of ngens(R) integers, create a free abelian group of type GrpAbFinGen given by one free generator, and convert the entries of W to elements of that group. Then create a $\mathbb Z$-graded ring by assigning the group elements as weights to the variables of R, and return the new ring, together with the vector of variables.

grade(R::MPolyRing)

As above, where the grading is the standard $\mathbb Z$-grading on R.

Examples

julia> R, (x, y, z) = polynomial_ring(QQ, ["x", "y", "z"])
(Multivariate polynomial ring in 3 variables over QQ, QQMPolyRingElem[x, y, z])

julia> W = [1, 2, 3];

julia> S, (x, y, z) = grade(R, W)
(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])

julia> T, (x, y, z) = grade(R)
(Graded multivariate polynomial ring in 3 variables over QQ, MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}[x, y, z])
source
graded_polynomial_ringMethod
graded_polynomial_ring(C::Ring, V, W; ordering=:lex)
graded_polynomial_ring(C::Ring, n::Int, s::T, W; ordering=:lex) where T<:VarName