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

Add all_perfect_groups #3434

Merged
merged 2 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions docs/src/Groups/grouplib.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ not have a faithful permutation representation of small degree.
Computations in these groups may be rather time consuming.

```@docs
all_perfect_groups
has_number_of_perfect_groups
has_perfect_group_identification
has_perfect_groups
Expand Down
70 changes: 69 additions & 1 deletion src/Groups/libraries/perfectgroups.jl
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,75 @@ function number_of_perfect_groups(n::IntegerUnion)
return res::Int
end

# TODO: add all_perfect_groups() iterator

"""
all_perfect_groups(L...)

Return the list of all perfect groups (up to permutation isomorphism)
satisfying the conditions described by the arguments. These conditions
may be of one of the following forms:

- `func => intval` selects groups for which the function `func` returns `intval`
- `func => list` selects groups for which the function `func` returns any element inside `list`
- `func` selects groups for which the function `func` returns `true`
- `!func` selects groups for which the function `func` returns `false`

As a special case, the first argument may also be one of the following:
- `intval` selects groups whose order equals `intval`; this is equivalent to `order => intval`
- `intlist` selects groups whose order is in `intlist`; this is equivalent to `order => intlist`

The following functions are currently supported as values for `func`:
Copy link
Member Author

Choose a reason for hiding this comment

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

Note that I do not actually restrict which functions are used in the code; my reading of "supported" here is "we promise these will work, anything else can lead to errors. I could explicitly reject other functions, but there seems no point in this right now.

Copy link
Member

Choose a reason for hiding this comment

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

No problem with the code; if someone asks for supersolvable perfect groups then this is fine.
But it is irritating to read is_supersolvable here.

Copy link
Member

Choose a reason for hiding this comment

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

This was exactly what I expected from the wording.
Is there a reason why this list is so much shorter than e.g. for the transitive groups?

The following functions are currently supported as values for `func`:
- `degree`
- `is_abelian`
- `is_almost_simple`
- `is_cyclic`
- `is_nilpotent`
- `is_perfect`
- `is_primitive`
- `is_quasisimple`
- `is_simple`
- `is_sporadic_simple`
- `is_solvable`
- `is_supersolvable`
- `is_transitive`
- `number_of_conjugacy_classes`
- `number_of_moved_points`
- `order`
- `transitivity`

I suppose this is too computationally expensive?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, just most of these filters make no sense: the only perfect group which is abelian/cyclic/nilpotent/solvable/super-solvable is the trivial group.

And primitive/transitive/degree etc. don't really make sense here -- while we return permutation groups, (a) in a future version we may give the user a choice to also get fp groups, (b) which permutation group representations we use is arbitrary. I.e.: the "degree" of a transitive group is well-defined; the "degree" of a perfect group is not.

Copy link
Member

Choose a reason for hiding this comment

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

Ah okay, thanks for clarifying this.

- `is_quasisimple`
- `is_simple`
- `is_sporadic_simple`
- `number_of_conjugacy_classes`
- `order`

The type of the returned groups is `PermGroup`.

# Examples
```jldoctest
julia> all_perfect_groups(7200)
2-element Vector{PermGroup}:
Permutation group of degree 29 and order 7200
Permutation group of degree 288 and order 7200

julia> all_perfect_groups(order => 1:200, !is_simple)
2-element Vector{PermGroup}:
Permutation group of degree 1 and order 1
Permutation group of degree 24 and order 120
```
"""
function all_perfect_groups(L...)
@req !isempty(L) "must specify at least one filter"
if L[1] isa IntegerUnion || L[1] isa AbstractVector{<:IntegerUnion}
L = (order => L[1], L[2:end]...)
end
# first get all order restrictions
ordsL = [x for x in L if x isa Pair && x[1] == order]
@req !isempty(ordsL) "must restrict the order"
conds = [x for x in L if !(x isa Pair && x[1] == order)]
orders = intersect([x[2] for x in ordsL]...)
fingolfin marked this conversation as resolved.
Show resolved Hide resolved
@req has_perfect_groups(maximum(orders)) "only orders up to 2 million are supported"
res = PermGroup[]
for n in orders, i in 1:number_of_perfect_groups(n)
G = perfect_group(n, i)
ok = true
for c in conds
if c isa Pair
val = c[1](G)
ok = (val == c[2] || val in c[2])
elseif c isa Function
ok = c(G)
else
throw(ArgumentError("expected a function or a pair, got $arg"))
end
ok || break
end
ok && push!(res, G)
end
return res
end

function __init_extraperfect()
for i in [27, 33]
Expand Down
1 change: 1 addition & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export all_blocks
export all_character_table_names
export all_cohomologies
export all_neighbors
export all_perfect_groups
export all_primitive_groups
export all_small_groups
export all_subsets_matroid
Expand Down
15 changes: 15 additions & 0 deletions test/Groups/libraries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ end
@test_throws ArgumentError number_of_perfect_groups(0) # invalid argument
@test_throws ArgumentError number_of_perfect_groups(ZZRingElem(60)^10) # result not known

Gs = all_perfect_groups(order => 1:200)
@test length(Gs) == sum(number_of_perfect_groups, 1:200)
@test Gs == all_perfect_groups(1:200)
@test length(all_perfect_groups(7200)) = number_of_perfect_groups(7200)
benlorenz marked this conversation as resolved.
Show resolved Hide resolved

# all_perfect_groups with additional attributse
@test filter(G -> number_of_conjugacy_classes(G) in 5:8, Gs) == all_perfect_groups(1:200, number_of_conjugacy_classes => 5:8)
@test filter(is_simple, Gs) == all_perfect_groups(1:200, is_simple)
@test filter(is_simple, Gs) == all_perfect_groups(1:200, is_simple => true)
@test filter(!is_simple, Gs) == all_perfect_groups(1:200, !is_simple)
@test filter(!is_simple, Gs) == all_perfect_groups(1:200, is_simple => false)

# all_perfect_groups with multiple order specifications
@test all_perfect_groups(order => 1:5:200, order => 25:50) == all_perfect_groups(order => intersect(1:5:200, 25:50))

# lazy artifact loading (needs network access, see https://github.com/oscar-system/Oscar.jl/issues/2480)
#@test perfect_group(1376256, 1) isa PermGroup
end
Expand Down
Loading