From 48b9752cd289ed9a0aad65abd160c475ce544cb3 Mon Sep 17 00:00:00 2001 From: Matthias Zach Date: Wed, 4 Oct 2023 12:29:23 +0200 Subject: [PATCH] Implement iteration over module monomials of a specific degree. --- experimental/Schemes/Auxiliary.jl | 90 +++++++++++++++++++++++++++++++ test/Modules/GradedModules.jl | 13 +++++ 2 files changed, 103 insertions(+) diff --git a/experimental/Schemes/Auxiliary.jl b/experimental/Schemes/Auxiliary.jl index 4a9dc29f51a3..2e2eca310366 100644 --- a/experimental/Schemes/Auxiliary.jl +++ b/experimental/Schemes/Auxiliary.jl @@ -383,3 +383,93 @@ end ### Generic pullback and pushforward for composite maps pushforward(f::Generic.CompositeMap, a::Any) = pushforward(map2(f), pushforward(map1(f), a)) pullback(f::Generic.CompositeMap, a::Any) = pullback(map1(f), pullback(map2(f), a)) + +### Iteration over monomials in modules of a certain degree +struct AllModuleMonomials{ModuleType<:FreeMod} + F::ModuleType + d::Int + + function AllModuleMonomials(F::FreeMod{T}, d::Int) where {T <: MPolyDecRingElem} + is_graded(F) || error("module must be graded") + S = base_ring(F) + is_standard_graded(S) || error("iterator implemented only for the standard graded case") + return new{typeof(F)}(F, d) + end +end + +underlying_module(amm::AllModuleMonomials) = amm.F +degree(amm::AllModuleMonomials) = amm.d + +function all_monomials(F::FreeMod{T}, d::Int) where {T<:MPolyDecRingElem} + return AllModuleMonomials(F, d) +end + +Base.eltype(amm::AllModuleMonomials{T}) where {T} = elem_type(T) + +function Base.length(amm::AllModuleMonomials) + F = underlying_module(amm) + r = rank(F) + R = base_ring(F) + d = degree(amm) + result = 0 + for i in 1:r + d_loc = d - Int(degree(F[i])[1]) + d_loc < 0 && continue + result = result + length(all_monomials(R, d_loc)) + end + return result +end + +function Base.iterate(amm::AllModuleMonomials, state::Nothing = nothing) + i = 1 + F = underlying_module(amm) + d = degree(amm) + R = base_ring(F) + + d_loc = d - Int(degree(F[i])[1]) + while i < ngens(F) && d_loc < 0 + i = i+1 + d_loc = d - Int(degree(F[i])[1]) + end + + i == ngens(F) && d_loc < 0 && return nothing + + mon_it = all_monomials(R, d_loc) + res = iterate(mon_it, nothing) + res === nothing && i == ngens(F) && return nothing + + x, s = res + return x*F[1], (i, mon_it, s) +end + +function Base.iterate(amm::AllModuleMonomials, state::Tuple{Int, AllMonomials, Vector{Int}}) + F = underlying_module(amm) + d = degree(amm) + R = base_ring(F) + + i, mon_it, s = state + res = iterate(mon_it, s) + if res === nothing + i == ngens(F) && return nothing + i = i+1 + d_loc = d - Int(degree(F[i])[1]) + + while i < ngens(F) && d_loc < 0 + i = i+1 + d_loc = d - Int(degree(F[i])[1]) + end + + i == ngens(F) && d_loc < 0 && return nothing + + mon_it = all_monomials(R, d_loc) + res_loc = iterate(mon_it, nothing) + res_loc === nothing && i == ngens(F) && return nothing + + x, s = res_loc + return x*F[i], (i, mon_it, s) + end + + x, s = res + return x*F[i], (i, mon_it, s) +end + diff --git a/test/Modules/GradedModules.jl b/test/Modules/GradedModules.jl index 517e63c5d7b7..5742bd7fd83d 100644 --- a/test/Modules/GradedModules.jl +++ b/test/Modules/GradedModules.jl @@ -68,3 +68,16 @@ end K = kernel(phi)[1] @test (iszero(quo(M2,K)) && iszero(quo(K,M2))) # mathematical equality end + +@testset "all_monomials for graded free modules" begin + R, (x, y, u, v, w) = QQ[:x, :y, :u, :v, :w] + S, (x, y, u, v, w) = grade(R) + + F = graded_free_module(S, [-1, 2]) + + for d in -4:4 + amm = Oscar.all_monomials(F, d) + @test d < -1 || !isempty(amm) + @test all(x->degree(x) == grading_group(F)([d]), amm) + end +end