Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More hilbert_series #2630

Merged
merged 62 commits into from
Aug 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
16ee3a8
Preliminary tests for unified hilbert_series
JohnAAbbott Aug 7, 2023
a961ce5
Include tests.
HechtiDerLachs Aug 7, 2023
3bb7d08
Hooked in Abbott code
JohnAAbbott Aug 7, 2023
6f2fadd
Merge branch 'Hilbert_series_integration' of github.com:JohnAAbbott/O…
JohnAAbbott Aug 7, 2023
0735b9d
Extract my implementation of hilbert series into a separate file.
HechtiDerLachs Aug 7, 2023
67dee24
Add some comments.
HechtiDerLachs Aug 7, 2023
346255d
Merge branch 'Hilbert_series_integration' of github.com:JohnAAbbott/O…
HechtiDerLachs Aug 7, 2023
dc227fc
New scope for verbosity in hilbert series numerator code
JohnAAbbott Aug 7, 2023
8fdacae
Extensive cleaning; working towards OSCAR coding stds
JohnAAbbott Aug 7, 2023
b190fe8
Fixed minor typos
JohnAAbbott Aug 7, 2023
dd5fb6a
Minor modification in method selection and cwlean up of docstrings.
HechtiDerLachs Aug 7, 2023
9cc8462
Return the denominator for the hilbert series in factorized form.
HechtiDerLachs Aug 7, 2023
73f0d19
Adjust tests.
HechtiDerLachs Aug 7, 2023
33ec78f
Merge branch 'Hilbert_series_integration' of github.com:JohnAAbbott/O…
HechtiDerLachs Aug 7, 2023
f54e2ef
Renaming (to OSCAR conventions); syntactic cleaning
JohnAAbbott Aug 8, 2023
c3aa506
Fixed bug in ideal(0) short-cut
JohnAAbbott Aug 8, 2023
fad4434
First implementation of hilbert series numerator for modules; more cl…
JohnAAbbott Aug 8, 2023
62d034a
Fixed small typo
JohnAAbbott Aug 9, 2023
7893ac1
First step towards unifying hilbert_series interface
JohnAAbbott Aug 9, 2023
88b389b
Corrected doc; renamed local var
JohnAAbbott Aug 9, 2023
96ca8f6
Added kwarg parent; corrected indentation
JohnAAbbott Aug 9, 2023
25f2205
Get rid of restrictive types.
HechtiDerLachs Aug 9, 2023
536903e
Clean up the multi_hilbert_series.
HechtiDerLachs Aug 9, 2023
2964068
Update tests.
HechtiDerLachs Aug 9, 2023
08f6e91
Merge branch 'Hilbert_series_integration' of github.com:JohnAAbbott/O…
HechtiDerLachs Aug 9, 2023
fb8903d
Clean up the original hilbert_series.
HechtiDerLachs Aug 9, 2023
f1cb501
Add some cleanup.
HechtiDerLachs Aug 9, 2023
0588ca5
Update tests.
HechtiDerLachs Aug 9, 2023
375c09c
Added test_throws
JohnAAbbott Aug 9, 2023
d45ac8b
Handle R^0 correctly; new UI to allow freemodule as arg
JohnAAbbott Aug 9, 2023
92dd69c
Now allow R/ideal() as input; partial prototype for denom
JohnAAbbott Aug 9, 2023
fda8825
Commented out short-cut for ideal(0) because it got denom wrong
JohnAAbbott Aug 9, 2023
3714388
Merge branch 'oscar-system:master' into Hilbert_series_integration
JohnAAbbott Aug 9, 2023
a6a3e0c
Renamed HSNum_fudge to HSNum_abbott
JohnAAbbott Aug 10, 2023
3f0576f
First phase of refactoring
JohnAAbbott Aug 10, 2023
72289f2
Main fn is now called hilbert_series; cannot handle non ZZ^m grading
JohnAAbbott Aug 10, 2023
56c32cb
Tidying & renaming; internal fns now require HSRing arg
JohnAAbbott Aug 10, 2023
327ae9c
Scattered tidying inside multi_hilbert_series
JohnAAbbott Aug 10, 2023
d56a2fe
hilbert_series: Now has kwargs backend & parent; not yet working for …
JohnAAbbott Aug 10, 2023
446face
Better comment
JohnAAbbott Aug 10, 2023
59e718a
Improved example in doc; removed cruft
JohnAAbbott Aug 10, 2023
db05ab2
Merge branch 'oscar-system:master' into Hilbert_series_integration
JohnAAbbott Aug 10, 2023
13ec90e
Removed cruft
JohnAAbbott Aug 10, 2023
2d08095
Removed cruft
JohnAAbbott Aug 10, 2023
ff019d2
Fixed rank 0 case; added comments
JohnAAbbott Aug 10, 2023
11fa50b
Disabled MPolyBuildCtx in HS_denominator: gives error for univariate …
JohnAAbbott Aug 11, 2023
84b6194
Merge branch 'oscar-system:master' into Hilbert_series_integration
JohnAAbbott Aug 11, 2023
0ecea3a
Syntactic cleaning
JohnAAbbott Aug 11, 2023
d5cce04
Improved comment
JohnAAbbott Aug 11, 2023
17a640e
Added new test hilbert.jl
JohnAAbbott Aug 11, 2023
aa69d1c
Now have hilbert_series and multi_hilbert_series (for modules)
JohnAAbbott Aug 11, 2023
34c1266
Merge branch 'Hilbert_series_integration' of github.com:JohnAAbbott/O…
JohnAAbbott Aug 11, 2023
b9e7e03
Changed fn prototype for graded_map (line 575): AbstractFreeModElem i…
JohnAAbbott Aug 11, 2023
fa8dc41
Corrected doc string; added new doc string
JohnAAbbott Aug 11, 2023
6ce8b6f
Merge branch 'oscar-system:master' into Hilbert_series_integration
JohnAAbbott Aug 11, 2023
41472e1
Corrected doctest
JohnAAbbott Aug 11, 2023
25e42d9
New tests (for hilbert_series)
JohnAAbbott Aug 11, 2023
a7ccd49
Merge branch 'oscar-system:master' into Hilbert_series_integration
JohnAAbbott Aug 11, 2023
490e4cc
Use univariate laurent polynomials as default in the module case.
HechtiDerLachs Aug 11, 2023
7ec551d
Fix doctests.
HechtiDerLachs Aug 11, 2023
a148caf
Fix doctests once more.
HechtiDerLachs Aug 11, 2023
61b0ace
Merge branch 'master' into Hilbert_series_integration
HechtiDerLachs Aug 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Modules/Modules.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include("ModuleTypes.jl")
include("hilbert.jl")
include("UngradedModules.jl")
include("homological-algebra.jl")
include("FreeModElem-orderings.jl")
Expand Down
2 changes: 1 addition & 1 deletion src/Modules/ModulesGraded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ function graded_map(F::FreeMod{T}, A::MatrixElem{T}) where {T <: RingElement}
return phi
end

function graded_map(F::FreeMod{T}, V::Vector{<:FreeModElem{T}}) where {T <: RingElement}
function graded_map(F::FreeMod{T}, V::Vector{<:AbstractFreeModElem{T}}) where {T <: RingElement}
R = base_ring(F)
G = grading_group(R)
nrows = length(V)
Expand Down
187 changes: 187 additions & 0 deletions src/Modules/hilbert.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# This cannot be included in src/Rings/hilbert.jl because the include
# order defined in src/Oscar.jl includes ring stuff before module stuff
# (and it probably would not work if we inverted the inclusion order).

# ==================================================================
# Hilbert series numerator for modules

function _power_product(T, expv)
return prod([T[k]^expv[k] for k in 1:length(expv)]);
end


function HSNum_module(SubM::SubquoModule{T}, HSRing::Ring, backend::Symbol=:Abbott) where T <: MPolyRingElem
C,phi = present_as_cokernel(SubM, :with_morphism); # phi is the morphism
LM = leading_module(C.quo);
F = ambient_free_module(C.quo);
r = rank(F);
P = base_ring(C.quo);
# short-cut for module R^0 (to avoid problems with empty sum below)
if iszero(r)
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
# 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
for j in 1:r
if SR[j] != 0
push!(L[j], SR[j]);
end
end
end
IdealList = [ideal(P,G) for G in L];
HSeriesList = [multi_hilbert_series(quo(P,I)[1]; parent=HSRing, backend=backend)[1][1] for I in IdealList];
shifts = [degree(phi(g)) for g in gens(F)];
@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)

Compute a pair of pairs `(N ,D), (H ,iso)` where `N` and `D` are the non-reduced numerator and denominator of the Hilbert
series of the subquotient `M`, and `H` is the SNF of the grading group together with the identifying isomorphism `iso`.
If the kwarg `parent` is supplied `N` and `D` are computed in the ring `parent`.

!!! note
CURRENT LIMITATION: the grading must be over ZZ^m (more general gradings are not yet supported)

!!! note
Applied to a homogeneous subquotient `M`, the function first computes a Groebner basis to
obtain the leading term module; the rest of the computation uses this latter module
(sliced into ideals, one for each ambient free module component).

# Examples
```jldoctest
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);

julia> Rg, (x, y, z) = grade(R, [4,3,2]);

julia> F = graded_free_module(Rg, 1);

julia> A = Rg[x; y];

julia> B = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, A, B);

julia> (num,den),_ = multi_hilbert_series(M);

julia> num
-t^25 + 2*t^17 + t^16 + t^15 - t^12 - t^11 - t^9 - t^8 - t^7 + t^4 + t^3

julia> den
Factored element with data
Dict{AbstractAlgebra.Generic.LaurentMPolyWrap{ZZRingElem, ZZMPolyRingElem, AbstractAlgebra.Generic.LaurentMPolyWrapRing{ZZRingElem, ZZMPolyRing}}, ZZRingElem}(-t^4 + 1 => 1, -t^3 + 1 => 1, -t^2 + 1 => 1)

```
"""
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"

# Wrap the case where G is abstractly isomorphic to ℤᵐ, but not realized as a
# free Abelian group.
#
# We use the Smith normal form to get there, recreate the graded ring with the
# free grading group, do the computation there and return the isomorphism for
# the grading.
G = grading_group(R)
if !is_zm_graded(R)
error("non-ZZ^m-grading not yet implemented for modules (see issue #2657)") ### Needs improvement to change_base_ring (see below)
H, iso = snf(G)
V = [preimage(iso, x) for x in gens(G)]
isoinv = hom(G, H, V)
W = [isoinv(R.d[i]) for i = 1:ngens(R)]
S, _ = graded_polynomial_ring(coefficient_ring(R), symbols(R), W)
map_into_S = hom(R, S, gens(S))
SubM2,_ = change_base_ring(map_into_S,SubM) # !!! BUG this seems to forget that things are graded BUG (issue #2657) !!!
(numer, denom), _ = hilbert_series(SubM2; parent=parent, backend=backend)
return (numer, denom), (H, iso)

Check warning on line 115 in src/Modules/hilbert.jl

View check run for this annotation

Codecov / codecov/patch

src/Modules/hilbert.jl#L106-L115

Added lines #L106 - L115 were not covered by tests
end

# Now we may assume that the grading group is free Abelian.
m = ngens(G)
n = ngens(R)
HSRing = _hilbert_series_ring(parent, m)
# Get the weights as Int values: W[k] contains the weight(s) of x[k]
W = [[ Int(R.d[i][j]) for j in 1:m] for i in 1:n]
denom = _hilbert_series_denominator(HSRing, W)
numer = HSNum_module(SubM, HSRing, backend)
return (numer, denom), (G, identity_map(G))
end

function multi_hilbert_series(F::FreeMod{T}; parent::Union{Nothing,Ring} = nothing, backend::Symbol = :Abbott) where T <: MPolyRingElem
return multi_hilbert_series(sub(F,gens(F))[1]; parent=parent, backend=backend)

Check warning on line 130 in src/Modules/hilbert.jl

View check run for this annotation

Codecov / codecov/patch

src/Modules/hilbert.jl#L129-L130

Added lines #L129 - L130 were not covered by tests
end


@doc raw"""
hilbert_series(M::SubquoModule; parent::Union{Nothing,Ring} = nothing)

Compute a pair `(N,D)` where `N` and `D` are the non-reduced numerator and denominator of the Hilbert
series of the subquotient `M`. If the kwarg `parent` is supplied `N` and `D` are computed in the ring `parent`.

!!! note
Applied to a homogeneous subquotient `M`, the function first computes a Groebner basis to
obtain the leading term module; the rest of the computation uses this latter module
(sliced into ideals, one for each ambient free module component).

# Examples
```jldoctest
julia> R, _ = polynomial_ring(QQ, ["x", "y", "z"]);

julia> Z = abelian_group(0);

julia> Rg, (x, y, z) = grade(R, [Z[1],Z[1],Z[1]]);

julia> F = graded_free_module(Rg, 1);

julia> A = Rg[x; y];

julia> B = Rg[x^2; y^3; z^4];

julia> M = SubquoModule(F, A, B);

julia> num,den = hilbert_series(M);

julia> num
-t^9 + t^7 + 2*t^6 - t^5 - t^3 - 2*t^2 + 2*t

julia> den
Factored element with data
Dict{AbstractAlgebra.Generic.LaurentPolyWrap{ZZRingElem, ZZPolyRingElem, AbstractAlgebra.Generic.LaurentPolyWrapRing{ZZRingElem, ZZPolyRing}}, ZZRingElem}(-t + 1 => 3)

```
"""
function hilbert_series(SubM::SubquoModule{T}; parent::Union{Nothing,Ring} = nothing, backend::Symbol = :Abbott) where T <: MPolyRingElem
@req is_z_graded(base_ring(SubM)) "ring must be ZZ-graded; use `multi_hilbert_series` otherwise"
if parent === nothing
parent, _ = LaurentPolynomialRing(ZZ, :t)
end
HS, _ = multi_hilbert_series(SubM; parent=parent, backend=backend)
return HS
end

function hilbert_series(F::FreeMod{T}; parent::Union{Nothing,Ring} = nothing, backend::Symbol = :Abbott) where T <: MPolyRingElem
@req is_z_graded(base_ring(F)) "ring must be ZZ-graded; use `multi_hilbert_series` otherwise"
if parent === nothing
parent, _ = LaurentPolynomialRing(ZZ, :t)
end
return hilbert_series(sub(F,gens(F))[1]; parent=parent, backend=backend)
end
2 changes: 2 additions & 0 deletions src/Oscar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ function __init__()
add_verbose_scope(:Blowup)
add_assert_scope(:Blowup)

add_verbose_scope(:hilbert)
add_assert_scope(:hilbert)

add_verbose_scope(:GlobalTateModel)
add_verbose_scope(:WeierstrassModel)
Expand Down
2 changes: 2 additions & 0 deletions src/Rings/Rings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ include("orderings.jl")
include("mpoly.jl")
include("mpoly_types.jl")
include("mpoly-graded.jl")
include("hilbert_zach.jl")
include("mpoly-ideals.jl")
include("groebner.jl")
include("solving.jl")
Expand Down Expand Up @@ -33,4 +34,5 @@ include("AlgClosureFp.jl")
include("PBWAlgebra.jl")
include("PBWAlgebraQuo.jl")
include("FreeAssAlgIdeal.jl")
include("hilbert.jl")

Loading
Loading