Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function normal_form(M::ModuleGens{T}, GB::ModuleGens{T}) where {T <: MonoidAlge

P = isdefined(GB, :quo_GB) ? union(GB, GB.quo_GB) : GB

red = _reduce(singular_generators(M), singular_generators(P))
red = _reduce(singular_generators(M, GB.ordering), singular_generators(P))
res = ModuleGens(oscar_free_module(M), red)
return res
end
Expand Down
21 changes: 19 additions & 2 deletions src/Modules/UngradedModules/ModuleGens.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,23 @@ function singular_generators(M::ModuleGens)
return M.S
end

@doc raw"""
singular_generators(M::ModuleGens, ordering::ModuleOrdering)

Return the generators of `M` in a Singular module over a Singular polynomial ring with the given `ordering`.
"""
function singular_generators(M::ModuleGens, ordering::ModuleOrdering)
#= TODO: Maybe cache these 'singular_generators' in a Dict with the 'ModuleOrdering' as a key,
like it is the case for 'groebner_basis'? =#
@assert M.F === ordering.M
SF = singular_module(M.F, ordering)
sr = base_ring(SF)
if length(M) == 0
return Singular.Module(sr, Singular.vector(sr, sr(0)))
end
return Singular.Module(sr, [SF(x) for x in oscar_generators(M)]...)
end

@doc raw"""
singular_ordering(M::ModuleGens)

Expand Down Expand Up @@ -462,7 +479,7 @@ function normal_form(M::ModuleGens{T}, GB::ModuleGens{T}) where {T <: MPolyRingE

P = isdefined(GB, :quo_GB) ? union(GB, GB.quo_GB) : GB

red = _reduce(singular_generators(M), singular_generators(P))
red = _reduce(singular_generators(M, GB.ordering), singular_generators(P))
res = ModuleGens(oscar_free_module(M), red)
return res
end
Expand All @@ -484,7 +501,7 @@ function normal_form_with_unit(M::ModuleGens{T}, GB::ModuleGens{T}) where {T <:

P = isdefined(GB, :quo_GB) ? union(GB, GB.quo_GB) : GB

red = _reduce(singular_generators(M), singular_generators(P))
red = _reduce(singular_generators(M, GB.ordering), singular_generators(P))
res = ModuleGens(oscar_free_module(M), red)
return res, [R(1) for _ in 1:ngens(M)]
end
Expand Down
28 changes: 28 additions & 0 deletions test/Modules/UngradedModules.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2171,3 +2171,31 @@ end
# not a finite module over `QQ`
@test_throws ErrorException vector_space_basis(S)
end

@testset "normal form different module orderings" begin
R, (x,y) = QQ[:x,:y]
F = free_module(R, 3)
M, _ = sub(F, [F[1]+F[3], F[2]])

v = (x^2+x)*F[1]
w = F[2]

# default ordering
GB = groebner_basis(M)
@test normal_form(v, GB) == (x^2+x)*F[1]
@test normal_form(w, GB) == zero(F)
@test Oscar.normal_form_with_unit(v, GB) == ((x^2+x)*F[1], one(R))

# another global ordering
ord = invlex(F)*deglex(R)
GB_ord = groebner_basis(M, ordering = ord)
@test normal_form(v, GB_ord) == -(x^2+x)*F[3]
@test normal_form(w, GB_ord) == zero(F)
@test Oscar.normal_form_with_unit(v, GB_ord) == (-(x^2+x)*F[3], one(R))

# local ordering
ord_loc = invlex(F)*negdeglex(R)
SB = standard_basis(M, ordering = ord_loc)
@test normal_form(v, SB) == -x*F[3]
@test normal_form(w, SB) == zero(F)
end
Loading