From 175c8b9e7a970e0141e8957df4a1fc019e1ae856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20P=2E?= Date: Tue, 17 Jun 2025 15:02:46 +0200 Subject: [PATCH] Dimension and Hilbert: handle zero ideal --- src/algorithms/dimension.jl | 6 ++---- src/algorithms/hilbert.jl | 11 ++++------- test/algorithms/dimension.jl | 4 ++++ test/algorithms/hilbert.jl | 9 +++++++++ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/algorithms/dimension.jl b/src/algorithms/dimension.jl index 89ade19..c17e522 100644 --- a/src/algorithms/dimension.jl +++ b/src/algorithms/dimension.jl @@ -26,10 +26,7 @@ function dimension(I::Ideal{T}) where T <: MPolyRingElem R = parent(first(gb)) res = Set([trues(ngens(R))]) - lead_exps = Vector{Vector{Int}}(undef, length(gb)) - for i in eachindex(gb) - lead_exps[i] = _lead_exp_ord(gb[i], :degrevlex) - end + lead_exps = [ _lead_exp_ord(g, :degrevlex) for g in gb if !iszero(g) ] for lexp in lead_exps nz_exps = (!iszero).(lexp) nz_exps_ind = findall(nz_exps) @@ -62,6 +59,7 @@ function _all_lesseq(a::BitVector, b::BitVector)::Bool end function _lead_exp_ord(p::MPolyRingElem, order::Symbol) + @req !iszero(p) "Zero polynomial does not have a leading term" R = parent(p) internal_ordering(R)==order && return first(exponent_vectors(p)) diff --git a/src/algorithms/hilbert.jl b/src/algorithms/hilbert.jl index 2ff270c..a42103e 100644 --- a/src/algorithms/hilbert.jl +++ b/src/algorithms/hilbert.jl @@ -27,11 +27,8 @@ function hilbert_series(I::Ideal{T}) where T <: MPolyRingElem gb = get!(I.gb, 0) do groebner_basis(I, complete_reduction = true) end - lead_exps = Vector{Vector{Int}}(undef, length(gb)) - for i in eachindex(gb) - lead_exps[i] = _lead_exp_ord(gb[i], :degrevlex) - end - return _hilbert_series_mono(lead_exps) + lead_exps = [ _lead_exp_ord(g, :degrevlex) for g in gb if !iszero(g) ] + return _hilbert_series_mono(lead_exps, nvars(parent(I))) end @doc Markdown.doc""" @@ -134,11 +131,11 @@ function hilbert_polynomial(I::Ideal{T}) where T <: MPolyRingElem end # Computes hilbert series of a monomial ideal on input list of exponents -function _hilbert_series_mono(exps::Vector{Vector{Int}}) +function _hilbert_series_mono(exps::Vector{Vector{Int}}, nr_vars::Int) h = _num_hilbert_series_mono(exps) t = gen(parent(h)) - return h//(1-t)^length(first(exps)) + return h//(1-t)^nr_vars end # Computes numerator hilbert series of a monomial ideal on input list of exponents diff --git a/test/algorithms/dimension.jl b/test/algorithms/dimension.jl index 8fd8458..dc836a4 100644 --- a/test/algorithms/dimension.jl +++ b/test/algorithms/dimension.jl @@ -9,6 +9,10 @@ @test iszero(dimension(I)) @test iszero(I.dim) + I = Ideal([R(0)]) + @test dimension(I) == ngens(R) + @test I.dim == ngens(R) + I = Ideal([R(1)]) @test dimension(I) == -1 @test I.dim == -1 diff --git a/test/algorithms/hilbert.jl b/test/algorithms/hilbert.jl index 361e92e..80fedb5 100644 --- a/test/algorithms/hilbert.jl +++ b/test/algorithms/hilbert.jl @@ -21,6 +21,15 @@ @test iszero(hilbert_dimension(I)) @test 4 == hilbert_degree(I) + I = Ideal([R(0)]) + HS = 1//(1-t)^(nvars(R)) + HP = (1//6*s^3 + s^2 + 11//6*s + 1, 0) + + @test HS == hilbert_series(I) + @test HP == hilbert_polynomial(I) + @test nvars(R) == hilbert_dimension(I) + @test isone(hilbert_degree(I)) + I = Ideal([R(1)]) @test iszero(hilbert_series(I)) @test all(iszero, hilbert_polynomial(I))