Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More tests for gradings. Corrections. #1134

Merged
merged 4 commits into from
Mar 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 8 additions & 35 deletions docs/src/CommutativeAlgebra/affine_algebras.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,10 @@ minimal_subalgebra_generators(V::Vector{T}) where T <: Union{MPolyElem, MPolyQuo
## Noether Normalization

```@docs
noether_normalization(A::MPolyQuo)
noether_normalization(A::MPolyQuo{<:MPolyElem{<:FieldElem}})
```

###### Example
###### Examples

```@repl oscar
R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"]);
Expand All @@ -305,32 +305,14 @@ L[1]
L[2]
L[3]
```

## Normalization of Rings
## Normalization

```@docs
normalization(A::MPolyQuo)
normalization_with_delta(A::MPolyQuo)
```

###### Examples

```@repl oscar
R, (x, y) = PolynomialRing(QQ, ["x", "y"])
A, _ = quo(R, ideal(R, [(x^2-y^3)*(x^2+y^2)*x]))
L = normalization(A)
```

```@repl oscar
R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
A, _ = quo(R, ideal(R, [z^3-x*y^4]))
L = normalization(A)
normalization(A::MPolyQuo{<:MPolyElem{<:FieldElem}})
```

```@repl oscar
R, (x, y) = PolynomialRing(QQ, ["x", "y"])
A, _ = quo(R, ideal(R, [(x^2-y^3)*(x^2+y^2)*x]))
L = normalization_with_delta(A)
```@docs
normalization_with_delta(A::MPolyQuo{<:MPolyElem{<:FieldElem}})
```

## Integral Bases
Expand All @@ -339,15 +321,6 @@ L = normalization_with_delta(A)
integral_basis(f::MPolyElem, i::Int)
```

###### Example


```@repl oscar
R, (x, y) = PolynomialRing(QQ, ["x", "y"])
f = (y^2-2)^2 + x^5
integral_basis(f, 2)
```

## Tests on Affine Algebras

### Reducedness Test
Expand All @@ -362,7 +335,7 @@ isreduced(Q::MPolyQuo)
isnormal(A::MPolyQuo)
```

###### Example
###### Examples

```@repl oscar
R, (x, y, z) = PolynomialRing(QQ, ["x", "y", "z"])
Expand All @@ -374,7 +347,7 @@ isnormal(A)

iscohenmacaulay(R)

###### Example
###### Examples

## Hilbert Series and Hilbert Polynomial

Expand Down
15 changes: 10 additions & 5 deletions docs/src/CommutativeAlgebra/rings.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,14 @@ are thought of as column vectors in $\mathbb Z^m$, and $W$ as an $m \times n$-ma
entries in $\mathbb Z$. In particular, if $G = \mathbb Z$, then $W$ is thought of as a row vector
in $\mathbb Z^n$.

We refer to the textbooks [MS05](@cite) and [KR05](@cite) for details on multigradings. With respect to notation,
we follow the former book.

!!! note
Given a $G$-grading on $R$, we say that $R$ is *$G$-graded*, or simply that $R$ is *graded*.
We say that $R$ is *positively graded (by $G$)* if each graded part $R_g$ has finite rank.
Equivalently, the degree zero part consists of the constants only.

See [MS05](@cite) and [KR05](@cite) for details on multigradings.
We say that $R$ is *positively graded (by $G$)* if $G$ is torsion-free and each graded part $R_g$
has finite rank. The latter condition is equivalent to the condition that the degree zero
part consists of the constants only (see Theorem 8.6 in [MS05](@cite).


### Types
Expand Down Expand Up @@ -176,6 +178,10 @@ GradedPolynomialRing(C::Ring, V::Vector{String}, W; ordering=:lex)

### Tests on Graded Rings

```@docs
is_standard_graded(R::MPolyRing_dec)
```

```@docs
is_z_graded(R::MPolyRing_dec)
```
Expand Down Expand Up @@ -320,4 +326,3 @@ degree(f::MPolyElem_dec)

How to handle homomorphisms of multivariate polynomial rings and their graded versions is described in
a more general context in the section on affine algebras.

148 changes: 122 additions & 26 deletions src/Rings/mpoly-affine-algebras.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export noether_normalization, normalization, integral_basis
export isreduced, subalgebra_membership
export hilbert_series, hilbert_series_reduced, hilbert_series_expanded, hilbert_function, hilbert_polynomial, degree
export issurjective, isinjective, isbijective, inverse, preimage, isfinite
export _multi_hilbert_series, _multi_hilbert_series_reduced

##############################################################################
#
Expand Down Expand Up @@ -40,6 +41,10 @@ end
#
##############################################################################





@doc Markdown.doc"""
hilbert_series(A::MPolyQuo)

Expand Down Expand Up @@ -199,7 +204,7 @@ return `true` if `A` is normal, `false` otherwise.
"""
function isnormal(A::MPolyQuo)
_, _, d = normalization_with_delta(A)
return d == 1
return d == 0
end

##############################################################################
Expand Down Expand Up @@ -473,7 +478,7 @@ function _conv_normalize_data(A, l, br)
end

@doc Markdown.doc"""
normalization(A::MPolyQuo; alg = :equidimDec)
normalization(A::MPolyQuo{<:MPolyElem{<:FieldElem}}; 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$
Expand All @@ -486,11 +491,11 @@ $f: A \rightarrow \overline{A}$.
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
the normalization maps $f_k: R/I_k \rightarrow A_k=\overline{R/I_k}$, such that
maps $A = R/I \rightarrow A_k=\overline{R/I_k}$ which give rise to the normalization map of $A$:

$f=f_1\times \dots\times f_r: A \rightarrow A_1\times \dots\times A_r=\overline{A}$
$A\hookrightarrow A_1\times \dots\times A_r=\overline{A}$

is the normalization map of $A$. For each $k$, the function specifies two representations
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
Expand All @@ -506,8 +511,40 @@ See [GLS10](@cite).

!!! warning
The function does not check whether $A$ is reduced. Use `isreduced(A)` in case you are unsure (this may take some time).

# Examples
```jldoctest
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]
Algebra homomorphism with

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)

defining images of generators: MPolyQuoElem{fmpq_mpoly}[x, y]

julia> LL[1][3]
(y, ideal(x, y))
```
"""
function normalization(A::MPolyQuo; alg=:equidimDec)
function normalization(A::MPolyQuo{<:MPolyElem{<:FieldElem}}; alg=:equidimDec)
I = A.I
br = base_ring(A.R)
singular_assure(I)
Expand All @@ -516,11 +553,11 @@ function normalization(A::MPolyQuo; alg=:equidimDec)
end

@doc Markdown.doc"""
normalization_with_delta(A::MPolyQuo; alg = :equidimDec)
normalization_with_delta(A::MPolyQuo{<:MPolyElem{<:FieldElem}}; alg = :equidimDec)

Compute the normalization

$f=f_1\times \dots\times f_r: A \rightarrow A_1\times \dots\times A_r=\overline{A}$
$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
Expand All @@ -533,8 +570,43 @@ The return value is a tuple whose first element is `normalize(A)`, whose second
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
```jldoctest
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}, AlgHom{fmpq}, 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), Algebra homomorphism with

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)

defining images of generators: MPolyQuoElem{fmpq_mpoly}[x, y, z]
, (z^2, ideal(x*y^2*z, x*y^3, z^2)))], [-1], -1)
```
"""
function normalization_with_delta(A::MPolyQuo; alg=:equidimDec)
function normalization_with_delta(A::MPolyQuo{<:MPolyElem{<:FieldElem}}; alg=:equidimDec)
I = A.I
br = base_ring(A.R)
singular_assure(I)
Expand All @@ -550,18 +622,19 @@ end
##############################################################################

@doc Markdown.doc"""
noether_normalization(A::MPolyQuo)
noether_normalization(A::MPolyQuo{<:MPolyElem{<:FieldElem}})

Given an affine algebra $A=R/I$ over a field $K$, the return value is a triple $(V,F,G)$ such that:
$V$ is a vector of $d=\dim A$ elements $l_i$ of $A$, all represented by linear forms in $R$, and
such that $K[V]\rightarrow A$ is a Noether normalization for $A$; $F: A \rightarrow A$ is an
automorphism of $A$, induced by a linear change of coordinates of $R$, and mapping the
$l_i$ to the last $d$ variables of $A$; and $G = F^{-1}$.
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}$.

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

"""
function noether_normalization(A::MPolyQuo)
function noether_normalization(A::MPolyQuo{<:MPolyElem{<:FieldElem}})
I = A.I
R = base_ring(I)
singular_assure(I)
Expand All @@ -570,13 +643,18 @@ function noether_normalization(A::MPolyQuo)
i2 = [R(x) for x = gens(l[2])]
m = matrix([[coeff(x, y) for y = gens(R)] for x = i1])
mi = inv(m)
mi_arr = [collect(matrix([gens(R)])*map_entries(R, mi))[i] for i in 1:ngens(R)]
h1 = AlgebraHomomorphism(A, A, map(A, i1))
h2 = AlgebraHomomorphism(A, A, map(A, mi_arr))
return map(x->h2(A(x)), i2), h1, h2
###mi_arr = [collect(matrix([gens(R)])*map_entries(R, mi))[i] for i in 1:ngens(R)]
mi_arr = [collect(map_entries(R, mi)*gens(R))[i] for i in 1:ngens(R)]
h = AlgebraHomomorphism(R, R, i1)
V = map(x->h(x), gens(I))
B, _ = quo(R, ideal(R, V))
h1 = AlgebraHomomorphism(A, B, map(B, i1))
h2 = AlgebraHomomorphism(B, A, map(A, mi_arr))
return map(x->h2(B(x)), i2), h1, h2
end



##############################################################################
#
# Integral bases
Expand All @@ -593,27 +671,43 @@ Then the normalization of $A = Q[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]$. Relying on the algorithm by Böhm, Decker, Laplagne, and Pfister,
over $K[x]$. Relying on the algorithm by [BDLP19](@cite),
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]$. See [BDLP19](@cite).
form an integral basis for $\overline{A}$ over $K[x]$.

!!! note
The conditions on $f$ are automatically checked.

# Examples
```jldoctest
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])
```
"""
function integral_basis(f::MPolyElem, i::Int)
R = parent(f)

if typeof(R) <: MPolyRing_dec
throw(ArgumentError("Not implemented for decorated rings."))
end

if !(nvars(R) == 2)
throw(ArgumentError("The base ring must be a ring in two variables."))
throw(ArgumentError("The parent ring must be a polynomial ring in two variables."))
end

if !(i == 1 || i == 2)
throw(ArgumentError("The index $i must be either 1 or 2, indicating the integral variable."))
end

if !(base_ring(R) == QQ || base_ring(R) == Singular.QQ)
throw(ArgumentError("The base ring must be the rationals."))
if !(coefficient_ring(R) == QQ || base_ring(R) == Singular.QQ)
throw(ArgumentError("The coefficient ring must be the rationals."))
end

if !isone(coeff(f, [i], [degree(f, i)]))
Expand All @@ -626,6 +720,8 @@ function integral_basis(f::MPolyElem, i::Int)

SR = singular_ring(R)
l = Singular.LibIntegralbasis.integralBasis(SR(f), i, "isIrred")
return (R(l[2]), R.(gens(l[1])))
A, p = quo(R, ideal(R, [f]))
###return (R(l[2]), R.(gens(l[1])))
return (p(R(l[2])), [p(R(x)) for x = gens(l[1])])
end

Loading