Basics
Elements of groups
Given a group G
, it is always possible to have access to some particular elements.
GAPGroup
— TypeGAPGroup <: AbstractAlgebra.Group
Each object of the abstract type GAPGroup
stores a group object from the GAP system, and thus can delegate questions about this object to GAP.
For expert usage, you can extract the underlying GAP object via GapObj
, i.e., if G
is a GAPGroup
, then GapObj(G)
is the GapObj
underlying G
.
Concrete subtypes of GAPGroup
are PermGroup
, FPGroup
, SubFPGroup
, PcGroup
, SubPcGroup
, and MatrixGroup
.
BasicGAPGroupElem
— TypeBasicGAPGroupElem{T<:GAPGroup} <: GAPGroupElem{T}
The type BasicGAPGroupElem
gathers all types of group elements described only by an underlying GAP object.
If $x$ is an element of the group G
of type T
, then the type of $x$ is BasicGAPGroupElem{T}
.
elem_type
— Methodelem_type(::Type{T}) where T <: GAPGroup
elem_type(::T) where T <: GAPGroup
elem_type
maps (the type of) a group to the type of its elements. For now, a group of type T
has elements of type BasicGAPGroupElem{T}
. So we provide it mostly for consistency with other parts of OSCAR. In the future, a more elaborate setup for group element types might also be needed.
one
— Methodone(G::GAPGroup) -> elem_type(G)
Return the identity of the group G
.
one
— Methodone(x::GAPGroupElem{T}) -> GAPGroupElem{T}
Return the identity of the parent group of x
.
is_finite_order
— Methodis_finite_order(g::GAPGroupElem) -> Bool
Return true
if g
has finite order, and false
otherwise.
Examples
julia> is_finite_order(gen(symmetric_group(5), 1))
true
julia> is_finite_order(gen(free_group(2), 1))
false
gens
— Methodgens(G::Group)
Return a vector of generators of G
. To get the i
-th generator, use G[i]
or gen(G,i)
(see gen
) instead of gens(G)[i]
, as that is more efficient.
Examples
julia> g = symmetric_group(5); gens(g)
2-element Vector{PermGroupElem}:
(1,2,3,4,5)
(1,2)
julia> g[2]
(1,2)
The output of gens(G)
is not, in general, the minimal list of generators for G
.
has_gens
— Methodhas_gens(G::Group)
Return whether generators for the group G
are known.
Examples
julia> F = free_group(2)
Free group of rank 2
julia> has_gens(F)
true
julia> H = derived_subgroup(F)[1]
Free group
julia> has_gens(H)
false
number_of_generators
— Methodnumber_of_generators(G::GAPGroup) -> Int
Return the length of the vector gens
(G)
.
this is NOT, in general, the minimum number of generators for G.
gen
— Methodgen(G::GAPGroup, i::Int)
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 abs(i)
is larger than the length of gens(G)
.
Examples
julia> g = symmetric_group(5); gen(g, 1)
(1,2,3,4,5)
julia> g[-1]
(1,5,4,3,2)
small_generating_set
— Methodsmall_generating_set(G::GAPGroup)
Return a reasonably short vector of elements in G
that generate G
; in general the length of this vector is not minimal.
Examples
julia> length(small_generating_set(abelian_group(SubPcGroup, [2,3,4])))
2
julia> length(small_generating_set(abelian_group(PermGroup, [2,3,4])))
3
rand
— Methodrand(rng::Random.AbstractRNG = Random.GLOBAL_RNG, G::Group)
Return a random element of G
, using the random number generator rng
.
rand_pseudo
— Methodrand_pseudo(G::GAPGroup)
Return a pseudo random element of G
. This works faster than rand
, but the returned elements are not necessarily uniformly distributed.
It is sometimes necessary to work with finite groups that we cannot effectively enumerate, e.g. matrix groups over finite fields. We may not even know the size of these groups. Yet many algorithms need to sample elements from the group "as randomly as possible", whatever that means; but also they need this fast.
The function rand_pseudo
returns elements that are cheap to compute and somehow random, but makes no guarantees about their distribution.
For finitely presented groups, it returns random words of bounded length.
For finite permutation and matrix groups, it uses a variant of the product replacement algorithm. For most inputs, the resulting stream of elements relatively quickly converges to a uniform distribution.
It is also possible to obtain the generators of G
by typing
f1,f2,f3 = gens(G)
This is equivalent to
f1=G[1]; f2=G[2]; f3=G[3];
For a group G
that has been created as a subgroup of another group, generated by a list L
of elements, gens(G)
is equal to L
.
Operations on group elements
OSCAR supports the following operations and functions on group elements.
*
, multiplication between two elements in a group.inv(x)
andx^-1
, the inverse ofx
.x/y
, the elementx y^-1
.x^n
, then
-th power ofx
; ifn == 0
, the identity of the group is returned; ifn < 0
, the-n
-th power of the inverse ofx
is returned.isone(x)
returns whetherx
is the identity of the group.conj(x,y)
andx^y
, the conjugate ofx
byy
, i.e., the elementy^-1 x y
.comm(x,y)
, the commutator ofx
andy
, i.e., the elementx^-1 y^-1 x y
.
In OSCAR, the expression x^y^z
is equivalent to x^(y^z)
. In other words, conjugations are evaluated from the right to the left.
comm
— Methodcomm(x::GAPGroupElem, y::GAPGroupElem)
Return the commutator of x
and y
, which is defined as x^-1*y^-1*x*y
, and usually denoted as [x,y]
in the literature.
Properties of groups
is_finite
— Methodis_finite(G::GAPGroup) -> Bool
Return true
if G
is finite, and false
otherwise.
Examples
julia> is_finite(symmetric_group(5))
true
julia> is_finite(free_group(2))
false
is_trivial
— Methodis_trivial(G::GAPGroup)
Return true
if G
has order 1
, and false
otherwise.
Examples
julia> is_trivial(symmetric_group(1))
true
julia> is_trivial(symmetric_group(2))
false
is_cyclic
— Methodis_cyclic(G::GAPGroup)
Return true
if G
is cyclic, i.e., if G
can be generated by one element.
is_abelian
— Methodis_abelian(G::Group)
Return true
if G
is abelian (commutative), that is, $x*y = y*x$ holds for all elements $x, y$ in G
.
is_elementary_abelian
— Methodis_elementary_abelian(G::Group)
Return true
if G
is a abelian (see is_abelian
) and if there is a prime p
such that the order of each element in G
divides p
.
Examples
julia> g = alternating_group(5);
julia> is_elementary_abelian(sylow_subgroup(g, 2)[1])
true
julia> g = alternating_group(6);
julia> is_elementary_abelian(sylow_subgroup(g, 2)[1])
false
is_pgroup
— Methodis_pgroup(G)
Return true
if G
is a $p$-group for some prime $p$, that is, if the order of every element in G
is a power of $p$.
Note that a finite group is a $p$-group if and only if its order is a prime power. In particular, the trivial group is a $p$-group for every prime.
Examples
julia> is_pgroup(symmetric_group(1))
true
julia> is_pgroup(symmetric_group(2))
true
julia> is_pgroup(symmetric_group(3))
false
is_pgroup_with_prime
— Methodis_pgroup_with_prime(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion
Return (true, nothing)
if G
is the trivial group, (true, p)
if the order of every element in G
is a power of a prime p
, and (false, nothing)
otherwise.
For finite groups G
, the first return value is true
if and only if the order of G
is a prime power.
Examples
julia> is_pgroup_with_prime(symmetric_group(1))
(true, nothing)
julia> is_pgroup_with_prime(symmetric_group(2))
(true, 2)
julia> is_pgroup_with_prime(symmetric_group(3))
(false, nothing)
is_nilpotent
— Methodis_nilpotent(G::GAPGroup)
Return whether G
is nilpotent, i.e., whether the lower central series of G
reaches the trivial subgroup in a finite number of steps.
Examples
julia> is_nilpotent(dihedral_group(8))
true
julia> is_nilpotent(dihedral_group(10))
false
is_supersolvable
— Methodis_supersolvable(G::GAPGroup)
Return whether G
is supersolvable, i.e., G
is finite and has a normal series with cyclic factors.
Examples
julia> is_supersolvable(symmetric_group(3))
true
julia> is_supersolvable(symmetric_group(4))
false
julia> is_supersolvable(symmetric_group(5))
false
is_solvable
— Methodis_solvable(G::GAPGroup)
Return whether G
is solvable, i.e., whether derived_series
(G
) reaches the trivial subgroup in a finite number of steps.
Examples
julia> is_solvable(symmetric_group(3))
true
julia> is_solvable(symmetric_group(4))
true
julia> is_solvable(symmetric_group(5))
false
is_perfect
— Methodis_perfect(G::GAPGroup)
Return whether G
is a perfect group, i.e., equal to its derived subgroup.
Examples
julia> is_perfect(special_linear_group(2, 5))
true
julia> is_perfect(symmetric_group(5))
false
is_simple
— Methodis_simple(G::GAPGroup)
Return whether G
is a simple group, i.e., G
is not trivial and has no non-trivial normal subgroups.
Examples
julia> is_simple(alternating_group(5))
true
julia> is_simple(symmetric_group(5))
false
is_almost_simple
— Methodis_almost_simple(G::GAPGroup)
Return whether G
is an almost simple group, i.e., G
is isomorphic to a group $H$ with the property $S \leq H \leq Aut(S)$, for some non-abelian simple group $S$.
Examples
julia> is_almost_simple(symmetric_group(5))
true
julia> is_almost_simple(special_linear_group(2, 5))
false
is_quasisimple
— Methodis_quasisimple(G::GAPGroup)
Return whether G
is a quasisimple group, i.e., G
is perfect such that the factor group modulo its center is a non-abelian simple group.
Examples
julia> is_quasisimple(special_linear_group(2, 5))
true
julia> is_quasisimple(symmetric_group(5))
false
is_sporadic_simple
— Methodis_sporadic_simple(G::GAPGroup)
Return whether G
is a sporadic simple group.
Examples
julia> is_sporadic_simple(mathieu_group(11))
true
julia> is_sporadic_simple(mathieu_group(10))
false
is_finitely_generated
— Methodis_finitely_generated(G::GAPGroup)
Return whether G
is a finitely generated group.
Examples
julia> F = free_group(2)
Free group of rank 2
julia> is_finitely_generated(F)
true
julia> H = derived_subgroup(F)[1]
Free group
julia> is_finitely_generated(H)
false
Attributes of groups
order
— Methodorder(::Type{T} = ZZRingElem, x::Union{GAPGroupElem, GAPGroup}) where T <: IntegerUnion
Return the order of x
, as an instance of T
.
For a group element x
in the group G
, the order of x
is the smallest positive integer n
such that x^n
is the identity of G
. For a group x
, the order of x
is the number of elements in x
.
An exception is thrown if the order of x
is infinite, use is_finite
for checking the finiteness of a group, and is_finite_order
for checking whether a group element has finite order.
Examples
julia> g = symmetric_group(3);
julia> order(g)
6
julia> order(gen(g, 1))
3
julia> g = free_group(1);
julia> is_finite(g)
false
julia> is_finite_order(gen(g, 1))
false
abelian_invariants
— Methodabelian_invariants(::Type{T} = ZZRingElem, G::Union{GAPGroup, FinGenAbGroup}) where T <: IntegerUnion
Return the sorted vector of abelian invariants of the commutator factor group of G
(see maximal_abelian_quotient
). The entries are prime powers or zeroes and have the type T
. They describe the structure of the commutator factor group of G
as a direct product of cyclic groups of prime power (or infinite) order.
Examples
julia> abelian_invariants(symmetric_group(4))
1-element Vector{ZZRingElem}:
2
julia> abelian_invariants(Int, abelian_group([2, 12]))
3-element Vector{Int64}:
2
3
4
julia> abelian_invariants(alternating_group(5))
ZZRingElem[]
abelian_invariants_schur_multiplier
— Methodabelian_invariants_schur_multiplier(::Type{T} = ZZRingElem, G::Union{GAPGroup, FinGenAbGroup}) where T <: IntegerUnion
Return the sorted vector of abelian invariants (see abelian_invariants
) of the Schur multiplier of G
. The entries are prime powers or zeroes and have the type T
. They describe the structure of the Schur multiplier of G
as a direct product of cyclic groups of prime power (or infinite) order.
Examples
julia> abelian_invariants_schur_multiplier(symmetric_group(4))
1-element Vector{ZZRingElem}:
2
julia> abelian_invariants_schur_multiplier(Int, alternating_group(6))
2-element Vector{Int64}:
2
3
julia> abelian_invariants_schur_multiplier(abelian_group([2, 12]))
1-element Vector{ZZRingElem}:
2
julia> abelian_invariants_schur_multiplier(cyclic_group(5))
ZZRingElem[]
cyclic_generator
— Methodcyclic_generator(G::GAPGroup)
Return an element of G
that generates G
if G
is cyclic, and throw an error otherwise.
Examples
julia> g = permutation_group(5, [cperm(1:3), cperm(4:5)])
Permutation group of degree 5
julia> cyclic_generator(g)
(1,2,3)(4,5)
exponent
— Methodexponent(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion
Return the exponent of G
, as an instance of T
, i.e., the smallest positive integer $e$ such that $g^e$ is the identity of G
for every $g$ in G
.
Examples
julia> exponent(symmetric_group(3))
6
julia> exponent(symmetric_group(13))
360360
describe
— Methoddescribe(G::GAPGroup)
Return a string that describes some aspects of the structure of G
.
For finite groups, the function works well if G
is an abelian group or a finite simple group or a group in one of the following series: symmetric, dihedral, quasidihedral, generalized quaternion, general linear, special linear.
For other finite groups, the function tries to decompose G
as a direct product or a semidirect product, and if this is not possible as a non-splitting extension of a normal subgroup $N$ with the factor group G
$/N$, where $N$ is the center or the derived subgroup or the Frattini subgroup of G
.
For infinite groups, if the group is known to be finitely generated and abelian or free, a reasonable description is printed.
For general infinite groups, or groups for which finiteness is not (yet) known, not much if anything can be done. In particular we avoid potentially expensive checks such as computing the size of the group or whether it is abelian. While we do attempt a few limited fast checks for finiteness and commutativity, these will not detect all finite or commutative groups.
Thus calling describe
again on the same group after additional information about it becomes known to Oscar may yield different outputs.
- for finitely presented groups, even deciding if the group is trivial is impossible in general; the same holds for most other properties, like whether the group is finite, abelian, etc.,
- there is in general no "nice" decomposition of
G
, - there may be several decompositions of
G
, - nonisomorphic groups may yield the same
describe
result, - isomorphic groups may yield different
describe
results, - the computations can take a long time (for example in the case of large $p$-groups), and the results are still often not very helpful.
The following notation is used in the returned string.
Description | Syntax |
---|---|
trivial group | 1 |
finite cyclic group | C<size> |
infinite cyclic group | Z |
alternating group | A<degree> |
symmetric group | S<degree> |
dihedral group | D<size> |
quaternion group | Q<size> |
quasidihedral group | QD<size> |
projective special linear group | PSL(<n>,<q>) |
special linear group | SL(<n>,<q>) |
general linear group | GL(<n>,<q>) |
proj. special unitary group | PSU(<n>,<q>) |
orthogonal group, type B | O(2<n>+1,<q>) |
orthogonal group, type D | O+(2<n>,<q>) |
orthogonal group, type 2D | O-(2<n>,<q>) |
proj. special symplectic group | PSp(2<n>,<q>) |
Suzuki group (type 2B) | Sz(<q>) |
Ree group (type 2F or 2G) | Ree(<q>) |
Lie group of exceptional type | E(6,<q>), E(7,<q>), E(8,<q>), 2E(6,<q>), F(4,<q>), G(2,<q>) |
Steinberg triality group | 3D(4,<q>) |
sporadic simple group | M11, M12, M22, M23, M24, J1, J2, J3, J4, Co1, Co2, Co3, Fi22, Fi23, Fi24', Suz, HS, McL, He, HN, Th, B, M, ON, Ly, Ru |
Tits group | 2F(4,2)' |
the indicated group from the library of perfect groups | PerfectGroup(<size>,<id>) |
direct product | A x B |
semidirect product | N : H |
non-split extension | Z(G) . G/Z(G) = G' . G/G', Phi(G) . G/Phi(G) |
Examples
julia> g = symmetric_group(6);
julia> describe(g)
"S6"
julia> describe(sylow_subgroup(g,2)[1])
"C2 x D8"
julia> describe(sylow_subgroup(g, 3)[1])
"C3 x C3"
julia> describe(free_group(3))
"a free group of rank 3"
nilpotency_class
— Methodnilpotency_class(G::GAPGroup) -> Int
Return the nilpotency class of G
, i.e., the smallest integer $n$ such that G
has a central series with $n$ steps (meaning that it consists of $n+1$ groups). The trivial group is the unique group with nilpotency class 0 and all abelian groups have nilpotency class 1.
An exception is thrown if G
is not nilpotent.
See also lower_central_series
and upper_central_series
.
Examples
julia> nilpotency_class(dihedral_group(8))
2
julia> nilpotency_class(dihedral_group(12))
ERROR: ArgumentError: The group is not nilpotent.
prime_of_pgroup
— Functionprime_of_pgroup(::Type{T} = ZZRingElem, G::GAPGroup) where T <: IntegerUnion
Return the prime $p$ if G
is a non-trivial $p$-group.
An exception is thrown if G
is not a $p$-group or is a trivial group.
Examples
julia> prime_of_pgroup(quaternion_group(8))
2
julia> prime_of_pgroup(UInt16, quaternion_group(8))
0x0002
julia> prime_of_pgroup(symmetric_group(1))
ERROR: ArgumentError: only supported for non-trivial p-groups
julia> prime_of_pgroup(symmetric_group(3))
ERROR: ArgumentError: only supported for non-trivial p-groups
derived_length
— Functionderived_length(G::GAPGroup)
Return the number of steps in the derived series of $G$, that is the series length minus 1. See also derived_series
.
Examples
julia> derived_length(symmetric_group(4))
3
julia> derived_length(symmetric_group(5))
1
julia> derived_length(dihedral_group(8))
2
schur_cover
— Methodschur_cover(::Type{T} = FPGroup, G::GAPGroup) where T <: GAPGroup
Return S, f
where S
is a Schur cover of G
and f
is an epimorphism from S
to G
.
Examples
julia> S, f = schur_cover(symmetric_group(4)); order(S)
48
julia> S, f = schur_cover(PermGroup, dihedral_group(12)); order(S)
24
schur_multiplier
— Methodschur_multiplier(::Type{T} = FinGenAbGroup, G::Union{GAPGroup, FinGenAbGroup}) where T <: Union{GAPGroup, FinGenAbGroup}
Return the Schur multiplier of G
. This is an abelian group whose abelian invariants can be computed with abelian_invariants_schur_multiplier
.
Examples
julia> schur_multiplier(symmetric_group(4))
Z/2
julia> schur_multiplier(PcGroup, alternating_group(6))
Pc group of order 6
julia> schur_multiplier(abelian_group([2, 12]))
Z/2
julia> schur_multiplier(cyclic_group(5))
Z/1