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

twisted modules #2807

Merged
merged 3 commits into from
Sep 18, 2023
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 @@ -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}
```
86 changes: 86 additions & 0 deletions src/Modules/ModulesGraded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not going to block this PR over this, but, normally we strive to indent code with (at least) two spaces.

(But of course we are already widely inconsistent about this, which is why I am not asking for it to be changed here and now, just wanted to point it out)

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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is == here enough or do we need ===? (same at other places)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fieker Please clearify!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sideremark:
If === is needed, this problem is not restricted to this PR. The problem then also occurs in Modules/ModulesGraded.jl (and possibly other files) as the same kind of comparison also occurs there with ==.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think == and === are the same for rings, so either is fine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As confirmed by @fieker, it is as I thought: There is no difference between == and === here. That is, the PR can be merged and no other action is needed.

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
1 change: 1 addition & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions test/Modules/ModulesGraded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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