Basics

Elements of groups

Given a group G, it is always possible to have access to some particular elements.

GAPGroupType
GAPGroup <: 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.

source
BasicGAPGroupElemType
BasicGAPGroupElem{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}.

source
elem_typeMethod
elem_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.

source
oneMethod
one(G::GAPGroup) -> elem_type(G)

Return the identity of the group G.

source
oneMethod
one(x::GAPGroupElem{T}) -> GAPGroupElem{T}

Return the identity of the parent group of x.

source
is_finite_orderMethod
is_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
source
gensMethod
gens(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)
Note

The output of gens(G) is not, in general, the minimal list of generators for G.

source
has_gensMethod
has_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
source
number_of_generatorsMethod
number_of_generators(G::GAPGroup) -> Int

Return the length of the vector gens(G).

WARNING:

this is NOT, in general, the minimum number of generators for G.

source
genMethod
gen(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)
source
small_generating_setMethod
small_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
source
randMethod
rand(rng::Random.AbstractRNG = Random.GLOBAL_RNG, G::Group)

Return a random element of G, using the random number generator rng.

source
rand_pseudoMethod
rand_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.

source

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) and x^-1, the inverse of x.
  • x/y, the element x y^-1.
  • x^n, the n-th power of x; if n == 0, the identity of the group is returned; if n < 0, the -n-th power of the inverse of x is returned.
  • isone(x) returns whether x is the identity of the group.
  • conj(x,y) and x^y, the conjugate of x by y, i.e., the element y^-1 x y.
  • comm(x,y), the commutator of x and y, i.e., the element x^-1 y^-1 x y.
Note

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.

commMethod
comm(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.

source

Properties of groups

is_finiteMethod
is_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
source
is_trivialMethod
is_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
source
is_cyclicMethod
is_cyclic(G::GAPGroup)

Return true if G is cyclic, i.e., if G can be generated by one element.

source
is_abelianMethod
is_abelian(G::Group)

Return true if G is abelian (commutative), that is, $x*y = y*x$ holds for all elements $x, y$ in G.

source
is_elementary_abelianMethod
is_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
source
is_pgroupMethod
is_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
source
is_pgroup_with_primeMethod
is_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)
source
is_nilpotentMethod
is_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
source
is_supersolvableMethod
is_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
source
is_solvableMethod
is_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
source
is_perfectMethod
is_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
source
is_simpleMethod
is_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
source
is_almost_simpleMethod
is_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
source
is_quasisimpleMethod
is_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
source
is_sporadic_simpleMethod
is_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
source
is_finitely_generatedMethod
is_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
source

Attributes of groups

orderMethod
order(::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
source
abelian_invariantsMethod
abelian_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[]
source
abelian_invariants_schur_multiplierMethod
abelian_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[]
source
cyclic_generatorMethod
cyclic_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)
source
exponentMethod
exponent(::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
source
describeMethod
describe(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.

Note
  • 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.

DescriptionSyntax
trivial group1
finite cyclic groupC<size>
infinite cyclic groupZ
alternating groupA<degree>
symmetric groupS<degree>
dihedral groupD<size>
quaternion groupQ<size>
quasidihedral groupQD<size>
projective special linear groupPSL(<n>,<q>)
special linear groupSL(<n>,<q>)
general linear groupGL(<n>,<q>)
proj. special unitary groupPSU(<n>,<q>)
orthogonal group, type BO(2<n>+1,<q>)
orthogonal group, type DO+(2<n>,<q>)
orthogonal group, type 2DO-(2<n>,<q>)
proj. special symplectic groupPSp(2<n>,<q>)
Suzuki group (type 2B)Sz(<q>)
Ree group (type 2F or 2G)Ree(<q>)
Lie group of exceptional typeE(6,<q>), E(7,<q>), E(8,<q>), 2E(6,<q>), F(4,<q>), G(2,<q>)
Steinberg triality group3D(4,<q>)
sporadic simple groupM11, 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 group2F(4,2)'
the indicated group from the library of perfect groupsPerfectGroup(<size>,<id>)
direct productA x B
semidirect productN : H
non-split extensionZ(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"
source
nilpotency_classMethod
nilpotency_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.
source
prime_of_pgroupFunction
prime_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
source
derived_lengthFunction
derived_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
source
schur_coverMethod
schur_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
source
schur_multiplierMethod
schur_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
source