Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasBreuer committed Feb 13, 2024
1 parent e7a75c2 commit d0cc35f
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 4 deletions.
12 changes: 12 additions & 0 deletions docs/src/Groups/subgroups.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ upper_central_series
one can type `embedding(G,H)`.


The following functions return an iterator of subgroups.
Usually it is more efficient to work with (representatives of) the
underlying conjugacy classes of subgroups instead.

```@docs
complements(G::T, N::T) where T <: GAPGroup
hall_subgroups
low_index_subgroups
maximal_subgroups
subgroups(G::GAPGroup)
```

## Conjugation action of elements and subgroups

```@docs
Expand Down
82 changes: 82 additions & 0 deletions src/Groups/GAPGroups.jl
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,23 @@ function subgroup_classes(G::GAPGroup; order::T = ZZRingElem(-1)) where T <: Int
return [GAPGroupConjClass(G, _as_subgroup_bare(G, GAPWrap.Representative(cc)), cc) for cc in L]
end

"""
subgroups(G::GAPGroup)
Return an iterator of all subgroups in `G`.
Very likely it is better to use [`subgroup_classes`](@ref) instead.
# Examples
```jldoctest
julia> println([order(H) for H in subgroups(symmetric_group(3))])
ZZRingElem[1, 2, 2, 2, 3, 6]
julia> println([order(H) for H in subgroups(quaternion_group(8))])
ZZRingElem[1, 2, 4, 4, 4, 8]
```
"""
subgroups(G::GAPGroup) = Iterators.flatten(subgroup_classes(G))

"""
maximal_subgroup_classes(G::Group)
Expand All @@ -810,6 +827,23 @@ julia> maximal_subgroup_classes(G)
return Vector{GAPGroupConjClass{T, T}}(LL)
end

"""
maximal_subgroups(G::Group)
Return an iterator of the maximal subgroups in `G`.
Very likely it is better to use [`maximal_subgroup_classes`](@ref) instead.
# Examples
```jldoctest
julia> println([order(H) for H in maximal_subgroups(symmetric_group(3))])
ZZRingElem[3, 2, 2, 2]
julia> println([order(H) for H in maximal_subgroups(quaternion_group(8))])
ZZRingElem[4, 4, 4]
```
"""
maximal_subgroups(G::T) where T <: Union{GAPGroup, FinGenAbGroup} = Iterators.flatten(maximal_subgroup_classes(G))

"""
low_index_subgroup_classes(G::GAPGroup, n::Int)
Expand All @@ -832,6 +866,22 @@ function low_index_subgroup_classes(G::GAPGroup, n::Int)
return [conjugacy_class(G, H) for H in _as_subgroups(G, ll)]
end

"""
low_index_subgroups(G::Group, n::Int)
Return an iterator of the subgroups of index at most `n` in `G`.
Very likely it is better to use [`low_index_subgroup_classes`](@ref) instead.
# Examples
```jldoctest
julia> G = alternating_group(6);
julia> length(collect(low_index_subgroups(G, 6)))
13
```
"""
low_index_subgroups(G::T, n::Int) where T <: Union{GAPGroup, FinGenAbGroup} = Iterators.flatten(low_index_subgroup_classes(G, n))

"""
conjugate_group(G::T, x::GAPGroupElem) where T <: GAPGroup
Expand Down Expand Up @@ -1254,6 +1304,22 @@ function hall_subgroup_classes(G::GAPGroup, P::AbstractVector{<:IntegerUnion})
end
end

"""
hall_subgroups(G::Group, P::AbstractVector{<:IntegerUnion})
Return an iterator of the Hall `P`-subgroups in `G`.
Very likely it is better to use [`hall_subgroup_classes`](@ref) instead.
# Examples
```jldoctest
julia> g = GL(3, 2);
julia> describe(first(hall_subgroups(g, [2, 3])))
"S4"
```
"""
hall_subgroups(G::T, P::AbstractVector{<:IntegerUnion}) where T <: Union{GAPGroup, FinGenAbGroup} = Iterators.flatten(hall_subgroup_classes(G, P))

@doc raw"""
sylow_system(G::Group)
Expand Down Expand Up @@ -1304,6 +1370,22 @@ function complement_classes(G::T, N::T) where T <: GAPGroup
end
end

@doc raw"""
complements(G::T, N::T) where T <: GAPGroup
Return an iterator of the complements of the normal subgroup `N` in `G`.
Very likely it is better to use [`complement_classes`](@ref) instead.
# Examples
```jldoctest
julia> G = symmetric_group(3);
julia> describe(first(complements(G, derived_subgroup(G)[1])))
"C2"
```
"""
complements(G::T, N::T) where T <: GAPGroup = Iterators.flatten(complement_classes(G, N))

@doc raw"""
complement_system(G::Group)
Expand Down
9 changes: 6 additions & 3 deletions src/Groups/sub.jl
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ julia> lower_central_series(symmetric_group(4))
upper_central_series(G::GAPGroup)
Return the vector $[ G_1, G_2, \ldots ]$ where the last entry is the
trivial group, and $G_i$ is defined as the overgroup of $G_{i+1}
trivial group, and $G_i$ is defined as the overgroup of $G_{i+1}$
satisfying $G_i / G_{i+1} = Z(G/G_{i+1})$. The series ends as soon as
it is repeating (e.g. when the whole group $G$ is reached, which
happens if and only if $G$ is nilpotent).
Expand Down Expand Up @@ -554,9 +554,12 @@ function is_maximal_subgroup(H::T, G::T; check::Bool = true) where T <: GAPGroup
if check
@req is_subset(H, G) "H is not a subgroup of G"
end
if order(G) // order(H) < 100
ind = index(G, H)
is_prime(ind) && return true
if ind < 100
# Do not unpack the right transversal object.
t = right_transversal(G, H)[2:end] #drop the identity
return all(x -> order(sub(G, vcat(gens(H), [x]))[1]) == order(G), t)
return all(i -> order(sub(G, vcat(gens(H), [t[i]]))[1]) == order(G), 2:ind)
end
return any(C -> H in C, maximal_subgroup_classes(G))
end
Expand Down
4 changes: 4 additions & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ export complement_of_point_ideal
export complement_of_prime_ideal
export complement_scheme
export complement_system, has_complement_system, set_complement_system
export complements
export complete_bipartite_graph
export complete_graph
export complete_intersection_germ
Expand Down Expand Up @@ -611,6 +612,7 @@ export halfspace
export halfspace_matrix_pair
export hall_subgroup
export hall_subgroup_classes
export hall_subgroups
export hall_system, has_hall_system, set_hall_system
export has_du_val_singularities
export has_edge
Expand Down Expand Up @@ -944,6 +946,7 @@ export localization
export localized_ring
export loops
export low_index_subgroup_classes
export low_index_subgroups
export lower_central_series, has_lower_central_series, set_lower_central_series
export lower_triangular_matrix
export map
Expand Down Expand Up @@ -982,6 +985,7 @@ export maximal_groebner_cone
export maximal_normal_subgroups, has_maximal_normal_subgroups, set_maximal_normal_subgroups
export maximal_polyhedra, maximal_polyhedra_and_multiplicities
export maximal_subgroup_classes, has_maximal_subgroup_classes, set_maximal_subgroup_classes
export maximal_subgroups
export metadata
export milnor_algebra
export milnor_number
Expand Down
5 changes: 5 additions & 0 deletions test/Groups/GrpAb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ end
# conjugacy classes of subgroups
CC = subgroup_classes(G1)
@test length(CC) == length(subgroup_classes(G2))
@test length(CC) == length(collect(subgroups(G1)))
@test all(C -> length(C) == 1, CC)
@test rand(CC[1]) == representative(CC[1])
@test acting_group(CC[1]) == G1
Expand Down Expand Up @@ -117,10 +118,12 @@ end
S1 = low_index_subgroup_classes(G1, n)
S2 = low_index_subgroup_classes(G2, n)
@test length(S1) == length(S2)
@test length(S1) == length(collect(low_index_subgroups(G1, n)))
end
S1 = maximal_subgroup_classes(G1)
S2 = maximal_subgroup_classes(G2)
@test sort!([length(x) for x in S1]) == sort!([length(x) for x in S2])
@test length(S1) == length(collect(maximal_subgroups(G1)))

# operations
x = representative(rand(cc))
Expand All @@ -140,6 +143,8 @@ end
for P in subsets(Set(primes))
@test [images(iso, representative(C))[1] for C in hall_subgroup_classes(G1, collect(P))] ==
map(representative, hall_subgroup_classes(G2, collect(P)))
@test [images(iso, C)[1] for C in hall_subgroups(G1, collect(P))] ==
collect(hall_subgroups(G2, collect(P)))
end
@test sort!([order(images(iso, S)[1]) for S in hall_system(G1)]) ==
sort!([order(S) for S in hall_system(G2)])
Expand Down
4 changes: 3 additions & 1 deletion test/Groups/conjugation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@

G = symmetric_group(5)
CC = @inferred maximal_subgroup_classes(G)
all(H -> degree(H) == degree(G), map(representative, CC))
@test all(H -> degree(H) == degree(G), map(representative, CC))
@test all(H -> is_maximal_subgroup(G, H), map(representative, CC))
@test !is_maximal_subgroup(G, trivial_subgroup(G)[1])

G = symmetric_group(10)
x = rand(G)
Expand Down

0 comments on commit d0cc35f

Please sign in to comment.