Skip to content

Commit

Permalink
Refactor canonical_{in/pro}jection (#2747)
Browse files Browse the repository at this point in the history
  • Loading branch information
lgoettgens authored and antonydellavecchia committed Sep 19, 2023
1 parent 9597eca commit 59f5e38
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 54 deletions.
16 changes: 8 additions & 8 deletions experimental/GModule/GaloisCohomology.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1081,15 +1081,15 @@ function Oscar.completion(I::IdelParent, P::NfAbsOrdIdl)
mUp = I.L[p]
mGp = I.D[p]

inj = Hecke.canonical_injection(I.M, p+1) #units are first
pro = Hecke.canonical_projection(I.M, p+1)
inj = canonical_injection(I.M, p+1) #units are first
pro = canonical_projection(I.M, p+1)


@assert domain(inj) == codomain(pro)

J = components(I.M)[p+1]
if mKp.P == P #easy case
return Kp, mKp, mGp, mUp, pro * Hecke.canonical_projection(J, 1) , Hecke.canonical_injection(J, 1)*inj
return Kp, mKp, mGp, mUp, pro * canonical_projection(J, 1), canonical_injection(J, 1)*inj
end

prm = get_attribute(J, :induce)[2]
Expand All @@ -1100,7 +1100,7 @@ function Oscar.completion(I::IdelParent, P::NfAbsOrdIdl)

nKp = MapFromFunc(I.k, Kp, x->mKp(mG(pr)(x)), y->mG(inv(pr))(preimage(mKp, y)))

return Kp, nKp, mGp, mUp, pro * Hecke.canonical_projection(J, z[1]), Hecke.canonical_injection(J, z[1])*inj
return Kp, nKp, mGp, mUp, pro * canonical_projection(J, z[1]), canonical_injection(J, z[1])*inj
end

function Oscar.map_entries(mp::Union{Map, Function}, C::GrpCoh.CoChain{N, G, M}; parent::GModule) where {N, G, M}
Expand Down Expand Up @@ -1726,11 +1726,11 @@ end
function serre(A::IdelParent, P::Union{Integer, ZZRingElem})
C = A.data[1]
t = findfirst(isequal(ZZ(P)), [minimum(x) for x = A.S])
Inj = Hecke.canonical_injection(A.M, t+1)
Pro = Hecke.canonical_projection(A.M, t+1)
Inj = canonical_injection(A.M, t+1)
Pro = canonical_projection(A.M, t+1)

inj = Hecke.canonical_injection(domain(Inj), 1)
pro = Hecke.canonical_projection(domain(Inj), 1)
inj = canonical_injection(domain(Inj), 1)
pro = canonical_projection(domain(Inj), 1)

Kp, mKp, mGp, mUp, _, _ = completion(A, A.S[t])
@assert domain(inj) == domain(mUp)
Expand Down
35 changes: 21 additions & 14 deletions src/Modules/FreeModules-graded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1214,25 +1214,32 @@ function direct_product(G::ModuleFP_dec...; task::Symbol = :none)
end
(M::ModuleFP_dec...) = direct_product(M..., task = :none)

function canonical_injections(G::ModuleFP_dec)
H = get_attribute(G, :direct_product)
@req H !== nothing "module not a direct product"
return [canonical_injection(G, i) for i in 1:length(H)]
end

function Hecke.canonical_injection(G::ModuleFP_dec, i::Int)
function canonical_injection(G::ModuleFP_dec, i::Int)
H = get_attribute(G, :direct_product)
if H === nothing
error("module not a direct product")
end
0<i<= length(H) || error("index out of bound")
j = i == 1 ? 0 : sum(ngens(H[l]) for l=1:i-1) -1
return hom(H[i], G, [G[l+j] for l = 1:ngens(H[i])])
@req H !== nothing "module not a direct product"
@req 0 < i <= length(H) "index out of bound"
j = sum(ngens(H[l]) for l in 1:i-1; init=0)
return hom(H[i], G, [G[l+j] for l in 1:ngens(H[i])])
end

function Hecke.canonical_projection(G::ModuleFP_dec, i::Int)
function canonical_projections(G::ModuleFP_dec)
H = get_attribute(G, :direct_product)
if H === nothing
error("module not a direct product")
end
0<i<= length(H) || error("index out of bound")
j = i == 1 ? 0 : sum(ngens(H[l]) for l=1:i-1)
return hom(G, H[i], vcat([zero(H[i]) for l=1:j], gens(H[i]), [zero(H[i]) for l=1+j+ngens(H[i]):ngens(G)]))
@req H !== nothing "module not a direct product"
return [canonical_projection(G, i) for i in 1:length(H)]
end

function canonical_projection(G::ModuleFP_dec, i::Int)
H = get_attribute(G, :direct_product)
@req H !== nothing "module not a direct product"
@req 0 < i <= length(H) "index out of bound"
j = sum(ngens(H[l]) for l in 1:i-1; init=0)
return hom(G, H[i], vcat([zero(H[i]) for l in 1:j], gens(H[i]), [zero(H[i]) for l in 1+j+ngens(H[i]):ngens(G)]))
end

##################################################
Expand Down
53 changes: 36 additions & 17 deletions src/Modules/UngradedModules.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5067,7 +5067,7 @@ function hom_product(M::ModuleFP, N::ModuleFP, A::Matrix{<:ModuleFPHom})
@assert length(tM) == size(A, 1) && length(tN) == size(A, 2)
@assert all(ij -> domain(A[ij[1],ij[2]]) === tM[ij[1]] && codomain(A[ij[1],ij[2]]) === tN[ij[2]], Base.Iterators.ProductIterator((1:size(A, 1), 1:size(A, 2))))
#need the canonical maps..., maybe store them as well?
return hom(M,N,Vector{elem_type(N)}([sum([Hecke.canonical_injection(N,j)(sum([A[i,j](Hecke.canonical_projection(M,i)(g)) for i=1:length(tM)])) for j=1:length(tN)]) for g in gens(M)]))
return hom(M,N,Vector{elem_type(N)}([sum([canonical_injection(N,j)(sum([A[i,j](canonical_projection(M,i)(g)) for i=1:length(tM)])) for j=1:length(tN)]) for g in gens(M)]))
end
# hom(prod -> X), hom(x -> prod)
# if too much time: improve the hom(A, B) in case of A and/or B are products - or maybe not...
Expand Down Expand Up @@ -7299,45 +7299,64 @@ end

(M::ModuleFP...) = direct_sum(M..., task = :none)

@doc raw"""
canonical_injections(G::ModuleFP)
Return the canonical injections from all components into $G$
where $G = G_1 \oplus \cdot \oplus G_n$.
"""
function canonical_injections(G::ModuleFP)
H = get_attribute(G, :direct_product)
@req H !== nothing "module not a direct product"
return [canonical_injection(G, i) for i in 1:length(H)]
end

@doc raw"""
Hecke.canonical_injection(G::ModuleFP, i::Int)
canonical_injection(G::ModuleFP, i::Int)
Return the canonical injection $G_i \to G$ where $G = G_1 \oplus \cdot \oplus G_n$.
"""
function Hecke.canonical_injection(G::ModuleFP, i::Int)
function canonical_injection(G::ModuleFP, i::Int)
H = get_attribute(G, :direct_product)
if H === nothing
error("module not a direct product")
end
@req H !== nothing "module not a direct product"
injection_dictionary = get_attribute(G, :injection_morphisms)
if haskey(injection_dictionary, i)
return injection_dictionary[i]
end
0<i<= length(H) || error("index out of bound")
j = i == 1 ? 0 : sum(ngens(H[l]) for l=1:i-1)
emb = hom(H[i], G, Vector{elem_type(G)}([G[l+j] for l = 1:ngens(H[i])]))
@req 0 < i <= length(H) "index out of bound"
j = sum(ngens(H[l]) for l in 1:i-1; init=0)
emb = hom(H[i], G, Vector{elem_type(G)}([G[l+j] for l in 1:ngens(H[i])]))
injection_dictionary[i] = emb
return emb
end

@doc raw"""
Hecke.canonical_projection(G::ModuleFP, i::Int)
canonical_projections(G::ModuleFP)
Return the canonical projections from $G$ to all components
where $G = G_1 \oplus \cdot \oplus G_n$.
"""
function canonical_projections(G::ModuleFP)
H = get_attribute(G, :direct_product)
@req H !== nothing "module not a direct product"
return [canonical_projection(G, i) for i in 1:length(H)]
end

@doc raw"""
canonical_projection(G::ModuleFP, i::Int)
Return the canonical projection $G \to G_i$ where $G = G_1 \oplus \cdot \oplus G_n$.
"""
function Hecke.canonical_projection(G::ModuleFP, i::Int)
function canonical_projection(G::ModuleFP, i::Int)
H = get_attribute(G, :direct_product)
if H === nothing
error("module not a direct product")
end
@req H !== nothing "module not a direct product"
projection_dictionary = get_attribute(G, :projection_morphisms)
if haskey(projection_dictionary, i)
return projection_dictionary[i]
end
0<i<= length(H) || error("index out of bound")
j = i == 1 ? 0 : sum(ngens(H[l]) for l=1:i-1)
pro = hom(G, H[i], Vector{elem_type(H[i])}(vcat([zero(H[i]) for l=1:j], gens(H[i]), [zero(H[i]) for l=1+j+ngens(H[i]):ngens(G)])))
@req 0 < i <= length(H) "index out of bound"
j = sum(ngens(H[l]) for l in 1:i-1; init=0)
pro = hom(G, H[i], Vector{elem_type(H[i])}(vcat([zero(H[i]) for l in 1:j], gens(H[i]), [zero(H[i]) for l in 1+j+ngens(H[i]):ngens(G)])))
projection_dictionary[i] = pro
return pro
end
Expand Down
14 changes: 7 additions & 7 deletions test/Modules/ModulesGraded.jl
Original file line number Diff line number Diff line change
Expand Up @@ -918,13 +918,13 @@ end
@test is_graded(prod_N)
@test ngens(prod_M) == ngens(M1) + ngens(M2)
for g in gens(prod_N)
@test g == sum([Hecke.canonical_injection(prod_N,i)(Hecke.canonical_projection(prod_N,i)(g)) for i=1:2])
@test g == sum([canonical_injection(prod_N,i)(canonical_projection(prod_N,i)(g)) for i=1:2])
end
for g in gens(N1)
@test g == Hecke.canonical_projection(prod_N,1)(Hecke.canonical_injection(prod_N,1)(g))
@test g == canonical_projection(prod_N,1)(canonical_injection(prod_N,1)(g))
end
for g in gens(N2)
@test g == Hecke.canonical_projection(prod_N,2)(Hecke.canonical_injection(prod_N,2)(g))
@test g == canonical_projection(prod_N,2)(canonical_injection(prod_N,2)(g))
end

M1_to_N1 = SubQuoHom(M1,N1,zero_matrix(Rg,3,3))
Expand All @@ -948,12 +948,12 @@ end
phi = hom_product(prod_M,prod_N,[M1_to_N1 M1_to_N2; M2_to_N1 M2_to_N2])
@test degree(phi) == 6*Z[1]
for g in gens(M1)
@test M1_to_N1(g) == Hecke.canonical_projection(prod_N,1)(phi(emb[1](g)))
@test M1_to_N2(g) == Hecke.canonical_projection(prod_N,2)(phi(emb[1](g)))
@test M1_to_N1(g) == canonical_projection(prod_N,1)(phi(emb[1](g)))
@test M1_to_N2(g) == canonical_projection(prod_N,2)(phi(emb[1](g)))
end
for g in gens(M2)
@test M2_to_N1(g) == Hecke.canonical_projection(prod_N,1)(phi(emb[2](g)))
@test M2_to_N2(g) == Hecke.canonical_projection(prod_N,2)(phi(emb[2](g)))
@test M2_to_N1(g) == canonical_projection(prod_N,1)(phi(emb[2](g)))
@test M2_to_N2(g) == canonical_projection(prod_N,2)(phi(emb[2](g)))
end
prod_FN,prod,emb = direct_product(F2,N2,task=:both)
@test is_graded(prod_FN)
Expand Down
16 changes: 8 additions & 8 deletions test/Modules/UngradedModules.jl
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ end

@testset "direct product" begin
R, (x,y,z) = polynomial_ring(QQ, ["x", "y", "z"])

F2 = FreeMod(R,2)
F3 = FreeMod(R,3)

Expand Down Expand Up @@ -753,13 +753,13 @@ end
@test ngens(prod_M) == ngens(M1) + ngens(M2)

for g in gens(prod_N)
@test g == sum([Hecke.canonical_injection(prod_N,i)(Hecke.canonical_projection(prod_N,i)(g)) for i=1:2])
@test g == sum([canonical_injection(prod_N,i)(canonical_projection(prod_N,i)(g)) for i=1:2])
end
for g in gens(N1)
@test g == Hecke.canonical_projection(prod_N,1)(Hecke.canonical_injection(prod_N,1)(g))
@test g == canonical_projection(prod_N,1)(canonical_injection(prod_N,1)(g))
end
for g in gens(N2)
@test g == Hecke.canonical_projection(prod_N,2)(Hecke.canonical_injection(prod_N,2)(g))
@test g == canonical_projection(prod_N,2)(canonical_injection(prod_N,2)(g))
end

# testing hom_product
Expand All @@ -777,12 +777,12 @@ end

phi = hom_product(prod_M,prod_N,[M1_to_N1 M1_to_N2; M2_to_N1 M2_to_N2])
for g in gens(M1)
@test M1_to_N1(g) == Hecke.canonical_projection(prod_N,1)(phi(emb[1](g)))
@test M1_to_N2(g) == Hecke.canonical_projection(prod_N,2)(phi(emb[1](g)))
@test M1_to_N1(g) == canonical_projection(prod_N,1)(phi(emb[1](g)))
@test M1_to_N2(g) == canonical_projection(prod_N,2)(phi(emb[1](g)))
end
for g in gens(M2)
@test M2_to_N1(g) == Hecke.canonical_projection(prod_N,1)(phi(emb[2](g)))
@test M2_to_N2(g) == Hecke.canonical_projection(prod_N,2)(phi(emb[2](g)))
@test M2_to_N1(g) == canonical_projection(prod_N,1)(phi(emb[2](g)))
@test M2_to_N2(g) == canonical_projection(prod_N,2)(phi(emb[2](g)))
end

# testing mixed typed modules
Expand Down

0 comments on commit 59f5e38

Please sign in to comment.