This is a collection of examples showing how
the &GAP; system <Cite Key="GAP"/>
can be used to compute information about the probabilistic generation of
finite almost simple groups.
It includes all examples that were needed for the computational results
in <Cite Key="BGK"/>.
<P/>
The purpose of this writeup is twofold.
On the one hand, the computations are documented this way.
On the other hand, the &GAP; code shown for the examples can be used as
test input for automatic checking of the data and the functions used.
<P/>
A first version of this document, which was based on &GAP; 4.4.10,
had been accessible in the web since April 2006
and is available in the arXiv (no. 0710.3267) since October 2007. <!-- cite as http://arxiv.org/abs/0710.3267v1 -->
The differences between that document and the current version are as follows.
<List>
<Item>
The format of the &GAP; output was adjusted to the changed behaviour
of &GAP; until version 4.10.
This affects mainly the way how &GAP; records are printed.
</Item>
<Item>
Several computations are now easier because more character tables of
almost simple groups and maximal subgroups of such groups are available
in the &GAP; Character Table Library.
(The more involved computations from the original version have been kept
in the file.)
</Item>
<Item>
The computation of all conjugacy classes of a subgroup of
<M>&POmega;^+(12,3)</M>
has been replaced by the computation of the conjugacy classes of elements
of prime order in this subgroup.
</Item>
<Item>
The irreducible element chosen in the simple group <M>&POmega;^-(10,3)</M> has
order <M>61</M> not <M>122</M>.
</Item>
</List>
The main purpose of this note is to document the &GAP; computations
that were carried out in order to obtain the computational results
in <Cite Key="BGK"/>.
Table I lists the simple groups among these examples.
The first column gives the group names,
the second and third columns contain a plus sign <M>+</M> or a minus sign
<M>-</M>, depending on whether the quantities
<M>&total;(G,s)</M> and <M>∝(G,s)</M>, respectively,
are less than <M>1/3</M>.
The fourth column lists the orders of elements <M>s</M> which either prove
the <M>+</M> signs or cover most of the cases for proving these signs.
The fifth column lists the sections in this note where the example is
treated.
The rows of the table are ordered alphabetically w.r.t. the group names.
<P/>
In order to keep this note self-contained,
we first describe the theory needed,
in Section <Ref Sect="sect:probgen-background"/>.
The translation of the relevant formulae into &GAP; functions
can be found in Section <Ref Sect="sect:probgen-functions"/>.
Then Section <Ref Sect="sect:chartheor"/> describes the computations
that only require (ordinary) character tables in the
&GAP; Character Table Library <Cite Key="CTblLib"/>.
Computations using also the groups are shown in
Section <Ref Sect="sect:hard"/>.
In each of the last two sections, the examples are ordered alphabetically
w.r.t. the names of the simple groups.
Contrary to <Cite Key="BGK"/>,
&ATLAS; notation is used throughout this note,
because the identifiers used for character tables in the
&GAP; Character Table Library follow mainly the
&ATLAS; <Cite Key="CCN85"/>.
For example, we write
<M>L_d(q)</M> for <M>&PSL;(d,q)</M>,
<M>S_d(q)</M> for <M>&PSp;(d,q)</M>,
<M>U_d(q)</M> for <M>&PSU;(d,q)</M>, and
<M>O^+_{2d}(q)</M>, <M>O^-_{2d}(q)</M>, <M>O_{2d+1}(q)</M> for
<M>&POmega;^+(2d,q)</M>, <M>&POmega;^-(2d,q)</M>, <M>&POmega;(2d+1,q)</M>,
respectively.
<P/>
Furthermore, in the case of classical groups,
the character tables of the (almost) <E>simple</E> groups
are considered
not the tables of the matrix groups (which are in fact often not available
in the &GAP; Character Table Library).
Consequently, also element orders and the description of maximal subgroups
refer to the (almost) simple groups not to the matrix groups.
<P/>
This note contains also several examples that are not needed for the proofs
in <Cite Key="BGK"/>.
Besides several small simple groups <M>G</M> whose character table
is contained in the &GAP; Character Table Library
and for which enough information is available for computing <M>&total;(G)</M>,
in Section <Ref Subsect="easyloop"/>,
a few such examples appear in individual sections.
In the table of contents, the section headers of the latter kind of examples
are marked with an asterisk <M>(\ast)</M>.
<P/>
The examples use the &GAP; Character Table Library,
the &GAP; Library of Tables of Marks, <!-- %T TODO: cite the package! -->
and the &GAP; interface <Cite Key="AtlasRep"/> to the
&ATLAS; of Group Representations <Cite Key="AGRv3"/>,
so we first load these three packages in the required versions.
The &GAP; output was adjusted to the versions shown below;
in older versions, features necessary for the computations may be missing,
and it may happen that with newer versions, the behaviour is different.
Some of the computations in Section <Ref Sect="sect:hard"/>
require about <M>800</M> MB of space (on <M>32</M> bit machines).
Therefore we check whether &GAP; was started with sufficient maximal
memory; the command line option for this is <C>-o 800m</C>.
<P/>
<Example><![CDATA[
gap> max:= GAPInfo.CommandLineOptions.o;;
gap> if not ( ( IsSubset( max, "m" ) and
> Int( Filtered( max, IsDigitChar ) ) >= 800 ) or
> ( IsSubset( max, "g" ) and
> Int( Filtered( max, IsDigitChar ) ) >= 1 ) ) then
> Print( "the maximal allowed memory might be too small\n" );
> fi;
]]></Example>
<P/>
Several computations involve calls to the &GAP; function
<Ref Func="Random" BookName="ref"/>.
In order to make the results of individual examples reproducible,
independent of the rest of the computations,
we reset the relevant random number generators
whenever this is appropriate.
For that, we store the initial states in the variable <C>staterandom</C>,
and provide a function for resetting the random number generators.
(The <Ref Func="Random" BookName="ref"/> calls in the &GAP; library
use the two random number generators
<Ref Var="GlobalRandomSource" BookName="ref"/> and
<Ref Var="GlobalMersenneTwister" BookName="ref"/>.)
Let <M>G</M> be a finite group, <M>S</M> the socle of <M>G</M>,
and denote by <M>G^{\times}</M> the set of nonidentity elements in <M>G</M>.
For <M>s, g \in G^{\times}</M>, let
<M>∝( g, s ):=
|\{ h \in G; S \nsubseteq \langle s^h, g \rangle \}| / |G|</M>,
the proportion of elements in the class <M>s^G</M> which fail to generate
at least <M>S</M> with <M>g</M>;
we set <M>∝( G, s ):= \max\{ ∝( g, s ); g \in G^{\times} \}</M>.
We are interested in finding a class <M>s^G</M> of elements in <M>S</M>
such that <M>∝( G, s ) < 1/3</M> holds.
<P/>
First consider <M>g \in S</M>,
and let <M>&M;(S,s)</M> denote the set of those maximal subgroups of <M>S</M>
that contain <M>s</M>.
We have
<Display Mode="M">
|\{ h \in S; S \nsubseteq \langle s^h, g \rangle \}|
= |\{ h \in S; \langle s, h g h^{-1} \rangle ¬eq; S \}| \\
\leq \sum_{M \in &M;(S,s)} |\{ h \in S; h g h^{-1} \in M \}|
</Display>
Since <M>h g h^{-1} \in M</M> holds if and only if the coset <M>M h</M>
is fixed by <M>g</M> under the permutation action of <M>S</M>
on the right cosets of <M>M</M> in <M>S</M>,
we get that
<M>|\{ h \in S; h g h^{-1} \in M \}| = |C_S(g)| \cdot |g^S \cap M|
= |M| \cdot 1_M^S(g)</M>,
where <M>1_M^S</M> is the permutation character of this action,
of degree <M>|S|/|M|</M>.
Thus
<Display Mode="M">
|\{ h \in S; \langle s, h g h^{-1} \rangle ¬eq; S \}| / |S|
\leq \sum_{M \in &M;(S,s)} 1_M^S(g) / 1_M^S(1) .
</Display>
We abbreviate the right hand side of this inequality by <M>&total;( g, s )</M>,
set <M>&total;( S, s ):= \max\{ &total;( g, s ); g \in S^{\times} \}</M>,
and choose a transversal <M>T</M> of <M>S</M> in <M>G</M>.
Then <M>∝( g, s ) \leq |T|^{-1} \cdot \sum_{t \in T} &total;( g^t, s )</M>
and thus <M>∝( G, s ) \leq &total;( S, s )</M> holds.
<P/>
If <M>S = G</M> and if <M>&M;(G,s)</M> consists of a single maximal subgroup
<M>M</M> of <M>G</M> then equality holds,
i.e., <M>∝( g, s ) = &total;( g, s ) = 1_M^S(g) / 1_M^S(1)</M>.
<P/>
The quantity <M>1_M^S(g) / 1_M^S(1) = |g^S \cap M| / |g^S|</M>
is the proportion of fixed points of <M>g</M> in the permutation action
of <M>S</M> on the right cosets of its subgroup <M>M</M>.
This is called the <E>fixed point ratio</E> of <M>g</M>
w. r. t. <M>S/M</M>, and is denoted as <M>&fpr;(g,S/M)</M>.
<P/>
For a subgroup <M>M</M> of <M>S</M>,
the number <M>n</M> of <M>S</M>-conjugates of <M>M</M>
containing <M>s</M> is equal to <M>|M^S| \cdot |s^S \cap M| / |s^S|</M>.
To see this, consider the set <M>\{ (s^h, M^k); h, k \in S, s^h \in M^k \}</M>,
the cardinality of which can be counted either as
<M>|M^S| \cdot |s^S \cap M|</M> or as <M>|s^S| \cdot n</M>.
So we get <M>n = |M| \cdot 1_M^S(s) / |N_S(M)|</M>.
<P/>
If <M>S</M> is a finite <E>nonabelian simple</E> group
then each maximal subgroup in <M>S</M> is self-normalizing,
and we have <M>n = 1_M^S(s)</M> if <M>M</M> is maximal.
So we can replace the summation over <M>&M;(S,s)</M> by one over a set
<M>&MM;(S,s)</M> of representatives of conjugacy classes
of maximal subgroups of <M>S</M>,
and get that
Furthermore, we have <M>|&M;(S,s)| = \sum_{M \in &MM;(S,s)} 1_M^S(s)</M>.
<P/>
In the following, we will often deal with the quantities
<M>&total;(S):= \min\{ &total;( S, s ); s \in S^{\times} \}</M> and
<M>&sprtotal;(S):= \lceil 1 / &total;(S) - 1 \rceil</M>.
These values can be computed easily from the primitive
permutation characters of <M>S</M>.
<P/>
Analogously, we set
<M>∝(S):= \min \{ ∝( S, s ); s \in S^{\times} \}</M> and
<M>&sprbound;(S):= \lceil 1 / ∝(S) - 1 \rceil</M>.
Clearly we have <M>∝(S) \leq &total;(S)</M> and
<M>&sprbound;(S) \geq &sprtotal;(S)</M>.
<P/>
One interpretation of <M>&sprbound;(S)</M> is that if this value is
at least <M>k</M>
then it follows that for any <M>g_1, g_2, \ldots, g_k \in S^{\times}</M>,
there is some <M>s \in S</M> such that <M>S = \langle g_i, s \rangle</M>,
for <M>1 \leq i \leq k</M>.
In this case, <M>S</M> is said to have <E>spread</E> at least <M>k</M>.
(Note that the lower bound <M>&sprtotal;(S)</M> for <M>&sprbound;(S)</M>
can be computed from the list of primitive permutation characters of <M>S</M>.)
<P/>
Moreover, <M>&sprbound;(S) \geq k</M> implies that the element <M>s</M>
can be chosen uniformly from a fixed conjugacy class of <M>S</M>.
This is called <E>uniform spread</E> at least <M>k</M>
in <Cite Key="BGK"/>.
<P/>
It is proved in <Cite Key="GK"/> that all finite simple groups
have uniform spread at least <M>1</M>,
that is, for any element <M>x \in S^{\times}</M>,
there is an element <M>y</M> in a prescribed class of <M>S</M>
such that <M>G = \langle x, y \rangle</M> holds.
In <Cite Key="BGK" Where="Corollary 1.3"/>,
it is shown that all finite simple groups have uniform spread at least <M>2</M>,
and the finite simple groups with (uniform) spread exactly <M>2</M> are listed.
<P/>
Concerning the spread, it should be mentioned that the methods used here and
in <Cite Key="BGK"/> are nonconstructive in the sense that they cannot
be used for finding an element <M>s</M> that generates <M>G</M> together
with each of the <M>k</M> prescribed elements <M>g_1, g_2, \ldots, g_k</M>.
<P/>
Now consider <M>g \in G \setminus S</M>.
Since <M>∝( g^k, s ) \geq ∝( g, s )</M> for any positive integer
<M>k</M>,
we can assume that <M>g</M> has prime order <M>p</M>, say.
We set <M>H = \langle S, g \rangle \leq G</M>, with <M>[H:S] = p</M>,
choose a transversal <M>T</M> of <M>H</M> in <M>G</M>,
let <M>&M;^{\prime}(H,s):= &M;(H,s) \setminus \{ S \}</M>,
and let <M>&MM;^{\prime}(H,s)</M> denote a set of representatives of
<M>H</M>-conjugacy classes of these groups.
As above,
<!-- <Display Mode="M"> |\{ h \in H; S \nsubseteq \langle s^h, g \rangle \}| / |H| = |\{ h \in H; \langle s^h, g \rangle ¬eq; H \}| / |H| \\ \leq \sum_{M \in &M;^{\prime}(H,s)} |\{ h \in H; h g h^{-1} \in M \}| / |H| \\ = \sum_{M \in &M;^{\prime}(H,s)} 1_M^H(g) / 1_M^H(1) \\ = \sum_{M \in &MM;^{\prime}(H,s)} 1_M^H(g) \cdot 1_M^H(s) / 1_M^H(1) </Display>
-->
<Table Align="rcl">
<Row>
<Item><M>|\{ h \in H; S \nsubseteq \langle s^h, g \rangle \}| / |H|</M></Item>
<Item><M>=</M></Item>
<Item><M>|\{ h \in H; \langle s^h, g \rangle ¬eq; H \}| / |H|</M></Item>
</Row>
<Row>
<Item> </Item>
<Item><M>\leq</M></Item>
<Item><M>\sum_{M \in &M;^{\prime}(H,s)}
|\{ h \in H; h g h^{-1} \in M \}| / |H|</M></Item>
</Row>
<Row>
<Item> </Item>
<Item><M>=</M></Item>
<Item><M>\sum_{M \in &M;^{\prime}(H,s)} 1_M^H(g) / 1_M^H(1)</M></Item>
</Row>
<Row>
<Item> </Item>
<Item><M>=</M></Item>
<Item><M>\sum_{M \in &MM;^{\prime}(H,s)} 1_M^H(g) \cdot 1_M^H(s) / 1_M^H(1)</M></Item>
</Row>
</Table>
(Note that no summand for <M>M = S</M> occurs,
so each group in <M>&MM;^{\prime}(H,s)</M> is self-normalizing.)
We abbreviate the right hand side by <M>&total;(H,g,s)</M>,
and set <M>&total;^{\prime}( H, s ) =
\max\{ &total;(H,g,s); g \in H \setminus S, |g| = [H:S] \}</M>.
Then we get
<M>∝( g, s ) \leq |T|^{-1} \cdot \sum_{t \in T} &total;(H^t,g^t,s)</M>
and thus
<Display Mode="M">
∝( G, s ) \leq \max\{ ∝( S, s ),
\max\{ &total;^{\prime}( H, s );
S \leq H \leq G, [H:S] \textrm{\ prime} \} \} .
</Display>
For convenience, we set
<M>∝^{\prime}(G,s) = \max\{ ∝(g,s); g \in G \setminus S \}</M>.
The following criteria will be used when we have to show
the existence or nonexistence of <M>x_1, x_2, \ldots, x_k</M>,
and <M>s \in G</M> with the property
<M>\langle x_i, s \rangle = G</M> for <M>1 \leq i \leq k</M>.
Note that manipulating lists of integers (representing fixed or moved points)
is much more efficient than testing whether certain permutations generate
a given group.
<P/>
Lemma:
<P/>
Let <M>G</M> be a finite group, <M>s \in G^{\times}</M>,
and <M>X = \bigcup_{M \in &M;(G,s)} G/M</M>.
For <M>x_1, x_2, \ldots, x_k \in G</M>,
the conjugate <M>s^{\prime}</M> of <M>s</M> satisfies
<M>\langle x_i, s^{\prime} \rangle = G</M> for <M>1 \leq i \leq k</M>
if and only if
<M>&Fix;_{X}(s^{\prime}) \cap \bigcup_{i=1}^k &Fix;_{X}(x_i) = \emptyset</M>
holds.
<P/>
<E>Proof.</E>
If <M>s^g \in U \leq G</M> for some <M>g \in G</M> then
<M>&Fix;_{X}(U) = \emptyset</M> if and only if <M>U = G</M> holds;
note that <M>&Fix;_{X}(G) = \emptyset</M>,
and <M>&Fix;_{X}(U) = \emptyset</M> implies that <M>U \nsubseteq h^{-1} M h</M>
holds for all <M>h \in G</M> and <M>M \in &M;(G,s)</M>, thus <M>U = G</M>.
Applied to <M>U = \langle x_i, s^{\prime} \rangle</M>,
we get <M>\langle x_i, s^{\prime} \rangle = G</M> if and only if
<M>&Fix;_{X}(s^{\prime}) \cap &Fix;_{X}(x_i) = &Fix;_{X}(U) = \emptyset</M>.
<!-- % weaken this? --> <!-- % one direction without X being the union of all perm. repr. including s? -->
<P/>
Corollary 1:
<P/>
If <M>&M;(G,s) = \{ M \}</M> in the situation of the above Lemma
then there is a conjugate <M>s^{\prime}</M> of <M>s</M> that satisfies
<M>\langle x_i, s^{\prime} \rangle = G</M> for <M>1 \leq i \leq k</M>
if and only if
<M>\bigcup_{i=1}^k &Fix;_{X}(x_i) ¬eq; X</M>.
<P/>
Corollary 2:
<P/>
Let <M>G</M> be a finite simple group
and let <M>X</M> be a <M>G</M>-set such that each <M>g \in G</M> fixes at least one
point in <M>X</M> but that <M>&Fix;_{X}(G) = \emptyset</M> holds.
If <M>x_1, x_2, \ldots x_k</M> are elements in <M>G</M> such that
<M>\bigcup_{i=1}^k &Fix;_{X}(x_i) = X</M> holds
then for each <M>s \in G</M> there is at least one <M>i</M> with
<M>\langle x_i, s \rangle ¬eq; G</M>.
</Subsection>
</Section>
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="sect:probgen-functions">
<Heading>&GAP; Functions for the Computations</Heading>
After the introduction of general utilities in
Section <Ref Subsect="subsect:utils"/>,
we distinguish two different tasks.
Section <Ref Subsect="subsect:probgen-ctfun"/> introduces functions
that will be used
in the following to compute <M>&total;(g,s)</M> with character-theoretic methods.
Functions for computing <M>∝(g,s)</M> or an upper bound for this value
will be introduced in Section <Ref Subsect="subsect:groups"/>.
<P/>
The &GAP; functions shown in this section
are collected in the file <F>tst/probgen.g</F> that is
distributed with the &GAP; Character Table Library,
see <URL>http://www.math.rwth-aachen.de/~Thomas.Breuer/ctbllib</URL>.
<P/>
The functions have been designed for the examples in the later sections,
they could be generalized and optimized for other examples.
It is not our aim to provide a package for this functionality.
Let <C>list</C> be a dense list and <C>prop</C> be a unary function that returns
<K>true</K> or <K>false</K> when applied to the entries of <C>list</C>.
<C>PositionsProperty</C> returns the set of positions in <C>list</C> for which
<K>true</K> is returned.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#A PositionsProperty( <list>, <prop> )
##
## Let <list> be a dense list and <prop> be a unary function that returns
## `true' or `false' when applied to the entries of <list>.
## `PositionsProperty' returns the set of positions in for which
## `true' is returned.
##
]]></Ignore>
<Example><![CDATA[
gap> if not IsBound( PositionsProperty ) then
> PositionsProperty:= function( list, prop )
> return Filtered( [ 1 .. Length( list ) ], i -> prop( list[i] ) );
> end;
> fi;
]]></Example>
<P/>
<!-- Let <C>list</C> be a dense list and <C>k</C> be a nonnegative integer. <C>UnorderedTuplesNoSort</C> returns a list of all unordered <C>k</C>-tuples with repetitions of elements in <C>list</C>. The only difference to the &GAP; library function <C>UnorderedTuples</C> is that the entries in the result of <C>UnorderedTuplesNoSort</C> need not be sorted. This is advantageous when the comparison of elements in <C>list</C> is expensive, e. g., when these elements are conjugacy classes in a group.
<Ignore Remark="gapfilecomments"><![CDATA[ ############################################################################# ## #A UnorderedTuplesNoSort( <list>, <k> ) ## ## Let <list> be a dense list and <k> be a nonnegative integer. ## `UnorderedTuplesNoSort' returns a list of all unordered <k>-tuples with ## repetitions of elements in <list>. ## The only difference to the GAP library function `UnorderedTuples' is ## that the entries in the result of `UnorderedTuplesNoSort' need not be ## sorted. ## This is advantageous when the comparison of elements in <list> is ## expensive, e.~g., when these elements are conjugacy classes in a group. ## ]]></Ignore> <Example><![CDATA[ gap> BindGlobal( "UnorderedTuplesNoSort", function( list, k ) > return List( UnorderedTuples( [ 1 .. Length( list ) ], k ), > tuple -> list{ tuple } ); > end ); ]]></Example>
-->
The following two functions implement loops over ordered triples
(and quadruples, respectively) in a Cartesian product.
A prescribed function <C>prop</C> is subsequently applied to the triples
(quadruples),
and if the result of this call is <K>true</K> then this triple (quadruple)
is returned immediately;
if none of the calls to <C>prop</C> yields <K>true</K> then <K>fail</K>
is returned.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F TripleWithProperty( <threelists>, <prop> )
#F QuadrupleWithProperty( <fourlists>, <prop> )
##
## Let <threelists> be a list of three lists $l_1, l_2, l_3$,
## and <prop> be a unary function that takes a triple $[ x_1, x_2, x_3 ]$
## with $x_i \in l_i$ as its argument and returns either `true' or `false'.
## `TripleWithProperty' returns a triple for which `prop' returns `true'
## if such a triple exists, and `fail' otherwise.
##
## Analogously, the first argument of `QuadrupleWithProperty' is a list
## <fourlists> of four lists, and the second argument <prop> takes a
## quadruple as its argument.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "TripleWithProperty", function( threelists, prop )
> local i, j, k, test;
>
> for i in threelists[1] do
> for j in threelists[2] do
> for k in threelists[3] do
> test:= [ i, j, k ];
> if prop( test ) then
> return test;
> fi;
> od;
> od;
> od;
>
> return fail;
> end );
gap> BindGlobal( "QuadrupleWithProperty", function( fourlists, prop )
> local i, j, k, l, test;
>
> for i in fourlists[1] do
> for j in fourlists[2] do
> for k in fourlists[3] do
> for l in fourlists[4] do
> test:= [ i, j, k, l ];
> if prop( test ) then
> return test;
> fi;
> od;
> od;
> od;
> od;
>
> return fail;
> end );
]]></Example>
<P/>
Of course one could do better by considering <E>un</E>ordered <M>n</M>-tuples
when several of the argument lists are equal,
and in practice, backtrack searches would often allow one to prune parts
of the search tree in early stages.
However, the above loops are not time critical in the examples presented
here, so the possible improvements are not worth the effort for our
purposes.
<P/>
The function <C>PrintFormattedArray</C> prints the matrix <C>array</C>
in a columnwise formatted way.
(The only diference to the &GAP; library function
<Ref Func="PrintArray" BookName="ref"/> is that
<C>PrintFormattedArray</C> chooses each column width according to the entries
only in this column not w.r.t. the whole matrix.)
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F PrintFormattedArray( <array> )
##
## Let <array> be a rectangular table.
## `PrintFormattedArray' prints such that each column is right
## aligned.
## The only difference to the GAP library function `PrintArray'
## is that the latter prints all columns at the same width.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "PrintFormattedArray", function( array )
> local colwidths, n, row;
> array:= List( array, row -> List( row, String ) );
> colwidths:= List( TransposedMat( array ),
> col -> Maximum( List( col, Length ) ) );
> n:= Length( array[1] );
> for row in List( array, row -> List( [ 1 .. n ],
> i -> String( row[i], colwidths[i] ) ) ) do
> Print( " ", JoinStringsWithSeparator( row, " " ), "\n" );
> od;
> end );
]]></Example>
<P/>
Finally, <C>CleanWorkspace</C> is a utility for reducing the space needed.
This is achieved by unbinding those user variables
that are not write protected and are not mentioned in the list
<C>NeededVariables</C> of variable names that are bound now,
and by flushing the caches of tables of marks and character tables.
<!-- %T In a forthcoming version, flushing these caches should become easier. -->
<P/>
<Example><![CDATA[
gap> BindGlobal( "NeededVariables", NamesUserGVars() );
gap> BindGlobal( "CleanWorkspace", function()
> local name, record;
>
> for name in Difference( NamesUserGVars(), NeededVariables ) do
> if not IsReadOnlyGlobal( name ) then
> UnbindGlobal( name );
> fi;
> od;
> for record in [ LIBTOMKNOWN, LIBTABLE ] do
> for name in RecNames( record.LOADSTATUS ) do
> Unbind( record.LOADSTATUS.( name ) );
> Unbind( record.( name ) );
> od;
> od;
> end );
]]></Example>
<P/>
The function <C>PossiblePermutationCharacters</C> takes two ordinary character
tables <C>sub</C> and <C>tbl</C>,
computes the possible class fusions from <C>sub</C> to <C>tbl</C>,
then induces the trivial character of <C>sub</C> to <C>tbl</C>, w.r.t. these fusions,
and returns the set of these class functions.
(So if <C>sub</C> and <C>tbl</C> are the character tables of groups <M>H</M> and <M>G</M>,
respectively, where <M>H</M> is a subgroup of <M>G</M>,
then the result contains the permutation character <M>1_H^G</M>.)
<P/>
Note that the columns of the character tables
in the &GAP; Character Table Library
are not explicitly associated with particular conjugacy classes of the
corresponding groups,
so from the character tables,
we can compute only <E>possible</E> class fusions,
i.e., maps between the columns of two tables that satisfy certain
necessary conditions, see the section about the function
<C>PossibleClassFusions</C> in the &GAP; Reference Manual for details.
There is no problem if the permutation character is uniquely determined
by the character tables, in all other cases we give ad hoc arguments
for resolving the ambiguities.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F PossiblePermutationCharacters( <sub>, <tbl> )
##
## For two ordinary character tables <sub> and <tbl>,
## `PossiblePermutationCharacters' returns the set of all induced class
## functions of the trivial character of <sub> to <tbl>,
## w.r.t.~the possible class fusions from <sub> to <tbl>.
##
]]></Ignore>
<Example><![CDATA[
gap> if not IsBound( PossiblePermutationCharacters ) then
> BindGlobal( "PossiblePermutationCharacters", function( sub, tbl )
> local fus, triv;
>
> fus:= PossibleClassFusions( sub, tbl );
> if fus = fail then
> return fail;
> fi;
> triv:= [ TrivialCharacter( sub ) ];
>
> return Set(
> List( fus, map -> Induced( sub, tbl, triv, map )[1] ) );
> end );
> fi;
]]></Example>
We want to use the &GAP; libraries of character tables
and of tables of marks, and proceed in three steps.
<P/>
First we extract the primitive permutation characters from the library
information if this is available;
for that, we write the function <C>PrimitivePermutationCharacters</C>.
Then the result can be used as the input for the function <C>ApproxP</C>,
which computes the values <M>&total;( g, s )</M>.
Finally,
the functions <C>ProbGenInfoSimple</C> and <C>ProbGenInfoAlmostSimple</C>
compute <M>&sprtotal;( G )</M>.
<P/>
For a group <M>G</M> whose character table <M>T</M> is contained in the &GAP;
character table library, the complete set of primitive permutation
characters can be easily computed if the character tables of all maximal
subgroups and their class fusions into <M>T</M> are known
(in this case, we check whether the attribute
<Ref Attr="Maxes" BookName="ctbllib"/> of <M>T</M> is bound)
or if the table of marks of <M>G</M> and the class fusion from <M>T</M> into this
table of marks are known
(in this case, we check whether the attribute
<Ref Attr="FusionToTom" BookName="ctbllib"/> of <M>T</M> is bound).
If the attribute <Ref Attr="UnderlyingGroup" BookName="ref"/> of <M>T</M>
is bound then this group
can be used to compute the primitive permutation characters.
The latter happens if <M>T</M> was computed from the group object in &GAP;;
for tables in the &GAP; character table library,
this is not the case by default.
<P/>
The &GAP; function <C>PrimitivePermutationCharacters</C> tries to compute
the primitive permutation characters of a group using this information;
it returns the required list of characters if this can be computed this way,
otherwise <K>fail</K> is returned.
(For convenience, we use the &GAP; mechanism of <E>attributes</E>
in order to store the permutation characters in the character table object
once they have been computed.)
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#A PrimitivePermutationCharacters( <tbl> )
##
## For an ordinary character table <tbl> for which either the value of one
## of the attributes `Maxes' or `UnderlyingGroup' is stored or the table of
## marks is contained in the GAP library of tables of marks,
## `PrimitivePermutationCharacters' returns the list of all primitive
## permutation characters of <tbl>.
## Otherwise `fail' is returned.
##
## We use 'InstallOtherMethod' not 'InstallMethod' because another test file
## declares the same attribute and installs the same method.
##
]]></Ignore>
<Example><![CDATA[
gap> DeclareAttribute( "PrimitivePermutationCharacters",
> IsCharacterTable );
gap> InstallOtherMethod( PrimitivePermutationCharacters,
> [ IsCharacterTable ],
> function( tbl )
> local maxes, i, fus, poss, tom, G;
>
> if HasMaxes( tbl ) then
> maxes:= List( Maxes( tbl ), CharacterTable );
> for i in [ 1 .. Length( maxes ) ] do
> fus:= GetFusionMap( maxes[i], tbl );
> if fus = fail then
> fus:= PossibleClassFusions( maxes[i], tbl );
> poss:= Set( fus,
> map -> InducedClassFunctionsByFusionMap(
> maxes[i], tbl,
> [ TrivialCharacter( maxes[i] ) ], map )[1] );
> if Length( poss ) = 1 then
> maxes[i]:= poss[1];
> else
> return fail;
> fi;
> else
> maxes[i]:= TrivialCharacter( maxes[i] )^tbl;
> fi;
> od;
> return maxes;
> elif HasFusionToTom( tbl ) then
> tom:= TableOfMarks( tbl );
> maxes:= MaximalSubgroupsTom( tom );
> return PermCharsTom( tbl, tom ){ maxes[1] };
> elif HasUnderlyingGroup( tbl ) then
> G:= UnderlyingGroup( tbl );
> return List( MaximalSubgroupClassReps( G ),
> M -> TrivialCharacter( M )^tbl );
> fi;
>
> return fail;
> end );
]]></Example>
<P/>
The function <C>ApproxP</C> takes a list <C>primitives</C>
of primitive permutation characters of a group <M>G</M>, say,
and the position <C>spos</C> of the class <M>s^G</M> in the character table
of <M>G</M>.
<P/>
Assume that the elements in <C>primitives</C> have the form <M>1_M^G</M>,
for suitable maximal subgroups <M>M</M> of <M>G</M>,
and let <M>&MM;</M> be the set of these groups <M>M</M>.
<C>ApproxP</C> returns the class function <M>\psi</M> of <M>G</M>
that is defined by <M>\psi(1) = 0</M> and
If <C>primitives</C> contains all those primitive permutation characters <M>1_M^G</M>
of <M>G</M> (with multiplicity according to the number of conjugacy classes
of these maximal subgroups) that do not vanish at <M>s</M>,
and if all these <M>M</M> are self-normalizing in <M>G</M>
–this holds for example if <M>G</M> is a finite simple group–
then <M>\psi(g) = &total;( g, s )</M> holds.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F ApproxP( <primitives>, <spos> )
##
## Let <primitives> be a list of primitive permutation characters of a group
## $G$, say, and <spos> the position of the conjugacy class of the element
## $s \in G$.
## Assume that the elements in <primitives> have the form $1_M^G$,
## for suitable maximal subgroups $M$ of $G$,
## and let $\MM$ be the set of these groups $M$.
## `ApproxP' returns the class function $\psi$ of $G$ that is defined by
## $\psi(1) = 0$ and
## \[
## \psi(g) = \sum_{M \in \MM}
## \frac{1_M^G(s) \cdot 1_M^G(g)}{1_M^G(1)}
## \]
## otherwise.
##
## If <primitives> contains all those primitive permutation characters
## $1_M^G$ of $G$ (with multiplicity according to the number of conjugacy
## classes of these maximal subgroups) that do not vanish at $s$,
## and if all these $M$ are self-normalizing in $G$
## --this holds for example if $G$ is a finite simple group--
## then $\psi(g) = &total;( g, s )$ holds.
##
## The latter is an upper bound for the proportion
## $∝( g, s )$ of elements in the conjugacy class of $s$ that generate
## together with $g$ a proper subgroup of $G$.
##
## Note that if $∝( g, s )$ is less than $1/k$ for all
## $g \in G^{\times}$ then $G$ has spread at least $k$.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "ApproxP", function( primitives, spos )
> local sum;
>
> sum:= ShallowCopy( Sum( List( primitives,
> pi -> pi[ spos ] * pi / pi[1] ) ) );
> sum[1]:= 0;
>
> return sum;
> end );
]]></Example>
<P/>
Note that for computations with permutation characters,
it would make the functions more complicated (and not more efficient)
if we would consider only elements <M>g</M> of prime order,
and only one representative of Galois conjugate classes.
<P/>
The next functions needed in this context compute <M>&total;(S)</M> and
<M>&sprtotal;( S )</M>, for a simple group <M>S</M>,
and <M>&total;^{\prime}(G,s)</M> for an almost simple group <M>G</M>
with socle <M>S</M>, respectively.
<P/>
<C>ProbGenInfoSimple</C> takes the character table <C>tbl</C> of <M>S</M>
as its argument.
If the full list of primitive permutation characters of <M>S</M> cannot be
computed with <C>PrimitivePermutationCharacters</C> then the function returns
<K>fail</K>.
Otherwise <C>ProbGenInfoSimple</C> returns a list containing
the identifier of the table,
the value <M>&total;(S)</M>,
the integer <M>&sprtotal;( S )</M>,
a list of &ATLAS; names of representatives of Galois families of those
classes of elements <M>s</M> for which <M>&total;(S) = &total;( S, s )</M> holds,
and the list of the corresponding cardinalities <M>|&M;(S,s)|</M>.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F ProbGenInfoSimple( <tbl> )
##
## Let <tbl> be the ordinary character table of a finite simple group $S$.
## If the full list of primitive permutation characters of <tbl> cannot be
## computed with `PrimitivePermutationCharacters' then `fail' is returned.
## Otherwise `ProbGenInfoSimple' returns a list of length $5$, containing
## the identifier of <tbl>,
## the value $&total;(S)$,
## the value $\sprtotal( S )$,
## a list of {\ATLAS} names of the classes of elements $s$ for which
## $&total;(S) = &total;( S, s )$ holds,
## and the list of the corresponding cardinalities $|&M;(S,s)|$.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "ProbGenInfoSimple", function( tbl )
> local prim, max, min, bound, s;
> prim:= PrimitivePermutationCharacters( tbl );
> if prim = fail then
> return fail;
> fi;
> max:= List( [ 1 .. NrConjugacyClasses( tbl ) ],
> i -> Maximum( ApproxP( prim, i ) ) );
> min:= Minimum( max );
> bound:= Inverse( min );
> if IsInt( bound ) then
> bound:= bound - 1;
> else
> bound:= Int( bound );
> fi;
> s:= PositionsProperty( max, x -> x = min );
> s:= List( Set( s, i -> ClassOrbit( tbl, i ) ), i -> i[1] );
> return [ Identifier( tbl ),
> min,
> bound,
> AtlasClassNames( tbl ){ s },
> Sum( List( prim, pi -> pi{ s } ) ) ];
> end );
]]></Example>
<P/>
<C>ProbGenInfoAlmostSimple</C> takes the character tables <C>tblS</C> and
<C>tblG</C> of <M>S</M> and <M>G</M>,
and a list <C>sposS</C> of class positions (w.r.t. <C>tblS</C>)
as its arguments.
It is assumed that <M>S</M> is simple and has prime index in <M>G</M>.
If <C>PrimitivePermutationCharacters</C> can compute the full list
of primitive permutation characters of <M>G</M> then the function returns
a list containing
the identifier of <C>tblG</C>,
the maximum <M>m</M> of <M>&total;^{\prime}( G, s )</M>,
for <M>s</M> in the classes described by <C>sposS</C>,
a list of &ATLAS; names (in <M>G</M>) of the classes of elements <M>s</M>
for which this maximum is attained,
and the list of the corresponding cardinalities <M>|&M;^{\prime}(G,s)|</M>.
When <C>PrimitivePermutationCharacters</C> returns <K>fail</K>,
also <C>ProbGenInfoAlmostSimple</C> returns <K>fail</K>.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F ProbGenInfoAlmostSimple( <tblS>, <tblG>, <sposS> )
##
## Let <tblS> be the ordinary character table of a finite simple group $S$,
## <tblG> be the character table of an automorphic extension $G$ of $S$
## in which $S$ has prime index,
## and <sposS> a list of class positions in <tblS>.
##
## If the full list of primitive permutation characters of <tblG> cannot be
## computed with `PrimitivePermutationCharacters' then `fail' is returned.
## Otherwise `ProbGenInfoAlmostSimple' returns a list of length five,
## containing
## the identifier of <tblG>,
## the maximum $m$ of $&total;^{\prime}( G, s )$,
## for $s$ in the classes described by <sposS>,
## a list of {\ATLAS} names (w.r.t. $G$) of the classes of elements $s$
## for which this maximum is attained,
## and the list of the corresponding cardinalities $|\M^{\prime}(G,s)|$.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "ProbGenInfoAlmostSimple", function( tblS, tblG, sposS )
> local p, fus, inv, prim, sposG, outer, approx, l, max, min,
> s, cards, i, names;
>
> p:= Size( tblG ) / Size( tblS );
> if not IsPrimeInt( p )
> or Length( ClassPositionsOfNormalSubgroups( tblG ) ) <> 3 then
> return fail;
> fi;
> fus:= GetFusionMap( tblS, tblG );
> if fus = fail then
> return fail;
> fi;
> inv:= InverseMap( fus );
> prim:= PrimitivePermutationCharacters( tblG );
> if prim = fail then
> return fail;
> fi;
> sposG:= Set( fus{ sposS } );
> outer:= Difference( PositionsProperty(
> OrdersClassRepresentatives( tblG ), IsPrimeInt ), fus );
> approx:= List( sposG, i -> ApproxP( prim, i ){ outer } );
> if IsEmpty( outer ) then
> max:= List( approx, x -> 0 );
> else
> max:= List( approx, Maximum );
> fi;
> min:= Minimum( max);
> s:= sposG{ PositionsProperty( max, x -> x = min ) };
> cards:= List( prim, pi -> pi{ s } );
> for i in [ 1 .. Length( prim ) ] do
> # Omit the character that is induced from the simple group.
> if ForAll( prim[i], x -> x = 0 or x = prim[i][1] ) then
> cards[i]:= 0;
> fi;
> od;
> names:= AtlasClassNames( tblG ){ s };
> Perform( names, ConvertToStringRep );
>
> return [ Identifier( tblG ),
> min,
> names,
> Sum( cards ) ];
> end );
]]></Example>
<P/>
The next function computes <M>&total;(G,s)</M> from
the character table <C>tbl</C> of a simple or almost simple group <M>G</M>,
the name <C>sname</C> of the class of <M>s</M> in this table,
the list <C>maxes</C> of the character tables of all subgroups <M>M</M>
with <M>M \in &M;(G,s)</M>,
and the list <C>numpermchars</C> of the numbers of possible permutation characters
induced from <C>maxes</C>.
If the string <C>"outer"</C> is given as an optional argument then <M>G</M> is assumed
to be an automorphic extension of a simple group <M>S</M>, with <M>[G:S]</M> a prime,
and <M>&total;^{\prime}(G,s)</M> is returned.
In both situations,
the result is <K>fail</K> if the numbers of possible permutation characters
induced from <C>maxes</C> do not coincide with the numbers prescribed in
<C>numpermchars</C>.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F SigmaFromMaxes( <tbl>, <sname>, <maxes>, <numpermchars> )
#F SigmaFromMaxes( <tbl>, <sname>, <maxes>, <numpermchars>, <choice> )
##
## Let <tbl> be the ordinary character table of a finite almost simple group
## $G$ with socle $S$,
## <sname> be the name of a class in <tbl>,
## <maxes> be a list of character tables of all those maximal subgroups
## of $G$ which contain elements $s$ in the class with the name <sname>.
## Further let <numpermchars> be a list of integers such that the $i$-th
## entry in <maxes> induces `<numpermchars>[i]' different permutation
## characters.
## (So if several classes of maximal subgroups in $G$ induce the same
## permutation character then the table of this subgroup must occur with
## this multiplicity in <maxes>, and the corresponding entries in
## <numpermchars> must be $1$.
## Conversely, if there are $n$ classes of isomorphic maximal subgroups
## which induce $n$ different permutation characters then the table must
## occur only once in <maxes>, and the corresponding multiplicity in
## <numpermchars> must be $n$.)
##
## The return value is `fail' if there is an entry `[i]' such that
## `PossiblePermutationCharacters' does not return a list of length
## `<numpermchars>[i]' when its arguments are `[i]' and <tbl>.
##
## If the string `"outer"' is entered as the optional argument then
## $G$ is assumed to be an automorphic extension of $S$,
## with $[G:S]$ a prime,
## and $&total;^{\prime}(G,s)$ is returned.
##
## Otherwise `SigmaFromMaxes' returns $&total;(G,s)$.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "SigmaFromMaxes", function( arg )
> local t, sname, maxes, numpermchars, prim, spos, outer;
>
> t:= arg[1];
> sname:= arg[2];
> maxes:= arg[3];
> numpermchars:= arg[4];
> prim:= List( maxes, s -> PossiblePermutationCharacters( s, t ) );
> spos:= Position( AtlasClassNames( t ), sname );
> if ForAny( [ 1 .. Length( maxes ) ],
> i -> Length( prim[i] ) <> numpermchars[i] ) then
> return fail;
> elif Length( arg ) = 5 and arg[5] = "outer" then
> outer:= Difference(
> PositionsProperty( OrdersClassRepresentatives( t ), IsPrimeInt ),
> ClassPositionsOfDerivedSubgroup( t ) );
> return Maximum( ApproxP( Concatenation( prim ), spos ){ outer } );
> else
> return Maximum( ApproxP( Concatenation( prim ), spos ) );
> fi;
> end );
]]></Example>
<P/>
The following function allows us to extract information about <M>&M;(G,s)</M>
from the character table <C>tbl</C> of <M>G</M> and a list <C>snames</C>
of class positions of <M>s</M>.
If <C>Maxes( tbl )</C> is stored then the names of the character tables of the
subgroups in <M>&M;(G,s)</M> and the number of conjugates are printed,
otherwise <K>fail</K> is printed.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F DisplayProbGenMaxesInfo( <tbl>, <snames> )
##
## For a character table <tbl> with known `Maxes' value and a list
## of class names in <tbl>,
## `DisplayProbGenMaxesInfo' prints a description of the maximal subgroups
## of <tbl> that contain an element $s$ in the classes with names in the
## list <snames>.
## Printed are the `Identifier' values of the tables of the maximal
## subgroups and the number of conjugate subgroups in this class
## that contain $s$.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "DisplayProbGenMaxesInfo", function( tbl, snames )
> local mx, prim, i, spos, nonz, indent, j;
>
> if not HasMaxes( tbl ) then
> Print( Identifier( tbl ), ": fail\n" );
> return;
> fi;
>
> # Now we are sure that the order of the characters returned by
> # 'PrimitivePermutationCharacters' is compatible with 'Maxes( tbl )'.
> mx:= List( Maxes( tbl ), CharacterTable );
> prim:= List( PrimitivePermutationCharacters( tbl ), ShallowCopy );
> for i in [ 1 .. Length( prim ) ] do
> # Deal with the case that the subgroup is normal.
> if ForAll( prim[i], x -> x = 0 or x = prim[i][1] ) then
> prim[i]:= prim[i] / prim[i][1];
> fi;
> od;
>
> spos:= List( snames,
> nam -> Position( AtlasClassNames( tbl ), nam ) );
> nonz:= List( spos, x -> PositionsProperty( prim, pi -> pi[x] <> 0 ) );
> for i in [ 1 .. Length( spos ) ] do
> Print( Identifier( tbl ), ", ", snames[i], ": " );
> indent:= ListWithIdenticalEntries(
> Length( Identifier( tbl ) ) + Length( snames[i] ) + 4, ' ' );
> if not IsEmpty( nonz[i] ) then
> Print( Identifier( mx[ nonz[i][1] ] ), " (",
> prim[ nonz[i][1] ][ spos[i] ], ")\n" );
> for j in [ 2 .. Length( nonz[i] ) ] do
> Print( indent, Identifier( mx[ nonz[i][j] ] ), " (",
> prim[ nonz[i][j] ][ spos[i] ], ")\n" );
> od;
> else
> Print( "\n" );
> fi;
> od;
> end );
]]></Example>
</Subsection>
<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Subsection Label="subsect:groups">
<Heading>Computations with Groups</Heading>
Here, the task is to compute <M>∝(g,s)</M> or <M>∝(G,s)</M>
using explicit computations with <M>G</M>,
where the character-theoretic bounds are not sufficient.
<P/>
We start with small utilities that make the examples shorter.
<P/>
For a finite solvable group <C>G</C>,
the function <C>PcConjugacyClassReps</C> returns a list of representatives of
the conjugacy classes of <C>G</C>,
which are computed using a polycyclic presentation for <C>G</C>.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F PcConjugacyClassReps( <G> )
##
## Let <G> be a finite solvable group.
## `PcConjugacyClassReps' returns a list of representatives of
## the conjugacy classes of <G>,
## which are computed using a polycyclic presentation for <G>.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "PcConjugacyClassReps", function( G )
> local iso;
>
> iso:= IsomorphismPcGroup( G );
> return List( ConjugacyClasses( Image( iso ) ),
> c -> PreImagesRepresentative( iso, Representative( c ) ) );
> end );
]]></Example>
<P/>
For a finite group <C>G</C>, a list <C>primes</C> of prime integers,
and a normal subgroup <C>N</C> of <C>G</C>,
the function <C>ClassesOfPrimeOrder</C> returns a list of those
conjugacy classes of <C>G</C>
that are not contained in <C>N</C> and whose elements' orders occur
in <C>primes</C>.
<P/>
For each prime <M>p</M> in <C>primes</C>,
first class representatives of order <M>p</M>
in a Sylow <M>p</M> subgroup of <C>G</C> are computed,
then the representatives in <C>N</C> are discarded,
and then representatives w. r. t. conjugacy in <C>G</C>
are computed.
<P/>
<!-- % Note that we do not call 'IsConjugate' but create the conjugacy classes % of the two elements in question, and then ask for equality, % since the latter is much faster --don't ask why. % Also, we do not first create the list of conjugacy classes % of all elements in question, and then compare the classes in this list % (using the very elegant 'DuplicateFreeList'), % because then the required memory would be too large: % There are cases where more than 1000 elements must be processed, % and the comparison causes the centralizer of the representative % to be stored in the class object.
-->
(Note that this approach may be inappropriate
for example if a large elementary abelian Sylow <M>p</M> subgroup occurs,
and if the conjugacy tests in <C>G</C> are expensive,
see Section <Ref Subsect="O8p4"/>.)
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F ClassesOfPrimeOrder( <G>, <primes>, <N> )
##
## Let <G> be a finite group, <primes> be a list of primes,
## and <N> be a normal subgroup of <G>.
## `ClassesOfPrimeOrder' returns a list of those conjugacy classes of
## that are not contained in <N>
## and whose elements' orders occur in .
##
## For each prime $p$ in <primes>, first class representatives of order $p$
## in a Sylow $p$ subgroup of <G> are computed,
## then the representatives in <N> are discarded,
## and then representatives w. r. t. conjugacy in <G> are computed.
##
## (Note that this approach may be inappropriate if an elementary abelian
## Sylow $p$ subgroup for a large prime $p$ occurs, and if the conjugacy
## tests in <G> are expensive.)
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "ClassesOfPrimeOrder", function( G, primes, N )
> local ccl, p, syl, Greps, reps, r, cr;
>
> ccl:= [];
> for p in primes do
> syl:= SylowSubgroup( G, p );
> Greps:= [];
> reps:= Filtered( PcConjugacyClassReps( syl ),
> r -> Order( r ) = p and not r in N );
> for r in reps do
> cr:= ConjugacyClass( G, r );
> if ForAll( Greps, c -> c <> cr ) then
> Add( Greps, cr );
> fi;
> od;
> Append( ccl, Greps );
> od;
>
> return ccl;
> end );
]]></Example>
<P/>
The function <C>IsGeneratorsOfTransPermGroup</C> takes a
<E>transitive</E> permutation group <C>G</C> and a list <C>list</C>
of elements in <C>G</C>,
and returns <K>true</K> if the elements in <C>list</C> generate <C>G</C>,
and <K>false</K> otherwise.
The main point is that the return value <K>true</K> requires the group
generated by <C>list</C> to be transitive, and the check for transitivity
is much cheaper than the test whether this group is equal to <C>G</C>.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F IsGeneratorsOfTransPermGroup( <G>, <list> )
##
## Let <G> be a finite group that acts *transitively* on its moved points,
## and <list> a list of elements in <G>.
##
## `IsGeneratorsOfTransPermGroup' returns `true' if the elements in <list>
## generate <G>, and `false' otherwise.
## The main point is that the return value `true' requires the group
## generated by `list' to be transitive, and the check for transitivity
## is much cheaper than the test whether this group is equal to `G'.
##
]]></Ignore>
<Example><![CDATA[
gap> if not IsBound( IsGeneratorsOfTransPermGroup) then
> BindGlobal( "IsGeneratorsOfTransPermGroup", function( G, list )
> local S;
>
> if not IsTransitive( G ) then
> Error( " must be transitive on its moved points" );
> fi;
> S:= SubgroupNC( G, list );
>
> return IsTransitive( S, MovedPoints( G ) ) and
> Size( S ) = Size( G );
> end );
> fi;
]]></Example>
<P/>
<C>RatioOfNongenerationTransPermGroup</C> takes a <E>transitive</E> permutation
group <C>G</C> and two elements <C>g</C> and <C>s</C> of <C>G</C>,
and returns the proportion <M>∝(g,s)</M>.
(The function tests the (non)generation only for representatives of
<M>C_G(g)</M>-<M>C_G(s)</M>-double cosets.
Note that for <M>c_1 \in C_G(g)</M>, <M>c_2 \in C_G(s)</M>,
and a representative <M>r \in G</M>,
we have <M>\langle g^{c_1 r c_2}, s \rangle = \langle g^r, s \rangle^{c_2}</M>.)
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F RatioOfNongenerationTransPermGroup( <G>, <g>, <s> )
##
## Let <G> be a finite group that acts *transitively* on its moved points,
## and <g> and <s> be two elements in <G>.
##
## `RatioOfNongenerationTransPermGroup' returns the proportion
## $∝(g,s)$.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "RatioOfNongenerationTransPermGroup", function( G, g, s )
> local nongen, pair;
>
> if not IsTransitive( G ) then
> Error( " must be transitive on its moved points" );
> fi;
> nongen:= 0;
> for pair in DoubleCosetRepsAndSizes( G, Centralizer( G, g ),
> Centralizer( G, s ) ) do
> if not IsGeneratorsOfTransPermGroup( G, [ s, g^pair[1] ] ) then
> nongen:= nongen + pair[2];
> fi;
> od;
>
> return nongen / Size( G );
> end );
]]></Example>
<P/>
Let <M>G</M> be a group,
and let <C>groups</C> be a list <M>[ G_1, G_2, \ldots, G_n ]</M>
of permutation groups such that <M>G_i</M> describes the action of <M>G</M>
on a set <M>\Omega_i</M>, say.
Moreover, we require that for <M>1 \leq i, j \leq n</M>,
mapping the <C>GeneratorsOfGroup</C> list of <M>G_i</M> to that of <M>G_j</M>
defines an isomorphism.
<C>DiagonalProductOfPermGroups</C> takes <C>groups</C> as its argument,
and returns the action of <M>G</M> on the disjoint union of
<M>\Omega_1, \Omega_2, \ldots, \Omega_n</M>.
<P/>
<Ignore Remark="gapfilecomments"><![CDATA[
#############################################################################
##
#F DiagonalProductOfPermGroups( <groups> )
##
## Let $G$ be a group, and let <groups> be a list
## $[ G_1, G_2, \ldots, G_n ]$ of permutation groups such that $G_i$
## describes the action of $G$ on a set $\Omega_i$, say.
## Moreover, we require that for $1 \leq i, j \leq n$,
## mapping the `GeneratorsOfGroup' list of $G_i$ to that of $G_j$
## defines an isomorphism.
##
## `DiagonalProductOfPermGroups' takes `groups' as its argument,
## and returns the action of $G$ on the disjoint union of
## $\Omega_1, \Omega_2, \ldots \Omega_n$.
##
]]></Ignore>
<Example><![CDATA[
gap> BindGlobal( "DiagonalProductOfPermGroups", function( groups )
> local prodgens, deg, i, gens, D, pi;
>
> prodgens:= GeneratorsOfGroup( groups[1] );
> deg:= NrMovedPoints( prodgens );
> for i in [ 2 .. Length( groups ) ] do
> gens:= GeneratorsOfGroup( groups[i] );
> D:= MovedPoints( gens );
> pi:= MappingPermListList( D, [ deg+1 .. deg+Length( D ) ] );
> deg:= deg + Length( D );
> prodgens:= List( [ 1 .. Length( prodgens ) ],
> i -> prodgens[i] * gens[i]^pi );
> od;
>
> return Group( prodgens );
--> --------------------
--> maximum size reached
--> --------------------
¤ Dauer der Verarbeitung: 0.73 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.