From f5295f0e29e5af38d1ba10815db30119ae582da2 Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Mon, 18 Sep 2023 13:41:23 +0200 Subject: [PATCH] twisted modules (#2807) * twisted modules --- .../module_operations.md | 8 ++ src/Modules/ModulesGraded.jl | 86 +++++++++++++++++++ src/exports.jl | 1 + test/Modules/ModulesGraded.jl | 10 +++ 4 files changed, 105 insertions(+) diff --git a/docs/src/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations.md b/docs/src/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations.md index d1d61e118551..5ccefdd8bd51 100644 --- a/docs/src/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations.md +++ b/docs/src/CommutativeAlgebra/ModulesOverMultivariateRings/module_operations.md @@ -39,3 +39,11 @@ direct_product(M::ModuleFP{T}...; task::Symbol = :prod) where T ```@docs truncate(M::ModuleFP, g::GrpAbFinGenElem, task::Symbol = :with_morphism) ``` + +## Twists + +In the graded case, we have: + +```@docs +twist(M::ModuleFP{T}, g::GrpAbFinGenElem) where {T<:MPolyDecRingElem} +``` diff --git a/src/Modules/ModulesGraded.jl b/src/Modules/ModulesGraded.jl index 8714c1c0e402..90a38eec1c1a 100644 --- a/src/Modules/ModulesGraded.jl +++ b/src/Modules/ModulesGraded.jl @@ -2567,3 +2567,89 @@ function ideal_as_module(I::MPolyIdeal) e1 = F[1] return sub(F, [x * e1 for x = gens(I)], :module) end + + + +########################################################################## +##### Twists +########################################################################## + +@doc raw""" + twist(M::ModuleFP{T}, g::GrpAbFinGenElem) where {T<:MPolyDecRingElem} + +Return the twisted module `M(g)`. + + twist(M::ModuleFP{T}, W::Vector{<:IntegerUnion}) where {T<:MPolyDecRingElem} + +Given a module `M` over a $\mathbb Z^m$-graded polynomial ring and a vector `W` of $m$ integers, +convert `W` into an element `g` of the grading group of the ring and proceed as above. + + twist(M::ModuleFP{T}, d::IntegerUnion) where {T<:MPolyDecRingElem} + +Given a module `M` over a $\mathbb Z$-graded polynomial ring and an integer `d`, +convert `d` into an element `g` of the grading group of the ring and proceed as above. + +# Examples +```jldoctest +julia> R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"]); + +julia> I = ideal(R, [zero(R)]) +ideal(0) + +julia> M = quotient_ring_as_module(I) +Graded submodule of R^1 +1 -> e[1] +represented as subquotient with no relations + +julia> degree(gen(M, 1)) +[0] + +julia> N = twist(M, 2) +Graded submodule of R^1 +1 -> e[1] +represented as subquotient with no relations + +julia> degree(gen(N, 1)) +[-2] + +``` +""" +function twist(M::ModuleFP{T}, g::GrpAbFinGenElem) where {T<:MPolyDecRingElem} + error("Not implemented for the given type") +end + +function twist(M::SubquoModule{T}, g::GrpAbFinGenElem) where {T<:MPolyDecRingElem} + R = base_ring(M) + @req parent(g) == grading_group(R) "Group element not contained in grading group of base ring" + F = ambient_free_module(M) + FN = twist(F, g) + GN = free_module(R, ngens(M)) + HN = free_module(R, length(relations(M))) + a = hom(GN, F, ambient_representatives_generators(M)) + b = hom(HN, F, relations(M)) + A = matrix(a) + B = matrix(b) + N = subquotient(FN, A, B) + return N +end + +function twist(F::FreeMod{T}, g::GrpAbFinGenElem) where {T<:MPolyDecRingElem} + R = base_ring(F) + @req parent(g) == grading_group(R) "Group element not contained in grading group of base ring" + W = [x-g for x in F.d] + G = graded_free_module(R, rank(F)) + G.d = W + return G +end + +function twist(M::ModuleFP{T}, W::Vector{<:IntegerUnion}) where {T<:MPolyDecRingElem} + R = base_ring(M) + @assert is_zm_graded(R) + return twist(M, grading_group(R)(W)) +end + +function twist(M::ModuleFP{T}, d::IntegerUnion) where {T<:MPolyDecRingElem} + R = base_ring(M) + @assert is_z_graded(R) + return twist(M, grading_group(R)([d])) +end diff --git a/src/exports.jl b/src/exports.jl index 782fee7393b6..dd3e6a52d937 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -1397,6 +1397,7 @@ export truncate export turn_denominator_into_polyhedron export tutte_connectivity export tutte_polynomial +export twist export two_neighbor_step export two_sided_ideal export underlying_glueing diff --git a/test/Modules/ModulesGraded.jl b/test/Modules/ModulesGraded.jl index 17a01965f552..58ae121a04d2 100644 --- a/test/Modules/ModulesGraded.jl +++ b/test/Modules/ModulesGraded.jl @@ -1166,3 +1166,13 @@ end b = transpose(a) * a @test is_symmetric(b) end + +@testset "twist" begin + R, (x, y) = graded_polynomial_ring(QQ, ["x", "y"], [1 0; 0 1]); + I = ideal(R, [x, y]) + M = quotient_ring_as_module(I) + N = twist(M, [1, 2]) + @test Int(degree(gen(N, 1))[1]) == -1 + @test Int(degree(gen(N, 1))[2]) == -2 +end +