Skip to content

Commit

Permalink
Add hilbert_series (#694)
Browse files Browse the repository at this point in the history
  • Loading branch information
hannes14 authored Aug 15, 2023
1 parent 464a02c commit d0bae9a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
16 changes: 16 additions & 0 deletions deps/src/ideals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,22 @@ void singular_define_ideals(jlcxx::Module & Singular)
delete v;
rChangeCurrRing(origin);
});
Singular.method("scHilbPoly", [](ideal I, ring r, ring Qt) {
const ring origin = currRing;
rChangeCurrRing(r);
poly h=hFirstSeries0p(I,r->qideal,NULL,r,Qt);
rChangeCurrRing(origin);
return h;
});
Singular.method("scHilbPolyWeighted", [](ideal I, ring r, jlcxx::ArrayRef<int> weights, ring Qt) {
intvec *w = to_intvec(weights);
const ring origin = currRing;
rChangeCurrRing(r);
poly h=hFirstSeries0p(I,r->qideal,w,r,Qt);
delete w;
rChangeCurrRing(origin);
return h;
});
Singular.method("id_Homogen", id_Homogen);
Singular.method("id_HomModule", [](jlcxx::ArrayRef<int> weights, ideal I, ring r) {
intvec* w = NULL;
Expand Down
32 changes: 32 additions & 0 deletions src/ideal/ideal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,38 @@ function hilbert_series(I::sideal{spoly{T}}, w::Vector{<:Integer}) where T <: Ne
return z
end

@doc raw"""
hilbert_series(I::sideal{spoly{T}}, Qt::PolyRing) where T <: Nemo.FieldElem
Return the polynomial $Q(t)$ as element of Qt where `Q(t)/(1-t)^nvars(base_ring(I))`
is the Hilbert-Poincare series of $I$ for weights $(1, \dots, 1)$.
The generators of $I$ must be given as a Groebner basis.
"""
function hilbert_series(I::sideal{spoly{T}}, Qt::PolyRing) where T <: Nemo.FieldElem
I.isGB || error("Not a Groebner basis")
R = base_ring(I)
GC.@preserve I R Qt new_ptr = libSingular.scHilbPoly(I.ptr, R.ptr, Qt.ptr)
return Qt(new_ptr)
end

@doc raw"""
hilbert_series(I::sideal{spoly{T}}, w::Vector{<:Integer}) where T <: Nemo.FieldElem
Return the polynomial $Q(t)$ of Qt where $\frac{Q(t)}{\prod_i (1-t^{w_i})}$
is the Hilbert-Poincare series of $I$ for weights $\{w_i\}$. Each weight must be
positive $w_i > 0$.
The generators of $I$ must be given as a Groebner basis.
"""
function hilbert_series(I::sideal{spoly{T}}, w::Vector{<:Integer}, Qt::PolyRing) where T <: Nemo.FieldElem
I.isGB || error("Not a Groebner basis")
R = base_ring(I)
length(w) == nvars(R) || error("wrong number of weights")
all(x -> x > 0, w) || error("weights must be positive")
w = convert(Vector{Int32}, w)
GC.@preserve I R Qt new_ptr = libSingular.scHilbPolyWeighted(I.ptr, R.ptr, w, Qt.ptr)
return Qt(new_ptr)
end

@doc raw"""
std_hilbert(I::sideal{spoly{T}}, hs::Vector{Int32}; complete_reduction::Bool=false) where T <: Nemo.FieldElem
Expand Down
4 changes: 4 additions & 0 deletions test/ideal/sideal-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,10 @@ end

@test ngens(std_hilbert(j, h, w, complete_reduction = true)) ==
ngens(std(j, complete_reduction = true))
Qt,(t,)= polynomial_ring(QQ, ["t"])
I=Ideal(R,[x,y,z])
I=std(I)
@test hilbert_series(I,Qt) == -t^3+3*t^2-3*t+1
end

@testset "sideal.oscar#1702" begin
Expand Down

0 comments on commit d0bae9a

Please sign in to comment.