Finitely generated groups and their subgroups are important domains in GAP3. They are represented as permutation groups, matrix groups, ag groups or even more complicated constructs as for instance automorphism groups, direct products or semi-direct products where the group elements are represented by records.
Groups are created using Group
(see Group), they are represented by
records that contain important information about the groups. Subgroups
are created as subgroups of a given group using Subgroup
, and are also
represented by records. See More about Groups and Subgroups for
details about the distinction between groups and subgroups.
Because this chapter is very large it is split into several parts. Each part consists of several sections.
Note that some functions will only work if the elements of a group are represented in an unique way. This is not true in finitely presented groups, see Group Functions for Finitely Presented Groups for a list of functions applicable to finitely presented groups.
The first part describes the operations and functions that are available
for group elements, e.g., Order
(see Group Elements). The next part
tells your more about the distinction of parent groups and subgroups (see
More about Groups and Subgroups). The next parts describe the
functions that compute subgroups, e.g., SylowSubgroup
(Subgroups),
and series of subgroups, e.g., DerivedSeries
(see Series of
Subgroups). The next part describes the functions that compute and test
properties of groups, e.g., AbelianInvariants
and IsSimple
(see
Properties and Property Tests), and that identify the isomorphism type.
The next parts describe conjugacy classes of elements and subgroups (see
Conjugacy Classes) and cosets (see Cosets of Subgroups). The next
part describes the functions that create new groups, e.g.,
DirectProduct
(see Group Constructions). The next part describes
group homomorphisms, e.g., NaturalHomomorphism
(see Group
Homomorphisms). The last part tells you more about the implementation
of groups, e.g., it describes the format of group records (see Set
Functions for Groups).
The functions described in this chapter are implemented in the following
library files. LIBNAME/"grpelms.g"
contains the functions for group
elements, LIBNAME/"group.g"
contains the dispatcher and default group
functions, LIBNAME/"grpcoset.g"
contains the functions for cosets and
factor groups, LIBNAME/"grphomom.g"
implements the group
homomorphisms, and LIBNAME/"grpprods.g"
implements the group
constructions.
The following sections describe the operations and functions available for group elements (see Comparisons of Group Elements, Operations for Group Elements, IsGroupElement, and Order).
Note that group elements usually exist independently of a group, e.g., you can write down two permutations and compute their product without ever defining a group that contains them.
7.2 Comparisons of Group Elements
g = h
g <> h
The equality operator =
evaluates to true
if the group elements g
and h are equal and to false
otherwise. The inequality operator
<>
evaluates to true
if the group elements g and h are not equal
and to false
otherwise.
You can compare group elements with objects of other types. Of course they are never equal. Standard group elements are permutations, ag words and matrices. For examples of generic group elements see for instance DirectProduct.
g < h
g <= h
g >= h
g > h
The operators <
, <=
, >=
and >
evaluate to true
if the group
element g is strictly less than, less than or equal to, greater than or
equal to and strictly greater than the group element h. There is no
general ordering on group elements.
Standard group elements may be compared with objects of other types while generic group elements may disallow such a comparison.
7.3 Operations for Group Elements
The operators *
and /
evaluate to the product and quotient of the
two group elements g and h. The operands must of course lie in a
common parent group, otherwise an error is signaled.
The operator ^
evaluates to the conjugate <h>-1* g* h of
g under h for two group elements elements g and h. The operands
must of course lie in a common parent group, otherwise an error is
signaled.
The powering operator ^
returns the i-th power of a group element
g and an integer i. If i is zero the identity of a parent group of
g is returned.
In this form the operator *
returns a new list where each entry is the
product of g and the corresponding entry of list. Of course
multiplication must be defined between g and each entry of list.
In this form the operator /
returns a new list where each entry is the
quotient of g and the corresponding entry of list. Of course
division must be defined between g and each entry of list.
Comm
returns the commutator <g>-1* h-1* g* h of two
group elements g and h. The operands must of course lie in a common
parent group, otherwise an error is signaled.
LeftNormedComm
returns the left normed commutator
Comm( LeftNormedComm( g1, ..., gn-1 ), gn )
of group elements
g1, ..., gn. The operands must of course lie in a common parent
group, otherwise an error is signaled.
RightNormedComm( g1, g2, ..., gn )
RightNormedComm
returns the right normed commutator
Comm( g1, RightNormedComm( g2, ..., gn ) )
of group elements
g1, ..., gn. The operands must of course lie in a common parent
group, otherwise an error is signaled.
LeftQuotient
returns the left quotient <g>-1* h of two group
elements g and h. The operands must of course lie in a common parent
group, otherwise an error is signaled.
IsGroupElement( obj )
IsGroupElement
returns true
if obj, which may be an object of
arbitrary type, is a group element, and false
otherwise. The function
will signal an error if obj is an unbound variable.
gap> IsGroupElement( 10 ); false gap> IsGroupElement( (11,10) ); true gap> IsGroupElement( IdWord ); true
Order( G, g )
Order
returns the order of a group element g in the group G.
The order is the smallest positive integer i such that <g>i is the identity. The order of the identity is one.
gap> Order( Group( (1,2), (1,2,3,4) ), (1,2,3) ); 3 gap> Order( Group( (1,2), (1,2,3,4) ), () ); 1
7.6 More about Groups and Subgroups
GAP3 distinguishs between parent groups and subgroups of parent groups. Each subgroup belongs to a unique parent group. We say that this parent group is the parent of the subgroup. We also say that a parent group is its own parent.
Parent groups are constructed by Group
and subgroups are constructed by
Subgroup
. The first argument of Subgroup
must be a parent group,
i.e., it must not be a subgroup of a parent group, and this parent group
will be the parent of the constructed subgroup.
Those group functions that take more than one argument require that the
arguments have a common parent. Take for instance CommutatorSubgroup
. It
takes two arguments, a group G and a group H, and returns the
commutator subgroup of H with G. So either G is a parent group,
and H is a
subgroup of this parent group, or G and H are subgroups of a common
parent group P.
gap> s4 := Group( (1,2), (1,2,3,4) ); Group( (1,2), (1,2,3,4) ) gap> c3 := Subgroup( s4, [ (1,2,3) ] ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2,3) ] ) gap> CommutatorSubgroup( s4, c3 ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,3,2), (1,2,4) ] ) # ok,c3
is a subgroup of the parent groups4
gap> a4 := Subgroup( s4, [ (1,2,3), (2,3,4) ] ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2,3), (2,3,4) ] ) gap> CommutatorSubgroup( a4, c3 ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,4)(2,3), (1,3)(2,4) ] ) # also ok,c3
anda4
are subgroups of the parent groups4
gap> x3 := Group( (1,2,3) ); Group( (1,2,3) ) gap> CommutatorSubgroup( s4, x3 ); Error, <G> and <H> must have the same parent group # not ok,s4
is its own parent andx3
is its own parent
Those functions that return new subgroups, as with CommutatorSubgroup
above,
return this subgroup as a subgroup of the common parent of their
arguments. Note especially that the commutator subgroup of c3
with
a4
is
returned as a subgroup of their common parent group s4
, not as a
subgroup of a4
. It can not be a subgroup of a4
, because subgroups
must be subgroups of parent groups, and a4
is not a parent group. Of
course, mathematically the commutator subgroup is a subgroup of a4
.
Note that a subgroup of a parent group need not be a proper subgroup, as can be seen in the following example.
gap> s4 := Group( (1,2), (1,2,3,4) ); Group( (1,2), (1,2,3,4) ) gap> x4 := Subgroup( s4, [ (1,2,3,4), (3,4) ] ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2,3,4), (3,4) ] ) gap> Index( s4, x4 ); 1
One exception to the rule are functions that construct new groups such as
DirectProduct
. They accept groups with different parents. If you want
rename the function DirectProduct
to OuterDirectProduct
.
Another exception is Intersection
(see Intersection), which allows
groups with different parent groups, it computes the intersection in such
cases as if the groups were sets of elements. This is because
Intersection
is not a group function, but a domain function, i.e., it
accepts two (or more) arbitrary domains as arguments.
Whenever you have two subgroups which have different parent groups but
have a common supergroup G you can use AsSubgroup
(see AsSubgroup)
in order to construct new subgroups which have a common parent group G.
gap> s4 := Group( (1,2), (1,2,3,4) ); Group( (1,2), (1,2,3,4) ) gap> x3 := Group( (1,2,3) ); Group( (1,2,3) ) gap> CommutatorSubgroup( s4, x3 ); Error, <G> and <H> must have the same parent group # not ok,s4
is its own parent andx3
is its own parent gap> c3 := AsSubgroup( s4, x3 ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2,3) ] ) gap> CommutatorSubgroup( s4, c3 ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,3,2), (1,2,4) ] )
The following sections describe the functions related to this concept (see IsParent, Parent, Group, AsGroup, IsGroup, Subgroup, AsSubgroup).
IsParent( G )
IsParent
returns true
if G is a parent group, and false
otherwise
(see More about Groups and Subgroups).
Parent( U1, ..., Un )
Parent
returns the common parent group of its subgroups and parent
group arguments.
In case more than one argument is given, all groups must have the same parent group. Otherwise an error is signaled. This can be used to ensure that a collection of given subgroups have a common parent group.
Group( U )
Let U be a parent group or a subgroup. Group
returns a new parent
group G which is isomorphic to U. The generators of G need not be
the same elements as the generators of U. The default group function
uses the same generators, while the ag group function may create new
generators along with a new collector.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> s3 := Subgroup( s4, [ (1,2,3), (1,2) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2,3), (1,2) ] ) gap> Group( s3 ); # same elements Group( (1,2,3), (1,2) ) gap> s4.1 * s3.1; (1,3,4,2) gap> s4 := AgGroup( s4 ); Group( g1, g2, g3, g4 ) gap> a4 := DerivedSubgroup( s4 ); Subgroup( Group( g1, g2, g3, g4 ), [ g2, g3, g4 ] ) gap> a4 := Group( a4 ); # different elements Group( g1, g2, g3 ) gap> s4.1 * a4.1; Error, AgWord op: agwords have different groups
Group( list, id )
Group
returns a new parent group G generated by group elements g1,
..., gn of list. id must be the identity of this group.
Group( g1, ..., gn )
Group
returns a new parent group G generated by group elements
g1, ..., gn.
The generators of this new parent group need not be the same elements as g1, ..., gn. The default group function however returns a group record with generators g1, ..., gn and identity id, while the ag group function may create new generators along with a new collector.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> z4 := Group( s4.1 ); # same element Group( (1,2,3,4) ) gap> s4.1 * z4.1; (1,3)(2,4) gap> s4 := AgGroup( s4 ); Group( g1, g2, g3, g4 ) gap> z4 := Group( s4.1 * s4.3 ); # different elements Group( g1, g2 ) gap> s4.1 * z4.1; Error, AgWord op: agwords have different groups
Let gi1, ..., gim be the set of nontrivial generators in all
four cases. Groups
sets record components G.1
, ..., G.m
to
these generators.
AsGroup( D )
Let D be a domain. AsGroup
returns a group G such that the set of
elements of D is the same as the set of elements of G if this is
possible.
If D is a list of group elements these elements must form a group. Otherwise an error is signaled.
Note that this function returns a parent group or a subgroup of a parent
group depending on D. In order to convert a subgroup into a parent
group you must use Group
(see Group).
gap> s4 := AgGroup( Group( (1,2,3,4), (2,3) ) ); Group( g1, g2, g3, g4 ) gap> Elements( last ); [ IdAgWord, g4, g3, g3*g4, g2, g2*g4, g2*g3, g2*g3*g4, g2^2, g2^2*g4, g2^2*g3, g2^2*g3*g4, g1, g1*g4, g1*g3, g1*g3*g4, g1*g2, g1*g2*g4, g1*g2*g3, g1*g2*g3*g4, g1*g2^2, g1*g2^2*g4, g1*g2^2*g3, g1*g2^2*g3*g4 ] gap> AsGroup( last ); Group( g1, g2, g3, g4 )
The default function GroupOps.AsGroup
for a group D returns a copy of
D. If D is a subgroup then a subgroup is returned. The default
function GroupElementsOps.AsGroup
expects a list D of group elements
forming a group and uses successively Closure
in order to compute a
reduced generating set.
IsGroup( obj )
IsGroup
returns true
if obj, which can be an object of arbitrary
type, is a parent group or a subgroup and false
otherwise. The function
will signal an error if obj is an unbound variable.
gap> IsGroup( Group( (1,2,3) ) ); true gap> IsGroup( 1/2 ); false
Subgroup( G, L )
Let G be a parent group and L be a list of elements g1, ..., gn
of G. Subgroup
returns the subgroup U generated by g1, ..., gn
with parent group G.
Note that this function is the only group function in which the name
Subgroup
does not refer to the mathematical terms subgroup and
supergroup but to the implementation of groups as subgroups and parent
groups. IsSubgroup
(see IsSubgroup) is not the negation of
IsParent
(see IsParent) but decides subgroup and supergroup
relations.
Subgroup
always binds a copy of L to U.generators
, so it is safe
to modify L after calling Subgroup
because this will not change the
entries in U.
Let gi1, ..., gim be the nontrivial generators. Subgroups
binds these generators to U.1
, ..., U.m
.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> v4 := Subgroup( s4, [ (1,2), (1,2)(3,4) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2), (1,2)(3,4) ] ) gap> IsParent( v4 ); false
AsSubgroup( G, U )
Let G be a parent group and U be a parent group or a subgroup with a
possibly different parent group, such that the generators g1, ..., gn
of U are elements of G. AsSubgroup
returns a new subgroup S such
that S has parent group G and is generated by g1, ..., gn.
gap> d8 := Group( (1,2,3,4), (1,2)(3,4) ); Group( (1,2,3,4), (1,2)(3,4) ) gap> z := Centre( d8 ); Subgroup( Group( (1,2,3,4), (1,2)(3,4) ), [ (1,3)(2,4) ] ) gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> Normalizer( s4, AsSubgroup( s4, z ) ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (2,4), (1,2,3,4), (1,3)(2,4) ] )
The following sections describe functions that compute certain subgroups
of a given group, e.g., SylowSubgroup
computes a Sylow subgroup of a
group (see Centralizer, Centre, Closure, CommutatorSubgroup,
ConjugateSubgroup, Core, DerivedSubgroup, FittingSubgroup,
FrattiniSubgroup, NormalClosure, NormalIntersection, Normalizer,
PCore, PrefrattiniSubgroup, Radical, SylowSubgroup,
TrivialSubgroup).
They return group records as described in Group Records for the computed subgroups. Some functions may not terminate if the given group has an infinite set of elements, while other functions may signal an error in such cases.
Here the term ``subgroup'' is used in a mathematical sense. But in GAP3, every group is either a parent group or a subgroup of a unique parent group. If you compute a Sylow subgroup S of a group U with parent group G then S is a subgroup of U but its parent group is G (see More about Groups and Subgroups).
Further sections describe functions that return factor groups of a given group (see FactorGroup and CommutatorFactorGroup).
Agemo( G, p )
G must be a p-group. Agemo
returns the subgroup of G generated
by the p.th powers of the elements of G.
gap> d8 := Group( (1,3)(2,4), (1,2) ); Group( (1,3)(2,4), (1,2) ) gap> Agemo( d8, 2 ); Subgroup( Group( (1,3)(2,4), (1,2) ), [ (1,2)(3,4) ] )
The default function GroupOps.Agemo
computes the subgroup of G
generated by the p.th powers of the generators of G if G is
abelian. Otherwise the function computes the normal closure of the
p.th powers of the representatives of the conjugacy classes of G.
Centralizer( G, x )
Centralizer
returns the centralizer of an element x in G where x
must be an element of the parent group of G.
The centralizer of an element x in G is defined as the set C of elements c of G such that c and x commute.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> v4 := Centralizer( s4, (1,2) ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (3,4), (1,2) ] )
The default function GroupOps.Centralizer
uses Stabilizer
(see
Stabilizer) in order to compute the centralizer of x in G acting by
conjugation.
Centralizer( G, U )
Centralizer
returns the centralizer of a group U in G as group
record. Note that G and U must have a common parent group.
The centralizer of a group U in G is defined as the set C of elements c of C such c commutes with every element of U.
If G is the parent group of U then Centralizer
will set and test
the record component U.centralizer
.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> v4 := Centralizer( s4, (1,2) ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (3,4), (1,2) ] ) gap> c2 := Subgroup( s4, [ (1,3) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,3) ] ) gap> Centralizer( v4, c2 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ ] )
The default function GroupOps.Centralizer
uses Stabilizer
in order to
compute successively the stabilizer of the generators of U.
Centre( G )
Centre
returns the centre of G.
The centre of a group G is defined as the centralizer of G in G.
Note that Centre
sets and tests the record component G.centre
.
gap> d8 := Group( (1,2,3,4), (1,2)(3,4) ); Group( (1,2,3,4), (1,2)(3,4) ) gap> Centre( d8 ); Subgroup( Group( (1,2,3,4), (1,2)(3,4) ), [ (1,3)(2,4) ] )
The default group function GroupOps.Centre
uses Centralizer
(see
Centralizer) in order to compute the centralizer of G in G.
Closure( U, g )
Let U be a group with parent group G and let g be an element of
G. Then Closure
returns the closure C of U and g as subgroup of
G. The closure C of U and g is the subgroup generated by U and
g.
gap> s4 := Group( (1,2,3,4), (1,2 ) ); Group( (1,2,3,4), (1,2) ) gap> s2 := Subgroup( s4, [ (1,2) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2) ] ) gap> Closure( s2, (3,4) ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2), (3,4) ] )
The default function GroupOps.Closure
returns U if U is a parent
group, or if g or its inverse is a generator of U, or if the set of
elements is known and g is in this set, or if g is trivial.
Otherwise the function constructs a new subgroup C which is generated
by the generators of U and the element g.
Note that if the set of elements of U is bound to U.elements
then
GroupOps.Closure
computes the set of elements for C and binds it to
C.elements
.
If U is known to be non-abelian or infinite so is C. If U is known to be abelian the function checks whether g commutes with every generator of U.
Closure( U, S )
Let U and S be two group with a common parent group G. Then
Closure
returns the subgroup of G generated by U and S.
gap> s4 := Group( (1,2,3,4), (1,2 ) ); Group( (1,2,3,4), (1,2) ) gap> s2 := Subgroup( s4, [ (1,2) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2) ] ) gap> z3 := Subgroup( s4, [ (1,2,3) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2,3) ] ) gap> Closure( z3, s2 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2,3), (1,2) ] )
The default function GroupOps.Closure
returns the parent of U and S
if U or S is a parent group. Otherwise the function computes the
closure of U under all generators of S.
Note that if the set of elements of U is bound to U.elements
then
GroupOps.Closure
computes the set of elements for the closure C and
binds it to C.elements
.
CommutatorSubgroup( G, H )
Let G and H be groups with a common parent group.
CommutatorSubgroup
returns the commutator subgroup [ G, H ].
The commutator subgroup of G and H is the group generated by all commutators [ g, h ] with g∈ G and h∈ H.
See also DerivedSubgroup
(DerivedSubgroup).
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> d8 := Group( (1,2,3,4), (1,2)(3,4) ); Group( (1,2,3,4), (1,2)(3,4) ) gap> CommutatorSubgroup( s4, AsSubgroup( s4, d8 ) ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,3)(2,4), (1,3,2) ] )
Let G be generated by g1, ..., gn and H be generated by h1,
..., hm. The normal closure of the subgroup S generated by Comm(
gi, hj ) for 1 ≤ i ≤ n and 1 ≤ j ≤ m under G and H
is the commutator subgroup of G and H (see Hup67). The
default function GroupOps.CommutatorSubgroup
returns the normal closure
of S under the closure of G and H.
ConjugateSubgroup( U, g )
ConjugateSubgroup
returns the subgroup <U>g conjugate to U under
g, which must be an element of the parent group of G.
If present, the flags U.isAbelian
, U.isCyclic
,
U.isElementaryAbelian
, U.isFinite
, U.isNilpotent
,
U.isPerfect
, U.isSimple
, U.isSolvable
, and U.size
are
copied to <U>g .
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> c2 := Subgroup( s4, [ (1,2)(3,4) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2)(3,4) ] ) gap> ConjugateSubgroup( c2, (1,3) ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,4)(2,3) ] )
The default function GroupOps.ConjugateSubgroup
returns U if the set
of elements of U is known and g is an element of this set or if g
is a generator of U. Otherwise it conjugates the generators of U
with g.
If the set of elements of U is known the default function also conjugates and binds it to the conjugate subgroup.
Core( S, U )
Let S and U be groups with a common parent group G. Then Core
returns the core of U under conjugation of S.
The core of a group U under a group S CoreS( U ) is the intersection ∩s∈ S Us of all groups conjugate to U under conjugation by elements of S.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> s4.name := "s4";; gap> d8 := Subgroup( s4, [ (1,2,3,4), (1,2)(3,4) ] ); Subgroup( s4, [ (1,2,3,4), (1,2)(3,4) ] ) gap> Core( s4, d8 ); Subgroup( s4, [ (1,2)(3,4), (1,3)(2,4) ] ) gap> Core( d8, s4 ); s4
The default function GroupOps.Core
starts with U and replaces U
with the intersection of U and a conjugate subgroup of U under a
generator of G until the subgroup is normalized by G.
DerivedSubgroup( G )
DerivedSubgroup
returns the derived subgroup <G>' = [ G, G
] of G.
The derived subgroup of G is the group generated by all commutators [ g, h ] with g, h∈ G.
Note that DerivedSubgroup
sets and tests G.derivedSubgroup
.
CommutatorSubgroup
(see CommutatorSubgroup) allows you to compute the
commutator group of two subgroups.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> DerivedSubgroup( s4 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,3,2), (2,4,3) ] )
Let G be generated by g1, ..., gn. Then the default function
GroupOps.DerivedSubgroup
returns the normal closure of S under G
where S is the subgroup of G generated by Comm( gi, gj ) for 1
≤ j < i ≤ n.
FittingSubgroup( G )
FittingSubgroup
returns the Fitting subgroup of G.
The Fitting subgroup of a group G is the biggest nilpotent normal subgroup of G.
gap> s4; Group( (1,2,3,4), (1,2) ) gap> FittingSubgroup( s4 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,3)(2,4), (1,4)(2,3) ] ) gap> IsNilpotent( last ); true
Let G be a finite group. Then the default group function
GroupOps.FittingSubgroup
computes the subgroup of G generated by the
cores of the Sylow subgroups in G.
FrattiniSubgroup( G )
FrattiniSubgroup
returns the Frattini subgroup of group G.
The Frattini subgroup of a group G is the intersection of all maximal subgroups of G.
gap> s4 := SymmetricGroup( AgWords, 4 );; gap> ss4 := SpecialAgGroup( s4 );; gap> FrattiniSubgroup( ss4 ); Subgroup( Group( g1, g2, g3, g4 ), [ ] )
The generic method computes the Frattini subgroup as intersection of the cores (see Core) of the representatives of the conjugacy classes of maximal subgroups (see ConjugacyClassesMaximalSubgroups).
NormalClosure( S, U )
Let S and U be groups with a common parent group G. Then
NormalClosure
returns the normal closure of U under S as a subgroup
of G.
The normal closure N of a group U under the action of a group S is the smallest subgroup in G that contains U and is invariant under conjugation by elements of S. Note that N is independent of G.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> s4.name := "s4";; gap> d8 := Subgroup( s4, [ (1,2,3,4), (1,2)(3,4) ] ); Subgroup( s4, [ (1,2,3,4), (1,2)(3,4) ] ) gap> NormalClosure( s4, d8 ); Subgroup( s4, [ (1,2,3,4), (1,2)(3,4), (1,3,4,2) ] ) gap> last = s4; true
NormalIntersection( N, U )
Let N and U be two subgroups with a common parent group.
NormalIntersection
returns the intersection in case U normalizes N.
Depending on the domain this may be faster than the general intersection
algorithm (see Intersection). The default function
GroupOps.NormalIntersection
however uses Intersection
.
Normalizer( S, U )
Let S and U be groups with a common parent group G. Then
Normalizer
returns the normalizer of U in S.
The normalizer NS( U ) of U in S is the biggest subgroup of S which leaves U invariant under conjugation.
If S is the parent group of U then Normalizer
sets and tests
U.normalizer
.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> c2 := Subgroup( s4, [ (1,2) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2) ] ) gap> Normalizer( s4, c2 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (3,4), (1,2) ] )
The default function GroupOps.Normalizer
uses Stabilizer
(see
Stabilizer) in order to compute the stabilizer of U in S acting by
conjugation (see ConjugateSubgroup).
PCore( G, p )
PCore
returns the p-core of the finite group G for a prime p.
The p-core is the largest normal subgroup whose size is a power of p. This is the core of the Sylow-p-subgroups (see Core and SylowSubgroup).
Note that PCore
sets and tests G.pCores[ p ]
.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> PCore( s4, 2 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,4)(2,3), (1,3)(2,4) ] ) gap> PCore( s4, 3 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ ] )
The default function GroupOps.PCore
computes the p-core as the core
of a Sylow-p-subgroup (see Core and SylowSubgroup).
PrefrattiniSubgroup( G )
PrefrattiniSubgroup
returns a Prefrattini subgroup of the group G.
A factor M/N of G is called a Frattini factor if M/N ≤ φ(G/N) holds. The group P is a Prefrattini subgroup of G if P covers each Frattini chief factor of G, and if for each maximal subgroup of G there exists a conjugate maximal subgroup, which contains P.
gap> s4 := SymmetricGroup( AgWords, 4 );; gap> ss4 := SpecialAgGroup( s4 );; gap> PrefrattiniSubgroup( ss4 ); Subgroup( Group( g1, g2, g3, g4 ), [ ] )
Currently PrefrattiniSubgroup
can only be applied to special Ag groups
(see Special Ag Groups).
Radical( G )
Radical
returns the radical of the finite group G.
The radical is the largest normal solvable subgroup of G.
gap> g := Group( (1,5), (1,5,6,7,8)(2,3,4) ); Group( (1,5), (1,5,6,7,8)(2,3,4) ) gap> Radical( g ); Subgroup( Group( (1,5), (1,5,6,7,8)(2,3,4) ), [ ( 2, 3, 4) ] )
The default function GroupOps.Radical
tests if G is solvable and
signals an error if not.
SylowSubgroup( G, p )
SylowSubgroup
returns a Sylow-p-subgroup of the finite group G for
a prime p.
Let p be a prime and G be a finite group of order <p>n m where m is relative prime to p. Then by Sylow's theorem there exists at least one subgroup S of G of order <p>n.
Note that SylowSubgroup
sets and tests G.sylowSubgroups[ p ]
.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> SylowSubgroup( s4, 2 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (3,4), (1,2), (1,3)(2,4) ] ) gap> SylowSubgroup( s4, 3 ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (2,3,4) ] )
The default function GroupOps.SylowSubgroup
computes the set of
elements of p power order of G, starts with such an element of
maximal order and computes the closure (see Closure) with normalizing
elements of p power order until a Sylow group is found.
TrivialSubgroup( U )
Let U be a group with parent group G. Then TrivialSubgroup
returns
the trivial subgroup T of U. Note that the parent group of T is G
not U (see Subgroups).
The default function GroupOps.TrivialSubgroup
binds the set of elements
of U, namely [ U.identity ], to T.elements
,
FactorGroup( G, N )
FactorGroup
returns the factor group <G> / N where N must be a
normal subgroup of G (see IsNormal). This is the same as G / N
(see Operations for Groups).
NaturalHomomorphism
returns the natural homomorphism from G (or a
subgroup thereof) onto the factor group (see NaturalHomomorphism).
It is not specified how the factor group N is represented.
gap> a4 := Group( (1,2,3), (2,3,4) );; a4.name := "a4"; "a4" gap> v4 := Subgroup(a4,[(1,2)(3,4),(1,3)(2,4)]);; v4.name := "v4"; "v4" gap> f := FactorGroup( a4, v4 ); (a4 / v4) gap> Size( f ); 3 gap> Elements( f ); [ FactorGroupElement( v4, () ), FactorGroupElement( v4, (2,3,4) ), FactorGroupElement( v4, (2,4,3) ) ]
If G is the parent group of N, FactorGroup
first checks for the
knowledge component N.factorGroup
. If this component is bound,
FactorGroup
returns its value. Otherwise, FactorGroup
calls
G.operations.FactorGroup( G, N )
, remembers the returned value in
N.factorGroup
, and returns it. If G is not the parent group of
N, FactorGroup
calls G.operations.FactorGroup( G, N )
and
returns this value.
The default function called this way is GroupOps.FactorGroup
. It
returns the factor group as a group of factor group elements (see
FactorGroupElement). Look under FactorGroup in the index to see for
which groups this function is overlaid.
FactorGroupElement( N, g )
FactorGroupElement
returns the coset N * g
as a group element.
It is not tested whether g normalizes N, but g must be an element
of the parent group of N.
Factor group elements returned by FactorGroupElement
are represented by
records. Those records contain the following components.
isGroupElement
:true
.
isFactorGroupElement
:true
.
element
:
domain
:FactorGroupElements
(see Domain).
operations
:FactorGroupElementOps
.
All operations for group elements (see Operations for Group Elements) are available for factor group elements, e.g., two factor group elements can be multiplied (provided that they have the same subgroup N).
gap> a4 := Group( (1,2,3), (2,3,4) );; a4.name := "a4";; gap> v4 := Subgroup(a4,[(1,2)(3,4),(1,3)(2,4)]);; v4.name := "v4";; gap> x := FactorGroupElement( v4, (1,2,3) ); FactorGroupElement( v4, (2,4,3) ) gap> y := FactorGroupElement( v4, (2,3,4) ); FactorGroupElement( v4, (2,3,4) ) gap> x * y; FactorGroupElement( v4, () )
CommutatorFactorGroup( G )
CommutatorFactorGroup
returns a group isomorphic to G/<G>'
where <G>' is the derived subgroup of G (see
DerivedSubgroup).
gap> s4 := AgGroup( Group( (1,2,3,4), (1,2) ) ); Group( g1, g2, g3, g4 ) gap> CommutatorFactorGroup( s4 ); Group( g1 )
The default group function GroupOps.CommutatorFactorGroup
uses
DerivedSubgroup
(see DerivedSubgroup) and FactorGroup
(see
FactorGroup) in order to compute the commutator factor group.
The following sections describe functions that compute and return series of subgroups of a given group (see DerivedSeries, LowerCentralSeries, SubnormalSeries, and UpperCentralSeries). The series are returned as lists of subgroups of the group (see More about Groups and Subgroups).
These functions print warnings if the argument is an infinite group, because they may run forever.
DerivedSeries( G )
DerivedSeries
returns the derived series of G.
The derived series is the series of iterated derived subgroups. The group G is solvable if and only if this series reaches {1} after finitely many steps.
Note that this function does not terminate if G is an infinite group with derived series of infinite length.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> DerivedSeries( s4 ); [ Group( (1,2,3,4), (1,2) ), Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,3,2), (1,4,3) ] ), Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,4)(2,3), (1,3)(2,4) ] ), Subgroup( Group( (1,2,3,4), (1,2) ), [ ] ) ]
The default function GroupOps.DerivedSeries
uses DerivedSubgroup
(see
DerivedSubgroup) in order to compute the derived series of G.
CompositionSeries( G )
CompositionSeries
returns a composition series of G as list of
subgroups.
gap> s4 := SymmetricGroup( 4 ); Group( (1,4), (2,4), (3,4) ) gap> s4.name := "s4";; gap> CompositionSeries( s4 ); [ Subgroup( s4, [ (1,2), (1,3,2), (1,3)(2,4), (1,2)(3,4) ] ), Subgroup( s4, [ (1,3,2), (1,3)(2,4), (1,2)(3,4) ] ), Subgroup( s4, [ (1,3)(2,4), (1,2)(3,4) ] ), Subgroup( s4, [ (1,2)(3,4) ] ), Subgroup( s4, [ ] ) ] gap> d8 := SylowSubgroup( s4, 2 ); Subgroup( s4, [ (1,2), (3,4), (1,3)(2,4) ] ) gap> CompositionSeries( d8 ); [ Subgroup( s4, [ (1,3)(2,4), (1,2), (3,4) ] ), Subgroup( s4, [ (1,2), (3,4) ] ), Subgroup( s4, [ (3,4) ] ), Subgroup( s4, [ ] ) ]
Note that there is no default function. GroupOps.CompositionSeries
signals an error if called.
ElementaryAbelianSeries( G )
Let G be a solvable group (see IsSolvable). Then the functions returns a normal series G = E0, E1, ..., En = {1} of G such that the factor groups Ei / Ei+1 are elementary abelian groups.
gap> s5 := SymmetricGroup( 5 );; s5.name := "s5";; gap> s4 := Subgroup( s5, [ (2,3,4,5), (2,3) ] ); Subgroup( s5, [ (2,3,4,5), (2,3) ] ) gap> ElementaryAbelianSeries( s4 ); [ Subgroup( s5, [ (2,3), (2,4,3), (2,5)(3,4), (2,3)(4,5) ] ), Subgroup( s5, [ (2,4,3), (2,5)(3,4), (2,3)(4,5) ] ), Subgroup( s5, [ (2,5)(3,4), (2,3)(4,5) ] ), Subgroup( s5, [ ] ) ]
The default function GroupOps.ElementaryAbelianSeries
uses AgGroup
(see AgGroup) in order to convert G into an isomorphic ag group and
computes the elementary abelian series in this group. (see
Group Functions for Ag Groups).
JenningsSeries( G, p )
JenningsSeries
returns the Jennings series of a p-group G.
The Jennings series of a p-group G is defined as follows. S1 = G and Sn = [ Sn-1, G ] Sip where i is the smallest integer equal or greater than n / p. The length l of S is the smallest integer such that Sl = { 1 }.
Note that Sn = Sn+1 is possible.
gap> G := CyclicGroup( AgWords, 27 ); Group( c27_1, c27_2, c27_3 ) gap> G.name := "G";; gap> JenningsSeries( G ); [ G, Subgroup( G, [ c27_2, c27_3 ] ), Subgroup( G, [ c27_2, c27_3 ] ), Subgroup( G, [ c27_3 ] ), Subgroup( G, [ c27_3 ] ), Subgroup( G, [ c27_3 ] ), Subgroup( G, [ c27_3 ] ), Subgroup( G, [ c27_3 ] ), Subgroup( G, [ c27_3 ] ), Subgroup( G, [ ] ) ]
LowerCentralSeries( G )
LowerCentralSeries
returns the lower central series of G as a list of
group records.
The lower central series is the series defined by S1 = G and Si = [ G, Si-1 ]. The group G is nilpotent if this series reaches {1} after finitely many steps.
Note that this function may not terminate if G is an infinite group.
LowerCentralSeries
sets and tests the record component
G.lowerCentralSeries
in the group record of G.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> LowerCentralSeries( s4 ); [ Group( (1,2,3,4), (1,2) ), Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,3,2), (2,4,3) ] ) ]
The default group function GroupOps.LowerCentralSeries
uses
CommutatorSubgroup
(see CommutatorSubgroup) in order to compute the
lower central series of G.
PCentralSeries( G, p )
PCentralSeries
returns the p-central series of a group G for a
prime p.
The p-central series of a group G is defined as follows. S1 = G and Si+1 is set to [G,Si] * Sip. The length of this series is n, where n = max{ i ; Si > Si+1 }.
gap> s4 := Group( (1,2,3,4), (1,2) );; s4.name := "s4";; gap> PCentralSeries( s4, 3 ); [ s4 ] gap> PCentralSeries( s4, 2 ); [ s4, Subgroup( s4, [ (1,2,3), (1,3,4) ] ) ]
SubnormalSeries( G, U )
Let U be a subgroup of G, then SubnormalSeries
returns a subnormal
series <G> = G1 > ... > Gn of groups such that U is contained in
Gn and there exists no proper subgroup V between Gn and U which
is normal in Gn.
Gn is equal to U if and only if U is subnormal in G.
Note that this function may not terminate if G is an infinite group.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> c2 := Subgroup( s4, [ (1,2) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2) ] ) gap> SubnormalSeries( s4, c2 ); [ Group( (1,2,3,4), (1,2) ) ] gap> IsSubnormal( s4, c2 ); false gap> c2 := Subgroup( s4, [ (1,2)(3,4) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2)(3,4) ] ) gap> SubnormalSeries( s4, c2 ); [ Group( (1,2,3,4), (1,2) ), Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2)(3,4), (1,3)(2,4) ] ), Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2)(3,4) ] ) ] gap> IsSubnormal( s4, c2 ); true
The default function GroupOps.SubnormalSeries
constructs the subnormal
series as follows. G1 = G and Gi+1 is set to the normal closure
(see NormalClosure) of U under Gi. The length of the series is
n, where n = max{i; Gi > Gi+1}.
UpperCentralSeries( G )
UpperCentralSeries
returns the upper central series of G as a list of
subgroups.
The upper central series is the series Sn, ..., S0 defined by S0 = {1} < G and Si/Si-1 = Z( G/Si-1 ) where n = min{ i ; Si = Si+1 }
Note that this function may not terminate if G is an infinite group.
UpperCentralSeries
sets and tests G.upperCentralSeries
in the group
record of G.
gap> d8 := AgGroup( Group( (1,2,3,4), (1,2)(3,4) ) ); Group( g1, g2, g3 ) gap> UpperCentralSeries( d8 ); [ Group( g1, g2, g3 ), Subgroup( Group( g1, g2, g3 ), [ g3 ] ), Subgroup( Group( g1, g2, g3 ), [ ] ) ]
7.45 Properties and Property Tests
The following sections describe the functions that computes or test properties of groups (see AbelianInvariants, DimensionsLoewyFactors, EulerianFunction, Exponent, Factorization, Index, IsAbelian, IsCentral, IsConjugate, IsCyclic, IsElementaryAbelian, IsNilpotent, IsNormal, IsPerfect, IsSimple, IsSolvable, IsSubgroup, IsSubnormal, IsTrivial for Groups, GroupId, PermutationCharacter).
All tests expect a parent group or subgroup and return true
if the
group has the property and false
otherwise. Some functions may not
terminate if the given group has an infinite set of elements. A warning
may be printed in such cases.
In addition the set theoretic functions Elements
, Size
and
IsFinite
, which are described in chapter Domains, can be used for
groups. Size
(see Size) returns the order of a group, this is either
a positive integer or the string ``infinity''. IsFinite
(see
IsFinite) returns true
if a group is finite and false
otherwise.
AbelianInvariants( G )
Let G be an abelian group. Then AbelianInvariants
returns the
abelian invariants of G as a list of integers. If G is not abelian
then the abelian invariants of the commutator factor group of G are
returned.
Let G be a finitely generated abelian group. Then there exist n nontrivial subgroups Ai of prime power order piei and m infinite cyclic subgroups Zj such that <G> = A1 × ... × An × Z1 ... × Zm. The invariants of G are the integers p1e1, ..., pnen together with m zeros.
Note that AbelianInvariants
tests and sets G.abelianInvariants
.
gap> AbelianInvariants( AbelianGroup( AgWords, [2,3,4,5,6,9] ) ); [ 2, 2, 3, 3, 4, 5, 9 ]
The default function GroupOps.AbelianInvariants
requires that G is
finite.
Let G be a finite abelian group of order p1e1...pnen where pi are distinct primes. The default function constructs for every prime pi the series <G>, Gpi, Gpi2, ... and computes the abelian invariants using the indices of these groups.
DimensionsLoewyFactors( G )
Let G be p-group. Then DimensionsLoewyFactors
returns the
dimensions ci of the Loewy factors of FpG.
The Loewy series of FpG is defined as follows. Let R be the Jacobson radical of the group ring FpG. The series R0 = FpG > R1 > ... > Rl+1 = {1} is the Loewy series. The dimensions ci are the dimensions of Ri / Ri+1.
gap> f6 := FreeGroup( 6, "f6" );; gap> g := f6 / [ f6.1^3, f6.2^3, f6.3^3, f6.4^3, f6.5^3, f6.6^3, > Comm(f6.3,f6.2)/f6.6^2, Comm(f6.3,f6.1)/(f6.6*f6.5), > Comm(f6.2,f6.1)/(f6.5*f6.4^2) ];; gap> a := AgGroupFpGroup(g); Group( f6.1, f6.2, f6.3, f6.4, f6.5, f6.6 ) gap> DimensionsLoewyFactors(a); [ 1, 3, 9, 16, 30, 42, 62, 72, 87, 85, 87, 72, 62, 42, 30, 16, 9, 3, 1 ]
The default function GroupOps.DimensionsLoewyFactors
computes the
Jennings series of G and uses Jennings thereom in order to calculate
the dimensions of the Loewy factors.
Let G = X1 ≥ X2 ≥ ... ≥ Xl > Xl+1={1} be the Jennings series of G (see JenningsSeries) and let di be the dimensions of Xi / Xi+1. Then the Jennings polynomial is
∑i=0l ci xi = ∏k=1l (1+xk+x2k+...+x(p-1)k)dk. |
EulerianFunction( G, n )
EulerianFunction
returns the number of n-tuples (g1, g2, ...
gn) of elements of the group G that generate the whole group G.
The elements of a tuple need not be different.
gap> s4 := SymmetricGroup( AgWords, 4 );; gap> ss4 := SpecialAgGroup( s4 );; gap> EulerianFunction( ss4, 1 ); 0 gap> EulerianFunction( ss4, 2 ); 216 gap> EulerianFunction( ss4, 3 ); 10080
Currently EulerianFunction
can only be applied to special Ag groups
(see Special Ag Groups).
Exponent( G )
Let G be a finite group. Then Exponent
returns the exponent of G.
Note that Exponent
tests and sets G.exponent
.
gap> Exponent( Group( (1,2,3,4), (1,2) ) ); 12
The default function GroupOps.Exponent
computes all elements of G and
their orders.
Factorization( G, g )
Let G be a group with generators g1, ..., gn and let g be an
element of G. Factorization
returns a representation of g as word
in the generators of G.
The group record of G must have a component G.abstractGenerators
which contains a list of n abstract words h1, ..., hn. Otherwise a
list of n abstract generators is bound to G.abstractGenerators
. The
function returns an abstract word h = hi1e1 * ... *
himem such that gi1e1 * ... * gimem = g.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> Factorization( s4, (1,2,3) ); x1^3*x2*x1*x2 gap> (1,2,3,4)^3 * (1,2) * (1,2,3,4) * (1,2); (1,2,3)
The default group function GroupOps.Factorization
needs a finite group
G. It computes the set of elements of G using a Dimino algorithm,
together with a representation of these elements as words in the
generators of G.
Index( G, U )
Let U be a subgroup of G. Then Index
returns the index of U in
G as an integer.
Note that Index
sets and checks U.index
if G is the parent group
of U.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> Index( s4, DerivedSubgroup( s4 ) ); 2
The default function GroupOps.Index
needs a finite group G. It
returns the quotient of Size( G )
and Size( U )
.
IsAbelian( G )
IsAbelian
returns true
if the group G is abelian and false
otherwise.
A group G is abelian if and only if for every g, h∈ G the equation g* h = h* g holds.
Note that IsAbelian
sets and tests the record component
G.isAbelian
. If G is abelian it also sets G.centre
.
gap> s4 := Group( (1,2,3,4), (1,2) );; gap> IsAbelian( s4 ); false gap> IsAbelian( Subgroup( s4, [ (1,2) ] ) ); true
The default group function GroupOps.IsAbelian
returns true
for a
group G generated by g1, ..., gn if gi commutes with gj for
i > j.
IsCentral( G, U )
IsCentral
returns true
if the group G centralizes the group U and
false
otherwise.
A group G centralizes a group U if and only if for all g∈ G and for all u∈ U the equation g* u = u* g holds. Note that U need not to be a subgroup of G but they must have a common parent group.
Note that IsCentral
sets and tests U.isCentral
if G is the parent
group of U.
gap> s4 := Group( (1,2,3,4), (1,2) );; gap> d8 := Subgroup( s4, [ (1,2,3,4), (1,2)(3,4) ] );; gap> c2 := Subgroup( s4, [ (1,3)(2,4) ] );; gap> IsCentral( s4, c2 ); false gap> IsCentral( d8, c2 ); true
The default function GroupOps.IsCentral
tests whether G centralizes
U by testing whether the generators of G commutes with the generators
of U.
IsConjugate( G, x, y )
Let x and y be elements of the parent group of G. Then
IsConjugate
returns true
if x is conjugate to y under an element
g of G and false
otherwise.
gap> s5 := Group( (1,2,3,4,5), (1,2) ); Group( (1,2,3,4,5), (1,2) ) gap> a5 := Subgroup( s5, [ (1,2,3), (2,3,4), (3,4,5) ] ); Subgroup( Group( (1,2,3,4,5), (1,2) ), [ (1,2,3), (2,3,4), (3,4,5) ] ) gap> IsConjugate( a5, (1,2,3,4,5), (1,2,3,4,5)^2 ); false gap> IsConjugate( s5, (1,2,3,4,5), (1,2,3,4,5)^2 ); true
The default function GroupOps.IsConjugate
uses Representative
(see
Representative) in order to check whether x is conjugate to y under
G.
IsCyclic( G )
IsCyclic
returns true
if G is cyclic and false
otherwise.
A group G is cyclic if and only if there exists an element g∈ G such that G is generated by g.
Note that IsCyclic
sets and tests the record component G.isCyclic
.
gap> z6 := Group( (1,2,3), (4,5) );; gap> IsCyclic( z6 ); true gap> z36 := AbelianGroup( AgWords, [ 9, 4 ] );; gap> IsCyclic( z36 ); true
The default function GroupOps.IsCyclic
returns false
if G is not an
abelian group. Otherwise it computes the abelian invariants (see
AbelianInvariants) if G is infinite. If G is finite of order
p1e1 ... pnen, where pi are distinct primes, then G is
cyclic if and only if each <G>pi has index pi in G.
IsElementaryAbelian( G )
IsElementaryAbelian
returns true
if the group G is an elementary
abelian p-group for a prime p and false
otherwise.
A p-group G is elementary abelian if and only if for every g, h∈ G the equations g* h = h* g and gp = 1 hold.
Note that the IsElementaryAbelian
sets and tests
G.isElementaryAbelian
.
gap> z4 := Group( (1,2,3,4) );; gap> IsElementaryAbelian( z4 ); false gap> v4 := Group( (1,2)(3,4), (1,3)(2,4) );; gap> IsElementaryAbelian( v4 ); true
The default function GroupOps.IsElementaryAbelian
returns true
if G
is abelian and for some prime p each generator is of order p.
IsNilpotent( G )
IsNilpotent
returns true
if the group G is nilpotent and false
otherwise.
A group G is nilpotent if and only if the lower central series of G is of finite length and reaches {1}.
Note that IsNilpotent
sets and tests the record component
G.isNilpotent
.
gap> s4 := Group( (1,2,3,4), (1,2) );; gap> IsNilpotent( s4 ); false gap> v4 := Group( (1,2)(3,4), (1,3)(2,4) );; gap> IsNilpotent( v4 ); true
The default group function GroupOps.IsNilpotent
computes the lower
central series using LowerCentralSeries
(see LowerCentralSeries) in
order to check whether G is nilpotent.
If G has an infinite set of elements a warning is given, as this function does not stop if G has a lower central series of infinite length.
IsNormal( G, U )
IsNormal
returns true
if the group G normalizes the group U and
false
otherwise.
A group G normalizes a group U if and only if for every g∈ G and u∈ U the element ug is a member of U. Note that U need not be a subgroup of G but they must have a common parent group.
Note that IsNormal
tests and sets U.isNormal
if G is the parent
group of U.
gap> s4 := Group( (1,2,3,4), (1,2) );; gap> d8 := Subgroup( s4, [ (1,2,3,4), (1,2)(3,4) ] );; gap> c2 := Subgroup( s4, [ (1,3)(2,4) ] );; gap> IsNormal( s4, c2 ); false gap> IsNormal( d8, c2 ); true
Let G be a finite group. Then the default function GroupOps.IsNormal
checks whether the conjugate of each generator of U under each
generator of G is an element of U.
If G is an infinite group, then the default function
GroupOps.IsNormal
checks whether the conjugate of each generator of U
under each generator of G and its inverse is an element of U.
IsPerfect( G )
IsPerfect
returns true
if G is a perfect group and false
otherwise.
A group G is perfect if G is equal to its derived subgroup. See DerivedSubgroup.
Note that IsPerfect
sets and tests G.isPerfect
.
gap> a4 := Group( (1,2,3), (2,3,4) ); Group( (1,2,3), (2,3,4) ) gap> IsPerfect( a4 ); false gap> a5 := Group( (1,2,3), (2,3,4), (3,4,5) ); Group( (1,2,3), (2,3,4), (3,4,5) ) gap> IsPerfect( a5 ); true
The default group function GroupOps.IsPerfect
checks for a finite group
G the index of <G>' (see DerivedSubgroup) in G. For an
infinite group it computes the abelian invariants of the commutator
factor group (see AbelianInvariants and CommutatorFactorGroup).
IsSimple( G )
IsSimple
returns true
if G is simple and false
otherwise.
A group G is simple if and only if G and the trivial subgroup are the only normal subgroups of G.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> IsSimple( DerivedSubgroup( s4 ) ); false gap> s5 := Group( (1,2,3,4,5), (1,2) ); Group( (1,2,3,4,5), (1,2) ) gap> IsSimple( DerivedSubgroup( s5 ) ); true
IsSolvable( G )
IsSolvable
returns true
if the group G is solvable and false
otherwise.
A group G is solvable if and only if the derived series of G is of finite length and reaches {1}.
Note that IsSolvable
sets and tests G.isSolvable
.
gap> s4 := Group( (1,2,3,4), (1,2) );; gap> IsSolvable( s4 ); true
The default function GroupOps.IsSolvable
computes the derived series
using the function DerivedSeries
(see DerivedSeries) in order to see
whether G is solvable.
If G has an infinite set of elements a warning is given, as this function does not stop if G has a derived series of infinite length.
IsSubgroup( G, U )
IsSubgroup
returns true
if U is a subgroup of G and false
otherwise.
Note that G and U must have a common parent group. This function
returns true
if and only if the set of elements of U is a subset of
the set of elements of G, it is not the inverse of IsParent
(see
IsParent).
gap> s6 := Group( (1,2,3,4,5,6), (1,2) );; gap> s4 := Subgroup( s6, [ (1,2,3,4), (1,2) ] );; gap> z2 := Subgroup( s6, [ (5,6) ] );; gap> IsSubgroup( s4, z2 ); false gap> v4 := Subgroup( s6, [ (1,2)(3,4), (1,3)(2,4) ] );; gap> IsSubgroup( s4, v4 ); true
If the elements of G are known, then the default function
GroupOps.IsSubgroup
checks whether the set of generators of U is a
subset of the set of elements of G. Otherwise the function checks
whether each generator of U is an element of G using in
.
IsSubnormal( G, U )
IsSubnormal
returns true
if the subgroup U of G is subnormal in
G and false
otherwise.
A subgroup U of G is subnormal if and only if there exists a series of subgroups <G> = G0 > G1 > ... > Gn = U such that Gi is normal in Gi-1 for all i∈{1, ..., n}.
Note that U must be a subgroup of G. The function sets and checks
U.isSubnormal
if G is the parent group of G.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> c2 := Subgroup( s4, [ (1,2) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2) ] ) gap> IsSubnormal( s4, c2 ); false gap> c2 := Subgroup( s4, [ (1,2)(3,4) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2)(3,4) ] ) gap> IsSubnormal( s4, c2 ); true
The default function GroupOps.IsSubnormal
uses SubnormalSeries
(see
SubnormalSeries) in order to check if U is subnormal in G.
GroupOps.IsTrivial( G )
GroupOps.IsTrivial
returns true
if G is the trivial group and
false
otherwise.
Note that G is trivial if and only if the component generators
of the
group record of G is the empty list. It is faster to check this than
to call IsTrivial
.
GroupId( G )
For certain small groups the function returns a record which will identify the isomorphism type of G with respect to certain classifications. This record contains the components described below.
The function will work for all groups of order at most 100 or whose order
is a product of at most three primes. Moreover if the ANU pq is
installed and loaded (see RequirePackage and ANU pq Package) you can
also use GroupId
to identify groups of order 128, 256, 243 and 729. In
this case a standard presentation for G is computed (see
StandardPresentation) and the returned record will only contain the
components size
, pGroupId
, and possibly abelianInvariants
. For 2-
or 3-groups of order at most 100 GroupId
will return the pGroupId
identifier even if the ANU pq is not installed.
catalogue
:
Note that there are minor discrepancies between n and the number in
Neu67 for abelian groups and groups of type D(p,q)xr
.
However, a solvable group G is isomorphic to SolvableGroup(o, n)
,
i.e., GroupId(SolvableGroup(o,n)).catalogue
will be
[o,n]
.
If G is a 2- or 3-group of order at most 100, its number in the
appropriate p-group library is also returned. Note that, for such
groups, the number n usually differs from the p-group identifier
returned in pGroupId
(see below).
3primes
:3primes
holds an identifier for G. The following
isomorphisms are returned in 3primes
:["A",p]
= A(p^3)
, ["B",p]
= B(p^3)
,
["D",p,q,r]
= D(p,q)xr
, ["D",p,q]
= D(p,q)
,
["G",p,q]
= G(p^2,q)
, ["G",p,q,r,s]
= G(p,q,r,s)
,["H",p,q]
= H(p^2,q)
, ["H",p,q,r]
= H(p,q,r)
,
["K",p,q]
= K(p,q^2)
, ["L",p,q,s]
= L(p,q^2,s)
,
["M",p,q]
= M(p,q^2)
, ["N",p,q]
= N(p,q^2)
names
below for a definition of A
... N
).
pGroupId
:GroupId(TwoGroup(o,n)).pGroupId
is always n (and similarly for
3-groups). See The 2-Groups Library and The 3-Groups Library for
details about the libraries of 2- and 3-groups. Note that if G is
a 2- or 3-group of order at most 100 its pGroupId
usually differs
from its GAP solvable library number returned in catalogue
.
abelianInvariants
:
names
:
m
is the cyclic group of order m,
Dm
is the dihedral group of order m,
Qm
is the quaternion group of order m,
QDm
is the quasi-dihedral group of order m,
Sm
is the symmetric group on m points,
Am
is the alternating group on m points,
SL(d,q)
is the special linear group,
GL(d,q)
is the general linear group,
PSL(d,q)
is the projective special linear group,
K^n
is the direct power of m copies of K,
K\$H
is a wreath product of K and H,
K:H
is a split extension of K by H,
K.H
is a non-split extension of K and H,
K+H
is a subdirect product with identified factor groups of K
and H,
KYH
is a central amalgamated product of the groups K and H,
KxH
is the direct product of K and H,
A(p^3)
is 〈 A, B, C ; Ap = Bp = Cp = [A,B] = [A,C] = 1,
[B,C] = A 〉,
B(p^3)
is 〈 A, B, C ; Bp = Cp = A, Ap = [A,B] = [A,C] =
1, [B,C] = A 〉,
D(p,q)
is 〈 A, B ; Aq = Bp = 1, AB = Ax 〉 such
that p|q-1, x ≠ 1 mod q, and xp = 1 mod q,
G(p^2,q)
is 〈 A, B, C ; Ap = Bq = 1, Cp = A, [A,B] =
[A,C] = 1, BC = Bx 〉 such that p|q-1, x ≠ 1 mod
q, and xp = 1 mod q,
G(p,q,r,s)
is 〈 A, B, C ; Ar = Bq = Cp = [A,B] = 1, AC =
Ax, BC = B(ys) 〉 such that p|q-1, p|r-1, x
minimal with x ≠ 1 mod r and xp = 1 mod r, y minimal
with y ≠ 1 mod q and yp = 1 mod q, and 0 < s <
p,
H(p^2,q)
is 〈 A, B ; Aq = B(p2) = 1, AB = Ax
〉 such that p2|q-1, xp ≠ 1 mod q, and x(p2) =
1 mod q,
H(p,q,r)
is 〈 A, B ; Ar = Bpq = 1, AB = Ax 〉
such that pq|r-1, xp ≠ 1 mod r, xq ≠ 1 mod r, and
xpq = 1 mod r,
K(p,q^2)
is 〈 A, B, C ; Aq = Bq = Cp = [A,B] = 1, AC =
Ax, BC = Bx 〉 such that p|q-1, x ≠ 1 mod q, and
xp = 1 mod q,
L(p,q^2,s)
is 〈 A, B, C ; Aq = Bq = Cp = [A,B] = 1, AC
= Ax, BC = B(xs) 〉 such that p|q-1, x ≠ 1 mod
q, xp = 1 mod q, and 1 < s < p, note that
L(q,p^2,s)
≅ L(q,p^2,t)
iff s t = 1 mod p,
M(p,q^2)
is 〈 A, B ; A(q2) = Bp = 1, AB = Ax
〉 such that p|q-1, x ≠ 1 mod q2, and xp = 1 mod
q2,
N(p,q^2)
is 〈 A, B, C ; Aq = Bq = Cp = [A,B] = 1, AC =
A-1B, BC = A-1Bxq+x-1 〉 such that 2 < p,
p|q+1, x is an element of order p mod q2,
^
has the strongest, x
the weakest binding.
gap> q8 := SolvableGroup( 8, 5 );; gap> s4 := SymmetricGroup(4);; gap> d8 := SylowSubgroup( s4, 2 );; gap> GroupId(q8); rec( catalogue := [ 8, 5 ], names := [ "Q8" ], 3primes := [ "B", 2 ], size := 8, pGroupId := 4 ) gap> GroupId(d8); rec( catalogue := [ 8, 4 ], names := [ "D8" ], 3primes := [ "A", 2 ], size := 8, pGroupId := 3 ) gap> GroupId(s4); rec( catalogue := [ 24, 15 ], names := [ "S4" ], size := 24 ) gap> GroupId(DirectProduct(d8,d8)); rec( catalogue := [ 64, 154 ], names := [ "D8xD8" ], size := 64, pGroupId := 226 ) gap> GroupId(DirectProduct(q8,d8)); rec( catalogue := [ 64, 155 ], names := [ "D8xQ8" ], size := 64, pGroupId := 230 ) gap> GroupId( WreathProduct( CyclicGroup(2), CyclicGroup(4) ) ); rec( catalogue := [ 64, 250 ], names := [ ], size := 64, pGroupId := 32 ) gap> f := FreeGroup("c","b","a");; a:=f.3;;b:=f.2;;c:=f.1;; gap> r := [ c^5, b^31, a^31, Comm(b,c)/b^7, Comm(a,c)/a, Comm(a,b) ];; gap> g := AgGroupFpGroup( f / r ); Group( c, b, a ) gap> GroupId(g); rec( 3primes := [ "L", 5, 31, 2 ], names := [ "L(5,31^2,2)" ], size := 4805 ) gap> RequirePackage("anupq"); gap> g := TwoGroup(256,4); Group( a1, a2, a3, a4, a5, a6, a7, a8 ) gap> GroupId(g); rec( size := 256, pGroupId := 4 ) gap> g := TwoGroup(256,232); Group( a1, a2, a3, a4, a5, a6, a7, a8 ) gap> GroupId(g); rec( size := 256, pGroupId := 232 )
PermutationCharacter( G, U )
computes the permutation character of the operation of G on the cosets of U. The permutation character is returned as list of integers such that the i.th position contains the value of the permutation character on the i.th conjugacy class of G (see ConjugacyClasses).
The value of the permutation character of U in G on a class c of G is the number of right cosets invariant under the action of an element of c.
gap> G := SymmetricPermGroup(5);; gap> PermutationCharacter( G, SylowSubgroup(G,2) ); [ 15, 3, 3, 0, 0, 1, 0 ]
For small groups the default function GroupOps.PermutationCharacter
calculates the permutation character by inducing the trivial character of
U. For large groups it counts the fixed points by examining double
cosets of U and the subgroup generated by a class element.
The following sections describe how one can compute conjugacy classes of elements and subgroups in a group (see ConjugacyClasses and ConjugacyClassesSubgroups). Further sections describe how conjugacy classes of elements are created (see ConjugacyClass and IsConjugacyClass), and how they are implemented (see Set Functions for Conjugacy Classes and Conjugacy Class Records). Further sections describe how classes of subgroups are created (see ConjugacyClassSubgroups and IsConjugacyClassSubgroups), and how they are implemented (see Set Functions for Subgroup Conjugacy Classes and Subgroup Conjugacy Class Records). Another section describes the function that returns a conjugacy class of subgroups as a list of subgroups (see ConjugateSubgroups).
ConjugacyClasses( G )
ConjugacyClasses
returns a list of the conjugacy classes of elements of
the group G. The elements in the list returned are conjugacy class
domains as created by ConjugacyClass
(see ConjugacyClass). Because
conjugacy classes are domains, all set theoretic functions can be applied
to them (see Domains).
gap> a5 := Group( (1,2,3), (3,4,5) );; a5.name := "a5";; gap> ConjugacyClasses( a5 ); [ ConjugacyClass( a5, () ), ConjugacyClass( a5, (3,4,5) ), ConjugacyClass( a5, (2,3)(4,5) ), ConjugacyClass( a5, (1,2,3,4,5) ), ConjugacyClass( a5, (1,2,3,5,4) ) ]
ConjugacyClasses
first checks if G.conjugacyClasses
is bound. If
the component is bound, it returns that value. Otherwise it calls
G.operations.ConjugacyClasses( G )
, remembers the returned value in
G.conjugacyClasses
, and returns it.
The default function called this way is GroupOps.ConjugacyClasses
.
This function takes random elements in G and tests whether such a
random element g lies in one of the already known classes. If it does
not it adds the new class ConjugacyClass( G, g )
(see
ConjugacyClass). Also after adding a new class it tests whether any
power of the representative gives rise to a new class. It returns the
list of classes when the sum of the sizes is equal to the size of G.
ConjugacyClass( G, g )
ConjugacyClass
returns the conjugacy class of the element g in the
group G. Signals an error if g is not an element in G. The
conjugacy class is returned as a domain, so that all set theoretic
functions are applicable (see Domains).
gap> a5 := Group( (1,2,3), (3,4,5) );; a5.name := "a5";; gap> c := ConjugacyClass( a5, (1,2,3,4,5) ); ConjugacyClass( a5, (1,2,3,4,5) ) gap> Size( c ); 12 gap> Representative( c ); (1,2,3,4,5) gap> Elements( c ); [ (1,2,3,4,5), (1,2,4,5,3), (1,2,5,3,4), (1,3,5,4,2), (1,3,2,5,4), (1,3,4,2,5), (1,4,3,5,2), (1,4,5,2,3), (1,4,2,3,5), (1,5,4,3,2), (1,5,2,4,3), (1,5,3,2,4) ]
ConjugacyClass
calls G.operations.ConjugacyClass( G, g )
and
returns that value.
The default function called this way is GroupOps.ConjugacyClass
, which
creates a conjugacy class record (see Conjugacy Class Records) with the
operations record ConjugacyClassOps
(see Set Functions for Conjugacy
Classes). Look in the index under ConjugacyClass to see for which
groups this function is overlaid.
PositionClass( G, g )
G must be a domain for which ConjugacyClasses
is defined and g must
be an element of G. This functions returns a positive integer i
such
that g in ConjugacyClasses( G )[i]
.
gap> G := Group( (1,2)(3,4), (1,2,3,4,5) );; gap> ConjugacyClasses( G ); [ ConjugacyClass( Group( (1,2)(3,4), (1,2,3,4,5) ), () ), ConjugacyClass( Group( (1,2)(3,4), (1,2,3,4,5) ), (3,4,5) ), ConjugacyClass( Group( (1,2)(3,4), (1,2,3,4,5) ), (2,3)(4,5) ), ConjugacyClass( Group( (1,2)(3,4), (1,2,3,4,5) ), (1,2,3,4,5) ), ConjugacyClass( Group( (1,2)(3,4), (1,2,3,4,5) ), (1,2,3,5,4) ) ] gap> g := Random( G ); (1,2,5,4,3) gap> PositionClass( G, g ); 5
IsConjugacyClass( obj )
IsConjugacyClass
returns true
if obj is a conjugacy class as
created by ConjugacyClass
(see ConjugacyClass) and false
otherwise.
gap> a5 := Group( (1,2,3), (3,4,5) );; a5.name := "a5";;
gap> c := ConjugacyClass( a5, (1,2,3,4,5) );
ConjugacyClass( a5, (1,2,3,4,5) )
gap> IsConjugacyClass( c );
true
gap> IsConjugacyClass(
> [ (1,2,3,4,5), (1,2,4,5,3), (1,2,5,3,4), (1,3,5,4,2),
> (1,3,2,5,4), (1,3,4,2,5), (1,4,3,5,2), (1,4,5,2,3),
> (1,4,2,3,5), (1,5,4,3,2), (1,5,2,4,3), (1,5,3,2,4) ] );
false # even though this is as a set equal to c
7.72 Set Functions for Conjugacy Classes
As mentioned above, conjugacy classes are domains, so all domain functions are applicable to conjugacy classes (see Domains). This section describes the functions that are implemented especially for conjugacy classes. Functions not mentioned here inherit the default functions mentioned in the respective sections.
In the following let C be the conjugacy class of the element g in the group G.
The elements of the conjugacy class C are computed as the orbit of g under G, where G operates by conjugation.
The size of the conjugacy class C is computed as the index of the centralizer of g in G.
To test whether an element h lies in C, in
tests whether there is
an element of G that takes h to g. This is done by calling
RepresentativeOperation(G,h,g)
(see RepresentativeOperation).
A random element of the conjugacy class C is computed by conjugating g with a random element of G.
A conjugacy class C of an element g in a group G is represented by a record with the following components.
isDomain
:true
.
isConjugacyClass
:true
.
group
:
representative
:The following component is optional. It is computed and assigned when the size of a conjugacy class is computed.
centralizer
:7.74 ConjugacyClassesSubgroups
ConjugacyClassesSubgroups( G )
ConjugacyClassesSubgroups
returns a list of all conjugacy classes of
subgroups of the group G. The elements in the list returned are
conjugacy class domains as created by ConjugacyClassSubgroups
(see
ConjugacyClassSubgroups). Because conjugacy classes are domains, all
set theoretic functions can be applied to them (see Domains).
In fact, ConjugacyClassesSubgroups
computes much more than it returns,
for it calls (indirectly via the function
G.operations.ConjugacyClassesSubgroups( G )
) the Lattice
command
(see Lattice), constructs the whole subgroup lattice of G, stores it
in the record component G.lattice
, and finally returns the list
G.lattice.classes
. This means, in particular, that it will fail if
G is non-solvable and its maximal perfect subgroup is not in the
built-in catalogue of perfect groups (see the description of the
Lattice
command Lattice for details).
gap> # Conjugacy classes of subgroups of S4 gap> s4 := Group( (1,2,3,4), (1,2) );; gap> s4.name := "s4";; gap> cl := ConjugacyClassesSubgroups( s4 ); [ ConjugacyClassSubgroups( s4, Subgroup( s4, [ ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (1,2)(3,4) ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (3,4) ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (2,3,4) ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (1,2)(3,4), (1,3)(2,4) ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (3,4), (1,2) ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (1,2)(3,4), (1,4,2,3) ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (2,3,4), (3,4) ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (3,4), (1,2), (1,3)(2,4) ] ) ), ConjugacyClassSubgroups( s4, Subgroup( s4, [ (1,2)(3,4), (1,3)(2,4), (2,3,4) ] ) ), ConjugacyClassSubgroups( s4, s4 ) ]
Each entry of the resulting list is a domain. As an example, let us take the seventh class in the above list of conjugacy classes of S4.
gap> # Conjugacy classes of subgroups of S4 (continued) gap> class7 := cl[7];; gap> # Print the class representative subgroup. gap> rep7 := Representative( class7 ); Subgroup( s4, [ (1,2)(3,4), (1,4,2,3) ] ) gap> # Print the order of the class representative subgroup. gap> Size( rep7 ); 4 gap> # Print the number of conjugates. gap> Size( class7 ); 3
Lattice( G )
Lattice
returns the lattice of subgroups of the group G in the form
of a record L, say, which contains certain lists with some appropriate
information on the subgroups of G and their conjugacy classes. In
particular, in its component L.classes
, L provides the same list of
all conjugacy classes of all subgroups of G as is returned by the
ConjugacyClassesSubgroups
command (see ConjugacyClassesSubgroups).
The construction of the subgroup lattice record L of a group G may be
very time consuming. Therefore, as soon as L has been computed for the
first time, it will be saved as a component G.lattice
in the group
record G to avoid any duplication of that effort.
The underlying routines are a reimplementation of the subgroup lattice routines which have been developed since 1958 by several people in Kiel and Aachen under the supervision of Joachim Neubüser. Their final version, written by Volkmar Felsch in 1984, has been available since then in Cayley (see BC92) and has also been used in SOGOS (see Sog89). The current implementation in GAP3 by Jürgen Mnich is described in Mni92, a summary of the method and references to all predecessors can be found in FS84.
The Lattice
command invokes the following procedure. In a first step,
the solvable residuum P, say, of G is computed and looked up in
a built-in catalogue of perfect groups which is given in the file
LIBNAME/"lattperf.g"
. A list of subgroups is read off from that
catalogue which contains just one representative of each conjugacy class
of perfect subgroups of P and hence at least one representative of each
conjugacy class of perfect subgroups of G. Then, starting from the
identity subgroup and the conjugacy classes of perfect subgroups, the so
called cyclic extension method is used to compute the non-perfect
subgroups of G by forming for each class representative all its not yet
involved cyclic extensions of prime number index and adding their
conjugacy classes to the list.
It is clear that this procedure cannot work if the catalogue of perfect
groups does not contain a group isomorphic to P. At present, it
contains only all perfect groups of order less than 5000 and, in
addition, the groups PSL(3,3), M11, and A8. If the Lattice
command is called for a group G with a solvable residuum P not in the
catalogue, it will provide an error message. As an example we handle the
group SL(2,19) of order 6840.
gap> s := [ [4,0], [0,5] ] * Z( 19 )^0;; gap> t := [ [4,4], [-9,-4] ] * Z(19)^0;; gap> G := Group( s, t );; gap> Size( G ); 6840 gap> Lattice( G ); Error, sorry, can' t identify the group's solvable residuum
However, if you know the perfect subgroups of G, you can use the
Lattice
command to compute the whole subgroup lattice of G even if
the solvable residuum of G is not in the catalogue. All you have to do
in such a case is to create a list of subgroups of G which contains at
least one representative of each conjugacy class of proper perfect
subgroups of G, attach this list to the group record as a new component
G.perfectSubgroups
, and then call the Lattice
command. The
existence of that record component will prevent GAP3 from looking up
the solvable residuum of G in the catalogue. Instead, it will insert
the given subgroups into the lattice, leaving it to you to guarantee that
in fact all conjugacy classes of proper perfect subgroups are involved.
If you miss classes, the resulting lattice will be incomplete, but you
will not get any warning. As long as you are aware of this fact, you may
use this possibility to compute a sublattice of the subgroup lattice of
G without getting the above mentioned error message even if the
solvable residuum of G is not in the catalogue. In particular, you will
get at least the classes of all proper solvable subgroups of G if you
define G.perfectSubgroups
to be an empty list.
As an example for the computation of the complete lattice of subgroups of a group which is not covered by the catalogue, we handle the Mathieu group M12.
gap> # Define the Mathieu group M12. gap> a := (2,3,5,7,11,9,8,12,10,6,4);; gap> b := (3,6)(5,8)(9,11)(10,12);; gap> c := (1,2)(3,4)(5,9)(6,8)(7,12)(10,11);; gap> M12 := Group( a, b, c );; gap> Print( "#I M12 has order ", Size( M12 ), "\n" ); #I M12 has order 95040 gap> # Define a list of proper perfect subgroups of M_12 and attach gap> # it to the group record M12 as component M12.perfectSubgroups. gap> L2_11a := Subgroup( M12, [ a, b ] );; gap> M11a := Subgroup( M12, [ a, b, c*a^-1*b*a*c ] );; gap> M11b := Subgroup( M12, [ a, b, c*a*b*a^-1*c ] );; gap> x := a*b*a^2;; gap> y := a*c*a^-1*b*a*c*a^6;; gap> A6a := Subgroup( M12, [ x, y ] );; gap> A5c := Subgroup( M12, [ x*y, x^3*y^2*x^2*y ] );; gap> x := a^2*b*a;; gap> y := a^6*c*a*b*a^-1*c*a;; gap> A6b := Subgroup( M12, [ x, y ] );; gap> A5d := Subgroup( M12, [ x*y, x^3*y^2*x^2*y ] );; gap> x := a;; gap> y := b*c*b;; gap> z := c;; gap> L2_11b := Subgroup( M12, [ x, y, z ] );; gap> A5b := Subgroup( M12, [ y, x*z ] );; gap> x := c;; gap> y := b*a^-1*c*a*b;; gap> z := a^2*b*a^-1*c*a*b*a^-2;; gap> A5a := Subgroup( M12, [ (x*z)^2, (y*z)^2 ] );; gap> M12.perfectSubgroups := [ > L2_11a, L2_11b, M11a, M11b, A6a, A6b, A5a, A5b, A5c, A5d ];; gap> # Now compute the subgroup lattice of M12. gap> lat := Lattice( M12 ); LatticeSubgroups( Group( ( 2, 3, 5, 7,11, 9, 8,12,10, 6, 4), ( 3, 6) ( 5, 8)( 9,11)(10,12), ( 1, 2)( 3, 4)( 5, 9)( 6, 8)( 7,12)(10,11) ) )
The Lattice
command returns a record which represents a very
complicated structure.
gap> # Subgroup lattice of M12 (continued) gap> RecFields( lat ); [ "isLattice", "classes", "group", "printLevel", "operations" ]
Probably the most important component of the lattice record is the list
lat.classes
. Its elements are domains. They are described in section
ConjugacyClassesSubgroups. We can use this list, for instance, to print
the number of conjugacy classes of subgroups and the number of subgroups
of M12.
gap> # Subgroup lattice of M12 (continued) gap> n1 := Length( lat.classes );; gap> n2 := Sum( [ 1 .. n1 ], i -> Size( lat.classes[i] ) );; gap> Print( "#I M12 has ", n1, " classes of altogether ", n2, > " subgroups\n" ); #I M12 has 147 classes of altogether 214871 subgroups
It would not make sense to get all components of a subgroup lattice
record printed in full detail whenever we ask GAP3 to print the
lattice. Therefore, as you can see in the above example, the default
printout is just an expression of the form "Lattice(\,group\,)
".
However, you can ask GAP3 to display some additional information in any
subsequent printout of the lattice by increasing its individual print
level. This print level is stored (in the form of a list of several
print flags) in the lattice record and can be changed by an appropriate
call of the SetPrintLevel
command described
below.
The following example demonstrates the effect of the subgroup lattice print level.
gap> # Subgroup lattice of S4 gap> s4 := Group( (1,2,3,4), (1,2) );; gap> lat := Lattice( s4 ); LatticeSubgroups( Group( (1,2,3,4), (1,2) ) )
The default subgroup lattice print level is 0. In this case, the print command provides just the expression mentioned above.
gap> # Subgroup lattice of S4 (continued) gap> SetPrintLevel( lat, 1 ); gap> lat; #I class 1, size 1, length 1 #I class 2, size 2, length 3 #I class 3, size 2, length 6 #I class 4, size 3, length 4 #I class 5, size 4, length 1 #I class 6, size 4, length 3 #I class 7, size 4, length 3 #I class 8, size 6, length 4 #I class 9, size 8, length 3 #I class 10, size 12, length 1 #I class 11, size 24, length 1 LatticeSubgroups( Group( (1,2,3,4), (1,2) ) )
If the print level is set to a value greater than 0, you get, in addition, for each class a kind of heading line. This line contains the position number and the length of the respective class as well as the order of the subgroups in the class.
gap> # Subgroup lattice of S4 (continued) gap> SetPrintLevel( lat, 2 ); gap> lat; #I class 1, size 1, length 1 #I representative [ ] #I maximals #I class 2, size 2, length 3 #I representative [ (1,2)(3,4) ] #I maximals [ 1, 1 ] #I class 3, size 2, length 6 #I representative [ (3,4) ] #I maximals [ 1, 1 ] #I class 4, size 3, length 4 #I representative [ (2,3,4) ] #I maximals [ 1, 1 ] #I class 5, size 4, length 1 #I representative [ (1,2)(3,4), (1,3)(2,4) ] #I maximals [ 2, 1 ] [ 2, 2 ] [ 2, 3 ] #I class 6, size 4, length 3 #I representative [ (3,4), (1,2) ] #I maximals [ 3, 1 ] [ 3, 4 ] [ 2, 1 ] #I class 7, size 4, length 3 #I representative [ (1,2)(3,4), (1,4,2,3) ] #I maximals [ 2, 1 ] #I class 8, size 6, length 4 #I representative [ (2,3,4), (3,4) ] #I maximals [ 4, 1 ] [ 3, 1 ] [ 3, 2 ] [ 3, 3 ] #I class 9, size 8, length 3 #I representative [ (3,4), (1,2), (1,3)(2,4) ] #I maximals [ 7, 1 ] [ 6, 1 ] [ 5, 1 ] #I class 10, size 12, length 1 #I representative [ (1,2)(3,4), (1,3)(2,4), (2,3,4) ] #I maximals [ 5, 1 ] [ 4, 1 ] [ 4, 2 ] [ 4, 3 ] [ 4, 4 ] #I class 11, size 24, length 1 #I representative [ (1,2,3,4), (1,2) ] #I maximals [ 10, 1 ] [ 9, 1 ] [ 9, 2 ] [ 9, 3 ] [ 8, 1 ] [ 8, 2 ] [ 8, 3 ] [ 8, 4 ] LatticeSubgroups( Group( (1,2,3,4), (1,2) ) ) gap> PrintClassSubgroupLattice( lat, 8 ); #I class 8, size 6, length 4 #I representative [ (2,3,4), (3,4) ] #I maximals [ 4, 1 ] [ 3, 1 ] [ 3, 2 ] [ 3, 3 ]
If the subgroup lattice print level is at least 2, GAP3 prints, in
addition, for each class representative subgroup a set of generators and
a list of its maximal subgroups, where each maximal subgroup is
represented by a pair of integers consisting of its class number and its
position number in that class. As this information blows up the output,
it may be convenient to restrict it to a particular class. We can do this
by calling the PrintClassSubgroupLattice
command described below.
gap> # Subgroup lattice of S4 (continued) gap> SetPrintLevel( lat, 3 ); gap> PrintClassSubgroupLattice( lat, 8 ); #I class 8, size 6, length 4 #I representative [ (2,3,4), (3,4) ] #I maximals [ 4, 1 ] [ 3, 1 ] [ 3, 2 ] [ 3, 3 ] #I conjugate 2 by (1,4,3,2) is [ (1,2,3), (2,3) ] #I conjugate 3 by (1,2) is [ (1,3,4), (3,4) ] #I conjugate 4 by (1,3)(2,4) is [ (1,2,4), (1,2) ]
If the subgroup lattice print level has been set to at least 3, GAP3 displays, in addition, for each non-representative subgroup of a class its number in the class, an element which transforms the class representative subgroup into that subgroup, and a set of generators.
gap> # Subgroup lattice of S4 (continued) gap> SetPrintLevel( lat, 4 ); gap> PrintClassSubgroupLattice( lat, 8 ); #I class 8, size 6, length 4 #I representative [ (2,3,4), (3,4) ] #I maximals [ 4, 1 ] [ 3, 1 ] [ 3, 2 ] [ 3, 3 ] #I conjugate 2 by (1,4,3,2) is [ (1,2,3), (2,3) ] #I maximals [ 4, 2 ] [ 3, 2 ] [ 3, 4 ] [ 3, 5 ] #I conjugate 3 by (1,2) is [ (1,3,4), (3,4) ] #I maximals [ 4, 3 ] [ 3, 1 ] [ 3, 5 ] [ 3, 6 ] #I conjugate 4 by (1,3)(2,4) is [ (1,2,4), (1,2) ] #I maximals [ 4, 4 ] [ 3, 4 ] [ 3, 6 ] [ 3, 3 ]
A subgroup lattice print level value of at least 4 causes GAP3 to list the maximal subgroups not only for the class representatives, but also for the other subgroups.
gap> # Subgroup lattice of S4 (continued) gap> SetPrintLevel( lat, 5 ); gap> PrintClassSubgroupLattice( lat, 8 ); #I class 8, size 6, length 4 #I representative [ (2,3,4), (3,4) ] #I maximals [ 4, 1 ] [ 3, 1 ] [ 3, 2 ] [ 3, 3 ] #I minimals [ 11, 1 ] #I conjugate 2 by (1,4,3,2) is [ (1,2,3), (2,3) ] #I maximals [ 4, 2 ] [ 3, 2 ] [ 3, 4 ] [ 3, 5 ] #I minimals [ 11, 1 ] #I conjugate 3 by (1,2) is [ (1,3,4), (3,4) ] #I maximals [ 4, 3 ] [ 3, 1 ] [ 3, 5 ] [ 3, 6 ] #I minimals [ 11, 1 ] #I conjugate 4 by (1,3)(2,4) is [ (1,2,4), (1,2) ] #I maximals [ 4, 4 ] [ 3, 4 ] [ 3, 6 ] [ 3, 3 ] #I minimals [ 11, 1 ]
The maximal valid value of the subgroup lattice print level is 5. If it
is set, GAP3 displays not only the maximal subgroups, but also the
minimal supergroups of each subgroup. This is the most extensive output
of a subgroup lattice record which you can get with the Print
command,
but of course you can use the RecFields
command (see RecFields) to
list all record components and then print them out individually in full
detail.
If the computation of some subgroup lattice is very time consuming (as in the above example of the Mathieu group M12), you might wish to see some intermediate printout which informs you about the progress of the computation. In fact, you can get such messages by activating a print mechanism which has been inserted into the subgroup lattice routines for diagnostic purposes. All you have to do is to replace the call
lat := Lattice( M12 );
by the three calls
InfoLattice1 := Print; lat := Lattice( M12 ); InfoLattice1 := Ignore;
Note, however, that the final numbering of the conjugacy classes of subgroups will differ from the order in which they occur in the intermediate listing because they will be reordered by increasing subgroup orders at the end of the construction.
PrintClassSubgroupLattice( lattice, n )
PrintClassSubgroupLattice
prints information on the nth conjugacy
class of subgroups in the subgroup lattice lattice. The amount of this
information depends on the current value of the subgroup lattice print
level of lattice. Note that the default of that print level is zero
which means that you will not get any output from the
PrintClassSubgroupLattice
command without increasing it (see
SetPrintLevel
below). Examples are given in the above description of
the Lattice
command.
SetPrintLevel( lattice, level )
SetPrintLevel
changes the subgroup lattice print level of the subgroup
lattice lattice to the specified value level by an appropriate
alteration of the list of print flags which is stored in
lattice.printLevel
. The argument level is expected to be an
integer between 0 and 5.
Examples of the effect of the subgroup lattice print level are given in
the above description of the Lattice
command.
ConjugacyClassSubgroups( G, U )
ConjugacyClassSubgroups
returns the conjugacy class of the subgroup U
in the group G. Signals an error if U is not a subgroup of G. The
conjugacy class is returned as a domain, so all set theoretic functions
are applicable (see Domains).
gap> s5 := Group( (1,2), (1,2,3,4,5) );; s5.name := "s5";; gap> a5 := DerivedSubgroup( s5 ); Subgroup( s5, [ (1,2,3), (2,3,4), (3,4,5) ] ) gap> C := ConjugacyClassSubgroups( s5, a5 ); ConjugacyClassSubgroups( s5, Subgroup( s5, [ (1,2,3), (2,3,4), (3,4,5) ] ) ) gap> Size( C ); 1
Another example of such domains is given in section ConjugacyClassesSubgroups.
ConjugacyClassSubgroups
calls
G.operations.ConjugacyClassSubgroups( G, U )
and returns this value.
The default function called is GroupOps.ConjugacyClassSubgroups
, which
creates a conjugacy class record (see Subgroup Conjugacy Class Records)
with the operations record ConjugacyClassSubgroupsOps
(see Set
Functions for Subgroup Conjugacy Classes). Look in the index under
ConjugacyClassSubgroups to see for which groups this function is
overlaid.
7.77 IsConjugacyClassSubgroups
IsConjugacyClassSubgroups( obj )
IsConjugacyClassSubgroups
returns true
if obj is a conjugacy class
of subgroups as created by ConjugacyClassSubgroups
(see
ConjugacyClassSubgroups) and false
otherwise.
gap> s5 := Group( (1,2), (1,2,3,4,5) );; s5.name := "s5";;
gap> a5 := DerivedSubgroup( s5 );
Subgroup( s5, [ (1,2,3), (2,3,4), (2,4)(3,5) ] )
gap> c := ConjugacyClassSubgroups( s5, a5 );
ConjugacyClassSubgroups( s5, Subgroup( s5,
[ (1,2,3), (2,3,4), (2,4)(3,5) ] ) )
gap> IsConjugacyClassSubgroups( c );
true
gap> IsConjugacyClassSubgroups( [ a5 ] );
false # even though this is as a set equal to c
7.78 Set Functions for Subgroup Conjugacy Classes
As mentioned above, conjugacy classes of subgroups are domains, so all set theoretic functions are also are applicable to conjugacy classes (see Domains). This section describes the functions that are implemented especially for conjugacy classes. Functions not mentioned here inherit the default functions mentioned in the respective sections.
The elements of the conjugacy class C with representative U in the group G are computed by first finding a right transversal of the normalizer of U in G and by computing the conjugates of U with the elements in the right transversal.
Membership of a group V is tested by comparing the set of contained cyclic subgroups of prime power order of V with those of the groups in C.
The size of the conjugacy class C with representative U in the group G is computed as the index of the normalizer of U in G.
7.79 Subgroup Conjugacy Class Records
Each conjugacy class of subgroups C is represented as a record with at least the following components.
isDomain
:true
, because conjugacy classes of subgroups are
domains.
isConjugacyClassSubgroups
:true
.
group
:
representative
:The following components are optional and may be bound by some functions which compute or make use of their value.
normalizer
:C.representative
in C.group
.
normalizerLattice
:ConjugacyClassesSubgroups
. It
determines the normalizer of the subgroup C.representative
.
It is a list of length 2. The first element is another conjugacy
class D (in the same group), the second is an element g in
C.group
. The normalizer of C.representative
is then
D.representative ^ g
.
conjugands
:C.representative
in
C.group
. Thus the elements of the class C can be computed
by conjugating C.representative
with those elements.
7.80 ConjugacyClassesMaximalSubgroups
ConjugacyClassesMaximalSubgroups( G )
ConjugacyClassesMaximalSubgroups
returns a list of conjugacy classes of
maximal subgroups of the group G.
A subgroup H of G is maximal if H is a proper subgroup and for all subgroups I of G with H < I ≤ G the equality I = G holds.
gap> s4 := SymmetricGroup( AgWords, 4 );; gap> ss4 := SpecialAgGroup( s4 );; gap> ConjugacyClassesMaximalSubgroups( ss4 ); [ ConjugacyClassSubgroups( Group( g1, g2, g3, g4 ), Subgroup( Group( g1, g2, g3, g4 ), [ g2, g3, g4 ] ) ), ConjugacyClassSubgroups( Group( g1, g2, g3, g4 ), Subgroup( Group( g1, g2, g3, g4 ), [ g1, g3, g4 ] ) ), ConjugacyClassSubgroups( Group( g1, g2, g3, g4 ), Subgroup( Group( g1, g2, g3, g4 ), [ g1, g2 ] ) ) ]
The generic method computes the entire lattice of conjugacy classes of subgroups (see Lattice) and returns the maximal ones.
MaximalSubgroups
(see MaximalSubgroups) computes the list of all
maximal subgroups.
MaximalSubgroups( G )
MaximalSubgroups calculates all maximal subroups of the special ag group G.
gap> s4 := SymmetricGroup( AgWords, 4 );; gap> ss4 := SpecialAgGroup( s4 );; gap> MaximalSubgroups( ss4 ); [ Subgroup( Group( g1, g2, g3, g4 ), [ g2, g3, g4 ] ), Subgroup( Group( g1, g2, g3, g4 ), [ g1, g3, g4 ] ), Subgroup( Group( g1, g2, g3, g4 ), [ g1*g2^2, g3, g4 ] ), Subgroup( Group( g1, g2, g3, g4 ), [ g1*g2, g3, g4 ] ), Subgroup( Group( g1, g2, g3, g4 ), [ g1, g2 ] ), Subgroup( Group( g1, g2, g3, g4 ), [ g1, g2*g3*g4 ] ), Subgroup( Group( g1, g2, g3, g4 ), [ g1*g4, g2*g4 ] ), Subgroup( Group( g1, g2, g3, g4 ), [ g1*g4, g2*g3 ] ) ]
ConjugacyClassesMaximalSubgroups
(see
ConjugacyClassesMaximalSubgroups) computes the list of conjugacy
classes of maximal subgroups.
NormalSubgroups( G )
NormalSubgroups
returns a list of all normal subgroups of G. The
subgroups are sorted according to their sizes.
gap> s4 := Group( (1,2,3,4), (1,2) );; s4.name := "s4";; gap> NormalSubgroups( s4 ); [ Subgroup( s4, [ ] ), Subgroup( s4, [ (1,2)(3,4), (1,4)(2,3) ] ), Subgroup( s4, [ (2,3,4), (1,3,4) ] ), Subgroup( s4, [ (3,4), (1,4), (1,2,4) ] ) ]
The default function GroupOps.NormalSubgroups
uses the conjugacy
classes of G and normal closures in order to compute the normal
subgroups.
ConjugateSubgroups( G, U )
ConjugateSubgroups
returns the orbit of U under G acting by
conjugation (see ConjugateSubgroup) as list of subgroups. U and G
must have a common parent group.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> s3 := Subgroup( s4, [ (1,2,3), (1,2) ] ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2,3), (1,2) ] ) gap> ConjugateSubgroups( s4, s3 ); [ Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2,3), (1,2) ] ), Subgroup( Group( (1,2,3,4), (1,2) ), [ (2,3,4), (2,3) ] ), Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,3,4), (3,4) ] ), Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,2,4), (1,4) ] ) ]
The following sections describe how one can compute the right, left, and double cosets of subgroups (see RightCosets, LeftCosets, DoubleCosets). Further sections describe how cosets are created (see RightCoset, IsRightCoset, LeftCoset, IsLeftCoset, DoubleCoset, and IsDoubleCoset), and their implementation (see Set Functions for Right Cosets, Right Cosets Records, Set Functions for Double Cosets, and Double Coset Records).
A coset is a GAP3 domain, which is different from a group. Altough the
set of elements of a group and its trivial coset are equal, the group
functions do not take trivial cosets as arguments. A trivial coset must
be convert into a group using AsGroup
(see AsGroup) in order to be
used as group.
Cosets( G, U )
RightCosets( G, U )
Cosets
and RightCosets
return a list of the right cosets of the
subgroup U in the group G. The list is not sorted, i.e., the right
cosets may appear in any order. The right cosets are domains as
constructed by RightCoset
(see RightCoset).
gap> G := Group( (1,2), (1,2,3,4) );; gap> G.name := "G";; gap> U := Subgroup( G, [ (1,2), (3,4) ] );; gap> RightCosets( G, U ); [ (Subgroup( G, [ (1,2), (3,4) ] )*()), (Subgroup( G, [ (1,2), (3,4) ] )*(2,4,3)), (Subgroup( G, [ (1,2), (3,4) ] )*(2,3)), (Subgroup( G, [ (1,2), (3,4) ] )*(1,2,4,3)), (Subgroup( G, [ (1,2), (3,4) ] )*(1,2,3)), (Subgroup( G, [ (1,2), (3,4) ] )*(1,3)(2,4)) ]
If G is the parent of U, the dispatcher RightCosets
first checks
whether U has a component rightCosets
. If U has this component, it
returns that value. Otherwise it calls
G.operations.RightCosets(G,U)
, remembers the returned value in
U.rightCosets
and returns it. If G is not the parent of U,
RightCosets
directly calls the function
G.operations.RightCosets(G,U)
and returns that value.
The default function called this way is GroupOps.RightCosets
, which
calls Orbit( G, RightCoset( U ), OnRight )
. Look up RightCosets
in the index, to see for which groups this function is overlaid.
U * u
Coset( U, u )
RightCoset( U, u )
Coset( U )
RightCoset( U )
The first three forms return the right coset of the subgroup U with the representative u. u must lie in the parent group of U, otherwise an error is signalled. In the last two forms the right coset of U with the identity element of the parent of U as representative is returned. In each case the right coset is returned as a domain, so all domain functions are applicable to right cosets (see chapter Domains and Set Functions for Right Cosets).
gap> G := Group( (1,2), (1,2,3,4) );; gap> U := Subgroup( G, [ (1,2), (3,4) ] );; gap> U * (1,2,3); (Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2), (3,4) ] )*(1,2,3))
RightCosets
(see RightCosets) computes the set of all right cosets of
a subgroup in a group. LeftCoset
(see LeftCoset) constructs left
cosets.
RightCoset
calls U.operations.RightCoset( U, u )
and returns
that value.
The default function called this way is GroupOps.RightCoset
, which
creates a right coset record (see Right Cosets Records) with the
operations record RightCosetGroupOps
(see Set Functions for Right
Cosets). Look up the entries for RightCoset
in the index to see for
which groups this function is overlaid.
IsRightCoset( obj )
IsCoset( obj )
IsRightCoset
and IsCoset
return true
if the object obj is a right
coset, i.e., a record with the component isRightCoset
with value
true
, and false
otherwise. Will signal an error if obj is an
unbound variable.
gap> C := Subgroup( Group( (1,2), (1,2,3) ), [ (1,2,3) ] ) * (1,2);; gap> IsRightCoset( C ); true gap> D := (1,2) * Subgroup( Group( (1,2), (1,2,3) ), [ (1,2,3) ] );; gap> IsCoset( D ); false # note that D is a left coset record, gap> C = D; true # though as a set, it is of course also a right coset gap> IsCoset( 17 ); false
7.88 Set Functions for Right Cosets
Right cosets are domains, thus all set theoretic functions are applicable to cosets (see chapter Domains). The following describes the functions that are implemented especially for right cosets. Functions not mentioned here inherit the default function mentioned in the respective sections.
More technically speaking, all right cosets of generic groups have the
operations record RightCosetGroupOps
, which inherits its functions from
DomainOps
and overlays the components mentioned below with more
efficient functions.
In the following let C be the coset U * u
.
To compute the proper set of elements of a right coset C the proper set of elements of the subgroup U is computed, each element is multiplied by u, and the result is sorted.
This returns the result of applying IsFinite
to the subgroup U.
This returns the result of applying Size
to the subgroup U.
If C and D are both right cosets of the same subgroup, =
returns
true
if the quotient of the representatives lies in the subgroup U,
otherwise the test is delegated to DomainOps.=
.
h in U
If h is an element of the parent group of U, this returns true
if
the quotient h / u
lies in the subgroup U, otherwise the test is
delegated to DomainOps.in
.
If C and D are both right cosets of subgroups U and V with the
same parent group the result is a right coset of the intersection of U
and V. The representative is found by a random search for a common
element. In other cases the computation of the intersection is delegated
to DomainOps.Intersection
.
This takes a random element of the subgroup U and returns the product of this element by the representative u.
A right coset C is printed as (U * u)
(the parenthesis are used
to avoid confusion about the precedence, which could occur if the coset
is part of a larger object).
If v is an element of the parent group of the subgroup U, the result
is a new right coset of U with representative u * v
. Otherwise
the result is obtained by multiplying the proper set of elements of C
with the element v, which may signal an error.
v * C
The result is obtained by multiplying the proper set of elements of the coset C with the element v, which may signal an error.
A right coset is represented by a domain record with the following tag components.
isDomain
:true
.
isRightCoset
:true
.
The right coset is determined by the following identity components, which every right coset record has.
group
:
representative
:In addition, a right coset record may have the following optional information components.
elements
:
isFinite
:true
if the coset is finite, and false
if the coset is infinite. If not present it is not known whether
the coset is finite or infinite.
size
:
LeftCosets( G, U )
LeftCosets
returns a list of the left cosets of the subgroup U in the
group G. The list is not sorted, i.e., the left cosets may appear in
any order. The left cosets are domains as constructed by LeftCosets
(see LeftCosets).
gap> G := Group( (1,2), (1,2,3,4) );; gap> G.name := "G";; gap> U := Subgroup( G, [ (1,2), (3,4) ] );; gap> LeftCosets( G, U ); [ (()*Subgroup( G, [ (1,2), (3,4) ] )), ((2,3,4)*Subgroup( G, [ (1,2), (3,4) ] )), ((2,3)*Subgroup( G, [ (1,2), (3,4) ] )), ((1,3,4,2)*Subgroup( G, [ (1,2), (3,4) ] )), ((1,3,2)*Subgroup( G, [ (1,2), (3,4) ] )), ((1,3)(2,4)*Subgroup( G, [ (1,2), (3,4) ] )) ]
If G is the parent of U, the dispatcher LeftCosets
first checks
whether U has a component leftCosets
. If U has this component, it
returns that value. Otherwise LeftCosets
calls
G.operations.LeftCosets(G,U)
, remembers the returned value in
U.leftCosets
and returns it. If G is not the parent of U,
LeftCosets
calls G.operations.LeftCosets(G,U)
directly and
returns that value.
The default function called this way is GroupOps.LeftCosets
, which
calls RightCosets( G, U )
and turns each right coset U * u
into the left coset u^-1 * U
. Look up the entries for
LeftCosets
in the index, to see for which groups this function is
overlaid.
u * U
LeftCoset( U, u )
LeftCoset( U )
LeftCoset
is exactly like RightCoset
, except that it constructs left
cosets instead of right cosets. So everything that applies to
RightCoset
applies also to LeftCoset
, with right replaced by left
(see RightCoset, Set Functions for Right Cosets, Right Cosets
Records).
gap> G := Group( (1,2), (1,2,3,4) );; gap> U := Subgroup( G, [ (1,2), (3,4) ] );; gap> (1,2,3) * U; ((1,2,3)*Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2), (3,4) ] ))
LeftCosets
(see LeftCosets) computes the set of all left cosets of a
subgroup in a group.
IsLeftCoset( obj )
IsLeftCoset
returns true
if the object obj is a left coset, i.e., a
record with the component isLeftCoset
with value true
, and false
otherwise. Will signal an error if obj is an unbound variable.
gap> C := (1,2) * Subgroup( Group( (1,2), (1,2,3) ), [ (1,2,3) ] );; gap> IsLeftCoset( C ); true gap> D := Subgroup( Group( (1,2), (1,2,3) ), [ (1,2,3) ] ) * (1,2);; gap> IsLeftCoset( D ); false # note that D is a right coset record, gap> C = D; true # though as a set, it is of course also a left coset gap> IsLeftCoset( 17 ); false
IsRightCoset
(see IsRightCoset) tests if an object is a right coset.
DoubleCosets( G, U, V )
DoubleCosets
returns a list of the double cosets of the subgroups U and
V in the group G. The three groups G, U and V must have a common
parent. The list is not sorted, i.e., the double cosets may appear in
any order. The double cosets are domains as constructed by DoubleCoset
(see DoubleCoset).
gap> G := Group( (1,2), (1,2,3,4) );; gap> U := Subgroup( G, [ (1,2), (3,4) ] );; U.name := "U";; gap> DoubleCosets( G, U, U ); [ DoubleCoset( U, (), U ), DoubleCoset( U, (2,3), U ), DoubleCoset( U, (1,3)(2,4), U ) ]
DoubleCosets
calls G.operations.DoubleCoset( G, U, V )
and
returns that value.
The default function called this way is GroupOps.DoubleCosets
, which
takes random elements from G, tests if this element lies in one of the
already found double cosets, adds the double coset if this is not the
case, and continues this until the sum of the sizes of the found double
cosets equals the size of G. Look up DoubleCosets
in the index, to
see for which groups this function is overlaid.
DoubleCoset( U, u, V )
DoubleCoset
returns the double coset with representative u and left
group U and right group V. U and V must have a common parent and
u must lie in this parent, otherwise an error is signaled. Double
cosets are domains, so all domain function are applicable to double
cosets (see chapter Domains and Set Functions for Double Cosets).
gap> G := Group( (1,2), (1,2,3,4) );; gap> U := Subgroup( G, [ (1,2), (3,4) ] );; gap> D := DoubleCoset( U, (1,2,3), U ); DoubleCoset( Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2), (3,4) ] ), (1,2,3), Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2), (3,4) ] ) ) gap> Size( D ); 16
DoubleCosets
(see DoubleCosets) computes the set of all double cosets
of two subgroups in a group.
DoubleCoset
calls U.operations.DoubleCoset(U,u,V)
and returns
that value.
The default function called this way is GroupOps.DoubleCoset
, which
creates a double coset record (see Double Coset Records) with the
operations record DoubleCosetGroupOps
(see Set Functions for Double
Cosets). Look up DoubleCosets
in the index to see for which groups
this function is overlaid.
IsDoubleCoset( obj )
IsDoubleCoset
returns true
if the object obj is a double coset,
i.e., a record with the component isDoubleCoset
with value true
, and
false
otherwise. Will signal an error if obj is an unbound variable.
gap> G := Group( (1,2), (1,2,3,4) );; gap> U := Subgroup( G, [ (1,2), (3,4) ] );; gap> D := DoubleCoset( U, (1,2,3), U );; gap> IsDoubleCoset( D ); true
7.96 Set Functions for Double Cosets
Double cosets are domains, thus all set theoretic functions are applicable to double cosets (see chapter Domains). The following describes the functions that are implemented especially for double cosets. Functions not mentioned here inherit the default functions mentioned in the respective sections.
More technically speaking, double cosets of generic groups have the
operations record DoubleCosetGroupOps
, which inherits its functions
from DomainOps
and overlays the components mentioned below with more
efficient functions.
Most functions below use the component D.rightCosets
that contains a
list of right cosets of the left group U whose union is this double
coset. If this component is unbound they will compute it by computing
the orbit of the right group V on the right coset U * u
, where
u is the representative of the double coset (see Double Coset
Records).
To compute the proper set of elements the union of the right cosets
D.rightCosets
is computed.
This returns the result of IsFinite( U ) and IsFinite( V )
.
This returns the size of the left group U times the number of cosets in
D.rightCosets
.
If C and D are both double cosets with the same left and right groups
this returns the result of testing whether the representative of C lies
in D. In other cases the test is delegated to DomainOps.=
.
g in D
If g is an element of the parent group of the left and right group of
D, this returns true
if g lies in one of the right cosets in
D.rightCosets
. In other cases the the test is delegated to
DomainOps.in
.
If C and D are both double cosets that are equal, this returns C.
If C and D are both double cosets with the same left and right groups
that are not equal, this returns []
. In all other cases the
computation is delegated to DomainsOps.Intersection
.
This takes a random right coset from D.rightCosets
and returns the
result of applying Random
to this right coset.
This prints the double coset in the form DoubleCoset( U, u, V )
.
Those returns the result of multiplying the proper set of element of D with the element g, which may signal an error.
A double coset is represented by a domain record with the following tag components.
isDomain
:true
.
isDoubleCoset
:true
.
The double coset is determined by the following identity components, which every double coset must have.
leftGroup
:
rightGroup
:
representative
:In addition, a double coset record may have the following optional information components.
rightCosets
:
elements
:
isFinite
:true
if the double coset is finite and
false
if the double coset is infinite. If not present it is
not known whether the double coset is finite or infinite.
size
:The following functions construct new parent groups from given groups (see DirectProduct, SemidirectProduct, SubdirectProduct and WreathProduct).
DirectProduct( G1, ..., Gn )
DirectProduct
returns a group record of the direct product D of the
groups G1, ...., Gn which need not to have a common parent
group, it is even possible to construct the direct product of an ag group
with a permutation group.
Note that the elements of the direct product may be just represented as records. But more complicate constructions, as for instance installing a new collector, may be used. The choice of method strongly depends on the type of group arguments.
Embedding( U, D, i )
Let U be a subgroup of Gi . Embedding
returns a homomorphism of
U into D which describes the embedding of U in D.
Let U be a supergroup of Gi . Projection
returns a homomorphism
of D into U which describes the projection of D onto Gi .
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> S4 := AgGroup( s4 ); Group( g1, g2, g3, g4 ) gap> D := DirectProduct( s4, S4 ); Group( DirectProductElement( (1,2,3,4), IdAgWord ), DirectProductElement( (1,2), IdAgWord ), DirectProductElement( (), g1 ), DirectProductElement( (), g2 ), DirectProductElement( (), g3 ), DirectProductElement( (), g4 ) ) gap> pr := Projection( D, s4, 1 );; gap> Image( pr ); Group( (1,2,3,4), (1,2) )
7.100 DirectProduct for Groups
GroupOps.DirectProduct( L )
Let L be a list of groups G1, ..., Gn. Then a group element g of the direct product D is represented as record containing the following components.
element
:
domain
:GroupElements
.
isGroupElement
:true
.
isDirectProductElement
:true
.
operations
:DirectProductElementOps
(see Domain).
SemidirectProduct( G, a, H )
SemidirectProduct
returns the semidirect product of G with H. a
must be a homomorphism that from G onto a group A that operates on
H via the caret (^
) operator. A may either be a subgroup of the
parent group of H that normalizes H, or a subgroup of the
automorphism group of H, i.e., a group of automorphisms (see Group
Homomorphisms).
The semidirect product of G and H is a the group of pairs (g,h) with g ∈ G and h ∈ H, where the product of (g1,h1) (g2,h2) is defined as (g1 g2, h1g2a h2). Note that the elements (1G,h) form a normal subgroup in the semidirect product.
Embedding( U, S, 1 )
Let U be a subgroup of G. Embedding
returns the homomorphism of
U into the semidirect product S where u is mapped to (u,1)
.
Let U be a subgroup of H. Embedding
returns the homomorphism of
U into the semidirect product S where u is mapped to (1,u)
.
Projection
returns the homomorphism of S onto G, where (g,h)
is mapped to g.
Projection( S, H, 2 )
Projection
returns the homomorphism of S onto H, where (g,h)
is mapped to h.
It is not specified how the elements of the semidirect product are
represented. Thus Embedding
and Projection
are the only general
possibility to relate G and H with the semidirect product.
gap> s4 := Group( (1,2), (1,2,3,4) );; s4.name := "s4";; gap> s3 := Subgroup( s4, [ (1,2), (1,2,3) ] );; s3.name := "s3";; gap> a4 := Subgroup( s4, [ (1,2,3), (2,3,4) ] );; a4.name := "a4";; gap> a := IdentityMapping( s3 );; gap> s := SemidirectProduct( s3, a, a4 ); Group( SemidirectProductElement( (1,2), (1,2), () ), SemidirectProductElement( (1,2,3), (1,2,3), () ), SemidirectProductElement( (), (), (1,2,3) ), SemidirectProductElement( (), (), (2,3,4) ) ) gap> Size( s ); 72
Note that the three arguments of SemidirectProductElement
are the
element g, its image under a, and the element h.
SemidirectProduct
calls the function G.operations.SemidirectProduct
with the arguments G, a, and H, and returns the result.
The default function called this way is GroupOps.SemidirectProduct
.
This function constructs the semidirect product as a group of semidirect
product elements (see SemidirectProduct for Groups). Look in the index
under SemidirectProduct to see for which groups this function is
overlaid.
7.102 SemidirectProduct for Groups
The function GroupOps.SemidirectProduct
constructs the semidirect
product as a group of semidirect product elements. In the following let
G, a, and H be the arguments of SemidirectProduct
.
Each such element (g,h)
is represented by a record with the
following components.
element
:[ g, h ]
.
automorphism
:
isGroupElement
:true
.
isSemidirectProductElement
:true
.
domain
:GroupElements
.
operations
:SemidirectProductOps
.
The operations of semidirect product elements in done in the obvious way.
SubdirectProduct( G1, G2, h1, h2 )
SubdirectProduct
returns the subdirect product of the groups G1 and
G2. h1 and h2 must be homomorphisms from G1 and G2 into a
common group H.
The subdirect product of G1 and G2 is the subgroup of the direct product of G1 and G2 of those elements (g1,g2) with g1h1 = g2h2. This subgroup is generated by the elements (g1,xg1), where g1 loops over the generators of G1 and xg1 ∈ G2 is an arbitrary element such that g1h1 = xg1h2 together with the element (1G,k2) where k2 loops over the generators of the kernel of h2.
Projection
returns the projection of S onto G1, where (g1,g2)
is mapped to g1.
Projection( S, G2, 2 )
Projection
returns the projection of S onto G2, where (g1,g2)
is mapped to g2.
It is not specified how the elements of the subdirect product are
represented. Therefor Projection
is the only general possibility to
relate G1 and G2 with the subdirect product.
gap> s3 := Group( (1,2,3), (1,2) );; gap> c3 := Subgroup( s3, [ (1,2,3) ] );; gap> x1 := Operation( s3, Cosets( s3, c3 ), OnRight );; gap> h1 := OperationHomomorphism( s3, x1 );; gap> d8 := Group( (1,2,3,4), (2,4) );; gap> c4 := Subgroup( d8, [ (1,2,3,4) ] );; gap> x2 := Operation( d8, Cosets( d8, c4 ), OnRight );; gap> h2 := OperationHomomorphism( d8, x2 );; gap> s := SubdirectProduct( s3, d8, h1, h2 ); Group( (1,2,3), (1,2)(5,7), (4,5,6,7) ) gap> Size( s ); 24
SubdirectProduct
calls the function G1.operations.SubdirectProduct
with the arguments G1, G2, h1, and h2.
The default function called this way is GroupOps.SubdirectProduct
.
This function constructs the subdirect product as a subgroup of the
direct product. The generators for this subgroup are computed as
described above.
WreathProduct( G, H )
WreathProduct( G, H, α )
In the first form of WreathProduct
the right regular permutation
representation of H on its elements is used as the homomorphism
α. In the second form α must be a homomorphism of H
into a permutation group. Let d be the degree of the range of
α. Then WreathProduct
returns the wreath product of G by
H with respect to α, that is the semi-direct product of the
direct product of d copies of G which are permuted by H through
application of α to H.
gap> s3 := Group( (1,2,3), (1,2) ); Group( (1,2,3), (1,2) ) gap> z2 := CyclicGroup( AgWords, 2 ); Group( c2 ) gap> f := IdentityMapping( s3 ); IdentityMapping( Group( (1,2,3), (1,2) ) ) gap> w := WreathProduct( z2, s3, f ); Group( WreathProductElement( c2, IdAgWord, IdAgWord, (), () ), WreathProductElement( IdAgWord, c2, IdAgWord, (), () ), WreathProductElement( IdAgWord, IdAgWord, c2, (), () ), WreathProductElement( IdAgWord, IdAgWord, IdAgWord, (1,2,3), (1,2,3) ), WreathProductElement( IdAgWord, IdAgWord, IdAgWord, (1,2), (1,2) ) ) gap> Factors( Size( w ) ); [ 2, 2, 2, 2, 3 ]
7.105 WreathProduct for Groups
GroupOps.WreathProduct( G, H, α )
Let d be the degree of α.range
. A group element of the
wreath product W is represented as a record containing the following
components.
element
:
permutation
:
domain
:GroupElements
.
isGroupElement
:true
.
isWreathProductElement
:true
.
operations
:WreathProductElementOps
(see Domain).
Since groups is probably the most important category of domains in GAP3 group homomorphisms are probably the most important homomorphisms (see chapter Homomorphisms)
A group homomorphism φ is a mapping that maps each element of a group G, called the source of φ, to an element of another group H, called the range of φ, such that for each pair x, y ∈ G we have (xy)φ = xφ yφ.
Examples of group homomorphisms are the natural homomorphism of a group into a factor group (see NaturalHomomorphism) and the homomorphism of a group into a symmetric group defined by an operation (see OperationHomomorphism). Look under group homomorphisms in the index for a list of all available group homomorphisms.
Since group homomorphisms are just a special case of homomorphisms, all functions described in chapter Homomorphisms are applicable to all group homomorphisms, e.g., the function to test if a homomorphism is an automorphism (see IsAutomorphism). More general, since group homomorphisms are just a special case of mappings all functions described in chapter Mappings are also applicable, e.g., the function to compute the image of an element under a group homomorphism (see Image).
The following sections describe the functions that test whether a mapping is a group homomorphism (see IsGroupHomomorphism), compute the kernel of a group homomorphism (see KernelGroupHomomorphism), how the general mapping functions are implemented for group homomorphisms (see Mapping Functions for Group Homomorphisms), the natural homomorphism of a group onto a factor group (see NaturalHomomorphism), homomorphisms by conjugation (see ConjugationGroupHomomorphism, InnerAutomorphism), and the most general group homomorphism, which is defined by simply specifying the images of a set of generators (see GroupHomomorphismByImages).
IsGroupHomomorphism( map )
IsGroupHomomorphism
returns true
if the function map is a group
homomorphism and false
otherwise. Signals an error if map is a multi
value mapping.
A mapping map is a group homomorphism if its source G and range H are both groups and if for every pair of elements x, y ∈ G it holds that (x y)map = xmap ymap.
gap> s4 := Group( (1,2), (1,2,3,4) );; gap> v4 := Subgroup( s4, [ (1,2)(3,4), (1,3)(2,4) ] );; gap> phi := NaturalHomomorphism( s4, s4/v4 );; gap> IsGroupHomomorphism( phi ); true gap> IsHomomorphism( phi ); true # since the source is a group this is equivalent to the above gap> IsGroupHomomorphism( FrobeniusAutomorphism( GF(16) ) ); false # it is a field automorphism
IsGroupHomomorphism
first tests if the flag map.isGroupHomomorphism
is bound. If the flag is bound, IsGroupHomomorphism
returns its value.
Otherwise it calls
map.source.operations.IsGroupHomomorphism( map )
, remembers the
returned value in map.isGroupHomomorphism
, and returns it. Note that
of course all functions that create group homomorphisms set the flag
map.isGroupHomomorphism
to true
, so that no function is called for
those group homomorphisms.
The default function called this way is MappingOps.IsGroupHomomorphism
.
It computes all the elements of the source of map and for each such
element x and each generator y tests whether (xy)map = xmap
ymap. Look under IsHomomorphism in the index to see for which
mappings this function is overlaid.
KernelGroupHomomorphism( hom )
KernelGroupHomomorphism
returns the kernel of the group homomorphism
hom as a subgroup of the group hom.source
.
The kernel of a group homomorphism hom is the subset of elements x of the source G that are mapped to the identity of the range H, i.e., xhom = H.identity.
gap> s4 := Group( (1,2), (1,2,3,4) );; gap> v4 := Subgroup( s4, [ (1,2)(3,4), (1,3)(2,4) ] );; gap> phi := NaturalHomomorphism( s4, s4/v4 );; gap> KernelGroupHomomorphism( phi ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2)(3,4), (1,3)(2,4) ] ) gap> Kernel( phi ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (1,2)(3,4), (1,3)(2,4) ] ) # since the source is a group this is equivalent to the above gap> rho := GroupHomomorphismByImages( s4, Group( (1,2) ), > [ (1,2), (1,2,3,4) ], [ (1,2), (1,2) ] );; gap> Kernel( rho ); Subgroup( Group( (1,2), (1,2,3,4) ), [ (2,4,3), (1,4,3) ] )
KernelGroupHomomorphism
first tests if hom.kernelGroupHomomorphism
is bound. If it is bound, KernelGroupHomomorphisms
returns that value.
Otherwise it calls
hom.operations.KernelGroupHomomorphism( hom )
, remembers the
returned value in hom.kernelGroupHomomorphism
, and returns it.
The default function for this is MappingOps.KernelGroupHomomorphism
,
which simply tries random elements of the source of hom, until the
subgroup generated by those that map to the identity has the correct
size, i.e., Size( hom.source ) / Size( Image( hom ) )
. Note that
this implies that the image of hom and its size are computed. Look
under Kernel in the index to see for which group homomorphisms this
function is overlaid.
7.109 Mapping Functions for Group Homomorphisms
This section describes how the mapping functions defined in chapter Mappings are implemented for group homomorphisms. Those functions not mentioned here are implemented by the default functions described in the respective sections.
The group homomorphism hom is injective if the kernel of hom
KernelGroupHomomorphism( hom )
(see KernelGroupHomomorphism) is
trivial.
The group homomorphism hom is surjective if the size of the image
Size( Image( hom ) )
(see Image and below) is equal to the size of
the range Size( hom.range )
.
The two group homomorphisms hom1 and hom2 are equal if the have the same source and range and if the images of the generators of the source under hom1 and hom2 are equal.
By definition hom1 is smaller than hom2 if either the source of
hom1 is smaller than the source of hom2, or, if the sources are
equal, if the range of hom1 is smaller than the range of hom2, or, if
sources and ranges are equal, the image of the smallest element x of
the source for that the images are not equal under hom1 is smaller than
the image under hom2. Therefor GroupHomomorphismOps.<
first
compares the sources and the ranges. For group homomorphisms with equal
sources and ranges only the images of the smallest irredundant generating
system are compared. A generating system g1, g2, ..., gn is called
irredundant if no gi lies in the subgroup generated by g1, ...,
gi-1. The smallest irredundant generating system is simply the
smallest such generating system with respect to the lexicographical
ordering.
Image( hom )
Image( hom, H )
Images( hom, H )
The image of a subgroup under a group homomorphism is computed by computing the images of a set of generators of the subgroup, and the result is the subgroup generated by those images.
The preimages of an element under a group homomorphism are computed by
computing a representative with PreImagesRepresentative( hom, elm )
and the result is the coset of Kernel( hom )
containing this
representative.
PreImage( hom )
PreImage( hom, H )
PreImages( hom, H )
The preimages of a subgroup under a group homomorphism are computed by computing representatives of the preimages of all the generators of the subgroup, adding the generators of the kernel of hom, and the result is the subgroup generated by those elements.
Look under IsInjective, IsSurjective, equality, ordering, Image, Images, PreImage, and PreImages in the index to see for which group homomorphisms these functions are overlaid.
NaturalHomomorphism( G, F )
NaturalHomomorphism
returns the natural homomorphism of the group G
into the factor group F. F must be a factor group, i.e., the result
of FactorGroup(H,N)
(see FactorGroup) or H/N
(see
Operations for Groups), and G must be a subgroup of H.
Mathematically the factor group H/N consists of the cosets of N, and the natural homomorphism φ maps each element h of H to the coset N h. Note that in GAP3 the representation of factor group elements is unspecified, but they are never cosets (see IsRightCoset), because cosets are domains and not group elements in GAP3. Thus the natural homomorphism is the only connection between a group and one of its factorgroups.
G is the source of the natural homomorphism φ, F is its range. Note that because G may be a proper subgroup of the group H of which F is a factor group φ need not be surjective, i.e., the image of φ may be a proper subgroup of F. The kernel of φ is of course the intersection of N and G.
gap> s4 := Group( (1,2), (1,2,3,4) );; gap> v4 := Subgroup( s4, [ (1,2)(3,4), (1,3)(2,4) ] );; gap> v4.name := "v4";; gap> phi := NaturalHomomorphism( s4, s4/v4 );; gap> (1,2,3) ^ phi; FactorGroupElement( v4, (2,4,3) ) gap> PreImages( phi, last ); (v4*(2,4,3)) gap> (1,2,3) in last; true gap> rho := > NaturalHomomorphism( Subgroup( s4, [ (1,2), (1,2,3) ] ), s4/v4 );; gap> Kernel( rho ); Subgroup( Group( (1,2), (1,2,3,4) ), [ ] ) gap> IsIsomorphism( rho ); true
NaturalHomomorphism
calls
F.operations.NaturalHomomorphism( G, F )
and returns that value.
The default function called this way is GroupOps.NaturalHomomorphism
.
The homomorphism constructed this way has the operations record
NaturalHomomorphismOps
. It computes the image of an element g of G
by calling FactorGroupElement( N, g )
, the preimages of an factor
group element f as Coset( Kernel(phi), f.element.representative
)
, and the kernel by computing Intersection( G, N )
. Look under
NaturalHomomorphism in the index to see for which groups this function
is overlaid.
7.111 ConjugationGroupHomomorphism
ConjugationGroupHomomorphism( G, H, x )
ConjugationGroupHomomorphism
returns the homomorphism from G into H
that takes each element g in G to the element g ^ x
. G and
H must have a common parent group P and x must lie in this parent
group. Of course G ^ x
must be a subgroup of H.
gap> d12 := Group( (1,2,3,4,5,6), (2,6)(3,5) );; d12.name := "d12";; gap> c2 := Subgroup( d12, [ (2,6)(3,5) ] ); Subgroup( d12, [ (2,6)(3,5) ] ) gap> v4 := Subgroup( d12, [ (1,2)(3,6)(4,5), (1,4)(2,5)(3,6) ] ); Subgroup( d12, [ (1,2)(3,6)(4,5), (1,4)(2,5)(3,6) ] ) gap> x := ConjugationGroupHomomorphism( c2, v4, (1,3,5)(2,4,6) ); ConjugationGroupHomomorphism( Subgroup( d12, [ (2,6)(3,5) ] ), Subgroup( d12, [ (1,2)(3,6)(4,5), (1,4)(2,5)(3,6) ] ), (1,3,5)(2,4,6) ) gap> IsSurjective( x ); false gap> Image( x ); Subgroup( d12, [ (1,5)(2,4) ] )
ConjugationGroupHomomorphism
calls
G.operations.ConjugationGroupHomomorphism( G, H, x )
and returns that value.
The default function called is GroupOps.ConjugationGroupHomomorphism
.
It just creates a homomorphism record with range G, source H, and the
component element
with the value x. It computes the image of an
element g of G as g ^ x
. If the sizes of the range and the
source are equal the inverse of such a homomorphism is computed as a
conjugation homomorphism from H to G by x^-1
. To multiply two
such homomorphisms their elements are multiplied. Look under
ConjugationGroupHomomorphism in the index to see for which groups this
default function is overlaid.
InnerAutomorphism( G, g )
InnerAutomorphism
returns the automorphism on the group G that takes
each element h to h ^ g
. g must be an element in the parent
group of G (but need not actually be in G) that normalizes G.
gap> s5 := Group( (1,2), (1,2,3,4,5) );; s5.name := "s5";; gap> i := InnerAutomorphism( s5, (1,2) ); InnerAutomorphism( s5, (1,2) ) gap> (1,2,3,4,5) ^ i; (1,3,4,5,2)
InnerAutomorphism( G, g )
calls ConjugationGroupHomomorphism( G,
G, g )
(see ConjugationGroupHomomorphism).
7.113 GroupHomomorphismByImages
GroupHomomorphismByImages( G, H, gens, imgs )
GroupHomomorphismByImages
returns the group homomorphism with source
G and range H that is defined by mapping the list gens of
generators of G to the list imgs of images in H.
gap> g := Group( (1,2,3,4), (1,2) );; gap> h := Group( (2,3), (1,2) );; gap> m := GroupHomomorphismByImages(g,h,g.generators,h.generators); GroupHomomorphismByImages( Group( (1,2,3,4), (1,2) ), Group( (2,3), (1,2) ), [ (1,2,3,4), (1,2) ], [ (2,3), (1,2) ] ) gap> Image( m, (1,3,4) ); (1,3,2) gap> Kernel( m ); Subgroup( Group( (1,2,3,4), (1,2) ), [ (1,4)(2,3), (1,2)(3,4) ] )
Note that the result need not always be a single value mapping, even though the name seems to imply this. Namely if the elements in imgs do not satisfy all relations that hold for the generators gens, no element of G has a unique image under the mapping. This is demonstrated in the following example.
gap> g := Group( (1,2,3,4,5,6,7,8,9,10) );; gap> h := Group( (1,2,3,4,5,6) );; gap> m := GroupHomomorphismByImages(g,h,g.generators,h.generators); GroupHomomorphismByImages( Group( ( 1, 2, 3, 4, 5, 6, 7, 8, 9,10 ) ), Group( (1,2,3,4,5,6) ), [ ( 1, 2, 3, 4, 5, 6, 7, 8, 9,10) ], [ (1,2,3,4,5,6) ] ) gap> IsMapping( m ); false gap> Images( m, () ); (Subgroup( Group( (1,2,3,4,5,6) ), [ ( 1, 3, 5)( 2, 4, 6) ] )*()) gap> g.1^10; () # the generator of g satisfies this relation gap> h.1^10; (1,5,3)(2,6,4) # but its image does not
The set of images of the identity returned by Images
is the set of
elements h.1^n
such that g.1^n
is the identity in g
.
The test whether a mapping constructed by GroupHomomorphismByImages
is
a single valued mapping, is usually quite expensive. Note that this test
is automatically performed the first time that you apply a function that
expects a single valued mapping, e.g., Image
or Images
. There are
two possibilities to avoid this test. When you know that the mapping
constructed is really a single valued mapping, you can set the flag
map.isMapping
to true
. Then the functions assume that map is
indeed a mapping and do not test it again. On the other hand if you are
not certain whether the mapping is single valued, you can use
ImagesRepresentative
instead of Image
(see ImagesRepresentative).
ImagesRepresentative
returns just one possible image, without testing
whether there might actually be more than one possible image.
GroupHomomorphismByImages
calls
G.operations.GroupHomomorphismByImages( G, H, gens, imgs )
and returns this value.
The default function called this way is
GroupOps.GroupHomomorphismByImages
. Below we describe how the mapping
functions are implemented for such a mapping. The functions not
mentioned below are implemented by the default functions described in
Mapping Functions for Group Homomorphisms.
All the function below first compute the list of elements of G with an
orbit algorithm, sorts this list, and stores this list in
hom.elements
. In parallel they computes and sort a list of images,
and store this list in hom.images
.
The mapping constructed by GroupHomomorphismByImages
is a single valued
mapping if for each i and for each k the following equation holds
map.images[Position(map.elements,map.elements[i]*gens[k])]
.
= map.images[i] * imgs[k]
If the mapping map is a single valued mapping, the image of an element
elm is computed as map.images[ Position(map.elements,elm) ]
.
ImagesRepresentative( map, elm )
The representative of the images of an element elm under the mapping
map is computed as map.images[ Position(map.elements,elm) ]
.
The inverse of the mapping map is constructed as
GroupHomomorphismByImages( H, G, imgs, gens )
.
CompositionMapping( map1, map2 )
If map2 is a mapping constructed by GroupHomomorphismByImages
the
composition is constructed by making a copy of map2 and replacing every
element in map2.images
with its image under map1.
Look under GroupHomomorphismByImages in the index to see for which groups this function is overlaid.
7.114 Set Functions for Groups
As already mentioned in the introduction of the chapter, groups are
domains. Thus all set theoretic functions, for example Intersection
and Size
can be applied to groups. This and the following sections
give further comments on the definition and implementations of those
functions for groups. All set theoretic functions not mentioned here not
treated specially for groups. The last section describes the format of
the records that describe groups (see Group Records).
The elements of a group G are constructed using a Dimino algorithm. See Elements for Groups.
If G and H are groups then IsSubset
tests whether the generators of
H are elements of G. Otherwise DomainOps.IsSubset
is used.
The intersection of groups G and H is computed using an orbit algorithm. See Intersection for Groups.
GroupOps.Elements( G )
GroupOps.Elements
returns the sets of elements of G (see Elements).
The function starts with the trivial subgroup of G, for which the set
of elements is known and constructs the successive closures with the
generators of G using GroupOps.Closure
(see Closure).
Note that this function neither checks nor sets the record component
G.elements
. It recomputes the set of elements even it is bound to
G.elements
.
GroupOps.Intersection( G, H )
GroupOps.Intersection
returns the intersection of G and H either as
set of elements or as a group record (see Intersection).
If one argument, say G, is a set and the other a group, say H, then
GroupOps.Intersection
returns the subset of elements of G which lie
in H.
If G and H have different parent groups then GroupOps.Intersection
uses the function DomainOps.Intersection
in order to compute the
intersection.
Otherwise GroupOps.Intersection
computes the stabilizer of the trivial
coset of the bigger group in the smaller group using Stabilizer
and
Coset
.
The operator ^
evaluates to the subgroup conjugate to G under a
group element s of the parent group of G. See ConjugateSubgroup.
gap> s4 := Group( (1,2,3,4), (1,2) ); Group( (1,2,3,4), (1,2) ) gap> s4.name := "s4";; gap> v4 := Subgroup( s4, [ (1,2), (1,2)(3,4) ] ); Subgroup( s4, [ (1,2), (1,2)(3,4) ] ) gap> v4 ^ (2,3); Subgroup( s4, [ (1,3), (1,3)(2,4) ] ) gap> v4 ^ (2,5); Error, <g> must be an element of the parent group of <G>
The operator in
evaluates to true
if s is an element of G and
false
otherwise. s must be an element of the parent group of G.
gap> (1,2,3,4) in v4; false gap> (2,4) in v4^(2,3); true
The operator *
evaluates to the right coset of G with representative
s. s must be an element of the parent group of G. See
RightCoset for details about right cosets.
s * G
The operator *
evaluates to the left coset of G with representative
s. s must be an element of the parent group of G. See LeftCoset
for details about left cosets.
gap> v4 * (1,2,3,4); (Subgroup( s4, [ (1,2), (1,2)(3,4) ] )*(1,2,3)) gap> (1,2,3,4) * v4; ((1,2,3,4)*Subgroup( s4, [ (1,2), (1,2)(3,4) ] ))
The operator /
evaluates to the factor group <G> / N where N must
be a normal subgroup of G. This is the same as FactorGroup(G,N)
(see FactorGroup).
As for all domains (see Domains and Domain Records) groups and their
subgroups are represented by records that contain important information
about groups. Most of the following functions return such records. Of
course it is possible to create a group record by hand but generally
Group
(see Group) and Subgroup
(see Subgroup) should be used for
such tasks.
Once a group record is created you may add record components to it but
you must not alter informations already present, especially not
generators
and identity
.
Group records must always contain the components generators
,
identity
, isDomain
and isGroup
. Subgroups contain an additional
component parent
. The contents of all components of a group G are
described below.
The following two components are the so-called category components used to identify the category this domain belongs to.
isDomain
:true
as a group is a domain.
isGroup
:true
as G is a group.
The following three components determine a group domain. These are the so-called identification components.
generators
:generators
is the empty
list. Note that once created this entry must never be changed, as
most of the other entries depend on generators
.
identity
:
parent
:The following components are optional and contain knowledge about the group G.
abelianInvariants
:
centralizer
:
centre
:
commutatorFactorGroup
:
conjugacyClasses
:
core
:
derivedSubgroup
:
elements
:
fittingSubgroup
:
frattiniSubgroup
:
index
:
lowerCentralSeries
:
normalizer
:
normalClosure
:
upperCentralSeries
:
subnormalSeries
:
sylowSubgroups
:
size
:
perfectSubgroups
:
lattice
:
conjugacyClassesSubgroups
:G.lattice.classes
, contains the
conjugacy classes of subgroups of G. See
ConjugacyClassesSubgroups.
tableOfMarks
:
The following components are true
if the group G has the property,
false
if not, and are not present if it is unknown whether the group
has the property or not.
isAbelian
:true
if the group G is abelian. See IsAbelian.
isCentral
:true
if the group G is central in its parent
group. See IsCentral.
isCyclic
:true
if the group G is cyclic. See IsCyclic.
isElementaryAbelian
:true
if the group G is elementary abelian. See
IsElementaryAbelian.
isFinite
:true
if the group G is finite. If you know that a group
for which you want to use the generic low level group functions
is infinite, you should set this component to false
. This
will avoid attempts to compute the set of elements.
isNilpotent
:true
if the group G is nilpotent. See IsNilpotent.
isNormal
:true
if the group G is normal in its parent group. See
IsNormal.
isPerfect
:true
if the group G is perfect. See IsPerfect.
isSimple
:true
if the group G is simple. See IsSimple.
isSolvable
:true
if the group G is solvable. See IsSolvable.
isSubnormal
:true
if the group G is subnormal in its parent group. See
IsSubnormal.
The component operations
contains the operations record (see Domain
Records and Dispatchers).
gap3-jm