Skip to content

Commit

Permalink
Implement iteration over module monomials of a specific degree.
Browse files Browse the repository at this point in the history
  • Loading branch information
HechtiDerLachs committed Oct 4, 2023
1 parent 4062c3b commit 48b9752
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
90 changes: 90 additions & 0 deletions experimental/Schemes/Auxiliary.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

13 changes: 13 additions & 0 deletions test/Modules/GradedModules.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 48b9752

Please sign in to comment.