Skip to content

Commit

Permalink
support gen(G::GAPGroup, 0) (#3332)
Browse files Browse the repository at this point in the history
* support `gen(G::GAPGroup, 0)`

This was already supported for `FinGenAbGroup`.

(The delegations between methods are not the same:
For `FinGenAbGroup`, there is special code for `getindex(A, i)`,
and `gen(A, i)` calls `getindes(A, i)`.
For `GAPGroup`, there is special code for `gen(G, i)`,
and the generic `getindex` method from AbstractAlgebra calls `gen(G, i)`.)

* support negative indices, meaning inverses
  • Loading branch information
ThomasBreuer committed Feb 26, 2024
1 parent 6308dd7 commit 58566cc
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 8 deletions.
24 changes: 19 additions & 5 deletions src/Groups/GAPGroups.jl
Original file line number Diff line number Diff line change
Expand Up @@ -445,16 +445,30 @@ has_gens(G::GAPGroup) = GAP.Globals.HasGeneratorsOfGroup(G.X)::Bool
"""
gen(G::GAPGroup, i::Int)
Return the `i`-th element of the vector `gens(G)`.
This is equivalent to `G[i]`, and returns `gens(G)[i]`
Return `one(G)` if `i == 0`,
the `i`-th element of the vector `gens(G)` if `i` is positive,
and the inverse of the `i`-th element of `gens(G)` if `i` is negative.
For positive `i`, this is equivalent to `G[i]`, and returns `gens(G)[i]`
but may be more efficient than the latter.
An exception is thrown if `i` is larger than the length of `gens(G)`.
An exception is thrown if `abs(i)` is larger than the length of `gens(G)`.
# Examples
```jldoctest
julia> g = symmetric_group(5); gen(g, 1)
(1,2,3,4,5)
julia> g[-1]
(1,5,4,3,2)
```
"""
function gen(G::GAPGroup, i::Int)
i == 0 && return one(G)
L = GAPWrap.GeneratorsOfGroup(G.X)::GapObj
@assert length(L) >= i "The number of generators is lower than the given index"
return group_element(G, L[i]::GapObj)
0 < i && i <= length(L) && return group_element(G, L[i]::GapObj)
i < 0 && -i <= length(L) && return group_element(G, inv(L[-i])::GapObj)
@req false "i must be in the range -$(length(L)):$(length(L))"
end

"""
Expand Down
10 changes: 9 additions & 1 deletion src/Groups/matrices/MatGrp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,15 @@ function gens(G::MatrixGroup)
return G.gens
end

gen(G::MatrixGroup, i::Int) = gens(G)[i]
# Note that the `gen(G::GAPGroup, i::Int)` method cannot be used
# for `MatrixGroup` because of the `:gens` attribute.
function gen(G::MatrixGroup, i::Int)
i == 0 && return one(G)
L = gens(G)
0 < i && i <= length(L) && return L[i]
i < 0 && -i <= length(L) && return inv(L[-i])
@req false "i must be in the range -$(length(L)):$(length(L))"
end

number_of_generators(G::MatrixGroup) = length(gens(G))

Expand Down
7 changes: 7 additions & 0 deletions test/Groups/conformance.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ include(joinpath(dirname(pathof(AbstractAlgebra)), "..", "test", "Groups-conform
@test ngens(G) isa Int
@test gens(G) isa Vector{typeof(g)}

@test G[0] == one(G)
l = ngens(G)
@test G[l] == gen(G, l)
@test G[-l] == inv(gen(G, l))
@test_throws ArgumentError G[l+1]
@test_throws ArgumentError G[-l-1]

if is_finite(G)
@test order(G) isa ZZRingElem
@test order(G) > 0
Expand Down
7 changes: 5 additions & 2 deletions test/Groups/elements.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,14 @@ end
@test K[i] == G[i]
@test K[i] == gen(G,i)
end
@test G[0] == gen(G, 0)
@test G[0] == one(G)
@test_throws BoundsError K[0]
end

G = free_group(2)
@test_throws AssertionError gen(G, 3)
@test_throws ErrorException gen(G, 0)
@test_throws ArgumentError gen(G, 3)
@test_throws ArgumentError gen(G, -3)
end

@testset "deepcopy" begin
Expand Down

0 comments on commit 58566cc

Please sign in to comment.