# Affine Algebras

With regard to notation, we use *affine algebra* as a synonym for *quotient ring of a multivariate polynomial ring modulo an ideal*. More specifically, if $R$ is a multivariate polynomial ring with coefficient ring $C$, and $A=R/I$ is the quotient ring of $R$ modulo an ideal $I$ of $R$, we refer to $A$ as an *affine algebra over $C$*, or an *affine $C$-algebra*. In this section, we discuss functionality for handling such algebras in OSCAR.

Most of the functions discussed here rely on Gröbner basis techniques. They are implemented for affine algebras over fields (exact fields supported by OSCAR) and, if not indicated otherwise, for affine algebras over the integers.

In OSCAR, elements of quotient rings are not necessarily reduced with regard to the modulus of the quotient ring. Operations involving Gröbner basis computations may lead to partial reductions. Full reductions, depending on the choice of a monomial ordering, are achieved by explicitly computing normal forms. The functions `simplify`

and `simplify!`

discussed in this section implements this.

Each grading on a multivariate polynomial ring `R`

in OSCAR descends to a grading on the affine algebra `A = R/I`

(recall that OSCAR ideals of graded polynomial rings are required to be homogeneous). Functionality for dealing with such gradings and our notation for describing this functionality descend accordingly. This applies, in particular, to the functions `ìs_graded`

, `ìs_standard_graded`

, `ìs_z_graded`

, `ìs_zm_graded`

, and `ìs_positively_graded`

which will not be discussed again here.

## Types

The OSCAR type for quotient rings of multivariate polynomial rings is of parametrized form `MPolyQuo{T}`

, with elements of type `MPolyQuoElem{T}`

. Here, `T`

is the element type of the polynomial ring.

## Constructors

`quo`

— Method`quo(R::MPolyRing, I::MPolyIdeal) -> MPolyQuoRing, Map`

Create the quotient ring $R/I$ and return the new ring as well as the projection map $R\rightarrow R/I$.

`quo(R::MPolyRing, V::Vector{MPolyElem}) -> MPolyQuoRing, Map`

As above, where $I\subset R$ is the ideal generated by the polynomials in $V$.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]))
(Quotient of Multivariate Polynomial Ring in x, y over Rational Field by ideal(x^2 - y^3, x - y), Map from
Multivariate Polynomial Ring in x, y over Rational Field to Quotient of Multivariate Polynomial Ring in x, y over Rational Field by ideal(x^2 - y^3, x - y) defined by a julia-function with inverse)
julia> typeof(A)
MPolyQuo{fmpq_mpoly}
julia> typeof(x)
fmpq_mpoly
julia> typeof(A(x))
MPolyQuoElem{fmpq_mpoly}
julia> A, p = quo(R, ideal(R, [x^2-y^3, x-y]));
julia> p
Map from
Multivariate Polynomial Ring in x, y over Rational Field to Quotient of Multivariate Polynomial Ring in x, y over Rational Field by ideal(x^2 - y^3, x - y) defined by a julia-function with inverse
julia> p(x)
x
julia> typeof(p(x))
MPolyQuoElem{fmpq_mpoly}
julia> S, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"]);
julia> B, _ = quo(S, ideal(S, [x^2*z-y^3, x-y]))
(Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] by ideal(x^2*z - y^3, x - y), Map from
Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] to Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] by ideal(x^2*z - y^3, x - y) defined by a julia-function with inverse)
julia> typeof(B)
MPolyQuo{MPolyElem_dec{fmpq, fmpq_mpoly}}
```

## Data Associated to Affine Algebras

### Basic Data

If `A=R/I`

is the quotient ring of a multivariate polynomial ring `R`

modulo an ideal `I`

of `R`

, then

`base_ring(A)`

refers to`R`

,`modulus(A)`

to`I`

,`gens(A)`

to the generators of`A`

,`ngens(A)`

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

as well as`A[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> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]))
(Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z), Map from
Multivariate Polynomial Ring in x, y, z over Rational Field to Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z) defined by a julia-function with inverse)
julia> base_ring(A)
Multivariate Polynomial Ring in x, y, z over Rational Field
julia> modulus(A)
ideal(-x^2 + y, -x^3 + z)
julia> gens(A)
3-element Vector{MPolyQuoElem{fmpq_mpoly}}:
x
y
z
julia> ngens(A)
3
julia> gen(A, 2)
y
```

In the graded case, we additionally have:

`grading_group`

— Method`grading_group(A::MPolyQuo{<:MPolyElem_dec})`

If `A`

is, say, `G`

-graded, return `G`

.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [x^2*z-y^3, x-y]));
julia> grading_group(A)
GrpAb: Z
```

### Dimension

`dim`

— Method`dim(A::MPolyQuo)`

Return the Krull dimension of `A`

.

**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> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]))
(Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z), Map from
Multivariate Polynomial Ring in x, y, z over Rational Field to Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z) defined by a julia-function with inverse)
julia> dim(A)
1
```

`vdim`

— Method`vdim(A::MPolyQuo)`

If, say, $A = R/I$, where $R$ is a multivariate polynomial ring over a field $K$, and $I$ is an ideal of $R$, return the dimension of $A$ as a $K$-vector space if $I$ is zero-dimensional (otherwise, return $-1$).

**Examples**

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [x^3+y^3+z^3-1, x^2+y^2+z^2-1, x+y+z-1]));
julia> vdim(A)
6
julia> I = modulus(A)
ideal(x^3 + y^3 + z^3 - 1, x^2 + y^2 + z^2 - 1, x + y + z - 1)
julia> groebner_basis(I, ordering = lex(base_ring(I)))
Gröbner basis with elements
1 -> z^3 - z^2
2 -> y^2 + y*z - y + z^2 - z
3 -> x + y + z - 1
with respect to the ordering
lex([x, y, z])
```

## Elements of Affine Algebras

### Types

The OSCAR type for elements of quotient rings of multivariate polynomial rings is of parametrized form `MPolyQuo{T}`

, where `T`

is the element type of the polynomial ring.

### Creating Elements of Affine Algebras

Elements of an affine algebra $A = R/I$ are created as images of elements of $R$ under the projection map or by directly coercing elements of $R$ into $A$.

###### Examples

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, p = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]))
(Quotient of Multivariate Polynomial Ring in x, y over Rational Field by ideal(x^3*y^2 - x^2*y^3, x*y^4 - x*y^2), Map from
Multivariate Polynomial Ring in x, y over Rational Field to Quotient of Multivariate Polynomial Ring in x, y over Rational Field by ideal(x^3*y^2 - x^2*y^3, x*y^4 - x*y^2) defined by a julia-function with inverse)
julia> f = p(x^3*y^2-y^3*x^2+x*y)
x^3*y^2 - x^2*y^3 + x*y
julia> typeof(f)
MPolyQuoElem{fmpq_mpoly}
julia> g = A(x^3*y^2-y^3*x^2+x*y)
x^3*y^2 - x^2*y^3 + x*y
julia> f == g
true
```

### Reducing Elements of Affine Algebras

`simplify`

— Method`simplify(f::MPolyQuoElem)`

Reduce `f`

with regard to the modulus of the quotient ring.

`simplify!(f::MPolyQuoElem)`

Reduce `f`

with regard to the modulus of the quotient ring, and replace `f`

by the reduction.

**Examples**

```
julia> R, (x,) = PolynomialRing(QQ, ["x"]);
julia> A, p = quo(R, ideal(R, [x^4]));
julia> f = p(x-x^6)
-x^6 + x
julia> simplify(f)
x
julia> f
-x^6 + x
julia> simplify!(f)
x
julia> f
x
```

### Tests on Elements of Affine Algebras

`==`

— Method`==(f::MPolyQuoElem{T}, g::MPolyQuoElem{T}) where T`

Return `true`

if `f`

is equal to `g`

, `false`

otherwise.

**Examples**

```
julia> R, (x,) = PolynomialRing(QQ, ["x"]);
julia> A, p = quo(R, ideal(R, [x^4]));
julia> f = p(x-x^6)
-x^6 + x
julia> g = p(x)
x
julia> f == g
true
```

In the graded case, we additionally have:

`is_homogeneous`

— Method`is_homogeneous(f::MPolyQuoElem{<:MPolyElem_dec})`

Given an element `f`

of a graded affine algebra, return `true`

if `f`

is homogeneous, `false`

otherwise.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"]);
julia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));
julia> f = p(y^2-x^2+z^4)
-x^2 + y^2 + z^4
julia> is_homogeneous(f)
true
julia> f
z^4
```

### Data associated to Elements of Affine Algebras

Given an element `f`

of an affine algebra `A`

,

`parent(f)`

refers to`A`

.

In the graded case, we also have:

`homogeneous_components`

— Method`homogeneous_components(f::MPolyQuoElem{<:MPolyElem_dec})`

Given an element `f`

of a graded affine algebra, return the homogeneous components of `f`

.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"]);
julia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));
julia> f = p(y^2-x^2+x*y*z+z^4)
-x^2 + x*y*z + y^2 + z^4
julia> homogeneous_components(f)
Dict{GrpAbFinGenElem, MPolyQuoElem{MPolyElem_dec{fmpq, fmpq_mpoly}}} with 2 entries:
[4] => z^4
[3] => y^2*z
```

`homogeneous_component`

— Method`homogeneous_component(f::MPolyQuoElem{<:MPolyElem_dec}, g::GrpAbFinGenElem)`

Given an element `f`

of a graded affine algebra, and given an element `g`

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

of degree `g`

.

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

Given an element `f`

of a $\mathbb Z^m$-graded affine algebra `A`

, say, and given a vector `g`

of $m$ integers, convert `g`

into an element of the grading group of `A`

, and return the homogeneous component of `f`

whose degree is that element.

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

Given an element `f`

of a $\mathbb Z$-graded affine algebra `A`

, say, and given an integer `g`

, convert `g`

into an element of the grading group of `A`

, and return the homogeneous component of `f`

whose degree is that element.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"]);
julia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]));
julia> f = p(y^2-x^2+x*y*z+z^4)
-x^2 + x*y*z + y^2 + z^4
julia> homogeneous_component(f, 4)
z^4
```

`degree`

— Method`degree(f::MPolyQuoElem{<:MPolyElem_dec})`

Given a homogeneous element `f`

of a graded affine algebra, return the degree of `f`

.

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

Given a homogeneous element `f`

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

, converted to a vector of integer numbers.

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

Given a homogeneous element `f`

of a $\mathbb Z$-graded affine algebra, return the degree of `f`

, converted to an integer number.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"] );
julia> A, p = quo(R, ideal(R, [y-x, z^3-x^3]))
(Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] by ideal(-x + y, -x^3 + z^3), Map from
Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] to Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field graded by
x -> [1]
y -> [1]
z -> [1] by ideal(-x + y, -x^3 + z^3) defined by a julia-function with inverse)
julia> f = p(y^2-x^2+z^4)
-x^2 + y^2 + z^4
julia> degree(f)
graded by [4]
julia> typeof(degree(f))
GrpAbFinGenElem
julia> degree(Int, f)
4
julia> typeof(degree(Int, f))
Int64
```

## Ideals in Affine Algebras

### Constructors

`ideal`

— Method`ideal(A::MPolyQuo{T}, V::Vector{T}) where T <: MPolyElem`

Given a (graded) quotient ring `A=R/I`

and a vector `V`

of (homogeneous) polynomials in `R`

, create the ideal of `A`

which is generated by the images of the entries of `V`

.

`ideal(A::MPolyQuo{T}, V::Vector{MPolyQuoElem{T}}) where T <: MPolyElem`

Given a (graded) quotient ring `A`

and a vector `V`

of (homogeneous) elements of `A`

, create the ideal of `A`

which is generated by the entries of `V`

.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
julia> I = ideal(A, [x^2-y])
ideal(x^2 - y)
julia> S, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"]);
julia> B, _ = quo(S, ideal(S, [x^2*z-y^3, x-y]));
julia> J = ideal(B, [x^2-y^2])
ideal(x^2 - y^2)
```

### Reducing Ideals in Affine Algebras

`simplify`

— Method`simplify(a::MPolyQuoIdeal)`

Reduce `a`

with regard to the modulus of the quotient ring.

`simplify!(a::MPolyQuoIdeal)`

Reduce `a`

with regard to the modulus of the quotient ring, and replace `a`

by the reduction.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));
julia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])
ideal(x^3*y^4 - x + y, x*y^2 + x*y)
julia> simplify(a)
ideal(x^2*y^3 - x + y, x*y^2 + x*y)
julia> a
ideal(x^3*y^4 - x + y, x*y^2 + x*y)
julia> simplify!(a);
julia> a
ideal(x^2*y^3 - x + y, x*y^2 + x*y)
```

### Data Associated to Ideals in Affine Algebras

#### Basic Data

If `a`

is an ideal of the affine algebra `A`

, then

`base_ring(a)`

refers to`A`

,`gens(a)`

to the generators of`a`

,`ngens(a)`

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

as well as`a[i]`

to the`i`

-th such generator.

###### Examples

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));
julia> a = ideal(A, [x-y, z^4])
ideal(x - y, z^4)
julia> base_ring(a)
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z)
julia> gens(a)
2-element Vector{MPolyQuoElem{fmpq_mpoly}}:
x - y
z^4
julia> ngens(a)
2
julia> gen(a, 2)
z^4
```

#### Dimension of Ideals in Affine Algebras

`dim`

— Method`dim(a::MPolyQuoIdeal)`

Return the Krull dimension of `a`

.

**Examples**

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));
julia> a = ideal(A, [x-y])
ideal(x - y)
julia> dim(a)
0
```

#### Minimal Sets of Generators

In the graded case, we have:

`minimal_generating_set`

— Method`minimal_generating_set(I::MPolyQuoIdeal{<:MPolyElem_dec})`

Given a homogeneous ideal `I`

in a graded affine algebra over a field, return an array containing a minimal set of generators of `I`

.

**Examples**

```
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"]);
julia> V = [x, z^2, x^3+y^3, y^4, y*z^5];
julia> I = ideal(R, V)
ideal(x, z^2, x^3 + y^3, y^4, y*z^5)
julia> A, p = quo(R, ideal(R, [x-y]));
julia> J = ideal(A, [p(x) for x in V]);
julia> minimal_generating_set(J)
2-element Vector{MPolyQuoElem{MPolyElem_dec{fmpq, fmpq_mpoly}}}:
x
z^2
```

### Operations on Ideals in Affine Algebras

#### Simple Ideal Operations in Affine Algebras

##### Powers of Ideal

`^`

— Method`:^(a::MPolyQuoIdeal, m::Int)`

Return the `m`

-th power of `a`

.

##### Sum of Ideals

`+`

— Method`:+(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T`

Return the sum of `a`

and `b`

.

##### Product of Ideals

`*`

— Method`:*(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T`

Return the product of `a`

and `b`

.

#### Intersection of Ideals

`intersect`

— Method`intersect(a::MPolyQuoIdeal{T}, bs::MPolyQuoIdeal{T}...) where T`

Return the intersection of two or more ideals.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
julia> a = ideal(A, [y^2])
ideal(y^2)
julia> b = ideal(A, [x])
ideal(x)
julia> intersect(a,b)
ideal(x*y)
```

#### Ideal Quotients

`quotient`

— Method`quotient(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T`

Return the ideal quotient of `a`

by `b`

. Alternatively, use `a:b`

.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [x^2-y^3, x-y]));
julia> a = ideal(A, [y^2])
ideal(y^2)
julia> b = ideal(A, [x])
ideal(x)
julia> a:b
ideal(y)
```

### Tests on Ideals in Affine Algebras

#### Basic Tests

`iszero`

— Method`iszero(a::MPolyQuoIdeal)`

Return `true`

if `a`

is the zero ideal, `false`

otherwise.

#### Equality of Ideals in Affine Algebras

`==`

— Method`==(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T`

Return `true`

if `a`

is equal to `b`

, `false`

otherwise.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));
julia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])
ideal(x^3*y^4 - x + y, x*y^2 + x*y)
julia> b = ideal(A, [x^3*y^3-x+y, x^2*y+y^2*x])
ideal(x^3*y^3 - x + y, x^2*y + x*y^2)
julia> a == b
false
```

#### Containment of Ideals in Affine Algebras

`issubset`

— Method`issubset(a::MPolyQuoIdeal{T}, b::MPolyQuoIdeal{T}) where T`

Return `true`

if `a`

is contained in `b`

, `false`

otherwise.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [x^3*y^2-y^3*x^2, x*y^4-x*y^2]));
julia> a = ideal(A, [x^3*y^4-x+y, x*y+y^2*x])
ideal(x^3*y^4 - x + y, x*y^2 + x*y)
julia> b = ideal(A, [x^3*y^3-x+y, x^2*y+y^2*x])
ideal(x^3*y^3 - x + y, x^2*y + x*y^2)
julia> issubset(a,b)
false
julia> issubset(b,a)
true
```

## Homomorphisms From Affine Algebras

If $A=R/I$ is an affine $C$-algebra, and $S$ is any ring, then defining a ring homomorphism $\overline{\phi}: A \rightarrow S$ means to define a ring homomorphism $\phi: R \rightarrow S$ such that $I\subset \ker(\phi)$. Thus, $\overline{\phi} $ is determined by specifying its restriction to $C$, and by assigning an image to each generator of $A$. In OSCAR, such homomorphisms are created by using the following constructor:

`hom`

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

Given a homomorphism `coeff_map`

from `C`

to `S`

, where `C`

is the coefficient ring of the base ring of `A`

, and given a vector `images`

of `ngens(A)`

elements of `S`

, return the homomorphism `A`

$\to$ `S`

whose restriction to `C`

is `coeff_map`

, and which sends the `i`

-th generator of `A`

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.

The function returns a well-defined homomorphism `A`

$\to$ `S`

iff the given data defines a homomorphism from the base ring of `A`

to `S`

whose kernel contains the modulus of `A`

. This condition is checked by the function in case `check = true`

(default).

In case `check = true`

(default), the function also 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> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"] );
julia> A, _ = quo(R, ideal(R, [y-x^2, z-x^3]));
julia> S, (s, t) = PolynomialRing(QQ, ["s", "t"]);
julia> F = hom(A, S, [s, s^2, s^3])
Map with following data
Domain:
=======
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z)
Codomain:
=========
Multivariate Polynomial Ring in s, t over Rational Field
```

Given a ring homomorphism `F`

from `R`

to `S`

as above, `domain(F)`

and `codomain(F)`

refer to `R`

and `S`

, respectively. Given ring homomorphisms `F`

from `R`

to `S`

and `G`

from `S`

to `T`

as above, `compose(F, G)`

refers to their composition.

## Homomorphisms of Affine Algebras

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 what follows.

### Data Associated to Homomorphisms of Affine Algebras

`preimage`

— Method`preimage(F::AffAlgHom, I::U) where U <: Union{MPolyIdeal, MPolyQuoIdeal}`

Return the preimage of the ideal `I`

under `F`

.

`kernel`

— Method`kernel(F::AffAlgHom)`

Return the kernel of `F`

.

###### Examples

```
julia> D1, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"]);
julia> C1, (s,t) = GradedPolynomialRing(QQ, ["s", "t"]);
julia> V1 = [s^3, s^2*t, s*t^2, t^3];
julia> para = hom(D1, C1, V1)
Map with following data
Domain:
=======
Multivariate Polynomial Ring in w, x, y, z over Rational Field graded by
w -> [1]
x -> [1]
y -> [1]
z -> [1]
Codomain:
=========
Multivariate Polynomial Ring in s, t over Rational Field graded by
s -> [1]
t -> [1]
julia> twistedCubic = kernel(para)
ideal(-x*z + y^2, -w*z + x*y, -w*y + x^2)
julia> C2, p2 = quo(D1, twistedCubic);
julia> D2, (a, b, c) = GradedPolynomialRing(QQ, ["a", "b", "c"]);
julia> V2 = [p2(w-y), p2(x), p2(z)];
julia> proj = hom(D2, C2, V2)
Map with following data
Domain:
=======
Multivariate Polynomial Ring in a, b, c over Rational Field graded by
a -> [1]
b -> [1]
c -> [1]
Codomain:
=========
Quotient of Multivariate Polynomial Ring in w, x, y, z over Rational Field graded by
w -> [1]
x -> [1]
y -> [1]
z -> [1] by ideal(-x*z + y^2, -w*z + x*y, -w*y + x^2)
julia> nodalCubic = kernel(proj)
ideal(-a^2*c + b^3 - 2*b^2*c + b*c^2)
```

```
julia> D3,y = PolynomialRing(QQ, "y" => 1:3);
julia> C3, x = PolynomialRing(QQ, "x" => 1:3);
julia> V3 = [x[1]*x[2], x[1]*x[3], x[2]*x[3]];
julia> F3 = hom(D3, C3, V3)
Map with following data
Domain:
=======
Multivariate Polynomial Ring in y[1], y[2], y[3] over Rational Field
Codomain:
=========
Multivariate Polynomial Ring in x[1], x[2], x[3] over Rational Field
julia> sphere = ideal(C3, [x[1]^3 + x[2]^3 + x[3]^3 - 1])
ideal(x[1]^3 + x[2]^3 + x[3]^3 - 1)
julia> steinerRomanSurface = preimage(F3, sphere)
ideal(y[1]^6*y[2]^6 + 2*y[1]^6*y[2]^3*y[3]^3 + y[1]^6*y[3]^6 + 2*y[1]^3*y[2]^6*y[3]^3 + 2*y[1]^3*y[2]^3*y[3]^6 - y[1]^3*y[2]^3*y[3]^3 + y[2]^6*y[3]^6)
```

### Tests on Homomorphisms of Affine Algebras

`is_injective`

— Method`is_injective(F::AffAlgHom)`

Return `true`

if `F`

is injective, `false`

otherwise.

`is_surjective`

— Method`is_surjective(F::AffAlgHom)`

Return `true`

if `F`

is is_surjective, `false`

otherwise.

`is_bijective`

— Method`is_bijective(F::AffAlgHom)`

Return `true`

if `F`

is bijective, `false`

otherwise.

`isfinite`

— Method`isfinite(F::AffAlgHom)`

Return `true`

if `F`

is finite, `false`

otherwise.

###### Examples

```
julia> D, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);
julia> S, (a, b, c) = PolynomialRing(QQ, ["a", "b", "c"]);
julia> C, p = quo(S, ideal(S, [c-b^3]));
julia> V = [p(2*a + b^6), p(7*b - a^2), p(c^2)];
julia> F = hom(D, C, V)
Map with following data
Domain:
=======
Multivariate Polynomial Ring in x, y, z over Rational Field
Codomain:
=========
Quotient of Multivariate Polynomial Ring in a, b, c over Rational Field by ideal(-b^3 + c)
julia> is_surjective(F)
true
julia> D1, _ = quo(D, kernel(F));
julia> F1 = hom(D1, C, V);
julia> is_bijective(F1)
true
```

```
julia> R, (x, y, z) = PolynomialRing(QQ, [ "x", "y", "z"]);
julia> C, (s, t) = PolynomialRing(QQ, ["s", "t"]);
julia> V = [s*t, t, s^2];
julia> paraWhitneyUmbrella = hom(R, C, V)
Map with following data
Domain:
=======
Multivariate Polynomial Ring in x, y, z over Rational Field
Codomain:
=========
Multivariate Polynomial Ring in s, t over Rational Field
julia> D, _ = quo(R, kernel(paraWhitneyUmbrella));
julia> isfinite(hom(D, C, V))
true
```

### Inverting Homomorphisms of Affine Algebras

`inverse`

— Method`inverse(F::AffAlgHom)`

If `F`

is bijective, return its inverse.

**Examples**

```
julia> D1, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);
julia> D, _ = quo(D1, [y-x^2, z-x^3])
(Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z), Map from
Multivariate Polynomial Ring in x, y, z over Rational Field to Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z) defined by a julia-function with inverse)
julia> C, (t,) = PolynomialRing(QQ, ["t"]);
julia> F = hom(D, C, [t, t^2, t^3]);
julia> is_bijective(F)
true
julia> G = inverse(F)
Map with following data
Domain:
=======
Multivariate Polynomial Ring in t over Rational Field
Codomain:
=========
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z)
julia> G(t)
x
```

```
julia> D1, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);
julia> D, _ = quo(D1, [y-x^2, z-x^3])
(Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z), Map from
Multivariate Polynomial Ring in x, y, z over Rational Field to Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z) defined by a julia-function with inverse)
julia> C, (t,) = PolynomialRing(QQ, ["t"]);
julia> para = hom(D, C, [t, t^2, t^3]);
julia> is_bijective(para)
true
julia> inverse(para)
Map with following data
Domain:
=======
Multivariate Polynomial Ring in t over Rational Field
Codomain:
=========
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x^2 + y, -x^3 + z)
```

## Subalgebras

### Subalgebra Membership

`subalgebra_membership`

— Method`subalgebra_membership(f::T, V::Vector{T}) where T <: Union{MPolyElem, MPolyQuoElem}`

Given an element `f`

of a graded multivariate polynomial ring over a field, or of a quotient ring of such a ring, and given a vector `V`

of elements in the same ring, consider the subalgebra generated by the entries of `V`

in that ring. If `f`

is contained in the subalgebra, return `(true, h)`

, where `h`

is giving the polynomial relation. Return, `(false, 0)`

, otherwise.

**Examples**

```
julia> R, x = PolynomialRing(QQ, "x" => 1:3)
(Multivariate Polynomial Ring in x[1], x[2], x[3] over Rational Field, fmpq_mpoly[x[1], x[2], x[3]])
julia> f = x[1]^6*x[2]^6-x[1]^6*x[3]^6;
julia> V = [x[1]^3*x[2]^3-x[1]^3*x[3]^3, x[1]^3*x[2]^3+x[1]^3*x[3]^3]
2-element Vector{fmpq_mpoly}:
x[1]^3*x[2]^3 - x[1]^3*x[3]^3
x[1]^3*x[2]^3 + x[1]^3*x[3]^3
julia> subalgebra_membership(f, V)
(true, t_1*t_2)
```

### Minimal Subalgebra Generators

`minimal_subalgebra_generators`

— Method`minimal_subalgebra_generators(V::Vector{T}) where T <: Union{MPolyElem, MPolyQuoElem}`

Given a vector `V`

of homogeneous elements of a positively graded multivariate polynomial ring, or of a quotient ring of such a ring, return a minimal subset of the elements in `V`

which, in the given ring, generate the same subalgebra as all elements in `V`

.

The conditions on `V`

and the given ring are automatically checked.

**Examples**

```
julia> R, (x, y) = GradedPolynomialRing(QQ, ["x", "y"])
(Multivariate Polynomial Ring in x, y over Rational Field graded by
x -> [1]
y -> [1], MPolyElem_dec{fmpq, fmpq_mpoly}[x, y])
julia> V = [x, y, x^2+y^2]
3-element Vector{MPolyElem_dec{fmpq, fmpq_mpoly}}:
x
y
x^2 + y^2
julia> minimal_subalgebra_generators(V)
2-element Vector{MPolyElem_dec{fmpq, fmpq_mpoly}}:
x
y
```

## Noether Normalization

`noether_normalization`

— Method`noether_normalization(A::MPolyQuo)`

Given an affine algebra $A=R/I$ over a field $K$, return a triple $(V,F,G)$ such that: $V$ is a vector of $d=\dim A$ elements of $A$, represented by linear forms $l_i\in R$, and such that $K[V]\hookrightarrow A$ is a Noether normalization for $A$; $F: A=R/I \rightarrow B = R/\phi(I)$ is an isomorphism, induced by a linear change $ \phi $ of coordinates of $R$ which maps the $l_i$ to the the last $d$ variables of $R$; and $G = F^{-1}$.

The algorithm may not terminate over a small finite field. If it terminates, the result is correct.

###### Examples

```
julia> R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [x*y, x*z]));
julia> L = noether_normalization(A);
julia> L[1]
2-element Vector{MPolyQuoElem{fmpq_mpoly}}:
-2*x + y
-5*y + z
julia> L[2]
Map with following data
Domain:
=======
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(x*y, x*z)
Codomain:
=========
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(2*x^2 + x*y, 10*x^2 + 5*x*y + x*z)
julia> L[3]
Map with following data
Domain:
=======
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(2*x^2 + x*y, 10*x^2 + 5*x*y + x*z)
Codomain:
=========
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(x*y, x*z)
```

## Normalization

`normalization`

— Method`normalization(A::MPolyQuo; alg = :equidimDec)`

Find the normalization of a reduced affine algebra over a perfect field $K$. That is, given the quotient $A=R/I$ of a multivariate polynomial ring $R$ over $K$ modulo a radical ideal $I$, compute the integral closure $\overline{A}$ of $A$ in its total ring of fractions $Q(A)$, together with the embedding $f: A \rightarrow \overline{A}$.

**Implemented Algorithms and how to Read the Output**

The function relies on the algorithm of Greuel, Laplagne, and Seelisch which proceeds by finding a suitable decomposition $I=I_1\cap\dots\cap I_r$ into radical ideals $I_k$, together with maps $A = R/I \rightarrow A_k=\overline{R/I_k}$ which give rise to the normalization map of $A$:

\[A\hookrightarrow A_1\times \dots\times A_r=\overline{A}\]

For each $k$, the function specifies two representations of $A_k$: It returns an array of triples $(A_k, f_k, \mathfrak a_k)$, where $A_k$ is represented as an affine $K$-algebra, and $f_k$ as a map of affine $K$-algebras. The third entry $\mathfrak a_k$ is a tuple $(d_k, J_k)$, consisting of an element $d_k\in A$ and an ideal $J_k\subset A$, such that $\frac{1}{d_k}J_k = A_k$ as $A$-submodules of the total ring of fractions of $A$.

By default (`alg = :equidimDec`

), as a first step on its way to find the decomposition $I=I_1\cap\dots\cap I_r$, the algorithm computes an equidimensional decomposition of the radical ideal $I$. Alternatively, if specified by `alg = :primeDec`

, the algorithm computes $I=I_1\cap\dots\cap I_r$ as the prime decomposition of the radical ideal $I$.

See Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010).

The function does not check whether $A$ is reduced. Use `is_reduced(A)`

in case you are unsure (this may take some time).

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [(x^2-y^3)*(x^2+y^2)*x]));
julia> L = normalization(A);
julia> size(L)
(2,)
julia> LL = normalization(A, alg = :primeDec);
julia> size(LL)
(3,)
julia> LL[1][1]
Quotient of Multivariate Polynomial Ring in T(1), x, y over Rational Field by ideal(-T(1)*y + x, -T(1)*x + y^2, T(1)^2 - y, -x^2 + y^3)
julia> LL[1][2]
Map with following data
Domain:
=======
Quotient of Multivariate Polynomial Ring in x, y over Rational Field by ideal(x^5 - x^3*y^3 + x^3*y^2 - x*y^5)
Codomain:
=========
Quotient of Multivariate Polynomial Ring in T(1), x, y over Rational Field by ideal(-T(1)*y + x, -T(1)*x + y^2, T(1)^2 - y, -x^2 + y^3)
julia> LL[1][3]
(y, ideal(x, y))
```

`normalization_with_delta`

— Method`normalization_with_delta(A::MPolyQuo; alg = :equidimDec)`

Compute the normalization

\[A\hookrightarrow A_1\times \dots\times A_r=\overline{A}\]

of $A$ as does `normalize(A)`

, but return additionally the `delta invariant`

of $A$, that is, the dimension

\[\dim_K(\overline{A}/A)\]

.

**How to Read the Output**

The return value is a tuple whose first element is `normalize(A)`

, whose second element is an array containing the delta invariants of the $A_k$, and whose third element is the (total) delta invariant of $A$. The return value -1 in the third element indicates that the delta invariant is infinite.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"]);
julia> A, _ = quo(R, ideal(R, [(x^2-y^3)*(x^2+y^2)*x]));
julia> L = normalization_with_delta(A);
julia> L[2]
3-element Vector{Int64}:
1
1
0
julia> L[3]
13
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> A, _ = quo(R, ideal(R, [z^3-x*y^4]))
(Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x*y^4 + z^3), Map from
Multivariate Polynomial Ring in x, y, z over Rational Field to Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x*y^4 + z^3) defined by a julia-function with inverse)
julia> L = normalization_with_delta(A)
(Tuple{MPolyQuo{fmpq_mpoly}, Oscar.MPolyAnyMap{MPolyQuo{fmpq_mpoly}, MPolyQuo{fmpq_mpoly}, Nothing, MPolyQuoElem{fmpq_mpoly}}, Tuple{MPolyQuoElem{fmpq_mpoly}, MPolyQuoIdeal{fmpq_mpoly}}}[(Quotient of Multivariate Polynomial Ring in T(1), T(2), x, y, z over Rational Field by ideal(T(1)*y - T(2)*z, T(2)*y - z, -T(1)*z + x*y^2, T(1)^2 - x*z, T(1)*T(2) - x*y, -T(1) + T(2)^2, x*y^4 - z^3), Map with following data
Domain:
=======
Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x*y^4 + z^3)
Codomain:
=========
Quotient of Multivariate Polynomial Ring in T(1), T(2), x, y, z over Rational Field by ideal(T(1)*y - T(2)*z, T(2)*y - z, -T(1)*z + x*y^2, T(1)^2 - x*z, T(1)*T(2) - x*y, -T(1) + T(2)^2, x*y^4 - z^3), (z^2, ideal(x*y^2*z, x*y^3, z^2)))], [-1], -1)
```

## Integral Bases

`integral_basis`

— Method`integral_basis(f::MPolyElem, i::Int; alg = :normal_local)`

Given a polynomial $f$ in two variables with coefficients in a field $K$, and given an integer $i\in\{1,2\}$ specifying one of the variables, $f$ must be irreducible and monic in the specified variable: Say, $f\in\mathbb K[x,y]$ is monic in $y$. Then the normalization of $A = K[x,y]/\langle f \rangle$, that is, the integral closure $\overline{A}$ of $A$ in its quotient field, is a free module over $K[x]$ of finite rank, and any set of free generators for $\overline{A}$ over $K[x]$ is called an *integral basis* for $\overline{A}$ over $K[x]$. The function returns a pair $(d, V)$, where $d$ is an element of $A$, and $V$ is a vector of elements in $A$, such that the fractions $v/d, v\in V$, form an integral basis for $\overline{A}$ over $K[x]$.

By default (`alg = :normal_local`

), the function relies on the local-to-global approach to normalization presented in Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Andreas Steenpaß, Stefan Steidel (2013). Alternatively, if specified by `alg = :normal_global`

, the global normalization algorithm in Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010) is used. If $K = \mathbb Q$, it is recommended to apply the algorithm in Janko Böhm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister (2019), which makes use of Puiseux expansions and Hensel lifting (`alg = :hensel`

).

The conditions on $f$ are automatically checked.

**Examples**

```
julia> R, (x, y) = PolynomialRing(QQ, ["x", "y"])
(Multivariate Polynomial Ring in x, y over Rational Field, fmpq_mpoly[x, y])
julia> f = (y^2-2)^2 + x^5
x^5 + y^4 - 4*y^2 + 4
julia> integral_basis(f, 2)
(x^2, MPolyQuoElem{fmpq_mpoly}[x^2, x^2*y, y^2 - 2, y^3 - 2*y])
```

## Tests on Affine Algebras

### Reducedness Test

`is_reduced`

— Method`is_reduced(A::MPolyQuo)`

Given an affine algebra `A`

, return `true`

if `A`

is reduced, `false`

otherwise.

The function computes the radical of the modulus of `A`

. This may take some time.

**Examples**

```
julia> R, (x,) = PolynomialRing(QQ, ["x"])
(Multivariate Polynomial Ring in x over Rational Field, fmpq_mpoly[x])
julia> A, _ = quo(R, ideal(R, [x^4]))
(Quotient of Multivariate Polynomial Ring in x over Rational Field by ideal(x^4), Map from
Multivariate Polynomial Ring in x over Rational Field to Quotient of Multivariate Polynomial Ring in x over Rational Field by ideal(x^4) defined by a julia-function with inverse)
julia> is_reduced(A)
false
```

### Normality Test

`is_normal`

— Method`is_normal(A::MPolyQuo)`

Given an affine algebra `A`

over a perfect field, return `true`

if `A`

is normal, `false`

otherwise.

This function performs the first step of the normalization algorithm of Greuel, Laplagne, and Seelisch Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch (2010) and may, thus, be more efficient than computing the full normalization of `A`

.

**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> A, _ = quo(R, ideal(R, [z^2-x*y]))
(Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x*y + z^2), Map from
Multivariate Polynomial Ring in x, y, z over Rational Field to Quotient of Multivariate Polynomial Ring in x, y, z over Rational Field by ideal(-x*y + z^2) defined by a julia-function with inverse)
julia> is_normal(A)
true
```

### Cohen-Macaulayness Test

iscohenmacaulay(R)

###### Examples

## Hilbert Series and Hilbert Polynomial

Given a multivariate polynomial ring $R$ over a field $K$ together with a (multi)grading on $R$ by a finitely generated abelian group $G$, let $I$ be an ideal of $R$ which is homogeneous with respect to this grading. Then the affine $K-$algebra $A=R/I$ inherits the grading: $A = \bigoplus_{g\in G} A_g$. Suppose now that $R$ is positively graded by $G$. That is, $G$ is free and each graded piece $R_g$ has finite dimension. Then also $A_g$ is a finite dimensional $K$-vector space for each $g$, and we have the well-defined *Hilbert function* of $A$,

\[H(A, \underline{\phantom{d}}): G \to \N, \; g\mapsto \dim_K(A_g).\]

The *Hilbert series* of $A$ is the generating function

\[H_A(\mathbb t)=\sum_{g\in G} H(A, g) \mathbb t^g\]

(see Section 8.2 in Ezra Miller, Bernd Sturmfels (2005) for a formal discussion extending the classical case of $\mathbb Z$-gradings with positive weights to the more general case of multigradings). As in the classical case, the infinitely many values of the Hilbert function can be expressed in finite terms by representing the Hilbert series as a rational function (see Theorem 8.20 in Ezra Miller, Bernd Sturmfels (2005) for a precise statement).

By a result of Macaulay, if $A = R/I$ is an affine algebra, and $L_{>}(I)$ is the leading ideal of $I$ with respect to a global monomial ordering $>$, then the Hilbert function of $A$ equals that of $R/L_{>}(I)$ (see Theorem 15.26 in David Eisenbud (1995)). Thus, using Gröbner bases, the computation of Hilbert series can be reduced to the case where the modulus of the affine algebra is a monomial ideal. In the latter case, we face a problem of combinatorial nature, and there are various strategies of how to proceed (see Martin Kreuzer, Lorenzo Robbiano (2005)). The functions `hilbert_series`

, `hilbert_series_reduced`

, `hilbert_series_expanded`

, `hilbert_function`

, `hilbert_polynomial`

, and `degree`

address the case of $\mathbb Z$-gradings with positive weights, relying on corresponding Singular functionality. The functions `multi_hilbert_series`

, `multi_hilbert_series_reduced`

, and `multi_hilbert_function`

offer a variety of different strategies and allow one to handle positive gradings in general.

### $\mathbb Z$-Gradings With Positive Weights

Let $R=K[x_1, \dots x_n]$ be a polynomial ring in $n$ variables over a field $K$. Assign positive integer weights $w_i$ to the variables $x_i$, and grade $R=\bigoplus_{d\in \mathbb Z} R_d=\bigoplus_{d\geq 0} R_d$ according to the corresponding weighted degree. Let $I$ be an ideal of $R$ which is homogeneous with respect to this grading. Then the affine $K$-algebra $A=R/I$ inherits the grading: $A = \bigoplus_{d\geq 0} A_d$, where each graded piece $A_d$ is a finite dimensional $K$-vector space. In this situation, the *Hilbert function* of $A$ is of type

\[H(A, \underline{\phantom{d}}): \N \to \N, \;d \mapsto \dim_K(d),\]

and the *Hilbert series* of $A$ is the formal power series

\[H_A(t)=\sum_{d\geq 0} H(A, d) t^d\in\mathbb Z[[t]].\]

The Hilbert series can be written as a rational function $p(t)/q(t)$, with denominator

\[q(t) = (1-t^{w_1})\cdots (1-t^{w_n}).\]

In the standard $\mathbb Z$-graded case, where the weights on the variables are all 1, the Hilbert function is of polynomial nature: There exists a unique polynomial $P_A(t)\in\mathbb{Q}[t]$, the *Hilbert polynomial*, which satisfies $H(M,d)=P_M(d)$ for all $d \gg 0$. Furthermore, the *degree* of $A$ is defined as the dimension of $A$ over $K$ if this dimension is finite, and as the integer $d$ such that the leading term of the Hilbert polynomial has the form $d t^e/e!$, otherwise.

`hilbert_series`

— Method`hilbert_series(A::MPolyQuo)`

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from a $\mathbb Z$-grading on the polynomial ring $R$ defined by assigning positive integer weights to the variables, return a pair $(p,q)$, say, of univariate polynomials $p, q\in\mathbb Z[t]$ such that $p/q$ represents the Hilbert series of $A$ as a rational function with denominator

\[q = (1-t^{w_1})\cdots (1-t^{w_n}),\]

where $n$ is the number of variables of $R$, and $w_1, \dots, w_n$ are the assigned weights.

See also `hilbert_series_reduced`

.

**Examples**

```
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> hilbert_series(A)
(2*t^3 - 3*t^2 + 1, t^4 - 4*t^3 + 6*t^2 - 4*t + 1)
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3]);
julia> A, _ = quo(R, ideal(R, [x*y*z]));
julia> hilbert_series(A)
(-t^6 + 1, -t^6 + t^5 + t^4 - t^2 - t + 1)
```

`hilbert_series_reduced`

— Method`hilbert_series_reduced(A::MPolyQuo)`

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from a $\mathbb Z$-grading on the polynomial ring $R$ defined by assigning positive integer weights to the variables, return a pair $(p,q)$, say, of univariate polynomials $p, q\in\mathbb Z[t]$ such that $p/q$ represents the Hilbert series of $A$ as a rational function written in lowest terms.

See also `hilbert_series`

.

**Examples**

```
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> hilbert_series_reduced(A)
(2*t + 1, t^2 - 2*t + 1)
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3]);
julia> A, _ = quo(R, ideal(R, [x*y*z]));
julia> hilbert_series(A)
(-t^6 + 1, -t^6 + t^5 + t^4 - t^2 - t + 1)
julia> hilbert_series_reduced(A)
(t^2 - t + 1, t^2 - 2*t + 1)
```

`hilbert_series_expanded`

— Method`hilbert_series_expanded(A::MPolyQuo, d::Int)`

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from a $\mathbb Z$-grading on the polynomial ring $R$ defined by assigning positive integer weights to the variables, return the Hilbert series of $A$ to precision $d$.

**Examples**

```
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> hilbert_series_expanded(A, 7)
1 + 4*t + 7*t^2 + 10*t^3 + 13*t^4 + 16*t^5 + 19*t^6 + 22*t^7 + O(t^8)
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3]);
julia> A, _ = quo(R, ideal(R, [x*y*z]));
julia> hilbert_series_expanded(A, 5)
1 + t + 2*t^2 + 3*t^3 + 4*t^4 + 5*t^5 + O(t^6)
```

`hilbert_function`

— Method`hilbert_function(A::MPolyQuo, d::Int)`

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from a $\mathbb Z$-grading on the polynomial ring $R$ defined by assigning positive integer weights to the variables, return the value $H(A, d),$ where

\[H(A, \underline{\phantom{d}}): \N \rightarrow \N, \; d \mapsto \dim_K A_d,\]

is the Hilbert function of $A$.

**Examples**

```
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> hilbert_function(A,7)
22
julia> R, (x, y, z) = GradedPolynomialRing(QQ, ["x", "y", "z"], [1, 2, 3]);
julia> A, _ = quo(R, ideal(R, [x*y*z]));
julia> hilbert_function(A, 5)
5
```

`hilbert_polynomial`

— Method` hilbert_polynomial(A::MPolyQuo)`

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from the standard $\mathbb Z$-grading on the polynomial ring $R$, return the Hilbert polynomial of $A$.

**Examples**

```
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> hilbert_polynomial(A)
3*t + 1
```

`degree`

— Method`degree(A::MPolyQuo)`

Given a $\mathbb Z$-graded affine algebra $A = R/I$ over a field $K$, where the grading is inherited from the standard $\mathbb Z$-grading on the polynomial ring $R$, return the degree of $A$.

**Examples**

```
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"]);
julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> degree(A)
3
```

### Positive Gradings in General

`multi_hilbert_series`

— Method`multi_hilbert_series(A::MPolyQuo; alg::Symbol=:BayerStillmanA)`

Return the Hilbert series of the positively graded affine algebra `A`

.

The advanced user can select a `alg`

for the computation; see the code for details.

**Examples**

```
julia> W = [1 1 1; 0 0 -1];
julia> R, x = GradedPolynomialRing(QQ, ["x[1]", "x[2]", "x[3]"], W)
(Multivariate Polynomial Ring in x[1], x[2], x[3] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [1 0]
x[3] -> [1 -1], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3]])
julia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);
julia> A, _ = quo(R, I);
julia> H = multi_hilbert_series(A);
julia> H[1][1]
-t[1]^7*t[2]^-2 + t[1]^6*t[2]^-1 + t[1]^6*t[2]^-2 + t[1]^5*t[2]^-4 - t[1]^4 + t[1]^4*t[2]^-2 - t[1]^4*t[2]^-4 - t[1]^3*t[2]^-1 - t[1]^3*t[2]^-2 + 1
julia> H[1][2]
-t[1]^3*t[2]^-1 + t[1]^2 + 2*t[1]^2*t[2]^-1 - 2*t[1] - t[1]*t[2]^-1 + 1
julia> H[2][1]
GrpAb: Z^2
julia> H[2][2]
Identity map with
Domain:
=======
GrpAb: Z^2
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> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> H = multi_hilbert_series(A);
julia> H[1][1]
2*t^3 - 3*t^2 + 1
julia> H[1][2]
t^4 - 4*t^3 + 6*t^2 - 4*t + 1
julia> H[2][1]
GrpAb: Z
julia> H[2][2]
Map with following data
Domain:
=======
Abelian group with structure: Z
Codomain:
=========
(General) abelian group with relation matrix
[1 -1]
with structure of Abelian group with structure: Z
```

`multi_hilbert_series_reduced`

— Method`multi_hilbert_series_reduced(A::MPolyQuo; alg::Symbol=:BayerStillmanA)`

Return the reduced Hilbert series of the positively graded affine algebra `A`

.

The advanced user can select a `alg`

for the computation; see the code for details.

**Examples**

```
julia> W = [1 1 1; 0 0 -1];
julia> R, x = GradedPolynomialRing(QQ, ["x[1]", "x[2]", "x[3]"], W)
(Multivariate Polynomial Ring in x[1], x[2], x[3] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [1 0]
x[3] -> [1 -1], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3]])
julia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);
julia> A, _ = quo(R, I);
julia> H = multi_hilbert_series_reduced(A);
julia> H[1][1]
-t[1]^5*t[2]^-1 + t[1]^3 + t[1]^3*t[2]^-3 + t[1]^2 + t[1]^2*t[2]^-1 + t[1]^2*t[2]^-2 + t[1] + t[1]*t[2]^-1 + 1
julia> H[1][2]
-t[1] + 1
julia> H[2][1]
GrpAb: Z^2
julia> H[2][2]
Identity map with
Domain:
=======
GrpAb: Z^2
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> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> H = multi_hilbert_series_reduced(A);
julia> H[1][1]
2*t + 1
julia> H[1][2]
t^2 - 2*t + 1
julia> H[2][1]
GrpAb: Z
julia> H[2][2]
Map with following data
Domain:
=======
Abelian group with structure: Z
Codomain:
=========
(General) abelian group with relation matrix
[1 -1]
with structure of Abelian group with structure: Z
```

`multi_hilbert_function`

— Method`multi_hilbert_function(A::MPolyQuo, g::GrpAbFinGenElem)`

Given a positively graded affine algebra $A$ over a field $K$ with grading group $G$, say, and given an element $g$ of $G$, return the value $H(A, g)$ of the Hilbert function

\[H(A, \underline{\phantom{d}}): G \to \N, \; g\mapsto \dim_K(A_g).\]

`multi_hilbert_function(A::MPolyQuo, g::Vector{<:IntegerUnion})`

Given a positively $\mathbb Z^m$-graded affine algebra $A$ over a field $K$, and given a vector $g$ of $m$ integers, convert $g$ into an element of the grading group of $A$, and return the value $H(A, g)$ as above.

`multi_hilbert_function(A::MPolyQuo, g::IntegerUnion)`

Given a positively $\mathbb Z$-graded affine algebra $A$ over a field $K$, and given an integer $g$, convert $g$ into an element of the grading group of $A$, and return the value $H(A, g)$ as above.

**Examples**

```
julia> W = [1 1 1; 0 0 -1];
julia> R, x = GradedPolynomialRing(QQ, ["x[1]", "x[2]", "x[3]"], W)
(Multivariate Polynomial Ring in x[1], x[2], x[3] over Rational Field graded by
x[1] -> [1 0]
x[2] -> [1 0]
x[3] -> [1 -1], MPolyElem_dec{fmpq, fmpq_mpoly}[x[1], x[2], x[3]])
julia> I = ideal(R, [x[1]^3*x[2], x[2]*x[3]^2, x[2]^2*x[3], x[3]^4]);
julia> A, _ = quo(R, I);
julia> multi_hilbert_function(A::MPolyQuo, [1, 0])
2
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"], [-1, -1, -1, -1]);
julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> multi_hilbert_function(A, -7)
22
julia> G = abelian_group(fmpz_mat([1 -1]));
julia> g = gen(G, 1);
julia> W = [g, g, g, g];
julia> R, (w, x, y, z) = GradedPolynomialRing(QQ, ["w", "x", "y", "z"], W);
julia> A, _ = quo(R, ideal(R, [w*y-x^2, w*z-x*y, x*z-y^2]));
julia> multi_hilbert_function(A, 7*g)
22
```