We will give some more extended examples which are intended to give the user an idea of the behaviour on different inputs, how to use the package more efficently, to use characters not available in libraries and how InfoLevels can be helpful. We will give some more examples which are intended to give the user an idea of the behavior on different inputs and the variable HeLP_sol. We also give hints how to use the package more efficiently, to use characters not available in libraries and how InfoLevels can be helpful.

gap> G := SL(2,7); SL(2,7) gap> HeLP_ZC(G); #I The Brauer tables for the following primes are not available: [ 2, 3, 7 ]. #I (ZC) can't be solved, using the given data, for the orders: [ 8 ]. false gap> C1 := CharacterTable(G); CharacterTable( SL(2,7) ) gap> HeLP_ZC(C1); #I The Brauer tables for the following primes are not available: [ 2, 3, 7 ]. #I (ZC) can't be solved, using the given data, for the orders: [ 8 ]. false gap> C2 := CharacterTable("2.L2(7)"); CharacterTable( "2.L3(2)" ) gap> HeLP_ZC(C2); true

Note that the first and the second call of `HeLP_ZC`

(2.1-1) are equivalent -- the only difference being that in the first version the character table of the group is also calculated by the function, in the second version the calculations are performed with the given character table. For the third call of `HeLP_ZC`

(2.1-1) a character table for SL2(7) is used which comes from the character table library. The different result is due to the fact, that in the third version the Brauer tables are available (the Brauer table for the prime \(p = 7\) is needed to rule out some non-trivial partial augmentations for elements of order 8), whereas for the first and the second call no Brauer tables are available in GAP.

This sections demonstrates when the global variable `HeLP_sol`

is reset. This is the case if calculations are performed using (the character table of) another group than before:

gap> C := CharacterTable("A5"); CharacterTable( "A5" ) gap> HeLP_ZC(C); true gap> HeLP_sol; [ [ [ [ 1 ] ] ], [ [ [ 1 ] ] ], [ [ [ 1 ] ] ],, [ [ [ 0, 1 ] ], [ [ 1, 0 ] ] ], [ ],,,, [ ],,,,, [ ],,,,,,,,,,,,,,, [ ] ] gap> C := CharacterTable("L3(7).2"); CharacterTable( "L3(7).2" ) gap> HeLP_WithGivenOrderAndPA(Irr(C){[3,7,9,10]},21,[[1],[3,9,-11]]); #I Number of solutions for elements of order 21 with these partial augmentation s for the powers: 1. [ [ [ 1 ], [ 3, 9, -11 ], [ -6, 0, 3, 4 ] ] ] gap> HeLP_sol; [ [ [ [ 1 ] ] ] ]

The function `HeLP_WithGivenOrderAndPA`

(3.1-2) does not write a result in `HeLP_sol[k]`

(as it does not calculate all possible solutions of order \(k\)). However `HeLP_sol`

is reset as a different character table is used. We continue the above example.

gap> HeLP_WithGivenOrder(C,3); #I Number of solutions for elements of order 3: 1; stored in HeLP_sol[3]. [ [ [ 1 ] ] ] gap> HeLP_sol; [ [ [ [ 1 ] ] ],, [ [ [ 1 ] ] ] ]

If HeLP detects that the table used belongs to the same group, `HeLP_sol`

is not reset:

gap> HeLP_WithGivenOrder(C mod 7, 19); #I Number of solutions for elements of order 19: 3; stored in HeLP_sol[19]. [ [ [ 0, 0, 1 ] ], [ [ 0, 1, 0 ] ], [ [ 1, 0, 0 ] ] ] gap> HeLP_sol; [ [ [ [ 1 ] ] ],, [ [ [ 1 ] ] ],,,,,,,,,,,,,,,, [ [ [ 0, 0, 1 ] ], [ [ 0, 1, 0 ] ], [ [ 1, 0, 0 ] ] ] ] # the previously calaculated result for order 3 is still there.

HeLP can detect that the character tables belong to the same group, if they are identical objects in GAP or if both are tables of the same group from the ATLAS and their InfoText begins with "origin: ATLAS of finite groups" (which is usually the case for ATLAS tables). If the program can verify that the character table which is used at the current call of a function belongs to the same group as in the previous call of a function, the solutions stored in `HeLP_sol`

are kept. If the character table belongs to another group or it can not be made sure that the character tabel belongs to the same group, `HeLP_sol`

is reset to the initial value `[ [ [1] ] ]`

representing the trivial solution for units of order \(1\).

Not reseting `HeLP_sol`

can also be achieved using `HeLP_ChangeCharKeepSols`

(3.4-1). However, caution should be exercised when using this command since it may manipulate `HeLP_sol`

into something meaningless.

gap> G := PSL(2,7); Group([ (3,7,5)(4,8,6), (1,2,6)(3,4,8) ]) gap> HeLP_ZC(G); #I The Brauer tables for the following primes are not available: [ 2, 3, 7 ]. #I (ZC) can't be solved, using the given data, for the orders: [ 6 ]. false gap> HeLP_sol; [ [ [ [ 1 ] ] ], [ [ [ 1 ] ] ], [ [ [ 1 ] ] ], [ [ [ 1 ], [ 0, 1 ] ] ],, [ [ [ 1 ], [ 1 ], [ -2, 3 ] ] ], [ [ [ 0, 1 ] ], [ [ 1, 0 ] ] ],,,,, [ ],, [ ],,,,,,, [ ],,,,,,, [ ],,,,,,,,,,,,,, [ ],,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,, [ ] ] gap> C := CharacterTable("L2(7)") mod 7; BrauerTable( "L3(2)", 7 ) gap> HeLP_ChangeCharKeepSols(C); #This table belongs to the same group. gap> HeLP_WithGivenOrder(C,6); #I Number of solutions for elements of order 6: 0; stored in HeLP_sol[6]. [ ] gap> HeLP_sol; [ [ [ [ 1 ] ] ], [ [ [ 1 ] ] ], [ [ [ 1 ] ] ], [ [ [ 1 ], [ 0, 1 ] ] ],, [ ], [ [ [ 0, 1 ] ], [ [ 1, 0 ] ] ],,,,, [ ],, [ ],,,,,,, [ ],,,,,,, [ ],,,,,,,,,,,,,, [ ],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, [ ] ] gap> C := CharacterTable("L3(7).2") mod 7; BrauerTable( "L3(7).2", 7 ) gap> HeLP_ChangeCharKeepSols(C); #This table is from a different group gap> HeLP_WithGivenOrder(C,19); #I Number of solutions for elements of order 19: 3; stored in HeLP_sol[19]. [ [ [ 0, 0, 1 ] ], [ [ 0, 1, 0 ] ], [ [ 1, 0, 0 ] ] ] gap> HeLP_sol; [ [ [ [ 1 ] ] ], [ [ [ 1 ] ] ], [ [ [ 1 ] ] ], [ [ [ 1 ], [ 0, 1 ] ] ],, [ ], [ [ [ 0, 1 ] ], [ [ 1, 0 ] ] ],,,,, [ ],, [ ],,,,, [ [ [ 0, 0, 1 ] ], [ [ 0, 1, 0 ] ], [ [ 1, 0, 0 ] ] ],, [ ],,,,,,, [ ],,,, ,,,,,,,,,, [ ],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, [ ] ] # The content of HeLP_sol does not have a mathematical value anymore.

The following functions manipulate the variable `HeLP_sol`

: `HeLP_ZC`

(2.1-1), `HeLP_PQ`

(2.2-1), `HeLP_WithGivenOrder`

(3.1-1), `HeLP_WithGivenOrderSConstant`

(3.2-1) (for elements of order \(t\) and if the existence of elements of order \(st\) can be excluded also for this order), `HeLP_AllOrders`

(3.3-1), `HeLP_AllOrdersPQ`

(3.3-2), `HeLP_VerifySolution`

(3.6-1) (if existing solutions were checked), `HeLP_FindAndVerifySolution`

(3.6-2). Note that the functions only will write results in `HeLP_sol[k]`

if \(k\) is a divisor of the exponent of the group as this information is enough to decide whether (ZC) and (PQ) are valid for the group in consideration. In all other cases an empty list will be returned but no value will be written in `HeLP_sol[k]`

.

The most time consuming operation when using the functions of this package is solving the system of inequalities given by the HeLP method, see Section 5.3. This package uses the programs 4ti2 and/or normaliz to do this and it is not completely clear to the authors of this package which input is solved faster by these programs. In any case it is helpful to reduce the number of variables, using e.g. \(p\)-constant characters, and in many situations it is useful to reduce the number of inequalities, i.e. of used characters.

To measure the time a function needs we use `IO_gettimeofday`

from the IO-package rather than functions like `time`

or `Runtime`

, since these measure only the GAP time, but do not return the time the functions spend using 4ti2 or normaliz. We used the following function (which is essentially due to Alexander Konovalov) to meassure the time used for the computation:

TimeFunction := function(f, args) # input: the function of which the computing time should be measured # and the list of arguments for this function # output: time needed for the calculations in seconds local start; start := IO_gettimeofday(); CallFuncList(f,args); return IO_gettimeofday().tv_sec - start.tv_sec; end;

All times will be given in seconds. The computations were perfomed on an a machine with four 2,6 GHz kernels.

A lot of time might be saved by testing only a few characters instead of a whole character table:

gap> C := CharacterTable("L2(49)");; gap> HeLP_Solver("normaliz"); 'normaliz' will be used from now on. gap> TimeFunction(HeLP_WithGivenOrder, [C,35]); #I Number of solutions for elements of order 35: 0; stored in HeLP_sol[35]. 6 # I.e.: The computation took 6 seconds. gap> TimeFunction(HeLP_WithGivenOrder, [Irr(C){[2]}, 35]); #I Number of solutions for elements of order 35: 0; stored in HeLP_sol[35]. 0 gap> HeLP_Solver("4ti2"); '4ti2' will be used from now on. gap> TimeFunction(HeLP_WithGivenOrder, [C,35]); #I Number of solutions for elements of order 35: 0; stored in HeLP_sol[35]. 6 gap> TimeFunction(HeLP_WithGivenOrder, [Irr(C){[2]}, 35]); #I Number of solutions for elements of order 35: 0; stored in HeLP_sol[35]. 1

I.e.: Using only one character instead of all of them is about six times faster in this situation and this is also quickly found by `HeLP_FindAndVerifySolution`

.

Using only a few characters might even be a life saver:

gap> C := CharacterTable("L4(3).2^2");; gap> HeLP_WithGivenOrder(C, 3);; #I Number of solutions for elements of order 3: 63; stored in HeLP_sol[3]. gap> HeLP_WithGivenOrder(C, 13);; #I Number of solutions for elements of order 13: 198; stored in HeLP_sol[13]. gap> SetInfoLevel(HeLP_Info,4); gap> HeLP_Solver("4ti2"); '4ti2' will be used from now on. gap> HeLP_UseRedund(true); 'redund' will be used from now on. gap> TimeFunction(HeLP_WithGivenOrder, [Irr(C){[5,11,16]}, 39]); #I Number of solutions for elements of order 39: 0; stored in HeLP_sol[39]. 438 gap> HeLP_UseRedund(false); The calculations will be performed without using 'redund' from now on. gap> TimeFunction(HeLP_WithGivenOrder, [Irr(C){[5,11,16]}, 39]); #I Number of solutions for elements of order 39: 0; stored in HeLP_sol[39]. 430 gap> HeLP_Solver("normaliz"); 'normaliz' will be used from now on. gap> TimeFunction(HeLP_WithGivenOrder, [Irr(C){[5,11,16]}, 39]); #I Number of solutions for elements of order 39: 0; stored in HeLP_sol[39]. 340 gap> HeLP_UseRedund(true); 'redund' will be used from now on. gap> TimeFunction(HeLP_WithGivenOrder, [Irr(C){[5,11,16]}, 39]); #I Number of solutions for elements of order 39: 0; stored in HeLP_sol[39]. 419 gap> HeLP_UseRedund(false); The calculations will be performed without using 'redund' from now on. gap> HeLP_Solver("normaliz"); 'normaliz' will be used from now on. gap> TimeFunction(HeLP_WithGivenOrder, [Irr(C), 39]); #I Number of solutions for elements of order 39: 0; stored in HeLP_sol[39]. 6234

Sometimes it is helpful to look at groups containing the group of interest:

gap> C := CharacterTable("2F4(2)'");; gap> HeLP_WithGivenOrder(C, 13);; #I Number of solutions for elements of order 13: 316; stored in HeLP_sol[13]. gap> HeLP_WithGivenOrder(C, 3);; #I Number of solutions for elements of order 3: 1; stored in HeLP_sol[3]. gap> TimeFunction(HeLP_WithGivenOrder, [C, 39]); #I Number of solutions for elements of order 39: 0; stored in HeLP_sol[39]. 80 gap> C:=CharacterTable("2F4(2)'.2"); CharacterTable( "2F4(2)'.2" ) gap> TimeFunction(HeLP_WithGivenOrder, [C, 39]); #I Number of solutions for elements of order 39: 0; stored in HeLP_sol[39]. 1

This is also a good example to use \(p\)-constant characters:

gap> C:=CharacterTable("2F4(2)'"); CharacterTable( "2F4(2)'" ) gap> TimeFunction(HeLP_WithGivenOrderSConstant, [C, 13, 3]); #I Number of non-trivial 13-constant characters in the list: 19. 0

If using 4ti2, for some groups switching redund on and off gives major improvements.

gap> HeLP_Solver("4ti2"); '4ti2' will be used from now on. gap> HeLP_UseRedund(true); 'redund' will be used from now on. gap> C := CharacterTable(SmallGroup(160,91));; gap> TimeFunction(HeLP_ZC, [C]); 26 gap> HeLP_Solver("normaliz"); 'normaliz' will be used from now on. gap> TimeFunction(HeLP_ZC, [C]); 12

Using 4ti2 but not redund `HeLP_ZC(C)`

ran for over 400 hours without a result.

gap> C := CharacterTable(SmallGroup(96,12));; gap> HeLP_UseRedund(false); The calculations will be performed without using 'redund' from now on. gap> HeLP_Solver("4ti2");; gap> TimeFunction(HeLP_ZC, [C]); 2

Running this example using redund the computations does not proceed for elements of order 12.

HeLP provides different InfoLevels for different situations. The variable controlling the InfoLevel is `HeLP_Info`

and it might be changed using `SetInfoLevel(HeLP_Info, n)`

to set the InfoLevel to n. The maximal `HeLP_Info`

entry is 5, the default InfoLevel is 1. The examples below give some idea, how one can use `HeLP_Info`

, but do not give complete information on all possibilities.

If one is only interested whether (ZC) or (PQ) can be solved using the HeLP method, one can set `HeLP_Info`

to 0:

gap> C := CharacterTable("M11"); CharacterTable( "M11" ) gap> HeLP_ZC(C); #I ZC can't be solved, using the given data, for the orders: [ 4, 6, 8 ]. false gap> SetInfoLevel(HeLP_Info, 0); gap> HeLP_ZC(C); false

If the InfoLevel is set to 2, the functions `HeLP_ZC`

(2.1-1) and `HeLP_PQ`

(2.2-1) print information which order of torsion units is currently considered, so that the user can keep track of the progress. This may be used for bigger groups to see, if the calculations might finish at some point. Continuing the above example:

gap> SetInfoLevel(HeLP_Info, 2); gap> HeLP_PQ(C); #I Checking order 2. #I Checking order 3. #I Checking order 5. #I Checking order 10. #I Checking order 11. #I Checking order 15. #I Checking order 22. #I Checking order 33. #I Checking order 55. true

`HeLP_Info`

at InfoLevel 3 provides also some information about the used ordinary character table or Brauer tables:

gap> SetInfoLevel(HeLP_Info, 3); gap> HeLP_PQ(C); #I Checking order 2. #I Using table BrauerTable( "M11", 3 ). #I Checking order 3. #I Using table BrauerTable( "M11", 3 ). #I Using table BrauerTable( "M11", 11 ). #I Checking order 5. #I Using table BrauerTable( "M11", 3 ). #I Checking order 10. #I Using table BrauerTable( "M11", 3 ). #I Checking order 11. #I Using table BrauerTable( "M11", 3 ). #I Checking order 15. #I Using table BrauerTable( "M11", 3 ). #I Using table BrauerTable( "M11", 11 ). #I Checking order 22. #I Using table BrauerTable( "M11", 3 ). #I Checking order 33. #I Using table BrauerTable( "M11", 3 ). #I Using table BrauerTable( "M11", 11 ). #I Using table BrauerTable( "M11", 2 ). #I Checking order 55. #I Using table BrauerTable( "M11", 3 ). true

Setting `HeLP_Info`

to 4 is useful when there are many possibilities for the partial augmentations of the powers of some unit. A good example is the example on "L4(3).2^2" in the section on Time Saving 4.3, see above: If you see quickly that almost nothing is happening, you might want to change your strategy.

`HeLP_Info`

at level 5 informs the user on all changes of the used character table. Using it makes sense, if you work with the command `HeLP_ChangeCharKeepSols`

(3.4-1).

The package also allows using characters even if the whole character table is not available. E.g. induced characters:

gap> C := CharacterTable("U3(8)"); CharacterTable( "U3(8)" ) gap> G := PSU(3,8); <permutation group of size 5515776 with 2 generators> gap> A := AutomorphismGroup(G); <group of size 99283968 with 4 generators> gap> AllCharacterTableNames(Size,Size(A)); [ "3.U3(8).6", "3.U3(8).S3" ]

This means: The character table of the automorphism group A of PSU(3,8) is not available in GAP. However one can use induced characters:

gap> NN := NormalSubgroups(A); [ <trivial group>, <group of size 5515776 with 2 generators>, <group with 3 generators>, <group of size 16547328 with 3 generators>, <group of size 49641984 with 4 generators>, <group of size 33094656 with 4 generators>, <group of size 99283968 with 4 generators> ] gap> H := NN[2]; #Subgroup of A isomorphic to G <group of size 5515776 with 2 generators> gap> CharacterTableWithStoredGroup(H,C); CharacterTable( <group of size 5515776 with 2 generators> ) gap> D := CharacterTable(H); CharacterTable( <group of size 5515776 with 2 generators> ) gap> chi := InducedClassFunction(Irr(D)[2],A); Character( CharacterTable( <group of size 99283968 with 4 generators> ), [ 1008, -144, -126, 18, 0, 0, 0, 0, 36, 36, 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, -18, 0, 0, 0, 0 ] ) gap> HeLP_WithGivenOrder([chi],7*19); #I Number of solutions for elements of order 133: 0; stored in HeLP_sol[133]. [ ]

One can also use characters, which are not available in GAP, but are entered manually:

gap> C := CharacterTable("L2(49)"); CharacterTable( "L2(49)" ) gap> HeLP_WithGivenOrder(C,15);; #I Number of solutions for elements of order 15: 56; stored in HeLP_sol[15]. gap> C7 := C mod 7; fail

The Brauer characters for the prime 7 are well known, see e.g. [Sri64] , but are not yet available in GAP.

gap> OrdersClassRepresentatives(C); [ 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 12, 12, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25 ] gap> chi := ClassFunction(C, [ 3, 0, -1, 0, -E(5)^2-E(5)^3, -E(5)-E(5)^4, 0, > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]); ClassFunction( CharacterTable( "L2(49)" ), [ 3, 0, -1, 0, -E(5)^2-E(5)^3, -E(5)-E(5)^4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ) gap> HeLP_WithGivenOrder([chi],15); #I Number of solutions for elements of order 15: 0; stored in HeLP_sol[15]. [ ]

The class function `chi`

above is of course not a proper character of the group, but the values coincide with the values of a 7-Brauer character of the group on the conjugacy classes of order 1, 3 and 5, i.e. the one needed to use HeLP for order 15. All functions of the HeLP-package only access values of class functions on conjugacy classes of elements with an order dividing the order of the unit in question. That is why this class function `chi`

can be used in this setting.

This section gives a demonstration of many functions of the package. The goal is to verify the Prime Graph Question for the McLaughlin simple group, which was proved in [BK07]

gap> C := CharacterTable("McL"); CharacterTable( "McL" ) gap> SetInfoLevel(HeLP_Info,4);

The function `HeLP_PQ(C)`

would take really long. Instead one can use `HeLP_AllOrdersPQ(C)`

several times on a high InfoLevel. Any time you see the function needs long, just try some manual calculations. Compute first the partial augmentations of elements of prime order:

gap> HeLP_WithGivenOrder(C,2);; #I Number of solutions for elements of order 2: 1; stored in HeLP_sol[2]. gap> HeLP_WithGivenOrder(C mod 2,3);; #I Number of solutions for elements of order 3: 4; stored in HeLP_sol[3]. gap> HeLP_WithGivenOrder(C mod 3,5);; #I Number of solutions for elements of order 5: 6; stored in HeLP_sol[5]. gap> HeLP_WithGivenOrder(C mod 3,7);; #I Number of solutions for elements of order 7: 174; stored in HeLP_sol[7]. gap> HeLP_WithGivenOrder(C mod 3,11);; #I Number of solutions for elements of order 11: 20; stored in HeLP_sol[11].

For mixed order in most situations \(p\)-constant characters are interesting. Check the tables for such characters of small degree.

gap> HeLP_WithGivenOrderSConstant(Irr(C){[2,3,4,5]},7,3); #I Number of non-trivial 7-constant characters in the list: 4. [ ] gap> HeLP_WithGivenOrderSConstant(Irr(C){[2,3,4,5]},11,2); #I Number of non-trivial 11-constant characters in the list: 4. [ ] gap> HeLP_WithGivenOrderSConstant(Irr(C){[2,3,4,5]},11,3); #I Number of non-trivial 11-constant characters in the list: 4. [ ] gap> HeLP_WithGivenOrderSConstant(Irr(C mod 3){[2,3,4,5]},7,5); #I Number of non-trivial 7-constant characters in the list: 4. [ ] gap> HeLP_WithGivenOrderSConstant(Irr(C mod 3){[2,3,4,5]},7,11); #I Number of non-trivial 7-constant characters in the list: 4. [ ] gap> HeLP_WithGivenOrderSConstant(Irr(C mod 3){[2,3,4,5]},11,5); #I Number of non-trivial 11-constant characters in the list: 2. [ ]

These calculations are enough to obtain an affirmative answer to the Prime Graph Question:

gap> HeLP_AllOrdersPQ(C); #I Checking order 2. #I Using the known solutions for elements of order 2. #I Checking order 3. #I Using the known solutions for elements of order 3. #I Checking order 5. #I Using the known solutions for elements of order 5. #I Checking order 7. #I Using the known solutions for elements of order 7. #I Checking order 11. #I Using the known solutions for elements of order 11. #I Checking order 21. #I Using the known solutions for elements of order 21. #I Checking order 22. #I Using the known solutions for elements of order 22. #I Checking order 33. #I Using the known solutions for elements of order 33. #I Checking order 35. #I Using the known solutions for elements of order 35. #I Checking order 55. #I Using the known solutions for elements of order 55. #I Checking order 77. #I Using the known solutions for elements of order 77. true

Checking these computations takes a few minutes.

generated by GAPDoc2HTML