When you start **GAP3** it already knows several groups. Currently **GAP3**
initially knows the following groups:

• some basic groups, such as cyclic groups or symmetric groups (see The Basic Groups Library),

• the primitive permutation groups of degree at most 50 (see The Primitive Groups Library),

• the transitive permutation groups of degree at most 15 (see The Transitive Groups Library),

• the solvable groups of size at most 100 (see The Solvable Groups Library),

• the 2-groups of size at most 256 (see The 2-Groups Library),

• the 3-groups of size at most 729 (see The 3-Groups Library),

• the irreducible solvable subgroups of *GL(n,p)* for *n > 1* and
*p ^{n} < 256* (see The Irreducible Solvable Linear Groups
Library),

• the finite perfect groups of size at most *10 ^{6}* (excluding 11
sizes) (see The Library of Finite Perfect Groups),

• the irreducible maximal finite integral matrix groups of dimension at most 24 (see Irreducible Maximal Finite Integral Matrix Groups),

• the crystallographic groups of dimension at most 4 (see The Crystallographic Groups Library).

• the groups of order at most 1000 except for 512 and 768 (see The Small Groups Library).

Each of the set of groups above is called a **library**. The whole set of
groups that **GAP3** knows initially is called the **GAP3** **collection of
group libraries**. There is usually no relation between the groups in the
different libraries.

Several of the libraries are accessed in a uniform manner. For each of
these libraries there is a so called **selection function** that allows you
to select the list of groups that satisfy given criterias from a library.
The **example function** allows you to select one group that satisfies
given criteria from the library. The low-level **extraction function**
allows you to extract a single group from a library, using a simple
indexing scheme. These functions are described in the sections Selection
Functions, Example Functions, and Extraction Functions.

Note that a system administrator may choose to install all, or only a few, or even none of the libraries. So some of the libraries mentioned below may not be available on your installation.

- The Basic Groups Library
- Selection Functions
- Example Functions
- Extraction Functions
- The Primitive Groups Library
- The Transitive Groups Library
- The Solvable Groups Library
- The 2-Groups Library
- The 3-Groups Library
- The Irreducible Solvable Linear Groups Library
- The Library of Finite Perfect Groups
- Irreducible Maximal Finite Integral Matrix Groups
- The Crystallographic Groups Library
- The Small Groups Library

`CyclicGroup( `

`n` )

`CyclicGroup( `

`D`, `n` )

In the first form `CyclicGroup`

returns the cyclic group of size `n` as a
permutation group. In the second form `D` must be a domain of group
elements, e.g., `Permutations`

or `AgWords`

, and `CyclicGroup`

returns
the cyclic group of size `n` as a group of elements of that type.

gap> c12 := CyclicGroup( 12 ); Group( ( 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12) ) gap> c105 := CyclicGroup( AgWords, 5*3*7 ); Group( c105_1, c105_2, c105_3 ) gap> Order(c105,c105.1); Order(c105,c105.2); Order(c105,c105.3); 105 35 7

`AbelianGroup( `

`sizes` )

`AbelianGroup( `

`D`, `sizes` )

In the first form `AbelianGroup`

returns the abelian group *C _{sizes[1]}
* C_{sizes[2]} * ... * C_{sizes[n]}*, where

`Permutations`

or `AgWords`

,
and `AbelianGroup`

returns the abelian group as a group of elements of
this type.

gap> g := AbelianGroup( AgWords, [ 2, 3, 7 ] ); Group( a, b, c ) gap> Size( g ); 42 gap> IsAbelian( g ); true

The default function `GroupElementsOps.AbelianGroup`

uses the functions
`CyclicGroup`

and `DirectProduct`

(see DirectProduct) to construct the
abelian group.

`ElementaryAbelianGroup( `

`n` )

`ElementaryAbelianGroup( `

`D`, `n` )

In the first form `ElementaryAbelianGroup`

returns the elementary abelian
group of size `n` as a permutation group. `n` must be a positive prime
power of course. In the second form `D` must be a domain of group
elements, e.g., `Permutations`

or `AgWords`

, and `ElementaryAbelianGroup`

returns the elementary abelian group as a group of elements of this type.

gap> ElementaryAbelianGroup( 16 ); Group( (1,2), (3,4), (5,6), (7,8) ) gap> ElementaryAbelianGroup( AgWords, 3 ^ 10 ); Group( m59049_1, m59049_2, m59049_3, m59049_4, m59049_5, m59049_6, m59049_7, m59049_8, m59049_9, m59049_10 )

The default function `GroupElementsOps.ElementaryAbelianGroup`

uses
`CyclicGroup`

and `DirectProduct`

(see DirectProduct to construct the
elementary abelian group.

`DihedralGroup( `

`n` )

`DihedralGroup( `

`D`, `n` )

In the first form `DihedralGroup`

returns the dihedral group of size `n`
as a permutation group. `n` must be a positive even integer. In the
second form `D` must be a domain of group elements, e.g., `Permutations`

or `AgWords`

, and `DihedralGroup`

returns the dihedral group as a group
of elements of this type.

gap> DihedralGroup( 12 ); Group( (1,2,3,4,5,6), (2,6)(3,5) )

`PolyhedralGroup( `

`p`, `q` )

`PolyhedralGroup( `

`D`, `p`, `q` )

In the first form `PolyhedralGroup`

returns the polyhedral group of size

as a permutation group. `p` * `q``p` and `q` must be positive
integers and there must exist a nontrivial `p`-th root of unity modulo
every prime factor of `q`. In the second form `D` must be a domain of
group elements, e.g., `Permutations`

or `Words`

, and `PolyhedralGroup`

returns the polyhedral group as a group of elements of this type.

gap> PolyhedralGroup( 3, 13 ); Group( ( 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13), ( 2, 4,10)( 3, 7, 6) ( 5,13,11)( 8, 9,12) ) gap> Size( last ); 39

`SymmetricGroup( `

`d` )

`SymmetricGroup( `

`D`, `d` )

In the first form `SymmetricGroup`

returns the symmetric group of degree
`d` as a permutation group. `d` must be a positive integer. In the
second form `D` must be a domain of group elements, e.g., `Permutations`

or `Words`

, and `SymmetricGroup`

returns the symmetric group as a group
of elements of this type.

gap> SymmetricGroup( 8 ); Group( (1,8), (2,8), (3,8), (4,8), (5,8), (6,8), (7,8) ) gap> Size( last ); 40320

`AlternatingGroup( `

`d` )

`AlternatingGroup( `

`D`, `d` )

In the first form `AlternatingGroup`

returns the alternating group of
degree `d` as a permutation group. `d` must be a positive integer. In
the second form `D` must be a domain of group elements, e.g.,
`Permutations`

or `Words`

, and `AlternatingGroup`

returns the alternating
group as a group of elements of this type.

gap> AlternatingGroup( 8 ); Group( (1,2,8), (2,3,8), (3,4,8), (4,5,8), (5,6,8), (6,7,8) ) gap> Size( last ); 20160

`GeneralLinearGroup( `

`n`, `q` )

`GeneralLinearGroup( `

`D`, `n`, `q` )

In the first form `GeneralLinearGroup`

returns the general linear group
*GL( n, q )* as a matrix group. In the second form

`Permutations`

or `AgWords`

, and
`GeneralLinearGroup`

returns

gap> g := GeneralLinearGroup( 2, 4 ); Size( g ); GL(2,4) 180

`SpecialLinearGroup( `

`n`, `q` )

`SpecialLinearGroup( `

`D`, `n`, `q` )

In the first form `SpecialLinearGroup`

returns the special linear group
*SL( n, q )* as a matrix group. In the second form

`Permutations`

or `AgWords`

, and
`SpecialLinearGroup`

returns

gap> g := SpecialLinearGroup( 3, 4 ); Size( g ); SL(3,4) 60480

`SymplecticGroup( `

`n`, `q` )

`SymplecticGroup( `

`D`, `n`, `q` )

In the first form `SymplecticGroup`

returns the symplectic group *SP(
n, q )* as a matrix group. In the second form

`Permutations`

or `AgWords`

, and
`SymplecticGroup`

returns

gap> g := SymplecticGroup( 4, 2 ); Size( g ); SP(4,2) 720

`GeneralUnitaryGroup( `

`n`, `q` )

`GeneralUnitaryGroup( `

`D`, `n`, `q` )

In the first form `GeneralUnitaryGroup`

returns the general unitary group
*GU( n, q )* as a matrix group. In the second form

`Permutations`

or `AgWords`

, and
`GeneralUnitaryGroup`

returns

gap> g := GeneralUnitaryGroup( 3, 3 ); Size( g ); GU(3,3) 24192

`SpecialUnitaryGroup( `

`n`, `q` )

`SpecialUnitaryGroup( `

`D`, `n`, `q` )

In the first form `SpecialUnitaryGroup`

returns the special unitary group
*SU( n, q )* as a matrix group. In the second form

`Permutations`

or `AgWords`

, and
`SpecialUnitaryGroup`

returns

gap> g := SpecialUnitaryGroup( 3, 3 ); Size( g ); SU(3,3) 6048

`MathieuGroup`

returns the Mathieu group of degree `d` as a permutation
group. `d` is expected to be 11, 12, 22, 23, or 24.

gap> g := MathieuGroup( 12 ); Size( g ); Group( ( 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11), ( 3, 7,11, 8) ( 4,10, 5, 6), ( 1,12)( 2,11)( 3, 6)( 4, 8)( 5, 9)( 7,10) ) 95040

`All`

`Library`Groups( `fun1`, `val1`, `fun2`, `val2`, ... )

For each group library there is a **selection function**. This function
allows you to select all groups from the library that have a given set of
properties.

The name of the selection functions always begins with `All`

and always
ends with `Groups`

. Inbetween is a name that hints at the nature of the
group library. For example, the selection function for the library of all
primitive groups of degree at most 50 (see The Primitive Groups
Library) is called `AllPrimitiveGroups`

, and the selection function for
the library of all 2-groups of size at most 256 (see The 2-Groups
Library) is called `AllTwoGroups`

.

These functions take an arbitrary number of pairs of arguments. The first argument in such a pair is a function that can be applied to the groups in the library, and the second argument is either a single value that this function must return in order to have this group included in the selection, or a list of such values.

For example

AllPrimitiveGroups( DegreeOperation, [10..15], Size, [1..100], IsAbelian, false );

should return a list of all primitive groups with degree between 10 and 15 and size less than 100 that are not abelian.

Thus the `AllPrimitiveGroups`

behaves as if it was implemented by a
function similar to the one defined below, where `PrimitiveGroupsList`

is
a list of all primitive groups. Note, in the definition below we assume
for simplicity that `AllPrimitiveGroups`

accepts exactly 4 arguments. It
is of course obvious how to change this definition so that the function
would accept a variable number of arguments.

AllPrimitiveGroups := function ( fun1, val1, fun2, val2 ) local groups, g, i; groups := []; for i in [ 1 .. Length( PrimitiveGroupsList ) ] do g := PrimitiveGroupsList[i]; if fun1(g) = val1 or IsList(val1) and fun1(g) in val1 and fun2(g) = val2 or IsList(val2) and fun2(g) in val2 then Add( groups, g ); fi; od; return groups; end;

Note that the real selection functions are considerably more difficult, to improve the efficiency. Most important, each recognizes a certain set of functions and handles those properties using an index (see About Group Libraries).

`One`

`Library`Group( `fun1`, `val1`, `fun2`, `val2`, ... )

For each group library there is a **example function**. This function
allows you to find one group from the library that has a given set of
properties.

The name of the example functions always begins with `One`

and always
ends with `Group`

. Inbetween is a name that hints at the nature of the
group library. For example, the example function for the library of all
primitive groups of degree at most 50 (see The Primitive Groups
Library) is called `OnePrimitiveGroup`

, and the example function for the
library of all 2-groups of size at most 256 (see The 2-Groups Library)
is called `OneTwoGroup`

.

These functions take an arbitrary number of pairs of arguments. The first argument in such a pair is a function that can be applied to the groups in the library, and the second argument is either a single value that this function must return in order to have this group returned by the example function, or a list of such values.

For example

OnePrimitiveGroup( DegreeOperation, [10..15], Size, [1..100], IsAbelian, false );

should return one primitive group with degree between 10 and 15 and size size less than 100 that is not abelian.

Thus the `OnePrimitiveGroup`

behaves as if it was implemented by a
function similar to the one defined below, where `PrimitiveGroupsList`

is
a list of all primitive groups. Note, in the definition below we assume
for simplicity that `OnePrimitiveGroup`

accepts exactly 4 arguments. It
is of course obvious how to change this definition so that the function
would accept a variable number of arguments.

OnePrimitiveGroup := function ( fun1, val1, fun2, val2 ) local g, i; for i in [ 1 .. Length( PrimitiveGroupsList ) ] do g := PrimitiveGroupsList[i]; if fun1(g) = val1 or IsList(val1) and fun1(g) in val1 and fun2(g) = val2 or IsList(val2) and fun2(g) in val2 then return g; fi; od; return false; end;

Note that the real example functions are considerably more difficult, to improve the efficiency. Most important, each recognizes a certain set of functions and handles those properties using an index (see About Group Libraries).

For each group library there is an **extraction function**. This function
allows you to extract single groups from the library.

The name of the extraction function always ends with `Group`

and begins
with a name that hints at the nature of the library. For example the
extraction function for the library of primitive groups (see The
Primitive Groups Library) is called `PrimitiveGroup`

, and the extraction
function for the library of all 2-groups of size at most 256 (see The
2-Groups Library) is called `TwoGroup`

.

What arguments the extraction function accepts, and how they are interpreted is described in the sections that describe the individual group libraries.

For example

` PrimitiveGroup( 10, 4 ); `

returns the 4-th primitive group of degree 10.

The reason for the extraction function is as follows. A group library is usually not stored as a list of groups. Instead a more compact representation for the groups is used. For example the groups in the library of 2-groups are represented by 4 integers. The extraction function hides this representation from you, and allows you to access the group library as if it was a table of groups (two dimensional in the above example).

This group library contains all primitive permutation groups of degree at most 50. There are a total of 406 such groups. Actually to be a little bit more precise, there are 406 inequivalent primitive operations on at most 50 points. Quite a few of the 406 groups are isomorphic.

`AllPrimitiveGroups( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`AllPrimitiveGroups`

returns a list containing all primitive groups that
have the properties given as arguments. Each property is specified by
passing a pair of arguments, the first being a function, which will be
applied to all groups in the library, and the second being a value or a
list of values, that this function must return in order to have this
group included in the list returned by `AllPrimitiveGroups`

.

The first argument must be `DegreeOperation`

and the second argument
either a degree or a list of degrees, otherwise `AllPrimitiveGroups`

will
print a warning to the effect that the library contains only groups with
degrees between 1 and 50.

gap> l := AllPrimitiveGroups( Size, 120, IsSimple, false ); #W AllPrimitiveGroups: degree automatically restricted to [1..50] [ S(5), PGL(2,5), S(5) ] gap> List( l, g -> g.generators ); [ [ (1,2,3,4,5), (1,2) ], [ (1,2,3,4,5), (2,3,5,4), (1,6)(3,4) ], [ ( 1, 8)( 2, 5, 6, 3)( 4, 9, 7,10), ( 1, 5, 7)( 2, 9, 4)( 3, 8,10) ] ]

`OnePrimitiveGroup( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`OnePrimitiveGroup`

returns one primitive group that has the properties
given as argument. Each property is specified by passing a pair of
arguments, the first being a function, which will be applied to all
groups in the library, and the second being a value or a list of values,
that this function must return in order to have this group returned by
`OnePrimitiveGroup`

. If no such group exists, `false`

is returned.

The first argument must be `DegreeOperation`

and the second argument
either a degree or a list of degrees, otherwise `OnePrimitiveGroup`

will
print a warning to the effect that the library contains only groups with
degrees between 1 and 50.

gap> g := OnePrimitiveGroup( DegreeOperation,5, IsSolvable,false ); A(5) gap> Size( g ); 60

`AllPrimitiveGroups`

and `OnePrimitiveGroup`

recognize the following
functions and handle them usually quite efficient. `DegreeOperation`

,
`Size`

, `Transitivity`

, and `IsSimple`

. You should pass those functions
first, e.g., it is more efficient to say ```
AllPrimitiveGroups( Size,120 ,
IsAbelian,false )
```

than to say ```
AllPrimitiveGroups( IsAbelian,false,
Size,120 )
```

(see About Group Libraries).

`PrimitiveGroup`

returns the `nr`-th primitive group of degree `deg`.
Both `deg` and `nr` must be positive integers. The primitive groups of
equal degree are sorted with respect to their size, so for example
`PrimitiveGroup( `

is the smallest primitive group of degree
`deg`, 1 )`deg`, e.g, the cyclic group of size `deg`, if `deg` is a prime.
Primitive groups of equal degree and size are in no particular order.

gap> g := PrimitiveGroup( 8, 1 ); AGL(1,8) gap> g.generators; [ (1,2,3,4,5,6,7), (1,8)(2,4)(3,7)(5,6) ]

Apart from the usual components described in Group Records, the group records returned by the above functions have the following components.

`transitivity`

:-

degree of transitivity of`G`.

`isSharpTransitive`

:-

`true`

if`G`is sharply

-fold transitive and`G`.transitivity`false`

otherwise.

`isKPrimitive`

:-

`true`

if`G`is`k`-fold primitive, and`false`

otherwise.

`isOdd`

:-

`false`

if`G`is a subgroup of the alternating group of degree

and`G`.degree`true`

otherwise.

`isFrobeniusGroup`

:-

`true`

if`G`is a Frobenius group and`false`

otherwise.

This library was computed by Charles Sims. The list of primitive
permutation groups of degree at most 20 was published in Sim70.
The library was brought into **GAP3** format by Martin
Schönert. He assumes the responsibility for all mistakes.

The transitive groups library contains representatives for all transitive permutation groups of degree at most 22. Two permutations groups of the same degree are considered to be equivalent, if there is a renumbering of points, which maps one group into the other one. In other words, if they lie in the save conjugacy class under operation of the full symmetric group by conjugation.

There are a total of 4945 such groups up to degree 22.

`AllTransitiveGroups( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`AllTransitiveGroups`

returns a list containing all transitive groups
that have the properties given as arguments. Each property is specified
by passing a pair of arguments, the first being a function, and the
second being a value or a list of values. `AllTransitiveGroups`

will
return all groups from the transitive groups library, for which all
specified functions have the specified values.

If the degree is not restricted to 22 at most, `AllTransitiveGroups`

will
print a warning.

`OneTransitiveGroup( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`OneTransitiveGroup`

returns one transitive group that has the properties
given as argument. Each property is specified by passing a pair of
arguments, the first being a function, and the second being a value or a
list of values. `OneTransitiveGroup`

will return one groups from the
transitive groups library, for which all specified functions have the
specified values. If no such group exists, `false`

is returned.

If the degree is not restricted to 22 at most, `OneTransitiveGroup`

will
print a warning.

`AllTransitiveGroups`

and `OneTransitiveGroup`

recognize the following
functions and get the corresponding properties from a precomputed list to
speed up processing:

`DegreeOperation`

, `Size`

, `Transitivity`

, and
`IsPrimitive`

. You do not need to pass those functions first, as the
selection function picks the these properties first.

`TransitiveGroup( `

`deg`, `nr` )

`TransitiveGroup`

returns the `nr`-th transitive group of degree `deg`.
Both `deg` and `nr` must be positive integers. The transitive groups of
equal degree are sorted with respect to their size, so for example
`TransitiveGroup( `

is the smallest transitive group of degree
`deg`, 1 )`deg`, e.g, the cyclic group of size `deg`, if `deg` is a prime. The
ordering of the groups corresponds to the list in Butler/McKay
BM83.

This library was computed by Gregory Butler, John McKay, Gordon Royle and Alexander Hulpke. The list of transitive groups up to degree 11 was published in BM83, the list of degree 12 was published in Roy87, degree 14 and 15 were published in But93.

The library was brought into **GAP3** format by Alexander Hulpke, who is
responsible for all mistakes.

gap> TransitiveGroup(10,22); S(5)[x]2 gap> l:=AllTransitiveGroups(DegreeOperation,12,Size,1440, > IsSolvable,false); [ S(6)[x]2, M_10.2(12) = A_6.E_4(12) = [S_6[1/720]{M_10}S_6]2 ] gap> List(l,IsSolvable); [ false, false ]

`TransitiveIdentification( `

`G` )

Let `G` be a permutation group, acting transitively on a set of up to 22
points. Then `TransitiveIdentification`

will return the position of this
group in the transitive groups library. This means, if `G` operates on
*m* points and `TransitiveIdentification`

returns *n*, then `G` is
permutation isomorphic to the group `TransitiveGroup(m,n)`

.

gap> TransitiveIdentification(Group((1,2),(1,2,3))); 2

**GAP3** has a library of the 1045 solvable groups of size between 2 and
100. The groups are from lists computed by M. Hall and J. K. Senior
(size 64, see HS64), R. Laue (size 96, see Lau82) and
J. Neubüser (other sizes, see Neu67).

`AllSolvableGroups( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`AllSolvableGroups`

returns a list containing all solvable groups that
have the properties given as arguments. Each property is specified by
passing a pair of arguments, the first being a function, which will be
applied to all the groups in the library, and the second being a value or
a list of values, that this function must return in order to have this
group included in the list returned by `AllSolvableGroups`

.

gap> AllSolvableGroups(Size,24,IsNontrivialDirectProduct,false); [ 12.2, grp_24_11, D24, Q8+S3, Sl(2,3), S4 ]

`OneSolvableGroup( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`OneSolvableGroup`

returns a solvable group with the specified
properties. Each property is specified by passing a pair of arguments,
the first being a function, which will be applied to all the groups in
the library, and the second being a value or a list of values, that this
function must return in order to have this group returned by
`OneSolvableGroup`

. If no such group exists, `false`

is returned.

gap> OneSolvableGroup(Size,100,x->Size(DerivedSubgroup(x)),10); false gap> OneSolvableGroup(Size,24,IsNilpotent,false); S3x2^2

`AllSolvableGroups`

and `OneSolvableGroup`

recognize the following
functions and handle them usually very efficiently: `Size`

, `IsAbelian`

,
`IsNilpotent`

, and `IsNonTrivialDirectProduct`

.

`SolvableGroup`

returns the `nr`-th group of size `size` in the library.
`SolvableGroup`

will signal an error if `size` is not between 2 and 100,
or if `nr` is larger than the number of solvable groups of size `size`.
The group is returned as finite polycyclic group (see Finite Polycyclic
Groups).

gap> SolvableGroup( 32 , 15 ); Q8x4

The library of 2-groups contains all the 2-groups of size dividing 256. There are a total of 58760 such groups, 1 of size 2, 2 of size 4, 5 of size 8, 14 of size 16, 51 of size 32, 267 of size 64, 2328 of size 128, and 56092 of size 256.

`AllTwoGroups( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`AllTwoGroups`

returns the list of all the 2-groups that have the
properties given as arguments. Each property is specified by passing a
pair of arguments, the first is a function that can be applied to each
group, the second is either a single value or a list of values that the
function must return in order to select that group.

gap> l := AllTwoGroups( Size, 256, Rank, 3, pClass, 2 ); [ Group( a1, a2, a3, a4, a5, a6, a7, a8 ), Group( a1, a2, a3, a4, a5, a6, a7, a8 ), Group( a1, a2, a3, a4, a5, a6, a7, a8 ), Group( a1, a2, a3, a4, a5, a6, a7, a8 ) ] gap> List( l, g -> Length( ConjugacyClasses( g ) ) ); [ 112, 88, 88, 88 ]

`OneTwoGroup( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`OneTwoGroup`

returns a single 2-group that has the properties given as
arguments. Each property is specified by passing a pair of arguments,
the first is a function that can be applied to each group, the second is
either a single value or a list of values that the function must return
in order to select that group.

gap> g := OneTwoGroup( Size, [64..128], Rank, [2..3], pClass, 5 ); #I size restricted to [ 64, 128 ] Group( a1, a2, a3, a4, a5, a6 ) gap> Size( g ); 64 gap> Rank( g ); 2

`AllTwoGroups`

and `OneTwoGroup`

recognize the following functions and
handle them usually very efficiently. `Size`

, `Rank`

for the rank of the
Frattini quotient of the group, and `pClass`

for the exponent-*p* class
of the group. Note that `Rank`

and `pClass`

are dummy functions that
can be used only in this context, i.e., they can not be applied to
arbitrary groups.

`TwoGroup`

returns the `nr`-th group of size `size`. The group is
returned as a finite polycyclic group (see Finite Polycyclic Groups).
`TwoGroup`

will signal an error if `size` is not a power of 2 between 2
and 256, or `nr` is larger than the number of groups of size `size`.

Within each size the following criteria have been used, in turn, to determine the index position of a group in the list

- 1:
- increasing generator number;

- 2:
- increasing exponent-2 class;

- 3:
- the position of its parent in the list of groups of appropriate size;

- 4:
- the list in which the Newman and O'Brien implementation of the
*p*-group generation algorithm outputs the immediate descendants of a group.

gap> g := TwoGroup( 32, 45 ); Group( a1, a2, a3, a4, a5 ) gap> Rank( g ); 4 gap> pClass( g ); 2 gap> g.abstractRelators; [ a1^2*a5^-1, a2^2, a2^-1*a1^-1*a2*a1, a3^2, a3^-1*a1^-1*a3*a1, a3^-1*a2^-1*a3*a2, a4^2, a4^-1*a1^-1*a4*a1, a4^-1*a2^-1*a4*a2, a4^-1*a3^-1*a4*a3, a5^2, a5^-1*a1^-1*a5*a1, a5^-1*a2^-1*a5*a2, a5^-1*a3^-1*a5*a3, a5^-1*a4^-1*a5*a4 ]

Apart from the usual components described in Group Records, the group records returned by the above functions have the following components.

`rank`

:

rank of Frattini quotient of`G`.

`pclass`

:-

exponent-*p*class of`G`.

`abstractGenerators`

:-

a list of abstract generators of`G`(see AbstractGenerator).

`abstractRelators`

:-

a list of relators of`G`stored as words in the abstract generators.

Descriptions of the algorithms used in constructing the library data may be found in OBr90,OBr91. Using these techniques, a library was first prepared in 1987 by M.F. Newman and E.A. O'Brien; a partial description may be found in NO89.

The library was brought into the **GAP3** format by Werner Nickel, Alice
Niemeyer, and E.A. O'Brien.

The library of 3-groups contains all the 3-groups of size dividing 729. There are a total of 594 such groups, 1 of size 3, 2 of size 9, 5 of size 27, 15 of size 81, 67 of size 243, and 504 of size 729.

`AllThreeGroups( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`AllThreeGroups`

returns the list of all the 3-groups that have the
properties given as arguments. Each property is specified by passing a
pair of arguments, the first is a function that can be applied to each
group, the second is either a single value or a list of values that the
function must return in order to select that group.

gap> l := AllThreeGroups( Size, 243, Rank, [2..4], pClass, 3 );; gap> Length ( l ); 33 gap> List( l, g -> Length( ConjugacyClasses( g ) ) ); [ 35, 35, 35, 35, 35, 35, 35, 243, 99, 99, 51, 51, 51, 51, 51, 51, 51, 51, 99, 35, 243, 99, 99, 51, 51, 51, 51, 51, 35, 35, 35, 35, 35 ]

`OneThreeGroup( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`OneThreeGroup`

returns a single 3-group that has the properties given as
arguments. Each property is specified by passing a pair of arguments,
the first is a function that can be applied to each group, the second is
either a single value or a list of values that the function must return
in order to select that group.

gap> g := OneThreeGroup( Size, 729, Rank, 4, pClass, [3..5] ); Group( a1, a2, a3, a4, a5, a6 ) gap> IsAbelian( g ); true

`AllThreeGroups`

and `OneThreeGroup`

recognize the following functions
and handle them usually very efficiently. `Size`

, `Rank`

for the rank of
the Frattini quotient of the group, and `pClass`

for the exponent-*p*
class of the group. Note that `Rank`

and `pClass`

are dummy functions
that can be used only in this context, i.e., they cannot be applied to
arbitrary groups.

`ThreeGroup`

returns the `nr`-th group of size `size`. The group is
returned as a finite polycyclic group (see Finite Polycyclic Groups).
`ThreeGroup`

will signal an error if `size` is not a power of 3 between
3 and 729, or `nr` is larger than the number of groups of size `size`.

Within each size the following criteria have been used, in turn, to determine the index position of a group in the list

- 1:
- increasing generator number;

- 2:
- increasing exponent-3 class;

- 3:
- the position of its parent in the list of groups of appropriate size;

- 4:
- the list in which the Newman and O'Brien implementation of the
*p*-group generation algorithm outputs the immediate descendants of a group.

gap> g := ThreeGroup( 243, 56 ); Group( a1, a2, a3, a4, a5 ) gap> pClass( g ); 3 gap> g.abstractRelators; [ a1^3, a2^3, a2^-1*a1^-1*a2*a1*a4^-1, a3^3, a3^-1*a1^-1*a3*a1, a3^-1*a2^-1*a3*a2*a5^-1, a4^3, a4^-1*a1^-1*a4*a1*a5^-1, a4^-1*a2^-1*a4*a2, a4^-1*a3^-1*a4*a3, a5^3, a5^-1*a1^-1*a5*a1, a5^-1*a2^-1*a5*a2, a5^-1*a3^-1*a5*a3, a5^-1*a4^-1*a5*a4 ]

Apart from the usual components described in Group Records, the group records returned by the above functions have the following components.

`rank`

:

rank of Frattini quotient of`G`.

`pclass`

:-

exponent-*p*class of`G`.

`abstractGenerators`

:-

a list of abstract generators of`G`(see AbstractGenerator).

`abstractRelators`

:-

a list of relators of`G`stored as words in the abstract generators.

Descriptions of the algorithms used in constructing the library data may be found in OBr90,OBr91.

The library was generated and brought into **GAP3** format by E.A. O'Brien
and Colin Rhodes. David Baldwin, M.F. Newman, and Maris Ozols have
contributed in various ways to this project and to correctly determining
these groups. The library design is modelled on and borrows extensively
from the 2-groups library, which was brought into **GAP3** format by
Werner Nickel, Alice Niemeyer, and E.A. O'Brien.

The **IrredSol** group library provides access to the irreducible solvable
subgroups of *GL(n,p)*, where *n > 1*, *p* is prime and *p ^{n} < 256*.
The library contains exactly one member from each of the 370 conjugacy
classes of such subgroups.

By well known theory, this library also doubles as a library of primitive
solvable permutation groups of non-prime degree less than 256. To access
the data in this form, you must first build the matrix group(s) of
interest and then call the function

`PrimitivePermGroupIrreducibleMatGroup( `

`matgrp` )

This function returns a permutation group isomorphic to the semidirect
product of an irreducible matrix group (over a finite field) and its
underlying vector space.

`AllIrreducibleSolvableGroups( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`AllIrreducibleSolvableGroups`

returns a list containing all irreducible
solvable linear groups that have the properties given as arguments. Each
property is specified by passing a pair of arguments, the first being a
function which will be applied to all groups in the library, and the
second being a value or a list of values that this function must return
in order to have this group included in the list returned by
`AllIrreducibleSolvableGroups`

.

gap> AllIrreducibleSolvableGroups( Dimension, 2, > CharFFE, 3, > Size, 8 ); [ Group( [ [ 0*Z(3), Z(3)^0 ], [ Z(3)^0, 0*Z(3) ] ], [ [ Z(3), 0*Z(3) ], [ 0*Z(3), Z(3)^0 ] ], [ [ Z(3)^0, 0*Z(3) ], [ 0*Z(3), Z(3) ] ] ), Group( [ [ 0*Z(3), Z(3)^0 ], [ Z(3), 0*Z(3) ] ], [ [ Z(3)^0, Z(3) ], [ Z(3), Z(3) ] ] ), Group( [ [ 0*Z(3), Z(3)^0 ], [ Z(3)^0, Z(3) ] ] ) ]

`OneIrreducibleSolvableGroup( `

`fun1`, `val1`, `fun2`, `val2`, ... )

`OneIrreducibleSolvableGroup`

returns one irreducible solvable linear
group that has the properties given as arguments. Each property is
specified by passing a pair of arguments, the first being a function
which will be applied to all groups in the library, and the second being
a value or a list of values that this function must return in order to
have this group returned by `OneIrreducibleSolvableGroup`

. If no such
group exists, `false`

is returned.

gap> OneIrreducibleSolvableGroup( Dimension, 4, > IsLinearlyPrimitive, false ); Group( [ [ 0*Z(2), 0*Z(2), Z(2)^0, 0*Z(2) ], [ 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ], [ Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2) ], [ 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ] ], [ [ 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ], [ Z(2)^0, Z(2)^0, 0*Z(2), 0*Z(2) ], [ 0*Z(2), 0*Z(2), Z(2)^0, 0*Z(2) ], [ 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ] ], [ [ Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2) ], [ 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ], [ 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ], [ 0*Z(2), 0*Z(2), Z(2)^0, Z(2)^0 ] ] )

`AllIrreducibleSolvableGroups`

and `OneIrreducibleSolvableGroup`

recognize the following functions and handle them very efficiently
(because the information is stored with the groups and so no computations
are needed): `Dimension`

for the linear degree, `CharFFE`

for the field
characteristic, `Size`

, `IsLinearlyPrimitive`

, and
`MinimalBlockDimension`

. Note that the last two are dummy functions that
can be used only in this context. Their meaning is explained at the end
of this section.

`IrreducibleSolvableGroup( `

`n`, `p`, `i` )

`IrreducibleSolvableGroup`

returns the `i`-th irreducible solvable
subgroup of *GL*( `n`, `p` ). The irreducible solvable subgroups of

*GL(n,p)*are ordered with respect to the following criteria:-
• increasing size;

• increasing guardian number. If two groups have the same size and guardian, they are in no particular order. (See the library documentation or [Sho92] for the meaning of guardian.)

gap> g := IrreducibleSolvableGroup( 3, 5, 12 ); Group( [ [ 0*Z(5), Z(5)^2, 0*Z(5) ], [ Z(5)^2, 0*Z(5), 0*Z(5) ], [ 0*Z(5), 0*Z(5), Z(5)^2 ] ], [ [ 0*Z(5), Z(5)^0, 0*Z(5) ], [ 0*Z(5), 0*Z(5), Z(5)^0 ], [ Z(5)^0, 0*Z(5), 0*Z(5) ] ], [ [ Z(5)^2, 0*Z(5), 0*Z(5) ], [ 0*Z(5), Z(5)^0, 0*Z(5) ], [ 0*Z(5), 0*Z(5), Z(5)^2 ] ], [ [ Z(5)^0, 0*Z(5), 0*Z(5) ], [ 0*Z(5), Z(5)^2, 0*Z(5) ], [ 0*Z(5), 0*Z(5), Z(5)^2 ] ], [ [ Z(5), 0*Z(5), 0*Z(5) ], [ 0*Z(5), Z(5), 0*Z(5) ], [ 0*Z(5), 0*Z(5), Z(5) ] ] )

`size`

:-

size of`G`.

`isLinearlyPrimitive`

:-

`false`

if`G`preserves a direct sum decomposition of the underlying vector space, and`true`

otherwise.

`minimalBlockDimension`

:-

not bound if`G`is linearly primitive; otherwise equals the dimension of the blocks in an unrefinable system of imprimitivity for`G`.

This library was computed and brought into **GAP3** format by Mark Short.
Descriptions of the algorithms used in computing the library data can be
found in Sho92.

The **GAP3** library of finite perfect groups provides, up to isomorphism,
a list of all perfect groups whose sizes are less than *10 ^{6}* excluding
the following:

• For *n = 61440*, 122880, 172032, 245760, 344064, 491520, 688128, or
983040, the perfect groups of size *n* have not completely been
determined yet. The library neither provides the number of these
groups nor the groups themselves. \vspace-1mm

• For *n = 86016*, 368640, or 737280, the library does not yet
contain the perfect groups of size *n*, it only provides their
their numbers which are 52, 46, or 54, respectively. \vspace-2mm

Except for these eleven sizes, the list of altogether 1096 perfect groups
in the library is complete. It relies on results of Derek F. Holt and
Wilhelm Plesken which are published in their book * Perfect Groups*
HP89. Moreover, they have supplied to us files with presentations
of 488 of the groups. In terms of these, the remaining 607 nontrivial
groups in the library can be described as 276 direct products, 107
central products, and 224 subdirect products. They are computed
automatically by suitable **GAP3** functions whenever they are needed.

We are grateful to Derek Holt and Wilhelm Plesken for making their groups
available to the **GAP3** community by contributing their files. It should
be noted that their book contains a lot of further information for many
of the library groups. So we would like to recommend it to any **GAP3**
user who is interested in the groups.

The library has been brought into **GAP3** format by Volkmar Felsch.

Like most of the other **GAP3** libraries, the library of finite perfect
groups provides an extraction function, `PerfectGroup`

. It returns the
specified group in form of a finitely presented group which, in its group
record, bears some additional information that allows you to easily
construct an isomorphic permutation group of some appropriate degree by
just calling the `PermGroup`

function.

Further, there is a function `NumberPerfectGroups`

which returns the
number of perfect groups of a given size.

The library does not provide a selection or an example function. There
is, however, a function `DisplayInformationPerfectGroups`

which allows
the display of some information about arbitrary library groups without
actually loading the large files with their presentations, and without
constructing the groups themselves.

Moereover, there are two functions which allow you to formulate loops
over selected library groups. The first one is the
`NumberPerfectLibraryGroups`

function which, for any given size, returns
the number of groups in the library which are of that size.

The second one is the `SizeNumbersPerfectGroups`

function. It allows you
to ask for all library groups which contain certain composition factors.
The answer is provided in form of a list of pairs [*size*,*n*] where each
such pair characterizes the *n ^{ th}* library group of size

`PerfectGroup`

and the `DisplayInformationPerfectGroups`

function, you
may use their list to formulate a loop over the associated groups.
Now we shall give an individual description of each library function.

`NumberPerfectGroups`

returns the number of non-isomorphic perfect groups
of size *size* for each positive integer *size* up to *10 ^{6}* except for
the eight sizes listed at the beginning of this section for which the
number is not yet known. For these values as well as for any argument out
of range it returns the value

`NumberPerfectLibraryGroups( `

`size` )

`NumberPerfectLibraryGroups`

returns the number of perfect groups of size
*size* which are available in the library of finite perfect groups.

The purpose of the function is to provide a simple way to formulate a loop over all library groups of a given size.

`SizeNumbersPerfectGroups( `

`factor1`, `factor2` ... )

`SizeNumbersPerfectGroups`

returns a list of the * size numbers* (see
above) of all library groups that contain the specified factors among
their composition factors. Each argument must either be the name of a
simple group or an integer expression which is the product of the sizes
of one or more cyclic factors. The function ignores the order in which
the argmuments are given and, in fact, replaces any list of more than one
integer expression among the arguments by their product.

The following text strings are accepted as simple group names.

•[] `"A5"`

, `"A6"`

, `"A7"`

, `"A8"`

, `"A9"`

or `"A(5)"`

, `"A(6)"`

,
`"A(7)"`

, `"A(8)"`

, `"A(9)"`

for the alternating groups *A _{n}*,

•[] `"L2(`

*q*`)"`

or `"L(2,`

*q*`)"`

for *PSL(2,q)*, where *q* is any
prime power with *4 ≤ q ≤ 125*, \vspace-2mm

•[] `"L3(`

*q*`)"`

or `"L(3,`

*q*`)"`

for *PSL(3,q)* with *2 ≤ q
≤ 5*, \vspace-2mm

•[] `"U3(`

*q*`)"`

or `"U(3,`

*q*`)"`

for *PSU(2,q)* with *3 ≤ q
≤ 5*, \vspace-2mm

•[] `"U4(2)`

or `"U(4,2)"`

for *PSU(4,2)*, \vspace-2mm

•[] `"Sp4(4)"`

or `"S(4,4)"`

for the symplectic group *S(4,4)*,

•[] `"Sz(8)"`

for the Suzuki group *Sz(8)*, \vspace-2mm

•[] `"M11"`

, `"M12"`

, `"M22"`

or `"M(11)"`

, `"M(12)"`

, `"M(22)"`

for
the Matthieu groups *M _{11}*,

•[] `"J1"`

, `"J2"`

or `"J(1)"`

, `"J(2)"`

for the Janko groups *J _{1}*
and

Note that, for most of the groups, the preceding list offers two
different names in order to be consistent with the notation used in
HP89 as well as with the notation used in the
`DisplayCompositionSeries`

command of **GAP3**. However, as the names are
compared as text strings, you are restricted to the above choice. Even
expressions like `"L2(`

`32`

`)"`

or `"L2(2^5)"`

are not accepted.

As the use of the term *PSU(n,q)* is not unique in the literature, we
state that here it denotes the factor group of *SU(n,q)* by its centre,
where *SU(n,q)* is the group of all *n × n* unitary matrices with
entries in *GF(q ^{2})* and determinant 1.

The purpose of the function is to provide a simple way to formulate a loop over all library groups which contain certain composition factors.

`DisplayInformationPerfectGroups( `

`size` )

`DisplayInformationPerfectGroups( `

`size`, `n` )

`DisplayInformationPerfectGroups( [ `

`size`, `n` ] )

`DisplayInformationPerfectGroups`

displays some information about the
library group *G*, say, which is specified by the size number
[`size`,`n`] or by the two arguments *size* and *n*. If, in the second
case, `n` is omitted, the function will loop over all library groups of
size `size`.

The information provided for *G* includes the following items:

• a headline containing the size number *[size,n]* of *G* in the form
*size.n* (the suffix *.n* will be suppressed if, up to isomorphism,
*G* is the only perfect group of size *size*), \vspace-2mm

• a message if *G* is simple or quasisimple, i.e., if the factor
group of *G* by its centre is simple, \vspace-2mm

• the ``description'' of the structure of *G* as it is given by
Holt and Plesken in HP89 (see below), \vspace-2mm

• the size of the centre of *G* (suppressed, if *G* is simple),

• the prime decomposition of the size of *G*, \vspace-2mm

• orbit sizes for a faithful permutation representation of *G* which
is provided by the library (see below), \vspace-2mm

• a reference to each occurrence of *G* in the tables of section 5.3
of HP89. Each of these references consists of a class number
and an internal number *(i,j)* under which *G* is listed in that
class. For some groups, there is more than one reference because
these groups belong to more than one of the classes in the book.

Example:

gap> DisplayInformationPerfectGroups( 30720, 3 ); #I Perfect group 30720.3: A5 ( 2^4 E N 2^1 E 2^4 ) A #I centre = 1 size = 2^11*3*5 orbit size = 240 #I Holt-Plesken class 1 (9,3) gap> DisplayInformationPerfectGroups( 30720, 6 ); #I Perfect group 30720.6: A5 ( 2^4 x 2^4 ) C N 2^1 #I centre = 2 size = 2^11*3*5 orbit size = 384 #I Holt-Plesken class 1 (9,6) gap> DisplayInformationPerfectGroups( Factorial( 8 ) / 2 ); #I Perfect group 20160.1: A5 x L3(2) 2^1 #I centre = 2 size = 2^6*3^2*5*7 orbit sizes = 5 + 16 #I Holt-Plesken class 31 (1,1) (occurs also in class 32) #I Perfect group 20160.2: A5 2^1 x L3(2) #I centre = 2 size = 2^6*3^2*5*7 orbit sizes = 7 + 24 #I Holt-Plesken class 31 (1,2) (occurs also in class 32) #I Perfect group 20160.3: ( A5 x L3(2) ) 2^1 #I centre = 2 size = 2^6*3^2*5*7 orbit size = 192 #I Holt-Plesken class 31 (1,3) #I Perfect group 20160.4: simple group A8 #I size = 2^6*3^2*5*7 orbit size = 8 #I Holt-Plesken class 26 (0,1) #I Perfect group 20160.5: simple group L3(4) #I size = 2^6*3^2*5*7 orbit size = 21 #I Holt-Plesken class 27 (0,1)

For any library group *G*, the library files do not only provide a
presentation, but, in addition, a list of one or more subgroups *S _{1},
..., S_{r}* of

`PermGroup`

function described below. The `DisplayInformationPerfectGroups`

function
displays only the available degree. The message
` orbit size = 8 `

in the above example means that the available permutation representation is transitive and of degree 8, whereas the message

` orbit sizes = 7 + 24 `

means that a nontransitive permutation representation is available which acts on two orbits of size 7 and 24 respectively.

The notation used in the ``description'' of a group is explained in section 5.1.2 of HP89. We quote the respective page from there:

* `Within a class Q#p, an isomorphism type of groups will be
denoted by an ordered pair of integers (r,n), where r ≥ 0 and n >
0. More precisely, the isomorphism types in Q # p of order p^{r}
\!\! | \!\! Q \!\! | will be denoted by (r,1), (r,2), (r,3),
.... Thus Q will always get the size number (0,1).
*

*
In addition to the symbol (r,n), the groups in Q # p
will also be given a more descriptive name. The purpose of this is to
provide a very rough idea of the structure of the group. The names are
derived in the following manner. First of all, the isomorphism classes of
irreducible F_{p}Q-modules M with | \!\! Q \!\! | | \!\! M
\!\! | ≤ 10^{6}, where F_{p} is the field of order p, are
assigned symbols. These will either be simply p^{x}, where x is the
dimension of the module, or, if there is more than one isomorphism class
of irreducible modules having the same dimension, they will be denoted by
p^{x}, p^{x'}, etc. The one-dimensional module with trivial
Q-action will therefore be denoted by p^{1}. These symbols will be
listed under the description of Q. The group name consists essentially
of a list of the composition factors working from the top of the group
downwards; hence it always starts with the name of Q itself. (This
convention is the most convenient in our context, but it is different
from that adopted in the ATLAS (Conway {\it et al*. 1985), for example,
where composition factors are listed in the reverse order. For example,
we denote a group isomorphic to

Some other symbols are used in the name, in order to give some idea of the relationship between these composition factors, and splitting properties. We shall now list these additional symbols.

•[*×*] between two factors denotes a direct product of
*F _{p}Q*-modules or groups. \vspace-2mm

•[C] (for `commutator') between two factors means that the second
lies in the commutator subgroup of the first. Similarly, a segment
of the form *(f _{1} \! × \! f_{2}) C f_{3}* would mean that
the factors

•[A] (for `abelian') between two factors indicates that the second
is in the *p*th power (but not the commutator subgroup) of the
first. `A' may also follow the factors, if bracketed.

•[E] (for `elementary abelian') between two factors indicates that
together they generate an elementary abelian group (modulo
subsequent factors), but that the resulting *F _{p}Q*-module extension
does not split. \vspace-2mm

•[N] (for `nonsplit') before a factor indicates that *Q* (or
possibly its covering group) splits down as far at this factor but
not over the factor itself. So `*Q f _{1} N f_{2}*' means that
the normal subgroup

- Brackets have their obvious meaning. Summarizing, we have:

•[*×*] = dirext product; \vspace-2mm

•[C] = commutator subgroup; \vspace-2mm

•[A] = abelian; \vspace-2mm

•[E] = elementary abelian; and \vspace-2mm

•[N] = nonsplit. \vspace-2mm Here are some examples.

•[(i)] *A _{5} (2^{4} E 2^{1} E 2^{4}) A* means that the
pairs

•[(ii)] *A _{5} (2^{4} E 2^{1} A) C 2^{1}* means that

•[(iii)] *L _{3}(2) ((2^{1} E) \! × \! ( N 2^{3} E
2^{3'} A) C) 2^{3'}* means that the

We must stress that this notation does not always succeed in being precise or even unambiguous, and the reader is free to ignore it if it does not seem helpful.' }

If such a group description has been given in the book for *G* (and, in
fact, this is the case for most of the library groups), it is displayed
by the `DisplayInformationPerfectGroups`

function. Otherwise the function
provides a less explicit description of the (in these cases unique)
Holt-Plesken class to which *G* belongs, together with a serial number if
this is necessary to make it unique.

`PerfectGroup( `

`size` )

`PerfectGroup( `

`size`, `n` )

`PerfectGroup( [ `

`size`, `n` ] )

`PerfectGroup`

is the essential extraction function of the library. It
returns a finitely presented group, *G* say, which is isomorphic to the
library group specified by the size number [`size`,`n`] or by the two
separate arguments *size* and *n*. In the second case, you may omit the
parameter `n`. Then the default value is *n = 1*.

gap> G := PerfectGroup( 6048 ); PerfectGroup(6048) gap> G.generators; [ a, b ] gap> G.relators; [ a^2, b^6, a*b*a*b*a*b*a*b*a*b*a*b*a*b, a*b^2*a*b^2*a*b^2*a*b^-2*a*b^-2*a*b^-2, a*b*a*b^-2*a*b*a*b^-2*a*b*a*b^-2*a*b*a*b^-1*a*b^-1 ] gap> G.size; 6048 gap> G.description; "U3(3)" gap> G.subgroups; [ Subgroup( PerfectGroup(6048), [ a, b*a*b*a*b*a*b^3 ] ) ]

The generators and relators of `G` coincide with those given in
HP89.

Note that, besides the components that are usually initialized for any
finitely presented group, the group record of `G` contains the following
components:

`size`

:-

the size of`G`,

`isPerfect`

:-

always`true`

,

`description`

:-

the description of`G`as described with the`DisplayInformationPerfectGroups`

function above,

`source`

:-

some internal information used by the library functions,

`subgroups`

:-

a list of subgroups*S*of_{1}, ..., S_{r}`G`such that`G`acts faithfully on on the union of the sets of all cosets of the*S*._{i}

The last of these components exists only if `G` is one of the 488
nontrivial library groups which are given directly by a presentation on
file, i.e., which are not constructed from other library groups in form
of a direct, central, or subdirect product. It will be required by the
following function.

`PermGroup`

returns a permutation group, *P* say, which is isomorphic to
the given group `G` which is assumed to be a finitely presented perfect
group that has been extracted from the library of finite perfect groups
via the `PerfectGroup`

function.

Let *S _{1}, ..., S_{r}* be the subgroups listed in the component

`G`.subgroups

of the group record of Example (continued):

gap> P := PermGroup( G ); PermGroup(PerfectGroup(6048)) gap> P.size; 6048 gap> P.degree; 28

Note that some of the library groups do not have a faithful permutation representation of small degree. Computations in these groups may be rather time consuming.

Example:

gap> P := PermGroup( PerfectGroup( 129024, 2 ) ); PermGroup(PerfectGroup(129024,2)) gap> P.degree; 14336

A library of irreducible maximal finite integral matrix groups is
provided with **GAP3**. It contains *ℚ*-class representatives for all of
these groups of dimension at most 24, and *ℤ*-class representatives for
those of dimension at most 11 or of dimension 13, 17, 19, or 23.

The groups provided in this library have been determined by Wilhelm
Plesken, partially as joint work with Michael Pohst, or by members of his
institute (Lehrstuhl B für Mathematik, RWTH Aachen). In
particular, the data for the groups of dimensions 2 to 9 have been taken
from the output of computer calculations which they performed in 1979
(see PP77, PP80). The *ℤ*-class representatives of the
groups of dimension 10 have been determined and computed by Bernd
Souvignier (Sou94), and those of dimensions 11, 13, and 17 have
been recomputed for this library from the circulant Gram matrices given
in Ple85, using the stand-alone programs for the computation of
short vectors and Bravais groups which have been developed in Plesken's
institute. The *ℤ*-class representatives of the groups of dimensions 19
and 23 had already been determined in Ple85. Gabriele Nebe has
recomputed them for us. Her main contribution to this library, however,
is that she has determined and computed the *ℚ*-class representatives of
the groups of non-prime dimensions between 12 and 24 (see PN95,
NP95, Neb95).

The library has been brought into **GAP3** format by Volkmar Felsch. He has
applied several **GAP3** routines to check certain consistency of the data.
However, the credit and responsibility for the lists remain with the
authors. We are grateful to Wilhelm Plesken, Gabriele Nebe, and Bernd
Souvignier for supplying their results to **GAP3**.

In the preceding acknowledgement, we used some notations that will also be needed in the sequel. We first define these.

Any integral matrix group *G* of dimension *n* is a subgroup of
*GL _{n}(ℤ)* as well as of

In the context of this library we are only concerned with *ℤ*-classes
and *ℚ*-classes of subgroups of *GL _{n}(ℤ)* which are irreducible and
maximal finite in

First, there are those i.m.f. subgroups of *GL _{n}(ℤ)* which are also
maximal finite subgroups of

Secondly, there is the set *Q _{2}(n)* of the

As an example, let us consider the case *n = 4*. There are 6 *ℤ*-classes
of i.m.f. subgroups of *GL _{4}(ℤ)* with representative subgroups

*
The q_{1}(n) ℚ-classes of i.m.f. subgroups of GL_{n}(ℚ) have
been determined for each dimension n ≤ 24. The current GAP3
library provides integral representative groups for all these classes.
Moreover, all ℤ-classes of i.m.f. subgroups of GL_{n}(ℤ) are
known for n ≤ 11 and for n ∈ {13,17,19,23}. For these
dimensions, the library offers integral representative groups for all
ℚ-classes in Q_{1}(n) and Q_{2}(n) as well as for all ℤ-classes
of i.m.f. subgroups of GL_{n}(ℤ).
*

*
Any group G of dimension n given in the library is represented as the
automorphism group G = Aut(F,L) = { g ∈ GL_{n}(ℤ) | Lg = L
and g F g^{ tr} = F } of a positive definite symmetric n
× n matrix F ∈ ℤ^{n × n} on an n-dimensional lattice L
≅ ℤ^{1 × n} (for details see e.g. PN95). GAP3
provides for G a list of matrix generators and the Gram matrix
F.
*

*
The positive definite quadratic form defined by F defines a norm
v F v^{ tr} for each vector v ∈ L, and there is only a finite
set of vectors of minimal norm. These vectors are often simply called
the ``short vectors''. Their set splits into orbits under G,
and G being irreducible acts faithfully on each of these orbits by
multiplication from the right. GAP3 provides for each of these orbits
the orbit size and a representative vector.
*

*
Like most of the other GAP3 libraries, the library of
i.m.f. integral matrix groups supplies an extraction function,
ImfMatGroup. However, as the library involves only 423 different
groups, there is no need for a selection or an example function. Instead,
there are two functions, ImfInvariants and DisplayImfInvariants,
which provide some ℤ-class invariants that can be extracted from the
library without actually constructing the representative groups
themselves. The difference between these two functions is that the latter
one displays the resulting data in some easily readable format, whereas
the first one returns them as record components so that you can properly
access them.
*

*
We shall give an individual description of each of the library functions,
but first we would like to insert a short remark concerning their names:
Any self-explaining name of a function handling irreducible
maximal finite integral matrix groups would have to include this term in
full length and hence would grow extremely long. Therefore we have
decided to use the abbreviation Imf instead in order to restrict the
names to some reasonable length.
*

*
The first three functions can be used to formulate loops over the
classes.
*

*
*

*
ImfNumberQQClasses( dim )
ImfNumberQClasses( dim )
ImfNumberZClasses( dim, q )
*

*
ImfNumberQQClasses returns the number q_{1}(dim) of ℚ-classes
of i.m.f. rational matrix groups of dimension dim. Valid values
of dim are all positive integers up to 24.
*

*
Note: In order to enable you to loop just over the classes belonging to
Q_{1}(dim), we have arranged the list of ℚ-classes of dimension
dim for any dimension dim in the library such that, whenever the
classes of Q_{2}(dim) are known, too, i.e., in the cases dim ≤
11 or dim ∈ {13,17,19,23}, the classes of Q_{1}(dim) precede
those of Q_{2}(dim) and hence are numbered from 1 to q_{1}(dim).
*

*
ImfNumberQClasses returns the number of ℚ-classes of groups of
dimension dim which are available in the library. If dim ≤ 11 or
dim ∈ {13,17,19,23}, this is the number q_{1}(dim) +
q_{2}(dim) of ℚ-classes of i.m.f. subgroups of
GL_{dim}(ℤ). Otherwise, it is just the number q_{1}(dim) of
ℚ-classes of i.m.f. subgroups of GL_{dim}(ℚ). Valid values of
dim are all positive integers up to 24.
*

*
ImfNumberZClasses returns the number of ℤ-classes in the q^{
th} ℚ-class of i.m.f. integral matrix groups of dimension
dim. Valid values of dim are all positive integers up to 11 and all
primes up to 23.
*

*
*

*
DisplayImfInvariants( dim, q )
DisplayImfInvariants( dim, q, z )
*

*
DisplayImfInvariants displays the following ℤ-class invariants of
the groups in the z^{ th} ℤ-class in the q^{ th}
ℚ-class of i.m.f. integral matrix groups of dimension dim:
*

*• its ℤ-class number in the form dim.q.z, if dim is at
most 11 or a prime, or its ℚ-class number in the form dim.q,
else, \vspace-2mm
*

*• a message if the group is solvable, \vspace-2mm
*

*• the size of the group, \vspace-2mm
*

*• the isomorphism type of the group, \vspace-2mm
*

*• the elementary divisors of the associated quadratic form,
*

*
*

*• the sizes of the orbits of short vectors (these sizes are the
degrees of the faithful permutation representations which you may
construct using the PermGroup or PermGroupImfGroup commands
below), \vspace-2mm
*

*• the norm of the associated short vectors, \vspace-2mm
*

*• only in case that the group is not an i.m.f. group in
GL_{n}(ℚ): an appropriate message, including the ℚ-class
number of the corresponding rational i.m.f. class.
*

*
If you specify the value 0 for any of the parameters dim, q, or z,
the command will loop over all available dimensions, ℚ-classes of
given dimension, or ℤ-classes within the given ℚ-class,
respectively. Otherwise, the values of the arguments must be in range. A
value z ≠ 1 must not be specified if the ℤ-classes are not
known for the given dimension, i.e., if dim > 11 and dim ∉
{13,17,19,23}. The default value of z is 1. This value of z will
be accepted even if the ℤ-classes are not known. Then it specifies the
only representative group which is available for the q^{ th}
ℚ-class. The greatest legal value of dim is 24.
*

*
*

gap> DisplayImfInvariants( 3, 1, 0 ); #I Z-class 3.1.1: Solvable, size = 2^4*3 #I isomorphism type = C2 wr S3 = C2 x S4 = W(B3) #I elementary divisors = 1^3 #I orbit size = 6, minimal norm = 1 #I Z-class 3.1.2: Solvable, size = 2^4*3 #I isomorphism type = C2 wr S3 = C2 x S4 = C2 x W(A3) #I elementary divisors = 1*4^2 #I orbit size = 8, minimal norm = 3 #I Z-class 3.1.3: Solvable, size = 2^4*3 #I isomorphism type = C2 wr S3 = C2 x S4 = C2 x W(A3) #I elementary divisors = 1^2*4 #I orbit size = 12, minimal norm = 2 gap> DisplayImfInvariants( 8, 15, 1 ); #I Z-class 8.15.1: Solvable, size = 2^5*3^4 #I isomorphism type = C2 x (S3 wr S3) #I elementary divisors = 1*3^3*9^3*27 #I orbit size = 54, minimal norm = 8 #I not maximal finite in GL(8,Q), rational imf class is 8.5 gap> DisplayImfInvariants( 20, 23 ); #I Q-class 20.23: Size = 2^5*3^2*5*11 #I isomorphism type = (PSL(2,11) x D12).C2 #I elementary divisors = 1^18*11^2 #I orbit size = 3*660 + 2*1980 + 2640 + 3960, minimal norm = 4

Note that the `DisplayImfInvariants`

function uses a kind of shorthand to
display the elementary divisors. E. g., the expression `1*3^3*9^3*27`

in
the preceding example stands for the elementary divisors
*1,3,3,3,9,9,9,27*. (See also the next example which shows that the
`ImfInvariants`

function provides the elementary divisors in form of an
ordinary **GAP3** list.)

In the description of the isomorphism types the following notations are used:

•[] \beginitemize

•[] \beginitemize

•[{\makebox[15mm][l]*A*x*B*}] denotes a direct product of
a group *A* by a group *B*, \vspace-1mm

•[{\makebox[15mm][l]*A*subd*B*}] denotes a subdirect
product of *A* by *B*, \vspace-1mm

•[{\makebox[15mm][l]*A*Y*B*}] denotes a central product of
*A* by *B*, \vspace-1mm

•[{\makebox[15mm][l]*A*wr*B*}] denotes a wreath product of
*A* by *B*, \vspace-1mm

•[{\makebox[15mm][l]*A:B*}] denotes a split extension of *A* by
*B*, \vspace-1mm

•[{\makebox[15mm][l]*A.B*}] denotes just an extension of *A* by
*B* (split or nonsplit). \vspace-2mm
\enditemize
\enditemize
The groups involved are

• the cyclic groups *C _{n}*, dihedral groups

`C`

`D`

`Q`

• the alternating groups *A _{n}* and symmetric groups

`A`

`S`

• the linear groups *GL _{n}(q)*,

`GL(`

`,`

`)`

, `PGL(`

`,`

`)`

,
`SL(`

`,`

`)`

, and `PSL(`

`,`

`)`

, respectively,

• the unitary groups *SU _{n}(q)* and

`SU(`

`,`

`)`

and `PSU(`

`,`

`)`

, respectively,

• the symplectic groups *Sp(n,q)*, denoted by `Sp(`

`n``,`

`q``)`

,

• the orthogonal group *O _{8}^{+}(2)*, denoted by

`O+(8,2)`

,

• the extraspecial groups *2 _{+}^{1+8}*,

`2+^(1+8)`

,
`3+^(1+2)`

, `3+^(1+4)`

, and `5+^(1+2)`

, respectively, \vspace-2mm
• the Chevalley group *G _{2}(3)*, denoted by

`G(2,3)`

,

• the Weyl groups *W(A _{n})*,

`W(A`

`)`

, `W(B`

`)`

, `W(D`

`)`

,
`W(E`

`)`

, and `W(F4)`

, respectively, \vspace-2mm
• the sporadic simple groups *Co _{1}*,

`Co1`

, `Co2`

, `Co3`

, `HS`

, `J2`

, `M12`

, `M22`

, `M23`

, `M24`

, and
`Mc`

, respectively, \vspace-2mm
• a point stabilizer of index 11 in *M _{11}*, denoted by

`M10`

.

As mentioned above, the data assembled by the `DisplayImfInvariants`

command are ``cheap data'' in the sense that they can be provided by
the library without loading any of its large matrix files or performing
any matrix calculations. The following function allows you to get proper
access to these cheap data instead of just displaying them.

`ImfInvariants( `

`dim`, `q` )

`ImfInvariants( `

`dim`, `q`, `z` )

`ImfInvariants`

returns a record which provides some *ℤ*-class
invariants of the groups in the `z`^{ th}*ℤ*-class in the
`q`^{ th}*ℚ*-class of i.m.f. integral matrix groups of
dimension `dim`. A value `z`* ≠ 1* must not be specified if the
*ℤ*-classes are not known for the given dimension, i.e., if *dim > 11*
and *dim ∉ {13,17,19,23}*. The default value of `z` is 1. This
value of `z` will be accepted even if the *ℤ*-classes are not
known. Then it specifies the only representative group which is available
for the `q`^{ th}*ℚ*-class. The greatest legal value of `dim` is
24.

The resulting record contains six or seven components:

`size`

:-

the size of any representative group`G`,

`isSolvable`

:-

is`true`

if`G`is solvable,

`isomorphismType`

:-

a text string describing the isomorphism type of`G`(in the same notation as used by the`DisplayImfInvariants`

command above),

`elementaryDivisors`

:-

the elementary divisors of the associated Gram matrix`F`(in the same format as the result of the`ElementaryDivisorsMat`

function, see ElementaryDivisorsMat),

`minimalNorm`

:-

the norm of the associated short vectors,

`sizesOrbitsShortVectors`

:-

the sizes of the orbits of short vectors under`F`,

`maximalQClass`

:-

the*ℚ*-class number of an i.m.f. group in*GL*that contains_{n}(ℚ)`G`as a subgroup (only in case that not`G`itself is an i.m.f. subgroup of*GL*)._{n}(ℚ)

Note that four of these data, namely the group size, the solvability, the
isomorphism type, and the corresponding rational i.m.f. class, are
not only *ℤ*-class invariants, but also *ℚ*-class invariants.

Note further that, though the isomorphism type is a *ℚ*-class invariant,
you will sometimes get different descriptions for different *ℤ*-classes
of the same *ℚ*-class (as, e.g., for the classes 3.1.1 and 3.1.2 in
the last example above). The purpose of this behaviour is to provide some
more information about the underlying lattices.

gap> ImfInvariants( 8, 15, 1 ); rec( size := 2592, isSolvable := true, isomorphismType := "C2 x (S3 wr S3)", elementaryDivisors := [ 1, 3, 3, 3, 9, 9, 9, 27 ], minimalNorm := 8, sizesOrbitsShortVectors := [ 54 ], maximalQClass := 5 ) gap> ImfInvariants( 24, 1 ).size; 10409396852733332453861621760000 gap> ImfInvariants( 23, 5, 2 ).sizesOrbitsShortVectors; [ 552, 53130 ] gap> for i in [ 1 .. ImfNumberQClasses( 22 ) ] do > Print( ImfInvariants( 22, i ).isomorphismType, "\n" ); od; C2 wr S22 = W(B22) (C2 x PSU(6,2)).S3 (C2 x S3) wr S11 = (C2 x W(A2)) wr S11 (C2 x S12) wr C2 = (C2 x W(A11)) wr C2 C2 x S3 x S12 = C2 x W(A2) x W(A11) (C2 x HS).C2 (C2 x Mc).C2 C2 x S23 = C2 x W(A22) C2 x PSL(2,23) C2 x PSL(2,23) C2 x PGL(2,23) C2 x PGL(2,23)

`ImfMatGroup( `

`dim`, `q` )

`ImfMatGroup( `

`dim`, `q`, `z` )

`ImfMatGroup`

is the essential extraction function of this library. It
returns a representative group, `G` say, of the `z`^{ th}*ℤ*-class
in the `q`^{ th}*ℚ*-class of i.m.f. integral matrix groups of
dimension `dim`. A value `z`* ≠ 1* must not be specified if the
*ℤ*-classes are not known for the given dimension, i.e., if *dim > 11*
and *dim ∉ {13,17,19,23}*. The default value of `z` is 1. This
value of `z` will be accepted even if the *ℤ*-classes are not
known. Then it specifies the only representative group which is available
for the `q`^{ th}*ℚ*-class. The greatest legal value of `dim` is
24.

gap> G := ImfMatGroup( 5, 1, 3 ); ImfMatGroup(5,1,3) gap> for m in G.generators do PrintArray( m ); od; [ [ -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0 ], [ 0, 0, 0, 1, 0 ], [ -1, -1, -1, -1, 2 ], [ -1, 0, 0, 0, 1 ] ] [ [ 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1 ] ]

The group record of `G` contains the usual components of a matrix group
record. In addition, it includes the same six or seven records as the
resulting record of the `ImfInvariants`

function described above, namely
the components `size`

, `isSolvable`

, `isomorphismType`

,
`elementaryDivisors`

, `minimalNorm`

, and `sizesOrbitsShortVectors`

and,
if `G` is not a rational i.m.f. group, `maximalQClass`

. Moreover,
there are the two components

`form`

:-

the associated Gram matrix`F`,

`repsOrbitsShortVectors`

:-

representatives of the orbits of short vectors under`F`.

The last of these components will be required by the `PermGroup`

function
below.

Example:

gap> G.size; 3840 gap> G.isomorphismType; "C2 wr S5 = C2 x W(D5)" gap> PrintArray( G.form ); [ [ 4, 0, 0, 0, 2 ], [ 0, 4, 0, 0, 2 ], [ 0, 0, 4, 0, 2 ], [ 0, 0, 0, 4, 2 ], [ 2, 2, 2, 2, 5 ] ] gap> G.elementaryDivisors; [ 1, 4, 4, 4, 4 ] gap> G.minimalNorm; 4

If you want to perform calculations in such a matrix group `G` you should
be aware of the fact that **GAP3** offers much more efficient permutation
group routines than matrix group routines. Hence we recommend that you do
your computations, whenever it is possible, in the isomorphic permutation
group that is induced by the action of `G` on one of the orbits of the
associated short vectors. You may call one of the following functions to
get such a permutation group.

`PermGroup`

returns the permutation group which is induced by the given
i.m.f. integral matrix group `G` on an orbit of minimal size of `G`
on the set of short vectors (see also `PermGroupImfGroup`

below).

The permutation representation is computed by first constructing the
specified orbit, *S* say, of short vectors and then computing the
permutations which are induced on *S* by the generators of `G`. We would
like to warn you that in case of a large orbit this procedure may be
space and time consuming. Fortunately, there are only five *ℚ*-classes
in the library for which the smallest orbit of short vectors is of size
greater than 20000, the worst case being the orbit of size 196560 for the
Leech lattice (*dim = 24*, *q = 3*).

As mentioned above, `PermGroup`

constructs the required permutation
group, `P` say, as the image of `G` under the isomorphism between the
matrices in `G` and their action on *S*. Moreover, it constructs the
inverse isomorphism from `P` to `G`, *φ* say, and returns it in the
group record component `P`.`bijection`

of `P`. In fact, *φ* is
constructed by determining a *ℚ*-base *B ⊂ S* of *ℚ ^{1 ×
dim}* in

You may use *φ* at any time to compute the images in `G` of
permutations in `P` or to compute the preimages in `P` of matrices in
`G`.

The record of `P` contains, in addition to the usual components of
permutation group records, some special components. The most important of
those are:

`isomorphismType`

:-

a text string describing the isomorphism type of`P`(in the same notation as used by the`DisplayImfInvariants`

command above),

`matGroup`

:-

the associated matrix group`G`,

`bijection`

:-

the isomorphism*φ*from`P`to`G`,

`orbitShortVectors`

:-

the orbit*S*of short vectors (needed for*φ*),

`baseVectorPositions`

:-

the position numbers of the base vectors in*B*with respect to*S*(needed for*φ*),

`baseChangeMatrix`

:-

the base change matrix*M*(needed for*φ*).

As an example, let us compute a set *R* of matrix generators for the
solvable residuum of the group `G` that we have constructed in the
preceding example.

gap> # Perform the computations in an isomorphic permutation group. gap> P := PermGroup( G ); PermGroup(ImfMatGroup(5,1,3)) gap> P.generators; [ ( 1, 7, 6)( 2, 9)( 4, 5,10), ( 2, 3, 4, 5)( 6, 9, 8, 7) ] gap> D := DerivedSubgroup( P ); Subgroup( PermGroup(ImfMatGroup(5,1,3)), [ ( 1, 2,10, 9)( 3, 8)( 4, 5)( 6, 7), ( 1, 6)( 2, 7, 9, 4)( 3, 8)( 5,10), ( 1, 5,10, 6)( 2, 8, 9, 3) ] ) gap> Size( D ); 960 gap> IsPerfect( D ); true gap> # Now move the results back to the matrix group. gap> phi := P.bijection;; gap> R := List( D.generators, p -> Image( phi, p ) );; gap> for m in R do PrintArray( m ); od; [ [ -1, -1, -1, -1, 2 ], [ 0, -1, 0, 0, 0 ], [ 0, 0, 0, 1, 0 ], [ 0, 0, 1, 0, 0 ], [ -1, -1, 0, 0, 1 ] ] [ [ 0, 0, -1, 0, 0 ], [ 0, -1, 0, 0, 0 ], [ 1, 0, 0, 0, 0 ], [ -1, -1, -1, -1, 2 ], [ 0, -1, -1, 0, 1 ] ] [ [ 0, -1, 0, 0, 0 ], [ 1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0 ], [ -1, -1, -1, -1, 2 ], [ 0, -1, 0, -1, 1 ] ] gap> # The PreImage function allows us to use the inverse of phi. gap> PreImage( phi, R[1] ) = D.generators[1]; true

`PermGroupImfGroup`

returns the permutation group which is induced by the
given i.m.f. integral matrix group `G` on its `n`* ^{ th}* orbit of
short vectors. The only difference to the above

`PermGroup`

function is
that you can specify the orbit to be used. In fact, as the orbits of
short vectors are sorted by increasing sizes, the function ```
PermGroup(
````G` )

has been implemented such that it is equivalent to
`PermGroupImfGroup( ``G`, 1 )

.

gap> ImfInvariants( 12, 9 ).sizesOrbitsShortVectors; [ 120, 300 ] gap> G := ImfMatGroup( 12, 9 ); ImfMatGroup(12,9) gap> P1 := PermGroupImfGroup( G, 1 ); PermGroup(ImfMatGroup(12,9)) gap> P1.degree; 120 gap> P2 := PermGroupImfGroup( G, 2 ); PermGroupImfGroup(ImfMatGroup(12,9),2) gap> P2.degree; 300

**GAP3** provides a library of crystallographic groups of dimensions 2, 3,
and 4 which covers many of the data that have been listed in the book
``Crystallographic groups of four-dimensional space'' BBNWZ78.
It has been brought into **GAP3** format by Volkmar Felsch.

**How to access the data of the book**

Among others, the library offers functions which provide access to the data listed in the Tables 1, 5, and 6 of BBNWZ78:

• The information on the crystal families listed in Table 1 can be
reproduced using the `DisplayCrystalFamily`

function.

• Similarly, the `DisplayCrystalSystem`

function can be used to
reproduce the information on the crystal systems provided in Table
1.

• The information given in the *ℚ*-class headlines of Table 1 can
be displayed by the `DisplayQClass`

function, whereas the
`FpGroupQClass`

function can be used to reproduce the presentations
that are listed in Table 1 for the *ℚ*-class representatives.

• The information given in the *ℤ*-class headlines of Table 1 will
be covered by the results of the `DisplayZClass`

function, and the
matrix generators of the *ℤ*-class representatives can be
constructed by calling the `MatGroupZClass`

function.

• The `DisplaySpaceGroupType`

and the `DisplaySpaceGroupGenerators`

functions can be used to reproduce all of the information on the
space-group types that is provided in Table 1.

• The normalizers listed in Table 5 can be reproduced by calling the
`NormalizerZClass`

function.

• Finally, the `CharTableQClass`

function will compute the character
tables listed in Table 6, whereas the isomorphism types given in
Table 6 may be obtained by calling the `DisplayQClass`

function.

The display functions mentioned in the above list print their output with different indentation. So, calling them in a suitably nested loop, you may produce a listing in which the information about the objects of different type will be properly indented as has been done in Table 1 of BBNWZ78.

**Representation of space groups in {\GAP}**

Probably the most important function in the library is the `SpaceGroup`

function which provides representatives of the affine classes of space
groups. A space group of dimension *n* is represented by an
*(n+1)*-dimensional rational matrix group as follows.

If *S* is an *n*-dimensional space group, then each element *α ∈
S* is an affine mapping *α\!: V → V* of an
*n*-dimensional *ℝ*-vector space *V* onto itself. Hence *α* can be
written as the sum of an appropriate invertible linear mapping
*φ\!: V → V* and a translation by some translation
vector *t ∈ V* such that, if we write mappings from the left, we have
*α(v) = φ(v) + t* for all *v ∈ V*.

If we fix a basis of *V* and then replace each *v ∈ V* by the column
vector of its coefficients with respect to that basis (and hence *V* by
the isomorphic column vector space *ℝ ^{n × 1}*), we can describe
the linear mapping

Moreover, if we extend each column vector *v ∈ ℝ ^{n × 1}* to a
column

`c} \catcode`\`

=13
Before we describe all available library functions in detail, we have to add three remarks.

**Remark 1**

The concepts used in this section are defined in chapter 1 (Basic
definitions) of BBNWZ78. However, note that the definition of the
concept of a crystal system given on page 16 of that book relies on the
following statement about *ℚ*-classes:

•[] For a *ℚ*-class *C* there is a unique holohedry *H* such that
each f.u. group in *C* is a subgroup of some f.u. group in
*H*, but is not a subgroup of any f.u. group belonging to a
holohedry of smaller order.

This statement is correct for dimensions 1, 2, 3, and 4, and hence the definition of ``crystal system'' given on page 16 of BBNWZ78 is known to be unambiguous for these dimensions. However, there is a counterexample to this statement in seven-dimensional space so that the definition breaks down for some higher dimensions.

Therefore, the authors of the book have since proposed to replace this
definition of ``crystal system'' by the following much simpler one,
which has been discussed in more detail in NPW81. To formulate it,
we use the intersections of *ℚ*-classes and Bravais flocks as
introduced on page 17 of BBNWZ78, and we define the classification
of the set of all *ℤ*-classes into crystal systems as follows:

•[] **Definition**: A crystal system (introduced as an equivalence
class of *ℤ*-classes) consists of full geometric crystal
classes. The *ℤ*-classes of two (geometric) crystal classes
belong to the same crystal system if and only if these geometric
crystal classes intersect the same set of Bravais flocks of
*ℤ*-classes.

>From this definition of a crystal system of *ℤ*-classes one then
obtains crystal systems of f.u. groups, of space-group types, and of
space groups in the same manner as with the preceding definitions in the
book.

The new definition is unambiguous for all dimensions. Moreover, it can be checked from the tables in the book that it defines the same classification as the old one for dimensions 1, 2, 3, and 4.

It should be noted that the concept of crystal family is well-defined independently of the dimension if one uses the ``more natural'' second definition of it at the end of page 17. Moreover, the first definition of crystal family on page 17 defines the same concept as the second one if the now proposed definition of crystal system is used.

**Remark 2**

The second remark just concerns a different terminology in the tables of
BBNWZ78 and in the current library. In group theory, the number of
elements of a finite group usually is called the ``order'' of the
group. This notation has been used throughout in the book. Here,
however, we will follow the **GAP3** conventions and use the term
``size'' instead.

**Remark 3**

The third remark concerns a problem in the use of the space groups that should be well understood.

There is an alternative to the representation of the space group elements
by matrices of the form *[ \catcode`|=12 \begintabular{c*

c} \catcode`\

c} \catcode`\=13

From the mathematical point of view, both approaches are equivalent. In
particular, *M(S)* and *M(S)* are isomorphic, for instance via
the isomorphism *τ* mapping *M _{α} ∈ M(S)* to

The first convention, using matrices which act on column vectors from the
left, is not consistent with the fact that actions in **GAP3** are usually
from the right.

On the other hand, if we choose the second convention, we run into a
problem with the names of the space groups as introduced in
BBNWZ78. Any such name does not just describe the abstract
isomorphism type of the respective space group *S*, but reflects
properties of the matrix group *M(S)*. In particular, it contains as a
leading part the name of the *ℤ*-class of the associated point group
*P(S)*. Since the classification of space groups by affine equivalence
is tantamount to their classification by abstract isomorphism,
*M(S)* lies in the same affine class as *M(S)* and hence
should get the same name as *M(S)*. But the point group *P(S)* that
occurs in that name is not always *ℤ*-equivalent to the point group
*P(S)* of *M(S)*. For example, the isomorphism
*τ\!\!: M(S) → M(S)* defined above maps the
*ℤ*-class representative with the parameters *[3,7,3,2]* (in the
notation described below) to the *ℤ*-class representative with the
parameters *[3,7,3,3]*. In other words: The space group names
introduced for the groups *M(S)* in BBNWZ78 lead to confusing
inconsistencies if assigned to the groups *M(S)*.

In order to avoid this confusion we decided that the first convention is
the lesser evil. So the **GAP3** library follows the book, and if you call
the `SpaceGroup`

function you will get the same space group
representatives as given there. This does not cause any problems as long
as you do calculations within these groups treating them just as matrix
groups of certain isomorphism types. However, if it is necesary to
consider the action of a space group as affine mappings on the natural
lattice, you need to use the transposed representation of the space
group. For this purpose the library offers the `TransposedSpaceGroup`

function which not only transposes the matrices, but also adapts
appropriately the associated group presentation.

Both these functions are described in detail in the following.

**The library functions**

`NrCrystalFamilies`

returns the number of crystal families in case of
dimension `dim`. It can be used to formulate loops over the crystal
families.

There are 4, 6, and 23 crystal families of dimension 2, 3, and 4, respectively.

gap> n := NrCrystalFamilies( 4 ); 23

`DisplayCrystalFamily( `

`dim`, `family` )

`DisplayCrystalFamily`

displays for the specified crystal family
essentially the same information as is provided for that family in Table
1 of BBNWZ78, namely

• the family name,

• the number of parameters,

• the common rational decomposition pattern,

• the common real decomposition pattern,

• the number of crystal systems in the family, and

• the number of Bravais flocks in the family.

For details see BBNWZ78.

gap> DisplayCrystalFamily( 4, 17 ); #I Family XVII: cubic orthogonal; 2 free parameters; #I Q-decomposition pattern 1+3; R-decomposition pattern 1+3; #I 2 crystal systems; 6 Bravais flocks gap> DisplayCrystalFamily( 4, 18 ); #I Family XVIII: octagonal; 2 free parameters; #I Q-irreducible; R-decomposition pattern 2+2; #I 1 crystal system; 1 Bravais flock gap> DisplayCrystalFamily( 4, 21 ); #I Family XXI: di-isohexagonal orthogonal; 1 free parameter; #I R-irreducible; 2 crystal systems; 2 Bravais flocks

`NrCrystalSystems`

returns the number of crystal systems in case of
dimension `dim`. It can be used to formulate loops over the crystal
systems.

There are 4, 7, and 33 crystal systems of dimension 2, 3, and 4, respectively.

gap> n := NrCrystalSystems( 2 ); 4

The following two functions are functions of crystal systems.

Each crystal system is characterized by a pair `(`

where
`dim`,\,`system`)`dim` is the associated dimension, and `system` is the number of the
crystal system.

`DisplayCrystalSystem( `

`dim`, `system` )

`DisplayCrystalSystem`

displays for the specified crystal system
essentially the same information as is provided for that system in Table
1 of BBNWZ78, namely

• the number of *ℚ*-classes in the crystal system and

• the identification number, i.e., the tripel
`(`

described below, of the `dim`,\,`system`,\,`q-class`)*ℚ*-class
that is the holohedry of the crystal system.

For details see BBNWZ78.

gap> for sys in [ 1 .. 4 ] do DisplayCrystalSystem( 2, sys ); od; #I Crystal system 1: 2 Q-classes; holohedry (2,1,2) #I Crystal system 2: 2 Q-classes; holohedry (2,2,2) #I Crystal system 3: 2 Q-classes; holohedry (2,3,2) #I Crystal system 4: 4 Q-classes; holohedry (2,4,4)

`NrQClassesCrystalSystem( `

`dim`, `system` )

`NrQClassesCrystalSystem`

returns the number of *ℚ*-classes within the
given crystal system. It can be used to formulate loops over the
*ℚ*-classes.

The following five functions are functions of *ℚ*-classes.

In general, the parameters characterizing a *ℚ*-class will form a
triple `(`

where `dim`,\,`system`,\,`q-class`)`dim` is the associated
dimension, `system` is the number of the associated crystal system, and
`q-class` is the number of the *ℚ*-class within the crystal system.
However, in case of dimensions 2 or 3, a *ℚ*-class may also be
characterized by a pair `(`

where `dim`, `IT-number`)`IT-number` is the
number in the International Tables for Crystallography Hah83 of
any space-group type lying in (a *ℤ*-class of) that *ℚ*-class, or
just by the Hermann-Mauguin symbol of any space-group type lying in (a
*ℤ*-class of) that *ℚ*-class.

The Hermann-Mauguin symbols
which we use
in **GAP3** are the short Hermann-Mauguin symbols defined in the 1983
edition of the International Tables Hah83, but any occurring
indices are expressed by ordinary integers, and bars are replaced by
minus signs. For example, the Hermann-Mauguin symbol
`P`*42 _{1}m* will be represented by the string

`"P-421m"`

.

`DisplayQClass( `

`dim`, `system`, `q-class` )

`DisplayQClass( `

`dim`, `IT-number` )

`DisplayQClass( `

`Hermann-Mauguin-symbol` )

`DisplayQClass`

displays for the specified *ℚ*-class essentially the
same information as is provided for that *ℚ*-class in Table 1 of
BBNWZ78 (except for the defining relations given there), namely

• the size of the groups in the *ℚ*-class,

• the isomorphism type of the groups in the *ℚ*-class,

• the Hurley pattern,

• the rational constituents,

• the number of *ℤ*-classes in the *ℚ*-class, and

• the number of space-group types in the *ℚ*-class.

For details see BBNWZ78.

gap> DisplayQClass( "p2" ); #I Q-class H (2,1,2): size 2; isomorphism type 2.1 = C2; #I Q-constituents 2*(2,1,2); cc; 1 Z-class; 1 space group gap> DisplayQClass( "R-3" ); #I Q-class (3,5,2): size 6; isomorphism type 6.1 = C6; #I Q-constituents (3,1,2)+(3,4,3); ncc; 2 Z-classes; 2 space grps gap> DisplayQClass( 3, 195 ); #I Q-class (3,7,1): size 12; isomorphism type 12.5 = A4; #I C-irreducible; 3 Z-classes; 5 space grps gap> DisplayQClass( 4, 27, 4 ); #I Q-class H (4,27,4): size 20; isomorphism type 20.3 = D10xC2; #I Q-irreducible; 1 Z-class; 1 space group gap> DisplayQClass( 4, 29, 1 ); #I *Q-class (4,29,1): size 18; isomorphism type 18.3 = D6xC3; #I R-irreducible; 3 Z-classes; 5 space grps

Note in the preceding examples that, as pointed out above, the term
``size'' denotes the order of a representative group of the specified
*ℚ*-class and, of course, not the (infinite) class length.

`FpGroupQClass( `

`dim`, `system`, `q-class` )

`FpGroupQClass( `

`dim`, `IT-number` )

`FpGroupQClass( `

`Hermann-Mauguin-symbol` )

`FpGroupQClass`

returns a finitely presented group *F*, say, which is
isomorphic to the groups in the specified *ℚ*-class.

The presentation of that group is the same as the corresponding
presentation given in Table 1 of BBNWZ78 except for the fact that
its generators are listed in reverse order. The reason for this change
is that, whenever the group in question is solvable, the resulting
generators form an AG system (as defined in **GAP3**) if they are numbered
``from the top to the bottom'', and the presentation is a polycyclic
power commutator presentation. The `AgGroupQClass`

function described
next will make use of this fact in order to construct an ag group
isomorphic to *F*.

Note that, for any *ℤ*-class in the specified *ℚ*-class, the matrix
group returned by the `MatGroupZClass`

function (see below) not only is
isomorphic to *F*, but also its generators satisfy the defining relators
of *F*.

Besides of the usual components, the group record of *F* will have an
additional component *F*`.crQClass`

which saves a list of the parameters
that specify the given *ℚ*-class.

gap> F := FpGroupQClass( 4, 20, 3 ); FpGroupQClass( 4, 20, 3 ) gap> F.generators; [ f.1, f.2 ] gap> F.relators; [ f.1^2*f.2^-3, f.2^6, f.2^-1*f.1^-1*f.2*f.1*f.2^-4 ] gap> F.size; 12 gap> F.crQClass; [ 4, 20, 3 ]

`AgGroupQClass( `

`dim`, `system`, `q-class` )

`AgGroupQClass( `

`dim`, `IT-number` )

`AgGroupQClass( `

`Hermann-Mauguin-symbol` )

`AgGroupQClass`

returns an ag group *A*, say, isomorphic to the groups in
the specified *ℚ*-class, if these groups are solvable, or the value
`false`

(together with an appropriate warning), otherwise.

*A* is constructed by first establishing a finitely presented group (as
it would be returned by the `FpGroupQClass`

function described above) and
then constructing from it an isomorphic ag group. If the underlying
AG system is not yet a PAG system (see sections More about Ag Words and
More about Ag Groups), it will be refined appropriately (and a warning
will be displayed).

Besides of the usual components, the group record of *A* will have an
additional component *A*`.crQClass`

which saves a list of the parameters
that specify the given *ℚ*-class.

gap> A := AgGroupQClass( 4, 31, 3 ); #I Warning: a non-solvable group can't be represented as an ag group false gap> A := AgGroupQClass( 4, 20, 3 ); #I Warning: the presentation has been extended to get a PAG system AgGroupQClass( 4, 20, 3 ) gap> A.generators; [ f.1, f.21, f.22 ] gap> A.size; 12 gap> A.crQClass; [ 4, 20, 3 ]

`CharTableQClass( `

`dim`, `system`, `q-class` )

`CharTableQClass( `

`dim`, `IT-number` )

`CharTableQClass( `

`Hermann-Mauguin-symbol` )

`CharTableQClass`

returns the character table *T*, say, of a
representative group of (a *ℤ*-class of) the specified *ℚ*-class.

Although the set of characters can be considered as an invariant of the
specified *ℚ*-class, the resulting table will depend on the order in
which **GAP3** sorts the conjugacy classes of elements and the irreducible
characters and hence, in general, will not coincide with the
corresponding table presented in BBNWZ78.

`CharTableQClass`

proceeds as follows. If the groups in the given
*ℚ*-class are solvable, then it first calls the `AgGroupQClass`

and
`RefinedAgSeries`

functions to get an isomorphic ag group with a
PAG system, and then it calls the `CharTable`

function to compute the
character table of that ag group. In the case of one of the five
*ℚ*-classes of dimension 4 whose groups are not solvable, it first calls
the `FpGroupQClass`

function to get an isomorphic finitely presented
group, then it constructs a specially chosen faithful permutation
representation of low degree for that group, and finally it determines
the character table of the resulting permutation group again by calling
the `CharTable`

function.

In general, the above strategy will be much more efficient than the
alternative possibilities of calling the `CharTable`

function for a
finitely presented group provided by the `FpGroupQClass`

function or for
a matrix group provided by the `MatGroupZClass`

function.

gap> T := CharTableQClass( 4, 20, 3 );; gap> DisplayCharTable( T ); CharTableQClass( 4, 20, 3 ) 2 2 1 1 2 2 2 3 1 1 1 1 . . 1a 3a 6a 2a 4a 4b 2P 1a 3a 3a 1a 2a 2a 3P 1a 1a 2a 2a 4b 4a 5P 1a 3a 6a 2a 4a 4b X.1 1 1 1 1 1 1 X.2 1 1 1 1 -1 -1 X.3 1 1 -1 -1 A -A X.4 1 1 -1 -1 -A A X.5 2 -1 1 -2 . . X.6 2 -1 -1 2 . . A = E(4) = ER(-1) = i

`NrZClassesQClass( `

`dim`, `system`, `q-class` )

`NrZClassesQClass( `

`dim`, `IT-number` )

`NrZClassesQClass( `

`Hermann-Mauguin-symbol` )

`NrZClassesQClass`

returns the number of *ℤ*-classes within the given
*ℚ*-class. It can be used to formulate loops over the *ℤ*-classes.

The following functions are functions of *ℤ*-classes.

In general, the parameters characterizing a *ℤ*-class will form a
quadruple `(`

where `dim`,\,`system`, \mbox{`q-class`},\,`z-class`)`dim`
is the associated dimension, `system` is the number of the associated
crystal system, `q-class` is the number of the associated *ℚ*-class
within the crystal system, and `z-class` is the number of the *ℤ*-class
within the *ℚ*-class. However, in case of dimensions 2 or 3, a
*ℤ*-class may also be characterized by a pair `(`

where `dim`, `IT-number`)`IT-number` is the number in the International Tables Hah83
of any space-group type lying in that *ℤ*-class, or just by the
Hermann-Mauguin symbol of any space-group type lying in that *ℤ*-class.

`DisplayZClass( `

`dim`, `system`, `q-class`, `z-class` )

`DisplayZClass( `

`dim`, `IT-number` )

`DisplayZClass( `

`Hermann-Mauguin-symbol` )

`DisplayZClass`

displays for the specified *ℤ*-class essentially the
same information as is provided for that *ℤ*-class in Table 1 of
BBNWZ78 (except for the generating matrices of a class
representative group given there), namely

• for dimensions 2 and 3, the Hermann-Mauguin symbol of a
representative space-group type which belongs to that *ℤ*-class,

• the Bravais type,

• some decomposability information,

• the number of space-group types belonging to the *ℤ*-class,

• the size of the associated cohomology group.

For details see BBNWZ78.

gap> DisplayZClass( 2, 3 ); #I Z-class (2,2,1,1) = Z(pm): Bravais type II/I; fully Z-reducible; #I 2 space groups; cohomology group size 2 gap> DisplayZClass( "F-43m" ); #I Z-class (3,7,4,2) = Z(F-43m): Bravais type VI/II; Z-irreducible; #I 2 space groups; cohomology group size 2 gap> DisplayZClass( 4, 2, 3, 2 ); #I Z-class B (4,2,3,2): Bravais type II/II; Z-decomposable; #I 2 space groups; cohomology group size 4 gap> DisplayZClass( 4, 21, 3, 1 ); #I *Z-class (4,21,3,1): Bravais type XVI/I; Z-reducible; #I 1 space group; cohomology group size 1

`MatGroupZClass( `

`dim`, `system`, `q-class`, `z-class` )

`MatGroupZClass( `

`dim`, `IT-number` )

`MatGroupZClass( `

`Hermann-Mauguin-symbol` )

`MatGroupZClass`

returns a *dim × dim* matrix group *M*, say, which
is a representative of the specified *ℤ*-class. Its generators satisfy
the defining relators of the finitely presented group which may be
computed by calling the `FpGroupQClass`

function (see above) for the
*ℚ*-class which contains the given *ℤ*-class.

The generators of *M* are the same matrices as those given in Table 1 of
BBNWZ78. Note, however, that they will be listed in reverse order
to keep them in parallel to the abstract generators provided by the
`FpGroupQClass`

function (see above).

Besides of the usual components, the group record of *M* will have an
additional component *M*`.crZClass`

which saves a list of the parameters
that specify the given *ℤ*-class. (In fact, in order to make the
resulting group record consistent with those returned by the
`NormalizerZClass`

or `ZClassRepsDadeGroup`

functions described below, it
also will have an additional component *M*.`crConjugator`

containing just
the identity element of *M*.)

gap> M := MatGroupZClass( 4, 20, 3, 1 ); MatGroupZClass( 4, 20, 3, 1 ) gap> for g in M.generators do > Print( "\n" ); PrintArray( g ); od; Print( "\n" ); [ [ 0, 1, 0, 0 ], [ -1, 0, 0, 0 ], [ 0, 0, -1, -1 ], [ 0, 0, 0, 1 ] ] [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, -1, -1 ], [ 0, 0, 1, 0 ] ] gap> M.size; 12 gap> M.crZClass; [ 4, 20, 3, 1 ]

`NormalizerZClass( `

`dim`, `system`, `q-class`, `z-class` )

`NormalizerZClass( `

`dim`, `IT-number` )

`NormalizerZClass( `

`Hermann-Mauguin-symbol` )

`NormalizerZClass`

returns the normalizer *N*, say, in *GL(dim,ℤ)* of
the representative *dim × dim* matrix group which is constructed by
the `MatGroupZClass`

function (see above).

If the size of *N* is finite, then *N* again lies in some *ℤ*-class. In
this case, the group record of *N* will contain two additional components
*N*`.crZClass`

and *N*.`crConjugator`

which provide the parameters of
that *ℤ*-class and a matrix *g ∈ GL(dim,ℤ)*, respectively, such
that *N = g ^{-1} R g*, where

gap> N := NormalizerZClass( 4, 20, 3, 1 ); NormalizerZClass( 4, 20, 3, 1 ) gap> for g in N.generators do > Print( "\n" ); PrintArray( g ); od; Print( "\n" ); [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, -1, -1 ] ] [ [ 1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, -1, -1 ], [ 0, 0, 1, 0 ] ] [ [ 0, 1, 0, 0 ], [ -1, 0, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, -1, 0 ], [ 0, 0, 0, -1 ] ] gap> N.size; 96 gap> N.crZClass; [ 4, 20, 22, 1 ] gap> N.crConjugator = N.identity; true

gap> L := NormalizerZClass( 3, 42 ); NormalizerZClass( 3, 3, 2, 4 ) gap> L.size; 16 gap> L.crZClass; [ 3, 4, 7, 2 ] gap> L.crConjugator; [ [ 0, 0, -1 ], [ 1, 0, 0 ], [ 0, -1, -1 ] ] gap> M := NormalizerZClass( "C2/m" ); Group( [ [ -1, 0, 0 ], [ 0, -1, 0 ], [ 0, 0, -1 ] ], [ [ 0, -1, 0 ], [ -1, 0, 0 ], [ 0, 0, -1 ] ], [ [ 1, 0, 1 ], [ 0, 1, 1 ], [ 0, 0, 1 ] ], [ [ -1, 0, 0 ], [ 0, -1, 0 ], [ -1, -1, 1 ] ], [ [ 0, 1, -1 ], [ 1, 0, -1 ], [ 0, 0, -1 ] ] ) gap> M.size; "infinity" gap> IsBound( M.crZClass ); false

`NrSpaceGroupTypesZClass( `

`dim`, `system`, `q-class`, `z-class` )

`NrSpaceGroupTypesZClass( `

`dim`, `IT-number` )

`NrSpaceGroupTypesZClass( `

`Hermann-Mauguin-symbol` )

`NrSpaceGroupTypes`

returns the number of space-group types within the
given *ℤ*-class. It can be used to formulate loops over the space-group
types.

gap> N := NrSpaceGroupTypesZClass( 4, 4, 1, 1 ); 13

Some of the *ℤ*-classes of dimension *d*, say, are ``maximal'' in
the sense that the groups in these classes are maximal finite subgroups
of *GL(d,ℤ)*. Generalizing a term which is being used for dimension 4,
we call the representatives of these maximal *ℤ*-classes the ``**Dade
groups**'' of dimension *d*.

`NrDadeGroups`

returns the number of Dade groups of dimension `dim`. It
can be used to formulate loops over the Dade groups.

There are 2, 4, and 9 Dade groups of dimension 2, 3, and 4, respectively.

gap> NrDadeGroups( 4 ); 9

`DadeGroup`

returns the *n*th Dade group of dimension *dim*.

gap> D := DadeGroup( 4, 7 ); MatGroupZClass( 4, 31, 7, 2 )

`DadeGroupNumbersZClass( `

`dim`, `system`, `q-class`, `z-class` )

`DadeGroupNumbersZClass( `

`dim`, `IT-number` )

`DadeGroupNumbersZClass( `

`Hermann-Mauguin-symbol` )

`DadeGroupNumbersZClass`

returns the set of all those integers *n _{i}* for
which the

gap> dadeNums := DadeGroupNumbersZClass( 4, 4, 1, 2 ); [ 1, 5, 8 ] gap> for d in dadeNums do > D := DadeGroup( 4, d ); > Print( D, " of size ", Size( D ), "\n" ); > od; MatGroupZClass( 4, 20, 22, 1 ) of size 96 MatGroupZClass( 4, 30, 13, 1 ) of size 288 MatGroupZClass( 4, 32, 21, 1 ) of size 384

`ZClassRepsDadeGroup( `

`dim`, `system`, `q-class`, `z-class`, `n` )

`ZClassRepsDadeGroup( `

`dim`, `IT-number`, `n` )

`ZClassRepsDadeGroup( `

`Hermann-Mauguin-symbol`, `n` )

`ZClassRepsDadeGroup`

determines in the *n*th Dade group of dimension
*dim* all those conjugacy classes whose groups are, in *GL(dim,ℤ)*,
conjugate to the *ℤ*-class representative group *R*, say, of the given
*ℤ*-class. It returns a list of representative groups of these
conjugacy classes.

Let *M* be any group in the resulting list. Then the group record of *M*
provides two components *M*`.crZClass`

and *M*`.crConjugator`

which
contain the list of *ℤ*-class parameters of *R* and a suitable matrix
*g* from *GL(dim,ℤ)*, respectively, such that *M* equals *g ^{-1} R g*.

gap> DadeGroupNumbersZClass( 2, 2, 1, 2 ); [ 1, 2 ] gap> ZClassRepsDadeGroup( 2, 2, 1, 2, 1 ); [ MatGroupZClass( 2, 2, 1, 2 )^[ [ 0, 1 ], [ -1, 0 ] ] ] gap> ZClassRepsDadeGroup( 2, 2, 1, 2, 2 ); [ MatGroupZClass( 2, 2, 1, 2 )^[ [ 1, -1 ], [ 0, -1 ] ], MatGroupZClass( 2, 2, 1, 2 )^[ [ 1, 0 ], [ -1, 1 ] ] ] gap> R := last[2];; gap> R.crZClass; [ 2, 2, 1, 2 ] gap> R.crConjugator; [ [ 1, 0 ], [ -1, 1 ] ]

The following functions are functions of space-group types.

In general, the parameters characterizing a space-group type will form a
quintuple `(`

where
`dim`, `system`,\,`q-class`,\,`z-class`,\,`sg-type`)`dim` is the associated dimension, `system` is the number of the
associated crystal system, `q-class` is the number of the associated
*ℚ*-class within the crystal system, `z-class` is the number of the
*ℤ*-class within the *ℚ*-class, and `sg-type` is the space-group type
within the *ℤ*-class. However, in case of dimensions 2 or 3, you may
instead specify a *ℤ*-class by a pair `(`

or by its
Hermann-Mauguin symbol (as described above). Then the function will
handle the first space-group type within that `dim`, `IT-number`)*ℤ*-class, i.e.,
`sg-type` *= 1*, that is, the corresponding symmorphic space group (split
extension).

`DisplaySpaceGroupType( `

`dim`, `system`, `q-class`, `z-class`, `sg-type`
)

`DisplaySpaceGroupType( `

`dim`, `IT-number` )

`DisplaySpaceGroupType( `

`Hermann-Mauguin-symbol` )

`DisplaySpaceGroupType`

displays for the specified space-group type some
of the information which is provided for that space-group type in Table 1
of BBNWZ78, namely

• the orbit size associated with that space-group type and,

• for dimensions 2 and 3, the `IT-number` and the Hermann-Mauguin
symbol.

For details see BBNWZ78.

gap> DisplaySpaceGroupType( 2, 17 ); #I Space-group type (2,4,4,1,1); IT(17) = p6mm; orbit size 1 gap> DisplaySpaceGroupType( "Pm-3" ); #I Space-group type (3,7,2,1,1); IT(200) = Pm-3; orbit size 1 gap> DisplaySpaceGroupType( 4, 32, 10, 2, 4 ); #I *Space-group type (4,32,10,2,4); orbit size 18 gap> DisplaySpaceGroupType( 3, 6, 1, 1, 4 ); #I *Space-group type (3,6,1,1,4); IT(169) = P61, IT(170) = P65; #I orbit size 2; fp-free

`DisplaySpaceGroupGenerators( `

`dim`, `system`, `q-class`, `z-class`,
`sg-type` )

`DisplaySpaceGroupGenerators( `

`dim`, `IT-number` )

`DisplaySpaceGroupGenerators( `

`Hermann-Mauguin-symbol` )

`DisplaySpaceGroupGenerators`

displays the non-translation generators of
a representative space group of the specified space-group type without
actually constructing that matrix group.

In more details: Let *n = dim* be the given dimension, and let *M _{1},
..., M_{r}* be the generators of the representative

`MatGroupZClass`

function (see above) for that `SpaceGroup`

function described
below will construct as representative of that space-group type an `c} \catcode`\`

=13
`DisplaySpaceGroupGenerators`

function saves
time by not constructing the group, but just displaying the

gap> DisplaySpaceGroupGenerators( "P61" ); #I The non-translation generators of SpaceGroup( 3, 6, 1, 1, 4 ) are [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, 1, 1/2 ], [ 0, 0, 0, 1 ] ] [ [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ], [ 0, 0, 1, 1/3 ], [ 0, 0, 0, 1 ] ]

`SpaceGroup( `

`dim`, `system`, `q-class`, `z-class`, `sg-type` )

`SpaceGroup( `

`dim`, `IT-number` )

`SpaceGroup( `

`Hermann-Mauguin-symbol` )

`SpaceGroup`

returns a *(dim+1) × (dim+1 )* matrix group *S*, say,
which is a representative of the given space-group type (see also the
description of the `DisplaySpaceGroupGenerators`

function above).

gap> S := SpaceGroup( "P61" ); SpaceGroup( 3, 6, 1, 1, 4 ) gap> for s in S.generators do > Print( "\n" ); PrintArray( s ); od; Print( "\n" ); [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, 1, 1/2 ], [ 0, 0, 0, 1 ] ] [ [ 0, -1, 0, 0 ], [ 1, -1, 0, 0 ], [ 0, 0, 1, 1/3 ], [ 0, 0, 0, 1 ] ] [ [ 1, 0, 0, 1 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 1 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 1 ], [ 0, 0, 0, 1 ] ] gap> S.crSpaceGroupType; [ 3, 6, 1, 1, 4 ]

Besides of the usual components, the resulting group record of *S*
contains an additional component *S*`.crSpaceGroupType`

which saves a
list of the parameters that specify the given space-group type.

Moreover, it contains, in form of a finitely presented group, a
presentation of *S* which is satisfied by the matrix generators. If the
factor group of *S* by its translation normal subgroup is solvable then
this presentation is chosen such that it is a polycyclic power commutator
presentation. The proper way to access this presentation is to call the
following function.

`FpGroup`

returns a finitely presented group `G`, say, which is
isomorphic to `S`, where `S` is expected to be a space group. It is
chosen such that there is an isomrphism from `G` to `S` which maps each
generator of `G` onto the corresponding generator of `S`. This means, in
particular, that the matrix generators of `S` satisfy the relators of
`G`.

gap> G := FpGroup( S ); Group( g1, g2, g3, g4, g5 ) gap> for rel in G.relators do Print( rel, "\n" ); od; g1^2*g5^-1 g2^3*g5^-1 g2^-1*g1^-1*g2*g1 g3^-1*g1^-1*g3*g1*g3^2 g3^-1*g2^-1*g3*g2*g4*g3^2 g4^-1*g1^-1*g4*g1*g4^2 g4^-1*g2^-1*g4*g2*g4*g3^-1 g4^-1*g3^-1*g4*g3 g5^-1*g1^-1*g5*g1 g5^-1*g2^-1*g5*g2 g5^-1*g3^-1*g5*g3 g5^-1*g4^-1*g5*g4 gap> # Verify that the matrix generators of S satisfy the relators of G. gap> ForAll( G.relators, > rel -> MappedWord( rel, G.generators, S.generators ) = S.identity ); true

`TransposedSpaceGroup( `

`dim`, `system`, `q-class`, `z-class`, `sg-type` )

`TransposedSpaceGroup( `

`dim`, `IT-number` )

`TransposedSpaceGroup( `

`Hermann-Mauguin-symbol` )

`TransposedSpaceGroup( `

`S` )

`TransposedSpaceGroup`

returns a matrix group `T`, say, whose generators
are just the transposed generators (in the same order) of the
corresponding space group `S` specified by the arguments. As for `S`, you
may get a finite presentation for `T` via the `FpGroup`

function.

The purpose of this function is explicitly discussed in the introduction to this section.

gap> T := TransposedSpaceGroup( S ); TransposedSpaceGroup( 3, 6, 1, 1, 4 ) gap> for m in T.generators do > Print( "\n" ); PrintArray( m ); od; Print( "\n" ); [ [ -1, 0, 0, 0 ], [ 0, -1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 1/2, 1 ] ] [ [ 0, 1, 0, 0 ], [ -1, -1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 1/3, 1 ] ] [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 1, 0, 0, 1 ] ] [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 1, 0, 1 ] ] [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 1, 1 ] ]

This library contains all groups of order at most 1000 except for 512 and 768 up to isomorphism. There are a total of 174366 such groups.

The function `SmallGroup( `

returns the `size`, `i` )*i*th group of order
*size* in the catalogue. It will return an AgGroup, if the group is soluble
and a PermGroup otherwise.

The function `NumberSmallGroups( `

returns the number of groups of
the order `size` )*size*.

The function `AllSmallGroups( `

returns the list of all groups of
the order `size` )*size*.

`UnloadSmallGroups( `

`list of sizes` )

It is possible to work with the catalogue of groups of small order just using the functions described above. However, the catalogue is rather large even though the groups are stored in a very compact description. Thus it might be helpful for a space efficient usage of the catalogue, to know a little bit about unloading parts of the catalogue by hand.

At the first call of one of the functions described above, the groups of
order `size` are loaded and stored in a compact description. GAP will not
unload them itsself again. Thus if one calls one of the above functions for
a lot of different orders, then all the groups of these orders are stored.
Even though the description of the groups is space efficient, this might
use a lot of space. For example, if one uses the above functions to load
the complete catalogue, then GAP will grow to about 12 MB of workspace.

Thus it might be interesting to unload the groups of some orders again, if
they are not used anymore. This can be done by calling the function
`UnloadSmallGroups( `

`list of sizes` )

If the groups of order `size` are unloaded by hand, then GAP will of course
load them again at the next call of `SmallGroup( `

or one of
the other functions described at the beginning of this section.
`size`, `i` )

Let `G` be a PermGroup or AgGroup of order at most 1000, but not of order
256, 512 or 768. Then the function call `IdGroup( `

returns a tuple
`G` )*[size, i]* meaning that *G* is isomorphic to the *i*-th group in the
catalogue of groups of order *size*.

Note that this package calls and uses the ANUPQ share library of GAP in a few cases.

gap3-jm

02 Dec 2021