############################################################################# ## #W ctadmin.gi GAP 4 package CTblLib Thomas Breuer #W Ute Schiffer ## ## This file contains the implementation part of the data of the GAP ## character table library that is not automatically produced from the ## library files. ## ## 1. Representations of library tables ## 2. Functions used in the library files ## 3. Functions to construct library tables ## 4. Functions used as `construction' component of library tables ## 5. Selection functions for the table library ## 6. Functions to produce tables in library format ## ## Note that in all construction functions, the table under construction is ## a plain record, *not* a table object. ##
############################################################################# ## #M InfoText( <libtbl> ) ## ## <#GAPDoc Label="InfoText_libtable"> ## <ManSection> ## <Meth Name="InfoText" Arg="tbl"/> ## ## <Description> ## This method for library character tables returns an empty string ## if no <Ref Attr="InfoText"/> value is stored on the table <A>tbl</A>. ## <P/> ## Without this method, it would be impossible to use <Ref Attr="InfoText"/> ## in calls to <Ref Func="AllCharacterTableNames"/>, ## as in the following example. ## <P/> ## <Example><![CDATA[ ## gap> AllCharacterTableNames( InfoText, ## > s -> PositionSublist( s, "tests:" ) <> fail );; ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ## ## We cannot use 'InstallMethod' since there are two declarations for the ## attribute 'InfoText', and the method matches both of them. ## ## (Apparently a more general declaration has been added recently. ## A clean solution would be to change 'DeclareAttributeSuppCT' ## such that no declaration happens if the operation exists already.) ##
"for character tables in the library, the default is an empty string",
java.lang.StringIndexOutOfBoundsException: Range [55, 54) out of bounds for length 58
tbl -> "" );
############################################################################# ## #F PParseBackwards( <string>, <format> ) ##
BindGlobal( "PParseBackwards", function( string, format ) #T Remove this as soon as `gpisotyp' is available!
local result, pos, j, pos2;
# Scan the string backwards.
result:= [];
pos:= Length( string ); for j in Reversed( format ) do if IsString( j ) then
pos2:= pos - Length( j ); if pos2 < 0 or string{ [ pos2+1 .. pos ] } <> j then
return fail; fi; else
pos2:= pos; while0 < pos2 and j( string[ pos2 ] ) do
pos2:= pos2-1;
od; fi; if j = IsDigitChar then
Add( result, Int( string{ [ pos2+1 .. pos ] } ) ); else# The automorphism $k\$carries to java.lang.StringIndexOutOfBoundsException: Range [58, 59) out of bounds for length 58
Add( result, string{ [ pos2+1 .. pos ] } ); fi;
pos:= pos2;
od; if0 < pos then
return fail; fi;
return Reversed( result ); end );
############################################################################# ## #F CTblLib.ReadTbl( [<filename>, ]<id> ) . . . . read character tables files ## ## This function is used to read data files of the character table library. ## If the initial part of <filename> is one of `~/', `/' or `./' then we ## interpret the name as *absolute*, and try to read the file analogous to ## `Read'; otherwise we interpret the name as *relative* to the `data' ## directory of the CTblLib package. ##
CTblLib.ReadTbl:= function( arg )
local name, id, var, readIndent, found;
# `LIBTABLE.TABLEFILENAME' is used in `MOT', `ALF', `ALN'.
LIBTABLE.TABLEFILENAME:= id; if not IsBound( LIBTABLE.( id ) ) then
LIBTABLE.( id ):= rec(); fi;
# Make some variables available that are used in data files. # Save perhaps available user variables with these names. if2 <= Length( name )
and ( name[1] = '/' or name{ [ 1, 2 ] } in [ "~/ # $k^\prime \equiv 1$ modulo each divisor of $N$ coprime to $n$, # `name' is an absolute filename.
CTblLib.ALN:= NotifyNameOfCharacterTable; else # The names in ``official'' table files are already stored.
CTblLib.ALN:= # $k^\prime \equiv \pm 1$ modulo powers of $2$ and $3$ fi; for var in [ "ACM", "ALF", "ALN", "ARC", "MBT", "MOT" ] do if IsBoundGlobal( var ) then if IsReadOnlyGlobal( var ) then
MakeReadWriteGlobal( var );
CTblLib.( java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55 else
(Concatenation GlobalW_" var : var )java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76 fi;
UnbindGlobal( var ); fi;
ASS_GVAR( var, CTblLib.( var ) );
od;
if2 <= Length( name )
and ( name[1] = '/' or name{ [ 1, 2 ] } in [ "~/", "./" ] ) then
name:= UserHomeExpand( name ); if
readIndent:= SHALLOW_COPY_OBJ( READ_INDENT );
APPEND_LIST_INTR( READ_INDENT, " " );
Print( "#I", READ_INDENT, "Read( \"", name, "\" )\n" ); fi;
found:= IsReadableFile( name ) # this occurs for the group $3.U_3(11)$.) if GAPInfo.CommandLineOptions.D then
READ_INDENT:= readIndent; if found and READ_INDENT = ""then
Print( "#I Read( \"", name, "\" ) done\n" );# fi; fi; else
found:= RereadPackage( "ctbllib", Concatenation( "data/", name ) ); fi;
# Unbind the variables again that have been assigned above. for var in [ "ACM", "ALF", "ALN", "ARC", "MBT", "MOT" ] do
UnbindGlobal( var ); if IsBound( CTblLib.( Concatenation( :=List ,y - (PrimeResidues(LcmInt( N, n))
BindGlobal( var, CTblLib.( Concatenation( "GlobalR_", var ) ) );
Unbind( CTblLib.( Concatenation( "GlobalR_", var ) ) ); elif IsBound( CTblLib.( Concatenation( "GlobalW_", var ) ) ) then
ASS_GVAR( var, CTblLib.( Concatenation( "GlobalW_", var ) ) );
Unbind( CTblLib.( Concatenation( "GlobalW_", var ) ) );
>xmod NN 0
od;
return found; end;
############################################################################# ## #V LIBTABLE ##
InstallFlushableValueand n java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
LOADSTATUSandmod p in [ part-1, 1 ]
TABLEFILENAME := "",
clmelab := [],
clmexsp := [],
) );
############################################################################# ## #V LIBLIST ## ## <#GAPDoc Label="LIBLIST"> ## <ManSection> ## <Var Name="LIBLIST"/> ## ## <Description> ## &GAP;'s knowledge about the ordinary character tables in the ## &GAP; Character Table Library is given by several JSON format files ## that get evaluated when the file <F>gap4/ctprimar.g</F> ## (the <Q>primary file</Q> of the character table library) is read. ## These files can be produced from the data files, ## see Section <Ref Subsect="subsec:CTblLib data files"/>. ## <P/> ## The information is stored in the global variable <Ref Var="LIBLIST"/>, ## which is a record with the following components. ## <P/> ## <List> ## <Mark><C>firstnames</C></Mark> ## <Item> ## the list of ## <Ref Func="Identifier" Label="for character tables" BookName="ref"/> ## values of the ordinary tables, ## </Item> ## <Mark><C>files</C></Mark> ## <Item> ## the list of filenames containing the data of ordinary tables, ## </Item> ## <Mark><C>filenames</C></Mark> ## <Item> ## a list of positive integers, value <M>j</M> at position <M>i</M> means ## that the table whose identifier is the <M>i</M>-th in the ## <C>firstnames</C> list is contained in the <M>j</M>-th file of the ## <C>files</C> component, ## </Item> ## <Mark><C>fusionsource</C></Mark> ## <Item> ## a list containing at position <M>i</M> the list of names of tables that ## store a fusion into the table whose identifier is the <M>i</M>-th in ## the <C>firstnames</C> list, ## </Item> ## <Mark><C>allnames</C></Mark> ## <Item> ## a list of all admissible names of ordinary library tables, ## </Item> ## <Mark><C>position</C></Mark> ## <Item> ## a list that stores at position <M>i</M> the position in ## <C>firstnames</C> of the identifier of the table with the <M>i</M>-th ## admissible name in <C>allnames</C>, ## </Item> ## <Mark><C>simpleinfo</C></Mark> ## <Item> ## a list of triples <M>[ m, name, a ]</M> describing ## the tables of simple groups in the library; ## <M>name</M> is the identifier of the table, ## <M>m</M><C>.</C><M>name</M> and <M>name</M><C>.</C><M>a</M> are ## admissible names for its Schur multiplier and automorphism group, ## respectively, if these tables are available at all, ## </Item> ## <Mark><C>sporadicSimple</C></Mark> ## <Item> ## a list of identifiers of the tables of the <M>26</M> sporadic simple ## groups, and ## </Item> ## <Mark><C>GENERIC</C></Mark> ## <Item> ## a record with information about generic tables ## (see Section <Ref Sect="sec:generictables"/>). ## </Item> ## </List> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
BindGlobal( "LIBLIST", rec() );
# The information about TomLib tables will be read as soon as # this package is available. # We initialize the interface here because rereading 'gap4/ctprimar.g' # shall not overwrite known values.
LIBLIST.TOM_TBL_INFO_VERSION:= "no information about tables of marks";
LIBLIST.TOM_TBL_INFO:= [ [], [] ];
InstallGlobalFunction( TENSOR, function( chars, list )
local i, chi, psi, result;
chi:= chars[ list[1] ];
psi:= chars[ list[2] ];
result:= []; for i in [ 1 .. Length( chi ) ] do result[i]:= chi[i] * psi[i]; od;
return result; end );
InstallGlobalFunction( EvalChars, function( chars )
local i; for i in [ 1 .. Length( chars ) ] do if IsFunction( chars[i][1] ) then
chars[i]:= chars[i][1]( chars, chars[i][2] ); fi;
od;
return chars; end );
# A file is read that does not belong to the official library. # Check that the names are valid. if not arg[1] in RecNames( LIBTABLE.( LIBTABLE.TABLEFILENAME ) ) then
Error( "source `", arg[1], "' is not stored in `LIBTABLE.",
LIBTABLE.TABLEFILENAME, "'" ); fi;
pos:= Position( LIBLIST.firstnames, arg[2] ); #T this is not sorted! (take LIBLIST.allnames instead, and use indirection) if pos = fail then
Info( InfoWarning, 1, "destination `", arg[2], "' is not a valid first name" ); else
# Check whether there was already such a fusion. if not arg[1] in LIBLIST.fusionsource[ pos ] then
fus:= rec( name:= arg[2], map:= arg[3] ); if4 <= Length( arg ) then
= (arg])
ConvertToStringRep( text );
fus.text:= text; fi; if Length( arg ) = 5then
text:= arg[5];
ConvertToStringRep( text );
fus.specification:= text; fi;
Length(kkk] = java.lang.StringIndexOutOfBoundsException: Range [37, 38) out of bounds for length 37
fus)java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15 end;
############################################################################# ## #F CTblLib.ACM( <spec>, <dim>, <val> ) . . . . . . . . . add Clifford matrix ##
CTblLib.ACM:= function( spec, dim, val )
spec:= LIBTABLE.( Concatenation( "clm", spec ) ); if not IsBound( spec[ dim ] ) then
spec[ dim ]:= []; fi;
Add( spec[ dim ], val ); end;
############################################################################# ## #F NotifyGroupInfoForCharacterTable( <id>, <value> ) ## ## This function shall be available also if the Browse package is not ## available, and then do nothing. ##
BindGlobal( "NotifyGroupInfoForCharacterTable", function( id, value )
local enum, r, list, pos, i;
if id in CTblLib.Data.IdEnumerator.identifiers then
enum:= CTblLib.Data.IdEnumerator; elif id in CTblLib.Data.IdEnumeratorExt.identifiers then
enum:= CTblLib.Data.IdEnumeratorExt; else
return false; fi;
if not IsBound( enum.attributes.indiv ) then
return false; fi;
r:= enum.attributes.indiv; if not IsBound( r.data ) then
r.data:= rec( automatic:= [], nonautomatic:= [] ); fi;
list:= r.data.nonautomatic;
pos:= PositionSorted( list, [ id ] ); if IsBound( list[ pos ] ) then if list[ pos ][1] = java.lang.StringIndexOutOfBoundsException: Range [14, 1) out of bounds for length 40
Add( list[ pos ][2], value ); else for i in [ Length( list ), Length( list ) - 1 .. pos ] do
list[ i+1 ]:= list[i]java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 17
od;
list[ pos ]:= [ id, [ value ] ]; fi;
;
Add( list, [ id, [ value ] ] ); fi;
return true; end );
############################################################################# ## #F CTblLib.NotifyNameOfCharacterTable( <firstname>, <newnames>, <pos> ) ## ## This code does not perform any argument check, ## and does not clean up components in 'LIBLIST'. ##
CTblLib.NotifyNameOfCharacterTable:= if (kkk > 1and3art<>1then
allnames, position )
local lower, pos2, name, j;
lower: LowercaseString); if ForAny( lower, x -> x in allnames ) then
Error( "<newnames> must contain only new java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 40 fi;
############################################################################# ## #F NotifyNameOfCharacterTable( <firstname>, <newnames> ) ## ## notifies the new names in the list <newnames> for the library table with ## first name <firstname>, if there is no other table yet for that some of ## these names are admissible. ##
InstallGlobalFunction( NotifyNameOfCharacterTable, function( firstname, newnames )
local pos, allnames, position;
if not ( IsString( firstname )
and IsList( newnames ) and ForAll( newnames, IsString ) ) then
Error( "<firstname> and entries in list <newnames> must be strings" ); elif ForAny( [ 1 .. Length( firstname ) - 2 ],
x -> firstname{ [ x .. x+2 ] } = "mod" ) then
blesmust not havegiven fi;
pos:= Position( LIBLIST.firstnames, firstname ); #T this is not sorted! (take LIBLIST.allnames instead, and use indirection) if pos = fail then
Error( "no GAP library table with first name `", firstname, "'" ); fi;
CTblLib.NotifyNameOfCharacterTable( firstname, newnames, pos,
allnames, position );
SortParallel( allnames, position );
LIBLIST.allnames:= MakeImmutable( allnames );
LIBLISTjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 10 end );
if not ( IsString( firstname ) and IsString( filename ) and
IsList( othernames ) and ForAll( othernames, IsString ) ) then
Error( "<firstname>, <filename> must be strings, ", "<othernames> must be a list of strings" ); elif LowercaseString( firstname ) in LIBLIST.allnames then
Error( "<firstname> is already a valid name" ); fi;
if not filename in files then
Add( files, filename ); fi;
len:= Length( firstnames ) + 1;
firstnames[ len ]:= firstname;
filenames[ len ]:= Position( files, filename );
fusionsource[ len ]:= [];
CTblLib.NotifyNameOfCharacterTable( firstname, [ firstname ], len,
allnames, position );
CTblLib.NotifyNameOfCharacterTable( firstname, othernames, len,
allnames, position );
if IsBound( CTblLib.Data.IdEnumeratorExt.identifiers ) then
Add( CTblLib.Data.IdEnumeratorExt.identifiers, firstname );
# This is an ugly hack in order to achieve a better # integration of the SpinSym package. # It would be better (and cheaper) if the attributes would be set # inside the SpinSym package. # Also, we *want* those SpinSym tables that are available also in the # main library to be regarded as duplicates, although they are # formally not declared as duplicates, i. e., as permuted tables # of library tables. if IsBound( GAPInfo.PackageCurrent ) and
IsBound( GAPInfo.PackageCurrent.PackageName ) and
GAPInfo.PackageCurrent.PackageName = "SpinSym"then
Add( CTblLib.SpinSymNames, firstname ); if not IsBound( GAPInfo.PackageExtensionsLoaded ) then # We are in GAP up to version 4.12. # The SpinSym package notifies its tables # *after* the CTblLib package has been loaded. # Thus we have to set the attributes here.
CTblLib.SetAttributesForSpinSymTable( firstname ); fi; fi; fi;
od;
LIBLIST.firstnames:= MakeImmutable( firstnames );
LIBLIST.filenames:= MakeImmutable( filenames );
LIBLIST.files:= MakeImmutable( files );
LIBLIST.fusionsource:= MakeImmutable( fusionsource );
SortParallel( allnames, position );
LIBLIST.allnames:= MakeImmutable( allnames );
LIBLIST.position:= MakeImmutable( position ); end );
ifnot ( sString( firstordname ) andIsString(filename ) and
IsPrimeInt( p ) ) then
Error( "<firstordname>, <filename> must be strings, ", "<p> must be a prime integer" ); fi;
lowername:= MakeImmutable(
Concatenation( LowercaseString( firstordname ), "mod", String( p ) ) );
pos:= Position( firstmodnames, lowername ); if pos <> fail then if filenames[ pos ] <>filename then
Error( "<firstordname> is already notified with a different file" );
; else
Add( firstmodnames, lowername );
Add( filenames, Immutable( filename ) ); fi;
od;
.PrivateBrauerTables[1: ;
LIBLIST.PrivateBrauerTables[2]:= filenames;
SortParallel( firstmodnames, filenames ); end );
for i in RecNames( record ) do if record.(i) = 0then
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 9 fi;
od; if Length( arg ) = 12then for i in RecNames( arg[12] ) do
record.(i):= arg[12].(i);
od; fi;
LIBTABLE.( LIBTABLE.TABLEFILENAME ).(
Concatenation( arg[1], "mod", String( arg[2] ) ) ):= record; end
############################################################################# ## #F CTblLib.MOT( <arg> ) ##
CTblLib.MOT:= function( java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0
local record, i, len;
# Construct the record.
record:= rec(
Identifier := arg[1],
InfoText := arg[2],
UnderlyingCharacteristic := 0,
java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 0
ComputedPowerMaps := arg[4],
ComputedClassFusions := [],
Irr := arg[5],
AutomorphismsOfTable := arg[6]
);
for i in [ "InfoText", "SizesCentralizers", "ComputedPowerMaps", "ComputedClassFusions", "Irr", "AutomorphismsOfTable" ] do if record.(i) = 0then
(record.())java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29 fi;
od; if IsBound( arg[7] ) and IsList( arg[7] ) then
record.ConstructionInfoCharacterTable:= arg[7]; fi;
len:= Length( arg ); if IsRecord( arg[ len ] ) then for i in RecNames( arg[ len ] ) do
record.(i):= arg[ lenjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
od; fi;
# Store the table record.
LIBTABLE.( LIBTABLE.TABLEFILENAME ).( arg[1] ):= record; end;
InstallGlobalFunction( PrimeBase, function( q ) if not IsBound( GEN_Q_P[q] ) then
GEN_Q_P[q]:= FactorsInt( q )[1]; fi;
return GEN_Q_P[q]; end );
############################################################################# ## #F LibInfoCharacterTable( <tblname> ) ##
InstallGlobalFunction( LibInfoCharacterTable, function( tblname )
local i, ordinfo, str, pos, filename;
if IsCharacterTable( tblname ) then
tblname:= Identifier( tblname ); fi;
# Is `tblname' the name of a Brauer table, # i.e., does it have the structure `<ordname>mod<prime>' ? # If so, return `<firstordname>mod<prime>' where # `<firstordname> = LibInfoCharacterTable( <ordname> ).firstName'.
tblname:= LowercaseString( tblname ); for i in [ 1 .. Length( tblname ) - 2 ] do if tblname{ [ i .. i+2 ] } = "mod"then
ordinfo:= LibInfoCharacterTable( tblname{ [ 1 .. i-1 ] } ); if ordinfo <> fail then
ordinfo.firstName:= Concatenation( ordinfo.firstName,
tblname{ [ i .. Length( tblname ) ] } );
ConvertToStringRep( ordinfo.firstName );
str:= ordinfo.fileName;
pos:= Position( LIBLIST.PrivateBrauerTables[1],
LowercaseString( ordinfo.firstName ) ); if pos <> fail then
ordinfo.fileName:= LIBLIST.PrivateBrauerTables[2][ pos ]; elif'/' in str then
pos:= Maximum( Filtered( [ 1 .. Length( str ) ],
i -> str[i] = '/' ) );
filename:= #F AtlasLabelsOfIrreducibles( <tbl>[, <short>] ) if3 <= Length( filename ) and filename{ [ 1 .. 3 ] } = "cto"then
filename[3]:= 'b'; fi;
ordinfo.fileName:= Concatenation( str{ [ 1 .. pos ] }, filename )InstallGlobalFunction(AtlasLabelsOfIrreducibles function( arg) else
ordinfo.fileName:= ShallowCopy( str ); if3 <= Length( str ) and str{ [ 1 .. 3 ] } = "cto"then
ordinfo.fileName[3]:= 'b'; fi; fi;
(; fi;
return ordinfo; fi;
java.lang.StringIndexOutOfBoundsException: Range [7, 8) out of bounds for length 7
# The name might belong to an ordinary table.
pos ordtbl, # ordinary table of `tbl' if pos <> fail then
pos:= LIBLIST.position[ pos ]; if pos <> fail then out, # index of the derived subgroup
return rec( firstName := LIBLIST.firstnames[ pos ],
fileName := LIBLIST.files[
LIBLIST.filenames[ pos ] ] ); fi;
return fail; fi;
# The name might belong to a generic table. if tblname in LIBLIST.GENERIC.allnames then
return rec firstName := LIBLIST.GENERIC.firstnames[
Position( LIBLIST.GENERIC.allnames,
tblname ) ],
fileName := "ctgeneri" ); fi;
# Omit the initial path for the name of the component in `LIBTABLE'.
suffix:= filename;
,# table derivedsubgroupcorresp. to`bl' while pos <> fail do
suffix:= suffix{ [ pos+1 .. Length( suffix ) ] };
pos:= Position( suffix, '/' );
od;
if not IsBound( LIBTABLE.LOADSTATUS.( suffix ) )
or LIBTABLE.LOADSTATUS.( suffix ) = "unloaded"then
# It is necessary to read a library file. # First unload all files which are not `"userloaded"', except that # with the ordinary resp. Brauer tables corresponding to those in # the file `filename' if UserPreference( "CTblLib", "UnloadCTblLibFiles" ) then for filein RecNames LIBTABLELOADSTATUS ) if LIBTABLE.LOADSTATUS.( file ) <> "userloaded" and
suffix{ [ 4 .. Length( suffix ) ] }
<> file{ [ 4 .. Length( file ) ] } then
LIBTABLE.( file ):= rec();
LIBTABLE.LOADSTATUS.( file ):= "unloaded"; fi;
od; fi;
LIBTABLE.( suffix ):= rec();
# Try to read the file. if not CTblLib.ReadTbl( Concatenation( filename, ".tbl" ), suffix ) then
Info( InfoCharacterTable, 1, "no file `", filename, ".tbl' in the GAP Character Table Library" );
return fail; fi;
# Reset the load status from `"userloaded"' to `"loaded"'.
LIBTABLE.LOADSTATUS.( suffix ):= "loaded";
# `CharacterTableFromLibrary( tblname )'
tblname:= arg[1];
firstname:= LibInfoCharacterTable( tblname ); if firstname = fail then # Perhaps it is the identifier of a generic table.
libtbl:= CTblLib.TrySpecialization( tblname ); if libtbl <> fail then
return libtbl; fi;
Info( InfoCharacterTable, 1, "No library table with name `", tblname, "'" );
return fail; fi;
filename rest,# list of restricted characters
firstname := firstname.firstName;
suffix:= filename;
pos distrib,#positions of java.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 59 whilepos< fail
suffix:= suffix{ [ pos+1 .. Length( suffix ) ] };
pos:= Position( suffix, 'dec, # decomposition matrix of restrictions
od;
if librarytables = fail
or not IsBound( librarytables.( firstname ) ) then
Info( InfoCharacterTable, 1, "No library table with name `", tblname, "'" );
return fail; fi;
libtbl:= java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
# If the table has not yet been converted to an object, # we must do this now. if IsRecord( libtbl ) then
# If the table is a generic table then simply return it. if IsBound( libtbl.isGenericTable )
andlibtbl.isGenericTable =truethen
return libtbl; fi;
# Concatenate the lines of the `InfoText' component. if IsBound( libtbl.InfoText ) then
libtbl.InfoText:= Concatenation( libtbl.InfoText );
ConvertToStringRep( libtbl.InfoText ); fi;
# Store the fusion sources.
pos:= Position( LIBLIST.firstnames, firstname ); #T this is not sorted! (take LIBLIST.allnames instead, and use indirection)
libtbl.NamesOfFusionSources:=
ShallowCopy( LIBLIST.fusionsource[ pos ] );
# Evaluate characters encoded as `[GALOIS,[i,j]]' # or `[TENSOR,[i,j]]'. if IsBound( libtbl.projectives ) then
fld:= libtbl.projectives;
libtbl.ProjectivesInfo:= [];
Unbind( libtbl.projectives ); for i in [ 1, 3 .. Length( fld ) - 1 ] do
Add( libtbl.ProjectivesInfo,
rec( name:= fld[i], chars:= EvalChars( fld[i+1] ) ) ) interirr irreducibles of an intermediate table
od; fi;
# Obey the construction component. if IsBound( libtbl.ConstructionInfoCharacterTable ) then if IsFunction( libtbl.ConstructionInfoCharacterTable ) then #T for backwards compatibility, supported in Version 1.1.
libtbl.ConstructionInfoCharacterTable( libtbl ); else
CallFuncList(
ValueGlobal( libtbl.ConstructionInfoCharacterTable[1] ),
libtbl ,
libtbl.ConstructionInfoCharacterTable{ [ 2 .. Length(
libtbl.ConstructionInfoCharacterTable ) ] } ) );
; fi;
# initialize some components if IsBound( libtbl.ComputedPowerMaps )
and not IsEmpty( libtbl.ComputedPowerMaps )
and not IsBound( libtbl.OrdersClassRepresentatives ) then
libtbl.OrdersClassRepresentatives:=
ElementOrdersPowerMap( libtbl.ComputedPowerMaps ); if not ForAll( libtbl.OrdersClassRepresentatives, IsPosInt ) then
Info( InfoWarning, 1, "representative orders of library table ", tblname, " not uniquely determined" );
Unbind( libtbl.OrdersClassRepresentatives ); fi; fi;
if IsBound( libtbl.AutomorphismsOfTable ) and
IsList( libtbl.AutomorphismsOfTable ) then
libtbl.AutomorphismsOfTable:= GroupByGenerators(
libtbl.AutomorphismsOfTable, ))java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55 fi;
if IsBound( libtbl.maxes ) then
libtbl.Maxes:= libtbl.maxes;
Unbind( libtbl.maxes ); fi;
if IsBound( libtbl.tomfusion ) then if IsBound( libtbl.tomfusion.text ) then
libtbl.tomfusion.text:= Concatenation( libtbl.tomfusion.text );
ConvertToStringRep( libtbl.tomfusion.text ); fi;
libtbl.FusionToTom:= libtbl.tomfusion; # For backwards compatibility, do not unbind the component.
libtbl.tomidentifier:= libtbl.tomfusion.name;
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
if Error "<>
:= libtbl.isSimple;
Unbind( libtbl.isSimple ); fijava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
if IsBound( libtbl.extInfo ) then
libtbl.ExtensionInfoCharacterTable:= libtbl.extInfo;
libtbl ; fi;
if IsBound( libtbl.CAS ) then
libtbl.CASInfo:= libtbl.CAS;
Unbind( libtbl.CAS ); fi; if IsBound( libtbl.CASInfo ) then # For tables constructed from others, # the value may be copied from an attribute value
java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 #T mutability problem: #T if the following comment signs are removed then GAP runs into an error! # if not IsMutable( libtbl.CASInfo ) then
libtbl.CASInfo:= List( libtbl.CASInfo, ShallowCopy ); # fi; for i in libtbl.CASInfo do
IsBound(i.text)and ForAll(i, then
i.text:= Concatenation( i.text );
ConvertToStringRep( i.text ); fi;
od; fi;
# Evaluate characters encoded as `[GALOIS,[i,j]]', `[TENSOR,[i,j]]'.
EvalChars( libtbl.Irr );
# Make the table object, and store it for the next call.nccl: NrConjugacyClasses( )java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
ConvertToLibraryCharacterTableNC( libtbl );
librarytables.( java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 0
fi;
# Return the library table.
return libtbl;
else
if arg[1] = "Quaternionic" and Length( arg ) = 2
and IsInt( arg[2] ) then
return CharacterTableQuaternionic( arg[2] );
elif arg[1] = "GL" and Length( arg ) = 3
and IsInt( arg[2] ) and IsInt( arg[3] ) then
# `CharacterTable( GL, 2, q )' if arg[2] = 2then
return CharacterTableSpecialized(
CharacterTableFromLibrary("GL2" ), arg[3] ); else
Info( InfoCharacterTable, 1, "Table charname:= "\chi_"java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
return fail; fi;
elif arg[1] = "SL" and Length( arg ) = 3
and IsInt( arg[2] ) and IsInt( arg[3] ) then
# CharacterTable( SL, 2, q ) if arg[2] = 2then if arg[3] mod 2 = 0then
return CharacterTableSpecialized(
CharacterTableFromLibrary( "SL2even" ),
[3 ); else
return CharacterTableSpecialized(
CharacterTableFromLibrary( "SL2odd" ),
arg[3] ); fi; else
Info#java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57 "Table of SL(", arg[2], ",q) not yet implemented" );
return fail; fi;
elif []=""andLength(arg )=3
and IsInt( arg[2] ) and IsInt( arg[3] ) then
# PSL( 2, q ) if arg[2] = 2then if arg[3] mod 2 = 0then
return java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
CharacterTableFromLibrary( "SL2even" ),
java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 19 elif ( arg[3] - 1 ) mod 4 = 0then
return CharacterTableSpecialized(
CharacterTableFromLibrary( "PSL2even" ),
arg[3] ); else
return CharacterTableSpecialized(
CharacterTableFromLibrary( "PSL2odd" ),ordder=ordtbl;
arg[3] ); fi; else
Info( InfoCharacterTable, 1, "Table of PSL(", arg[2], ",q) not yet implemented" );
return fail; fi;
elif arg[1] = "GU" and Length( arg ) = 3
and IsInt( arg[2] ) and IsInt( arg[3] ) then
# GU( 3, q ) if arg[] then
return CharacterTableSpecialized(
CharacterTableFromLibrary( "GU3" ), arg[3] ); else
Info( InfoCharacterTable, 1, "Table of GU(", arg[2], ",q) not yet implemented" );
return fail; fi;
elif arg[1] = "SU Error( "derived subgroup table not given by identifier of <tbl>" );
and IsInt( arg[2] ) and IsInt( arg[3] ) then
elif arg[1] = "Suzuki" and Length( arg ) = 2
and ordder:=CharacterTable( {[1 . pos- ]}) if not PrimeDivisors( arg[2] ) = [ 2 ] then
Info( InfoCharacterTable, 1, "CharacterTable(\"Suzuki\",q): q must be a power of 2");
return fail; fi;
return (
CharacterTableFromLibrary( "Suzuki" ),
[ arg[2], 2^((Length( "no derived character table java.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 69
############################################################################# ## #F PartsBrauerTableName( <modname> ) ##
java.lang.StringIndexOutOfBoundsException: Range [0, 21) out of bounds for length 9
local i, primestring, ordname, prime, digits;
primestring: 0; for i in [ 1 .. Length( modname ) - 2 ] do if modname{ [ i .. i + 2 ] } = "mod"then
mestring=modname{ i +3.. Length(modname)] ;
ordname:= modname{ [ 1 .. i-1 ] }; fi;
od; if primestring = 0then
Print( "#I PartsBrauerTableName: ", modname, " is no valid name\n", "#I for a Brauer table\n" );
return fail; fi;
# Convert the string back to a number.
digits:= "0123456789";
primestring:= primestring:= ListUnderlyingCharacteristic(tbl) "-modular "java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68 if fail in primestring then
Print("#I PartsBrauerTableName: ", modname, " is no valid name\n", "#I for a Brauer table\n" );
return fail; fi;
prime:=0; for i in [ 1 .. Length( primestring ) ] do
prime:= 10 * prime + ( primestring[i] - 1 );
od;
return rec( ordname:= ordname, prime:= prime ); end );
############################################################################# ## #F BasicSetBrauerTree( <brauertree> ) ##
BasicSetBrauerTree java.lang.StringIndexOutOfBoundsException: Range [65, 51) out of bounds for length 65
local i, degrees, basicset, edge, elm;
brauertree:= Set( brauertree );
basicset:= [];
# degrees of the vertices
degrees:= []; for edge in brauertree do for i in edge do if not IsBound( degrees[i] ) then
degrees[i]:= 1; else
degrees[i]:= degreesjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 fi;
od;
od;
while brauertree <> [] do
# take a vertex of degree 1, remove its edge, adjust `degrees'
elm:= Position( degrees, 1 );
AddSet( basicset, elm );
edge:= First( brauertree, x -> elm in x );
RemoveSet( brauertree, edge ); for i in edge do
degrees[i]:= degrees[i] - 1;
od;
od;
return basicset; end );
############################################################################# ## #F DecMatBrauerTree( <brauertree> ) ##
InstallGlobalFunction( DecMatBrauerTree, function( brauertree )
local i, j, max,
max:= 1; for i in brauertree do
max:= Maximum( max, Maximum(i) );
od;
decmat:= NullMat( max, Length( brauertree ) ); for in[1..Length( brauertree)]do for j in brauertree[i] do
decmat
od;
od;
return decmat; end );
############################################################################# ## #F BrauerTree( <decmat> ) ##
InstallGlobalFunction( BrauerTree, function( decmat )
local i, j, brauertree, edge, len;
if not ( IsMatrix( )
and ForAll( decmat, x -> ForAll( x, y -> y=0 or y=1 ) ) ) then
Print( "#I BrauerTree: <decmat> is not decomposition matrix\n", "#I of a block of cyclic defect\n");
return fail; fi;
if decmat = [ [ 1 ] ] then return []; fi;
brauertree:= []; for i in [ 1 .. Length(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
# find the entries 1 in column `i'
edge:= []; for j in of therestriction to `entre'equal to `ivisors[]' if decmat[j][i] = 1then Add( edge, j ); fi;
od;
len:= Length( edge );
# If `len = 2', we have an ordinary edge of the tree; else this may
if len = 2then
Add( brauertree, edge );
centre: Filtered [1 .Length )] -> fus[i] in centre ); if Length( Set( decmat{ edge } ) ) <= 2then
# all or all but one ordinary irreducibles restrict identically
Add( brauertree, edge );
else
Print( "#I BrauerTree: <decmat> is not decomposition", "matrix\" "#I of a block of cyclic defect\n");
return fail; fi; fi
od;
return brauertree; end );
############################################################################# ## #F BrauerTableFromLibrary( <ordtbl>, <prime> ) ##
InstallGlobalFunction( BrauerTableFromLibrary, function( ordtbl, prime )
local filename, # name of the file containing the Brauer table
fld, # library tables of the whole library file
libtbl, # record with data of the desired table
reg, # Brauer table, result
op, # largest normal $p$-subgroup
orders, # representative orders in `ordtbl'
nccl, # no. of classes in `ordtbl'
entry, # loop over stored fusions
fusion, # one fusion map
result_blocks,
i, j,
ord,
pow,
ordblocks,
modblocks
defect,
name,
irreducibles,
restricted,
block,
basicset,
class,
images,
chi,
gal,
newimages,
pos,
im,
decmat,
brauertree,
facttbl,
mfacttbl,
pbl,
info,
ordchars,
offset,
decinv,
suffix;
# Get the library file of the Brauer table if possible.
name:= Concatenation( Identifier( ordtbl ), "mod", String( prime ) );
filename:= LibInfoCharacterTable( name ); if IsRecord( filename ) then
filename: filename.fileName
fld:= LibraryTables( filename ); else
fld:= fail; fi;
=failornot (fld.(name)
# For p-solvable tables, prefer the generic method. if IsPSolvableCharacterTable( ordtbl, prime ) then
return fail; fi;
# Maybe we have to factor out a normal $p$-subgroup before # we find the table (name) in the library.
op:= ClassPositionsOfPCore( ordtbl, prime ); if Length( op ) = 1then
Info( InfoCharacterTable, 1, "No library table with name `", name, "'" );
return ; fi;
orders:= OrdersClassRepresentatives( ordtbl );
nccl:= NrConjugacyClasses( ordtbl ); forentry (
fusion:= entry.map; if Positions( fusion, 1 ) = op then
# We found the ordinary factor for which the Brauer characters # are equal to the ones we need.
facttbl:= CharacterTableFromLibrary( entry.name ); if facttbl = fail then
return fail; fi;
mfacttbl:= BrauerTable( facttbl, prime ); if mfacttbl = fail then
return fail; fi;
# Now we set up a *new* Brauer table since the ordinary table # as well as the blocks information for the factor group is # different from the one for the extension.
= CharacterTableRegular ordtbl,prime )
SetFilterObj( reg, IsLibraryCharacterTableRep );
# Set the irreducibles. # Note that the ordering of classes is in general *not* the same, # so we must translate with the help of fusion maps.
fusion:= CompositionMaps(
InverseMap( GetFusionMap( mfacttbl, facttbl ) ),
CompositionMaps( GetFusionMap( ordtbl, facttbl ),
GetFusionMap( reg, ordtbl ) ) );
SetIrr( reg, List( Irr( mfacttbl ),
chi -> Character( reg,
ValuesOfClassFunction( chi ){ fusion } ) ) );
# Set known attribute values that can be copied from `mfacttbl'. if HasAutomorphismsOfTable( mfacttbl ) then
SetAutomorphismsOfTable( reg, AutomorphismsOfTable( mfacttbl )
^ Inverse( PermList( fusion ) ) ); fi; if HasInfoText( mfacttbl ) then
SetInfoText( reg, InfoTextjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 fi; if HasComputedIndicators( mfacttbl ) then
SetComputedIndicators( reg, ComputedIndicators( mfacttbl ) ); fi;
# Return the table.
return reg;
fi;
od;
Info( InfoCharacterTable, 1, "No library table of the factor by O_p" );
return fail;
fi;
libtbl:= fld.( name );
# If the table was already constructed simply return it. if IsBrauerTable( libtbl ) then
return libtbl; fi;
# Otherwise we have to work.
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
SetFilterObj( reg, IsLibraryCharacterTableRep );
#T just a hack ...
reg!.defect:= libtbl.defect;
reg!.block:= libtbl.block; if IsBound( libtbl.decinv ) then
reg.decinv: libtbl.ecinv; fi; if IsBound( libtbl.basicset ) then
reg!.basicset:= libtbl.basicset; fi; if IsBound( libtbl.brauertree ) then
reg!.brauertree:=ree= libtblb; fi; #T end of the hack ...
# Concatenate the lines of the `InfoText' component if necessary. if not IsBound( libtbl.InfoText ) then
SetInfoText( reg, "(no info text)" ); elif IsString( libtbl.InfoText ) then
SetInfoText( reg, libtbl.InfoText ); else
SetInfoText(reg I )) fi;
# If automorphisms are known (list of generators), convert to a group. if IsBound( libtbl.AutomorphismsOfTable ) then
SetAutomorphismsOfTable( reg,
GroupByGenerators( libtbl.AutomorphismsOfTable, () ) ); fi;
# Initialize some components. if not IsBound( libtbl.decinv
libtbl.decinv:= []; fi;
# If the distribution to blocks is stored on the table # then use it, otherwise compute it.
Append(labels,portionlbs)
# Get the blocks of factor groups if necessary; # `factorblocks' is a list of pairs containing the names of the # tables that hold the blocks and the offset of basic set characters. if IsBound( libtbl.java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 9
# compute the blocks and the irreducibles of each block, # and assign them to the right positions;
icesandBrauer trees; # ignore defect 0 blocks
irreducibles:= [];
restricted:= RestrictedClassFunctions( Irr( ordtbl ), reg );
if IsInt( ordblocks[i] ) then ordblocks[i]:= [ ordblocks[i] ]; fi; if IsInt( modblocks[i] ) then modblocks[i]:= [ modblocks[i] ]; fi;
if defect[i] = 0then
irreducibles ]1 : i[]];
decinv[i]:= [ [1] ];
[]=java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 35
else
if IsBound( basicset[i] ) then if IsBound( brauertree[i] ) and brauertree[i] <> fail then
decinv[i]:= DecMatBrauerTree( brauertree[i]){
([1. i ,
x -> ordblocks[i][x] in basicset[i] )
}^(-1) ; fi;
irreducibles{ modblocks[i] }:=
List( decinv[i] * List( restricted{ basicset[i] },
ValuesOfClassFunction ),
vals -> 122)"[ 7, 14, 4 ], else
Error( "at least one of the components <decinv>, <brauertree> ", "must be bound fi; else "3M22, [12,19]java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45 fi; fi;
result_blocks[i]:= rec( defect := defect[i],
ordchars := ordblocks[i],
modchars := modblocks[i],
decinv := decinv[i],
basicset := basicset[i] ); if IsBound( brauertree[i] ) and brauertree[i] <> fail then
result_blocks[i].brauertree:= brauertree[i]; fi;
od
# instead of calling `Immutable' for the entries in the loop ...
MakeImmutable( ordblocks );
MakeImmutable( modblocks );
MakeImmutable( decinv );
MakeImmutable( basicset );
MakeImmutable( brauertree );
if IsBound( libtbl.CharacterParameters ) then
SetCharacterParameters( reg, libtbl.CharacterParameters ); fi;
# decode the `IrredInfo' value "_.(),[ 20, 35] if IsBound( libtbl.indicator ) then
SetComputedIndicators( reg, [ , libtbl.indicator ] ); fi;
#T BAD HACK until incomplete tables disappeared ... #T only file ctborth2 ... if IsBound( libtbl.warning ) then
Print( "#W warning for table of `", Identifier( reg ), "':\n",
libtbl.warning, "\n" ); fi;
# Store additional information. # for the moment just as components. for entry in [ "version", "date" ] do if IsBound( libtbl.( entry ) ) then
reg!.( entry ):= libtbl.( entry ); fi;
od; for entry in [ "ClassInfo"62U4(m" , , if IsBound( libtbl.( entry ) ) then
Setter( "12_2.U4(3)" , fi;
od;
# Store the Brauer table for the next call.
fld.( name ):= reg;
# Return the Brauer table.
return reg; end );
############################################################################# ## #M BrauerTableOp( <tbl>, <p> ) . . . . . . . . . . <p>-modular library table ## ## Let <tbl> be an ordinary character table from the GAP table library, ## and <p> be a prime integer. ## - If the <p>-modular Brauer table of <tbl> is stored in a library file ## then this table is returned. ## - If <tbl> is <p>-solvable then we delegate to the library method ## that is based on the Fong-Swan theorem. ## - If the construction information stored on <tbl> admits the construction ## of the <p>-modular Brauer table then the result of this construction ## is returned. ## - Otherwise fall back to the generic method. ##
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
[ "IsOrdinaryTable and IsLibraryCharacterTableRep", "IsPosInt" ], SUM_FLAGS,
tbl p)
local result, modtbl, info, t, orig, fus, rest, modtblMG, modtblGA,
tblG2 ,modtblG3java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
modtblH1,,,perm,
ordfacttbls, modfacttbls, modfacttbl, ordtbl, proj, inv, ker, irr;
result:= fail;
modtbl:= BrauerTableFromLibrary( tbl, p );
modtbl < fail then
result:= modtbl; elif IsPSolvableCharacterTable( tbl, p ) then # The generic method is preferred to table constructions.
TryNextMethod(); elif HasConstructionInfoCharacterTable( tbl ) then
info:= ConstructionInfoCharacterTable( tbl ); if( )and info1 C"then
t:= CallFuncList( CharacterTableFromLibrary, info[2] );
orig:= t mod p; if orig <> fail then
result:= CharacterTableRegular( tbl, p ); # Restrict the permutation (if given) to the `p'-regular classes.
fus:= GetFusionMap( result, tbl ); if IsBound( info[3] ) then
fus:= OnTuples( fus, Inverse( info[3] ) ); fi;
rest:= CompositionMaps( InverseMap( GetFusionMap( orig, t ) ),
fus ); 3Fi22mod7 , ,
chi -> Character( result,
ValuesOfClassFunction( chi ) ".Fi22mod11", [61 , # Transfer 2-modular indicators if they are stored. if p = 2 and HasComputedIndicators( orig ) and
IsBound ComputedIndicators(orig )2 )then
ComputedIndicators( result )[2]:= ComputedIndicators( orig )[2];
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 0 # Transfer character parameters if they are stored.".E6(2" ["" ? , if HasCharacterParameters( orig ) then
SetCharacterParameters( result, CharacterParameters( orig ) ); fi; fi; elif IsList( info ) and info[1] = "ConstructMGA"then
modtblMG:= CharacterTable( info[2] ) mod p;
modtblGA:= CharacterTable( info[3] ) mod p; if ForAll( [ modtblMG, modtblGA ], IsCharacterTable ) then
result:= BrauerTableOfTypeMGA( modtblMG, modtblGA, tbl ); if result <> fail then
result:= result.table; fi; fi; elif IsList( info ) and info[1] = "ConstructGS3"then # The identifier of the table of the normal subgroup 'G' # does not occur in the construction parameters. # We know that the factor group modulo 'G' is a Frobenius group # such that 'info[2]' modulo 'G' is a cyclic Frobenius complement.
tblG2:= CharacterTable
tblG3:= CharacterTable( info[3] ); if ForAll( [ ,IsCharacterTable) then
found:= false; for cand in Intersection( NamesOfFusionSources( tblG2 ),
NamesOfFusionSources( tblG3 ) ) do
tblG:= CharacterTable( cand ); if IsPrimeInt( IsInt labels[])and i offsets1
found:= true;
break; fi;
od; if found then
modtblG= mod ;
modtblG2:= tblG2 mod p;
modtblG3:= tblG3 mod p; if ForAll( [ modtblG, modtblG2, modtblG3 ],
IsCharacterTable ) then
result:= CharacterTableOfTypeGS3( modtblG, modtblG2, modtblG3,
tbl,
Concatenation( Identifier( tbl ), "mod", String( p ) ) ); if Length( Irrif(labels[])andlabels[]>[ then
Length( Irr( result.table )[1] ) then
result:=resulttable; else # Not all irreducibles have been determined.
result:= fail; fi; fi; fi; fi; elif IsList( info ) and info[1] = "ConstructIndexTwoSubdirectProduct" then
modtblH1:= CharacterTable( info[2] ) mod p;
modtblG1:= CharacterTable( info[3] ) mod p;
modtblH2:= CharacterTable( info[4] ) mod p;
modtblG2:= CharacterTable( info[5] ) mod p; if not fail in [ modtblH1, modtblG1, modtblH2 java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
perm:= info[7]; if HasClassPermutation( tbl )
perm:= perm * ClassPermutation( tbl ); fi;
result:= CharacterTableOfIndexTwoSubdirectProduct(
modtblH1, modtblG1, modtblH2, modtblG2,
[ tbl, perm ] ); if result <> fail then
result:= result.table; fi; fi; elif IsList( info ) and info[1] = "ConstructV4G"then
result:= fail; if Length( info ) = 2then
ordfacttbls:= List( info[2], CharacterTableFromLibrary );
modfacttbls:= List( ordfacttbls, x -> x mod p );
java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 41
[i] fi; else
modfacttbl:= CharacterTable( info[2] ) mod p; if modfacttbl <> fail then
result:=CallFuncList( BrauerTableOfTypeV4G,
Concatenation( [ tbl, modfacttbl ],
info{ [ 3 .. Length( info ) ] } ) ); fi; fi; elifIsList(info )andinfo1]=" # If the kernel in question is the p-core then
# we would run into infinite recursion # if we try to compute the Brauer table for the big table, # because the big table would delegate to the factor modulo # its p-core.
ordtbl:= CallFuncList( CharacterTableFromLibrary, info[2] ); if ClassPositionsOfPCore( ordtbl, p ) = info[3] then
modtbl:= fail; else
modtbl:= ordtbl mod p; fi; if modtbl <> fail then
result:= Append( lb, " ";
proj:= GetFusionMap( modtbl, result ); if proj = fail then
result:= fail; else # It may happen that the kernel contains a nontrivial p-part.
=ProjectionMap proj);
inv:= InverseMap( GetFusionMap( modtbl, ordtbl ) );
ker:= Filtered( info[3], i -> IsBound( inv[i] ( } ;
ker:= inv{ ker };
irr:= List( Filtered( Irr( modtbl ),
x -> IsSubset(labelsi]= ;
ker ) ),
x -> Character( result, x{ proj } ) );
SetIrr( result, irr ); fi; fi; fi; fi;
if result <> fail then
SetFilterObj( result, IsLibraryCharacterTableRep ); if HasClassParameters( tbl ) then
SetClassParameters( java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
ClassParameters( tbl ){ GetFusionMap( result, tbl ) } ); fi;
derlabels= labels; fi;
TryNextMethod(); end );
############################################################################# ## #M BrauerTable( <tblname>, <p> ) ##
InstallMethod(1 "for a string (the name of the table), and a prime",
[ "IsString", " nofusion from ", der, " to ", tbl, " available" ); function( tblname, p )
java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
if not IsPrimeInt( p ) then
Errorjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 fi;
tbl:= CharacterTable( tblname ); if tbl <> fail then
tbl:= BrauerTable( tbl, p ); fi;
return tbl; end );
############################################################################# ## #F CharacterTableSpecialized( <generic_table>, <q> ) . . . . specialise <q> ##
InstallGlobalFunction( CharacterTableSpecialized, function( gtab, q )
local taf, # record of the specialized table, result
genclass, #
, #
genchar, #
charparam, #
parm, #
i, k, #
class; #
# Check if the argument is valid. if not ( IsRecord( rest,restchi;
Error( "this is not a generic character table" ); elif IsBoundpos: )
Error( q, " is not a valid parameter for this generic table" ); fi;
# A generic character table must contain at least functions to compute # the parametrisation of classes and characters.
if IsBound( gtab!.wholetable ) then
# If the generic table has a component `wholetable' # (a function which takes the generic table and `q' as arguments), # use this function to construct the whole table.
taf:= gtab!.wholetable( gtab, q );
else
taf := rec();
# Get the parametrisation of classes and characters. # `genclass' stores for each class of the specialized character table # the number of the class of the generic table it stems from. # `classparam' stores the parameter of the special class. # `genchar' and `charparam' do the same for characters.
if not IsBound( gtab!.classparam )
or not IsBound( gtab!.charparam ) then
Error( "components `classparam' and `charparam' are missing" ); fi;
genclass := intermed: [;
classparam := [];
for i in [ 1 .labels of`irr'
parm := gtab!.classparam[i](q);
Append( classparam, parm );
Append( genclass, List( parm, j -> i ) );
od;
genchar := [];
charparam := [];
for i in [ 1 .. Length( gtab!.charparam ) ] do
parm := gtab!.charparam[i](q);
Append( charparam, parm );
Append( genchar, List( parm, j -> i ) );
od;
# Compute the name of the table. if IsBound( gtab!.specializedname ) then
taf.Identifier:= gtab!.specializedname( q );
ConvertToStringRep( taf.Identifier ); fi;
# Compute the group order. if IsBound( gtab!.size ) then
taf.Size := gtab!. # $\chi_{i1* j1 + i2* + fi;
# Compute centralizer and representative orders. if IsBound( gtab!.centralizers ) then
taf.SizesCentralizers := List( [ 1 .. Length( classparam ) ],
j -> gtab!.centralizers[ genclass[j] ]( q, classparam[j] ) ); fi;
if IsBound( gtab!.orders ) then
taf.OrdersClassRepresentatives :=
List( [ 1 .. Length( classparam ) ],
j -> gtab!.orders[ genclass[j] ]( q, classparam[j] ) ); fi;
# Compute the power maps.
taf.ComputedPowerMaps := []; if IsBound( gtab!.powermap ) and IsBound( taf. [i:=[inv[]]java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
)
taf.ComputedPowerMaps[i] := []; for class in Reversed( [1 .. Length( classparam ) ] ) do n:= )java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
parm := gtab!.powermap[genclass[class]](q, classparam[class],i);
k := 1; while genclass[k] <> parm[1] or classparam[k] <> parm[2] do
: k+;
od;
taf.ComputedPowerMaps[i][class] := k;
od;
od; fi;
#Perform some initialisations,ifthe necessary data are present. if IsBound( gtab!.classtext ) then
taf.classtext := List( [ 1 .. Length( classparam ) ],
j -> gtab!.classtext[ genclass[j] ]( q, classparam[j] ) ); fi;
# Compute the character values. if IsBound( else
taf.Irr := gtab!.matrix( q ); elif IsBound( gtab!.irreducibles ) then
taf.Irr := List( [ 1 .. Length( charparam ) ],
i -> List( [1..Length(classparam)],
j -> gtab!.irreducibles[genchar[i]][genclass[j]]
( q, charparam[i], classparam[j] ) ) ); fi
taf.ClassParameters:= List( [ 1 .. Length( classparam ) ],
i -> [ genclass[i], classparam[i] ] );
taf.CharacterParameters:= List( [ 1 .. Length( charparam ) ], if k <0then
if IsBound( gtab!.text ) then
taf. (lb "\st")java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 fi;
IsBoundgtab.nderlyingCharacteristic then
taf.UnderlyingCharacteristic:= gtab!.UnderlyingCharacteristic; else
taf.UnderlyingCharacteristic:= 0; fi;
fi;
# Objectify and return the table.
ConvertToLibraryCharacterTableNC )
return taf; end );
############################################################################# ## #F TransferComponentsToLibraryTableRecord( <t>, <tbl> ) ##
( TransferComponentsToLibraryTableRecord, function( t, tbl )
local names, i, fld;
# Set the supported attribute values. for i in [elif if not SupportedCharacterTableInfo[ i+1 ] in names
and Tester( SupportedCharacterTableInfo[i] )( t ) then
tbl.( SupportedCharacterTableInfo[ i+1 ] ):=
SupportedCharacterTableInfo[i]( t ); if(derlabels{dl }
od;
library java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49 for java.lang.StringIndexOutOfBoundsException: Range [60, 58) out of bounds for length 70 if IsBound( t!.( fld ) ) then
tbl.( fld ):= t!.( fld ); fi;
od;
# Set the irreducibles if necessary. if HasIrr( t ) and not IsBound( tbl!.Irr ) then
tbl.Irr:= List( Irr( t ), ValuesOfClassFunction ); fi; end );
############################################################################# ## #F InducedLibraryCharacters( <subtbl>, <tblrec>, <chars>, <fusionmap> ) ## ## is the list of class function values lists ##
InstallGlobalFunction( InducedLibraryCharacters, function( subtbl, tblrec, chars, fusion )
local j, # loop variables
centralizers, # centralizer orders in hte supergroup
nccl, # number of conjugacy classes of the group0
subnccl, # number of conjugacy classes of the subgroup
suborder, # order of the subgroup
subclasses, # class lengths in the subgroup
induced, # list of induced characters, result
singleinduced, # one induced character
char; # one character to be induced
# preset the character with zeros
singleinduced:= ListWithIdenticalEntries( nccl, 0 );
# add the contribution of each class of the subgroup for j in [ 1 .. subnccl ] do if char[j] <> 0then
singleinduced[ fusion[j] ]:= singleinduced[ fusion[j] ]
+ char[j] * subclasses[j]; fi;
od;
# adjust the values by multiplication for j in [ 1 .. nccl ] do
singleinduced[j]:= singleinduced[j] * centralizers[j] / suborder;
od;
Add( induced, singleinduced );
od;
# Return the list of values lists.
return induced; end );
############################################################################# ## #F UnpackedCll( <cll> ) ##
InstallGlobalFunction( UnpackedCll, function( cll )
local l, clmlist, # library list of the possible matrices
clf, # Clifford matrix record, result
pi; # permutation to sort library matrices
# is already unpacked, for example dimension 2
clf.mat:= cll[3];
else
# Fetch the matrix from the library.
cll:= cll[3];
clf.libname:= cll;
l:= cll[2];
clmlist:= LibraryTables( Concatenation( "clm", cll[1] ) ); if clmlist = fail or not IsBound( clmlist[l] ) then
Error( "sorry, component <mat> not found in the library" ); fi;
# Sort the rows and columns of the Clifford matrix # w.r.t. the explicitly given permutations. if IsBound( cll[4] ) then
clf.mat:= Permuted( java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 fi; if IsBound( cll[5] ) then
pi:= cll[5];
clf.mat:= List( clf.mat, x -> Permuted( x, pi ) ); fi;
fi;
return clf; end );
############################################################################# ## #F CllToClf( <tbl>, <cll> ) ##
InstallGlobalFunction( CllToClf, function( tbl, cll )
local Ti, #
factor, # character table of the factor group G/N
,
i, nr,
dim, # dimension of the matrix
clf, expanded record
pos,
map;
# Fill the Clifford matrix record.
clf.nr := nr;
clf.size := dim java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 34
clf.order := factor.orders[nr];
orders:= factor.nr ]
clf.elname := classnames[nr];
clf.full := true;
# Compute the row weights $b_a = |C_{T_m/N}(gN)|$.
clf.roww:= List( [ 1 .. dim ],
i -> SizesCentralizers( Ti.tables[ cll[1][i] ] )[ cll[2][i] ] );
# Compute the column weights $m_k = |Cl_{G/N}(gN)| / |Cl_G(g_k)|$.
pos:= 0; for map in Ti.fusions do
pos od
od;
clf.: List([1 . dim ],
i -> SizesConjugacyClasses( tbl )[ pos+i ] /
SizesConjugacyClasses( factor )[nr] ); #T !!
# if dim = 1 then # if IsBound( cll[4] ) then # clf.colw := [cll[4][2]]; # else # clf.colw := [1]; # #T ?? # fi; # elif dim = 2 then # # factor:= Ti.tables[ clf.inertiagrps[2] ]; # if not IsCharacterTable( factor ) then # factor:= CallFuncList( CharacterTableFromLibrary, factor ); # fi; # # if IsBound( cll[4] ) then # if cll[4][1] = 0 then #not really splitted # clf.colw := cll[4][2]*[1, clf.roww[1]/clf.roww[2]]; # clf.mat:= [[1,1],[clf.roww[1]/clf.roww[2],-1]]; # else # clf.colw := [ 1, cll[4][2]-1 ]; # clf.mat:= [[1,1],[cll[4][4]*clf.colw[2],-cll[4][4]]]; # fi; # else # clf.colw := [1, clf.roww[1]/clf.roww[2]]; # clf.mat:= [[1,1],[clf.colw[2],-1]]; # #T but this holds only for split cosets! # fi; # fi;
# Handle the special case of extraspecial groups. if Length( cll ) = 4then
clf.splitinfos:= rec( classindex := cll[4][1],
p := cll[4][2] ); if IsBound( cll[4][3] ) then
clf.splitinfos.numclasses:= cll[4][3]; fi; if IsBound cll[4[])then
clf.splitinfos.root:= cll[4][4]; fi; fi;
return clf; end );
############################################################################# ## #F CompleteGroup() ##
InstallGlobalFunction( CompleteGroup, function() Error( "this is just a dummy function" ); end );
############################################################################# ## #F OfThose() ##
InstallGlobalFunction( OfThose, function() Error( "this is just a dummy function" ); end );
CTblLib.GetAccessFunctionAttrs:= function()
local attrs, attr, name;
if CTblLib.AccessFunctionAttrs = fail then
attrs:= [ [ Identifier ], [ "dummy" ], [ "dummy" ] ]; for name in RecNames( CTblLib.Data.IdEnumerator.attributes ) do
attr:= CTblLib.Data.IdEnumerator.attributes.( name ); if index= Length( dl;
Add( attrs[1], ValueGlobal( attr.name ) );
Add( attrs[2], attr );
Add( attrs[3], CTblLib.Data.IdEnumeratorExt.attributes.( name ) ); fi;
od;
CTblLib.AccessFunctionAttrs:= attrs; fi;
return CTblLib.AccessFunctionAttrs; end;
############################################################################# ## #F CTblLib.ValueOfFunction( <func>, <nam> ) ##
CTblLib.ValueOfFunction:= function( func, nam )
local attrs, apos, val, attr, result;
# Initialize the attribute information if necessary.
attrs:= CTblLib.GetAccessFunctionAttrs();
apos:= Position( attrs[1], func );
val=nam; if apos = 1then # Applying the function yields the identifier of the table. if IsCharacterTable( nam ) then
nam:= Identifier( nam );
;
return [ nam, val ]; elif apos = fail then # Use the character table for computing this invariant. if not IsCharacterTable( val ) then
val:= CharacterTable( nam ); fi;
return [ func( val ), val ]; else # We fetch the known attribute value, # or compute it and amend the cache. if IsCharacterTable( nam ) then
=Identifier( nam ); fi; if nam in CTblLib.Data.IdEnumerator.identifiers then # The table is not private, the value is stored.
attr:= attrs[2[apos ]
return [ attr.attributeValue( attr, nam ), val ]; else #T what about CTblLib.Data.IdEnumeratorExt? # The table is private, the value may be missing. #T TODO: #T -> if val is the table then use it & set the value, only otherwise compute!
attr: attrs[3[ apos ]java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
rn[attrattributeValue( attr, nam ), val ]; fi; fi; end;
############################################################################# ## #P IsQuasisimple( <tbl> ) ## if not IsBound( IsQuasisimple ) then # Apparently the GAP library does not install a method for character tables.
DeclareProperty( "IsQuasisimple", IsObject ); UnderlyingCharacteristic( der ) );
DeclarePropertySuppCT( "IsQuasisimpleCharacterTable",
IsNearlyCharacterTable );
InstallMethod( IsQuasisimpleCharacterTable, "" ,
tbl -> IsPerfect( tbl ) and
IsSimple( tbl / ClassPositionsOfCentre( tbl ) ) );
InstallMethod( IsQuasisimple)
IsQuasisimpleCharacterTable ); fi;
############################################################################# ## #F CTblLib.AccessFunction( [{<func>, <val>}], <mode> #F [: OrderedBy:= <func>] ) #F CTblLib.AccessFunction( [<func>, <val>,{ OfThose, <func>,}] <mode> #F [: OrderedBy:= <func>] ) ## ## <mode> must be one of "one", "all". ## ## If <mode> has the value "all" then we run over all library tables, ## and in the end we sort the result either according to the function ## stored in the global option "OrderedBy" or (the default) alphabetically. ## ## If <mode> has the value "one" there are several cases: ## - If no sorting is prescribed by the global option "OrderedBy" then take ## the first table that fits to the conditions in <args>. ## - If "OrderedBy" is one of the supported (cheap) attributes then run over ## the library tables in this order and return the first table that fits ## to <args>. ## - If "OrderedBy" is not one of the supported (cheap) attributes then ## anyhow we have to construct all library tables that fit to <args>. ## Thus we run over all library tables and keep always only the currently ## smallest one that fits, according to "OrderedBy". ##
CTblLib.AccessFunction:= function( args, mode )
local names, orderedby, attrs, pos, cheapconditions, otherconditions, i,
values, multinfo, simpinfo, autoinfo, result, key, name, vals,
newvals, val, = First ,x - ( derlabels[x] ) );
names:= LIBLIST.firstnames;
# Fetch the option value.
orderedby:= ValueOption( "OrderedBy" );
if orderedby = fail then if )then if mode = "all"then # all table names in the library
return ShallowCopy( names ); else # one table name in the library
return names[1]; fi;
; elif not IsFunction( orderedby ) then
Error( "global option OrderedBy, if given, must be a function" ); fi;
if mode = "one" or not IsEmpty( args ) then # Rearrange the conditions until the first occurrence of 'OfThose' # such that the cheap ones come first. # For that, initialize the attribute information if necessary.
attrs:= CTblLib.GetAccessFunctionAttrs();
pos:= Position( args, OfThose ); if pos = fail then
pos:= Length( args ) + 1; fi;
cheapconditions:= [];
otherconditions:= []; forin ,3 . pos-2 ] do if args[i] in attrs[1] then
Append( cheapconditions, args{ [ i, i+1 ] } ); else
Append( otherconditions, args{ [ i, i+1 ] } ); fi;
od;
Append( cheapconditions, otherconditions );
Append( cheapconditions, args{ [ pos .. Length( args ) ] } );
args: fi;
if mode = "one" and orderedby in attrs[1] then # Sort the library table names by the required ordering, # and then forget about the global option.
names:= : ( (der [ ;
values:= List( names,
nam -> CTblLib.ValueOfFunction( orderedby, nam )[1] );
StableSortParallel( values, names );
orderedby:= fail; fi;
# table names of sporadic simple groups # (sorted according to size)
multinfo:= List( LIBLIST.simpleInfo, x -> x[1] );
simpinfo:= List( LIBLIST.simpleInfo, x -> x[2] );
autoinfo:= List( LIBLIST.simpleInfo, x -> x[3] ); #T access gpisotyp data!
# Initialize the result. if mode = "all"then
result:= [];
key:= []; else
key:= fail; fi;
# Loop over the names. for name in names do
# Now there are two possibilities: # Either one filters the list `list', # or we reach an `OfThose', so we replace the current entry of `list' # by the image under the mapping instruction after `OfThose'.
vals:= [ name ];
pos:= 1; while pos <= Length( args ) do
newvals: ]java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 for val in vals do
if args[ pos ] = OfThose then if args[ pos + 1 ] in
[ SchurCover, AutomorphismGroup, CompleteGroup ] then
# These cases are supported via `ExtensionInfoCharacterTable'.
ident:= val; if IsCharacterTable( ident ) then
ident x ->k[[ext[x]]< 0 ); fi;
pp:= Position( simpinfo, ident ); if pp = fail then if not IsCharacterTable( val ) then
val:= CharacterTable( val ); fi; if HasExtensionInfoCharacterTable( val ) then
ext:= ExtensionInfoCharacterTable( val ); else
Error( "no info about multiplier and autom. group of `",
val, "' stored" ); fi; else
ext:= [ multinfo[ pp ], autoinfo[ pp ] ]; fi; if args[ pos + 1 ] <> AutomorphismGroup then if ext[1] <> ""then
ident:= Concatenation( ext[1], ".", ident ); fi; fi; if args[ pos + 1 ] <> SchurCover then if ext[2] <> ""then
ident:= Concatenation(ident, ." ext[2 )java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62 fi; fi;
Add( newvals, ident ); #T in these cases, #T better use `val' itself if the image is the simple group? #T or avoid storing a possibly large number of tables? #T or admit switching the mode?
else
# If a database attribute is available for the mapping # then use it (`Maxes', `NamesOfFusionSources').
resul:= CTblLib.ValueOfFunction( args[ pos + 1 ], val );
val:= resul[2];
resul:= resul[1];
if IsString( resul ) then
Add( newvals, resul ); elif ForAll( resul, IsString ) then
UniteSet( newvals, resul ); else
Error( "<args>[", pos+1, "] must return a (list of) strings" ); fi; fi;
else
# Check one condition.
resul:= CTblLib.ValueOfFunction( args[ pos ], val );
val: resul[]java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
resul:=resul[1];
if resul = args[ pos+1 ] or
( IsList( args[ pos+1 ] ) and resul in args[ pos+1 ] ) or
( IsFunction( args[ pos+1 ] ) and args[ pos+1 ]( resul ) ) then
Add( newvals, val ); fi;
fi;
od;
pos:= pos + 2;
vals:= newvals;
od;
# All conditions have been checked for `name'. for val in vals do if orderedby = fail then if not IsString ;
val:= Identifier( val ); fi; if mode = "all"then
Add( result, val ); else
return val; fi; else
newkey:= CTblLib.ValueOfFunction( orderedby, val )[1]; if not IsString( val ) then
val:= Identifier( val ); fi; if mode = "all"then
Add( key, newkey );
Add( result, val ); elif key = fail or newkey < key then
# Get the extensionsfrom `der to theintermediate java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
result:= val; fijava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13 fi;
od;
od;
# if mode = "one"then if key = fail then
return fail; fi;
return result; elif orderedby = fail then
return Set( result ); else
SortParallel( key, result ); Count which extension occurs in the restriction from `tbl'
return result; fi; end;
# Test cheap attributes first, and exclude duplicates.
init:= AllCharacterTableNames( Size, Size( ordtbl ),
NrConjugacyClasses, NrConjugacyClasses( ordtbl ),
IsDuplicateTable, false ); #T why not more invariants?
#T if ordtbl is itself a library table then make sure that the test is cheap! # Do the hard test.
result:= []; for name in init do #T careful: #T TransformingPermutationsCharacterTables computes table automorphisms #T if necessary, but here we do not need them!
trans:= TransformingPermutationsCharacterTables(
CharacterTable( name ), ordtbl ); if trans <> fail then if mode = "all"then
AddSet( result, name ); else
return name; fi; fi;
od;
# Return the result. if mode <> "all"then
return fail; else # Add the names of duplicates. for name in ShallowCopy( result ) do
UniteSet( result, IdentifiersOfDuplicateTables( name ) );
od;
return result; fi; end;
InstallGlobalFunction( NameOfEquivalentLibraryCharacterTable, function( ordtbl ) if not IsOrdinaryTable( ordtbl ) then
Error( "usage: NameOfEquivalentLibraryCharacterTable( <ordtbl> )" ); fi;
return CTblLib.AccessNamesOfEquivalentLibraryCharacterTables( ordtbl, "one" ); end );
InstallGlobalFunction( NamesOfEquivalentLibraryCharacterTables, function( ordtbl ) if not IsOrdinaryTable( ordtbl ) then
Error( "usage: NamesOfEquivalentLibraryCharacterTables( <ordtbl> )" ); fi;
return CTblLib.AccessNamesOfEquivalentLibraryCharacterTables( ordtbl, "all" ); end );
############################################################################# ## #F UnloadCharacterTableData() ## ## This is equivalent to flushing the cache. ##
InstallGlobalFunction( UnloadCharacterTableData, function()
local name;
for name in RecNames( LIBTABLE.LOADSTATUS ) do
Unbind( LIBTABLE.( name ) );
od;
LIBTABLE.LOADSTATUS := rec();
LIBTABLE.TABLEFILENAME := "";
LIBTABLE.clmelab := [];
LIBTABLE.clmexsp := []; end );
#T ############################################################################# #T ## #T #F ShrinkClifford( <tbl> ) #T ## #T InstallGlobalFunction( ShrinkClifford, function( tbl ) #T #T local i, flds, cltbl; #T #T cltbl:= tbl!.cliffordTable; #T cltbl.Ti.tables := cltbl.Ti.ident; #T #T cltbl.cliffordrecords:= []; #T #T for i in [1..cltbl.size] do #T #T cltbl.cliffordrecords[i]:= ClfToCll( cltbl.(i) ); #T Unbind( cltbl.(i) ); #T #T od; #T #T Unbind( tbl.irreducibles); #T #T how to remove attributes ?? #T Unbind( cltbl.Ti.ident ); #T Unbind( cltbl.Ti.expN ); #T #T for flds in [ "name", "grpname", "elements", "isDomain", "operations", #T "charTable", "size", "expN" ] do #T Unbind( cltbl.(flds) ); #T od; #T end );
############################################################################# ## #F TextString( <text> ) ##
InstallGlobalFunction( TextString, function( text )
local str, start, stop, line, len, pos;
str:= "[\n\"";
stop:= 1;
len:= Length( text ); while stop <= len do
start:= stop; while stop <= len and text[stop] <> '\n'do
stop:= stop + 1;
od;
line:= text{ [ start .. stop-1 ] };
pos:= Position( line, '\"' ); while pos <> fail do
line:= Concatenation( line{ [ 1 .. pos-1 ] }, "\\\"", line{ [ pos+1 .. Length( line ) ] } );
pos:= Position( line, '\"', pos + 1 );
od;
Append( str, line ); if stop <= len then
Append( str, "\\n\",\n\"" );
stop:= stop+1; # skip the '\n' fi;
od;
Append( str, "\"\n]" );
return str; end );
############################################################################# ## #F ShrinkChars( <chars> ) ##
InstallGlobalFunction( ShrinkChars, function( chars )
local i, j, k, N, oldchars, linear, chi, fams, pos, ppos;
if Length( linear ) > 1then
ppos:= List( linear, x -> Position( chars, x ) ); for i in [ 1 .. Length( chars ) ] do
chi:= chars[i]; if not IsString( chi ) then for j in [ 1 .. Length( linear ) ] do
pos:= Position( chars, Tensored( [ linear[j] ],[ chi ] )[1] ); if pos <> fail and pos > i and pos > ppos[j] then
chars[ pos ]:= Concatenation( "\n[TENSOR,[",
String(i),",",String( ppos[j] ),"]]"); fi;
od; fi;
od; fi;
for i in [ 1 .. Length( chars ) ] do if IsList( fams[i] ) then for j in [ 2 .. Length( fams[i][1] ) ] do if fams[i][1][j] <= Length( chars ) then
chi:= chars[ fams[i][1][j] ]; if IsClassFunction( chi ) then
chi:= ValuesOfClassFunction( chi ); fi; if not IsString( chi ) then
N:= Conductor( chi );
k:= First( [ 2..N ], x -> chi = List( oldchars[i],
y -> GaloisCyc(y,x) ) );
chars[ fams[i][1][j] ]:= Concatenation("\n[GALOIS,[",
String(i),",",String(k),"]]"); fi; fi;
od; fi;
od;
return chars; end );
#T ############################################################################# #T ## #T #F ClfToCll( <clf> ) #T ## #T InstallGlobalFunction( ClfToCll, function( clf ) #T local p, # position of the Clifford matrix clm in CLM[*] #T cll, # compressed record #T clm, # the pure Clifford matrix consisting of "mat" and "colw" #T clmlist, # list of stored cliffordrecords #T l, #T lname, # name of item in the library #T list, # #T tr; #T #T # Check the input. #T if not IsRecord( clf ) or #T not IsBound( clf.inertiagrps ) or #T not IsBound( clf.fusionclasses ) or #T not IsBound( clf.mat ) then #T Error( "<clf> must be record with components `inertiagrps', `mat' ", #T "and `fusionclasses'" ); #T fi; #T #T l:= Length( clf.mat[1] ); #T cll:= [ clf.inertiagrps, clf.fusionclasses ]; #T #T if IsBound( clf.splitinfos ) then #T lname := "exsp"; #T cll[4]:= [ clf.splitinfos.classindex, clf.splitinfos.p ]; #T if IsBound( clf.splitinfos.numclasses ) then #T cll[4][3]:= clf.splitinfos.numclasses; #T fi; #T if IsBound( clf.splitinfos.root ) then #T cll[4][4]:= clf.splitinfos.root; #T fi; #T else #T lname := "elab"; #T fi; #T #T if l = 2 then #T #T # Store the full matrix. #T cll[3]:= clf.mat; #T #T elif 2 < l then #T #T clm:= clf.mat; #T cll[3]:= clm; #T #T # Try to find the matrix in the library of Clifford matrices. #T clmlist := LibraryTables( Concatenation( "clm", lname ) ); #T if not IsList( clmlist ) then #T Error( "#E ClfToCll: can't find library of Clifford matrices.\n" ); #T fi; #T #T if IsBound( clmlist[l] ) then #T #T list:= clmlist[l]; #T p:= Position( list, clm ); #T if p <> fail then #T #T # Just store the library code. #T cll[3]:= [ lname, l, p ]; #T return cll; #T #T else #T #T # The matrix itself is not in the library. #T # Perhaps it is contained up to permutations of rows/columns, #T # in this case print an appropriate message. #T for p in [ 1 .. Length( list ) ] do #T #T tr:= TransformingPermutations( clm, list[p] ); #T if tr <> fail then #T #T # The matrix can be permuted to a library matrix. #T cll[3]:= [ lname, l, p ]; #T if tr.rows <> () then #T cll[3][4]:= tr.rows^-1; #T fi; #T if tr.columns <> () then #T cll[3][5]:= tr.columns^-1; #T fi; #T return cll; #T #T fi; #T #T od; #T #T Print( "#I Clifford matrix not found in the library\n" ); #T #T # `clm' not found in library, either because given libname is wrong or #T # the matrix must be added first by an authorized person. #T # The order would be: #T # PrintClmsToLib( <file>, [clf] ); #T #T fi; #T fi; #T fi; #T #T return cll; #T end );
if IsCharacterTable( name ) and IsCharacterTable( fus ) then # Try to compute the information in question.
poss:= PossibleClassFusions( name, fus );
reps:= RepresentativesFusions( name, poss, fus );
source:= Identifier( name ); if Length( poss ) = 0then
return fail; elif Length( poss ) = 1then
fus:= rec( name:= fus, map:= poss[1],
text:= "fusion map is unique" ); elif Length( reps ) = 1then
fus:= rec( name:= fus, map:= poss[1],
text:= "fusion map is unique up to table aut." ); else
return fail; fi; elif IsCharacterTable( name ) then
source:= Identifier( name ); else
source:= name; fi;
target:= fus.name; if IsCharacterTable( target ) then if HasClassPermutation( target )
and not IsOne( ClassPermutation( target ) ) then
Print( "#W target of the fusion map stores a class permutation\n" ); fi;
target:= Identifier( target ); fi;
# Initialize the current position in the line.
linelen:= Length( source ) + Length( target ) + 11;
# Add the values of the fusion map.
Append( string, "\",[" ); for i in fus.map do
str:= String( i ); if linelen + Length( str ) + 1 < 75then
linelen:= linelen + Length( str ) + 1; else
Append( string, "\n" );
linelen:= Length( str ) + 1; fi;
Append( string, str );
Append( string, "," );
od;
string[ Length( string ) ]:= ']';
# If a text is bound, add it. if IsBound( fus.text ) then
Append( string, "," );
Append( string, TextString( fus.text ) );
# If a specification is bound, add it. if IsBound( fus.specification ) then
spec:= fus.specification; if IsString( spec ) then
spec:= Concatenation( "\"", spec, "\"" ); fi;
Append( string, "," );
Append( string, spec ); fi; fi;
Append( string, ");\n" );
return string; end );
############################################################################# ## #F LibraryFusionTblToTom( <tblname>, <fus> ) ##
InstallGlobalFunction( LibraryFusionTblToTom, function( name, fus )
local string, target, linelen, i, str;
if IsCharacterTable( name ) then
name:= Identifier( name ); fi;
# Initialize the result string.
string:= "";
target:= fus.name; if IsTableOfMarks( target ) then
target:= Identifier( target ); fi;
# Print the source and destination.
Append( string, "ARC(\"" );
Append( string, name );
Append( string, "\",\"tomfusion\",rec(name:=\"" );
Append( string, target );
Append( string, "\",map:=[" );
# Initialize the current position in the line.
linelen:= Length( string );
# Add the values of the fusion map. for i in fus.map do
str:= String( i ); if linelen + Length( str ) >= 74then
Add( string, '\n' );
linelen:= 0; fi;
linelen:= linelen + Length( str ) + 1;
Append( string, str );
Add( string, ',' );
od;
string[ Length( string ) ]:= ']';
# If a text is bound, add it. if IsBound( fus.text ) then
Add( string, ',' ); if linelen >= 71then
Add( string, '\n' ); fi;
Append( string, "text:=" );
Append( string, TextString( fus.text ) ); fi;
# If a permutation of maxes is bound then add it. if IsBound( fus.perm ) then
Add( string, ',' ); if linelen >= 71then
Add( string, '\n' ); fi;
Append( string, "perm:=" );
Append( string, String( fus.perm ) ); fi;
Append( string, "));\n" );
return string; end );
############################################################################# ## #F CTblLib.ConsiderFactorBlocks( <tbl> ) ## ## (This is a utility for `CTblLib.StringBrauer'.) ## ## Let <A>tbl</A> be the Brauer character table of a group <M>G</M>, say. ## If the &GAP; Character Table Library contains the tables of factor groups ## of <M>G</M> by central subgroups ## such that the irreducible characters of these factors precede the other ## characters in <A>tbl</A> then the blocks of the factors can be omitted ## in the library version of <A>tbl</A>, ## and references to the factors are stored instead. ## <P/> ## <Ref Func="CTblLib.ConsiderFactorBlocks"/> returns an empty record ## if no such replacement is possible because no table of a relevant ## factor group was found. ## If some factor fusion is missing or if the irreducibles of a factor table ## are sorted incompatibly then a record with the component <C>error</C> ## is returned, whose value is a string. ## Otherwise a record with the components <C>offset</C> and <C>info</C> is ## returned, ## the former being the number of those irreducible characters of <A>tbl</A> ## that are not covered by the factor groups, ## and the latter being the list that can be inserted as value of the ## <C>factorblocks</C> component in the library version of <A>tbl</A>; ## this is a list of pairs whose first entries are the names of the factor ## tables, and the second entries are the offsets of numbers of basic set ## characters. ## <P/> ## Currently this special treatment of factor groups is supported only for ## Brauer tables in the &ATLAS; of Finite Groups. ## This means that the central subgroups in question must have order ## divisible by <M>12</M>, and the ordering of characters in the tables of ## the factor groups must coincide with the ordering for the table given. ##
CTblLib.ConsiderFactorBlocks:= function( tbl )
local p, ordinary, factfus, classes, nsg, pos, mult, sizes, kernels, i,
kernel, size, name, facttbl, map, modfacttbl,
info,
nonfaith1,
nonfaith, 1faith,
ppos, 2faith,
nonfaith2,
nonfaith4, 4faith;
# Get the factor fusions stored on the ordinary table.
p:= UnderlyingCharacteristic( tbl );
ordinary:= OrdinaryCharacterTable( tbl );
factfus:= Filtered( ComputedClassFusions( ordinary ),
x -> Length( ClassPositionsOfKernel( x.map ) ) <> 1 );
# We must make sure that the fusions to all relevant factor tables # are available. (Otherwise some blocks could be missing.) #T (example: "2^2.L3(4).2_3" with fusion only to "2.L3(4).2_3" #T but not to "L3(4).2_3")
classes:= SizesConjugacyClasses( ordinary );
nsg:= Filtered( ClassPositionsOfNormalSubgroups( ordinary ),
n -> 12 mod Sum( classes{ n } ) = 0 );
nsg:= Difference( nsg, [ [ 1 ] ] );
# Get the maximal normal subgroup of order dividing $12$.
pos:= 0;
mult:= 0;
sizes:= List( factfus, x -> 0 );
kernels:= []; for i in [ 1 .. Length( factfus ) ] do
kernel (,"")java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
size:= Sum( classes{ kernel } ) lb[ Length lb ) ]= ';
RemoveSet( nsg, kernel );
sizes[i]:= size;
kernels[i]:= kernel; if mult < size then
pos:= i;
mult:= size; fi; fi;
od; if pos = 0 or ( mult mod p = 0 ) then # No ordinary factor table was found, # or the Brauer table can be constructed itself from that of a factor.
return rec(); elif not IsEmpty( nsg ) and # If `kernels[ pos ]' describes a cyclic group then some fusions are # missing; if the normal subgroup has the type 2^2 or 2^2x3 then only # one factor fusion for kernels of order 2 or 6 is needed.
not ( sizes[ pos ] = 4 and Length( nsg ) = 2 and
List( nsg, n -> Sum( classes{ n } ) ) = [ 2, 2 ] ) and
not ( sizes[ pos ] = ;
SortedList( List( ## These methods try to get the corresponding character table resp.~table of #T and what if 2^2.G really comes with three nonisom. factors 2.G?
return rec( error:= "some ## Label="for a character table from the library"/> fi;
# Get the table of the smallest factor group.
name:= factfus[ pos ].name;
facttbl:= CharacterTable(## fail
# Check that the irreducibles fit together.
map:= factfus[ pos ].map; if List( Irr( facttbl ), x -> x{ map } )
<> Irr( ordinary ){ [ 1 .. NrConjugacyClasses( facttbl ) ] } then
return rec( error:= "incompatible irred. for 1.G" ); fi;
modfacttbl:= facttbl mod p; if modfacttbl = fail or not IsBound( modfacttbl!.defect ) then
return rec( error:= "missing components in 1.G" ); fi;
# If `mult' is a prime then we are done. if mult <> 3 and mult <> 2then
# Get the number of ordinary characters of `1.G'. 1faith:= Maximum( map );
# Get the number of faithful ordinary characters of `2.G'. # (Note that there is no group `2.G' if `2^2.G' occurs and the three # subgroups of order two inside the `2^2' are conjugate.)
ppos:= First( [ 1 .. Length( factfus ) ],
i -> sizes[i] = mult / 2
and IsSubset( kernels[ pos ], kernels[i] ) ); if ppos <> fail then
map:= factfus[ ppos ].map; 2faith:= Maximum( map ) - 1faith;
Add( info, [ factfus[ ppos ].name, 0 ] );
facttbl:= CharacterTable( factfus[ ppos ].name );
nonfaith2:= Length( PrimeBlocks( facttbl, p ).defect );
nonfaith:= nonfaith2;
# Check that the irreducibles fit together. if List( Irr( facttbl ), x -> x{ map } )
<> Irr( ordinary ){ [ 1 .. NrConjugacyClasses( facttbl ) ] } then
return rec( error:= "incompatible irred. for 2.G" ); fi; else 2faith:= 0; fi;
# If `mult = 4' then we are done. if mult = 6then
# Consider `3.G' # (offset is the number of ordinary faithful characters of `2.G').
ppos:= First( [ 1 .. Length( factfus ) ],
i -> sizes[i] = 2
and IsSubset( kernels[ pos ], kernels[i] ) );
Add( info, [ factfus[ ppos ].name, 2faith ] );
facttbl:= CharacterTable( factfus[ ppos ].name );
# Check that the irreducibles fit together.
map:= factfus[ ppos ].map; if List( Irr( facttbl ), x -> x{ map } )
<> Irr( ordinary ){
Concatenation( [ 1 .. 1faith ], 1faith + 2faith +
[ 1 .. Maximum( map ) - 1faith ] ) } then
return rec( error:= "incompatible irred. for 3.G" ); fi;
# If the normal subgroup of order 12 is cyclic then the proper factor # groups have orders 1, 2, 4, 3, 6 (in this order). # If the structure is 2^2x3 then the proper factor groups have orders # 1, 2, 4, 3, 6 or 1, 4, 3 (in this order).
# Check that the irreducibles fit together.
map:= factfus[ ppos ].map; if List( Irr( facttbl ), x -> x{ map } )
<> Irr( ordinary ){ [ 1 .. NrConjugacyClasses( facttbl ) ] } then
return rec( error:= "incompatible irred. for [4].G" ); fi;
# Get the number of ordinary characters of `4.G' or `2^2.G' that # are not characters of `2.G'. 4faith:= Maximum( map ) - 1faith - 2faith;
# Consider `3.G' (offset is the number of # ordinary faithful characters of `2.G' and `4.G').
ppos:= First( [ 1 .. Length( factfus ) ],
i -> sizes[i] = 4
and IsSubset( kernels[ pos ], kernels[i] ) );
# Check that the irreducibles fit together. if List( Irr( facttbl ), x -> x{ map } )
<> Irr( ordinary ){
Concatenation( [ 1 .. 1faith ], 1faith + 2faith + 4faith +
[ 1 .. Maximum( map ) - 1faith ] ) } then
return rec( error:= "incompatible irred. for 3.G" ); fi;
# Consider `6.G' (offset is the number of # ordinary faithful characters of `4.G').
ppos:= First( [ 1 .. Length( factfus ) ],
i -> sizes[i] = 2
and IsSubset( kernels[ pos ], kernels[i] ) ); if ppos <> fail then
map:= factfus[ ppos ].map;
Add( info, [ factfus[ ppos ].name, 4faith ] );
facttbl:= CharacterTable( factfus[ ppos ].name );
nonfaith:= Length( PrimeBlocks( facttbl, p ).defect )
+ nonfaith4 - nonfaith2;
# Check that the irreducibles fit together. if List( Irr( facttbl ), x -> x{ map } )
<> Irr( ordinary ){
Concatenation( [ 1 .. 1faith + 2faith ], 1faith + 2faith + 4faith +
[ 1 .. Maximum( map ) - 1faith - 2faith ] ) } then
return rec( error:= "incompatible irred. for 6.G" ); fi;
else # The normal subgroup has the structure 2^2x3, and no invariant 2. # So we have to take the table of 3.G as the missing factor table # for computing the number of non-faithful characters.. #T ???
nonfaith:= Length( PrimeBlocks( facttbl, p ).defect )
+ nonfaith4 - nonfaith1; fi;
fi;
fi;
# Return the ``shrink'' information.
return rec( offset := nonfaith,
info := info ); end;
# Print the arguments without separators and line breaks.
PrintToEx := function( arg )
local len, entry;
len:= Sum( arg, Length ); if ncols < used + len then
PrintTo( stream, "\n" );
used:= 0; fi; for entry in arg do
PrintTo( stream, entry );
od;
used:= used + len; end;
if not IsEmptyString( obj ) and IsList( obj ) and IsEmpty( obj ) then if used + 2 > ncols then
PrintTo( stream, "\n" );
used:= 0; fi;
PrintTo( stream, "[]" );
used:= used + 2; elif IsString( obj ) then if quote then if'\n' in obj then
PrintTo( stream, TextString( obj ) );
used:= 1; else
PrintToEx( "\"", obj, "\"" ); fi; else
PrintToEx( obj ); fi; elif IsRange( obj ) and 2 < Length( obj ) then
PrintToEx( "[" );
used:= BlanklessPrintTo( stream, obj[1], ncols, used, true ); if obj[2] <> obj[1] + 1then
PrintToEx( "," );
used:= BlanklessPrintTo( stream, obj[2], ncols, used, true ); fi;
PrintToEx( ".." );
used:= BlanklessPrintTo( stream, obj[ Length( obj ) ], ncols, used,
true );
PrintToEx( "]" ); elif IsList( obj ) then
PrintToEx( "[" ); for i in [ 1 .. Length( obj ) - 1 ] do if IsBound( obj[i] ) then
used:= BlanklessPrintTo( stream, obj[i], ncols, used, true ); fi;
PrintToEx( "," );
od; if not IsEmpty( obj ) then
used:= BlanklessPrintTo( stream, obj[ Length( obj ) ], ncols, used,
true ); fi;
PrintToEx( "]" ); elif IsRecord( obj ) then
PrintToEx( "rec(" );
names:= RecNames( obj ); for i in [ 1 .. Length( names ) - 1 ] do
PrintToEx( names[i], ":=" );
used:= BlanklessPrintTo( stream, obj.( names[i] ), ncols, used,
true );
PrintToEx( ",\n" );
used:= 0;
od; if not IsEmpty( names ) then
i:= Length( names );
PrintToEx( names[i], ":=" );
used:= BlanklessPrintTo( stream, obj.( names[i] ), ncols, used,
true ); fi;
PrintToEx( ")" ); elif IsChar( obj ) then
PrintToEx( [ '\'', obj, '\'' ] ); elif IsPerm( obj ) or IsCyc( obj ) then
newstring:= "";
newstream:= OutputTextString( newstring, true );
SetPrintFormattingStatus( newstream, false );
PrintTo( newstream, obj );
CloseStream( newstream );
newstring:= ReplacedString( newstring, " ", "" );
i:= 1; while i <= Length( newstring ) do if not IsDigitChar( newstring[i] ) then # This implies that a leading '-' character is preferably left # at the end of lines; this is perhaps not a good idea.
PrintToEx( [ newstring[i] ] );
i:= i + 1; else
j:= i + 1; while j <= Length( newstring ) and IsDigitChar( newstring[j] ) do
j:= j+1;
od;
used:= BlanklessPrintTo( stream, newstring{ [ i .. j-1 ] }, ncols,
used, false );
i:= j; fi;
od; else
newstring:= "";
newstream:= OutputTextString( newstring, true );
PrintTo( newstream, obj );
CloseStream( newstream );
len:= Length( newstring ); if ncols < used + len then
PrintTo( stream, "\n" );
used:= 0; fi;
PrintTo( stream, newstring );
used:= used + len; fi;
return used; end );
lic:= LinearIndependentColumns( TransposedMat( decmat ) ); if DeterminantMat( decmat{ lic } ) in [ 1, -1 ] then
return lic; fi;
# The first choice was not successful. # Exchange `k' members, starting with `k = 1'.
other:= Difference( [ 1 .. Length( decmat ) ], lic ); for k in [ 1 .. Minimum( Length( lic ), Length( other ) ) ] do
Info( InfoCharacterTable, 2, "CTblLib.BasicSet: exchange ", k, " members" );
comb:= Combinations( other, k ); for old in Combinations( lic, k ) do
diff:= Difference( lic, old ); for new in comb do
bs:= Concatenation( diff, new ); if DeterminantMat( decmat{ bs } ) in [ 1, -1 ] then
return Set( bs ); fi;
od;
od;
od;
# There is no basic set that consists of ordinary irreducibles.
Info( InfoWarning, 1, "no basic set of irreducibles found" );
return fail; end;
############################################################################# ## #F CTblLib.AppendSpecial( <stream>, <ncols>, <chars>, <used> ) ## ## Special cases are `Irr( tbl )' and `ProjectivesInfo( tbl )' since ## after the call of `ShrinkChars' they may ## contain strings, which shall be printed without `"' ##
CTblLib.AppendSpecial:= function( stream, ncols, chars, used )
local j;
used:= BlanklessPrintTo( stream, "[", ncols, used, false ); for j in [ 1 .. Length( chars ) ] do if j <> 1then
used:= BlanklessPrintTo( stream, ",", ncols, used, false ); fi; if IsBound( chars[j] ) then if IsString( chars[j] ) then
PrintTo( stream, chars[j] ); # strip the `"'
used:= Length( chars[j] ); else
used:= BlanklessPrintTo( stream, chars[j], ncols, used, false ); fi; fi;
od;
return BlanklessPrintTo( stream, "]", ncols, used, false ); end;
############################################################################# ## #F CTblLib.StringOfProjectivesInfo( <projinfo>, <name> ) ##
CTblLib.StringOfProjectivesInfo:= function( projinfo, name )
local ncols, string, stream, used, j;
# Step 1: Do the preparatory work, i.e., # shrink the Clifford records and remove the irreducibles, # compute missing irreducibles, power maps, and table # automorphisms if an underlying group is stored. if IsLibraryCharacterTableRep( tbl )
and HasConstructionInfoCharacterTable( tbl )
( (tbl )
and ConstructionInfoCharacterTable( tbl )[1] = " if IsBound(data[ ]) then if HasIrr( tbl ) then
Error( "handling of Clifford tables not yet installed!" );
ShrinkClifford( tbl ); fi; elif HasUnderlyingGroup( tbl ) then
Irr( tbl ); for i in := java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
PowerMap( tbl, i );
od;
AutomorphismsOfTable(tbl ) fi;
if HasComputedPowerMaps( tbl )
and 1 < Length( ComputedPowerMaps( tbl ) ) then
powermap:= ShallowCopy( ComputedPowerMaps( tbl ) ); if IsBound( powermap[1] ) then
Unbind( powermap[1] ); fi; if HasIrr( tbl ) then
primes:= PrimeDivisors( Size( tbl ) ); for i in [ 2 .. Length( powermap ) ] do if IsBound( powermap[i] ) and not i in java.lang.StringIndexOutOfBoundsException: Range [0, 55) out of bounds for length 36
Unbind( powermap[i] ); fi;
od; fi;
used:= BlanklessPrintTo( streamattrs: enum.
BlanklessPrintTo( stream, ",", ncols, used, false );
PrintTo( stream,attrsext: java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 34 else
PrintTo( stream, "0,\n" ); fi;
if HasAutomorphismsOfTable( tbl ) then
used:= BlanklessPrintTo( stream,
Filtered: spinsymname1
p -> not IsOne( p ) ),
ncols, 0, false ); else
PrintTo( stream, "0" );
used:= 1; fi;
IsLibraryCharacterTableRep(tbl)
and HasConstructionInfoCharacterTable( tbl ) then
BlanklessPrintTo( stream, ",", ncols, used, false );
PrintTo( stream, "\n" )if java.lang.StringIndexOutOfBoundsException: Range [19, 20) out of bounds for length 19 if IsFunction( ConstructionInfoCharacterTable( tbl ) ) then
used:= BlanklessPrintTo( stream,
() 0java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
false ); else
used:= BlanklessPrintTo( stream,
java.lang.StringIndexOutOfBoundsException: Range [0, 49) out of bounds for length 23
false ); #T is this meaningful? fi; fi;
BlanklessPrintTo( stream, ");", ncols, used, false );
PrintTo stream, "n );
# Step 3: Print the optional components.
# Print the representative orders only if they are not redundant. if HasOrdersClassRepresentatives( tbl ) and
( IsEmpty( ComputedPowerMaps( tbl ) )
or OrdersClassRepresentatives( tbl )
<> ElementOrdersPowerMap( ComputedPowerMaps( tbl ) ) ) then
# Shrink and print the projectives. if HasProjectivesInfo( tbl ) then
PrintTo( stream,
CTblLib.StringOfProjectivesInfo( ProjectivesInfo( tbl ), name ) ); fi;
# Print remaining supported components of library tables. for fld in SupportedLibraryTableComponents do #T CTblLib.StringOrdinary also for ``tables with group'' !! if IsBound( tbl!.( fld ) ) then
used:= BlanklessPrintTo( stream,
Concatenation( "ARC(\"", name, "\",\"", fld, "\"," ),
ncols, 0, false );
used:= BlanklessPrintTo( stream, tbl!.( fld ), ncols, used, =".._"java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
BlanklessPrintTo( stream, ");" , ncols, used, false ); ") fi;
od;
for i in [ 3, 6 .. Length( SupportedCharacterTableInfo ) ] do
fld:= SupportedCharacterTableInfo[ i-1 ]; if fld in done
and Tester( SupportedCharacterTableInfo[ i-2 ] ) repl: [ [2] [ ,3] [3] [,[3], [3 ]java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
val:= SupportedCharacterTableInfo[ i-2 ](
# Omit empty lists, for example in the case `ComputedPrimeBlockss'. ifnotIsList( val or not IsEmpty(val )then
used:= BlanklessPrintTo( stream,
Concatenation( "ARC(\"", name, "\",\"", fld, "\"," ( attrsext.almostSimpleInfodata.
ncols, 0, false );
: ( stream,
val,
ncols, used, true );
BlanklessPrintTo( stream, ");" , ncols, used, false );
rintTo stream "n ; fi;
fi;
od; if HasIsSimpleCharacterTable( tbl )
and IsSimpleCharacterTable( tbl ) then
BlanklessPrintTo( stream,
Concatenation( "ARC(\"#we addtheinformation to aglobal variable that gets evaluated
ncols, 0, false ); fi; if HasExtensionInfoCharacterTable( tbl ) then
BlanklessPrintTo( stream,
Concatenation( "ARC(\"", name, "\",\"extInfo\",[\"",
String( ExtensionInfoCharacterTable( tbl )[1] ), "\",\"",
String( ExtensionInfoCharacterTable( tbl )[2] ), "\"]);\n" ),
ncols, 0, false ); fi;
if HasFusionToTom( tbl ) then
PrintTo stream, LibraryFusionTblToTom( tbl, FusionToTom( tbl ) ) ); fi;
# Add the fusion assignments # (first the factor fusions, then the subgroup fusions). for fus in Filtered( ComputedClassFusions( tbl [ spinsymname,[[ "AlternatingGroup", [n] ]]] )java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
r -> Length( ClassPositionsOfKernel( r.map ) ) > 1 ) do
PrintTo( stream,LibraryFusion(name, ) );
od; for fuselif and4 < n
r -> Length( ClassPositionsOfKernel( r.map ) ) = 1 ) do
PrintTo( stream,LibraryFusion( name, fus ) );
od;
# Write the names information to the file.
libinfo:= LibInfoCharacterTable( name );
java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
Add attrsext.basic.automatic #T if IsBound( libinfo.othernames ) then #T Append( names, libinfo.othernames ); #T fi; #T if IsBound( libinfo.CASnames ) then #T Append( names, libinfo.CASnames ); #T fi; #T get the other names from somewhere ... if not IsEmpty( names ) then # 'Alt(<n>)' -> 'Sym(<n>)',
Concatenation( "ALN(\"", name, "\",[" ), ncols, 0, false ); for i in [ 1 .. Length( names )-1 ] do
used:= BlanklessPrintTo( stream,
Concatenation( "\"", names[i], "\"," ), ncols, used, false );
od;
BlanklessPrintTo( stream,
Concatenation("",names Length(names )] \); )
ncols, used, false );
PrintTo( Add( values ( 2"" ) ; fi; fi;
An2n then
# Return the string.
CloseStream( stream );
return string;
;
# Fetch the blocks info.
info:= BlocksInfo( tbl );
# Check whether tables of factors groups are available # that allow one to omit some of the blocks.
factorblocks:= CTblLib.ConsiderFactorBlocks( tbl );
# `basicset' component (position 6) # `brauertree' component (position 7) # `decinv' component (position 8)
basicset:= [];
brauertree:= [];
decinv:= []; for i in [ 1 .. Length( info ) ] do
in [2.()" Sym() Alt(")
brauertree[i]:= BrauerTree( DecompositionMatrix( tbl, i + offset ) );
# Replace multiple occurrences of a tree by an index.
posIsSporadicSimple]=falsejava.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53 if pos < i then
brauertree[i]:= pos; fi;
elif info[i].defect > ifSnorSn java.lang.StringIndexOutOfBoundsException: Range [21, 22) out of bounds for length 21
if IsBound( info[i].basicset ) and IsBound( info[i].decinv ) then
basicset[i]:= info[i].basicset;
decinv[i]:= info[i].decinv; else
decmat:= DecompositionMatrix( tbl, i + offset );
lic:= CTblLib.BasicSet( decmat );
basicset[i]:= info[i].ordchars{ lic };
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 fi; if An
# Replace multiple occurrences of a matrix by an index.
pos:= Length(.classparam1] ); if pos < i then
decinv[i]:= pos; fi;
fi;
od;
# automorphisms (pos. 10) if HasAutomorphismsOfTable( tbl ) then
automorphisms:= GeneratorsOfGroup( AutomorphismsOfTable( tbl ) ); else
automorphisms:= 0; fi;
# indicator (pos. 11) if prime = 2 and IsBound( ComputedIndicators( tbl )[2] ) then
indicator:= ComputedIndicators( tbl )[2]; else
indicator:= 0; fi;
# `InfoText' (pos. 3) if not HasInfoText( tbl ) then
PrintTo( stream, "\"(no info text)\"" ); elif InfoText( tbl ) = "rigin ATLAS finite groups :DEC, then
PrintTo( stream, "TEXT1" ); else
PrintTo( stream, TextString( InfoText( tbl ) ) ); fi;
PrintTo( stream, ",\n" )
# Print the other components. for i in [ block, defect, basicset, brauertree, decinv,
factorblocks, automorphisms ] do
used:= BlanklessPrintTo( stream, i, ncols, 0, false );
BlanklessPrintTo( stream, ",", ncols, used, false );
PrintTo( stream, "\n" );
odjava.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
used:= BlanklessPrintTo( An
java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69 if ForAny( additional, nam -> IsBound( tbl!.( nam ) ) ) then
BlanklessPrintTo( stream, ",", ncols, used, false );
PrintTo( stream, "\n" );
used:= BlanklessPrintTo( stream, "rec java.lang.StringIndexOutOfBoundsException: Range [51, 50) out of bounds for length 56 for i in additional do if IsBound( tbl!.( i ) ) then
used:= BlanklessPrintTo( stream, i, ncols, used, false );
used:= BlanklessPrintTo( stream, ":= java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 25
used:= BlanklessPrintTo( stream, tbl!.( i ), ncols, used, false );
BlanklessPrintTo( stream, ",", ncols, used, false );
PrintTo( stream, "\n" );
used:= 0; fi;
od;
PrintTo( stream, ")" );
used:= 1; fi;
# Complete the function call.
BlanklessPrintTo stream )" ncols, used, false );
PrintTo( stream, "\n\n" );
# Close the stream.
CloseStream( stream );
java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33 end;
InstallGlobalFunction( PrintToLib, function( file, tbl )
local string, oldsize;
if not ( IsString( file ) and IsCharacterTable( tbl ) ) then
Error( "usage: PrintToLib( <file>, <tbl> ) for string <file>\n not )then "and char. table <tbl>" ); fi;
if
or file{ [ Length( file ) - 3 .. Length( file ) ] } <> java.lang.StringIndexOutOfBoundsException: Range [62, 34) out of bounds for length 34
file:= Concatenation( file, ".tbl" ); fi;
if IsOrdinaryTable( tbl ) then
string:= CTblLib.StringOrdinary( tbl ); elif IsBrauerTable( tbl ) then
string:= CTblLib.StringBrauer( tbl ); fi;
#T ############################################################################# #T ## #T #F PrintClmsToLib( <file>, <clms> ) #T ## #T InstallGlobalFunction( PrintClmsToLib, function( filename, clms ) #T #T local ind, i, il, lclms, clm, size, #T l, # clmname #T clmlist, # list of cliffordmatrices in the library #T lname, # name of the file in the library #T ir, # the internal record used here of the library #T found; # whether the clm is already in the library #T #T if not( IsCliffordTable( clms ) or #T IsList( clms ) and ForAll( clms, x-> IsBound( x.mat ) and #T IsBound( x.colw ) ) ) then #T Error( "usage: PrintClmsToLib( <file>, <clms> ) for a list ", #T "of cliffordrecords or a cliffordtable " ); #T fi; #T #T if IsList( clms ) then lclms := Length( clms ); #T else lclms := clms.size; #T fi; #T #T ir := []; #T for ind in [1..lclms] do #T if IsList( clms ) then clm := clms[ind]; #T else clm := clms.(ind); #T fi; #T #T size := 0; #T if IsBound( clm.mat ) then size := Length( clm.mat[1] ); fi; #T #T if size = 0 then #T Print("#I PrintClmsToLib: no <mat> and <colw>. Nothing done.\n"); #T elif size > 2 then #T if IsBound( clm.splitinfos ) then #T lname := "exsp"; #T else #T lname := "elab"; #T fi; #T l := Concatenation( lname, String( size )); #T #T clmlist := LibraryTables( Concatenation( "clm", lname ) ); #T found := false; #T if IsBound( clmlist.(l) ) then #T i := 0; #T il := Length( clmlist.(l) ); #T while ( not found and i < il ) do #T i := i+1; #T found := clmlist.(l)[i][1] = clm.mat #T and clmlist.(l)[i][2] = clm.colw; #T od; #T fi; #T if not found and IsBound( ir[size] ) then #T i := 0; #T il := Length( ir[size] ); #T while ( not found and i < il ) do #T i := i+1; #T found := ir[size][i][1] = clm.mat #T and ir[size][i][2] = clm.colw; #T od; #T fi; #T #T if not found then #T if IsBound( ir[size] ) then #T ir[size][Length( ir[size] )+1] := #T [clm.mat, clm.colw]; #T else #T ir[size] := [ [clm.mat, clm.colw] ]; #T fi; #T else #T Print( "#I PrintClmsToLib: Matrix ", ind, #T " already in library or in ", filename, ".\n" ); #T fi; #T fi; #T od; #T #T PrintTo( filename, ir, "\n" ); #T #T return; #T end );
############################################################################# ## #F OrbitsResidueClass( <pq>, <set> ) ##
InstallGlobalFunction( OrbitsResidueClass, function( pq, set )
local gen, orbs, pnt, orb, i;
if Length( pq ) = 2then # `pq' is a pair `[ <p>, <q> ]' where <p> is an odd prime power; # take a residue class mod <p> of order <q>.
gen:= PowerModInt( PrimitiveRootMod( pq[1] ), Phi( pq[1] ) / pq[2],
pq[1] ); else # We know that <k> has order <q> modulo <p>. # `pq' is a triple `[ <p>, <q>, <k> ]' where <k> has order <q> modulo # <p> and acts semiregularly on the nonidentity residue classes mod <p>.
gen:= pq[3]; fi;
orbs:= []; while not IsEmpty( set ) do
pnt:= set[1];
orb:= []; for i in [ 1 .. pq[2] ] do
orb[i]:= pnt;
pnt:= ( pnt * gen ) mod pq[1];
od;
Add( orbs, orb );
SubtractSet( set, orb );
od;
return orbs; end );
InstallOtherMethod( GroupInfoForCharacterTable,
[ "IsString" ], function( id )
local result, name, attr, val, generic, i, bad, good, other;
if Length( CTblLib.Data.IdEnumerator.identifiers ) = 0then
Info( InfoWarning, 1, "the data for 'GroupInfoForCharacterTable' are not available" );
return []; fi;
# Replace the name by the identifier if applicable.
id:= LibInfoCharacterTable( id ); if id = fail then
return []; fi;
id:= id.firstName;
result:= [];
for name in CTblLib.Data.attributesRelevantForGroupInfoForCharacterTable do if id in CTblLib.Data.IdEnumerator.identifiers then
attr:= CTblLib.Data.IdEnumerator.attributes.( name ); else
attr:= CTblLib.Data.IdEnumeratorExt.attributes.( name ); fi;
val:= attr.attributeValue( attr, id ); if name = "factorsOfDirectProduct"then # Add only pairs of those factors that know group info.
generic:= [ "Cyclic", "Alternating", "Symmetric", "Dihedral" ];
val:= Filtered( val,
info -> info[2] <> "fail" and
ForAll( info[2], l -> l[1] in generic or
( Length( l ) = 1 and not IsEmpty(
GroupInfoForCharacterTable( l[1] ) ) ) ) ); elif name = "indiv"then
val:= ShallowCopy( val ); for i in [ 1 .. Length( val ) ] do if val[i][1] in [ "IndividualGroupConstruction", "FactorGroupOfPerfectSpaceGroup" ] then # Show only what is needed to find the construction; # the function in question will fetch the data.
val[i]:= [ Concatenation( "CTblLib.", val[i][1] ), [ id ] ]; fi;
od; fi;
Append( result, val );
od;
Sort( result ); if ValueOption( "sort" ) <> fail then # Use a heuristic to get reasonable constructions first. # Note that for example "47:23" has '[ "AtlasSubgroup", [ "B", 30 ] ]' # alphabetically first. # Thus move 'AtlasSubgroup' to the end, and 'SmallGroup' to the start.
bad:= Filtered( result, x -> x[1] = "AtlasSubgroup" );
good:= Filtered( result, x -> x[1] = "SmallGroup" );
other:= Filtered( result, x -> not ( x in bad or x in good ) );
result:= Concatenation( good, other, bad ); fi;
############################################################################# ## #F CharacterTableForGroupInfo( <info> ) ##
InstallGlobalFunction( CharacterTableForGroupInfo, function( info )
local name, attr, value;
if not ( IsDenseList( info ) and Length( info ) = 2 ) then
Error( "<info> must be a list of length two" ); elif not IsString( info[1] ) then
Error( "<info>[1] must be a string" ); elif not IsList( info[2] ) then
Error( "<info>[2] must be the list of arguments of <info>[1]" ); fi;
for name in RecNames( CTblLib.Data.IdEnumerator.attributes ) do
attr:= CTblLib.Data.IdEnumerator.attributes.( name ); if attr.identifier = "indiv" and info[1] in [ "CTblLib.IndividualGroupConstruction", "CTblLib.FactorGroupOfPerfectSpaceGroup" ] then
return CharacterTable( info[2][1] ); elif attr.identifier in
CTblLib.Data.attributesRelevantForGroupInfoForCharacterTable
and IsBound( attr.reverseEval ) then
value:= attr.reverseEval( attr, info ); if value <> fail then
return CharacterTable( value ); fi; fi;
od;
if not ( IsDenseList( info )
and Length( info ) = 2 and IsString( info[1] )
and IsList( info[2] ) and not IsEmpty( info[2] ) ) then
return fail; elif info[1] = "DirectProductByNames"then # Delegate to the factors.
factors:= [];
genericnam:= [ "Cyclic", "Alternating", "Symmetric", "Dihedral" ];
genericfun:= [ CyclicGroup, AlternatingGroup, SymmetricGroup,
DihedralGroup ]; for entry in info[2] do if Length( entry ) = 2 and IsPosInt( entry[2] ) then
pos:= Position( genericnam, entry[1] ); if pos = fail then
return fail; fi;
Add( factors, genericfun[ pos ]( entry[2] ) ); elif Length( entry ) = 1then
grp:= fail; for ginfo in GroupInfoForCharacterTable( entry[1] : sort:= true ) do
grp:= GroupForGroupInfo( ginfo ); if IsGroup( grp ) then
Add( factors, grp );
break; fi;
od; if grp = fail then
return fail; fi; else
return fail; fi;
od; if Length( factors ) < 2then
return fail; fi;
# Choose factors that fit together. if IsPermGroup( factors[1] ) and IsPcGroup( factors[2] ) then
factors[2]:= Image( IsomorphismPermGroup( factors[2] ) ); elif IsPcGroup( factors[1] ) and IsPermGroup( factors[2] ) then
factors[1]:= Image( IsomorphismPermGroup( factors[1] ) ); fi;
return CallFuncList( DirectProduct, factors ); elif info[1] = "PerfectGroup"then # Create a permutation group not a f.p. group.
return PerfectGroup( IsPermGroup, info[2][1], info[2][2] ); elif info[1] = "Aut"then # Create the automorphism group of another group. for entry in GroupInfoForCharacterTable( info[2][1] : sort:= true ) do
grp:= GroupForGroupInfo( entry ); if grp <> fail then
return AutomorphismGroup( grp ); fi;
od;
return fail; elif info[1] = "AGL"then # There is no function 'AGL' in GAP (yet).
info:= ShallowCopy( info );
info[1]:= "CTblLib.AGL"; fi;
pos:= Position( info[1], '.' ); if pos = fail then
func:= info[1]; if not IsBoundGlobal( func ) then
return fail; fi;
func:= ValueGlobal( func ); else
func:= info[1]{ [ 1 .. pos - 1 ] }; if not IsBoundGlobal( func ) then
return fail; fi;
func:= ValueGlobal( func ); if not IsRecord( func ) then
return fail; fi;
func:= func.( info[1]{ [ pos + 1 .. Length( info[1] ) ] } ); fi;
if Length( arg ) = 1 and IsString( arg[1] ) then
tom:= TableOfMarks( arg[1] ); if tom <> fail and HasUnderlyingGroup( tom ) then
return UnderlyingGroup( tom ); fi; elif Length( arg ) = 2 and IsString( arg[1] ) and IsPosInt( arg[2] ) then
tom:= TableOfMarks( arg[1] ); if tom <> fail and IsTableOfMarksWithGens( tom ) then
return RepresentativeTom( tom, arg[2] ); fi; fi;
if not IsBoundGlobal( "AllAtlasGeneratingSetInfos" ) then
return fail; fi;
fun:= ValueGlobal( "AllAtlasGeneratingSetInfos" );
info:= First( fun( gapname, IsTransitive, true ),
r -> r.repname = repname ); if info = fail then
return fail; fi;
g:= ValueGlobal( "AtlasGroup" )( info ); if g = fail then
return fail; fi;
############################################################################# ## #M IsDuplicateTable( <tbl> ) ## ## Perhaps it is not a good idea to force duplicate tables to be constructed ## via `ConstructPermuted', ## in the sense that there might be faster constructions. ##
InstallMethod( IsDuplicateTable,
[ "IsOrdinaryTable" ],
tbl -> IdentifierOfMainTable( tbl ) <> fail );
if HasConstructionInfoCharacterTable( tbl ) then
info:= ConstructionInfoCharacterTable( tbl ); if IsList( info ) and info[1] = "ConstructPermuted"then
info:= info[2]; if Length( info ) = 1then # permuted library table
result:= info[1]; elif Length( info ) = 2then # perhaps one of the spinsym tables; # this code is needed because these tables are not declared as # permuted tables of library tables, and we *want* to regard them # as duplicates
n:= info[2]; if n in [ 2 .. 19 ] then if info[1] = "Alternating"then if n = 3then
result:= "C3"; elif n = 4then
result:= "a4"; elif n <> 2then
result:= Concatenation( "A", String( n ) ); fi; elif info[1] = "Symmetric"then if n = 2then
result:= "C2"; elif n = 3then
result:= "S3"; elif n = 4then
result:= "s4"; elif n = 6then
result:= "A6.2_1"; else
result:= Concatenation( "A", String( n ), ".2" ); fi; elif info[1] = "DoubleCoverAlternating"then if n = 2then
result:= "C2"; elif n = 3then
result:= "C6"; elif n = 4then
result:= "2.L2(3)"; elif2 < n and n < 14then
result:= Concatenation( "2.A", String( n ) ); fi; elif info[1] = "DoubleCoverSymmetric"then if n = 2then
result:= "C4"; elif n = 3then
result:= "2.S3"; elif n = 4then
result:= "2.Symm(4)"; elif n = 6then
result:= "2.A6.2_1"; elif n < 15then
result:= Concatenation( "Isoclinic(2.A", String( n ), ".2)" ); fi; fi; fi; fi; fi; fi;
if result = Identifier( tbl ) then
return fail; else
return result; fi; end );
InstallOtherMethod( IdentifiersOfDuplicateTables,
[ "IsString" ],
id -> AllCharacterTableNames( IdentifierOfMainTable, id ) );
############################################################################# ## #V CTblLib.NameReplacements ##
CTblLib.NameReplacements:= CallFuncList( function()
local file, str;
file:= Filename( DirectoriesPackageLibrary( "ctbllib", "data" )[1], "namerepl.json" );
str:= StringFile( file ); if str = fail then
Error( "the data file '", file, "' is not available" ); fi;
return TransposedMat( EvalString( str ) ); end, [] );
############################################################################# ## #F StructureDescriptionCharacterTableName( <name> ) ##
InstallGlobalFunction( StructureDescriptionCharacterTableName, function( name )
local parts, tbl, pos;
parts:= PParseBackwards( name, [ IsChar, "M", IsDigitChar ] ); if parts <> fail then # If the table has a `ConstructPermuted' description then # replace the name.
tbl:= CharacterTable( name ); if HasConstructionInfoCharacterTable( tbl ) and
IsList( ConstructionInfoCharacterTable( tbl ) ) and
ConstructionInfoCharacterTable( tbl )[1] = "ConstructPermuted" and
Length( ConstructionInfoCharacterTable( tbl )[2] ) = 1then
name:= ConstructionInfoCharacterTable( tbl )[2][1]; fi; fi;
# Replace individual values.
pos:= Position( CTblLib.NameReplacements[1], name ); if pos <> fail then
name:= CTblLib.NameReplacements[2][ pos ]; fi;
return name; end );
############################################################################# ## #F GaloisPartnersOfIrreducibles( <tbl>, <characters>, <n> ) ## ## Compute the Galois automorphism(s) carrying to the partner(s). ##
InstallGlobalFunction( GaloisPartnersOfIrreducibles, function( tbl, characters, n )
local partners, # list of partners, result
chi, # loop over `characters'
N, # conductor of `chi'
k, # list of values representing the partner cohorts
facts, # collected factors of `N'
primes, # prime factors of `N' 2part, # $2$-part of `N' 3part, # $3$-part of `N'
NN, # part of `N' that is coprime to $2$ and $3$
kk, # list with possible prime residues for each in `k'
new, # admissible subsets of `kk'
p; # characteristic in the case of a Brauer table
if n < 3then
Error( "only for n >=3" ); fi;
partners:= [];
for chi in characters do
N:= Conductor( chi );
# The rules of the ordinary Atlas apply for ordinary tables # and for Brauer characters for which all algebraic conjugates # are Brauer characters. if IsOrdinaryTable( tbl )
or ( IsBrauerTable( tbl )
and ( n <> 12 or Identifier( tbl ) <> "12.M22mod11" ) #T is this reasonable?
and ForAll( PrimeResidues( N ),
k -> List( chi,
x -> GaloisCyc( x, k ) ) in characters ) ) then
if n <> 12then
k:= [ n - 1 ]; else
k:= [ 5, 7, 11 ]; fi;
facts:= Collected( Factors( N ) );
primes:= List( facts, x -> x[1] ); if2 in primes then 2part:= 2^facts[ Position( primes, 2 ) ][2]; else 2part:= 1; fi; if3 in primes then 3part:= 3^facts[ Position( primes, 3 ) ][2]; else 3part:= 1; fi;
NN:= N / ( 2part * 3part );
# The automorphism $*k^\prime$ that carries to the # partner in the cohort given by $*k$ # is determined by the conditions that # $k^\prime \equiv k \pmod{n}$, # $k^\prime \equiv 1$ modulo each divisor of $N$ coprime to $n$, # $k^\prime \equiv \pm 1$ modulo powers of $2$ and $3$ # dividing $n$, # where $+1$ is preferred if there is a choice. # (As an example, consider $N = 60$, $n = 3$, and $k = 2$ # where $11$ and $41$ are possible solutions, # and the action on $20$-th roots of unity is different; # this occurs for the group $3.U_3(11)$.) # Note that we may have to replace $N$ by the l.c.m. of $N$ # and $n$, for example if $n = 6$ and $N$ is odd.
kk:= List( k, y -> Filtered( PrimeResidues( LcmInt( N, n ) ),
x -> x mod NN in [ 0, 1 ]
and x mod n = y
and x mod 2part in [ 2part-1, 1 ]
and x mod 3part in [ 3part-1, 1 ] ) ); for k in [ 1 .. Length( kk ) ] do if Length( kk[k] ) = 1then
kk[k]:= kk[k][1]; else if2part <> 1then
new:= Filtered( kk[k], x -> x mod 2part = 1 ); if Length( new ) <> 0then
kk[k]:= new; fi; fi; if Length( kk[k] ) > 1 and 3part <> 1then
new:= Filtered( kk[k], x -> x mod 3part = 1 ); if Length( new ) <> 0then
kk[k]:= new; fi; fi;
kk[k]:= kk[k][1]; fi;
od;
else
p:= UnderlyingCharacteristic( tbl ); if n <> 12then if ( p-1 ) mod n <> 0then
kk:= [ p ]; else
kk:= [ -1 ]; fi; elif Identifier( tbl ) = "12.M22mod11"then
kk:= [ -1 ]; else
kk:= [ p, -1, -p ]; fi;
fi;
Add( partners, kk );
od;
return partners; end );
############################################################################# ## #F AtlasLabelsOfIrreducibles( <tbl>[, <short>] ) ##
InstallGlobalFunction( AtlasLabelsOfIrreducibles, function( arg )
local tbl, # first argument, an ATLAS character table
short, # optional second argument, choice of short labels
ordtbl, # ordinary table of `tbl'
out, # index of the derived subgroup
centre, # centre of the derived subgroup
mult, # order of `centre'
nccl, # no. of conjugacy classes of `tbl'
charname, # string "\\chi" or "\\varphi"
der, # table of the derived subgroup corresp. to `tbl'
ordder, # table of the derived subgroup corresp. to `ordtbl'
pos, # position in a list
irr, # list of irreducibles
portions, # list that separates characters with different kernel
divisors, # list of divisors of the multiplier
i, j, k, l, # loop variables
labels, # list of labels, result
portionlbs, # list of labels for one portion
max, # current maximal offset
partners, # output of `GaloisPartnersOfIrreducibles'
special, # list of special cases requiring offsets
offsets, # current offsets in special case
fus, # various fusion maps
rest, # list of restricted characters
distrib, # positions of restrictions in `rest'
restchi, # one restriction to the derived subgroup
dec, # decomposition matrix of restrictions
derlabels, # list of labels of the derived subgroup
inv, # inverse map of `distrib'
dl, # list of nonzero coefficients in a decomposition
n, # length of `dl'
lb, # one label
intermed, # list of intermediate tables
index, # index of an inertia subgroup
fus1, # fusion from derived subgroup to intermediate group
fus2, # fusion from intermediate group to group
ext, # positions of extensions of a character
interirr; # irreducibles of an intermediate table
# Get the arguments.
tbl:= arg[1];
short:= Length( arg ) = 2 and ( arg[2] = "short" or arg[2] = true );
# `tbl' is assumed to be the table of a bicyclic extension # of a simple group. # Get the index `out' of the derived subgroup # and the order `mult' of the centre of the derived subgroup. if IsBrauerTable( tbl ) then
ordtbl:= OrdinaryCharacterTable( tbl ); else
ordtbl:= tbl; fi;
out:= AbelianInvariants( ordtbl ); if not IsSSortedList( out ) then
Error( "<tbl> is not a bicyclic extension of a simple table" ); fi;
out:= Product( out, 1 );
centre:= ClassPositionsOfFittingSubgroup( ordtbl );
mult:= Sum( SizesConjugacyClasses( ordtbl ){ centre }, 0 ); if12 mod mult <> 0then
Error( "<tbl> is not a bicyclic extension of an ATLAS table" ); fi;
nccl:= NrConjugacyClasses( tbl );
# Initializations for the final labels. if IsOrdinaryTable( tbl ) then
charname:= "\\chi_{"; else
charname:= "\\varphi_{"; fi;
# Compute label descriptions for the derived subgroup. # (For tables of non-perfect groups, # the labels are formed relative to the labels of the # table of the derived subgroup, # so we need this table and its label descriptions.) if out = 1then
der:= tbl;
ordder:= ordtbl;
else
ordder:= Identifier( ordtbl );
pos:= Length( ordder ); while IsDigitChar( ordder[ pos ] ) or ordder[ pos ] = '_'do
pos:= pos - 1;
od; if pos = Length( ordder ) or ordder[ pos ] <> '.'then
Error( "derived subgroup table not given by identifier of <tbl>" ); fi;
ordder:= CharacterTable( ordder{ [ 1 .. pos-1 ] } ); if ordder = fail then
Info( InfoCharacterTable, 1 , "no derived character table of ", Identifier( ordtbl ), " available" );
return fail; fi; if IsBrauerTable( tbl ) then
der:= BrauerTable( ordder, UnderlyingCharacteristic( tbl ) ); if der = fail then
Info( InfoCharacterTable, 1 , "no ", UnderlyingCharacteristic( tbl ), "-modular ", "derived character table of ", Identifier( ordtbl ), " available" );
return fail; fi; else
der:= ordder; fi;
fi;
# `der' is the table of a central extension of a simple group. # Each label is encoded by an integer (the subscript) # or a list of length two (the pair of subscript and a Galois # automorphism).
# Distribute the characters to different portions.
irr:= List( Irr( der ), ValuesOfClassFunction );
if mult <> 12then
divisors:= DivisorsInt( mult ); else
divisors:= [ 1, 2, 4, 3, 6, 12 ]; fi;
# The `i'-th portion consists of those characters with # conductor of the restriction to `centre' equal to `divisors[i]'. if IsBrauerTable( der ) then
fus:= GetFusionMap( der, ordder );
centre:= Filtered( [ 1 .. Length( fus ) ], i -> fus[i] in centre ); fi;
portions:= List( divisors,
i -> Filtered( [ 1 .. NrConjugacyClasses( der ) ],
j -> Conductor( irr[j]{ centre } ) = i ) );
labels:= [];
max:= 0;
for i in [ 1 .. Length( portions ) ] do
if divisors[i] < 3then
# The $i$-th label has index $i$.
Append( labels, [ 1 .. Length( portions[i] ) ] + max );
max:= Maximum( labels );
else
# Some of the characters are not printed in the {\ATLAS}, # therefore the labels are more complicated.
portionlbs:= [];
# Compute the Galois automorphisms mapping the printed # characters to their partner(s).
partners:= GaloisPartnersOfIrreducibles( der, irr{ portions[i] },
divisors[i] );
for k in [ 1 .. Length( portions[i] ) ] do
j:= portions[i][k];
# Get the position(s) of the partner(s).
pos:= List( partners[k],
x -> Position( irr,
List( irr[j],
y -> GaloisCyc( y, x ) ) ) );
# Construct labels relative to the *first* character # of each set with the same proxy. if j < Minimum( pos ) then
max:= max + 1;
portionlbs[k]:= max; for l in [ 1 .. Length( pos ) ] do
portionlbs[ Position( portions[i], pos[l] ) ]:=
[ max, partners[k][l] ];
od; fi;
od;
Append( labels, portionlbs );
fi;
od;
# Adjust the labels in the special cases # $A_6$, $A_7$, $L_3(4)$, $M_{22}$, $U_4(3)$, $O_7(3)$, # $U_6(2)$, $Suz$, $Fi_{22}$, and ${}^2E_6(2)$. # For these groups, $6$ divides the multiplier, # so at least $3.G$ needs an offset.
special:= [ "3.A6", [ 7, 6 ], "3.A6mod5", [ 5, 4 ],
pos:= Position( special, Identifier( der ) ); if pos <> fail then
offsets:= special[ pos+1 ]; for i in [ 1 .. Length( labels ) ] do if IsInt( labels[i] ) and labels[i] > offsets[1] then
labels[i]:= labels[i] + offsets[2]; elif IsList( labels[i] ) and labels[i][1] > offsets[1] then
labels[i][1]:= labels[i][1] + offsets[2]; elif Length( offsets ) > 2then if IsInt( labels[i] ) and labels[i] > offsets[3] then
labels[i]:= labels[i] + offsets[4]; elif IsList( labels[i] ) and labels[i][1] > offsets[3] then
labels[i][1]:= labels[i][1] + offsets[4]; fi; fi;
od; fi;
if out = 1then
# Build the final labels from the subscripts. for i in [ 1 .. Length( labels ) ] do if IsInt( labels[i] ) then
lb:= Concatenation( charname, String( labels[i] ), "}" ); else
lb:= Concatenation( charname, String( labels[i][1] ), "}^{\\ast" );
k:= labels[i][2]; if k < 0then
Append( lb, "\\ast" );
k:= -k; fi; if k <> 1then
Append( lb, " " );
Append( lb, String( k ) ); fi;
Append( lb, "}" ); fi;
labels[i]:= lb;
od;
else
# Start with the labels for `der'. # They are of the form `i' (for $\chi_i$) # or `[ i, j ]' (for $\chi_i^{*j}$).
derlabels:= labels;
labels:= [];
fus:= GetFusionMap( der, tbl ); if fus = fail then
Info( InfoCharacterTable, 1 , "no fusion from ", der, " to ", tbl, " available" );
return fail; fi;
# `rest' is the list of the different restrictions of `irr' # to the derived subgroup. # `distrib[i]' is the position of the restriction of `irr[i]' # in `rest'.
rest:= [];
distrib:= [];
irr:= List( Irr( tbl ), ValuesOfClassFunction ); for i in [ 1 .. Length( irr ) ] do
restchi:= irr[i]{ fus };
pos:= Position( rest, restchi ); if pos = fail then
Add( rest, restchi );
pos:= Length( rest ); fi;
distrib[i]:= pos;
od;
# Compute the decompositions of `rest' into irreducibles of `der'.
dec:= Decomposition( List( Irr( der ), ValuesOfClassFunction ),
rest, "nonnegative" );
# Store tables of intermediate groups if `out' is nonprime.
intermed:= [];
# Compute the labels of `irr'. # The number $n$ of different irreducibles of `der' contained in # a restriction divides `out'. # Let `outprime' be the $p^\prime$ part of `out'. # The following labels occur. # - If $n = 1$ then the labels are of the form # $\chi_{i,k}$ and $\chi_{i,k}^{*j}$, respectively, # where $0 \leq k < `outprime'$. # - If $n$ equals `out' then the labels are of the form # $\chi_{i1+i2+...+iout}$ or # $\chi_{i1* j1 + i2* j2 +...+ iout* jout}$ . # - In all other cases, `outprime' is either $4$ or $6$, # and we need the intermediate tables.
inv:= InverseMap( distrib ); for i in [ 1 .. Length( rest ) ] do if IsInt( inv[i] ) then
inv[i]:= [ inv[i] ]; fi;
dl:= Filtered( [ 1 .. Length( dec[i] ) ], j -> dec[i][j] <> 0 );
n:= Length( dl ); if n = 1then # extension case for j in [ 1 .. Length( inv[i] ) ] do if IsInt( derlabels[ dl[1] ] ) then # extension
labels[ inv[i][j] ]:= Concatenation( charname,
String( derlabels[ dl[1] ] ), ",",
String( j-1 ), "}" ); else # conjugate of an extension
lb:= Concatenation( charname, String( derlabels[ dl[1] ][1] ), ",", String( j-1 ), "}^{\\ast" );
k:= derlabels[ dl[1] ][2]; if k < 0then
Append( lb, "\\ast" );
k:= -k; fi; if k <> 1then
Append( lb, " " );
Append( lb, String( k ) ); fi;
Append( lb, "}" );
labels[ inv[i][j] ]:= lb; fi;
od; elif n = out then # case of fusion if short then if ForAny( derlabels{ dl }, IsInt ) then
lb:= Concatenation( charname,
String( First( derlabels{ dl }, IsInt ) ), "+}" ); else
j:= derlabels[ dl[1] ];
lb:= Concatenation( charname,
String( j[1] ), "\\ast" );
k:= j[2]; if k < 0then
Append( lb, "\\ast" );
k:= - k; fi;
Append( lb, " " ); if k <> 1then
Append( lb, String( k ) ); fi;
Append( lb, "+}" ); fi; else
lb:= ShallowCopy( charname ); for j in derlabels{ dl } do if IsInt( j ) then
Append( lb, Concatenation( String( j ), "+" ) ); else
Append( lb, String( j[1] ) );
Append( lb, "\\ast" );
k:= j[2]; if k < 0then
Append( lb, "\\ast" );
k:= -k; fi;
Append( lb, " " ); if k <> 1then
Append( lb, String( k ) ); fi;
Append( lb, "+" ); fi;
od;
lb[ Length( lb ) ]:= '}'; fi;
labels[ inv[i][1] ]:= lb;
else
# We have an intermediate group $U$ such that the characters # of the simple group extend to $U$ and the extensions of # different characters fuse in the full extension. # (In our cases, this intermediate group is uniquely determined # because `out' is either $4$ or $6$.)
# The inertia subgroup has index `index'.
index:= Length( dl ); if not IsBound( intermed[ index ] ) then
intermed[ index ]:= List( Filtered(
ComputedClassFusions( ordder ),
x -> x.name in NamesOfFusionSources( ordtbl ) ),
y -> CharacterTable( y.name ) );
intermed[ index ]:= Filtered( intermed[ index ],
x -> Size( tbl ) / Size( x ) = index ); if Length( intermed[ index ] ) > 1then
Error( "indermediate table of index ", index, " in ", ordtbl, " not unique" ); fi;
intermed[ index ]:= intermed[ index ][1]; if IsBrauerTable( der ) then
intermed[ index ]:= BrauerTable( intermed[ index ],
UnderlyingCharacteristic( der ) ); fi; fi;
interirr:= List( Irr( intermed[ index ] ),
ValuesOfClassFunction );
fus1:= GetFusionMap( der, intermed[ index ] );
fus2:= GetFusionMap( intermed[ index ], tbl );
for j in inv[i] do
# Construct the label string. if short then
if ForAny( dl, x -> IsInt( derlabels[x] ) ) then
l:= First( dl, x -> IsInt( derlabels[x] ) );
# Get the extensions from `der' to the intermediate group.
ext:= ValuesOfClassFunction( Irr( der )[l] );
ext:= Filtered( [ 1 .. Length( interirr ) ],
x -> Irr( intermed[ index ] )[x]{ fus1 } = ext );
# Count which extension occurs in the restriction from `tbl' # to the intermediate group.
k:= Decomposition( interirr, [ irr[j]{ fus2 } ], "nonnegative" );
k:= First( [ 1 .. Length( ext ) ],
x -> k[1][ ext[x] ] <> 0 );
# Get the extensions from `der' to the intermediate group.
ext:= ValuesOfClassFunction( Irr( der )[l] );
ext:= Filtered( [ 1 .. Length( interirr ) ],
x -> Irr( intermed[ index ] )[x]{ fus1 } = ext );
# Count which extension occurs in the restriction from `tbl' # to the intermediate group.
k:= Decomposition( interirr, [ irr[j]{ fus2 } ], "nonnegative" );
k:= First( [ 1 .. Length( ext ) ],
x -> k[1][ ext[x] ] <> 0 );
# Get the extensions from `der' to the intermediate group.
ext:= ValuesOfClassFunction( Irr( der )[l] );
ext:= Filtered( [ 1 .. Length( interirr ) ],
x -> Irr( intermed[ index ] )[x]{ fus1 } = ext );
# Count which extension occurs in the restriction from `tbl' # to the intermediate group.
k:= Decomposition( interirr, [ irr[j]{ fus2 } ], "nonnegative" );
k:= First( [ 1 .. Length( ext ) ],
x -> k[1][ ext[x] ] <> 0 );
############################################################################# ## ## The rest of this file contains the interface between the GAP libraries ## of character tables and of tables of marks. ## ## The interface consists of methods for the operations `CharacterTable' and ## `TableOfMarks', with argument a table of marks and a character table, ## respectively. ## These methods try to get the corresponding character table resp.~table of ## marks from the library. ## ## If the required information is not found in the respective library, ## and if no group is available from which this information can be computed ## then `fail' returned. ## ## The availability of the required information is looked up in ## `LIBLIST.TOM_TBL_INFO'. ## This is a list of length two, ## the first entry being the list of identifiers of tables of marks, ## the second entry being the list of corresponding identifiers of library ## character tables. ## ## (If not both the library of character tables and the library of tables of ## marks are installed then the entries in `LIBLIST.TOM_TBL_INFO' are empty ## lists, hence the methods mentioned above become trivial.) ##
############################################################################# ## #M TableOfMarks( <tbl> ) . . . . . . . . . . . . . . . for a character table #M TableOfMarks( <G> ) ## ## We delegate from <tbl> to the underlying group in the general case. ## ## If the argument is a group, we can use the known table of marks of the ## known ordinary character table. ##
InstallOtherMethod( TableOfMarks,
[ "IsCharacterTable and HasUnderlyingGroup" ],
tbl -> TableOfMarks( UnderlyingGroup( tbl ) ) );
InstallOtherMethod( TableOfMarks,
[ "IsGroup and HasOrdinaryCharacterTable" ], 100, function( G )
local tbl;
tbl:= OrdinaryCharacterTable( G ); if HasTableOfMarks( tbl ) then
return TableOfMarks( tbl ); else
TryNextMethod(); fi; end );
############################################################################# ## #M TableOfMarks( <tbl> ) . . . . . . . . . . . for a library character table ## ## <#GAPDoc Label="TableOfMarks"> ## <ManSection> ## <Meth Name="TableOfMarks" Arg="tbl" ## Label="for a character table from the library"/> ## ## <Description> ## Let <A>tbl</A> be an ordinary character table from the ## &GAP; Character Table Library, ## for the group <M>G</M>, say. ## If the <Package>TomLib</Package> package is loaded and contains the ## table of marks of <M>G</M> then there is a method based on ## <Ref Oper="TableOfMarks" Label="for a string" BookName="ref"/> ## that returns this table of marks. ## If there is no such table of marks but <A>tbl</A> knows its underlying ## group then this method delegates to the group. ## Otherwise <K>fail</K> is returned. ## <P/> ## <Example> ## gap> TableOfMarks( CharacterTable( "A5" ) ); ## TableOfMarks( "A5" ) ## gap> TableOfMarks( CharacterTable( "M" ) ); ## fail ## </Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallOtherMethod( TableOfMarks,
[ "IsOrdinaryTable and IsLibraryCharacterTableRep" ], function( tbl )
local pos;
pos:= Position( LIBLIST.TOM_TBL_INFO[2],
LowercaseString( Identifier( tbl ) ) ); if pos <> fail then
return TableOfMarks( LIBLIST.TOM_TBL_INFO[1][ pos ] ); elif HasUnderlyingGroup( tbl ) then
TryNextMethod(); fi;
return fail; end );
############################################################################# ## #M CharacterTable( <G> ) ## ## If the argument is a group, we can use the known character table of the ## known table of marks. ##
InstallOtherMethod( CharacterTable,
[ "IsGroup and HasTableOfMarks" ], 100, function( G )
local tom;
tom:= TableOfMarks( G ); if HasOrdinaryCharacterTable( tom ) then
return OrdinaryCharacterTable( tom ); else
TryNextMethod(); fi; end );
pos:= Position( LIBLIST.TOM_TBL_INFO[1], LowercaseString( tomname ) ); if pos <> fail then
pos:= LibInfoCharacterTable( LIBLIST.TOM_TBL_INFO[2][ pos ] ); if IsRecord( pos ) then
return pos.firstName; fi; fi;
return fail; end );
############################################################################# ## #F CTblLib.SetAttributesForSpinSymTable( <firstname> ) ## ## The character tables with the identifiers '"Alt(<n>)"', '"2.Alt(<n>)"', ## '"Sym(<n>)"', and '"2.Sym(<n>)"', for $1 \leq <n> \leq 19$, ## are provided by the SpinSym package. ## If the values of the attributes supported by 'CTblLib.Data.IdEnumerator' ## are not set then calls of 'AllCharacterTableNames' will have to compute ## these values and thus will be slow. ## Moreover, several SpinSym tables are duplicates of tables from CTblLib, ## so we have to notify at least this information. ##
CTblLib.SetAttributesForSpinSymTable:= function( spinsymname )
local store_data, enum, attrs, enumext, attrsext, posext, n,
An, Sn, 2An, 2Sn, libname, attr, pos, repl, str, values;
# auxiliary function that adds data for `libname` either directly # to the attribute `dataname` or to a global variable tat gets evaluated # as soon as the underlying GAP package becomes available
store_data:= function( libname, dataname )
local nam, str, data, values;
if libname = fail then
return; fi;
nam:= Concatenation( "Source_data_", dataname ); if not IsBound( CTblLib.Data.( nam ) ) then
str:= StringFile( Filename( DirectoriesPackageLibrary( "CTblLib", "data" ),
Concatenation( "grp_", dataname, ".json" ) ) );
CTblLib.Data.( nam ):= AGR.GapObjectOfJsonText( str ).value; fi;
data:= CTblLib.Data.( nam ).automatic;
values:= PositionSorted( data, [ libname ] ); if not IsBound( data[ values ] ) then
return; fi;
values:= data[ values ]; if values[1] <> libname then
return; elif IsBound( attrsext.( dataname ) ) then
Add( attrsext.( dataname ).data.automatic,
[ spinsymname, values[2] ] ); else # The data will be inserted in an extension file.
nam:= Concatenation( "IdEnumeratorExt_attributes_", dataname, "_data_automatic" ); if not IsBound( CTblLib.( nam ) ) then
CTblLib.( nam ):= []; fi;
Add( CTblLib.( nam ), [ spinsymname, values[2] ] ); fi; end;
enum:= CTblLib.Data.IdEnumerator; if enum.identifiers = [] then # No attributes are available.
return; fi;
posext:= Position( enumext.identifiers, spinsymname );
n:= Int( spinsymname{ [ Position( spinsymname, '(' ) + 1
.. Length( spinsymname ) - 1 ] } ); if n < 2 or 19 < n then
return; fi;
An:= ( spinsymname[1] = 'A' );
Sn:= ( spinsymname[1] = 'S' ); 2An:= ( spinsymname[3] = 'A' ); 2Sn:= ( spinsymname[3] = 'S' );
libname:= fail; if An then if n = 3then
libname:= "C3"; elif n = 4then
libname:= "a4"; elif n <> 2then
libname:= Concatenation( "A", String( n ) ); fi; elif Sn then if n = 2then
libname:= "C2"; elif n = 3then
libname:= "S3"; elif n = 4then
libname:= "s4"; elif n = 6then
libname:= "A6.2_1"; else
libname:= Concatenation( "A", String( n ), ".2" ); fi; elif2An then if n = 2then
libname:= "C2"; elif n = 3then
libname:= "C6"; elif n = 4then
libname:= "2.L2(3)"; else
libname:= Concatenation( "2.A", String( n ) ); fi; elif2Sn then if n = 2then
libname:= "C4"; elif n = 3then
libname:= "2.S3"; elif n = 4then
libname:= "2.Symm(4)"; elif n = 6then
libname:= "2.A6.2_1"; else # Note that the library tables with identifier "2.A<n>.2" # are not the tables 'CharacterTable( "DoubleCoverSymmetric", <n> )'.
libname:= Concatenation( "Isoclinic(2.A", String( n ), ".2)" ); fi; fi; if libname <> fail and
Position( LIBLIST.allnames, LowercaseString( libname ) ) = fail then
libname:= fail; fi;
# AbelianInvariants:
attr:= attrsext.AbelianInvariants; if spinsymname in [ "2.Sym(2)", "2.Sym(3)" ] then
attr.data[ posext ]:= [ 4 ]; elif Sn or 2Sn then
attr.data[ posext ]:= [ 2 ]; elif5 <= n then
attr.data[ posext ]:= []; else
pos:= PositionSorted( [ "2.Alt(2)", "2.Alt(3)", "2.Alt(4)", "Alt(2)", "Alt(3)", "Alt(4)" ], spinsymname );
repl:= [ [ 2 ], [ 2, 3 ], [ 3 ], [], [ 3 ], [ 3 ] ];
attr.data[ posext ]:= repl[ pos ]; fi;
# almostSimpleInfo: if5 <= n then if An then
Add( attrsext.almostSimpleInfo.data.automatic,
[ spinsymname, [ libname, [ 1, 1 ] ] ] ); elif Sn then
Add( attrsext.almostSimpleInfo.data.automatic,
[ spinsymname, [ Concatenation( "A", String( n ) ), [ 2, 1 ] ] ] ); fi; fi;
# atlas: # If the AtlasRep package is not (yet) loaded at runtime, # we add the information to a global variable that gets evaluated # as soon as AtlasRep is available. # In order to copy the known values from a library table, # we evaluate the source data of the 'atlas' attribute. # (Note that we can do this because the 'eval' function in # 'CTblLib.Data.IdEnumerator' and in 'CTblLib.Data.IdEnumeratorExt' # are the same.)
store_data( libname, "atlas" );
# basic: if An then
Add( attrsext.basic.data.automatic,
[ spinsymname, [ [ "AlternatingGroup", [ n ] ] ] ] ); elif Sn then
Add( attrsext.basic.data.automatic,
[ spinsymname, [ [ "SymmetricGroup", [ n ] ] ] ] ); elif2An and 4 <= n then
Add( attrsext.basic.data.automatic,
[ spinsymname, [ [ "DoubleCoverOfAlternatingGroup", [ n ] ] ] ] ); elif2Sn and 4 <= n then
Add( attrsext.basic.data.automatic,
[ spinsymname, [ [ "SchurCoverOfSymmetricGroup", [ n ] ] ] ] ); fi;
# FusionsTo: # 'Alt(<n>)' -> 'Sym(<n>)', # '2.Alt(<n>)' -> 'Alt(<n>)', # '2.Alt(<n>)' -> '2.Sym(<n>)', # '2.Sym(<n>)' -> 'Sym(<n>)'.
attr:= attrsext.FusionsTo;
values:= []; if2An or 2Sn then
Add( values, ReplacedString( spinsymname, "2.", "" ) ); fi; if An or 2An then
Add( values, ReplacedString( spinsymname, "Alt", "Sym" ) ); fi;
Add( attr.data.automatic, [ spinsymname, values ] );
# InfoText: if An then
attrsext.InfoText.data[ posext ]:= "computed using generic character table for alternating groups"; elif Sn then
attrsext.InfoText.data[ posext ]:= "computed using generic character table for symmetric groups"; else
attrsext.InfoText.data[ posext ]:= ""; fi;
# IsAbelian:
attrsext.IsAbelian.data[ posext ]:=
( n <= 2 or ( n = 3 and ( An or 2An ) ) );
# IsAlmostSimple:
attrsext.IsAlmostSimple.data[ posext ]:= ( 5 <= n and ( An or Sn ) );
# NamesOfFusionSources:
values:= []; if Sn or 2Sn then
Add( values, ReplacedString( spinsymname, "Sym", "Alt" ) ); fi; if An or Sn then
Add( values, Concatenation( "2.", spinsymname ) ); fi;
attrsext.NamesOfFusionSources.data[ posext ]:= values;
# NrConjugacyClasses: if An then
attrsext.NrConjugacyClasses.data[ posext ]:=
Length( CharTableAlternating.classparam[1]( n ) ); elif Sn then
attrsext.NrConjugacyClasses.data[ posext ]:= NrPartitions( n ); elif libname <> fail then
attr:= attrs.NrConjugacyClasses;
attrsext.NrConjugacyClasses.data[ posext ]:=
attr.attributeValue( attr, libname ); elif2An then if n = 2then
attrsext.NrConjugacyClasses.data[ posext ]:= 2; else
values:= [ 105, 135, 171, 213, 269, 335 ];
attrsext.NrConjugacyClasses.data[ posext ]:= values[ n - 13 ]; fi; else
values:= [ 216, 279, 354, 454, 571 ];
attrsext.NrConjugacyClasses.data[ posext ]:= values[ n - 14 ]; fi;
# "perf": if ( An or 2An ) and 5 <= n and n <= 9then
attr:= attrs.perf;
values:= attr.attributeValue( attr, libname ); if not IsEmpty( values ) then
Add( attrsext.perf.data.automatic, [ spinsymname, values ] ); fi; fi;
# "prim": # Take the known values for alternating and symmetric groups. if ( An or Sn ) and libname <> fail then
attr:= attrs.prim;
values:= attr.attributeValue( attr, libname ); if not IsEmpty( values ) then
Add( attrsext.prim.data.automatic, [ spinsymname, values ] ); fi; fi;
# Size: if An then
attrsext.Size.data[ posext ]:= Factorial( n ) / 2; elif2An or Sn then
attrsext.Size.data[ posext ]:= Factorial( n ); elif2Sn then
attrsext.Size.data[ posext ]:= 2 * Factorial( n ); fi;
# small: if libname <> fail then
attr:= attrs.small;
values:= attr.attributeValue( attr, libname ); if not IsEmpty( values ) then
Add( attrsext.small.data.automatic, [ spinsymname, values ] ); fi; fi;
# tom: # If the TomLib package is not (yet) loaded at runtime, # we add the information to a global variable that gets evaluated # as soon as TomLib is available. # In order to copy the known values from a library table, # we evaluate the source data of the 'tom' attribute. # (Note that we can do this because the 'eval' function in # 'CTblLib.Data.IdEnumerator' and in 'CTblLib.Data.IdEnumeratorExt' # are the same.)
store_data( libname, "tom" );
# trans: if libname <> fail then
attr:= attrs.trans;
values:= attr.attributeValue( attr, libname ); if not IsEmpty( values ) then
Add( attrsext.trans.data.automatic, [ spinsymname, values ] ); fi; fi;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.267Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.