Skip to content

Commit

Permalink
Add ListWreathProductElement and WreathProductElementList
Browse files Browse the repository at this point in the history
Add implementations of these operations for the following wreath products:
	- perm wreath product in imprimitive action
	- perm wreath product in product action
	- matrix wreath product
	- generic wreath product

Add documentation and tests for these operations.
  • Loading branch information
FriedrichRober authored and fingolfin committed Jun 16, 2021
1 parent 718887b commit 80a51fd
Show file tree
Hide file tree
Showing 6 changed files with 482 additions and 0 deletions.
2 changes: 2 additions & 0 deletions doc/ref/grpprod.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ has to be taken.)
<#Include Label="WreathProductImprimitiveAction">
<#Include Label="WreathProductProductAction">
<#Include Label="KuKGenerators">
<#Include Label="ListWreathProductElement">
<#Include Label="WreathProductElementList">

</Section>

Expand Down
63 changes: 63 additions & 0 deletions lib/gprd.gd
Original file line number Diff line number Diff line change
Expand Up @@ -566,3 +566,66 @@ InstallTrueMethod(IsGeneratorsOfMagmaWithInverses,

DeclareRepresentation("IsWreathProductElementDefaultRep",
IsWreathProductElement and IsPositionalObjectRep,[]);

#############################################################################
##
#F ListWreathProductElement
#O ListWreathProductElementNC
##
## <#GAPDoc Label="ListWreathProductElement">
## <ManSection>
## <Func Name="ListWreathProductElement" Arg='G, x[, testDecomposition]'/>
## <Oper Name="ListWreathProductElementNC" Arg='G, x, testDecomposition'/>
##
## <Description>
## Let <A>x</A> be an element of a wreath product <A>G</A>
## where <M>G = K \wr H</M> and <M>H</M> acts
## as a finite permutation group of degree <M>m</M>.
## We can identify the element <A>x</A> with a tuple <M>(f_1, \ldots, f_m; h)</M>,
## where <M>f_i \in K</M> is the <M>i</M>-th base component of <A>x</A>
## and <M>h \in H</M> is the top component of <A>x</A>.
## <P/>
## <Ref Func="ListWreathProductElement"/> returns a list <M>[f_1, \ldots, f_m, h]</M>
## containing the components of <A>x</A> or <K>fail</K> if <A>x</A> cannot be decomposed in the wreath product.
## <P/>
## If ommited, the argument <A>testDecomposition</A> defaults to true.
## If <A>testDecomposition</A> is true, <Ref Func="ListWreathProductElement"/> makes additional tests to ensure
## that the computed decomposition of <A>x</A> is correct,
## i.e. it checks that <A>x</A> is an element of the parent wreath product of <A>G</A>:
## <P/>
## If <M>K \leq \mathop{Sym}(l)</M>, this ensures that <M>x \in \mathop{Sym}(l) \wr \mathop{Sym}(m)</M>
## where the parent wreath product is considered in the same action as <A>G</A>,
## i.e. either in imprimitive action or product action.
## <P/>
## If <M>K \leq \mathop{GL}(n,q)</M>, this ensures that <M>x \in \mathop{GL}(n,q) \wr \mathop{Sym}(m)</M>.
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction( "ListWreathProductElement" );
DeclareOperation( "ListWreathProductElementNC", [HasWreathProductInfo, IsObject, IsBool] );

#############################################################################
##
#F WreathProductElementList
#O WreathProductElementListNC
##
## <#GAPDoc Label="WreathProductElementList">
## <ManSection>
## <Func Name="WreathProductElementList" Arg='G, list'/>
## <Oper Name="WreathProductElementListNC" Arg='G, list'/>
##
## <Description>
## Let <A>list</A> be equal to <M>[f_1, \ldots, f_m, h]</M> and <A>G</A> be a wreath product
## where <M>G = K \wr H</M>, <M>H</M> acts
## as a finite permutation group of degree <M>m</M>,
## <M>f_i \in K</M> and <M>h \in H</M>.
## <P/>
## <Ref Func="WreathProductElementList"/> returns the element <M>x \in G</M>
## identified by the tuple <M>(f_1, \ldots, f_m; h)</M>.
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction( "WreathProductElementList" );
DeclareOperation( "WreathProductElementListNC", [HasWreathProductInfo, IsList] );
67 changes: 67 additions & 0 deletions lib/gprd.gi
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,73 @@ local I,n,fam,typ,gens,hgens,id,i,e,info,W,p,dom;

end);

#############################################################################
##
#M ListWreathProductElement(<G>, <x>[, <testMembership>])
##
InstallGlobalFunction( ListWreathProductElement,
function(G, x, testDecomposition...)
local info;
if Length(testDecomposition) = 0 then
testDecomposition := true;
elif Length(testDecomposition) = 1 then
testDecomposition := testDecomposition[1];
elif Length(testDecomposition) > 1 then
ErrorNoReturn("too many arguments");
fi;
if not HasWreathProductInfo(G) then
ErrorNoReturn("usage: <G> must be a wreath product");
fi;
return ListWreathProductElementNC(G, x, testDecomposition);
end);

InstallMethod( ListWreathProductElementNC, "generic wreath product", true,
[ HasWreathProductInfo, IsWreathProductElement, IsBool ], 0,
function(G, x, testDecomposition)
local info, list, i;
info := WreathProductInfo(G);
list := EmptyPlist(info!.degI + 1);
for i in [1 .. info!.degI + 1] do
list[i] := StructuralCopy(x![i]);
od;
return list;
end);

#############################################################################
##
#M WreathProductElementList(<G>, <list>)
##
InstallGlobalFunction( WreathProductElementList,
function(G, list)
local info, i;

if not HasWreathProductInfo(G) then
ErrorNoReturn("usage: <G> must be a wreath product");
fi;
info := WreathProductInfo(G);
if Length(list) <> info.degI + 1 then
ErrorNoReturn("usage: <list> must have ",
"length 1 + <WreathProductInfo(G).degI>");
fi;
for i in [1 .. info.degI] do
if not list[i] in info.groups[1] then
ErrorNoReturn("usage: <list{[1 .. Length(list) - 1]}> must contain ",
"elements of <WreathProductInfo(G).groups[1]>");
fi;
od;
if not list[info.degI + 1] in info.groups[2] then
ErrorNoReturn("usage: <list[Length(list)]> must be ",
"an element of <WreathProductInfo(G).groups[2]>");
fi;
return WreathProductElementListNC(G, list);
end);

InstallMethod( WreathProductElementListNC, "generic wreath product", true,
[ HasWreathProductInfo, IsList ], 0,
function(G, list)
return Objectify(FamilyObj(One(G))!.defaultType, StructuralCopy(list));
end);

#############################################################################
##
#M PrintObj(<x>)
Expand Down
59 changes: 59 additions & 0 deletions lib/gprdmat.gi
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,65 @@ local info, degI, dimA, zero, projFunc;
return info.projection;
end);

#############################################################################
##
#M ListWreathProductElementNC( <G>, <x> )
##
InstallMethod( ListWreathProductElementNC, "matrix wreath product", true,
[ IsMatrixGroup and HasWreathProductInfo, IsObject, IsBool], 0,
function(G, x, testDecomposition)
local info, degI, dimA, h, list, i, j, k, zeroMat;

info := WreathProductInfo(G);
degI := info.degI;
dimA := info.dimA;

# The top group element
h := x ^ Projection(G);
if h = fail then
return fail;
fi;
list := EmptyPlist(degI + 1);
list[degI + 1] := h;
if testDecomposition then
# ZeroMatrix does not accept IsPlistRep
if IsPlistRep(x) then
zeroMat := NullMat(dimA, dimA, info.field);
else
zeroMat := ZeroMatrix(dimA, dimA, x);
fi;
fi;
for i in [1 .. degI] do
j := i ^ h;
list[i] := ExtractSubMatrix(x, [dimA * (i - 1) + 1 .. dimA * i], [dimA * (j - 1) + 1 .. dimA * j]);
if testDecomposition then
for k in [1 .. degI] do
if k = j then
continue;
fi;
if ExtractSubMatrix(x, [dimA * (i - 1) + 1 .. dimA * i], [dimA * (k - 1) + 1 .. dimA * k]) <> zeroMat then
return fail;
fi;
od;
fi;
od;
return list;
end);

#############################################################################
##
#M WreathProductElementListNC(<G>, <list>)
##
InstallMethod( WreathProductElementListNC, "matrix wreath product", true,
[ IsMatrixGroup and HasWreathProductInfo, IsList ], 0,
function(G, list)
local info;

info := WreathProductInfo(G);
# TODO: Remove `MatrixByBlockMatrix` when `BlockMatrix` supports the MatObj interface.
return MatrixByBlockMatrix(BlockMatrix(List([1 .. info.degI], i -> [i, i ^ list[info.degI + 1], list[i]]), info.degI, info.degI));
end);

# tensor wreath -- dimension d^e This is not a faithful representation of
# the tensor product if the matrix group has a center.
DeclareGlobalFunction("TensorWreathProduct");
Expand Down
76 changes: 76 additions & 0 deletions lib/gprdperm.gi
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,82 @@ local info, proj, H, degI, degK, constPoints, projFunc;
return proj;
end);

#############################################################################
##
#M ListWreathProductElementNC( <G>, <x> )
##
InstallMethod( ListWreathProductElementNC, "perm wreath product", true,
[ IsPermGroup and HasWreathProductInfo, IsObject, IsBool ], 0,
function(G, x, testDecomposition)
local info, list, h, f, degK, i, j, constPoints, imageComponents, comp, restPerm;

info := WreathProductInfo(G);
# The top group element
h := x ^ Projection(G);
if h = fail then
return fail;
fi;
# The product of the base group elements
f := x * Image(Embedding(G, info.degI + 1), h) ^ (-1);
list := EmptyPlist(info!.degI + 1);
list[info.degI + 1] := h;
# Imprimitive Action, tuple (i, j) corresponds
# to point i + degK * (j - 1)
if IsBound(info.permimpr) and info.permimpr then
for i in [1 .. info.degI] do
restPerm := RESTRICTED_PERM(f, info.components[i], testDecomposition);
if restPerm = fail then
return fail;
fi;
list[i] := restPerm ^ info.perms[i];
od;
# Primitive Action, tuple (t_1, ..., t_degI) corresponds
# to point Sum_{i=1}^degI t_i * degK ^ (i - 1)
elif IsBound(info.productType) and info.productType then
degK := NrMovedPoints(info.groups[1]);
# constPoints correspond to [1, 1, 1, ...], [2, 2, 2, ...], ...
constPoints := List([0 .. degK - 1], i -> Sum([0 .. info.degI - 1],
j -> i * degK ^ j)) + 1;
# imageComponents = [ [1 ^ f_1, 1 ^ f_2, 1 ^ f_3, ...],
# [2 ^ f_1, 2 ^ f_2, 2 ^ f_3, ...], ... ]
imageComponents := List(OnTuples(constPoints, f) - 1,
p -> CoefficientsQadic(p, degK) + 1);
# The qadic expansion has no "trailing" zeros. Thus we need to append them.
# For example if (1, ..., 1) ^ (f_1, ..., f_m) = (1, ..., 1),
# we have imageComponents[1] = CoefficientsQadic(0, degK) + 1 = [].
# Note that we append 1's instead of 0's,
# since we already transformed the result of the qadic expansion
# from [{0, ..., degK - 1}, ...] to [{1, ..., degK}, ...].
for i in [1 .. degK] do
comp := imageComponents[i];
Append(comp, ListWithIdenticalEntries(info.degI - Length(comp), 1));
od;
for j in [1 .. info.degI] do
list[j] := PermList(List([1 .. degK], i -> imageComponents[i,j]));
if list[j] = fail then
return fail;
fi;
od;
else
ErrorNoReturn("Error: cannot determine which action ",
"was used for wreath product");
fi;
return list;
end);

#############################################################################
##
#M WreathProductElementListNC(<G>, <list>)
##
InstallMethod( WreathProductElementListNC, "perm wreath product", true,
[ IsPermGroup and HasWreathProductInfo, IsList ], 0,
function(G, list)
local info;

info := WreathProductInfo(G);
return Product(List([1 .. info.degI + 1], i -> list[i] ^ Embedding(G, i)));
end);

#############################################################################
##
#F WreathProductProductAction( <G>, <H> ) wreath product in product action
Expand Down
Loading

0 comments on commit 80a51fd

Please sign in to comment.