Skip to content

Commit

Permalink
Hilbert series integration (#2698)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnAAbbott authored Aug 24, 2023
1 parent cafba7a commit b3682ec
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 11 deletions.
11 changes: 3 additions & 8 deletions src/Modules/hilbert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand Down
23 changes: 23 additions & 0 deletions src/Rings/hilbert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion src/Rings/mpoly-affine-algebras.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions test/Modules/hilbert.jl
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
8 changes: 8 additions & 0 deletions test/Rings/hilbert.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit b3682ec

Please sign in to comment.