############################################################################# ## ## This file is part of GAP, a system for computational discrete algebra. ## This file's authors include Götz Pfeiffer, Felix Noeske. ## ## Copyright of GAP belongs to its developers, whose names are too numerous ## to list here. Please refer to the COPYRIGHT file for details. ## ## SPDX-License-Identifier: GPL-2.0-or-later ## ## This file contains the functions needed for a direct computation of ## the character values of wreath products of a group $G$ with $S_n$, ## the symmetric group on n points. ##
res:= 1; for i in [1..Length(ptuple)] do
last:= 0; k:= 1; for p in ptuple[i] do
res:= res * sub_cen[i] * p; if p = last then
k:= k+1;
res:= res * k; else
k:= 1; fi;
last:= p;
od;
od;
power:= List(ptuple, x-> []); for i in [1..Length(ptuple)] do for k in ptuple[i] do if k mod p = 0then for j in [1..p] do
Add(power[i], k/p);
od; else
Add(power[sub_pm[i]], k); fi;
od;
od;
for k in power do
Sort(k, function(a,b) return a>b; end);
od;
# collect hook encodings. for i in [1..n] do
pm[i]:= List(Partitions(i), BetaSet);
scheme[i]:= []; for beta in pm[i] do
Add(scheme[i], hooks(beta, i));
od;
od;
return scheme;
end );
############################################################################# ## #F MatCharsWreathSymmetric( <tbl>, <n> ) . . . character matrix of G wr Sn. ##
InstallGlobalFunction( MatCharsWreathSymmetric, function( tbl, n)
local tbl_irreducibles,
i, j, k, m, r, s, t, pm, res, col, scheme, np, charCol, hooks,
pts, partitions;
# encode partition tuples by positions of partitions.
partitions:= List([1..n], Partitions);
pts:= []; for i in [1..n] do
pts[i]:= PartitionTuples(i, r); for j in [1..Length(pts[i])] do
np:= [[], []]; for t in pts[i][j] do
s:= Sum( t, 0 );
Add(np[1], s); if s = 0then
Add(np[2], 1); else
Add(np[2], Position( partitions[s], t, 0 )); fi;
od;
pts[i][j]:= np;
od;
od;
scheme:= InductionScheme(n);
# how to encode a hook.
hooks:= function(np, n)
local res, i, k, l, ni, pi, sign;
res:= []; for i in [1..r] do
res[i]:= List([1..n], x-> []);
od;
for i in [1..r] do
ni:= np[1][i]; pi:= np[2][i]; for k in [1..ni] do for l in scheme[ni][pi][k] do
np[1][i]:= ni-k; if l < 0then
np[2][i]:= -l;
sign:= -1; else
np[2][i]:= l;
sign:= 1; fi; if k = n then
Add(res[i][k], sign); else
Add(res[i][k], sign * Position(pts[n-k], np)); fi;
od;
od;
np[1][i]:= ni; np[2][i]:= pi;
od;
return res; end;
# collect hook encodings.
res:= [];
Info( InfoCharacterTable, 2, "Scheme:" ); for i in [1..n] do
Info( InfoCharacterTable, 2, i );
res[i]:= []; for np in pts[i] do
Add(res[i], hooks(np, i));
od;
od;
scheme:= res;
# how to construct a new column.
charCol:= function(n, t, k, p)
local i, j, col, pi, val;
col:= []; for pi in scheme[n] do
val:= 0; for j in [1..r] do for i in pi[j][k] do if i < 0then
val:= val - tbl_irreducibles[j][p] * t[-i]; else
val:= val + tbl_irreducibles[j][p] * t[i]; fi;
od;
od;
Add(col, val);
od;
return col; end;
# construct the columns.
pm:= List([1..n-1], x->[]);
Info( InfoCharacterTable, 2, "Cycles:" ); for m in [1..QuoInt(n,2)] do
# the $m$-cycle in all possible places
Info( InfoCharacterTable, 2, m ); for i in [1..r] do
s:= [1..n]*0+1;
s[m]:= i;
Add(pm[m], rec(col:= charCol(m, [1], m, i), pos:= s));
od;
# add the $m$-cycle to everything you know for k in [m+1..n-m] do for t in pm[k-m] do for i in [t.pos[m]..r] do
s:= ShallowCopy(t.pos);
s[m]:= i;
Add(pm[k], rec(col:= charCol(k, t.col, m, i), pos:= s));
od;
od;
od;
od;
# collect and transpose.
np:= Length(scheme[n]);
res:= List([1..np], x-> []);
Info( InfoCharacterTable, 2, "Tables:" ); for k in [1..n-1] do
Info( InfoCharacterTable, 2, k ); for t in pm[n-k] do for i in [t.pos[k]..r] do
col:= charCol(n, t.col, k, i); for j in [1..np] do
Add(res[j], col[j]);
od;
od;
od;
od;
for i in [1..r] do
col:= charCol(n, [1], n, i); for j in [1..np] do
Add(res[j], col[j]);
od;
od;
return res;
end );
############################################################################# ## #F CharValueSymmetric( <n>, <beta>, <pi> ) . . . . . character value in S_n. ##
InstallGlobalFunction( CharValueSymmetric, function(n, beta, pi)
local i, j, k, o, gamma, rho, val, sign;
# get length of longest cycle.
k:= pi[1];
# determine offset.
o:= 0; while beta[o+1] = o do
o:= o+1;
od;
# degree case. if k = 1then
# find all beads.
val:= 1; for i in [o+1..Length(beta)] do
val:= val * (beta[i] - o);
# find other free places. for j in [o+1..beta[i]-1] do if not j in beta then
val:= val * (beta[i]-j); fi;
od;
od;
return Factorial(n)/val; fi;
# almost trivial case. if k = n then if n + o in beta then
return (-1)^(Size(beta)+o+1); else
return 0; fi; fi;
rho:= pi{[2..Length(pi)]};
val:= 0;
# loop over the beta set. for i in beta do if i >= k+o and not i-k in beta then
# compute the leg parity.
sign:= 1; for j in [i-k+1..i-1] do if j in beta then
sign:= -sign; fi;
od;
# compute new beta set.
gamma:= Difference(beta, [i]);
AddSet(gamma, i-k);
# enter recursion.
val:= val + sign * CharValueSymmetric(n-k, gamma, rho); fi;
od;
# return the result.
return val; end );
############################################################################# ## #V CharTableSymmetric . . . . generic character table of symmetric groups. ## ## Note that this record is accessed in the `Irr' method for natural ## symmetric groups. ##
BindGlobal( "CharTableSymmetric", Immutable( rec(
isGenericTable:=
true,
identifier:= "Symmetric",
size:=
Factorial,
specializedname:=
( n -> Concatenation( "Sym(", String(n), ")" ) ),
text:= "generic character table for symmetric groups",
classparam:=
[ Partitions ],
charparam:=
[ Partitions ],
centralizers:=
[ function(n, pi)
local k, last, p, res;
res:= 1; last:= 0; k:= 1; for p in pi do
res:= res * p; if p = last then
k:= k+1;
res:= res * k; else
k:= 1; fi;
last:= p;
od;
return res; end ],
orders:=
[ function(n, lbl) return Lcm(lbl); end ],
powermap:=
[ function(n,k,pow) return [1,PowerPartition(k,pow)]; end ],
irreducibles:=
[ [ function(n, alpha, pi)
return CharValueSymmetric(n, BetaSet(alpha), pi); end ] ],
matrix:= function(n)
local scheme, beta, pm, i, m, k, t, col, np, res, charCol;
scheme:= InductionScheme(n);
# how to construct a new column.
charCol:= function(m, t, k)
local i, col, pi, val;
col:= []; for pi in scheme[m] do
val:= 0; for i in pi[k] do if i < 0then
val:= val - t[-i]; else
val:= val + t[i]; fi;
od;
Add(col, val);
od;
return col; end;
# construct the columns.
pm:= List([1..n-1], x-> []); for m in [1..QuoInt(n,2)] do
Add(pm[m], charCol(m, [1], m));
for k in [m+1..n-m] do for t in pm[k-m] do
Add(pm[k], charCol(k, t, m));
od;
od;
od;
# collect and transpose.
np:= Length(scheme[n]);
res:= List([1..np], x-> []); for k in [1..n-1] do for t in pm[n-k] do
col:= charCol(n, t, k); for i in [1..np] do
Add(res[i], col[i]);
od;
od;
od;
col:= charCol(n, [1], n); for i in [1..np] do
Add(res[i], col[i]);
od;
return res; end,
domain:=
IsPosInt
) ) );
############################################################################# ## #V CharTableAlternating . . generic character table of alternating groups. ##
BindGlobal( "CharTableAlternating", Immutable( rec(
isGenericTable:=
true,
identifier:= "Alternating",
size:=
( n -> Factorial(n)/2 ),
specializedname:=
( n -> Concatenation( "Alt(", String(n), ")" ) ),
text:= "generic character table for alternating groups",
classparam:=
[ function(n)
local labels, pi, pdodd;
pdodd:= function(pi)
local i; if pi[1] mod 2 = 0then
return false; fi; for i in [2..Length(pi)] do if pi[i] = pi[i-1] or pi[i] mod 2 = 0then
return false; fi;
od;
return true; end;
labels:= []; for pi in Partitions(n) do if SignPartition(pi) = 1then if pdodd(pi) then
Add(labels, [pi, '+']);
Add(labels, [pi, '-']); else
Add(labels, pi); fi; fi;
od;
return labels; end ],
charparam:=
[ function(n)
local alpha, labels;
labels:= []; for alpha in Partitions(n) do if alpha = AssociatedPartition(alpha) then
Add(labels, [alpha, '+']);
Add(labels, [alpha, '-']); elif alpha < AssociatedPartition(alpha) then
Add(labels, alpha); fi;
od;
return labels; end ],
centralizers:=
[ function(n, lbl)
local cen; if Length(lbl) = 2 and not IsInt(lbl[2]) then
return CharTableSymmetric!.centralizers[1](n, lbl[1]); else
return CharTableSymmetric!.centralizers[1](n, lbl)/2; fi; end ],
orders:=
[ function(n, lbl) if Length(lbl) = 2 and not IsInt(lbl[2]) then
lbl:= lbl[1]; fi;
return Lcm(lbl); end ],
powermap:=
[ function(n, lbl, prime)
local val, prod;
# split case. if Length(lbl) = 2 and not IsInt(lbl[2]) then
prod:= Product( lbl[1], 1 );
# coprime case needs complicated check. if prod mod prime <> 0then
val:= EB(prod); if val+1 = -GaloisCyc(val, prime) then if lbl[2] = '+'then
return [1, [lbl[1], '-']]; else
return [1, [lbl[1], '+']]; fi; else
return [1, lbl]; fi; else
return [1, PowerPartition(lbl[1], prime)]; fi; fi;
# ordinary case.
return [1, PowerPartition(lbl, prime)]; end ],
irreducibles:=
[ [ function(n, alpha, pi)
local val;
if Length(alpha) = 2 and not IsInt(alpha[2]) then if Length(pi) = 2 and not IsInt(pi[2]) then
val:= CharTableSymmetric!.irreducibles[1][1](n,
alpha[1], pi[1]); if val in [-1, 1] then if alpha[2] = pi[2] then
val:= -val * EB( Product( pi[1], 1 ) ); else
val:= val * (1 + EB( Product( pi[1], 1 ) )); fi; else
val:= val/2; fi; else
val:= CharTableSymmetric!.irreducibles[1][1](n,
alpha[1], pi)/2; fi;
else if Length(pi) = 2 and not IsInt(pi[2]) then
val:= CharTableSymmetric!.irreducibles[1][1](n,
alpha, pi[1]); else
val:= CharTableSymmetric!.irreducibles[1][1](n,
alpha, pi); fi; fi;
return val; end ] ],
wholetable := function( gtab, n )
local pars, classparam, charparam, centralizers, orders, fus,
classpars, charparsnr, nrpars, i, pi, ord, cen, ass, symvals,
matrix, nrchars, char, j, val, pow, p, prod;
# class parameters, cent. orders, element orders, char. parameters for i in [ 1 .. nrpars ] do
pi:= pars[i];
if SignPartition( pi ) = 1then
ord:= Lcm( pi );
cen:= CharTableSymmetric.centralizers[1]( n, pi ); if Length( Set( pi ) ) = Length( pi )
and ForAll( pi, IsOddInt ) then
Add( classparam, [pi, '+'] );
Add( classparam, [pi, '-'] );
Add( centralizers, cen );
Add( centralizers, cen );
Add( orders, ord );
Add( fus, i ); else
Add( classparam, pi );
Add( classpars, i );
Add( centralizers, cen / 2 ); fi;
Add( orders, ord );
Add( fus, i ); fi;
ass:= AssociatedPartition( pi ); if pi = ass then
Add( charparam, [pi, '+'] );
Add( charparam, [pi, '-'] );
Add( charparsnr,i );
Add( charparsnr,i ); elif pi < ass then
Add( charparam, pi );
Add( charparsnr, i ); fi;
od;
# irreducibles
symvals:= CharTableSymmetric.matrix( n );
matrix:= [];
nrchars:= Length( charparam ); for i in [ 1 .. nrchars ] do
char:= []; for j in [ 1 .. nrchars ] do if Length( charparam[i] ) = 2
and not IsInt( charparam[i][2] ) then if Length( classparam[j] ) = 2
and not IsInt( classparam[j][2] ) then
val:= symvals[ charparsnr[i] ][ fus[j] ]; if val in [ -1, 1 ] then if charparam[i][2] = classparam[j][2] then
val:= -val * EB( Product( classparam[j][1], 1 ) ); else
val:= val * ( 1 + EB( Product( classparam[j][1], 1 ) ) ); fi; else
val:= val / 2; fi; else
val:= symvals[ charparsnr[i] ][ fus[j] ] / 2; fi; else
val:= symvals[ charparsnr[i] ][ fus[j] ]; fi;
Add( char, val );
od;
Add( matrix, char );
od;
# power maps
pow:= []; for p in Filtered( [ 2 .. n ], IsPrimeInt ) do
pow[p]:= [ 1 .. nrchars ]; for i in [ 1 .. nrchars ] do
if Length( classparam[i] ) = 2
and not IsInt( classparam[i][2] ) then
prod:= Product( classparam[i][1] ); if prod mod p <> 0then
val:= EB( prod ); if val+1 = -GaloisCyc(val, p) then if classparam[i][2] = '+'then
pow[p][i]:= i+1; else
pow[p][i]:= i-1; fi; else
pow[p][i]:= i; fi; else
pow[p][i]:= Position( classparam,
PowerPartition( classparam[i][1], p ) ); fi; else
pow[p][i]:= Position( classparam,
PowerPartition( classparam[i], p ) ); fi;
od;
od;
return rec( Identifier:= Concatenation( "Alt(", String( n ), ")" ),
InfoText := "computed using generic character table for alternating groups",
UnderlyingCharacteristic:= 0,
ClassParameters:= List( classparam, pi -> [ 1, pi ] ),
CharacterParameters:= List( charparam, pi -> [ 1, pi ] ),
Size:= Factorial( n ) / 2,
NrConjugacyClasses:= nrchars,
SizesCentralizers:= centralizers,
ComputedPowerMaps:= pow,
OrdersClassRepresentatives:= orders,
Irr:= matrix,
ComputedClassFusions:= [ rec(
name := Concatenation( "Sym(", String( n ), ")" ),
map := fus ) ] ); end,
domain:=
( n -> IsInt(n) and n > 1 )
) ) );
############################################################################# ## #F CharValueWeylB( <n>, <beta>, <pi> ) . . . . . character value in 2 wr Sn. ##
InstallGlobalFunction( CharValueWeylB, function(n, beta, pi)
local i, j, k, lb, o, s, t, gamma, rho, sign, val;
# termination condition. if n = 0then
return 1; fi;
# negative cycles first. if pi[2] <> [] then
t:= 2; else
t:= 1; fi;
############################################################################# ## #V CharTableWeylD . . . . generic character table of Weyl groups of type D. ##
BindGlobal( "CharTableWeylD", rec(
isGenericTable:=
true,
identifier:= "WeylD",
size:=
( n -> 2^(n-1) * Factorial(n) ),
specializedname:=
( n -> Concatenation( "W(D", String(n), ")" ) ),
text:= "generic character table for Weyl groups of type D",
classparam:=
[ function(n)
local labels, pi;
labels:= []; for pi in PartitionTuples(n, 2) do if Length(pi[2]) mod 2 = 0then if pi[2] = [] and ForAll(pi[1], x-> x mod 2 = 0) then
Add(labels, [pi[1], '+']);
Add(labels, [pi[1], '-']); else
Add(labels, pi); fi; fi;
od;
return labels; end ],
charparam:=
[ function(n)
local alpha, labels;
labels:= [];
for alpha in PartitionTuples(n, 2) do if alpha[1] = alpha[2] then
Add(labels, [alpha[1], '+']);
Add(labels, [alpha[1], '-']); elif alpha[1] < alpha[2] then
Add(labels, alpha); fi;
od;
return labels; end ],
centralizers:=
[ function(n, lbl) if not IsList(lbl[2]) then
return CentralizerWreath([2,2], [lbl[1], []]); else
return CentralizerWreath([2,2], lbl) / 2; fi; end ],
orders:=
[ function(n, lbl)
local ord;
ord:= 1; if lbl[1] <> [] then
ord:= Lcm(lbl[1]); fi; if lbl[2] <> [] and IsList(lbl[2]) then
ord:= Lcm(ord, 2*Lcm(lbl[2])); fi;
return ord; end ],
powermap:=
[ function(n, lbl, pow)
local power;
if not IsList(lbl[2]) then
power:= PowerPartition(lbl[1], pow); if ForAll(power, x-> x mod 2 = 0) then
return [1, [power, lbl[2]]]; # keep the sign. else
return [1, [power, []]]; fi; else if pow = 2then
return [1, PowerWreath([1, 1], lbl, 2)]; else
return [1, PowerWreath([1, 2], lbl, pow)]; fi; fi; end ],
irreducibles:=
[ [ function(n, alpha, pi)
local delta, val;
if not IsList(alpha[2]) then
delta:= [alpha[1], alpha[1]]; if not IsList(pi[2]) then
val:= CharTableWeylB!.irreducibles[1][1](n,
delta, [pi[1], []])/2; if alpha[2] = pi[2] then
val:= val + 2^(Length(pi[1])-1) *
CharTableSymmetric!.irreducibles[1][1](n/2,
alpha[1], pi[1]/2); else
val:= val - 2^(Length(pi[1])-1) *
CharTableSymmetric!.irreducibles[1][1](n/2,
alpha[1], pi[1]/2); fi; else
val:= CharTableWeylB!.irreducibles[1][1](n, delta, pi)/2; fi; else if not IsList(pi[2]) then
val:= CharTableWeylB!.irreducibles[1][1](n,
alpha, [pi[1], []]); else
val:= CharTableWeylB!.irreducibles[1][1](n, alpha, pi); fi; fi;
return val; end ] ],
domain:=
( n -> IsInt(n) and n > 1 )
) );
CharTableWeylD.matrix := function(n)
local matB, matA, paramA, paramB, clp, chp, ctb, cta, val;
matB := CharTableWeylB!.matrix(n); if n mod 2 = 0then
matA := CharTableSymmetric!.matrix(n/2);
paramA := Partitions(n/2); fi;
paramB := PartitionTuples(n, 2);
clp := CharTableWeylD!.classparam[1](n);
chp := CharTableWeylD!.charparam[1](n);
ctb := function(alpha, pi)
return matB[Position(paramB, alpha)][Position(paramB, pi)]; end;
cta := function(alpha, pi)
return matA[Position(paramA, alpha)][Position(paramA, pi)]; end;
val := function(alpha, pi)
local delta, val; if not IsList(alpha[2]) then
delta := [alpha[1], alpha[1]]; if not IsList(pi[2]) then
val := ctb(delta, [pi[1], []])/2; if alpha[2] = pi[2] then
val := val + 2^(Length(pi[1])-1) * cta(alpha[1], pi[1]/2); else
val := val - 2^(Length(pi[1])-1) * cta(alpha[1], pi[1]/2); fi; else
val := ctb(delta, pi)/2; fi; else if not IsList(pi[2]) then
val := ctb(alpha, [pi[1], []]); else
val := ctb(alpha, pi); fi; fi;
return val; end;
return List(chp, alpha-> List(clp, pi-> val(alpha, pi))); end;
MakeImmutable(CharTableWeylD);
############################################################################# ## #F CharacterValueWreathSymmetric( <tbl>, <n>, <beta>, <pi> ) . . #F . . . . character value in G wr Sn ##
InstallGlobalFunction( CharacterValueWreathSymmetric, function( sub, n, beta, pi )
local i, j, k, lb, o, s, t, r, gamma, rho, sign, val, subirreds;
# termination condition. if n = 0then
return 1; fi;
r:= Length(pi);
# negative cycles first.
t:= r; while pi[t] = [] do
t:= t-1;
od;
subirreds:= List( Irr( sub ), ValuesOfClassFunction );
# loop over the beta sets. for s in [1..r] do
# determine offset.
o:= 0;
lb:= Length(beta[s]); while o < lb and beta[s][o+1] = o do
o:= o+1;
od;
for i in beta[s] do if i >= k+o and not i-k in beta[s] then
# compute the leg parity.
sign:= 1; for j in [i-k+1..i-1] do if j in beta[s] then
sign:= -sign; fi;
od;
# consider character table <sub>.
sign:= subirreds[s][t] * sign;
# construct new beta set.
gamma:= ShallowCopy(beta);
gamma[s]:= ShallowCopy( gamma[s] );
RemoveSet( gamma[s], i );
AddSet(gamma[s], i-k);
# enter recursion.
val:= val +
sign * CharacterValueWreathSymmetric( sub, n-k, gamma, rho ); fi;
od;
od;
# return the result.
return val;
end );
############################################################################# ## #F CharacterTableWreathSymmetric( <sub>, <n> ) . . char. table of G wr Sn. ##
InstallGlobalFunction( CharacterTableWreathSymmetric, function( sub, n )
local i, j, # loop variables
tbl, # character table, result
ident, # identifier of 'tbl'
nccs, # no. of classes of 'sub'
nccl, # no. of classes of 'tbl'
parts, # partitions parametrizing classes and characters
subcentralizers, # centralizer orders of 'sub'
suborders, # representative orders of 'sub'
orders, # representative orders of 'tbl'
powermap, # power maps of 'tbl'
prime, # loop over prime divisors of the size of 'tbl'
spm; # one power map of 'sub'
if not IsOrdinaryTable( sub ) then
Error( "<sub> must be an ordinary character table" ); fi;
# Make a record, and set the values of `Size', `Identifier', \ldots
ident:= Concatenation( Identifier( sub ), "wrS", String(n) );
ConvertToStringRep( ident );
tbl:= rec( UnderlyingCharacteristic := 0,
Size := Size( sub )^n * Factorial( n ),
Identifier := ident );
# \ldots, `OrdersClassRepresentatives', \ldots
subcentralizers:= SizesCentralizers( sub );
suborders:= OrdersClassRepresentatives( sub );
orders:= []; for i in [1..nccl] do
orders[i]:= 1; for j in [1..nccs] do if parts[i][j] <> [] then
orders[i]:= Lcm(orders[i], suborders[j]*Lcm(parts[i][j])); fi;
od;
od;
tbl.OrdersClassRepresentatives:= orders;
# \ldots, `SizesCentralizers', `CharacterParameters', \ldots
tbl.SizesCentralizers:= List( parts,
p -> CentralizerWreath( subcentralizers, p ) );
tbl.CharacterParameters:= parts;
# \ldots, `ComputedPowerMaps', \ldots
tbl.ComputedPowerMaps:= [];
powermap:= tbl.ComputedPowerMaps; for prime in PrimeDivisors( tbl.Size ) do
spm:= PowerMap( sub, prime );
powermap[prime]:= MakeImmutable( List( [ 1 .. nccl ],
i -> Position(parts, PowerWreath(spm, parts[i], prime)) ) );
od;
# \ldots and `Irr'.
tbl.Irr:= MatCharsWreathSymmetric( sub, n );
# Return the table.
ConvertToLibraryCharacterTableNC( tbl );
return tbl; end );
############################################################################# ## #M Irr( <Sn> ) ## ## Use `CharTableSymmetric' (see above) for computing the irreducibles; ## use the class parameters (partitions) in order to make the table ## compatible with the conjugacy classes of <Sn>. ## ## Note that we do *not* call `CharacterTable( "Symmetric", <n> )' directly ## because the character table library may be not installed. ##
InstallMethod( Irr, "ordinary characters for natural symmetric group",
[ IsNaturalSymmetricGroup, IsZeroCyc ], function( G, zero )
local gentbl, dom, deg, cG, cp, perm, i, irr, pow, fun, p;
gentbl:= CharTableSymmetric;
dom:= MovedPoints( G );
deg:= Length( dom ); if deg = 0then
dom:= [ 1 ];
deg:= 1; fi;
cG:= CharacterTable( G );
# Compute the correspondence of classes. cp:= gentbl.classparam[1]( deg );
perm:= []; for i in ConjugacyClasses( G ) do
i:= List( Orbits( SubgroupNC( G, [ Representative(i) ] ), dom ),
Length );
Sort( i );
Add( perm, Position( cp, Reversed( i ) ) );
od;
# Store the class and character parameters. cp:= List( cp, x -> [ 1, x ] );
SetCharacterParameters( cG, MakeImmutable( cp ) ); cp:= cp{ perm };
SetClassParameters( cG, MakeImmutable( cp ) );
# Compute and store the power maps.
pow:= ComputedPowerMaps( cG );
fun:= gentbl.powermap[1]; for p in PrimeDivisors( Size( G ) ) do if not IsBound( pow[p] ) then
pow[p]:= MakeImmutable(
List( cp, x -> Position( cp, fun( deg, x[2], p ) ) ) ); fi;
od;
# Compute and store centralizer orders and representative orders. if not HasSizesCentralizers( cG ) then
SetSizesCentralizers( cG,
MakeImmutable( List( cp, x -> gentbl.centralizers[1]( deg, x[2] ) ) ) ); fi; if not HasOrdersClassRepresentatives( cG ) then
SetOrdersClassRepresentatives( cG,
MakeImmutable( List( cp, x -> gentbl.orders[1]( deg, x[2] ) ) ) ); fi;
SetInfoText( cG, MakeImmutable( Concatenation( "computed using ", gentbl.text ) ) );
# Return the irreducibles.
return irr; end );
############################################################################# ## #M Irr( <An> ) ## ## Use `CharTableAlternating' (see above) for computing the irreducibles; ## use the class parameters in order to make the table ## compatible with the conjugacy classes of <An>. ## (Note that the pairs of classes obtained by splitting classes of the ## symmetric group can be chosen independently.) ## ## Note that we do *not* call `CharacterTable( "Alternating", <n> )' directly ## because the character table library may be not installed. ##
InstallMethod( Irr, "ordinary characters for natural alternating group",
[ IsNaturalAlternatingGroup, IsZeroCyc ], function( G, zero )
local dom, deg, cG, gentbl, whole, cp, perm, i, pos, irr, pow, known, inv;
dom:= MovedPoints( G );
deg:= Length( dom ); if deg = 0then
dom:= [ 1 ];
deg:= 1; fi;
cG:= CharacterTable( G );
# Compute the character table information.
gentbl:= CharTableAlternating;
whole:= gentbl.wholetable( gentbl, deg );
# Compute the correspondence of classes. cp:= List( whole.ClassParameters, x -> x[2] );
perm:= []; for i in ConjugacyClasses( cG ) do
i:= List( Orbits( SubgroupNC( G, [ Representative(i) ] ), dom ),
Length );
Sort( i );
i:= Reversed( i );
pos:= Position( cp, i ); if pos = fail then # splitting class
pos:= Position( cp, [ i, '+' ] ); if pos in perm then
pos:= Position( cp, [ i, '-' ] ); fi; fi;
Add( perm, pos );
od;
# Adjust and store the class and character parameters.
SetClassParameters( cG, MakeImmutable( whole.ClassParameters{ perm } ) );
SetCharacterParameters( cG, MakeImmutable( whole.CharacterParameters ) );
# Adjust and store the power maps.
pow:= ComputedPowerMaps( cG );
known:= whole.ComputedPowerMaps;
inv:= InverseMap( perm ); for i in [ 1 .. Length( known ) ] do if IsBound( known[i] ) and not IsBound( pow[i] ) then
pow[i]:= MakeImmutable( inv{ known[i]{ perm } } ); fi;
od;
# Compute and store centralizer orders and representative orders. if not HasSizesCentralizers( cG ) then
SetSizesCentralizers( cG, MakeImmutable( whole.SizesCentralizers{ perm } ) ); fi; if not HasOrdersClassRepresentatives( cG ) then
SetOrdersClassRepresentatives( cG, MakeImmutable( whole.OrdersClassRepresentatives{ perm } ) ); fi;
SetInfoText( cG, MakeImmutable( whole.InfoText ) );
# Return the irreducibles.
return irr; end );
############################################################################# ## #F DescendingListWithElementRemoved( <list>, <el> ) ## ## For a list <list> whose elements are descending and an element <el> of ## <list>, `DescendingListWithElementRemoved' returns the descending list ## obtained by removing <el>. ##
BindGlobal( "DescendingListWithElementRemoved", function( list, el )
local pos, res;
pos:= PositionSorted( list, el, function( a, b ) return \<( b, a ); end );
res:= list{ [ 1 .. pos-1 ] };
Append( res, list{ [ pos+1 .. Length( list ) ] } );
return res; end );
############################################################################# ## #F MorrisRecursion( <lambda>, <pi> ) ## ## For a bar partition <lambda> of $n$, for some positive integer $n$, ## and an odd parts partition <pi> of the same $n$ and different from ## <lambda>, `MorrisRecursion' returns the value of the spin character ## indexed by <lambda> on the class indexed by <pi>. ## If the class of <pi> splits in the double cover of the symmetric group of ## degree $n$ then the returned value is attained on the class containing ## the Schur standard lift of <pi>. ##
DeclareGlobalFunction( "MorrisRecursion" );
InstallGlobalFunction( MorrisRecursion, function( lambda, pi )
local n, sigma, k, P, i, j, rho, val, GT, sign, m, gamma, l;
# degree case if k = 1then # calc degree
P:= 2^sigma * Factorial( n ); for i in [ 1 .. Length( lambda ) ] do for j in [ i+1 .. Length( lambda ) ] do
P:= ( lambda[i] - lambda[j] ) / ( lambda[i] + lambda[j] ) * P;
od;
P:= P / Factorial( lambda[i] );
od;
return P; fi;
rho:= pi{ [ 2 .. Length( pi ) ] };
val:= 0;
GT:= function( a, b ) return LT( b, a ); end;
for i in lambda do if i >= k and not i-k in lambda then
# leg parity
sign:= 1; for j in [ i-k+1 .. i-1 ] do if j in lambda then
sign:= -sign; fi;
od;
# 2 power
m:= 1;
if i > k then if IsEvenInt( n - Length( lambda ) ) then
m:= 2; fi; fi;
# compute new lambda
gamma:= DescendingListWithElementRemoved( lambda, i ); if i > k then
Add( gamma, i-k );
Sort( gamma, GT ); fi;
val:= val + sign * m * MorrisRecursion( gamma, rho ); fi;
#I_- removal if i <= (k - 1) / 2 and k - i in lambda then
# calc. leg parity by pos. of smaller bead plus no. of beads # between conj. beads
sign:= (-1)^i; for l in [ i+1 .. k-1-i ] do if l in lambda then
sign:= -sign; fi;
od;
# 2 power
m:= 1; if IsEvenInt( n - Length( lambda ) ) then
m:= 2; fi;
# compute new lambda
gamma:= DescendingListWithElementRemoved( lambda, i );
gamma:= DescendingListWithElementRemoved( gamma, k-i );
# enter recursion
val:= val + sign * m * MorrisRecursion( gamma, rho ); fi;
od;
# return the result
return val; end );
############################################################################# ## #F CharValueDoubleCoverSymmetric( <n>, <lambda>, <pi> ) ## ## For a bar partition <lambda> and a partition <pi> of the positive integer ## <n>, `CharValueDoubleCoverSymmetric' returns the value of the spin ## character of the standard Schur double cover of the symmetric group of ## degree <n> that is indexed by <lambda>, on the class that is indexed by ## <pi>. ##
BindGlobal( "CharValueDoubleCoverSymmetric", function( n, lambda, pi ) if IsEvenInt( n - Length( pi ) ) then# pi is even if not ForAll( pi, IsOddInt ) then# pi is not in O(n)
return 0; else# pi is in O(n)
return MorrisRecursion( lambda, pi ); fi; else# pi is odd if Length( Set( pi ) ) <> Length( pi ) then
return 0; else# pi is bar partition if IsEvenInt( n - Length( lambda ) ) or lambda <> pi then
return 0; else# exceptional case
return E(4)^( ( n - Length( lambda ) + 1 ) / 2 )
* ER( Product( lambda ) / 2 ); fi; fi; fi; end );
########################################################################## ## #F BarPartitions( <n> ) ## ## For a non-negative integer <n>, `BarPartitions' returns the list of all ## bar partitions of <n>. ##
BindGlobal( "BarPartitions", function( n )
local B, j, k, l, p;
B:= List( [ 1 .. n-2 ], x -> [] ); for k in [ 1 .. QuoInt( n-1, 2 ) ] do
j:= n-k-1; while j >= k+1do for p in B[ j-k ] do
l:= [ n-j ];
Append( l, p );
l[2]:= k;
Add( B[j], l );
od;
j:= j - 1;
od;
Add( B[k], [ n-k, k ] );
od;
l:= Concatenation( B{ [ n-2, n-3 .. 1 ] } );
Add( l, [ n ] );
return l; end );
########################################################################### ## #F SpinInductionScheme( <n> ) ## ## For a non-negative integer <n>, `SpinInductionScheme' returns the spin ## induction scheme for <n>. ## The entry at position $[m][i][k]$ is the list of positions (with mult.) ## of all bar partitions of $m-k$ that are obtained by removing a $k$ bar ## from the $i$-th bar partition of $m$. ##
BindGlobal( "SpinInductionScheme", function( n )
local GT, bpm, scheme, bars, i, lambda;
GT:= function( a, b ) return LT( b, a ); end;
bpm:= []; # bar partitions of m
scheme:= [];
bars:= function( lambda )
local m, brs, i, z, sign, max, j, gamma, l;
m:= Sum( lambda );
brs:= []; # init bar list, for every possible bar length a list for i in [ 1 .. m ] do
brs[i]:= [];
od;
z:= 1; if ( m - Length( lambda ) ) mod 2 = 0then
z:= 2; fi;
for i in lambda do
sign:= 1; for j in [ 1 .. i ] do if i-j in lambda then
sign:= -sign; elif j mod 2 = 1then if j = m then if i <> j then
Add( brs[m], [ 1, sign * z ] ); else
Add( brs[m], [ 1, sign ] ); # case I_0, no 2 fi; else
gamma:= DescendingListWithElementRemoved( lambda, i ); if i <> j then
Add( gamma, i-j );
Sort( gamma, GT );
Add( brs[j], [ Position( bpm[m-j], gamma ), sign*z ] ); else # case I_0, no 2
Add( brs[j], [ Position( bpm[m-j], gamma ), sign ] ); fi; fi; fi;
od;
od;
#I- removal
max:= m; if max mod 2 = 0then
max:= max-1; fi; for j in [ 3, 5 .. max ] do#j-bar removal from partition lambda for i in [ 1 .. (j-1)/2 ] do if i in lambda and j-i in lambda then if j = m then
sign:= (-1)^i;
Add( brs[m], [ 1, sign*z ] ); else # calc leg parity by pos. of smaller bead plus no. of beads # between conj. beads
sign:= (-1)^i; for l in [ i+1 .. j-1-i ] do if l in lambda then
sign:= -sign; fi;
od;
gamma:= DescendingListWithElementRemoved( lambda, i );
gamma:= DescendingListWithElementRemoved( gamma, j-i );
for i in [ 1 .. n ] do
bpm[i]:= BarPartitions( i );
scheme[i]:= []; for lambda in bpm[i] do
Add( scheme[i], bars( lambda ) );
od;
od;
return scheme; end );
######################################################################## ## #F OddSpinVals( <n> ) ## ## For a non-negative integer <n>, `OddSpinVals' returns a matrix that ## contains the values of the spin characters of the standard double cover ## of the symmetric group of degree <n>, ## where it is assumed that the columns are indexed by odd part partitions. ##
BindGlobal( "OddSpinVals", function( n )
local scheme, charCol, pm, m, k, t, np, res, col, i, max;
scheme:= SpinInductionScheme( n );
charCol:= function( m, t, k) # t column of the char. table of S_{m-k}
local i, col, pi, val;
col:= []; for pi in scheme[m] do
val:= 0; for i in pi[k] do
val:= val + i[2] * t[ i[1] ];
od;
Add( col, val );
od;
return col; end;
pm:= List( [ 1 .. n-1 ], x -> [] );
max:= QuoInt( n, 2 ); if max mod 2 = 0then
max:= max - 1; fi; for m in [ 1, 3 .. max ] do# only odd parts can be removed
Add( pm[m], charCol( m, [1], m ) ); for k in [ m+1 .. n-m ] do for t in pm[ k-m ] do
Add( pm[k], charCol( k, t, m ) );
od;
od;
od;
np:= Length( scheme[n] );
res:= List( [ 1 .. np ], x -> [] ); for k in [ 1 .. n-1 ] do if k mod 2 = 1then for t in pm[ n-k ] do
col:= charCol( n, t, k ); for i in [ 1 .. np ] do
Add( res[i], col[i] );
od;
od; fi;
od;
col:= charCol( n, [1], n ); for i in [ 1 .. np ] do
Add( res[i], col[i] );
od;
return res; end );
###################################################################### ## #F MatrixSpinCharsSn( <n> ) ## ## For a non-negative integer <n>, `MatrixSpinCharsSn' returns the matrix ## of spin characters of the standard Schur double cover of the symmetric ## group of degree <n>. ##
BindGlobal( "MatrixSpinCharsSn", function( n )
local matrix, pars, bars, oddvals, i, char, achar, counter, pi;
matrix:= [];
pars:= GPartitions( n );
bars:= BarPartitions( n );
oddvals:= OddSpinVals( n );
for i in [ 1 .. Length( bars ) ] do
char:= [];
achar:= [];
counter:= 1;
for pi in pars do if ForAll( pi, IsOddInt ) then
Add( char, oddvals[i][ counter ] );
Add( char, -oddvals[i][ counter ] );
Add( achar, oddvals[i][ counter ] );
Add( achar, -oddvals[i][ counter ] );
counter:= counter+1;
elif IsOddInt( n - Length( bars[i] ) ) and bars[i] = pi then
Add( char, E(4)^( ( n - Length( bars[i] ) + 1 ) / 2 )
* ER( Product( bars[i] ) / 2 ) );
Add( char, -Last( char ) );
else
Add( char, 0 );
Add( achar, 0 ); if Length( Set( pi ) ) = Length( pi )
and IsOddInt( n-Length(pi) ) then
Add( char, 0 );
Add( achar,0 ); fi;
fi;
od;
Add( matrix, char ); if IsOddInt( n-Length(bars[i]) ) then
Add( matrix, achar ); fi;
od;
return matrix; end );
################################################################################ ## #F OrderOfSchurLift( <pi> ) ## ## For a partition <pi>, `OrderOfSchurLift' returns the order of the Schur ## standard lift of an element of cycle type <pi> in a symmetric group ## to the standard double cover. ##
BindGlobal( "OrderOfSchurLift", function( pi )
local ord, evencount, z, i;
ord:= Lcm( pi );
evencount:= 0;
z:= 1; for i in pi do if i mod 2 = 1then if QuoInt( i^2-1, 8 ) mod 2 = 1 and QuoInt( ord, i ) mod 2 = 1then
z:= -z; fi; else
evencount:= evencount + 1; if ( QuoInt( i, 2 ) mod 4 = 1 or QuoInt( i, 2 ) mod 4 = 2 ) and
QuoInt( ord, i ) mod 2 = 1then
z:= -z; fi; fi;
od;
if ( evencount mod 4 = 2 or evencount mod 4 = 3 ) and
QuoInt( ord, 2 ) mod 2 = 1then
z:= -z; fi;
if z = -1then
return 2*ord; else
return ord; fi; end );
########################################################################### ## #V CharTableDoubleCoverSymmetric ##
BindGlobal( "CharTableDoubleCoverSymmetric", MakeImmutable ( rec(
isGenericTable:=
true,
identifier:= "DoubleCoverSymmetric",
size:=
( n -> 2 * Factorial( n ) ),
specializedname:=
( n -> Concatenation( "2.Sym(", String(n), ")" ) ),
text:= "generic character table for a double cover of symmetric groups",
wholetable:= function( gtab, n )
local parts, nrparts, dist, distmin, odd, clpar, chpar,
fus, ord, cen, i, p, m, o, c, nrch, nrcl, invfus,
chars, pow, j, irr;
for i in [ 1 .. nrparts ] do
p:= parts[i];
m:= Length( p );
Add( clpar, [ 1, p ] );
Add( fus, i );
o:= OrderOfSchurLift( p );
Add( ord, o );
c:= CharTableSymmetric.centralizers[1]( n, p );
if ForAll( p, IsOddInt ) then# class splits
Add( odd, i );
Add( clpar, [ 2, p ] );
Add( fus, i ); if IsOddInt( o ) then
Add( ord, 2 * o ); else
Add( ord, o / 2 ); fi;
c:= 2 * c;
Add( cen, c ); fi;
if Length( Set( p ) ) = Length( p ) then
Add( dist, i );
Add( chpar, p ); if IsOddInt( n-m ) then# class splits
Add( distmin, i );
Add( chpar, p );
Add( clpar, [ 2, p ] );
Add( fus, i );
Add( ord, o );
c:= 2 * c;
Add( cen, c ); fi; fi;
Add( cen, c );
od;
# power maps
pow:= []; for p in Filtered( [ 2 .. n ], IsPrimeInt ) do
pow[p]:= [ 1 .. nrcl ] ; for i in [1 .. nrcl ] do
j:= invfus[ Position( parts,
PowerPartition( parts[ fus[i] ], p ) ) ]; if IsInt( j ) then
pow[p][i]:= j; else
o:= ord[i]; if ( o mod p = 0 ) then
o:= o / p; fi; if ord[j[1]] <> o then
pow[p][i]:= j[2]; elif ord[j[2]] <> o then
pow[p][i]:= j[1]; else
c:= Position( chpar, parts[ fus[i] ] ); if GaloisCyc( chars[c][i], p ) = chars[c][ j[1] ] then
pow[p][i]:= j[1]; else
pow[p][i]:= j[2]; fi; fi; fi;
od;
MakeImmutable( pow[p] );
od;
# Make the character parameters unique. for i in [ 2 .. Length( chpar ) ] do if chpar[i] = chpar[i-1] then
chpar[i-1] := [ chpar[i], '+' ];
chpar[i] := [ chpar[i], '-' ]; fi;
od;
# the spin character table record
return rec( Identifier := Concatenation( "2.Sym(", String(n), ")" ),
UnderlyingCharacteristic:= 0,
ClassParameters:= clpar,
CharacterParameters:= Concatenation(
List( parts, x -> [ 1, x ] ),
List( chpar, x -> [ 2, x ] ) ),
Size:= 2 * Factorial( n ),
NrConjugacyClasses:= nrcl,
SizesCentralizers:= cen,
ComputedPowerMaps:= pow,
OrdersClassRepresentatives:= ord,
ComputedClassFusions:=
[ rec( name:= Concatenation("Sym(",String(n),")"),
map:= MakeImmutable( fus ) ) ],
Irr:= MakeImmutable( Concatenation(
CharTableSymmetric.matrix( n )
{ [ 1 .. nrparts ] }{ fus }, chars ) ) ); end,
domain:= IsPosInt ) ) );
############################################################################# ## #V CharTableDoubleCoverAlternating ##
BindGlobal( "CharTableDoubleCoverAlternating", MakeImmutable( rec(
isGenericTable:=
true,
identifier:= "DoubleCoverAlternating",
size:=
Factorial,
specializedname:=
( n -> Concatenation( "2.Alt(", String(n), ")" ) ),
text:= "generic character table for the double cover of alternating groups",
matrix:= function( n )
local matrix, pars, bars, oddvals, evenpars, i, char1, char2,
counter, pi, delta, alpha, beta;
matrix:= [];
pars:= GPartitions( n );
bars:= BarPartitions( n );
oddvals:= OddSpinVals( n );
evenpars:= Filtered( pars, pi -> IsEvenInt( n - Length( pi ) ) );
for i in [ 1 .. Length( bars ) ] do
char1:= [];
char2:= [];
counter:=1; for pi in evenpars do
if IsEvenInt( n - Length( bars[i] ) ) then# 2 conj characters
delta:=0;
if ForAll( pi, IsOddInt ) then
if bars[i] = pi then
delta:= E(4)^( QuoInt( n - Length( pi ), 2 ) mod 4 )
* ER( Product( pi ) ); fi;
# power maps
pow:= []; for p in Filtered( [ 2 .. n ], IsPrimeInt ) do
pow[p]:= [ 1 .. nrcl ]; for i in [ 1 .. nrcl ] do
j:= Position( parts, PowerPartition( parts[ fus0[i] ], p ) );
k:= invfus0[j]; if IsInt( k ) then
pow[p][i]:= k; else
o:= ord[i]; if ( o mod p = 0 ) then
o:= o / p; fi; if j in odd then if j in distpos then if ord[ k[1] ] <> o then
k:= k{ [ 2, 4 ] }; else
k:= k{ [ 1, 3 ] }; fi;
c:= Position( chpar, parts[ fus0[i] ] );
val:= GaloisCyc( chars[c][i], p ); if IsCycInt( ( val-chars[c][ k[1] ] ) / p ) then
pow[p][i]:= k[1]; else
pow[p][i]:= k[2]; fi; else if ord[ k[1] ] <> o then
pow[p][i]:= k[2]; else
pow[p][i]:= k[1]; fi; fi; else
c:= Position( chpar, parts[ fus0[i] ] ); if GaloisCyc( chars[c][i], p ) = chars[c][ k[1] ] then
pow[p][i]:= k[1]; else
pow[p][i]:= k[2]; fi; fi; fi;
od;
MakeImmutable( pow[p] );
od;
# add the characters of Alt_n
tbl:= CharTableAlternating.wholetable( CharTableAlternating, n );
# Make the class and character parameters unique.
clpar:= tbl.ClassParameters{ fus1 }; for i in [ 2 .. Length( clpar ) ] do if fus1[i] = fus1[i-1] then
clpar[i]:= ShallowCopy( clpar[i] );
clpar[i][1]:= 2; fi;
od; for i in [ 2 .. Length( chpar ) ] do if chpar[i] = chpar[i-1] then
chpar[i-1] := [ chpar[i], '+' ];
chpar[i] := [ chpar[i], '-' ]; fi;
od;
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.57Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-10-12)
¤
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.