Skip to content

Commit

Permalink
addresseing Issue #2427 (#2473)
Browse files Browse the repository at this point in the history
* addresseing Issue #2427

---------

Co-authored-by: Matthias Zach <85350711+HechtiDerLachs@users.noreply.github.com>
Co-authored-by: anne <anne@krueger-berg.de>
  • Loading branch information
3 people committed Jun 18, 2023
1 parent 8be1e35 commit 04c90ae
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 15 deletions.
8 changes: 7 additions & 1 deletion experimental/Schemes/IdealSheaves.jl
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,13 @@ end
# return W, spec_dict
#end
#
function isone(I::IdealSheaf)
return all(x->isone(I(x)), affine_charts(scheme(I)))
end

function is_prime(I::IdealSheaf)
return all(U->is_prime(I(U)), basic_patches(default_covering(space(I))))
!isone(I) || return false
return all(U->(is_one(I(U)) || is_prime(I(U))), basic_patches(default_covering(space(I))))
end

function _minimal_power_such_that(I::Ideal, P::PropertyType) where {PropertyType}
Expand Down Expand Up @@ -586,6 +590,7 @@ More generally, a point ``x`` on a scheme ``X`` associated to a quasi-coherent s
Note that maximal associated points of an ideal sheaf on an affine scheme ``Spec(A)`` correspond to the minimal associated primes of the corresponding ideal in ``A``.
"""
function maximal_associated_points(I::IdealSheaf)
!isone(I) || return typeof(I)[]
X = scheme(I)
OOX = OO(X)

Expand Down Expand Up @@ -650,6 +655,7 @@ If ``U = Spec(A)`` is an affine open on a locally noetherian scheme ``X``, ``x \
"""
function associated_points(I::IdealSheaf)
!isone(I) || return typeof(I)[]
X = scheme(I)
OOX = OO(X)
charts_todo = copy(affine_charts(X)) ## todo-list of charts
Expand Down
46 changes: 32 additions & 14 deletions src/Rings/mpoly-ideals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ end
@doc raw"""
primary_decomposition(I::MPolyIdeal; algorithm = :GTZ, cache=true)
Return a minimal primary decomposition of `I`. If `I` is the unit ideal, return `[ideal(1)]`.
Return a minimal primary decomposition of `I`.
The decomposition is returned as a vector of tuples $(Q_1, P_1), \dots, (Q_t, P_t)$, say,
where each $Q_i$ is a primary ideal with associated prime $P_i$, and where the intersection of
Expand Down Expand Up @@ -533,14 +533,18 @@ function _compute_primary_decomposition(I::MPolyIdeal; algorithm::Symbol=:GTZ)
else
error("base ring not implemented")
end
return [(ideal(R, q[1]), ideal(R, q[2])) for q in L]
V = [(ideal(R, q[1]), ideal(R, q[2])) for q in L]
if length(V) == 1 && is_one(gen(V[1][1], 1))
return Tuple{typeof(I), typeof(I)}[]
end
return V
end

########################################################
@doc raw"""
absolute_primary_decomposition(I::MPolyIdeal{<:MPolyRingElem{QQFieldElem}})
If `I` is an ideal in a multivariate polynomial ring over the rationals, return an absolute minimal primary decomposition of `I`.
Given an ideal `I` in a multivariate polynomial ring over the rationals, return an absolute minimal primary decomposition of `I`.
Return the decomposition as a vector of tuples $(Q_i, P_i, P_{ij}, d_{ij})$, say,
where $(Q_i, P_i)$ is a (primary, prime) tuple as returned by `primary_decomposition(I)`,
Expand Down Expand Up @@ -625,11 +629,14 @@ Multivariate polynomial ring in 2 variables over number field graded by
decomp = d[:primary_decomp]
absprimes = d[:absolute_primes]
@assert length(decomp) == length(absprimes)
return [(_map_last_var(R, decomp[i][1], 1, one(QQ)),
_map_last_var(R, decomp[i][2], 1, one(QQ)),
_map_to_ext(R, absprimes[i][1]),
absprimes[i][2]::Int)
for i in 1:length(decomp)]
V = [(_map_last_var(R, decomp[i][1], 1, one(QQ))) for i in 1:length(decomp)]
if length(V) == 1 && is_one(gen(V[1], 1))
return Tuple{MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{QQMPolyRingElem}, MPolyIdeal{AbstractAlgebra.Generic.MPoly{nf_elem}}, Int64}[]
end
return [(V[i], _map_last_var(R, decomp[i][2], 1, one(QQ)),
_map_to_ext(R, absprimes[i][1]),
absprimes[i][2]::Int)
for i in 1:length(decomp)]
end

# the ideals in QQbar[x] come back in QQ[x,a] with an extra variable a added
Expand Down Expand Up @@ -670,7 +677,6 @@ end
minimal_primes(I::MPolyIdeal; algorithm::Symbol = :GTZ)
Return a vector containing the minimal associated prime ideals of `I`.
If `I` is the unit ideal, return `[ideal(1)]`.
# Implemented Algorithms
Expand Down Expand Up @@ -739,7 +745,11 @@ function minimal_primes(I::MPolyIdeal; algorithm::Symbol = :GTZ)
else
error("base ring not implemented")
end
return [ideal(R, i) for i in l]
V = [ideal(R, i) for i in l]
if length(V) == 1 && is_one(gen(V[1], 1))
return typeof(I)[]
end
return V
end
#######################################################
@doc raw"""
Expand All @@ -749,7 +759,7 @@ Return a vector of equidimensional ideals where the last entry is the
equidimensional hull of `I`, that is, the intersection of the primary
components of `I` of maximal dimension. Each of the previous entries
is an ideal of lower dimension whose associated primes are exactly the associated
primes of `I` of that dimension. If `I` is the unit ideal, return `[ideal(1)]`.
primes of `I` of that dimension.
# Implemented Algorithms
Expand Down Expand Up @@ -777,15 +787,19 @@ julia> L = equidimensional_decomposition_weak(I)
@req coefficient_ring(R) isa AbstractAlgebra.Field "The coefficient ring must be a field"
singular_assure(I)
l = Singular.LibPrimdec.equidim(I.gens.Sx, I.gens.S)
return [ideal(R, i) for i in l]
V = [ideal(R, i) for i in l]
if length(V) == 1 && is_one(gen(V[1], 1))
return typeof(I)[]
end
return V
end

@doc raw"""
equidimensional_decomposition_radical(I::MPolyIdeal)
Return a vector of equidimensional radical ideals increasingly ordered by dimension.
For each dimension, the returned radical ideal is the intersection of the associated primes
of `I` of that dimension. If `I` is the unit ideal, return `[ideal(1)]`.
of `I` of that dimension.
# Implemented Algorithms
Expand Down Expand Up @@ -813,7 +827,11 @@ julia> L = equidimensional_decomposition_radical(I)
@req coefficient_ring(R) isa AbstractAlgebra.Field "The coefficient ring must be a field"
singular_assure(I)
l = Singular.LibPrimdec.prepareAss(I.gens.Sx, I.gens.S)
return [ideal(R, i) for i in l]
V = [ideal(R, i) for i in l]
if length(V) == 1 && is_one(gen(V[1], 1))
return typeof(I)[]
end
return V
end
#######################################################
@doc raw"""
Expand Down
5 changes: 5 additions & 0 deletions test/Rings/mpoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ end
I = ideal(R, [(z+y)*(z^2+y^2)*(z^3+2*y^3)^2, x^3-y*z^2])
d = absolute_primary_decomposition(I)
@test length(d) == 5

# is_prime
R, (x, y) = polynomial_ring(QQ, ["x", "y"])
I = ideal(R, [one(R)])
@test is_prime(I) == false
end

@testset "Groebner" begin
Expand Down

0 comments on commit 04c90ae

Please sign in to comment.