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

Make inj/proj of products groups consistent with other products objects #3201

Merged
merged 3 commits into from
Jan 24, 2024
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
15 changes: 9 additions & 6 deletions docs/src/Groups/products.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ number_of_factors(G::DirectProductGroup)
cartesian_power(G::GAPGroup, n::Int)
inner_cartesian_power(G::T, n::Int; morphisms=false) where T<: GAPGroup
factor_of_direct_product(G::DirectProductGroup, j::Int)
embedding(G::DirectProductGroup, j::Int)
projection(G::DirectProductGroup, j::Int)
canonical_injection(G::DirectProductGroup, j::Int)
canonical_injections(G::DirectProductGroup)
canonical_projection(G::DirectProductGroup, j::Int)
canonical_projections(G::DirectProductGroup)
write_as_full(G::DirectProductGroup)
is_full_direct_product(G::DirectProductGroup)
```
Expand All @@ -32,8 +34,8 @@ normal_subgroup(G::SemidirectProductGroup)
acting_subgroup(G::SemidirectProductGroup)
homomorphism_of_semidirect_product(G::SemidirectProductGroup)
is_full_semidirect_product(G::SemidirectProductGroup)
embedding(G::SemidirectProductGroup, n::Int)
projection(G::SemidirectProductGroup)
canonical_injection(G::SemidirectProductGroup, n::Int)
canonical_projection(G::SemidirectProductGroup)
```

## Wreath products
Expand All @@ -45,6 +47,7 @@ normal_subgroup(W::WreathProductGroup)
acting_subgroup(W::WreathProductGroup)
homomorphism_of_wreath_product(G::WreathProductGroup)
is_full_wreath_product(G::WreathProductGroup)
projection(W::WreathProductGroup)
embedding(W::WreathProductGroup, n::Int)
canonical_projection(W::WreathProductGroup)
canonical_injection(W::WreathProductGroup, n::Int)
canonical_injections(W::WreathProductGroup)
```
97 changes: 65 additions & 32 deletions src/Groups/directproducts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,15 @@ end
Return the `j`-th factor of `G`.
"""
function factor_of_direct_product(G::DirectProductGroup, j::Int)
@req j in 1:length(G.L) "index not valid"
@req j in 1:number_of_factors(G) "index not valid"
return G.L[j]
end

"""
embedding(G::DirectProductGroup, j::Int)
canonical_injection(G::DirectProductGroup, j::Int)

Return the embedding of the `j`-th component of `G` into `G`, for `j` = 1,...,#factors of `G`.
Return the injection of the `j`-th component of `G` into `G`, for `j` = 1,...,#factors of `G`.
It is not defined for proper subgroups of direct products.

# Examples
```jldoctest
Expand All @@ -166,51 +167,61 @@ Permutation group of degree 3 and order 6
julia> K = symmetric_group(2)
Permutation group of degree 2 and order 2

julia> G = direct_product(H,K)
julia> G = direct_product(H, K)
Direct product of
Permutation group of degree 3 and order 6
Permutation group of degree 2 and order 2

julia> emb1 = embedding(G,1)
julia> inj1 = canonical_injection(G, 1)
Group homomorphism
from permutation group of degree 3 and order 6
to direct product of
Permutation group of degree 3 and order 6
Permutation group of degree 2 and order 2

julia> h = perm(H,[2,3,1])
julia> h = perm(H, [2,3,1])
(1,2,3)

julia> emb1(h)
julia> inj1(h)
(1,2,3)

julia> emb2 = embedding(G,2)
julia> inj2 = canonical_injection(G, 2)
Group homomorphism
from permutation group of degree 2 and order 2
to direct product of
Permutation group of degree 3 and order 6
Permutation group of degree 2 and order 2

julia> k = perm(K,[2,1])
julia> k = perm(K, [2,1])
(1,2)

julia> emb2(k)
julia> inj2(k)
(4,5)

julia> emb1(h)*emb2(k)
julia> inj1(h)*inj2(k)
(1,2,3)(4,5)
```
"""
function embedding(G::DirectProductGroup, j::Int)
@req j in 1:length(G.L) "index not valid"
@req G.isfull "Embedding is not defined for proper subgroups of direct products"
function canonical_injection(G::DirectProductGroup, j::Int)
@req j in 1:number_of_factors(G) "index not valid"
@req G.isfull "Injection is not defined for proper subgroups of direct products"
f = GAPWrap.Embedding(G.X, j)
gr = G.L[j]
return GAPGroupHomomorphism(gr, G, f)
end

"""
projection(G::DirectProductGroup, j::Int)
canonical_injections(G::DirectProductGroup)

Return the injection of the `j`-th component of `G` into `G`, for all `j` = 1,...,#factors of `G`.
It is not defined for proper subgroups of direct products.
"""
function canonical_injections(G::DirectProductGroup)
return [canonical_injection(G, j) for j in 1:number_of_factors(G)]
end

"""
canonical_projection(G::DirectProductGroup, j::Int)

Return the projection of `G` into the `j`-th component of `G`, for `j` = 1,...,#factors of `G`.

Expand All @@ -222,19 +233,19 @@ Permutation group of degree 3 and order 6
julia> K = symmetric_group(2)
Permutation group of degree 2 and order 2

julia> G = direct_product(H,K)
julia> G = direct_product(H, K)
Direct product of
Permutation group of degree 3 and order 6
Permutation group of degree 2 and order 2

julia> proj1 = projection(G,1)
julia> proj1 = canonical_projection(G, 1)
Group homomorphism
from direct product of
Permutation group of degree 3 and order 6
Permutation group of degree 2 and order 2
to permutation group of degree 3 and order 6

julia> proj2 = projection(G,2)
julia> proj2 = canonical_projection(G, 2)
Group homomorphism
from direct product of
Permutation group of degree 3 and order 6
Expand All @@ -251,15 +262,26 @@ julia> proj2(g)
(1,2)
```
"""
function projection(G::DirectProductGroup, j::Int)
function canonical_projection(G::DirectProductGroup, j::Int)
@req j in 1:number_of_factors(G) "index not valid"
f = GAPWrap.Projection(G.Xfull, j)
p = GAPWrap.RestrictedMapping(f, G.X)
return GAPGroupHomomorphism(G, factor_of_direct_product(G, j), p)
end

"""
canonical_projection(G::DirectProductGroup)

Return the projection of `G` into the `j`-th component of `G`, for all `j` = 1,...,#factors of `G`.
"""
function canonical_projections(G::DirectProductGroup)
return [canonical_projection(G, j) for j in 1:number_of_factors(G)]
end



function (G::DirectProductGroup)(V::AbstractVector{<:GAPGroupElem})
@req length(V) == length(G.L) "Wrong number of entries"
@req length(V) == number_of_factors(G) "Wrong number of entries"
arr = [GAPWrap.Image(GAPWrap.Embedding(G.Xfull, i), V[i].X) for i in 1:length(V)]
xgap = prod(arr)
@req xgap in G.X "Element not in the group"
Expand Down Expand Up @@ -301,7 +323,7 @@ function write_as_full(G::DirectProductGroup)
if G.isfull
return G
else
LK = [image(projection(G, j))[1] for j in 1:length(G.L)]
LK = [image(canonical_projection(G, j))[1] for j in 1:number_of_factors(G)]
H = direct_product(LK)
# index(H,G)==1 does not work because it does not recognize G as a subgroup of H
@req order(H) == order(G) "G is not a direct product of groups"
Expand Down Expand Up @@ -379,13 +401,13 @@ Return whether `G` is a semidirect product of two groups, instead of a proper su
is_full_semidirect_product(G::SemidirectProductGroup) = G.isfull

"""
embedding(G::SemidirectProductGroup, n::Int)
canonical_injection(G::SemidirectProductGroup, n::Int)

Return the embedding of the `n`-th component of `G` into `G`, for `n` = 1,2.
Return the injection of the `n`-th component of `G` into `G`, for `n` = 1,2.
It is not defined for proper subgroups of semidirect products.
"""
function embedding(G::SemidirectProductGroup, n::Int)
@req G.isfull "Embedding not defined for proper subgroups of semidirect products"
function canonical_injection(G::SemidirectProductGroup, n::Int)
@req G.isfull "Injection not defined for proper subgroups of semidirect products"
if n == 1
f = GAPWrap.Embedding(G.X, 2)
gr = G.N
Expand All @@ -399,11 +421,11 @@ function embedding(G::SemidirectProductGroup, n::Int)
end

"""
projection(G::SemidirectProductGroup)
canonical_projection(G::SemidirectProductGroup)

Return the projection of `G` into the second component of `G`.
"""
function projection(G::SemidirectProductGroup)
function canonical_projection(G::SemidirectProductGroup)
f = GAPWrap.Projection(G.Xfull)
p = GAPWrap.RestrictedMapping(f, G.X)
return GAPGroupHomomorphism(G, acting_subgroup(G), p)
Expand Down Expand Up @@ -571,23 +593,24 @@ Return whether `G` is a wreath product of two groups, instead of a proper subgro
is_full_wreath_product(G::WreathProductGroup) = G.isfull

"""
projection(G::WreathProductGroup)
canonical_projection(G::WreathProductGroup)

Return the projection of `wreath_product(G,H)` onto the permutation group `H`.
"""
function projection(W::WreathProductGroup)
function canonical_projection(W::WreathProductGroup)
# @req W.isfull "Projection not defined for proper subgroups of wreath products"
f = GAPWrap.Projection(W.Xfull)
p = GAPWrap.RestrictedMapping(f, W.X)
return GAPGroupHomomorphism(W, acting_subgroup(W), p)
end

"""
embedding(G::WreathProductGroup, n::Int)
canonical_injection(G::WreathProductGroup, n::Int)

Return the embedding of the `n`-th component of `G` into `G`.
Return the injection of the `n`-th component of `G` into `G`.
It is not defined for proper subgroups of wreath products.
"""
function embedding(W::WreathProductGroup, n::Int)
function canonical_injection(W::WreathProductGroup, n::Int)
@req W.isfull "Embedding not defined for proper subgroups of wreath products"
@req n <= GAP.Globals.NrMovedPoints(GAPWrap.Image(W.a.map)) + 1 "n is too big"
f = GAPWrap.Embedding(W.Xfull, n)
Expand All @@ -599,6 +622,16 @@ function embedding(W::WreathProductGroup, n::Int)
return GAPGroupHomomorphism(C, W, f)
end

"""
canonical_injections(G::WreathProductGroup)

Return the injection of the `n`-th component of `G` into `G` for all `n`.
It is not defined for proper subgroups of wreath products.
"""
function canonical_injections(W::WreathProductGroup)
return [canonical_injection(W, n) for n in 1:GAP.Globals.NrMovedPoints(GAPWrap.Image(W.a.map)) + 1]
end

Base.show(io::IO, x::WreathProductGroup) = print(io, String(GAPWrap.StringViewObj(x.X)))

#TODO : to be fixed
Expand Down
9 changes: 8 additions & 1 deletion src/deprecations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ Base.@deprecate_binding has_is_isomorphic_with_alternating_group has_is_isomorph
Base.@deprecate_binding set_is_isomorphic_with_alternating_group set_is_isomorphic_to_alternating_group

Base.@deprecate_binding are_algebraically_independent is_algebraically_independent_with_relations

Base.@deprecate ambient_ring(U::AbsMultSet) ring(U)

# Deprecated after 0.15
Expand Down Expand Up @@ -561,3 +561,10 @@ Base.@deprecate_binding ToricGlueingData ToricGluingData

Base.@deprecate_binding jacobi_matrix jacobian_matrix
Base.@deprecate_binding jacobi_ideal jacobian_ideal

@deprecate embedding(G::DirectProductGroup, j::Int) canonical_injection(G, j)
@deprecate projection(G::DirectProductGroup, j::Int) canonical_projection(G, j)
@deprecate embedding(G::SemidirectProductGroup, n::Int) canonical_injection(G, n)
@deprecate projection(G::SemidirectProductGroup) canonical_projection(G)
@deprecate embedding(W::WreathProductGroup, n::Int) canonical_injection(W, n)
@deprecate projection(W::WreathProductGroup) canonical_projection(W)
60 changes: 30 additions & 30 deletions test/Groups/directproducts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@

G,emb,proj = direct_product(S,C; morphisms=true)
@test G==direct_product(S,C)
@test emb[1]==embedding(G,1)
@test emb[2]==embedding(G,2)
@test proj[1]==projection(G,1)
@test proj[2]==projection(G,2)
@test emb[1]==canonical_injection(G,1)
@test emb[2]==canonical_injection(G,2)
@test proj[1]==canonical_projection(G,1)
@test proj[2]==canonical_projection(G,2)

x = rand(G)
@test x in G
@test projection(G,1)(x) in S
@test projection(G,2)(x) in C
@test embedding(G,1)(rand(S)) in G
@test embedding(G,2)(rand(C)) in G
@test x==G(projection(G,1)(x), projection(G,2)(x))
@test x==embedding(G,1)(projection(G,1)(x))*embedding(G,2)(projection(G,2)(x))
S1 = image(embedding(G,1))[1]
C1 = image(embedding(G,2))[1]
@test canonical_projection(G,1)(x) in S
@test canonical_projection(G,2)(x) in C
@test canonical_injection(G,1)(rand(S)) in G
@test canonical_injection(G,2)(rand(C)) in G
@test x==G(canonical_projection(G,1)(x), canonical_projection(G,2)(x))
@test x==canonical_injection(G,1)(canonical_projection(G,1)(x))*canonical_injection(G,2)(canonical_projection(G,2)(x))
S1 = image(canonical_injection(G,1))[1]
C1 = image(canonical_injection(G,2))[1]
@test intersect(G,S1)[1]==S1
@test is_isomorphic(S1,S)
@test is_isomorphic(quo(G,S1)[1],C)
Expand Down Expand Up @@ -150,20 +150,20 @@ end
@test is_subset(H, G)
@test index(G,H)==4
@test !is_full_semidirect_product(H)
@test projection(G)(x)==projection(H)(x)
@test canonical_projection(G)(x)==canonical_projection(H)(x)
@test H==center(G)[1]
y=G(Q[1],one(C))
K = sub(G,gens(G))[1]
# @test is_full_semidirect_product(K)
K = sub(G,[y])[1]
@test K==sub(y)[1]
@test K==sub(y)[1]
@test y == embedding(G,1)(Q[1])
@test_throws ArgumentError embedding(G,3)(Q[1])
@test codomain(projection(K))==C
@test order(image(projection(K))[1])==1
@test embedding(G,2)*projection(G)==id_hom(C)
@test image(embedding(G,1))[1]==kernel(projection(G))[1]
@test y == canonical_injection(G,1)(Q[1])
@test_throws ArgumentError canonical_injection(G,3)(Q[1])
@test codomain(canonical_projection(K))==C
@test order(image(canonical_projection(K))[1])==1
@test canonical_injection(G,2)*canonical_projection(G)==id_hom(C)
@test image(canonical_injection(G,1))[1]==kernel(canonical_projection(G))[1]
end


Expand All @@ -186,13 +186,13 @@ end
@test rand(W) isa elem_type(WreathProductGroup)
f1 = C[1]
x = W(f1,one(C),f1,one(C),cperm([1,4,2]))
@test embedding(W,1)(f1)==W(f1,one(C),one(C),one(C),one(H))
@test embedding(W,4)(f1)==W(one(C),one(C),one(C),f1,one(H))
@test_throws ArgumentError embedding(W,7)(f1) in W
@test embedding(W,5)(cperm([1,4,2]))==W(one(C),one(C),one(C),one(C),cperm([1,4,2]))
@test projection(W)(x)==cperm([1,4,2])
@test codomain(projection(W))==H
@test domain(embedding(W,2))==C
@test canonical_injection(W,1)(f1)==W(f1,one(C),one(C),one(C),one(H))
@test canonical_injection(W,4)(f1)==W(one(C),one(C),one(C),f1,one(H))
@test_throws ArgumentError canonical_injection(W,7)(f1) in W
@test canonical_injection(W,5)(cperm([1,4,2]))==W(one(C),one(C),one(C),one(C),cperm([1,4,2]))
@test canonical_projection(W)(x)==cperm([1,4,2])
@test codomain(canonical_projection(W))==H
@test domain(canonical_injection(W,2))==C
K = sub(W,gens(W))[1]
# @test is_full_wreath_product(K)
K = sub(W,[x])[1]
Expand All @@ -202,7 +202,7 @@ end
@test order(K)==6
@test is_cyclic(K)
@test index(W,K)==8
@test_throws ArgumentError embedding(K,1)(f1) in K
@test_throws ArgumentError canonical_injection(K,1)(f1) in K

C = cyclic_group(3)
a = hom(C,H,[C[1]],[cperm([1,2,4])])
Expand All @@ -212,8 +212,8 @@ end
@test is_isomorphic(normal_subgroup(W),C)
@test is_isomorphic(acting_subgroup(W),C)
@test homomorphism_of_wreath_product(W)==a
@test embedding(W,1)(C[1]) in W
@test canonical_injection(W,1)(C[1]) in W
@test W(C[1],one(C),one(C),C[1]) isa elem_type(WreathProductGroup)
@test image(projection(W))[1]==C
@test_throws ArgumentError embedding(W,5)(C[1])
@test image(canonical_projection(W))[1]==C
@test_throws ArgumentError canonical_injection(W,5)(C[1])
end
Loading
Loading