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 group s4
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 and a4 are subgroups of the parent group s4
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 and x3 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 and x3 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