diff --git a/src/Modules/hilbert.jl b/src/Modules/hilbert.jl index b9805d30a18d..00fddd997e56 100644 --- a/src/Modules/hilbert.jl +++ b/src/Modules/hilbert.jl @@ -21,7 +21,7 @@ function HSNum_module(SubM::SubquoModule{T}, HSRing::Ring, backend::Symbol=:Abbo return multi_hilbert_series(quo(P,ideal(P,[1]))[1]; parent=HSRing, backend=backend)[1][1] end GensLM = gens(LM); - L = [[] for _ in 1:r]; # L[k] will be list of monomial gens for k-th cooord + L = [[] for _ in 1:r]; # L[k] will be list of monomial gens for k-th coord # Nested loop below extracts the coordinate monomial ideals -- is there a better way? for g in GensLM SR = coordinates(ambient_representative(g)); # should have length = 1 @@ -37,19 +37,12 @@ function HSNum_module(SubM::SubquoModule{T}, HSRing::Ring, backend::Symbol=:Abbo @vprintln :hilbert 1 "HSNum_module: shifts are $(shifts)"; shift_expv = [gen_repr(d) for d in shifts]; @vprintln :hilbert 1 "HSNum_module: shift_expv are $(shift_expv)"; -### HSeriesRing = parent(HSeriesList[1]); -### @vprintln :hilbert 1 "HSNum_module: HSeriesRing = $(HSeriesRing)"; t = gens(HSRing); ScaleFactor = [_power_product(t,e) for e in shift_expv]; result = sum([ScaleFactor[k]*HSeriesList[k] for k in 1:r]); return result; end -# No longer needed -# function HSNum_module(F::FreeMod{T}; parent::Union{Nothing,Ring} = nothing) where T <: MPolyRingElem -# # ASSUME F is graded free module -# return HSNum_module(sub(F,gens(F))[1]; parent=parent) -# end @doc raw""" multi_hilbert_series(M::SubquoModule; parent::Union{Nothing,Ring} = nothing) @@ -93,6 +86,7 @@ julia> den function multi_hilbert_series(SubM::SubquoModule{T}; parent::Union{Nothing, Ring} = nothing, backend::Symbol = :Abbott) where T <: MPolyRingElem R = base_ring(SubM) @req coefficient_ring(R) isa AbstractAlgebra.Field "The coefficient ring must be a field" + @req is_positively_graded(R) "ring must be positively graded" # Wrap the case where G is abstractly isomorphic to ℤᵐ, but not realized as a # free Abelian group. @@ -126,6 +120,7 @@ function multi_hilbert_series(SubM::SubquoModule{T}; parent::Union{Nothing, Ring end function multi_hilbert_series(F::FreeMod{T}; parent::Union{Nothing,Ring} = nothing, backend::Symbol = :Abbott) where T <: MPolyRingElem + @req is_positively_graded(base_ring(F)) "ring must be positively graded" return multi_hilbert_series(sub(F,gens(F))[1]; parent=parent, backend=backend) end diff --git a/src/Rings/hilbert.jl b/src/Rings/hilbert.jl index f4bd52e4acca..7b1bed42b74d 100644 --- a/src/Rings/hilbert.jl +++ b/src/Rings/hilbert.jl @@ -927,6 +927,29 @@ function separate_simple_pps(gens::Vector{PP}) end +# !!!OBSOLESCENT!!! 2023-08-17 this fn will no be needed after Wolfram's PR is merged +# Returns nothing; throws if ker(W) contains a non-zero vector >= 0 +#function _hilbert_series_check_weights(W::Vector{Vector{Int}}) +# # assumes W is rectangular (and at least 1x1) +# # Transpose while converting: +# ncols = length(W); +# nrows = length(W[1]); +# A = zero_matrix(FlintZZ, nrows,ncols); +# for i in 1:nrows for j in 1:ncols A[i,j] = W[j][i]; end; end; +# b = zero_matrix(FlintZZ, nrows,1); +# try +# solve_non_negative(A, b); # any non-zero soln gives rise to infinitely many, which triggers an exception +# catch e +# if !(e isa ArgumentError && e.msg == "Polyhedron not bounded") +# rethrow(e) +# end +# # solve_non_negative must have thrown because there is a non-zero soln +# error("given weights permit infinite dimensional homogeneous spaces") +# end +# return nothing # otherwise it returns the result of solve_non_negative (Doh!!) +#end + + # Check args: either throws or returns nothing. function HSNum_check_args(gens::Vector{PP}, W::Vector{Vector{Int}}) if isempty(W) diff --git a/src/Rings/mpoly-affine-algebras.jl b/src/Rings/mpoly-affine-algebras.jl index 83caf8c77d6a..7bb375f25e54 100644 --- a/src/Rings/mpoly-affine-algebras.jl +++ b/src/Rings/mpoly-affine-algebras.jl @@ -544,6 +544,7 @@ function multi_hilbert_series( R = base_ring(A) I = modulus(A) @req coefficient_ring(R) isa AbstractAlgebra.Field "The coefficient ring must be a field" + @req is_positively_graded(A) "the ring must be positively graded" # Wrap the case where G is abstractly isomorphic to ℤᵐ, but not realized as a # free Abelian group. @@ -561,7 +562,7 @@ function multi_hilbert_series( map_into_S = hom(R, S, gens(S)) J = map_into_S(I) AA, _ = quo(S, J) - (numer, denom), _ = multi_hilbert_series(AA; algorithm, parent) + (numer, denom), _ = multi_hilbert_series(AA; algorithm, backend, parent) return (numer, denom), (H, iso) end @@ -735,6 +736,7 @@ G ``` """ function multi_hilbert_series_reduced(A::MPolyQuoRing; algorithm::Symbol=:BayerStillmanA) + @req is_positively_graded(A) "ring must be positively graded" (p, q), (H, iso) = multi_hilbert_series(A, algorithm=algorithm) f = p//evaluate(q) p = numerator(f) diff --git a/test/Modules/hilbert.jl b/test/Modules/hilbert.jl index 839744ca12f7..70fdc0011d50 100644 --- a/test/Modules/hilbert.jl +++ b/test/Modules/hilbert.jl @@ -1,14 +1,14 @@ @testset "Hilbert series and free resolution" begin R, _ = polynomial_ring(QQ, ["x", "y", "z"]); Z = abelian_group(0); - Rg, (x, y, z) = grade(R, [3*Z[1],Z[1],-Z[1]]); + Rg, (x, y, z) = grade(R, [3*Z[1],Z[1],Z[1]]); F = graded_free_module(Rg, 1); A = Rg[x; y]; B = Rg[x^2+y^6; y^7; z^4]; M = SubquoModule(F, A, B); fr = free_resolution(M) - # There is no length(fr), so instead we do the following + # 2023-08-18 There is no length(fr), so instead we do the following indexes = range(fr.C); fr_len = first(indexes) diff --git a/test/Rings/hilbert.jl b/test/Rings/hilbert.jl index 0dce2c506af1..e3f4c9ce821f 100644 --- a/test/Rings/hilbert.jl +++ b/test/Rings/hilbert.jl @@ -113,3 +113,11 @@ end @test numer1 == evaluate(numer2, T) @test numer3 == evaluate(numer2, first(gens(parent(numer3)))) end + +@testset "Hilbert series part 3" begin + R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"], [1, -1]); + I = ideal(R, [x]); + RmodI, _ = quo(R, I); + @test_throws ArgumentError hilbert_series(RmodI); # weights must be non-neg + @test_throws ArgumentError multi_hilbert_series(RmodI); # possible infinite dimension +end