# Creating Multivariate Rings

In this section, we illustrate by examples how to create multivariate polynomial rings and their elements, while at the same time introducing and illustrating a special ring type for modelling multivariate polynomial rings with gradings by finitely presented groups. For more details on multivariate polynomial rings, their coefficient rings (fields), and their elements, we refer to the chapters on rings and fields.

## 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:

`PolynomialRing(C::Ring, V::Vector{String}; ordering=:lex, cached = 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.

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}$ in the variables x, y, z with `ordering=:lex`

.

###### Examples

```
julia> R, (x, y, z) = PolynomialRing(ZZ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Integer Ring, fmpz_mpoly[x, y, z])
julia> typeof(R)
FmpzMPolyRing
julia> typeof(x)
fmpz_mpoly
julia> S, (x, y, z) = PolynomialRing(ZZ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Integer Ring, fmpz_mpoly[x, y, z])
julia> R === S
true
```

```
julia> R1, x = PolynomialRing(QQ, ["x"])
(Multivariate Polynomial Ring in x over Rational Field, fmpq_mpoly[x])
julia> typeof(x)
Vector{fmpq_mpoly} (alias for Array{fmpq_mpoly, 1})
julia> R2, (x,) = PolynomialRing(QQ, ["x"])
(Multivariate Polynomial Ring in x over Rational Field, fmpq_mpoly[x])
julia> typeof(x)
fmpq_mpoly
julia> R3, x = PolynomialRing(QQ, "x")
(Univariate Polynomial Ring in x over Rational Field, x)
julia> typeof(x)
fmpq_poly
```

```
julia> T, x = PolynomialRing(GF(3), ["x[1]", "x[2]"]);
julia> x
2-element Vector{gfp_mpoly}:
x[1]
x[2]
```

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

```
julia> R, x, y, z = PolynomialRing(QQ, "x" => (1:3, 1:4), "y" => 1:2, "z" => (1:1, 1:1, 1:1));
julia> x
3×4 Matrix{fmpq_mpoly}:
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{fmpq_mpoly}:
y[1]
y[2]
julia> z
1×1×1 Array{fmpq_mpoly, 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)
Galois field with characteristic 3
julia> GF(ZZ(2)^127 - 1)
Galois field with 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 F_2, a)
```

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

```
julia> T, t = PolynomialRing(QQ, "t")
(Univariate Polynomial Ring in t over Rational Field, t)
julia> K, a = NumberField(t^2 + 1, "a")
(Number field over Rational Field with defining polynomial t^2 + 1, a)
julia> F = GF(3)
Galois field with characteristic 3
julia> T, t = PolynomialRing(F, "t")
(Univariate Polynomial Ring in t over Galois field with characteristic 3, t)
julia> K, a = FiniteField(t^2 + 1, "a")
(Finite field of degree 2 over F_3, a)
```

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

```
julia> T, t = PolynomialRing(QQ, "t")
(Univariate Polynomial Ring in t over Rational Field, t)
julia> QT = FractionField(T)
Fraction field of Univariate Polynomial Ring in t over Rational Field
julia> parent(t)
Univariate Polynomial Ring in t over Rational Field
julia> parent(1//t)
Fraction field of Univariate Polynomial Ring in t over Rational Field
julia> T, (s, t) = PolynomialRing(GF(3), ["s", "t"]);
julia> QT = FractionField(T)
Fraction field of Multivariate Polynomial Ring in s, t over Galois field with characteristic 3
```

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

```
julia> ZZ
Integer Ring
```

## Gradings

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 \rightarrow 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.

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

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 `MPolyRing_dec{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.

The types `MPolyRing_dec{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 to distinguish between graded and filtered rings:

`is_graded`

— Method`is_graded(R::MPolyRing_dec)`

Return `true`

if `R`

is graded, `false`

otherwise.

### Constructors for Graded Rings

There are two basic ways of creating multivariate rings with gradings: While the `grade`

function allows one to assign a grading to a polynomial ring already constructed, the `GradedPolynomialRing`

function is meant to create a graded polynomial ring all at once.

`grade`

— Method`grade(R::MPolyRing, W::Vector{GrpAbFinGenElem})`

Given a vector `W`

of `ngens(R)`

elements of a group `G`

of type `GrpAbFinGen`

, define a `G`

-grading on `R`

by assigning weights to the variables according to the entries of `W`

. Return the graded ring as an object of type `MPolyRing_dec`

, together with the vector of variables.

**Examples**

```
julia> R, (t, x, y) = PolynomialRing(QQ, ["t", "x", "y"])
(Multivariate Polynomial Ring in t, x, y over Rational Field, fmpq_mpoly[t, x, y])
julia> typeof(R)
FmpqMPolyRing
julia> typeof(x)
fmpq_mpoly
julia> G = abelian_group([0])
GrpAb: Z
julia> g = gen(G, 1)
Element of
GrpAb: Z
with components [1]
julia> S, (t, x, y) = grade(R, [-g, g, g])
(Multivariate Polynomial Ring in t, x, y over Rational Field graded by
t -> [-1]
x -> [1]
y -> [1], MPolyElem_dec{fmpq, fmpq_mpoly}[t, x, y])
julia> typeof(S)
MPolyRing_dec{fmpq, FmpqMPolyRing}
julia> S isa MPolyRing
true
julia> typeof(x)
MPolyElem_dec{fmpq, fmpq_mpoly}
julia> R, x, y = PolynomialRing(QQ, "x" => 1:2, "y" => 1:3)
(Multivariate Polynomial Ring in x[1], x[2], y[1], y[2], y[3] over Rational Field, fmpq_mpoly[x[1], x[2]], fmpq_mpoly[y[1], y[2], y[3]])
julia> G = abelian_group([0, 0])
GrpAb: Z^2
julia> g = gens(G)
2-element Vector{GrpAbFinGenElem}:
Element of
GrpAb: Z^2
with components [1 0]
Element of
GrpAb: Z^2
with components [0 1]
julia> W = [g[1], g[1], g[2], g[2], g[2]];
julia> S, _ = grade(R, W)
(Multivariate Polynomial Ring in x[1], x[2], y[1], y[2], y[3] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [1 0]
y[1] -> [0 1]
y[2] -> [0 1]
y[3] -> [0 1], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], y[1], y[2], y[3]])
julia> typeof(x[1])
fmpq_mpoly
julia> x = map(S, x)
2-element Vector{MPolyElem_dec{fmpq, fmpq_mpoly}}:
x[1]
x[2]
julia> y = map(S, y)
3-element Vector{MPolyElem_dec{fmpq, fmpq_mpoly}}:
y[1]
y[2]
y[3]
julia> typeof(x[1])
MPolyElem_dec{fmpq, fmpq_mpoly}
julia> R, x = PolynomialRing(QQ, "x" => 1:5)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field, fmpq_mpoly[x[1], x[2], x[3], x[4], x[5]])
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
(General) abelian group with relation matrix
[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
with components [1 0 0 0]
Element of
(General) abelian group with relation matrix
[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
with components [0 1 0 0]
Element of
(General) abelian group with relation matrix
[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
with components [0 0 1 0]
Element of
(General) abelian group with relation matrix
[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
with components [0 0 0 1]
julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
julia> S, x = grade(R, W)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field graded by
x[1] -> [1 0 1 1]
x[2] -> [0 1 0 1]
x[3] -> [1 0 1 0]
x[4] -> [0 1 0 0]
x[5] -> [1 1 0 0], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3], x[4], x[5]])
```

`grade`

— Method`grade(R::MPolyRing, W::Vector{<:Vector{<:IntegerUnion}})`

Given a vector `W`

of `ngens(R)`

integer vectors of the same size `m`

, say, define a $\mathbb Z^m$-grading on `R`

by creating a free abelian group of type `GrpAbFinGen`

given by `m`

free generators, converting the vectors in `W`

to elements of that group, and assigning these elements as weights to the variables. Return the graded ring as an object of type `MPolyRing_dec`

, together with the vector of variables.

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

As above, converting the columns of `W`

.

**Examples**

```
julia> R, x, y = PolynomialRing(QQ, "x" => 1:2, "y" => 1:3)
(Multivariate Polynomial Ring in x[1], x[2], y[1], y[2], y[3] over Rational Field, fmpq_mpoly[x[1], x[2]], fmpq_mpoly[y[1], y[2], y[3]])
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
julia> grade(R, W)
(Multivariate Polynomial Ring in x[1], x[2], y[1], y[2], y[3] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [1 0]
y[1] -> [0 1]
y[2] -> [0 1]
y[3] -> [0 1], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], y[1], y[2], y[3]])
```

`grade`

— Method`grade(R::MPolyRing, W::Vector{<:IntegerUnion})`

Given a vector `W`

of `ngens(R)`

integers, define a $\mathbb Z$-grading on `R`

by creating a free abelian group of type `GrpAbFinGen`

given by one free generator, converting the entries of `W`

to elements of that group, and assigning these elements as weights to the variables. Return the graded ring as an object of type `MPolyRing_dec`

, 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) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])
julia> W = [1, 2, 3];
julia> S, (x, y, z) = grade(R, W)
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> T, (x, y, z) = grade(R)
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
```

`GradedPolynomialRing`

— Method`GradedPolynomialRing(C::Ring, V::Vector{String}, W; ordering=:lex)`

Create a multivariate polynomial ring with coefficient ring `C`

and variables which print according to the strings in `V`

, and grade this ring according to the data provided by `W`

(see the documentation of the `grade`

-function for what is possible). Return the graded ring as an object of type `MPolyRing_dec`

, together with the vector of variables.

`GradedPolynomialRing(C::Ring, V::Vector{String}; ordering=:lex)`

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

**Examples**

```
julia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]
4-element Vector{Vector{Int64}}:
[1, 0]
[0, 1]
[1, 0]
[4, 1]
julia> R, x = GradedPolynomialRing(QQ, ["x[1]", "x[2]", "x[3]", "x[4]"], W)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [0 1]
x[3] -> [1 0]
x[4] -> [4 1], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3], x[4]])
julia> S, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3])
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> T, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
```

## Tests on Graded Rings

`is_standard_graded`

— Method`is_standard_graded(R::MPolyRing_dec)`

Return `true`

if `R`

is standard $\mathbb Z$-graded, `false`

otherwise.

**Examples**

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])
julia> W = [1, 2, 3];
julia> S, (x, y, z) = grade(R, W)
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> is_standard_graded(S)
false
```

`is_z_graded`

— Method`is_z_graded(R::MPolyRing_dec)`

Return `true`

if `R`

is $\mathbb Z$-graded, `false`

otherwise.

Writing `G = grading_group(R)`

, we say that `R`

is $\mathbb Z$-graded if `is_free(G) && ngens(G) == rank(G) == 1`

evaluates to `true`

.

**Examples**

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])
julia> W = [1, 2, 3];
julia> S, (x, y, z) = grade(R, W)
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> is_z_graded(S)
true
```

`is_zm_graded`

— Method`is_zm_graded(R::MPolyRing_dec)`

Return `true`

if `R`

is $\mathbb Z^m$-graded for some $m$, `false`

otherwise.

Writing `G = grading_group(R)`

, we say that `R`

is $\mathbb Z^m$-graded if `is_free(G) && ngens(G) == rank(G) == m`

evaluates to `true`

.

**Examples**

```
julia> R, x = PolynomialRing(QQ, "x" => 1:5)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field, fmpq_mpoly[x[1], x[2], x[3], x[4], x[5]])
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);
julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
julia> S, x = grade(R, W)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field graded by
x[1] -> [1 0 1 1]
x[2] -> [0 1 0 1]
x[3] -> [1 0 1 0]
x[4] -> [0 1 0 0]
x[5] -> [1 1 0 0], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3], x[4], x[5]])
julia> is_zm_graded(S)
false
julia> G = abelian_group(fmpz_mat([1 -1]));
julia> g = gen(G, 1)
Element of
(General) abelian group with relation matrix
[1 -1]
with components [0 1]
julia> W = [g, g, g, g];
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"], W);
julia> is_free(G)
true
julia> is_zm_graded(R)
false
```

`is_positively_graded`

— Method`is_positively_graded(R::MPolyRing_dec)`

Return `true`

if `R`

is positively graded, `false`

otherwise.

We say that `R`

is *positively graded* by a finitely generated abelian group $G$ if the coefficient ring of `R`

is a field, $G$ is free, and each graded part $R_g$, $g\in G$, has finite dimension.

**Examples**

```
julia> R, (t, x, y) = PolynomialRing(QQ, ["t", "x", "y"])
(Multivariate Polynomial Ring in t, x, y over Rational Field, fmpq_mpoly[t, x, y])
julia> G = abelian_group([0])
GrpAb: Z
julia> S, (t, x, y) = grade(R, [-1, 1, 1])
(Multivariate Polynomial Ring in t, x, y over Rational Field graded by
t -> [-1]
x -> [1]
y -> [1], MPolyElem_dec{fmpq, fmpq_mpoly}[t, x, y])
julia> is_positively_graded(S)
false
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"])
(Multivariate Polynomial Ring in x, y over Rational Field, fmpq_mpoly[x, y])
julia> G = abelian_group([0, 2])
(General) abelian group with relation matrix
[0 0; 0 2]
julia> W = [gen(G, 1)+gen(G, 2), gen(G, 1)]
2-element Vector{GrpAbFinGenElem}:
Element of
(General) abelian group with relation matrix
[0 0; 0 2]
with components [1 1]
Element of
(General) abelian group with relation matrix
[0 0; 0 2]
with components [1 0]
julia> S, (x, y) = grade(R, W)
(Multivariate Polynomial Ring in x, y over Rational Field graded by
x -> [1 1]
y -> [1 0], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y])
julia> is_positively_graded(S)
false
```

## Data Associated to Multivariate Rings

Given a multivariate polynomial ring `R`

with coefficient ring `C`

,

`coefficient_ring(R)`

refers to`C`

,`gens(R)`

to the generators (variables) of`R`

,`ngens(R)`

to the number of these generators, and`gen(R, i)`

as well as`R[i]`

to the`i`

-th such generator.

###### Examples

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])
julia> coefficient_ring(R)
Rational Field
julia> gens(R)
3-element Vector{fmpq_mpoly}:
x
y
z
julia> gen(R, 2)
y
julia> R[3]
z
julia> ngens(R)
3
```

In the graded case, we additionally have:

`grading_group`

— Method`grading_group(R::MPolyRing_dec)`

If `R`

is, say, `G`

-graded, return `G`

.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3])
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> grading_group(R)
GrpAb: Z
```

`homogeneous_component`

— Method`homogeneous_component(R::MPolyRing_dec, g::GrpAbFinGenElem)`

Given a polynomial ring `R`

over a field which is graded by a free group of type `GrpAbFinGen`

, and given an element `g`

of that group, return the homogeneous component of `R`

of degree `g`

. Additionally, return the embedding of the component into `R`

.

`homogeneous_component(R::MPolyRing_dec, g::Vector{<:IntegerUnion})`

Given a $\mathbb Z^m$-graded polynomial ring `R`

over a field, and given a vector `g`

of $m$ integers, convert `g`

into an element of the grading group of `R`

, and return the homogeneous component of `R`

whose degree is that element. Additionally, return the embedding of the component into `R`

.

`homogeneous_component(R::MPolyRing_dec, g::IntegerUnion)`

Given a $\mathbb Z$-graded polynomial ring `R`

over a field, and given an integer `g`

, convert `g`

into an element of the grading group of `R`

, and return the homogeneous component of `R`

whose degree is that element. Additionally, return the embedding of the component into `R`

.

If the component is not finite dimensional, an error message will be thrown.

**Examples**

```
julia> R, x, y = PolynomialRing(QQ, "x" => 1:2, "y" => 1:3);
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
julia> S, _ = grade(R, W);
julia> G = grading_group(S)
GrpAb: Z^2
julia> L = homogeneous_component(S, [1, 1]);
julia> L[1]
homogeneous component of Multivariate Polynomial Ring in x[1], x[2], y[1], y[2], y[3] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [1 0]
y[1] -> [0 1]
y[2] -> [0 1]
y[3] -> [0 1] of degree graded by [1 1]
julia> FG = gens(L[1]);
julia> EMB = L[2]
Map from
homogeneous component of Multivariate Polynomial Ring in x[1], x[2], y[1], y[2], y[3] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [1 0]
y[1] -> [0 1]
y[2] -> [0 1]
y[3] -> [0 1] of degree graded by [1 1]
to Multivariate Polynomial Ring in x[1], x[2], y[1], y[2], y[3] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [1 0]
y[1] -> [0 1]
y[2] -> [0 1]
y[3] -> [0 1] defined by a julia-function with inverse
julia> for i in 1:length(FG) println(EMB(FG[i])) end
x[2]*y[3]
x[2]*y[2]
x[2]*y[1]
x[1]*y[3]
x[1]*y[2]
x[1]*y[1]
julia> T, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> G = grading_group(T)
GrpAb: Z
julia> L = homogeneous_component(T, 2)
(homogeneous component of Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] of degree graded by [2]
, Map from
homogeneous component of Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] of degree graded by [2]
to Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] defined by a julia-function with inverse)
julia> FG = gens(L[1]);
julia> EMB = L[2];
julia> for i in 1:length(FG) println(EMB(FG[i])) end
z^2
y*z
y^2
x*z
x*y
x^2
```

## Elements of Multivariate Rings

### Constructors

One way to create elements of a multivariate polynomial ring is to build up polynomials from the generators (variables) of the ring using basic arithmetic as shown below:

###### Examples

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])
julia> f = 3*x^2+y*z
3*x^2 + y*z
julia> typeof(f)
fmpq_mpoly
julia> S, (x, y, z) = grade(R)
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> g = 3*x^2+y*z
3*x^2 + y*z
julia> typeof(g)
MPolyElem_dec{fmpq, fmpq_mpoly}
julia> g == S(f)
true
```

Alternatively, there is the following constructor:

`(R::MPolyRing{T})(c::Vector{T}, e::Vector{Vector{Int}}) where T <: RingElem`

Its return value is the element of `R`

whose nonzero coefficients are specified by the elements of `c`

, with exponent vectors given by the elements of `e`

.

###### Examples

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
(Multivariate Polynomial Ring in x, y, z over Rational Field, fmpq_mpoly[x, y, z])
julia> f = 3*x^2+y*z
3*x^2 + y*z
julia> g = R(QQ.([3, 1]), [[2, 0, 0], [0, 1, 1]])
3*x^2 + y*z
julia> f == g
true
```

An often more effective way to create polynomials is to use the `MPoly`

build context as indicated below:

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"])
(Multivariate Polynomial Ring in x, y over Rational Field, fmpq_mpoly[x, y])
julia> B = MPolyBuildCtx(R)
Builder for an element of Multivariate Polynomial Ring in x, y over Rational Field
julia> for i = 1:5 push_term!(B, QQ(i), [i, i-1]) end
julia> finish(B)
5*x^5*y^4 + 4*x^4*y^3 + 3*x^3*y^2 + 2*x^2*y + x
```

### Special Elements

Given a multivariate polynomial ring `R`

, `zero(R)`

and `one(R)`

refer to the additive and multiplicative identity of `R`

, respectively. Relevant test calls on an element `f`

of `R`

are `iszero(f)`

and `isone(f)`

.

### Data Associated to Elements of Multivariate Rings

Given an element `f`

of a multivariate polynomial ring `R`

or a graded version of such a ring,

`parent(f)`

refers to`R`

,`total_degree(f)`

to the total degree of`f`

,`monomial(f, i)`

to the`i`

-th monomial of`f`

,`term(f, i)`

to the`i`

-th term of`f`

,`coeff(f, i)`

to the coefficient of the`i`

-th term of`f`

, and`exponent_vector(f, i)`

to the exponent vector of the`i`

-th term of`f`

.

###### Examples

```
julia> R, (x, y) = PolynomialRing(GF(5), ["x", "y"])
(Multivariate Polynomial Ring in x, y over Galois field with characteristic 5, gfp_mpoly[x, y])
julia> c = map(GF(5), [1, 2, 3])
3-element Vector{gfp_elem}:
1
2
3
julia> e = [[3, 2], [1, 0], [0, 1]]
3-element Vector{Vector{Int64}}:
[3, 2]
[1, 0]
[0, 1]
julia> f = R(c, e)
x^3*y^2 + 2*x + 3*y
julia> parent(f)
Multivariate Polynomial Ring in x, y over Galois field with characteristic 5
julia> total_degree(f)
5
julia> coeff(f, 2)
2
julia> exponent_vector(f, 2)
2-element Vector{Int64}:
1
0
julia> monomial(f, 2)
x
julia> term(f, 2)
2*x
```

Further functionality is available in the graded case:

`homogeneous_components`

— Method`homogeneous_components(f::MPolyElem_dec{T, S}) where {T, S}`

Given an element `f`

of a graded multivariate ring, return the homogeneous components of `f`

.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3])
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> f = x^2+y+z
x^2 + y + z
julia> homogeneous_components(f)
Dict{GrpAbFinGenElem, MPolyElem_dec{fmpq, fmpq_mpoly}} with 2 entries:
[2] => x^2 + y
[3] => z
julia> R, x = PolynomialRing(QQ, "x" => 1:5)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field, fmpq_mpoly[x[1], x[2], x[3], x[4], x[5]])
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);
julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
julia> S, x = grade(R, W)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field graded by
x[1] -> [1 0 1 1]
x[2] -> [0 1 0 1]
x[3] -> [1 0 1 0]
x[4] -> [0 1 0 0]
x[5] -> [1 1 0 0], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3], x[4], x[5]])
julia> f = x[1]^2+x[3]^2+x[5]^2
x[1]^2 + x[3]^2 + x[5]^2
julia> homogeneous_components(f)
Dict{GrpAbFinGenElem, MPolyElem_dec{fmpq, fmpq_mpoly}} with 2 entries:
[2 2 0 0] => x[5]^2
[2 0 0 0] => x[1]^2 + x[3]^2
```

`homogeneous_component`

— Method`homogeneous_component(f::MPolyElem_dec, g::GrpAbFinGenElem)`

Given an element `f`

of a graded multivariate ring, and given an element `g`

of the grading group of that ring, return the homogeneous component of `f`

of degree `g`

.

`homogeneous_component(f::MPolyElem_dec, g::Vector{<:IntegerUnion})`

Given an element `f`

of a $\mathbb Z^m$-graded multivariate ring `R`

, say, and given a vector `g`

of $m$ integers, convert `g`

into an element of the grading group of `R`

, and return the homogeneous component of `f`

whose degree is that element.

`homogeneous_component(f::MPolyElem_dec, g::IntegerUnion)`

Given an element `f`

of a $\mathbb Z$-graded multivariate ring `R`

, say, and given an integer `g`

, convert `g`

into an element of the grading group of `R`

, and return the homogeneous component of `f`

whose degree is that element.

**Examples**

```
julia> R, x = PolynomialRing(QQ, "x" => 1:5)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field, fmpq_mpoly[x[1], x[2], x[3], x[4], x[5]])
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);
julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
julia> S, x = grade(R, W)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field graded by
x[1] -> [1 0 1 1]
x[2] -> [0 1 0 1]
x[3] -> [1 0 1 0]
x[4] -> [0 1 0 0]
x[5] -> [1 1 0 0], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3], x[4], x[5]])
julia> f = x[1]^2+x[3]^2+x[5]^2
x[1]^2 + x[3]^2 + x[5]^2
julia> homogeneous_component(f, 2*g[1])
x[1]^2 + x[3]^2
julia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]
4-element Vector{Vector{Int64}}:
[1, 0]
[0, 1]
[1, 0]
[4, 1]
julia> R, x = GradedPolynomialRing(QQ, ["x[1]", "x[2]", "x[3]", "x[4]"], W)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [0 1]
x[3] -> [1 0]
x[4] -> [4 1], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3], x[4]])
julia> f = x[1]^2*x[2]+x[4]
x[1]^2*x[2] + x[4]
julia> homogeneous_component(f, [2, 1])
x[1]^2*x[2]
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3])
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> f = x^2+y+z
x^2 + y + z
julia> homogeneous_component(f, 1)
0
julia> homogeneous_component(f, 2)
x^2 + y
julia> homogeneous_component(f, 3)
z
```

`is_homogeneous`

— Method`is_homogeneous(f::MPolyElem_dec)`

Given an element `f`

of a graded multivariate ring, return `true`

if `f`

is homogeneous, `false`

otherwise.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3])
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> f = x^2+y*z
x^2 + y*z
julia> is_homogeneous(f)
false
julia> W = [1 2 1 0; 3 4 0 1]
2×4 Matrix{Int64}:
1 2 1 0
3 4 0 1
julia> S, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"], W)
(Multivariate Polynomial Ring in w, x, y, z over Rational Field graded by
w -> [1 3]
x -> [2 4]
y -> [1 0]
z -> [0 1], MPolyElem_dec{fmpq, fmpq_mpoly}[w, x, y, z])
julia> F = w^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3
w^3*y^3*z^3 + w^2*x*y^2*z^2 + w*x^2*y*z + x^3
julia> is_homogeneous(F)
true
```

`degree`

— Method`degree(f::MPolyElem_dec)`

Given a homogeneous element `f`

of a graded multivariate ring, return the degree of `f`

.

`degree(::Type{Vector{Int}}, f::MPolyElem_dec)`

Given a homogeneous element `f`

of a $\mathbb Z^m$-graded multivariate ring, return the degree of `f`

, converted to a vector of integer numbers.

`degree(::Type{Int}, f::MPolyElem_dec)`

Given a homogeneous element `f`

of a $\mathbb Z$-graded multivariate ring, return the degree of `f`

, converted to an integer number.

**Examples**

```
julia> R, x = PolynomialRing(QQ, "x" => 1:5)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field, fmpq_mpoly[x[1], x[2], x[3], x[4], x[5]])
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);
julia> W = [g[1]+g[3]+g[4], g[2]+g[4], g[1]+g[3], g[2], g[1]+g[2]];
julia> S, x = grade(R, W)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4], x[5] over Rational Field graded by
x[1] -> [1 0 1 1]
x[2] -> [0 1 0 1]
x[3] -> [1 0 1 0]
x[4] -> [0 1 0 0]
x[5] -> [1 1 0 0], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3], x[4], x[5]])
julia> f = x[2]^2+2*x[4]^2
x[2]^2 + 2*x[4]^2
julia> degree(f)
Element of
(General) abelian group with relation matrix
[0 0 0 0; 0 0 0 0; 0 0 2 0; 0 0 0 2]
with components [0 2 0 0]
julia> W = [[1, 0], [0, 1], [1, 0], [4, 1]]
4-element Vector{Vector{Int64}}:
[1, 0]
[0, 1]
[1, 0]
[4, 1]
julia> R, x = GradedPolynomialRing(QQ, ["x[1]", "x[2]", "x[3]", "x[4]"], W)
(Multivariate Polynomial Ring in x[1], x[2], x[3], x[4] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [0 1]
x[3] -> [1 0]
x[4] -> [4 1], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3], x[4]])
julia> f = x[1]^4*x[2]+x[4]
x[1]^4*x[2] + x[4]
julia> degree(f)
graded by [4 1]
julia> degree(Vector{Int}, f)
2-element Vector{Int64}:
4
1
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3])
(Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [2]
z -> [3], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y, z])
julia> f = x^6+y^3+z^2
x^6 + y^3 + z^2
julia> degree(f)
graded by [6]
julia> typeof(degree(f))
GrpAbFinGenElem
julia> degree(Int, f)
6
julia> typeof(degree(Int, f))
Int64
```

## Homomorphisms From Multivariate Rings

If $R$ is a multivariate polynomial ring, and $S$ is any ring, then a ring homomorphism $R \rightarrow S$ is determined by specifying its restriction to the coefficient ring of $R$, and by assigning an image to each variable of $R$. In OSCAR, such homomorphisms are created by using the following constructor:

`hom`

— Method```
hom(R::MPolyRing, S::NCRing, coeff_map, images::Vector; check::Bool = true)
hom(R::MPolyRing, S::NCRing, images::Vector; check::Bool = true)
```

Given a homomorphism `coeff_map`

from `C`

to `S`

, where `C`

is the coefficient ring of `R`

, and given a vector `images`

of `nvars(R)`

elements of `S`

, return the homomorphism `R`

$\to$ `S`

whose restriction to `C`

is `coeff_map`

, and which sends the `i`

-th variable of `R`

to the `i`

-th entry of `images`

.

If no coefficient map is entered, invoke a canonical homomorphism of `C`

to `S`

, if such a homomorphism exists, and throw an error, otherwise.

In case `check = true`

(default), the function checks the conditions below:

- If
`S`

is graded, the assigned images must be homogeneous with respect to the given grading. - If
`S`

is noncommutative, the assigned images must pairwise commute.

**Examples**

```
julia> K, a = FiniteField(2, 2, "a");
julia> R, (x, y) = PolynomialRing(K, ["x", "y"]);
julia> F = hom(R, R, z -> z^2, [y, x])
Map with following data
Domain:
=======
Multivariate Polynomial Ring in x, y over Finite field of degree 2 over F_2
Codomain:
=========
Multivariate Polynomial Ring in x, y over Finite field of degree 2 over F_2
julia> F(a * y)
(a + 1)*x
julia> Qi, i = quadratic_field(-1)
(Imaginary quadratic field defined by x^2 + 1, sqrt(-1))
julia> S, (x, y) = PolynomialRing(Qi, ["x", "y"]);
julia> G = hom(S, S, hom(Qi, Qi, -i), [x^2, y^2])
Map with following data
Domain:
=======
Multivariate Polynomial Ring in x, y over Imaginary quadratic field defined by x^2 + 1
Codomain:
=========
Multivariate Polynomial Ring in x, y over Imaginary quadratic field defined by x^2 + 1
julia> G(x+i*y)
x^2 - sqrt(-1)*y^2
julia> R, (x, y) = PolynomialRing(ZZ, ["x", "y"]);
julia> f = 3*x^2+2*x+1;
julia> S, (x, y) = PolynomialRing(GF(2), ["x", "y"]);
julia> H = hom(R, S, gens(S))
Map with following data
Domain:
=======
Multivariate Polynomial Ring in x, y over Integer Ring
Codomain:
=========
Multivariate Polynomial Ring in x, y over Galois field with characteristic 2
julia> H(f)
x^2 + 1
```

Given a ring homomorphism `F`

from `R`

to `S`

as above, `domain(F)`

and `codomain(F)`

refer to `R`

and `S`

, respectively.

The OSCAR homomorphism type `AffAlgHom`

models ring homomorphisms `R`

$\to$ `S`

such that the type of both `R`

and `S`

is a subtype of `Union{MPolyRing{T}, MPolyQuo{U}}`

, where `T <: FieldElem`

and `U <: MPolyElem{T}`

. Functionality for these homomorphism is discussed in the section on affine algebras.