# Some steps in the verification of the ordinary character table of the Monster group

### THOMAS BREUER, KAY MAGAARD, ROBERT A. WILSON

### July 24th, 2020

We show the details of certain computations that are used in [BMW20b].

# Contents

1 Overview
2 Some restrictions of the natural character of M
3 The permutation character (12.BM)2.B
4 The conjugacy classes of M
4.1 Our strategy to describe the conjugacy classes of M
4.2 Utility functions
4.3 Classes of elements of even order
4.4 Classes of elements of order divisible by 3
4.5 Classes of elements of order divisible by 5
4.6 Classes of elements of order divisible by 11
4.7 Classes of elements of the orders 17, 19, 23, 31, 47
4.8 Classes of elements of order 13
4.9 Classes of elements of order divisible by 29
4.10 Classes of elements of order divisible by 41
4.11 Classes of elements of order divisible by 59
4.12 Classes of elements of order divisible by 71
4.13 Classes of elements of order divisible by 7
5 The power maps of M
6 The degree 196 883 character χ of M
7 The irreducible characters of M
8 Appendix: The character table of 21+24.Co1
9 Appendix: The character table of 31+12.6.Suz.2
9.1 Overview
9.2 Permutation representations of H / E and H / X
9.3 A permutation representation of H / Y
9.4 A permutation representation of H
9.5 Class representatives of H / Y
9.5.1 Class representatives of Suz.2
9.5.2 Class representatives of 6.Suz.2
9.5.3 Class representatives of H / Y
9.6 Class representatives of H
9.7 The character table of H / Y
9.8 The class fusions from H to H / X, H / D1, and H / D2
9.9 The character table head of H
9.10 The character table of 31+12:(2 ×U5(2).2)
9.11 Complete the character table of H
10 Appendix: The character table of 51+6+.4.J2.2

## 1 Overview

The aim of [BMW20b] is to verify the ordinary character table of the Monster group M. Here we collect, in the form of an explicit and reproducible GAP [GAP21] session protocol, the computations that are needed in that paper.
We proceed as follows.
Section 2 verifies the decomposition of the restrictions of the ordinary irreducible character of degree 196 883 of M to the subgroups 2.B and 3.Fi24′ (and 3.Fi24), as stated in [BMW20b,Lemma 1].
Section 3 verifies the decompositions of the transitive constituents of the permutation character of the action of CM(a) ≅ 2.B on the conjugacy class aM, where a is a `2A` involution in M.
Sections 4 and 5 construct the character table head of M, that is, the lists of conjugacy class lengths, element orders, and power maps.
Section 6 constructs the values of the irreducible degree 196 883 character of M.
With this information and with the (already verified) character tables of the subgroups 2.B, 21+24.Co1, 3.Fi24, and 31+12.2.Suz.2 of M, computing the irreducible characters of M is then easy; this corresponds to [BMW20b,Section 5] and is done in Section 7.
We will use the GAP Character Table Library and the interface to the ATLAS of Group Representations [WWT+], thus we load these GAP packages.

        gap> LoadPackage( "ctbllib", false );
        true
        gap> LoadPackage( "atlasrep", false );
        true

The MAGMA system [BCP97] will be needed for computing some character tables and for many conjugacy tests. If the following command returns `false` then these steps will not work.

        gap> CTblLib.IsMagmaAvailable();
        true

We set the line length to 72, like in other standard testfiles.

        gap> SizeScreen( [ 72 ] );;

## 2 Some restrictions of the natural character of M

We assume the existence of an ordinary irreducible character χ of degree 196 883 of the Monster group M, and that M has only two conjugacy classes of involutions.
First we compute the restriction of χ to 2.B.
The only faithful degree 196 883 character of 2.B that has at most two different values on involutions is 1a + 4371a + 96255a + 96256a, as claimed in [BMW20b,Lemma 1]. This follows from the following data about 2.B.

        gap> table2B:= CharacterTable( "2.B" );;
        gap> cand:= Filtered( Irr( table2B ), x -> x[1] <= 196883 );;
        gap> List( cand, x -> x[1] );
        [ 1, 4371, 96255, 96256 ]
        gap> inv:= Positions( OrdersClassRepresentatives( table2B ), 2 );
        [ 2, 3, 4, 5, 7 ]
        gap> PrintArray( List( cand, x -> x{ Concatenation( [ 1 ], inv ) } ) );
        [ [       1,       1,       1,       1,       1,       1 ],
          [    4371,    4371,    -493,     275,     275,      19 ],
          [   96255,   96255,    4863,    2047,    2047,     255 ],
          [   96256,  -96256,       0,    2048,   -2048,       0 ] ]

Note that 96256a must occur as a constituent because it is the only faithful candidate, and it can occur only once because otherwise only 4371a + 2 ·96256a or 4371 ·1a + 2 ·96256a would be possible decompositions, which have more than two values on involution classes. Thus the values of χ2.B on the classes 4 and 5 differ by 4096.
If 96255a would not occur then the values of χ2.B on the classes 3 and 7 would differ by 512 times the multiplicity of 4371, but 65659 ·1a + 8 ·4371a + 96256a is not a solution. Thus 96255a must occur exactly once.
The sum of 96255a and 96256a has four different values on involutions, hence also 4371a must occur.
We see that the values of χ on the classes of involutions are 4371 and 275, respectively.

        gap> Sum( cand ){ inv };
        [ 4371, 4371, 4371, 275, 275 ]

The restriction of χ to 3.Fi24′ is computed similarly, as follows.
Exactly seven irreducible characters of 3.Fi24′ can occur as constituents of the restriction of χ.

        gap> table3Fi24prime:= CharacterTable( "3.Fi24'" );;
        gap> cand:= Filtered( Irr( table3Fi24prime ), x -> x[1] <= 196883 );;
        gap> inv:= Positions( OrdersClassRepresentatives( table3Fi24prime ), 2 );
        [ 4, 7 ]
        gap> mat:= List( cand, x -> x{ Concatenation([1], inv)});;
        gap> PrintArray( mat );
        [ [      1,      1,      1 ],
          [   8671,    351,    -33 ],
          [  57477,   1157,    133 ],
          [    783,     79,     15 ],
          [    783,     79,     15 ],
          [  64584,   1352,     72 ],
          [  64584,   1352,     72 ] ]

Since χ is rational, we need to consider only rationally irreducible characters, that is, the possible constituents are 1a, 8671a, 57377a, 783ab, and 64584ab.

        gap> List( cand, x -> x[2] );
        [ 1, 8671, 57477, 783*E(3), 783*E(3)^2, 64584*E(3), 64584*E(3)^2 ]

We see that the value on the first class of involutions must be 4371, since all values of the possible constituents are positive and too large for the other possible value 275.
Since the values of all possible constituents on the second class of involutions are at most equal to the values on the first class, and equal only for 1a, we conclude that the value on the second class of involutions is 275.
We see from the ratio of the value on the identity element and on the first class of involutions that constituents of degree 57477 or 64584 exist.

        gap> Float( 196883 / 4371 );
        45.043
        gap> List( mat, v -> Float( v[1] / v[2] ) );
        [ 1., 24.7037, 49.6776, 9.91139, 9.91139, 47.7692, 47.7692 ]
        gap> Float( ( 196883 - 2 * 64584 ) / ( 4371 - 2 * 1352 ) );
        40.6209
        gap> Float( ( 196883 - 57477 ) / ( 4371 - 1157 ) );
        43.3746
        gap> Float( ( 196883 - 2*57477 ) / ( 4371 - 2*1157 ) );
        39.8294
        gap> Float( ( 196883 - 3*57477 ) / ( 4371 - 3*1157 ) );
        27.1689

First suppose that 64584ab is not a constituent. The above ratios imply that (at least) three constituents of degree 57477 must occur.
However, then the degree admits at most two constituents of degree 8671, hence the value on the second class of involutions cannot be 275, a contradiction.
This means that both 64584ab and 57477a occur with multiplicity one.

        gap> mat[3] + mat[6] + mat[7];
        [ 186645, 3861, 277 ]

The second involution class forces one constituent of degree 8671 (which is the only candidate that can contribute a negative value), and then a character of degree 1567 remains to be decomposed. The only solution for the degrees of its constituents is 1 + 1566. We get the decomposition 1a + 8671a + 57477a + 783ab + 64584ab, as claimed in [BMW20b,Lemma 2].

        gap> Sum( mat );
        [ 196883, 4371, 275 ]

The characters of the degrees 1, 8671, and 57477 extend two-fold from 3.Fi24′ to 3.Fi24. In order to decompose the restriction of χ to 3.Fi24, we have to determine which extensions from 3.Fi24′ occur. The following irreducible characters of 3.Fi24 can occur as constituents of the restriction of χ.

        gap> table3Fi24:= CharacterTable( "3.Fi24" );;
        gap> cand:= Filtered( Irr( table3Fi24 ), x -> x[1] <= 196883 );;
        gap> inv:= Positions( OrdersClassRepresentatives( table3Fi24 ), 2 );
        [ 3, 5, 172, 173 ]
        gap> mat:= List( cand, x -> x{ Concatenation([1], inv)});;
        gap> PrintArray( mat );
        [ [       1,       1,       1,       1,       1 ],
          [       1,       1,       1,      -1,      -1 ],
          [    8671,     351,     -33,    1495,     -41 ],
          [    8671,     351,     -33,   -1495,      41 ],
          [   57477,    1157,     133,    5865,     233 ],
          [   57477,    1157,     133,   -5865,    -233 ],
          [    1566,     158,      30,       0,       0 ],
          [  129168,    2704,     144,       0,       0 ] ]

We get the decomposition 1a + 8671b + 57477a + 1566a + 129168a claimed in [BMW20b,Lemma 2].

        gap> Sum( mat{ [ 1, 4, 5, 7, 8 ] } );
        [ 196883, 4371, 275, 4371, 275 ]

## 3 The permutation character (12.BM)2.B

According to [GJMS89,Tables VII, IX], the restriction of the permutation character 12.BM to 2.B decomposes into nine transitive permutation characters 1U2.B, with the point stabilizers U listed in Table 1.
Table 1: Suborbit information

a c ∈ | Ga,c | |cGa|
`1A` | 2.B | 1
`2A` | 22.2E6(2) | 27143910000
`2B` | 22+22.Co2 | 11707448673375
`3A` | Fi23 | 2031941058560000
`3C` | th | 91569524834304000
`4A` | 21+22.McL | 1102935324621312000
`4B` | 2.F4(2) | 1254793905192960000
`5A` | HN | 30434513446055706624
`6A` | 2.Fi22 | 64353605265653760000

Here a denotes the central involution in 2.B, the action is that on the M-conjugacy class of a, and c ∈ aM is a representative of the orbit in question.
In this section, we compute the nine characters 1U2.B, where U is one of the above point stabilizers Ga,c. Note that a ∈ Ga,c holds (and thus the character is an inflated character of B) if and only if a and c commute; this happens exactly for the first three orbits.
All subgroups U except 22+22.Co2 and 21+22.McL are ATLAS groups whose character tables have been verified. The subgroup 22+22.Co2 is the preimage of a maximal subgroup 21+22.Co2 of B under the natural epimorphism from 2.B, and the computation/verification of the character table of 21+22.Co2 has been described in [BMW20a]. It will turn out that we do not need the character table of 21+22.McL.
The nine characters will be stored in the variables `pi1`, `pi2`, ..., `pi9`.
For U = 2.B, we have 1U2.B = 12.B.

        gap> pi1:= TrivialCharacter( table2B );;

For U = 22.2E6(2), the character 1U2.B is the inflation of 1[U]B from B to 2.B, for [U] = U / 〈a 〉 = 2.2E6(2).

        gap> tableB:= CharacterTable( "B" );;
        gap> tableUbar:= CharacterTable( "2.2E6(2)" );;
        gap> fus:= PossibleClassFusions( tableUbar, tableB );;
        gap> pi:= Set( fus,
        >              map -> InducedClassFunctionsByFusionMap( tableUbar, tableB,
        >                         [ TrivialCharacter( tableUbar ) ], map )[1] );;
        gap> Length( pi );
        1
        gap> pi2:= Inflated( tableB, table2B, pi )[1];;
        gap> mult:= List( Irr( table2B ),
        >                 chi -> ScalarProduct( table2B, chi, pi2 ) );;
        gap> Maximum( mult );
        1
        gap> Positions( mult, 1 );
        [ 1, 2, 3, 5, 7, 13, 15, 17 ]

For U = 22+22.Co2, the character 1U2.B is the inflation of 1[U]B from B to 2.B, for [U] = 21+22.Co2, a maximal subgroup of B.

        gap> tableUbar:= CharacterTable( "BN2B" );
        CharacterTable( "2^(1+22).\Co2" )
        gap> fus:= PossibleClassFusions( tableUbar, tableB );;
        gap> pi:= Set( fus,
        >              map -> InducedClassFunctionsByFusionMap( tableUbar, tableB,
        >                         [ TrivialCharacter( tableUbar ) ], map )[1] );;
        gap> Length( pi );
        1
        gap> pi3:= Inflated( tableB, table2B, pi )[1];;
        gap> mult:= List( Irr( table2B ),
        >                 chi -> ScalarProduct( table2B, chi, pi3 ) );;
        gap> Maximum( mult );
        1
        gap> Positions( mult, 1 );
        [ 1, 3, 5, 8, 13, 15, 28, 30, 37, 40 ]

Next we consider U = Fi23.

        gap> tableU:= CharacterTable( "Fi23" );;
        gap> fus:= PossibleClassFusions( tableU, table2B );;
        gap> pi:= Set( fus,
        >              map -> InducedClassFunctionsByFusionMap( tableU, table2B,
        >                         [ TrivialCharacter( tableU ) ], map )[1] );;
        gap> Length( pi );
        1
        gap> pi4:= pi[1];;
        gap> mult:= List( Irr( table2B ),
        >                 chi -> ScalarProduct( table2B, chi, pi4 ) );;
        gap> Maximum( mult );
        1
        gap> Positions( mult, 1 );
        [ 1, 2, 3, 5, 7, 8, 9, 12, 13, 15, 17, 23, 27, 30, 32, 40, 41, 54,
          63, 68, 77, 81, 83, 185, 186, 187, 188, 189, 194, 195, 196, 203,
          208, 220 ]

Next we consider U = th.

        gap> tableU:= CharacterTable( "Th" );;
        gap> fus:= PossibleClassFusions( tableU, table2B );;
        gap> pi:= Set( fus,
        >              map -> InducedClassFunctionsByFusionMap( tableU, table2B,
        >                         [ TrivialCharacter( tableU ) ], map )[1] );;
        gap> Length( pi );
        1
        gap> pi5:= pi[1];;
        gap> mult:= List( Irr( table2B ),
        >                 chi -> ScalarProduct( table2B, chi, pi5 ) );;
        gap> Maximum( mult );
        2
        gap> Positions( mult, 1 );
        [ 1, 3, 7, 8, 12, 13, 16, 19, 27, 28, 34, 38, 41, 57, 68, 70, 77, 78,
          85, 89, 113, 114, 116, 129, 133, 142, 143, 145, 155, 156, 185, 187,
          188, 193, 195, 196, 201, 208, 216, 219, 225, 232, 233, 235, 236,
          237, 242 ]
        gap> Positions( mult, 2 );
        [ 62 ]

For U = 21+22.McL, we carry out the computations described in [Breb,Section "A permutation character of 2.B"]. We know that U is a subgroup of 22+22.Co2, and that 〈U, a 〉 has the structure 22+22.McL.
As a first step, we induce the trivial character of 〈U, a 〉 to 2.B, which can be performed by inducing the trivial character of McL to Co2, then to inflate this character to 21+22.Co2, then to induce this character to B, and then to inflate this character to 2.B,
TODO: Perhaps add a picture?

        gap> mcl:= CharacterTable( "McL" );;
        gap> co2:= CharacterTable( "Co2" );;
        gap> fus:= PossibleClassFusions( mcl, co2 );;
        gap> Length( fus );
        4
        gap> ind:= Set( fus, map -> InducedClassFunctionsByFusionMap( mcl, co2,
        >                               [ TrivialCharacter( mcl ) ], map )[1] );;
        gap> Length( ind );
        1
        gap> bm2:= CharacterTable( "BM2" );
        CharacterTable( "2^(1+22).Co2" )
        gap> infl:= Inflated( co2, bm2, ind );;
        gap> ind:= Induced( bm2, tableB, infl );;
        gap> infl:= Inflated( tableB, table2B, ind )[1];;

As a second step, we compute 1U2.B with the GAP function `PermChars`, using that we can speed up these computations by prescribing the permutation character induced from the closure of U with the normal subgroup 〈a 〉 of 2.B.
(We are lucky: There is a unique solution, and its computation is quite fast.)

        gap> centre:= ClassPositionsOfCentre( table2B );
        [ 1, 2 ]
        gap> pi:= PermChars( table2B, rec( torso:= [ 2 * infl[1], 0 ],
        >                             normalsubgroup:= centre,
        >                             nonfaithful:= infl ) );;
        gap> Length( pi );
        1
        gap> pi6:= pi[1];;
        gap> List( Irr( table2B ), chi -> ScalarProduct( table2B, chi, pi6 ) );
        [ 1, 1, 2, 1, 2, 0, 2, 3, 2, 0, 0, 1, 4, 1, 2, 0, 3, 2, 0, 2, 0, 0,
          2, 2, 0, 0, 2, 3, 1, 5, 0, 4, 3, 2, 0, 0, 3, 2, 0, 6, 4, 0, 1, 1,
          0, 0, 0, 0, 3, 0, 1, 0, 0, 5, 0, 5, 2, 0, 0, 2, 0, 0, 4, 1, 0, 2,
          0, 4, 2, 4, 4, 3, 0, 2, 4, 2, 4, 0, 3, 0, 3, 2, 5, 0, 1, 0, 3, 1,
          0, 1, 1, 2, 5, 3, 1, 1, 4, 5, 1, 1, 0, 3, 0, 0, 3, 2, 1, 1, 2, 1,
          1, 4, 0, 3, 2, 3, 1, 3, 0, 1, 3, 0, 2, 2, 1, 3, 3, 0, 0, 2, 0, 0,
          0, 0, 3, 0, 3, 3, 3, 1, 0, 3, 0, 4, 0, 1, 0, 0, 2, 0, 0, 2, 0, 0,
          2, 1, 1, 0, 0, 0, 0, 1, 2, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 2, 1,
          1, 3, 3, 0, 0, 0, 1, 1, 1, 1, 2, 3, 2, 0, 0, 2, 2, 4, 3, 5, 2, 4,
          0, 0, 0, 0, 5, 2, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 7, 0, 0, 1, 7,
          7, 0, 0, 0, 1, 6, 4, 5, 0, 0, 3, 0, 0, 0, 0, 0, 4, 1, 1, 3, 8, 3,
          2, 2, 5, 0, 1 ]

Next we consider U = 2.F4(2). We know that U does not contain the central involution of 2.B.

        gap> tableU:= CharacterTable( "2.F4(2)" );;
        gap> fus:= PossibleClassFusions( tableU, table2B );;
        gap> pi:= Set( fus, map -> InducedClassFunctionsByFusionMap( tableU, table2B,
        >             [ TrivialCharacter( tableU ) ], map )[1] );;
        gap> Length( pi );
        2
        gap> pi:= Filtered( pi, x -> ClassPositionsOfKernel( x ) = [ 1 ] );;
        gap> Length( pi );
        1
        gap> pi7:= pi[1];;
        gap> List( Irr( table2B ), chi -> ScalarProduct( table2B, chi, pi7 ) );
        [ 1, 1, 2, 0, 2, 0, 2, 2, 1, 0, 0, 2, 4, 1, 3, 0, 2, 1, 0, 0, 0, 0,
          2, 1, 0, 0, 2, 2, 1, 4, 0, 2, 1, 2, 0, 0, 3, 2, 0, 4, 4, 0, 0, 0,
          0, 0, 1, 0, 0, 0, 1, 0, 0, 2, 1, 3, 3, 0, 0, 3, 0, 1, 4, 0, 0, 3,
          0, 6, 0, 3, 2, 0, 0, 1, 4, 1, 4, 2, 6, 1, 4, 0, 4, 0, 1, 1, 2, 0,
          0, 3, 2, 1, 3, 2, 0, 0, 4, 5, 3, 1, 0, 3, 0, 0, 1, 1, 2, 0, 0, 2,
          0, 2, 0, 3, 3, 3, 0, 4, 1, 0, 4, 1, 1, 1, 1, 1, 2, 1, 1, 2, 3, 0,
          0, 2, 2, 0, 5, 5, 3, 0, 1, 5, 1, 4, 0, 1, 0, 1, 1, 0, 0, 3, 1, 0,
          2, 3, 1, 0, 2, 0, 0, 2, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 2,
          1, 4, 4, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 0, 0, 1, 2, 3, 3, 3, 1, 2,
          0, 0, 1, 1, 4, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 1, 5,
          5, 0, 1, 1, 2, 2, 4, 4, 0, 0, 3, 1, 1, 1, 0, 0, 4, 1, 1, 5, 7, 3,
          2, 5, 5, 0, 1 ]

Next we consider U = HN.

        gap> tableU:= CharacterTable( "HN" );;
        gap> fus:= PossibleClassFusions( tableU, table2B );;
        gap> pi:= Set( fus, map -> InducedClassFunctionsByFusionMap( tableU, table2B,
        >             [ TrivialCharacter( tableU ) ], map )[1] );;
        gap> Length( pi );
        1
        gap> pi8:= pi[1];;
        gap> List( Irr( table2B ), chi -> ScalarProduct( table2B, chi, pi8 ) );
        [ 1, 1, 2, 1, 2, 0, 3, 4, 2, 1, 1, 4, 4, 2, 1, 1, 3, 3, 1, 3, 0, 0,
          5, 3, 0, 0, 6, 4, 5, 6, 1, 7, 4, 7, 0, 0, 3, 8, 2, 6, 11, 2, 5, 5,
          0, 0, 2, 1, 3, 4, 7, 0, 0, 7, 3, 9, 5, 0, 0, 6, 4, 2, 13, 6, 0, 4,
          4, 12, 11, 16, 9, 7, 3, 11, 13, 12, 20, 5, 10, 6, 11, 13, 17, 4,
          10, 7, 19, 7, 7, 8, 10, 14, 18, 19, 5, 10, 12, 23, 7, 12, 6, 24, 6,
          4, 17, 16, 8, 9, 17, 11, 12, 23, 8, 24, 18, 26, 21, 29, 10, 18, 31,
          10, 24, 21, 17, 27, 35, 13, 14, 29, 19, 12, 7, 18, 26, 15, 34, 34,
          35, 20, 14, 36, 14, 39, 8, 29, 24, 15, 40, 13, 9, 38, 24, 17, 35,
          32, 26, 26, 24, 22, 17, 31, 39, 29, 30, 30, 19, 44, 37, 37, 28, 30,
          31, 29, 42, 40, 40, 56, 56, 30, 30, 42, 50, 47, 2, 2, 4, 6, 4, 0,
          0, 4, 6, 10, 10, 12, 8, 12, 0, 0, 2, 4, 16, 10, 0, 0, 2, 12, 10, 0,
          0, 0, 0, 0, 0, 28, 0, 0, 14, 34, 40, 2, 10, 10, 22, 40, 44, 44, 8,
          8, 36, 14, 14, 16, 8, 8, 46, 28, 28, 58, 90, 72, 70, 92, 104, 56,
          90 ]

Finally, we consider U = 2.Fi22. There are two candidates for the permutation character (1U)2.B, according to the possible class fusions. One of the two characters is zero on the class of the central involution of 2.B, the other is not. We know that U does not contain the central involution of 2.B, hence we can decide which character is correct.

        gap> tableU:= CharacterTable( "2.Fi22" );;
        gap> fus:= PossibleClassFusions( tableU, table2B );;
        gap> pi:= Set( fus, map -> InducedClassFunctionsByFusionMap( tableU, table2B,
        >             [ TrivialCharacter( tableU ) ], map )[1] );;
        gap> Length( pi );
        2
        gap> pi:= Filtered( pi, x -> ClassPositionsOfKernel( x ) = [ 1 ] );;
        gap> Length( pi );
        1
        gap> pi9:= pi[1];;
        gap> List( Irr( table2B ), chi -> ScalarProduct( table2B, chi, pi9 ) );
        [ 1, 2, 3, 1, 4, 1, 5, 5, 5, 1, 1, 5, 8, 4, 4, 1, 7, 6, 0, 5, 0, 0,
          10, 7, 0, 0, 10, 6, 6, 13, 3, 14, 10, 11, 0, 0, 5, 11, 2, 14, 19,
          6, 6, 5, 0, 0, 0, 3, 6, 7, 11, 0, 0, 17, 2, 20, 9, 0, 0, 12, 8, 1,
          23, 11, 1, 8, 7, 23, 18, 27, 18, 12, 7, 22, 29, 21, 34, 6, 22, 7,
          22, 18, 33, 3, 19, 10, 34, 12, 12, 15, 17, 28, 34, 34, 7, 20, 26,
          40, 15, 25, 3, 40, 9, 6, 34, 25, 18, 21, 30, 21, 18, 43, 12, 45,
          39, 49, 38, 51, 18, 32, 63, 19, 42, 41, 33, 48, 64, 27, 29, 52, 38,
          29, 19, 40, 47, 31, 69, 69, 65, 42, 35, 68, 27, 73, 20, 53, 46, 38,
          75, 29, 24, 72, 50, 41, 72, 68, 58, 52, 54, 50, 44, 64, 75, 58, 69,
          65, 49, 85, 75, 75, 63, 68, 65, 63, 90, 87, 83, 118, 118, 74, 71,
          90, 109, 109, 2, 3, 6, 9, 8, 0, 0, 7, 10, 18, 16, 22, 12, 23, 0, 0,
          2, 6, 28, 19, 0, 0, 5, 16, 18, 0, 0, 0, 0, 0, 0, 52, 1, 1, 26, 59,
          76, 11, 18, 18, 39, 77, 80, 77, 22, 22, 66, 27, 27, 33, 20, 20, 87,
          60, 60, 103, 175, 148, 152, 187, 215, 140, 201 ]

Now we can form the restriction of (12.B)M to 2.B.

        gap> permchar:= Sum( [ pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8, pi9 ] );;

## 4 The conjugacy classes of M

### 4.1 Our strategy to describe the conjugacy classes of M

We know the order of M and its prime divisors. Let us check whether this fits to our data computed up to now.

        gap> constit:= [ pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8, pi9 ];;
        gap> pi:= Sum( constit );;
        gap> sizeM:= pi[1] * Size( table2B );
        808017424794512875886459904961710757005754368000000000
        gap> StringPP( sizeM );
        "2^46*3^20*5^9*7^6*11^2*13^3*17*19*23*29*31*41*47*59*71"
        gap> sizeM = Size( CharacterTable( "M" ) );
        true

For each prime p dividing |M|, we classify the conjugacy classes of elements of order p in M and use the facts that for each such class representative x, the classes of roots of x in the centralizer/normalizer of x are in bijection with the corresponding classes in M, and that this bijection respects centralizer orders.
For each element x ∈ M of order p ∈ { 2, 3, 5 }, we will use the character table of NM(〈x 〉) to establish M-conjugacy classes of roots of x. In order not to count the same class several times, we proceed by increasing p, and collect only those classes of roots of x for which p is the smallest prime divisor of the element order.
For elements x ∈ M of prime order p > 5, it is not necessary to use the character table of NM(〈x 〉); we will use the permutation character values (12.B)M(x) and ad hoc arguments.

### 4.2 Utility functions

During the process of finding the conjugacy classes of M, we record our knowledge about the character table of M in a global GAP variable `head`, which is a record with the following components.

`Size`
  the group order |M|,
`SizesCentralizers`
  the list of centralizer orders of the conjugacy classes established up to now,
`OrdersClassRepresentatives`
  the list of corresponding representative orders,
`fusions`
  a list that collects the currently known partial class fusions into M; each entry is a record with the components `subtable` (the character table of the subgroup) and `map` (the list of known images; unknown positions are unbound).

We initialize this variable, using the group order M and that there is an identity element.

        gap> head:= rec( Size:= sizeM,
        >                SizesCentralizers:= [ sizeM ],
        >                OrdersClassRepresentatives:= [ 1 ],
        >                fusions:= [],
        >              );;

The function `ExtendTableHeadByRootClasses` takes the object `head`, the character table `s` of a subgroup H of M, and an integer `pos` as its arguments, where it is assumed that the `pos`-th class of `s` contains an element x of prime order p such that NM(〈x 〉) = H holds and such that `head` contains information only about those classes of M whose elements have order divisible by a prime that is smaller than p.

        gap> ExtendTableHeadByRootClasses:= function( head, s, pos )
        >    local fus, orders, p, cents, oldnumber, i, ord;
        >
        >    # Initialize the fusion information.
        >    fus:= rec( subtable:= s, map:= [ 1 ] );
        >    Add( head.fusions, fus );
        >
        >    # Compute the positions of root classes of 'pos'.
        >    orders:= OrdersClassRepresentatives( s );
        >    p:= orders[ pos ];
        >    cents:= SizesCentralizers( s );
        >    oldnumber:= Length( head.OrdersClassRepresentatives );
        >
        >    # Run over the classes of 's'
        >    # are already contained in head
        >    for i in [ 1 .. NrConjugacyClasses( s ) ] do
        >      ord:= orders[i];
        >      if ord mod p = 0 and
        >         Minimum( PrimeDivisors( ord ) ) = p and
        >         PowerMap( s, ord / p, i ) = pos then
        >        # Class 'i' is a root class of 'pos' and is new in 'head'.
        >        Add( head.SizesCentralizers, cents[i] );
        >        Add( head.OrdersClassRepresentatives, orders[i] );
        >        fus.map[i]:= Length( head.SizesCentralizers );
        >      fi;
        >    od;
        >
        >    Print( "#I  after ", Identifier( s ), ": found ",
        >           Length( head.OrdersClassRepresentatives ) - oldnumber,
        >           " classes, now have ",
        >           Length( head.OrdersClassRepresentatives ), "\n" );
        >    end;;

In several cases, we will establish a conjugacy class gM without knowing the character table of a suitable subgroup of M to which `ExtendTableHeadByRootClasses` can be applied, where g is among the root classes. That is, we may know just element order `s` and centralizer order `cent`.
We are a bit better off if we know the character table `s` of a subgroup of M and the list `poss` of all those classes in this table which fuse to the class gM, because then we can store this information in the partial class fusion from `s` that is stored in `head`.

        gap> ExtendTableHeadByCentralizerOrder:= function( head, s, cent, poss )
        >    local ord, fus, i;
        >
        >    if IsCharacterTable( s ) then
        >      ord:= Set( OrdersClassRepresentatives( s ){ poss } );
        >      if Length( ord ) <> 1 then
        >        Error( "classes cannot fuse" );
        >      fi;
        >      ord:= ord[1];
        >    elif IsInt( s ) then
        >      ord:= s;
        >    fi;
        >    Add( head.SizesCentralizers, cent );
        >    Add( head.OrdersClassRepresentatives, ord );
        >
        >    Print( "#I  after order ", ord, " element" );
        >    if IsCharacterTable( s ) then
        >      # extend the stored fusion from s
        >      fus:= First( head.fusions,
        >                   r -> Identifier( r.subtable ) = Identifier( s ) );
        >      for i in poss do
        >        fus.map[i]:= Length( head.SizesCentralizers );
        >      od;
        >      Print( " from ", Identifier( s ) );
        >    fi;
        >    Print( ": have ",
        >           Length( head.OrdersClassRepresentatives ), " classes\n" );
        >    end;;

The permutation character 1HG, where H ≤ G are two groups, has the property 1HG(g) = |CG(g)| ·|gG ∩H| / |H|. For g ∈ H, this implies that |CG(g)| = 1HG(g) ·|H| / |gG ∩H| can be computed from the character (1HG)H and the class lengths in H, provided that we know which classes of H fuse into gG. The function `ExtendTableHeadByPermCharValue` extends the information in `head` by the data for the class gM, where `s` is the character table of H, `pi_rest_to_s` is (1HG)H, and `poss` is the list of positions of those classes in `s` that fuse to gM.

        gap> ExtendTableHeadByPermCharValue:= function( head, s, pi_rest_to_s, poss )
        >    local pival, cent;
        >
        >    pival:= Set( pi_rest_to_s{ poss } );
        >    if Length( pival ) <> 1 then
        >      Error( "classes cannot fuse" );
        >    fi;
        >
        >    cent:= pival[1] * Size( s ) / Sum( SizesConjugacyClasses( s ){ poss } );
        >    ExtendTableHeadByCentralizerOrder( head, s, cent, poss );
        >    end;;

### 4.3 Classes of elements of even order

We know that M has exactly two conjugacy classes of involutions, and that the involution centralizers have the structures 2.B (for the class `2A`) and 21+24.Co1 (for the class `2B`), respectively.
Moreover, the character tables of these subgroups that are stored in the GAP Character Table Library are correct. For 2.B, this follows from the correctness of the character table of B as shown in [BMW20a] and the computations in []. For 21+24.Co1, the recomputation of the character table is shown in Section 8.
Thus we can determine the M-conjugacy classes of elements of even order as follows.

        gap> s:= CharacterTable( "2.B" );;
        gap> ClassPositionsOfCentre( s );
        [ 1, 2 ]
        gap> ExtendTableHeadByRootClasses( head, s, 2 );
        #I  after 2.B: found 42 classes, now have 43
        gap> s:= CharacterTable( "MN2B" );;
        gap> ClassPositionsOfCentre( s );
        [ 1, 2 ]
        gap> ExtendTableHeadByRootClasses( head, s, 2 );
        #I  after 2^1+24.Co1: found 91 classes, now have 134

### 4.4 Classes of elements of order divisible by 3

We know that M has exactly three conjugacy classes of elements of order 3, and that their normalizers have the structures 3.Fi24 (for the class `3A`), 31+12.2.Suz.2 (for the class `3B`), and S3 ×th (for the class `3C`), respectively.
Moreover, the GAP character tables of 3.Fi24 and th are ATLAS tables and have been verified, see [BMO17].
We determine the M-conjugacy classes of elements of odd order that are roots of `3A` or `3C` elements, as follows.

        gap> s:= CharacterTable( "3.Fi24" );;
        gap> ClassPositionsOfPCore( s, 3 );
        [ 1, 2 ]
        gap> ExtendTableHeadByRootClasses( head, s, 2 );
        #I  after 3.F3+.2: found 12 classes, now have 146
        gap> s:= CharacterTableDirectProduct( CharacterTable( "Th" ),
        >                                     CharacterTable( "Symmetric", 3 ) );;
        gap> ClassPositionsOfPCore( s, 3 );
        [ 1, 3 ]
        gap> ExtendTableHeadByRootClasses( head, s, 3 );
        #I  after ThxSym(3): found 7 classes, now have 153

The situation with the `3B` normalizer is more involved. Section 9 documents the construction of the character table of a downward extension of the structure 31+12+:6.Suz.2 of the `3B` normalizer, and gives two candidates for the character table of the `3B` normalizer.
It will turn out that each of these candidates leads to "the same" root classes, in the sense that the number of these classes, their element orders, and their centralizer orders are equal. Note that the 3-core of H = 31+12+:6.Suz.2 has the structure N1 ×N2, where N1 has order 3 and N2 ≅ 31+12+ such that H / N2 ≅ 6.Suz.2 holds. We are interested in the two "diagonal" factors, that is, the factors of H by the one of the two normal subgroups of order 3 in H that are equal to none of N1 or Z(N2). (See the picture in Section 9 for the details.)
First we exclude the normal subgroup of order 3 that is contained in the unique normal subgroup N2 of order 313.

        gap> exts:= CharacterTable( "3^(1+12):6.Suz.2" );;
        gap> kernels:= Positions( SizesConjugacyClasses( exts ), 2 );
        [ 2, 18, 19, 20 ]
        gap> order3_13:= Filtered( ClassPositionsOfNormalSubgroups( exts ),
        >        l -> Sum( SizesConjugacyClasses( exts ){ l } ) = 3^13 );
        [ [ 1 .. 4 ] ]
        gap> kernels:= Difference( kernels, order3_13[1] );
        [ 18, 19, 20 ]

The classes in the subgroup N1 can be identified by the fact that exactly one factor of H by a normal subgroup of order 3 admits a class fusion from 2.Suz.2, and hence this must be the split extension of 31+12+ with 2.Suz.2.

        gap> facts:= List( kernels, i -> exts / [ 1, i ] );
        [ CharacterTable( "3^(1+12):6.Suz.2/[ 1, 18 ]" ),
          CharacterTable( "3^(1+12):6.Suz.2/[ 1, 19 ]" ),
          CharacterTable( "3^(1+12):6.Suz.2/[ 1, 20 ]" ) ]
        gap> f:= CharacterTable( "2.Suz.2" );;
        gap> facts:= Filtered( facts,
        >        x -> Length( PossibleClassFusions( f, x ) ) = 0 );
        [ CharacterTable( "3^(1+12):6.Suz.2/[ 1, 19 ]" ),
          CharacterTable( "3^(1+12):6.Suz.2/[ 1, 20 ]" ) ]

We compute the root classes for both candidates. For that, we first create a copy `head2` of the information in `head`.

        gap> kernels:= List( facts,
        >        f -> Positions( SizesConjugacyClasses( f ), 2 ) );
        [ [ 2 ], [ 2 ] ]
        gap> head2:= StructuralCopy( head );;
        gap> ExtendTableHeadByRootClasses( head, facts[1], 2 );
        #I  after 3^(1+12):6.Suz.2/[ 1, 19 ]: found 12 classes, now have 165
        gap> ExtendTableHeadByRootClasses( head2, facts[2], 2 );
        #I  after 3^(1+12):6.Suz.2/[ 1, 20 ]: found 12 classes, now have 165

We observe that `head` and `head2` differ only by the two character tables in the last fusion record.

        gap> nams:= RecNames( head );
        [ "Size", "OrdersClassRepresentatives", "SizesCentralizers",
          "fusions" ]
        gap> ForAll( Difference( nams, [ "fusions" ] ),
        >            nam -> head.( nam ) = head2.( nam ) );
        true
        gap> Length( head.fusions );
        5
        gap> ForAll( [ 1 .. 4 ], i -> head.fusions[i] = head2.fusions[i] );
        true
        gap> head.fusions[5].map = head2.fusions[5].map;
        true

We continue with establishing the conjugacy classes of M. The question which of the two above candidate tables belongs to a subgroup of M will be answered later.

### 4.5 Classes of elements of order divisible by 5

The group 2.B contains two rational conjugacy classes of elements of order 5, with different values of the permutation character (12.B)M.

        gap> s:= CharacterTable( "2.B" );;
        gap> pos:= Positions( OrdersClassRepresentatives( s ), 5 );
        [ 23, 25 ]
        gap> pi{ pos };
        [ 1539000, 7875 ]

This establishes two classes `5A`, `5B` of conjugacy classes of elements of order 5 in M, with centralizer orders 5 |HN| and 57 |2.J2|, respectively.

        gap> cents:= List( pos,
        >      i -> pi[i] * Size( s ) / SizesConjugacyClasses( s )[i] );
        [ 1365154560000000, 94500000000 ]
        gap> cents = [ 5 * Size( CharacterTable( "HN" ) ),
        >              5^7 * Size( CharacterTable( "2.J2" ) ) ];
        true

TODO: Add some arguments about the structures of the tables.
We know that M contains exactly two conjugacy classes of elements of order 5, `5A` with centralizer 5 ×HN and normalizer (D10 ×HN).2, and `5B` with centralizer 51+6+.2.J2 and normalizer 51+6+.4.J2.2.
The two classes are rational because this is the case already for their intersections with 2.B.

        gap> s:= CharacterTable( "MN5A" );
        CharacterTable( "(D10xHN).2" )
        gap> ClassPositionsOfPCore( s, 5 );
        [ 1, 45 ]
        gap> ExtendTableHeadByRootClasses( head, s, 45 );
        #I  after (D10xHN).2: found 5 classes, now have 170

The character table of 51+6+.4.J2.2 has been recomputed with MAGMA, see Section 10, thus we are allowed to use the character table from the GAP character table library.

        gap> s:= CharacterTable( "MN5B" );
        CharacterTable( "5^(1+6):2.J2.4" )
        gap> 5core:= ClassPositionsOfPCore( s, 5 );
        [ 1 .. 4 ]
        gap> SizesConjugacyClasses( s ){ 5core };
        [ 1, 4, 37800, 40320 ]
        gap> ExtendTableHeadByRootClasses( head, s, 2 );
        #I  after 5^(1+6):2.J2.4: found 3 classes, now have 173

### 4.6 Classes of elements of order divisible by 11

The group 2.B contains a rational class of elements of order 11. The permutation character (12.BM)2.B yields a class of elements of order 11 with centralizer order 11 |M12| in M.

        gap> s:= CharacterTable( "2.B" );;
        gap> pos:= Positions( OrdersClassRepresentatives( s ), 11 );
        [ 71 ]

By the arguments in [BMW20b], M has no other classes of element order 11.

        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos );
        #I  after order 11 element from 2.B: have 174 classes

### 4.7 Classes of elements of the orders 17, 19, 23, 31, 47

The elements of the orders 17, 19, 23, 31, 47 in M lie in cyclic Sylow subgroups that appear already in 2.B.
The elements of order 17 and 19 are rational in 2.B and hence also in M.

        gap> s:= CharacterTable( "2.B" );;
        gap> pos:= Positions( OrdersClassRepresentatives( s ), 17 );
        [ 118 ]
        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos );
        #I  after order 17 element from 2.B: have 175 classes
        gap> pos:= Positions( OrdersClassRepresentatives( s ), 19 );
        [ 128 ]
        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos );
        #I  after order 19 element from 2.B: have 176 classes

For elements g of order p ∈ { 23, 31, 47 }, the group 2.B contains exactly two Galois conjugate classes that contain the nonidentity powers of g, which means that [N2.B(〈g 〉):C2.B(g)] = (p−1)/2 holds. The equation |CM(g)| = |2.B| ·π(g) / |gM ∩2.B| implies

|NM(〈g 〉)| = [NM(〈g 〉):CM(g)] ·|2.B| ·π(g) / |gM| = (p−1)/2 ·|2.B| ·π(g) / |g2.B|.

Note that either the two classes of elements of order p in 2.B fuse in M or not; in the former case, we have [NM(〈g 〉):CM(g)] = p−1 and |gM ∩2.B| = 2 |g2.B|, whereas we have [NM(〈g 〉):CM(g)] = (p−1)/2 and |gM ∩2.B| = |g2.B| in the latter case. Thus we can compute |NM(〈g 〉)| in each case, and we can then find arguments why the two Galois conjugate classes do not fuse.
First we deal with p = 23.

        gap> s:= CharacterTable( "2.B" );
        CharacterTable( "2.B" )
        gap> ord:= OrdersClassRepresentatives( s );;
        gap> classes:= SizesConjugacyClasses( s );;
        gap> p:= 23;;
        gap> pos:= Positions( ord, p );
        [ 147, 149 ]
        gap> n:= (p-1)/2 * Size( s ) * pi[ pos[1] ] / classes[ pos[1] ];
        6072
        gap> Collected( Factors( n ) );
        [ [ 2, 3 ], [ 3, 1 ], [ 11, 1 ], [ 23, 1 ] ]

In order to prove that the two classes of elements of order 23 in 2.B do not fuse in M, it suffices to show that the centralizer order is divisible by 23. We see that this is the case already in the `2B` centralizer in M.

        gap> u:= CharacterTable( "MN2B" );
        CharacterTable( "2^1+24.Co1" )
        gap> upos:= Positions( OrdersClassRepresentatives( u ), p );
        [ 289, 294 ]
        gap> SizesCentralizers( u ){ upos } / 2^3;
        [ 23, 23 ]

Thus we have established two classes of element order 23 in M.

        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos{ [1] } );
        #I  after order 23 element from 2.B: have 177 classes
        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos{ [2] } );
        #I  after order 23 element from 2.B: have 178 classes

The case p = 31 is done analogously. Here the necessary 2-part of the centralizer occurs already in 2.B.

        gap> p:= 31;;
        gap> pos:= Positions( OrdersClassRepresentatives( s ), p );
        [ 190, 192 ]
        gap> n:= (p-1)/2 * Size( s ) * pi[ pos[1] ] / classes[ pos[1] ];
        2790
        gap> Collected( Factors( n ) );
        [ [ 2, 1 ], [ 3, 2 ], [ 5, 1 ], [ 31, 1 ] ]
        gap> SizesCentralizers( s ){ pos };
        [ 62, 62 ]
        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos{ [1] } );
        #I  after order 31 element from 2.B: have 179 classes
        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos{ [2] } );
        #I  after order 31 element from 2.B: have 180 classes

Finally, we deal with p = 47.

        gap> p:= 47;;
        gap> pos:= Positions( OrdersClassRepresentatives( s ), p );
        [ 228, 230 ]
        gap> n:= (p-1)/2 * Size( s ) * pi[ pos[1] ] / classes[ pos[1] ];
        2162
        gap> Collected( Factors( n ) );
        [ [ 2, 1 ], [ 23, 1 ], [ 47, 1 ] ]
        gap> SizesCentralizers( s ){ pos };
        [ 94, 94 ]
        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos{ [1] } );
        #I  after order 47 element from 2.B: have 181 classes
        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos{ [2] } );
        #I  after order 47 element from 2.B: have 182 classes

### 4.8 Classes of elements of order 13

The class `13A` of M arises from the rational class of elements of order 13 in 2.B.

        gap> p:= 13;;
        gap> pos:= Positions( OrdersClassRepresentatives( s ), p );
        [ 97 ]
        gap> c:= Size( s ) * pi[ pos[1] ] / classes[ pos[1] ];
        73008

TODO: discuss the details!
We use the permutation character to notify the class `13A`.

        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos );
        #I  after order 13 element from 2.B: have 183 classes

The class `13B` intersects the `2B` centralizer. Here we just know the centralizer order 133 ·23 ·3.
TODO: discuss the details!

        gap> c2b:= CharacterTable( "MN2B" );;
        gap> pos:= Positions( OrdersClassRepresentatives( c2b ), 13 );
        [ 220 ]
        gap> ExtendTableHeadByCentralizerOrder( head, c2b, 13^3 * 24, pos );
        #I  after order 13 element from 2^1+24.Co1: have 184 classes

### 4.9 Classes of elements of order divisible by 29

The group 3.Fi24 contains a rational class of elements of order 29, with centralizer order 3 ·29.

        gap> u:= CharacterTable( "3.Fi24" );;
        gap> pos:= Positions( OrdersClassRepresentatives( u ), 29 );
        [ 142 ]
        gap> SizesCentralizers( u ){ pos };
        [ 87 ]

The list of classes of M collected up to now covers all roots of elements of the orders 2, 3, 5, 11, 13, 17, 19, 23, 31, 47, and 29 occurs as a factor of the centralizer order only for the classes `1A`, `3A`, `87A`, and `87B`.

        gap> pos:= PositionsProperty( head.SizesCentralizers,
        >                             x -> x mod 29 = 0 );
        [ 1, 135, 144, 145 ]
        gap> head.OrdersClassRepresentatives{ pos };
        [ 1, 3, 87, 87 ]
        gap> head.SizesCentralizers{ pos };
        [ 808017424794512875886459904961710757005754368000000000,
          3765617127571985163878400, 87, 87 ]

Thus the only possible additional prime divisors of the centralizer order in M of an element x of order 29 are 7, 41, 59, and 71.

        gap> candprimes:= Difference( PrimeDivisors( head.Size ),
        >                     [ 2, 3, 5, 11, 13, 17, 19, 23, 29, 31, 47 ] );
        [ 7, 41, 59, 71 ]

The centralizer order of x has the form 3 ·29 ·7i ·41j ·59k ·71l, with 0 ≤ i ≤ 6 and j, k, l ∈ { 0, 1 }.

        gap> parts:= Filtered( Collected( Factors( head.Size ) ),
        >                      x -> x[1] in candprimes );
        [ [ 7, 6 ], [ 41, 1 ], [ 59, 1 ], [ 71, 1 ] ]
        gap> poss:= List( parts, l -> List( [ 0 .. l[2] ], i -> l[1]^i ) );;
        gap> cart:= Cartesian( poss );;
        gap> possord:= 3 * 29 * List( cart, Product );;

Only 3 ·29 and 3 ·29 ·59 satisfy Sylow's theorem, that is, |M| / |NM(〈x 〉)| ≡ 1 mod 29. Note that we have [NM(〈x 〉):CM(x)] = 28.

        gap> good:= Filtered( possord,
        >                     x -> ( head.Size / ( 28 * x ) ) mod 29 = 1 );
        [ 87, 5133 ]
        gap> List( good, Factors );
        [ [ 3, 29 ], [ 3, 29, 59 ] ]

Now we can exclude the possible centralizer order 3 ·29 ·59 by the fact that the Sylow 59 subgroup would be normal and thus would be normalized and hence centralized by an element of order 3, a contradiction.

        gap> Filtered( DivisorsInt( 5133 ), x -> x mod 59 = 1 );
        [ 1 ]

Thus we have established a rational class of elements of order 29, with centralizer of order 3 ·29.

        gap> ExtendTableHeadByCentralizerOrder( head, u, 3 * 29, pos );
        #I  after order 29 element from 3.F3+.2: have 185 classes

### 4.10 Classes of elements of order divisible by 41

We assume that M contains a subgroup of the structure 38.O8−(3), which implies that an element x of order 41 in M is normalized by an element of order 4.

        gap> t:= CharacterTable( "O8-(3)" );
        CharacterTable( "O8-(3)" )
        gap> Length( Positions( OrdersClassRepresentatives( t ), 41 ) );
        10

By the above arguments, the only possible odd prime divisors of |NM(〈x 〉)|/41 are 5, 7, 59, 71, where 5 cannot divide the centralizer order. As in the case of p = 29, we apply Sylow's theorem, and get |NM(〈x 〉)| ∈ { 23 ·5 ·41, 23 ·7 ·41 ·71 }.

        gap> possord:= 2^2 * 41 * DivisorsInt( 2 * 5 * 7^6 * 59 * 71 );;
        gap> good:= Filtered( possord,
        >                     x -> ( head.Size / x ) mod 41 = 1 );
        [ 1640, 163016 ]
        gap> List( good, Factors );
        [ [ 2, 2, 2, 5, 41 ], [ 2, 2, 2, 7, 41, 71 ] ]

Suppose that 71 divides |NM(〈x 〉)|. Then the 71 Sylow subgroup of NM(〈x 〉) is normal thus normalized by an element of order 8, and thus centralized by an involution, a contradiction.

        gap> Filtered( DivisorsInt( good[2] ), x -> x mod 71 = 1 );
        [ 1 ]

Thus we have established a rational class of self-centralizing elements of order 41.

        gap> ExtendTableHeadByCentralizerOrder( head, 41, 41, fail );
        #I  after order 41 element: have 186 classes

### 4.11 Classes of elements of order divisible by 59

By the above arguments, the normalizer order of an element of order 59 divides 58 ·76 ·59 ·71. Sylow's theorem admits just the normalizer order 59 ·29.

        gap> possord:= 59 * DivisorsInt( 58*7^6*71 );;
        gap> good:= Filtered( possord,
        >                     x -> ( head.Size / x ) mod 59 = 1 );
        [ 1711 ]
        gap> List( good, Factors );
        [ [ 29, 59 ] ]

Thus we have established a pair of Galois conjugate classes of self-centralizing elements of order 59.

        gap> ExtendTableHeadByCentralizerOrder( head, 59, 59, fail );
        #I  after order 59 element: have 187 classes
        gap> ExtendTableHeadByCentralizerOrder( head, 59, 59, fail );
        #I  after order 59 element: have 188 classes

### 4.12 Classes of elements of order divisible by 71

By the above arguments, the normalizer order of an element of order 71 divides 70 ·75 ·71. Sylow's theorem admits just the normalizer order 71 ·35.

        gap> possord:= 71 * DivisorsInt( 70*7^5 );;
        gap> good:= Filtered( possord,
        >                     x -> ( head.Size / x ) mod 71 = 1 );
        [ 2485 ]
        gap> List( good, Factors );
        [ [ 5, 7, 71 ] ]

Thus we have established a pair of Galois conjugate classes of self-centralizing elements of order 71.

        gap> ExtendTableHeadByCentralizerOrder( head, 71, 71, fail );
        #I  after order 71 element: have 189 classes
        gap> ExtendTableHeadByCentralizerOrder( head, 71, 71, fail );
        #I  after order 71 element: have 190 classes

### 4.13 Classes of elements of order divisible by 7

The subgroup 2.B yields a rational class `7A` with centralizer order 7 ·|He|.

        gap> s:= CharacterTable( "2.B" );;
        gap> pos:= Positions( OrdersClassRepresentatives( s ), 7 );
        [ 41 ]
        gap> ExtendTableHeadByPermCharValue( head, s, pi, pos );
        #I  after order 7 element from 2.B: have 191 classes
        gap> Last( head.SizesCentralizers ) = 7 * Size( CharacterTable( "He" ) );
        true

TODO: If I use the function `Last` then I need GAP 4.11.
TODO (used in the section about power maps): By additional arguments, we find that the `7A` centralizer has the structure 7 ×He, and the normalizer has the structure (7:3 ×He).2, a subdirect product of 7:6 and He.2.
Since He has a pair of Galois conjugate classes of element order 17, we get also a pair of Galois conjugate classes of element order 7 ·17 = 119.

        gap> ExtendTableHeadByCentralizerOrder( head, 119, 119, fail );
        #I  after order 119 element: have 192 classes
        gap> ExtendTableHeadByCentralizerOrder( head, 119, 119, fail );
        #I  after order 119 element: have 193 classes

The second class of elements of order 7, `7B`, is established by the fact that the subgroup 3.Fi24 contains two classes of elements of order 7, with different values of the degreee 196 883 character of M.

        gap> u:= CharacterTable( "3.Fi24" );;
        gap> cand:= Filtered( Irr( u ), x -> x[1] <= 196883 );;
        gap> rest:= Sum( cand{ [ 1, 4, 5, 7, 8 ] } );;
        gap> pos:= Positions( OrdersClassRepresentatives( u ), 7 );
        [ 41, 43 ]
        gap> rest{ pos };
        [ 50, 1 ]

TODO: argue that class 43 fuses to 7B (because 196883 restr. to 2.B has value 50 on 7A)
TODO: argue that the centralizer order of 7B is ...

        gap> ExtendTableHeadByCentralizerOrder( head, u, 7^5 * Factorial(7), [ 43 ] );
        #I  after order 7 element from 3.F3+.2: have 194 classes

Now the sum of class lengths in `head` is equal to the order of M.

        gap> Sum( head.SizesCentralizers, x -> head.Size / x ) = head.Size;
        true

We initialize the character table head of M.

        gap> m:= ConvertToCharacterTableNC( rec(
        >      UnderlyingCharacteristic:= 0,
        >      Size:= head.Size,
        >      SizesCentralizers:= head.SizesCentralizers,
        >      OrdersClassRepresentatives:= head.OrdersClassRepresentatives,
        >    ) );;

## 5 The power maps of M

Using the element orders of the class representatives of the table head of M, and the partial class fusions from the subgroups used in the previous sections, we compute approximations of the p-th power maps, for primes p up to the maximal element order in M.
Note that we have not yet determined which of the two possible character tables of the `3B` normalizer belongs to a subgroup of M, thus we exclude the corresponding partial fusion.

        gap> safe_fusions:= Filtered( head.fusions,
        >        r -> not IsIdenticalObj( r.subtable, facts[1] ) );;
        gap> Length( safe_fusions );
        6

First we initialize the class fusions, compatible with the definitions of the classes as given by the partial fusions which we have stored.

        gap> for r in safe_fusions do
        >      fus:= InitFusion( r.subtable, m );
        >      for i in [ 1 .. Length( r.map ) ] do
        >        if IsBound( r.map[i] ) then
        >          if IsInt( fus[i] ) then
        >            if fus[i] <> r.map[i] then
        >              Error( "fusion problem" );
        >            fi;
        >          elif IsInt( r.map[i] ) then
        >            if not r.map[i] in fus[i] then
        >              Error( "fusion problem" );
        >            fi;
        >          else
        >            if not IsSubset( fus[i], r.map[i] ) then
        >              Error( "fusion problem" );
        >            fi;
        >          fi;
        >          fus[i]:= r.map[i];
        >        fi;
        >      od;
        >      r.fus:= fus;
        >    od;

Next we initialize approximations of the power maps of the table of M, and improve them using the compatibility of these maps with the power maps of the subgroups w. r. t. the current knowledge of the class fusions. Note that also the knowledge about the class fusions increases this way.

        gap> maxorder:= Maximum( head.OrdersClassRepresentatives );
        119
        gap> powermaps:= [];;
        gap> primes:= Filtered( [ 1 .. maxorder ], IsPrimeInt );
        gap> for p in primes do
        >      powermaps[p]:= InitPowerMap( m, p );
        >      for r in safe_fusions do
        >        subpowermap:= PowerMap( r.subtable, p );
        >        if TransferDiagram( subpowermap, r.fus, powermaps[p] ) = fail then
        >          Error( "inconsistency" );
        >        fi;
        >      od;
        >    od;

We repeat applying the compatibility conditions until no further improvements are found.

        gap> found:= true;;
        gap> res:= "dummy";;  # avoid a syntax warning
        gap> while found do
        >      Print( "#I  start a round\n" );
        >      found:= false;
        >      for p in primes do
        >        for r in safe_fusions do
        >          subpowermap:= PowerMap( r.subtable, p );
        >          res:= TransferDiagram( subpowermap, r.fus, powermaps[p] );
        >          if res = fail then
        >            Error( "inconsistency" );
        >          elif ForAny( RecNames( res ), nam -> res.( nam ) <> [] ) then
        >            found:= true;
        >          fi;
        >        od;
        >      od;
        >    od;
        #I  start a round
        #I  start a round
        #I  start a round
        #I  start a round

Let us see where the power maps are still not determined uniquely, starting with the 5-th power map.

        gap> pos:= PositionsProperty( powermaps[5], IsList );
        [ 157, 158, 163, 164, 187, 188, 189, 190, 192, 193 ]
        gap> head.OrdersClassRepresentatives{ pos };
        [ 15, 15, 39, 39, 59, 59, 71, 71, 119, 119 ]

The ambiguities for the classes of the element orders 59, 71, and 119 are understandable: For each of these element orders, there is a pair of Galois conjugate classes, and the subgroups whose class fusions we have used do not contain these elements.
For each of the primes l ∈ { 59, 71 }, the field of l-th roots of unity contains a unique quadratic subfield, which is Q(√{−l}), and the p-th power map, for p coprime to l, fixes a class of element order l if and only if the Galois automorphism that raises l-th roots of unity to the p-th power fixes √{−l}.
In the case of element order l = 119 = 7 ·17, the field of l-th roots of unity contains the three quadratic subfields, Q(√{−7}), Q(√{17}), and Q(√{−119}). In order to decide which of them actually occurs, we look at a subgroup that contains elements of order 119. The `7A` centralizer in M has the structure 7 ×He, and the normalizer has the structure (7:3 ×He).2, a subdirect product of 7:6 and He.2, see Section 4.13.
The classes of element order 119 in the normalizer correspond to the classes of this element order in M, and the character values in ththe subgroup lie in the field Q(√{−119}).

        gap> u:= CharacterTable( "(7:3xHe):2" );;
        gap> ConstructionInfoCharacterTable( u );
        [ "ConstructIndexTwoSubdirectProduct", "7:3", "7:6", "He", "He.2",
          [ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
              130, 131, 132, 133, 134, 135, 207, 208, 209, 210, 211, 212,
              213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
              225, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307,
              308, 309, 310, 311, 312, 313, 314, 315 ], (), () ]
        gap> pos:= Positions( OrdersClassRepresentatives( u ), 119 );
        [ 52, 53 ]
        gap> f:= Field( Rationals, List( Irr( u ), x -> x[pos[1]] ) );;
        gap> Sqrt(-119) in f;
        true

We insert the relevant power map values.

        gap> for l in [ 59, 71, 119 ] do
        >      val:= Sqrt( -l );
        >      poss:= Positions( head.OrdersClassRepresentatives, l );
        >      for p in primes do
        >        if Gcd( l, p ) = 1 then
        >          if GaloisCyc( val, p ) = val then
        >            powermaps[p]{ poss }:= poss;
        >          else
        >            powermaps[p]{ poss }:= Reversed( poss );
        >          fi;
        >        fi;
        >      od;
        >    od;

Now p-th power maps, for p ≥ 17, are determined uniquely except for the images of two classes of element order 39. These classes had been found as roots of `3B` elements.

        gap> PositionsProperty( powermaps[17], IsList );
        [ 163, 164 ]
        gap> head.OrdersClassRepresentatives{ [ 163, 164 ] };
        [ 39, 39 ]
        gap> List( Filtered( head.fusions,
        >                    r -> IsSubset( r.map, [ 163, 164 ] ) ),
        >          r -> r.subtable );
        [ CharacterTable( "3^(1+12):6.Suz.2/[ 1, 19 ]" ) ]

In order to decide whether the p-th power map fixes or swaps the two classes, we consider the square roots of elements of order 78. There are three classes of element order 78 in M, a rational class that powers to `2A` and a pair of Galois conjugate classes that power to `2B`.

        gap> 78pos:= Positions( head.OrdersClassRepresentatives, 78 );
        [ 37, 132, 133 ]
        gap> head.fusions[1].subtable;
        CharacterTable( "2.B" )
        gap> Intersection( 78pos, head.fusions[1].map );
        [ 37 ]
        gap> s:= head.fusions[2].subtable;
        CharacterTable( "2^1+24.Co1" )
        gap> Intersection( 78pos, head.fusions[2].map );
        [ 132, 133 ]
        gap> Positions( head.fusions[2].map, 132 );
        [ 342 ]
        gap> Positions( head.fusions[2].map, 133 );
        [ 344 ]
        gap> PowerMap( s, 7 )[342];
        344

Since the `3B` normalizer in M contains a pair of Galois conjugate classes of element order 78 which power to the generators of the normal subgroup of order 3, these two classes fuse to the non-rational M-classes of elements of order 78, and their squares are the classes of element order 39 we are interested in.

        gap> poss:= Filtered( head.fusions, r -> IsSubset( r.map, [ 163, 164 ] ) );;
        gap> List( poss, r -> r.subtable );
        [ CharacterTable( "3^(1+12):6.Suz.2/[ 1, 19 ]" ) ]
        gap> Position( poss[1].map, 163 );
        173
        gap> Position( poss[1].map, 164 );
        174
        gap> List( facts, s -> Positions( OrdersClassRepresentatives( s ), 39 ) );
        [ [ 173, 174 ], [ 173, 174 ] ]
        gap> List( facts, s -> PowerMap( s, 7 )[173] );
        [ 174, 174 ]

The field of character values on the two classes of M is equal to the corresponding field of character values in the `3B` normalizer, which is Q(√{−39}). (Note that we have not yet decided which of the two candidate tables belong to the `3B` normalizer, but we get the same result for both candidates.)

        gap> fields:= List( facts,
        >                   s -> Field( Rationals, List( Irr( s ),
        >                                                x -> x[173] ) ) );;
        gap> Length( Set( fields ) );
        1
        gap> Sqrt(-39) in fields[1];
        true

Now we can set the power map values on the two classes.

        gap> val:= Sqrt( -39 );;
        gap> poss:= [ 163, 164 ];;
        gap> for p in primes do
        >      if Gcd( 39, p ) = 1 then
        >        if GaloisCyc( val, p ) = val then
        >          powermaps[p]{ poss }:= poss;
        >        else
        >          powermaps[p]{ poss }:= Reversed( poss );
        >        fi;
        >      fi;
        >    od;
        gap> List( powermaps, Indeterminateness );
        [ , 2048, 1536,, 4,, 2,,,, 2,, 9,,,, 1,, 1,,,, 1,,,,,, 1,, 1,,,,,, 1,,
          ,, 1,, 1,,,, 1,,,,,, 1,,,,,, 1,, 1,,,,,, 1,,,, 1,, 1,,,,,, 1,,,, 1,,
          ,,,, 1,,,,,,,, 1,,,, 1,, 1,,,, 1,, 1,,,, 1 ]

In the following, we use the two candidates for the `3B` normalizer table for answering most of the remaining questions about the power maps. Again, the answers are equal for both candidate tables.
First we initialize the class fusion from the first candidate table ...

        gap> r:= First( head.fusions, r -> IsIdenticalObj( r.subtable, facts[1] ) );;
        gap> fus:= InitFusion( r.subtable, m );;
        gap> for i in [ 1 .. Length( r.map ) ] do
        >      if IsBound( r.map[i] ) then
        >        if IsInt( fus[i] ) then
        >          if fus[i] <> r.map[i] then
        >            Error( "fusion problem" );
        >          fi;
        >        elif IsInt( r.map[i] ) then
        >          if not r.map[i] in fus[i] then
        >            Error( "fusion problem" );
        >          fi;
        >        else
        >          if not IsSubset( fus[i], r.map[i] ) then
        >            Error( "fusion problem" );
        >          fi;
        >        fi;
        >        fus[i]:= r.map[i];
        >      fi;
        >    od;
        gap> r.fus:= fus;;

... and the class fusion from the second candidate table, ...

        gap> r2:= First( head2.fusions, r -> IsIdenticalObj( r.subtable, facts[2] ) );;
        gap> fus2:= InitFusion( r2.subtable, m );;
        gap> for i in [ 1 .. Length( r2.map ) ] do
        >      if IsBound( r2.map[i] ) then
        >        if IsInt( fus2[i] ) then
        >          if fus2[i] <> r2.map[i] then
        >            Error( "fusion problem" );
        >          fi;
        >        elif IsInt( r2.map[i] ) then
        >          if not r2.map[i] in fus2[i] then
        >            Error( "fusion problem" );
        >          fi;
        >        else
        >          if not IsSubset( fus2[i], r2.map[i] ) then
        >            Error( "fusion problem" );
        >          fi;
        >        fi;
        >        fus2[i]:= r2.map[i];
        >      fi;
        >    od;
        gap> r2.fus:= fus2;;

... then we create an independent copy of the current approximations of power maps, and apply the consistency conditions for class fusion and power maps in the two cases.

        gap> powermaps2:= StructuralCopy( powermaps );;
        gap> s:= r.subtable;
        CharacterTable( "3^(1+12):6.Suz.2/[ 1, 19 ]" )
        gap> for p in primes do
        >      if TransferDiagram( PowerMap( s, p ), fus, powermaps[p] ) = fail then
        >        Error( "inconsistency" );
        >      fi;
        >    od;
        gap> s2:= r2.subtable;
        CharacterTable( "3^(1+12):6.Suz.2/[ 1, 20 ]" )
        gap> for p in primes do
        >      if TransferDiagram( PowerMap( s2, p ), fus2, powermaps2[p] ) = fail then
        >        Error( "inconsistency" );
        >      fi;
        >    od;
        gap> powermaps = powermaps2;
        true
        gap> List( powermaps, Indeterminateness );
        [ , 32, 64,, 1,, 1,,,, 1,, 1,,,, 1,, 1,,,, 1,,,,,, 1,, 1,,,,,, 1,,,,
          1,, 1,,,, 1,,,,,, 1,,,,,, 1,, 1,,,,,, 1,,,, 1,, 1,,,,,, 1,,,, 1,,,,,
          , 1,,,,,,,, 1,,,, 1,, 1,,,, 1,, 1,,,, 1 ]

One open question is about the squares of the non-rational classes of element order 78.

        gap> powermaps[2]{ [ 132, 133 ] };
        [ [ 163, 164 ], [ 163, 164 ] ]
        gap> pos78:= List( facts,
        >                  s -> Positions( OrdersClassRepresentatives( s ), 78 ) );
        [ [ 235, 236 ], [ 235, 236 ] ]
        gap> fus{ [ 235, 236 ] };
        [ [ 132, 133 ], [ 132, 133 ] ]
        gap> fus2{ [ 235, 236 ] };
        [ [ 132, 133 ], [ 132, 133 ] ]

We may identify one class of element order 78 in the `3B` normalizer with the corresponding class of M, and then draw conclusions.

        gap> fus[235]:= 132;;
        gap> fus2[235]:= 132;;
        gap> TransferDiagram( PowerMap( s, 2 ), fus, powermaps[2] ) <> fail;
        true
        gap> TransferDiagram( PowerMap( s2, 2 ), fus2, powermaps2[2] ) <> fail;
        true
        gap> powermaps = powermaps2;
        true
        gap> List( powermaps{ [ 2, 3 ] }, Indeterminateness );
        [ 8, 64 ]

Since also the cubes of the concerned classes of element order 39 are still not determined, this question is now decided using that the 2nd and the 3rd power map commute.

        gap> powermaps[3]{ [ 163, 164 ] };
        [ [ 183, 184 ], [ 183, 184 ] ]
        gap> TransferDiagram( powermaps[2], powermaps[3], powermaps[2] ) <> fail;
        true
        gap> List( powermaps{ [ 2, 3 ] }, Indeterminateness );
        [ 8, 16 ]

The next open question is about the cubes of elements of order 93. The classes of element order 93 -a pair of Galois conjugate classes- have been found inside subgroups of the type S3 ×th, and they do not occur in other subgroups we have considered. Thus we may choose which of them cubes to the first class of element order 31.

        gap> poss:= Filtered( head.fusions,
        >                     r -> 93 in OrdersClassRepresentatives( r.subtable ) );;
        gap> List( poss, r -> r.subtable );
        [ CharacterTable( "ThxSym(3)" ) ]
        gap> pos93:= Positions( head.OrdersClassRepresentatives, 93 );
        [ 152, 153 ]
        gap> powermaps[3]{ pos93 };
        [ [ 179, 180 ], [ 179, 180 ] ]
        gap> powermaps[3][152]:= 179;;
        gap> TransferDiagram( PowerMap( poss[1].subtable, 3 ), poss[1].fus,
        >                     powermaps[3] ) <> fail;
        true
        gap> List( powermaps{ [ 2, 3 ] }, Indeterminateness );
        [ 8, 4 ]

The next open question is about the cubes of elements of order 69. The classes of element order 69 -a pair of Galois conjugate classes- have been found inside subgroups of the type 3.Fi24, and they do not occur in other subgroups we have considered. Thus we may choose which of them cubes to the first class of element order 23.

        gap> poss:= Filtered( head.fusions,
        >                     r -> 69 in OrdersClassRepresentatives( r.subtable ) );;
        gap> List( poss, r -> r.subtable );
        [ CharacterTable( "3.F3+.2" ) ]
        gap> pos69:= Positions( head.OrdersClassRepresentatives, 69 );
        [ 142, 143 ]
        gap> powermaps[3]{ pos69 };
        [ [ 177, 178 ], [ 177, 178 ] ]
        gap> powermaps[3]{ [ 142, 143 ] }:= [ 177, 178 ];;
        gap> TransferDiagram( PowerMap( poss[1].subtable, 3 ), poss[1].fus,
        >                     powermaps[3] ) <> fail;
        true
        gap> List( powermaps{ [ 2, 3 ] }, Indeterminateness );
        [ 8, 1 ]

The next open question is about the squares of certain elements of order 46. There are two pairs of Galois conjugate classes of element order 46, and the 2nd power map is not yet determined for those classes which power to the class `2B`.

        gap> pos46:= Positions( head.OrdersClassRepresentatives, 46 );
        [ 26, 27, 118, 120 ]
        gap> powermaps[2]{ pos46 };
        [ 177, 178, [ 177, 178 ], [ 177, 178 ] ]
        gap> powermaps[23]{ pos46 };
        [ 2, 2, 44, 44 ]

We have defined the two classes of element order 23 as squares of those two classes of element order 46 that power to `2A`, and we have not yet distinguished the other two classes of element order 46. Thus we may set the power map values.

        gap> powermaps[2]{ [ 118, 120 ] }:= [ 177, 178 ];;
        gap> Indeterminateness ( powermaps[2] );
        2

Now just one value is left to be determined, the square of a class of element order 18 and centralizer order 3888.

        gap> powermaps[2][78];
        [ 155, 156 ]
        gap> head.OrdersClassRepresentatives[78];
        18
        gap> head.SizesCentralizers[78];
        3888

There are two classes with this property in M, both are roots of the generators of the normal subgroup of order 3 in 31+12.2.Suz.2, and the corresponding two classes in this subgroup have the same square.

        gap> Filtered( [ 1 .. Length( head.OrdersClassRepresentatives ) ],
        >              i -> head.OrdersClassRepresentatives[i] = 18 and
        >                   head.SizesCentralizers[i] = 3888 );
        [ 78, 79 ]
        gap> powermaps[3]{ [ 78, 79 ] };
        [ 52, 52 ]
        gap> powermaps[2][52];
        154
        gap> First( head.fusions, r -> 154 in r.map ).subtable;
        CharacterTable( "3^(1+12):6.Suz.2/[ 1, 19 ]" )
        gap> s:= facts[1];
        CharacterTable( "3^(1+12):6.Suz.2/[ 1, 19 ]" )
        gap> pos18:= Filtered( [ 1 .. NrConjugacyClasses( s ) ],
        >                i -> OrdersClassRepresentatives( s )[i] = 18 and
        >                     SizesCentralizers( s )[i] = 3888 );
        [ 67, 83 ]
        gap> PowerMap( s, 2 ){ pos18 };
        [ 24, 24 ]
        gap> s:= facts[2];
        CharacterTable( "3^(1+12):6.Suz.2/[ 1, 20 ]" )
        gap> pos18:= Filtered( [ 1 .. NrConjugacyClasses( s ) ],
        >                i -> OrdersClassRepresentatives( s )[i] = 18 and
        >                     SizesCentralizers( s )[i] = 3888 );
        [ 67, 83 ]
        gap> PowerMap( s, 2 ){ pos18 };
        [ 24, 24 ]

We set the last missing value, and improve the approximations of the class fusions we have used, by applying the consistency criteria.

        gap> powermaps[2][78]:= powermaps[2][79];;
        gap> for r in safe_fusions do
        >      if not TestConsistencyMaps( ComputedPowerMaps( r.subtable ), r.fus,
        >                                  powermaps ) then
        >        Error( "inconsistent!" );
        >      fi;
        >    od;
        gap> r:= First( head.fusions, r -> IsIdenticalObj( r.subtable, facts[1] ) );;
        gap> TestConsistencyMaps( ComputedPowerMaps( r.subtable ), r.fus,
        >                         powermaps );
        true
        gap> r2:= First( head2.fusions, r -> IsIdenticalObj( r.subtable, facts[2] ) );;
        gap> TestConsistencyMaps( ComputedPowerMaps( r2.subtable ), r2.fus,
        >                         powermaps );
        true
        gap> SetComputedPowerMaps( m, powermaps );

## 6 The degree 196 883 character χ of M

We know the values of the irreducible degree 196 883 character χ of M on the classes of 2.B, by Section 2.

        gap> r:= head.fusions[1];;
        gap> s:= r.subtable;
        CharacterTable( "2.B" )
        gap> cand:= Filtered( Irr( s ), x -> x[1] <= 196883 );;
        gap> List( cand, x -> x[1] );
        [ 1, 4371, 96255, 96256 ]
        gap> rest:= Sum( cand );;
        gap> rest[1];
        196883

Thus we know the values of χ on those classes of M that are known as images of the class fusion from 2.B. This yields 111 out of the 194 character values.

        gap> chi:= [];;
        gap> map:= r.fus;;
        gap> for i in [ 1 .. Length( map ) ] do
        >      if IsInt( map[i] ) then
        >        chi[ map[i] ]:= rest[i];
        >      fi;
        >    od;
        gap> Number( chi );
        111

Also the restriction of χ to 3.Fi24 is known, by Section 2. This yields 29 more character values.

        gap> r:= head.fusions[3];;
        gap> s:= r.subtable;
        CharacterTable( "3.F3+.2" )
        gap> cand:= Filtered( Irr( s ), x -> x[1] <= 196883 );;
        gap> rest:= Sum( cand{ [ 1, 4, 5, 7, 8 ] } );;
        gap> rest[1];
        196883
        gap> map:= r.fus;;
        gap> for i in [ 1 .. Length( map ) ] do
        >      if IsInt( map[i] ) then
        >        if IsBound( chi[ map[i] ] ) and chi[ map[i] ] <> rest[i] then
        >          Error( "inconsistency!" );
        >        fi;
        >        chi[ map[i] ]:= rest[i];
        >      fi;
        >    od;
        gap> Number( chi );
        140

Now we compute the restriction of χ to the `2B` normalizer. There are only 13 possible irreducible constituents of this restriction. We consider the matrix of values of these characters on those classes for which the class fusion to M is uniquely known and the value of χ on the image class is known. This matrix has full rank, thus we can directly compute the decomposition of the restriction into irreducibles, and get 41 more character values.

        gap> r:= head.fusions[2];;
        gap> s:= r.subtable;
        CharacterTable( "2^1+24.Co1" )
        gap> cand:= Filtered( Irr( s ), x -> x[1] <= chi[1] );;
        gap> map:= r.fus;;
        gap> knownpos:= Filtered( [ 1 .. Length( map ) ],
        >                      i -> IsInt( map[i] ) and IsBound( chi[ map[i] ] ) );;
        gap> rest:= List( knownpos, i -> chi[ map[i] ] );;
        gap> mat:= List( cand, x -> x{ knownpos } );;
        gap> Length( mat );
        13
        gap> RankMat( mat );
        13
        gap> sol:= SolutionMat( mat, rest );
        [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 ]
        gap> rest:= sol * cand;;
        gap> for i in [ 1 .. Length( map ) ] do
        >      if IsInt( map[i] ) then chi[ map[i] ]:= rest[i]; fi;
        >    od;
        gap> Number( chi );
        181

Which values are still missing?

        gap> missing:= Filtered( [ 1..194 ], i -> not IsBound( chi[i] ) );
        [ 151, 152, 153, 160, 169, 170, 186, 187, 188, 189, 190, 192, 193 ]
        gap> head.OrdersClassRepresentatives{ missing };
        [ 57, 93, 93, 27, 95, 95, 41, 59, 59, 71, 71, 119, 119 ]
        gap> head.SizesCentralizers{ missing };
        [ 57, 93, 93, 243, 95, 95, 41, 59, 59, 71, 71, 119, 119 ]

For g ∈ M, we have χ(g) ≡ χ(gp) mod p and |χ(g)|2 < |CM(g)|. We apply these conditions. In all cases except one, the centralizer orders are small enough for determining the character value uniquely.

        gap> for i in missing do
        >      ord:= head.OrdersClassRepresentatives[i];
        >      divs:= PrimeDivisors( ord );
        >      if ForAll( divs, p -> IsBound( chi[ powermaps[p][i] ] ) ) then
        >        congr:= List( divs, p -> chi[ powermaps[p][i] ] mod p );
        >        res:= ChineseRem( divs, congr );
        >        modulus:= Lcm( divs );
        >        c:= head.SizesCentralizers[i];
        >        Print( "#I  |g| = ", head.OrdersClassRepresentatives[i],
        >               ", |C_M(g)| = ", c,
        >               ": value ", res, " modulo ", modulus, "\n" );
        >        if ( res + 2 * modulus )^2 >= c and ( res - 2 * modulus )^2 >= c then
        >          cand:= Filtered( res + [ -1 .. 1 ] * modulus, a -> a^2 < c );
        >          if Length( cand ) = 1 then
        >            chi[i]:= cand[1];
        >          fi;
        >        fi;
        >      fi;
        >    od;
        #I  |g| = 57, |C_M(g)| = 57: value 56 modulo 57
        #I  |g| = 93, |C_M(g)| = 93: value 92 modulo 93
        #I  |g| = 93, |C_M(g)| = 93: value 92 modulo 93
        #I  |g| = 27, |C_M(g)| = 243: value 2 modulo 3
        #I  |g| = 95, |C_M(g)| = 95: value 0 modulo 95
        #I  |g| = 95, |C_M(g)| = 95: value 0 modulo 95
        #I  |g| = 41, |C_M(g)| = 41: value 1 modulo 41
        #I  |g| = 59, |C_M(g)| = 59: value 0 modulo 59
        #I  |g| = 59, |C_M(g)| = 59: value 0 modulo 59
        #I  |g| = 71, |C_M(g)| = 71: value 0 modulo 71
        #I  |g| = 71, |C_M(g)| = 71: value 0 modulo 71
        #I  |g| = 119, |C_M(g)| = 119: value 118 modulo 119
        #I  |g| = 119, |C_M(g)| = 119: value 118 modulo 119
        gap> missing:= Filtered( [ 1..194 ], i -> not IsBound( chi[i] ) );
        [ 160 ]

The one missing value can be computed from the scalar product with the trivial character.

        gap> diff:= Difference( [ 1 .. NrConjugacyClasses( m ) ], missing );;
        gap> classes:= SizesConjugacyClasses( m );;
        gap> sum:= Sum( diff, i -> classes[i] * chi[i] );
        -6650349175263480459970863415322722279882752000000000
        gap> chi[ missing[1] ]:= - sum / classes[ missing[1] ];
        2

Now we decide which of the two candidates for the character table of the `3B` normalizer is the correct one. For the first candidate, the restriction of χ cannot be decomposed into irreducibles.

        gap> r:= First( head.fusions, r -> IsIdenticalObj( r.subtable, facts[1] ) );;
        gap> map:= r.fus;;
        gap> knownpos:= Filtered( [ 1 .. Length( map ) ], i -> IsInt( map[i] ) );;
        gap> rest:= List( knownpos, i -> chi[ map[i] ] );;
        gap> cand:= Filtered( Irr( r.subtable ), x -> x[1] <= chi[1] );;
        gap> mat:= List( cand, x -> x{ knownpos } );;
        gap> Length( mat );
        95
        gap> RankMat( mat );
        88
        gap> SolutionMat( mat, rest );
        fail

The second candidate admits a decomposition.

        gap> r2:= First( head2.fusions, r -> IsIdenticalObj( r.subtable, facts[2] ) );;
        gap> map:= r2.fus;;
        gap> knownpos:= Filtered( [ 1 .. Length( map ) ], i -> IsInt( map[i] ) );;
        gap> rest:= List( knownpos, i -> chi[ map[i] ] );;
        gap> cand:= Filtered( Irr( r2.subtable ), x -> x[1] <= chi[1] );;
        gap> mat:= List( cand, x -> x{ knownpos } );;
        gap> Length( mat );
        95
        gap> RankMat( mat );
        88
        gap> SolutionMat( mat, rest );
        [ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 1, 1, 1, 0 ]
        gap> Add( safe_fusions, r2 );

The character table of the second candidate is equivalent to the character table that is stored in the GAP character table library.

        gap> TransformingPermutationsCharacterTables( r2.subtable,
        >        CharacterTable( "MN3B" ) ) <> fail;
        true

## 7 The irreducible characters of M

We will not compute the irreducibles of M from scratch but verify the irreducibles from the ATLAS character table of M, in the sense that we use the characters printed in the ATLAS as an "oracle". For that, we compute first a bijection between the columns of our character table head and those of the ATLAS character table of M. This is done by using the following invariants: element orders, centralizer orders, the values of χ, and the indirection of χ by the 2nd power map.

        gap> invs:= TransposedMat( [
        >      OrdersClassRepresentatives( m ),
        >      SizesCentralizers( m ),
        >      chi,
        >      CompositionMaps( chi, PowerMap( m, 2 ) ) ] );;
        gap> invs_set:= Set( invs );;
        gap> Length( invs_set );
        172
        gap> atlas_m:= CharacterTable( "M" );;
        gap> invs_atlas:= TransposedMat( [
        >      OrdersClassRepresentatives( atlas_m ),
        >      SizesCentralizers( atlas_m ),
        >      Irr( atlas_m )[2],
        >      CompositionMaps( Irr( atlas_m )[2], PowerMap( atlas_m, 2 ) ) ] );;
        gap> invs_atlas_set:= Set( invs_atlas );;
        gap> invs_atlas_set = invs_set;
        true

In particular, we see that the sets of invariants are equal for the two tables.
Note that we cannot get a better choice of invariants, since there are 22 pairs of Galois conjugate classes in M, and our current knowledge does not allow us to distinguish the classes of each pair.
Now we compute a permutation that maps the classes of the ATLAS table to suitable classes of our table head, permute the irreducibles of the ATLAS table accordingly, and create the "oracle" list.
(The explicit permutation (32,33)(179,180) makes sure that the power maps of the ATLAS table and of our table are compatible.)

        gap> pi1:= SortingPerm( invs );;
        gap> pi2:= SortingPerm( invs_atlas );;
        gap> pi:= pi2 / pi1 * (32,33)(179,180);;
        gap> oracle:= List( Irr( atlas_m ), x -> Permuted( x, pi ) );;

In order to prohibit that GAP tries to compute table automorphisms of our table head of M (which is impossible without knowing the irreducible characters), we set a trivial group as value of the attribute `AutomorphismsOfTable`; this will be revised as soon as the irreducibles are known.

        gap> SetAutomorphismsOfTable( m, Group( () ) );

First we compute candidates for the class fusion from 2.B, starting from the approximation we have already computed. Before we apply GAP's criteria for computing possible class fusions, we decide about the images of four classes of element orders 40 and 44.

        gap> r:= safe_fusions[1];;
        gap> s:= r.subtable;
        CharacterTable( "2.B" )
        gap> pos:= [ 217, 218, 222, 223 ];;
        gap> r.fus{ pos };
        [ [ 110, 111 ], [ 110, 111 ], [ 88, 89 ], [ 88, 89 ] ]
        gap> OrdersClassRepresentatives( s ){ pos };
        [ 40, 40, 44, 44 ]

The two classes of element order 40 are a pair of Galois conjugates in both 2.B and M. Note that their elements are roots of `2B` elements in M, and the classes 110 and 111 correspond to non-rational elements of order 40 in the `2B` normalizer.

        gap> r.fus[ PowerMap( s, 20 )[217] ];
        44
        gap> r2:= safe_fusions[2];;
        gap> s2:= r2.subtable;
        CharacterTable( "2^1+24.Co1" )
        gap> Position( r2.map, 110 );
        273
        gap> ForAll( Irr( s2 ), x -> IsInt( x[273] ) );
        false

We may freely choose the fusion from the classes 217 and 218 of 2.B because there is a table automorphism of 2.B that swaps exactly these two classes.

        gap> (217,218) in AutomorphismsOfTable( s );
        true
        gap> r.fus{ [ 217, 218 ] }:= [ 110, 111 ];;

With the same argument, also the two classes of element order 44 are a pair of Galois conjugates both in 2.B and M.

        gap> r.fus[ PowerMap( s, 22 )[ 222 ] ];
        44
        gap> Position( r2.map, 88 );
        178
        gap> ForAll( Irr( s2 ), x -> IsInt( x[178] ) );
        false

There is a table automorphism of 2.B that swaps three pairs of classes, where the classes of element order 44 form one pair, and each of the other two pairs is fused in M. Thus we may again freely choose the fusion from 222 and 223.

        gap> (143,144)(222,223)(244,245) in AutomorphismsOfTable( s );
        true
        gap> r.fus{ [ 143, 144, 244, 245 ] };
        [ 15, 15, 34, 34 ]
        gap> r.fus{ [ 222, 223 ] }:= [ 88, 89 ];;

Now the remaining open questions about the class fusion from 2.B can be answered by the GAP's function `PossibleClassFusions`.

        gap> knownirr:= [ TrivialCharacter( m ), chi ];;
        gap> poss:= PossibleClassFusions( s, m,
        >               rec( chars:= knownirr, fusionmap:= r.fus ) );;
        gap> List( poss, Indeterminateness );
        [ 1 ]

Now we can induce the irreducibles of 2.B to M.

        gap> induced:= InducedClassFunctionsByFusionMap( s, m, Irr( s ), poss[1] );;

Next we compute candidates for the class fusions from the subgroups 21+24.Co1, 31+12.2.Suz.2, and 3.Fi24. Here we enter also the characters of M obtained by induction from 2.B, because their restrictions to the subgroups provide additional conditions.
The fusion from 21+24.Co1 is determined uniquely up to automorphisms of the subgroup table. We extend the list of known induced characters.

        gap> poss:= PossibleClassFusions( s2, m,
        >               rec( chars:= Concatenation( knownirr, induced ),
        >                    fusionmap:= r2.fus ) );;
        gap> List( poss, Indeterminateness );
        [ 1 ]
        gap> Append( induced,
        >        InducedClassFunctionsByFusionMap( s2, m, Irr( s2 ), poss[1] ) );

In order to compute the fusion from 31+12.2.Suz.2, we have to consider two classes of element order 56 first. They are a pair of Galois conjugates both in 31+12.2.Suz.2 and M, and we may freely choose their fusion because there is a table automorphism of 31+12.2.Suz.2 that swaps exactly these two classes.

        gap> r:= safe_fusions[7];;
        gap> s:= r.subtable;
        CharacterTable( "3^(1+12):6.Suz.2/[ 1, 20 ]" )
        gap> pos:= Positions( OrdersClassRepresentatives( s ), 56 );
        [ 250, 251 ]
        gap> r.fus{ pos };
        [ [ 125, 126 ], [ 125, 126 ] ]
        gap> r.fus[ PowerMap( s, 28 )[ 250 ] ];
        44
        gap> Position( r2.map, 125 );
        319
        gap> ForAll( Irr( s2 ), x -> IsInt( x[319] ) );
        false
        gap> (250, 251) in AutomorphismsOfTable( s );
        true
        gap> r.fus{ [ 250, 251 ] }:= [ 125, 126 ];;

Now the class fusion to M is determined uniquely, and we extend the list of induced characters.

        gap> poss:= PossibleClassFusions( s, m,
        >               rec( chars:= Concatenation( knownirr, induced ),
        >                    fusionmap:= r.fus ) );;
        gap> List( poss, Indeterminateness );
        [ 1 ]
        gap> Append( induced,
        >        InducedClassFunctionsByFusionMap( s, m, Irr( s ), poss[1] ) );

The fusion from 3.Fi24 is determined uniquely up to automorphisms of the subgroup table. We extend the list of known induced characters.

        gap> r:= safe_fusions[3];;
        gap> s:= r.subtable;
        CharacterTable( "3.F3+.2" )
        gap> poss:= PossibleClassFusions( s, m,
        >               rec( chars:= Concatenation( knownirr, induced ),
        >                    fusionmap:= r.fus ) );;
        gap> List( poss, Indeterminateness );
        [ 1 ]
        gap> Append( induced,
        >        InducedClassFunctionsByFusionMap( s, m, Irr( s ), poss[1] ) );

Next we induce the irreducible characters of cyclic subgroups.

        gap> Append( induced,
        >      InducedCyclic( m, [ 2 .. NrConjugacyClasses( m ) ], "all" ) );

Now we reduce the induced characters with the two known irreducibles of M, and apply the LLL algorithm to the result of the reduction; this yields four new irreducibles.

        gap> red:= Reduced( m, knownirr, induced );;
        gap> Length( red.irreducibles );
        0
        gap> lll:= LLL( m, red.remainders );;
        gap> Length( lll.irreducibles );
        4

We extend the list of known irreducibles, reduce the induced characters, and apply LLL again.

        gap> knownirr:= Union( knownirr, lll.irreducibles );;
        gap> red:= Reduced( m, knownirr, induced );;
        gap> Length( red.irreducibles );
        0
        gap> lll:= LLL( m, red.remainders );;
        gap> Length( lll.irreducibles );
        0

Now we use the irreducibles of the ATLAS table of M as an oracle, as follows. Whenever an character from the oracle list belongs to the Z-lattice that is spanned by `lll.remainders` then we regard this character as verified, since we can compute the coefficients of the Z-linear combination, form the character, and check that it has indeed norm 1.

        gap> mat:= MatScalarProducts( m, oracle, lll.remainders );;
        gap> norm:= NormalFormIntMat( mat, 4 );;
        gap> rowtrans:= norm.rowtrans;;
        gap> normal:= norm.normal{ [ 1 .. norm.rank ] };;
        gap> one:= IdentityMat( NrConjugacyClasses( m ) );;
        gap> for i in [ 2 .. Length( one ) ] do
        >      extmat:= Concatenation( normal, [ one[i] ] );
        >      extlen:= Length( extmat );
        >      extnorm:= NormalFormIntMat( extmat, 4 );
        >      if extnorm.rank = Length( extnorm.normal ) or
        >         extnorm.rowtrans[ extlen ][ extlen ] <> 1 then
        >        coeffs:= fail;
        >      else
        >        coeffs:= - extnorm.rowtrans[ extlen ]{ [ 1 .. extnorm.rank ] }
        >                   * rowtrans{ [ 1 .. extnorm.rank ] };
        >      fi;
        >      if coeffs <> fail and ForAll( coeffs, IsInt ) then
        >        # The vector lies in the lattice.
        >        chi:= coeffs * lll.remainders;
        >        if not chi in knownirr then
        >          Add( knownirr, chi );
        >        fi;
        >      fi;
        >    od;
        gap> Length( knownirr );
        66
        gap> Set( knownirr, chi -> ScalarProduct( m, chi, chi ) );
        [ 1 ]

We reduce the generators of the Z-lattice and some symmetrizations of the known irreducibles with the known irreducibles, and apply LLL again.

        gap> red:= Reduced( m, knownirr, lll.remainders );;
        gap> Length( red.irreducibles );
        0
        gap> sym:= Symmetrizations( m, knownirr, 2 );;
        gap> sym:= Reduced( m, knownirr, sym );;
        gap> Length( sym.irreducibles );
        0
        gap> lll:= LLL( m, Concatenation( red.remainders, sym.remainders ) );;
        gap> Length( lll.irreducibles );
        0

We use the above oracle again, for the new Z-lattice.

        gap> mat:= MatScalarProducts( m, oracle, lll.remainders );;
        gap> norm:= NormalFormIntMat( mat, 4 );;
        gap> rowtrans:= norm.rowtrans;;
        gap> normal:= norm.normal{ [ 1 .. norm.rank ] };;
        gap> one:= IdentityMat( NrConjugacyClasses( m ) );;
        gap> for i in [ 2 .. Length( one ) ] do
        >      extmat:= Concatenation( normal, [ one[i] ] );
        >      extlen:= Length( extmat );
        >      extnorm:= NormalFormIntMat( extmat, 4 );
        >      if extnorm.rank = Length( extnorm.normal ) or
        >         extnorm.rowtrans[ extlen ][ extlen ] <> 1 then
        >        coeffs:= fail;
        >      else
        >        coeffs:= - extnorm.rowtrans[ extlen ]{ [ 1 .. extnorm.rank ] }
        >                   * rowtrans{ [ 1 .. extnorm.rank ] };
        >      fi;
        >      if coeffs <> fail and ForAll( coeffs, IsInt ) then
        >        Add( knownirr, coeffs * lll.remainders );
        >      fi;
        >    od;
        gap> Length( knownirr );
        194

Now we are done.

        gap> SetIrr( m, List( knownirr, x -> ClassFunction( m, x ) ) );
        gap> ResetFilterObj( m, HasAutomorphismsOfTable );
        gap> TransformingPermutationsCharacterTables( m, atlas_m ) <> fail;
        true

## 8 Appendix: The character table of 21+24.Co1

TODO: GAP code to describe the construction of the character table.
By ..., we know that the centralizer C of a `2B` element in M has the structure 21+24.Co1, which can be constructed as follows.
Consider a subdirect product H of two groups H/X and H/N, where X is a cyclic group of order two, N is an extraspecial group 21+24+, H/N is the double cover of Co1, and H/X is an extension of 21+24+ by Co1.
The centre of H is a Klein four group E whose order two subgroups are X, Y = Z(N), and a third subgroup D. We have C ≅ H/D.
Figure
Picture Omitted
From the explicit construction of a representation for M in [], we know the following representations, given by generators tat are preimages of standard generators of Co1.

- a monomial permutation representation of H/E ≅ 224.Co1, of degree 98 280 over the field with three elements,
- a matrix representation of H/X ≅ 21+24+.Co1, of dimension 4 096 over the field with three elements,
- a matrix representation of H/U ≅ 2.Co1, of dimension 24 over the field with three elements.

The tensor product of the two matrix representations is a faithful representation of H, such that D is represented by scalar matrices.
We proceed in the following steps.
A faithful permutation representation of H/Y on ... points is obtained by glueing the permutation generators of H/E and H/U together. The character table of this group can be computed directly with MAGMA.
Starting from the character table of the factor group H/E, the representation ... is used to compute the class splitting to H/X, as follows. The given 3-modular representation of degree 4096 lifts to characteristic zero because the restriction to the extraspecial group M/X is the unique faithful irreducible 3-modular representation of M/X, and because this representation extends to the full automorphism group of the extraspecial group, in particular to its subgroup Co1. Thus we can compute the Brauer character values of the representation on the 3-regular classes of H/X, and interpret the values as those of an ordinary character ψ, say. The tensor square ψ2 belongs to the group H/E, and the known values of ψ suffice to determine the decomposition of ψ2 into irreducibles of H/E, and thus to compute all values of ψ2. Taking square roots, we get all values of ψ, up to signs, which just means that we cannot distinguish which of the two values belongs to which of the two preimage classes.
From now on, we can argue character-theoretically.
The missing irreducible characters of H/X are computed as tensor products of χ with the irreducible characters of the factor group H/M ≅ Co1.
We compute the columns of the character table of H, together with the class fusions to the known tables of H/X and H/Y. For that, ...
The missing irreducible characters of H are now obtained by tensoring those irreducible characters of the two factor groups that do not contain E in their kernels, and applying the LLL algorithm.
Finally, we can compute the power maps (and thus the element orders) of the character table of H.

## 9 Appendix: The character table of 31+12.6.Suz.2

### 9.1 Overview

The `3B` normalizer in M has the structure 31+12+.2.Suz.2. Its character table has been computed by Richard Barraclough and Robert A. Wilson, see [BW07]. In order to describe a reproducible construction of the character table that does not assume the character table of M, we recompute this table.
Our approach is similar to that in [BW07]: The subgroup in question is a factor group of the split extension H of the extraspecial group N = 31+12+ by 6.Suz.2, and we compute the character table of this bigger group H.
Figure
Picture Omitted
We have H / N ≅ 6.Suz.2. Let M be the normal subgroup of H above N such that H / M ≅ 2.Suz.2 holds. Then M = X ×N for a normal subgroup X of order 3, where the extension of M / X by H / M is split.
Let Y = Z(N), of order 3. Then E = X ×Y ≅ 32 is elementary abelian, with diagonal normal subgroups D1 and D2. It will turn out that the extensions of M / D1 and M / D2 by H / M are non-split.
H / Y is a subdirect product of H / N and H / E ≅ 312.2.Suz.2, we have H / Y ≅ (3 ×312).2.Suz.2.
The `3B` normalizer in M is isomorphic to one of the two factor groups H / D1, H / D2. (We will decide at a later stage which of the two groups occurs as a subgroup of M.)
We use the following approach to compute the character table of H.

- Compute permutation generators `gensHmodX` and `gensHmodE` of H / X and H / E, of degrees 313 and 98 280, respectively, see Section 9.2. The first two generators are standard generators of 2.Suz.2, the third generator lies in M / X and M / E, respectively.
- Compute permutation generators `gensHmodY` of H / Y, of degree 103 626 = 98 280 + 5 346, see Section 9.3. The first two generators are standard generators of 6.Suz.2, the third generator lies in N / Y.
- Compute permutation generators `gensH` of H, of degree 1 599 669 = 1 594 323 + 5 346, see Section 9.4. The first two generators are standard generators of 6.Suz.2, the third generator lies in N.
- Compute class representatives of H / Y from `gensHmodY`, see Section 9.5.
- Compute class representatives of H from `gensH`, and the class fusion from H to H / Y, see Section 9.6.
- Compute the character table of H / Y, using MAGMA, see Section 9.7.
- Compute the class fusions from H to H / X, H / D1, and H / D2, see Section 9.8.
- Compute the character table head of H, that is, compute the relevant p-th power maps of H, see Section 9.9.
- Compute the character table of a subgroup of H, see Section 9.10.
- Complete the missing irreducible characters of H, using character theoretic methods, see Section 9.11.

Note that our faithful permutation representation of H / Y, of degree ..., is small enough for an automatic computation of the character table of the group with MAGMA, whereas it is apparently hard to perform conjugacy tests in the faithful permutation representation of H, of degree ....

### 9.2 Permutation representations of H / E and H / X

The ATLAS of Group Representations [WWT+] contains a faithful representation of H, as a group of 38 ×38 matrices over the field with three elements. The generating matrices are called `M3max7G0-f3r38B0.m1`, ... `M3max7G0-f3r38B0.m4`. These matrices are block diagonal matrices with blocks of the lengths 24 and 14.

        gap> info:= OneAtlasGeneratingSetInfo( "3^(1+12):6.Suz.2", Dimension, 38 );;
        gap> gens:= AtlasGenerators( info ).generators;;
        gap> Length( gens );
        4
        gap> ForAll( gens,
        >            m -> ForAll( [ 25 .. 38 ],
        >                         i -> ForAll( [ 1 .. 24 ],
        >                                      j -> IsZero( m[i,j] ) and
        >                                           IsZero( m[i,j] ) ) ) );
        true

Here we will use just in the lower right 14 ×14 blocks, which generate the factor group H / X ≅ 31+12+:2.Suz.2. (Note that the 12-dimensional irreducible representation of 2.Suz.2 over the field with 3 elements respects a symplectic form, and the embedding of 2.Suz.2 into Sp(12,3) -which is the automorphism group of the extraspecial group 31+12+- yields a construction of the semidirect product 31+12+:2.Suz.2 as a group of 14 ×14 matrices.)
Later we will construct a faithful permutation representation of H as a subdirect product of H / X and H / N ≅ 6.Suz.2. Let `g` be the group generated by the 14 ×14 matrices.
When one deals with H / X, the fourth generator is redundant, we will leave it out in the following.

        gap> mats:= List( gens, x -> x{ [ 25 .. 38 ] }{ [ 25 .. 38 ] } );;
        gap> List( mats, ConvertToMatrixRep );;
        gap> Comm( mats[3], mats[3]^mats[2] ) = Inverse( mats[4] );
        true
        gap> mats:= mats{ [ 1 .. 3 ] };;

We use just the following facts. The `g`-action on GF(3)14 has six orbits, from which we get a faithful permutation representation `homHtoHmodE` of H / E ≅ 312.2.Suz.2 on 196 560 points and a faithful representation `homHtoHmodX` of a group of the structure 31+12.2.Suz.2 on 1 594 323 points. Since the image contains a subgroup 2.Suz.2, the image is the split extension H / X of 31+12 by 2.Suz.2.

        gap> g:= GroupWithGenerators( mats );;
        gap> orbs:= ShallowCopy( OrbitsDomain( g, GF(3)^14 ) );;
        gap> Length( orbs );
        6
        gap> SortBy( orbs, Length );
        gap> List( orbs, Length );
        [ 1, 2, 196560, 1397760, 1594323, 1594323 ]
        gap> orb_small:= SortedList( First( orbs, x -> Length( x ) = 196560 ) );;
        gap> List( orb_small[1], Int );
        [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0 ]
        gap> homHtoHmodE:= ActionHomomorphism( g, orb_small );;
        gap> represHmodE:= Image( homHtoHmodE );;
        gap> Size( represHmodE );
        953076718360166400
        gap> Size( represHmodE ) = Size( CharacterTable( "2.Suz.2" ) ) * 3^12;
        true
        gap> v:= [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 ] * Z(3)^0;;
        gap> orb_large:= First( orbs, x -> v in x );;
        gap> Length( orb_large );
        1594323
        gap> Length( orb_large ) = 3^13;
        true
        gap> orb_large:= SortedList( orb_large );;
        gap> homHtoHmodX:= ActionHomomorphism( g, orb_large );;
        gap> represHmodX:= Image( homHtoHmodX );;
        gap> Print( "make the following faster!\n" );
        gap> Size( represHmodX );  # this takes a very long time!
        2859230155080499200
        gap> Size( represHmodX ) = Size( CharacterTable( "2.Suz.2" ) ) * 3^13;
        true

We conclude that the action on 196 560 points represents the group H / E. As for the action on 1 594 323 points, we show that it has a nonabelian normal subgroup of the order 313.

        gap> gensHmodX:= List( mats, m -> m^homHtoHmodX );;
        gap> n:= NormalClosure( represHmodX,
        >                       Subgroup( represHmodX, [ gensHmodX[3] ] ) );;
        gap> Size( n ) = 3^13;
        true
        gap> IsAbelian( n );
        false

In order to simplify later computations, we reduce the degree of the representation of H / E.

        gap> bl:= Blocks( represHmodE, MovedPoints( represHmodE ) );;
        gap> Length( bl[1] );
        2
        gap> acthom:= ActionHomomorphism( represHmodE, bl, OnSets );;
        gap> img:= Image( acthom );;
        gap> Size( img ) = Size( represHmodE );
        true
        gap> gensHmodE:= List( mats, m -> (m^homHtoHmodE)^acthom );;
        gap> NrMovedPoints( gensHmodE );
        98280

We have to show that the first two elements from both generating sets are standard generators of 2.Suz.2. For that, we first show that these elements are preimages of standard generators of Suz.2, by computing that the words in question lie in the centre of 2.Suz.2, and then show that the elements satisfy the conditions of standard generators of 2.Suz.2, that is, the second generator has order 3, see the page on Suz in the ATLAS of Group Representations [WWT+].

        gap> slp:= AtlasProgram( "Suz.2", "check" );;
        gap> prog:= StraightLineProgramFromStraightLineDecision( slp.program );;
        gap> res:= ResultOfStraightLineProgram( prog, gensHmodE );;
        gap> List( res, Order );
        [ 2, 1, 2, 1 ]
        gap> ForAll( gensHmodE{ [ 1, 2 ] }, x -> ForAll( res, y -> x*y = y*x ) );
        true
        gap> Order( gensHmodE[2] );
        3
        gap> res:= ResultOfStraightLineProgram( prog, gensHmodX );;
        gap> List( res, Order );
        [ 2, 1, 2, 1 ]
        gap> ForAll( gensHmodX{ [ 1, 2 ] }, x -> ForAll( res, y -> x*y = y*x ) );
        true
        gap> Order( gensHmodX[2] );
        3

### 9.3 A permutation representation of H / Y

The group H / Y is a subdirect product of H / E and H / N ≅ 6.Suz.2, w.r.t. the common factor group H / M ≅ 2.Suz.2. Let N2 be the normal subgroup of H such that N has index 2 in N2, and set M2 = M N2. Then H / Y is a subdirect product of H / E and H / N2 ≅ 3.Suz.2, w.r.t. the common factor group H / M2 ≅ Suz.2. Since we know that our generators for H / E are compatible with standard generators of the factor group Suz.2, it is sufficient to form the diagonal product of our representation of H / E and a representation of 3.Suz.2 on standard generators.

        gap> 3suz2:= OneAtlasGeneratingSet( "3.Suz.2", NrMovedPoints, 5346 );;
        gap> 3suz2:= 3suz2.generators;;
        gap> omega:= [ 1 .. LargestMovedPoint( 3suz2 ) ];;
        gap> shifted:= omega + LargestMovedPoint( gensHmodE );;
        gap> pi:= MappingPermListList( omega, shifted );;
        gap> shiftedgens:= List( 3suz2, x -> x^pi );;
        gap> Append( shiftedgens, [ () ] );
        gap> gensHmodY:= List( [ 1 .. 3 ], i -> gensHmodE[i] * shiftedgens[i] );;
        gap> NrMovedPoints( gensHmodY );
        103626

The first two of the generators are standard generators of 6.Suz.2. We now already that they are preimages of standard generators of Suz.2, it remains to show that they are elements C, D where D has order 3 and CDCDD has order 7.

        gap> Order( gensHmodY[2] );
        3
        gap> Order( Product( gensHmodY{ [ 1, 2, 1, 2, 2 ] } ) );
        7

### 9.4 A permutation representation of H

Analogously, we view H as a subdirect product of H / X and H / N2, and construct generators from `gensHmodX` and standard generators of 3.Suz.2.

        gap> shifted:= omega + LargestMovedPoint( gensHmodX );;
        gap> pi:= MappingPermListList( omega, shifted );;
        gap> shiftedgens:= List( 3suz2, x -> x^pi );;
        gap> Append( shiftedgens, [ () ] );
        gap> gensH:= List( [ 1 .. 3 ], i -> gensHmodX[i] * shiftedgens[i] );;
        gap> NrMovedPoints( gensH );
        1599669

Again, the first two of the generators are standard generators of 6.Suz.2.

        gap> Order( gensH[2] );
        3
        gap> Order( Product( gensH{ [ 1, 2, 1, 2, 2 ] } ) );
        7

### 9.5 Class representatives of H / Y

Our aim is to compute a straight line program that takes the generators `gensHmodY` as inputs and returns class representatives of H / Y.
We proceed in several steps.

- Compute class representatives of Suz.2 from standard generators of Suz.2, see Section 9.5.1.
- Compute class representatives of 6.Suz.2 from standard generators of 6.Suz.2, see Section 9.5.2.
- Compute class representatives of H / Y from the generators `gensHmodY`, see Section 9.5.3.

#### 1 Class representatives of Suz.2

There is no "official" straight line program yet for this purpose, thus we have to work.
We start with standard generators of Suz.2 in a permutation representation on 1782 points, and restrict the representation to Suz (the first maximal subgroup). We are lucky, the generators turn out to be standard generators of Suz.

        gap> suz2:= AtlasGroup( "Suz.2" );;
        gap> suzinsuz2:= AtlasProgram( "Suz.2", "maxes", 1 );;
        gap> suzgens:= ResultOfStraightLineProgram( suzinsuz2.program,
        >                  GeneratorsOfGroup( suz2 ) );;
        gap> NrMovedPoints( suzgens );
        1782
        gap> ResultOfStraightLineDecision( AtlasProgram( "Suz", "check" ).program,
        >        suzgens );
        true
        gap> suz:= GroupWithGenerators( suzgens );;

We take the straight line program for computing representatives of maximal cyclic subgroups of Suz, and compute words in terms of standard generators of Suz that belong to Suz.2-class representatives of Suz, as powers of suitable results of the straight line program. This way, we get representatives of the 37 classes of Suz.2 inside Suz.

        gap> cls:= AtlasProgram( "Suz", "cyclic" );
        rec( groupname := "Suz", identifier := [ "Suz", "SuzG1-cycW1", 1 ],
          outputs := [ "8B", "8C", "10B", "11A", "12B", "12C", "12D", "12E",
              "13A-B", "14A", "15A-B", "15C", "18A-B", "20A", "21A-B", "24A" ]
            , program := <straight line program>, standardization := 1,
          version := "1" )
        gap> cycreps:= ResultOfStraightLineProgram( cls.program, suzgens );;
        gap> Length( cycreps );
        16
        gap> classreps:= [];;
        gap> classwords:= [];;
        gap> for i in [ 1 .. Length( cycreps ) ] do
        >      x:= cycreps[i];
        >      if ForAll( classreps, y -> not IsConjugate( suz2, x, y ) ) then
        >        Add( classreps, x );
        >        Add( classwords, [ i, 1 ] );
        >      fi;
        >    od;
        gap> for i in [ 1 .. Length( classreps ) ] do
        >      x:= classreps[i];
        >      for j in [ 2 .. Order( x ) ] do
        >        xj:= x^j;
        >        if ForAll( classreps, y -> not IsConjugate( suz2, xj, y ) ) then
        >          Add( classreps, xj );
        >          Add( classwords, [ i, j ] );
        >        fi;
        >      od;
        >    od;
        gap> Length( classreps );
        37
        gap> Length( ClassPositionsOfKernel(
        >                Irr( CharacterTable( "Suz.2" ) )[2] ) );
        37

Sort these class representatives by element orders.

        gap> pi:= SortingPerm( List( classreps, Order ) );;
        gap> classreps:= Permuted( classreps, pi );;
        gap> classwords:= Permuted( classwords, pi );;

Form a straight line program that takes standard generators of Suz and returns the representatives computed up to now.

        gap> somereps:= CompositionOfStraightLinePrograms(
        >        StraightLineProgram( [ classwords ], Length( cls.outputs ) ),
        >        cls.program );;

In order to get class representatives for the outer classes of Suz.2, we form products of the representatives of inner classes with an element from Suz.2 \Suz. We may choose the first standard generator of Suz.2 as an outer element.

        gap> outer:= suz2.1;;
        gap> outer in suz;
        false

Create a straight line program that takes standard generators of Suz.2 and returns the concatenation of the inner class representatives and the first generator.

        gap> first_gen:= StraightLineProgram( [ [ [ 1, 1 ] ] ], 2 );;
        gap> somereps_plus_outer_Suz2:= IntegratedStraightLineProgram( [
        >      CompositionOfStraightLinePrograms( somereps, suzinsuz2.program ),
        >      first_gen ] );;

First we create products of the inner class representatives and the outer element.

        gap> outerpos:= Length( classreps ) + 1;;
        gap> classreps2:= [];;
        gap> classwords2:= [];;
        gap> for i in [ 1 .. Length( classreps ) ] do
        >      x:= classreps[i];
        >      xx:= x * outer;
        >      if ForAll( classreps2, y -> not IsConjugate( suz2, xx, y ) ) then
        >        Add( classreps2, xx );
        >        Add( classwords2, [ i, 1, outerpos, 1 ] );
        >      fi;
        >    od;
        gap> [ Length( classreps ), Length( classreps2 ) ];
        [ 37, 17 ]
        gap> NrConjugacyClasses( CharacterTable( "Suz.2" ) );
        68

We see that 14 class representatives are missing, and compute new candidates as powers of the known outer representatives, and as products of the known outer representatives with inner ones.

        gap> for i in [ 1 .. Length( classreps2 ) ] do
        >      x:= classreps2[i];
        >      for j in Filtered( [ 2 .. Order( x ) ], IsOddInt ) do
        >        xj:= x^j;
        >        if ForAll( classreps2, y -> not IsConjugate( suz2, xj, y ) ) then
        >          Add( classreps2, xj );
        >          Add( classwords2, [ i+38, j ] );
        >        fi;
        >      od;
        >    od;
        gap> Length( classreps2 );
        24
        gap> for i in [ 1 .. 37 ] do
        >      x:= classreps[i];
        >      for j in [ 1 .. Length( classreps2 ) ] do
        >        y:= classreps2[j];
        >        xy:= x*y;
        >        if ForAll( classreps2, yy -> not IsConjugate( suz2, xy, yy ) ) then
        >          Add( classreps2, xy );
        >          Add( classwords2, [ i, 1, j+38, 1 ] );
        >        fi;
        >      od;
        >    od;
        gap> Length( classreps2 );
        31

Create a straight line program that computes our class representatives from standard generators of Suz.2.

        gap> allreps:= StraightLineProgram(
        >                  Concatenation( classwords2,
        >                      [ List( Concatenation( [ 1 .. 37 ], [ 39 .. 69 ] ),
        >                              i -> [ i, 1 ] ) ] ), 38 );
        gap> classreps_suz2:= CompositionOfStraightLinePrograms( allreps,
        >                         somereps_plus_outer_Suz2 );

Check that the straight line program does what we expect.

        gap> ress:= ResultOfStraightLineProgram( classreps_suz2,
        >               GeneratorsOfGroup( suz2 ) );;
        gap> ress = Concatenation( classreps, classreps2 );
        true

#### 2 Class representatives of 6.Suz.2

Next we compute words in terms of standard generators for the conjugacy classes of 6.Suz.2. For that, we first take a faithful permutation representation of 6.Suz.2 (on standard generators) and a generator z of the cyclic normal subgroup of order 6, and then evaluate the class representatives words for Suz.2 in the generators of 6.Suz.2.

        gap> 6suz2:= AtlasGroup( "6.Suz.2" );
        gap> ker:= AtlasProgram( "6.Suz.2", "kernel", "Suz.2" );
        gap> z:= ResultOfStraightLineProgram( ker.program,
        >            GeneratorsOfGroup( 6suz2 ) );;
        gap> List( z, Order );
        [ 6 ]
        gap> z:= z[1];;
        gap> sreps2:= ResultOfStraightLineProgram( classreps_suz2,
        >                 GeneratorsOfGroup( 6suz2 ) );;

Representatives for the missing classes are obtained as products of the known representatives with powers of z.

        gap> classwords2:= [];;
        gap> classreps2:= [];;
        gap> for i in [ 1 .. Length( sreps2 ) ] do
        >      x:= sreps2[i];
        >      Add( classwords2, [ i, 1 ] );
        >      cand:= [ x ];
        >      for j in [ 1 .. 5 ] do
        >        xj:= x * z^j;
        >        if ForAll( cand, y -> not IsConjugate( 6suz2, xj, y ) ) then
        >          Add( cand, xj );
        >          Add( classwords2, [ i, 1, 69, j ] );
        >        fi;
        >      od;
        >      Append( classreps2, cand );
        >    od;
        gap> Length( classwords2 ) = NrConjugacyClasses( CharacterTable( "6.Suz.2" ) );
        true

For later use, we compute also the corresponding class lengths in 6.Suz.2.

        gap> classlengths:= [];;
        gap> for i in [ 1 .. Length( classwords2 ) ] do
        >      classlengths[i]:= Size( 6suz2 ) /
        >          Size( Centralizer( 6suz2, classreps2[i] ) );
        >    od;

Again, we create a straight line program for computing the representatives from standard generators.

        gap> reps_suz2_plus_z:= IntegratedStraightLineProgram( [
        >        classreps_suz2, ker.program ] );;
        gap> classreps_6suz2:= CompositionOfStraightLinePrograms(
        >        StraightLineProgram( [ classwords2 ], 69 ), reps_suz2_plus_z );;

#### 3 Class representatives of H / Y

Class representatives of 312:6.Suz.2 ≅ H / Y can be obtained by taking one preimage for each class representative of 6.Suz.2 and then forming products with suitable elements in the elementary abelian normal subgroup of order 312. We start with group generators of this normal subgroup; a straight line program for computing them is available.

        gap> ker2:= AtlasProgram( "3^(1+12):6.Suz.2", "kernel", "6.Suz.2" );;
        gap> ngens:= ResultOfStraightLineProgram( ker2.program,
        >                Concatenation( gensHmodY, [ () ] ) );;
        gap> n:= GroupWithGenerators( ngens );;
        gap> IsAbelian( n );
        true
        gap> Size( n ) = 3^12;
        true

The second ingredient are the preimages of class representatives of 6.Suz.2, evaluated in the representation for H / Y ≅ 312.6.Suz.2.

        gap> rreps3:= ResultOfStraightLineProgram( classreps_6suz2,
        >                 gensHmodY{ [ 1, 2 ] } );;

In order to compute words for the class representatives of 312.6.Suz.2, we use MAGMA to test the conjugacy of elements and to compute centralizer orders. (Note that the function `IsConjugateViaMagma` returns `true` if the two given elements are conjugate, and the class length of the first element otherwise.)

        gap> gg:= GroupWithGenerators( gensHmodY );;
        gap> Gclasswords:= [];
        gap> Gclassreps:= [];
        gap> for i in [ 1 .. Length( rreps3 ) ] do
        >      sum:= 3^12 * classlengths[i]
        >            - Size( gg ) / CentralizerOrderViaMagma( gg, rreps3[i] );
        >      Gclassreps[i]:= [ rreps3[i] ];
        >      Gclasswords[i]:= [];  # omit the word of length 0
        >      len:= 1;
        >      while sum > 0 do
        >        for tup in Combinations( [ 1 .. 12 ], len ) do
        >          cand:= rreps3[i] * Product( ngens{ tup } );
        >          conj:= IsConjugateViaMagma( gg, cand, Gclassreps[i] );
        >          if conj <> true then
        >            Add( Gclassreps[i], cand );
        >            Add( Gclasswords[i], tup );
        >            sum:= sum - Size( gg ) / conj;
        >            if sum <= 0 then
        >              break;
        >            fi;
        >          fi;
        >        od;
        >        len:= len + 1;;
        >      od;
        >    od;
        gap> Sum( List( Gclasswords, Length ) );
        323
        gap> Gclasswords;
        [ [ [ 1 ], [ 1, 2 ] ], [  ], [ [ 1 ], [ 1, 2 ] ], [  ], [ [ 1 ] ],
          [ [ 1 ], [ 8 ] ], [ [ 1 ] ], [ [ 1 ], [ 8 ] ], [  ], [  ],
          [ [ 1 ], [ 3 ], [ 6 ], [ 1, 7 ], [ 4, 5, 6 ] ], [  ],
          [ [ 1 ], [ 3 ], [ 6 ], [ 1, 7 ], [ 7, 11 ], [ 4, 5, 6 ] ], [  ],
          [ [ 1 ], [ 3 ], [ 4 ] ], [  ], [  ], [ [ 1 ], [ 3 ] ], [  ],
          [ [ 1 ] ], [ [ 1 ] ], [ [ 1 ] ], [ [ 2 ], [ 4 ] ], [ [ 2 ], [ 4 ] ],
          [ [ 1 ] ], [  ], [ [ 1 ] ], [  ], [  ], [  ], [  ],
          [ [ 1 ], [ 2 ] ], [ [ 1 ], [ 2 ] ], [  ], [  ], [  ], [  ], [  ],
          [ [ 1 ], [ 2 ] ], [ [ 1 ], [ 6 ], [ 8 ] ], [ [ 1 ], [ 2 ], [ 8 ] ],
          [ [ 1 ], [ 6 ], [ 8 ] ], [ [ 1 ], [ 3 ], [ 7 ] ], [ [ 1 ], [ 7 ] ],
          [ [ 1 ], [ 7 ] ], [ [ 1 ] ], [  ], [ [ 1 ], [ 10 ] ],
          [ [ 1 ], [ 2 ] ], [ [ 1 ], [ 10 ] ], [ [ 1 ], [ 2 ] ],
          [ [ 1 ], [ 10 ] ], [ [ 1 ], [ 2 ] ], [  ], [  ], [  ], [  ], [  ],
          [ [ 1 ] ], [  ], [ [ 1 ] ], [ [ 2 ], [ 3 ] ], [ [ 2 ], [ 3 ] ],
          [  ], [  ], [ [ 1 ], [ 3 ], [ 4 ] ], [  ], [ [ 1 ], [ 3 ], [ 4 ] ],
          [  ], [ [ 1 ], [ 3 ], [ 4 ] ], [  ], [  ], [  ], [  ], [  ], [  ],
          [  ], [ [ 1 ], [ 3 ], [ 4 ], [ 5 ] ], [  ], [  ],
          [ [ 1 ], [ 3 ], [ 4 ] ], [ [ 1 ], [ 2 ] ], [  ],
          [ [ 1 ], [ 2 ], [ 8 ] ], [  ], [ [ 1 ], [ 2 ], [ 3 ] ],
          [ [ 1 ], [ 2 ] ], [  ], [ [ 2 ] ], [ [ 1 ] ], [ [ 2 ] ], [  ],
          [ [ 1 ], [ 3 ] ], [  ], [ [ 1 ] ], [  ], [  ], [  ], [  ], [  ],
          [  ], [  ], [  ], [  ], [  ], [ [ 1 ], [ 4 ] ], [  ],
          [ [ 1 ], [ 3 ], [ 4 ], [ 5 ] ], [  ], [ [ 3 ] ], [ [ 1 ] ],
          [ [ 3 ] ], [ [ 1 ] ], [ [ 3 ] ], [ [ 1 ] ], [  ], [  ], [  ], [  ],
          [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ],
          [ [ 1 ] ], [ [ 1 ] ], [  ],
          [ [ 1 ], [ 2 ], [ 8 ], [ 12 ], [ 1, 9 ] ], [ [ 1 ] ], [ [ 2 ] ],
          [ [ 1 ] ], [ [ 1 ] ], [  ], [  ], [  ], [ [ 1 ], [ 3 ] ], [  ],
          [  ], [  ], [  ], [  ], [ [ 1 ] ], [ [ 1 ] ], [  ], [  ],
          [ [ 1 ] ], [ [ 2 ] ], [ [ 2 ] ], [ [ 1 ] ],
          [ [ 1 ], [ 4 ], [ 12 ] ], [ [ 1 ], [ 4 ] ], [  ], [  ], [  ], [  ],
          [  ], [  ], [ [ 1 ] ], [ [ 2 ] ], [  ], [  ], [  ], [  ],
          [ [ 1 ], [ 2 ] ], [  ], [  ], [ [ 1 ] ], [  ], [  ] ]

### 9.6 Class representatives of H

TODO: Now use Magma ...

### 9.7 The character table of H / Y

The group H / Y has 323 conjugacy classes. We ask MAGMA to compute its character table, where the columns correspond to our class representatives. In order to get class representatives that are compatible with the ordering of the columns in the character table of H / Y that is available in the GAP character table library, we apply a suitable permutation `pi`. (Yes, we need the character table of H / Y for computing this permutation; in this sense, we are cheating a little.)

        gap> pi:= (2,3)(4,56,172,163,298,51,170,162,157,318,272,161,293,258,
        > 114,86,108,89,100,70,216,218,226,235,242,256,112,87,109,81,107,88,
        > 110,79,101,69,53,47,37,22,27,65,262,192,207,212,221,225,236,316,210,
        > 323,263,139,275,313,287,283,228,239,248,271,123,95,72,215,219,222,
        > 224,237,315,211,289,285,317,209,304,247,269,307,128,133,132,131,268,
        > 280,229,238,249,39,21,29,33,31,34,35,64,124,309,126,253,136,140,130,
        > 266,281,230,241,310,125,120,92,98,75,291,261,193,206,322,265,282,
        > 227,234,243,312,251,135,141,264,138,274,159,294,12,61,168,257,115,
        > 84,104,66,292,259,116,82,105,200,180,187,196,197,182,186,202,177,
        > 191,208,321,118,93,74,52,48,44,17,7,15,59,43,18,9,6,16,8)(5,14,60,
        > 167,302,121,96,73,156,232,245,311,250,134,142,154,147,146,233,244,
        > 255,117,83,106,90,97,77,155,149,143,152,150,145,153,148,144,151,231,
        > 240,254,199,179,188,194,205,303,129,267,279,290,260,113,85,111,80,
        > 102,68,55,173,165,299,50,171,164,300,49,45,78,103,67,54,46,38,20,40,
        > 57,174,185,203,176,184,201,178,190,278,305,246,270,308,127,213,296,
        > 10)(11,62,169,320,119,91,99,76,214,220,223,295)(13,63,41,58,42,19,
        > 166,301,122,94,71,217,297)(23,25,24,26,28,36)(30,32)(137,276,314,
        > 277,306,175,183,204,288,286,284,319,273,160,158,252)(181,189,195,198);;
        gap> ccl:= [];;
        gap> for i in [ 1 .. Length( Gclasswords ) ] do
        >      r:= rreps3[i];
        >      Add( ccl, r );  # take case of the omitted empty word
        >      for l in Gclasswords[i] do
        >        Add( ccl, r * Product( ngens{ l }, () ) );
        >      od;
        >    od;
        gap> ccl:= Permuted( ccl, pi );;
        gap> SetConjugacyClasses( gg,
        >        List( ccl, x -> ConjugacyClass( gg, x ) ) );
        gap> tbl:= CharacterTableComputedByMagma( gg, "3^12.6.Suz.2magma" );

We check whether the computed table is equivalent to the table that occurs as a factor of the known GAP library table. (Since we have permuted the classes in advance, only the ordering of irreducible characters is different.)

        gap> lib:= CharacterTable( "3^(1+12):6.Suz.2" );;
        gap> tblHmodY:= lib / [ 1, 2 ];;
        gap> NrConjugacyClasses( tblHmodY );
        323
        gap> tr:= TransformingPermutationsCharacterTables( tbl, tblHmodY );;
        gap> tr.columns = ();
        true

From here on, we continue to work with the library table `tblHmodY`.

### 9.8 The class fusions from H to H / X, H / D1, and H / D2

During the computation of the class representatives of H, we have computed also the class fusion `HfusHmodY` from H to its factor group H / Y. The class fusion from H / Y to its factor group H / E can be computed from the character table of H / Y.

        gap> nsg:= ClassPositionsOfNormalSubgroups( tblHmodY );;
        gap> classesEmodY:= First( nsg,
        >        x -> Sum( SizesConjugacyClasses( tblHmodY ){x} ) = 3 );;
        gap> tblHmodE:= tblHmodY / classesEmodY;;
        gap> HmodYfusHmodE:= GetFusionMap( tblHmodY, tblHmodE );;
        gap> HfusHmodE:= CompositionMaps( HmodYfusHmodE, HfusHmodY );;

Now we compute the class fusions from H to the groups H / Z and from H / Z to H / E, where Z runs over the subgroups of order three in E different from Y. For that, we perform explicit conjugacy tests in H, using MAGMA. (Note that we need not create the factor groups H / Z.)
First we fix generators of the three subgroups Z in question.

        gap> cand:= Positions( Hclasslengths, 2 );
        [ 6, 7, 8, 9 ]
        gap> HfusHmodY{ cand };
        [ 5, 1, 5, 5 ]
        gap> gens3:= Hreps{ Filtered( cand, x -> HfusHmodY[x] <> 1 ) };;

TODO: now it gets subtle, conjugacy tests in the perm. repres. of H can be hard, we must be careful which questions we ask.

### 9.9 The character table head of H

TODO: Describe that we ask Magma.

### 9.10 The character table of 31+12:(2 ×U5(2).2)

The subgroups in the fourth class of maximal subgroups of Suz.2 have the structure U5(2).2, see [CCN+85,p. 131], the ATLAS of Group Representations [WWT+] provided a straight line program for computing generators of such a subgroup from standard generators of Suz.2.
Applying this program to standard generators of 6.Suz.2 yields generators of a subgroup of the structure 2 ×U5(2).2. Together with our generating element inside N, we get a generating set of a subgroup U ≅ 31+12:(2 ×U5(2).2) of H.

        gap> slpu:= AtlasProgram( "Suz.2", "maxes", 4 );;
        gap> firstgens:= ResultOfStraightLineProgram( slpu.program,
        >                    Hgens{ [ 1, 2 ] } );;
        gap> ugens:= Concatenation( firstgens, [ Hgens[3] ] );;
        gap> u:= Group( ugens );;
        gap> Size( u ) = 3^13 * Size( CharacterTable( "2xU5(2).2" ) );
        true

We ask MAGMA [BCP97] to compute the character table of U. This table is equivalent to the one that is contained in GAP's character table library, thus we can use the library table for our computations.

        gap> utbl:= CharacterTableComputedByMagma( u,
        >               "3^(1+12).(2xU5(2).2)magma" );;
        gap> IsRecord( TransformingPermutationsCharacterTables( utbl,
        >                  CharacterTable( "3^(1+12).(2xU5(2).2)" ) ) );
        true
        gap> utbl:= CharacterTable( "3^(1+12).(2xU5(2).2)" );;

### 9.11 Complete the character table of H

Finally, we use character theoretic methods for computing the missing irreducible characters of H. We produce some reducible characters by inducing from the subgroup U and from cyclic subgroups of H, take the natural permutation character of H, then reduce these characters with the known irreducibles (of the factor group H / Y), form tensor products with the known irreducibles,
TODO: finish the overview
We will compute the missing irreducibles of the three factor groups H / X, H / D1, H / D2 separately. For that, we need the following observation.
Any character ψ of H can be written as a sum ψ = ψX + ψD1 + ψD2 + ψE, where X, D1, and D2 is the kernel of ψX, ψD1, and ψD2, respectively, and the kernel of ψE contains E. The four constituents of ψ can be computed if the factor fusions from H to H / X, H / D1, H / D2, and H / E are known, without knowing the irreducible characters of the factor groups. Namely, "inducing" ψ to the factor group in question, using the usual induction formula, yields the corresponding projection, and inflation to H yields the constituent.
(This is a nice little exercise for a course in character theory, but actually the current situation is the first case where it turns out to be useful in practice.)
For the situation of H ≤ G, and ϕ a class function of H, the induced class function is defined as ϕG, with ϕG(g) = [1/|H|] ∑x ∈ G ϕ0(xgx−1). The right hand side can be computed as [(|CG(g)|)/|H|] ∑h |hH| ϕ(h), where h runs over representatives of those conjugacy classes of H that fuse to g in G.
Analogously, we define for N ≤ G and a class function ϕ of G the "induced" class function ϕ[G] of the group [G] = G/N by

ϕ[G](gN) = | |C[G](gN)| |G| |  | ∑ x | |xG| ϕ(x),

where x runs over representatives of those conjugacy of G that fuse to gN in [G].
For ϕ ∈ Irr(G), we have ϕ[G] = ϕ (viewed as a class function of G) if N ≤ ker(ϕ), and ϕ is zero otherwise. For arbitrary class functions ϕ of G, ϕ[G] is the projection to [G].
Proof: Let ψ ∈ Irr([G]). We have

[ϕ[G], | ψ | ][G] = | 1
| | - G | |
|  | ∑ gN ∈ [G] | ϕ[G](gN) ψ(gN) = | 1
| | - G | |
|  | ∑ gN ∈ [G] |  |   | |C[G](gN)| |G| |  | ∑ x | |xG| ϕ(x) |   | ψ(gN) = | 1 |G| |  | ∑ gN ∈ [G] |  |   | 1 |(gN)[G]| |  | ∑ x | |xG| ϕ(x) |   | ψ(x) = | 1 |G| |  | ∑ x | |xG| ϕ(x) ψ(x) = [ϕ, | ψ | ]G .

TODO: Finish the description as in `thirdstep.log`.

## 10 Appendix: The character table of 51+6+.4.J2.2

The normalizer of a `5B` element in M has the structure 51+6+.4.J2.2, generators for this group as a permutation group of degree 78 125 are available in the ATLAS of Group Representations [WWT+]. MAGMA [BCP97] can compute the character table from the group within a few minutes, the result turns out to be equivalent to the table that is available in GAP's character table library.

        gap> g:= AtlasGroup( "5^(1+6):2.J2.4" );;
        gap> if CTblLib.IsMagmaAvailable() then
        >      mgmt:= CharacterTableComputedByMagma( g, "MN5B_Magma" );
        >    else
        >      mgmt:= CharacterTable( "5^(1+6):2.J2.4" );
        >    fi;
        gap> IsRecord( TransformingPermutationsCharacterTables( mgmt,
        >        CharacterTable( "5^(1+6):2.J2.4" ) ) );
        true

## References

[BCP97]
  W. Bosma, J. Cannon, and C. Playoust, The Magma algebra system. I. The user language, J. Symbolic Comput. 24 (1997), no. 3-4, 235-265. MR 1484478
[BGH+17]
  M. Bhargava, R. Guralnick, G. Hiss, K. Lux, and P. H. Tiep (eds.), Finite simple groups: thirty years of the Atlas and beyond, Contemporary Mathematics, vol. 694, Providence, RI, American Mathematical Society, 2017. MR 3682583
[BMO17]
  T. Breuer, G. Malle, and E. A. O'Brien, Reliability and reproducibility of Atlas information, in Bhargava et al. [BGH+17], p. 21-31. MR 3682588
[BMW20a]
  T. Breuer, K. Magaard, and R. A. Wilson, Verification of the ordinary character table of the Baby Monster, J. Algebra 561 (2020), 111-130. MR 4135540
[BMW20b]

  , Verification of the ordinary character table of the Monster, 2020.
[]
  T. Breuer, Constructing the ordinary character tables of some Atlas groups using character theoretic methods., arXiv:1604.00754.
[Breb]

  , Permutation Characters in GAP, `https://www.math.rwth-aachen.de/` ``~`Thomas.Breuer/` `ctbllib/``doc2/` `manual.pdf`.
[BW07]
  R. W. Barraclough and R. A. Wilson, The character table of a maximal subgroup of the Monster, LMS J. Comput. Math. 10 (2007), 161-175. MR 2308856
[CCN+85]
  J. H. Conway, R. T. Curtis, S. P. Norton, R. A. Parker, and R. A. Wilson, Atlas of finite groups, Oxford University Press, Eynsham, 1985, Maximal subgroups and ordinary characters for simple groups, With computational assistance from J. G. Thackray. MR 827219 (88g:20025)
[GAP21]
  GAP - Groups, Algorithms, and Programming, Version 4.11.1, `https://www.gap-system.org`, Mar 2021.
[GJMS89]
  R. L. Griess Jr., U. Meierfrankenfeld, and Y. Segev, A uniqueness proof for the Monster, Ann. of Math. (2) 130 (1989), no. 3, 567-602. MR 1025167
[WWT+]
  R. A. Wilson, P. Walsh, J. Tripp, I. Suleiman, R. A. Parker, S. P. Norton, S. Nickerson, S. Linton, J. Bray, and R. Abbott, ATLAS of Finite Group Representations, `http://brauer.maths.qmul.ac.uk/` `Atlas/v3`.

File translated from TEX by TTH, version 3.59.
On 22 Feb 2024, 10:23.