diff --git a/doc/ref/grpprod.xml b/doc/ref/grpprod.xml
index 2255c64166..a94cf8cac5 100644
--- a/doc/ref/grpprod.xml
+++ b/doc/ref/grpprod.xml
@@ -118,6 +118,8 @@ has to be taken.)
<#Include Label="WreathProductImprimitiveAction">
<#Include Label="WreathProductProductAction">
<#Include Label="KuKGenerators">
+<#Include Label="ListWreathProductElement">
+<#Include Label="WreathProductElementList">
diff --git a/lib/gprd.gd b/lib/gprd.gd
index 6fb5c5d8bb..5403952a04 100644
--- a/lib/gprd.gd
+++ b/lib/gprd.gd
@@ -566,3 +566,66 @@ InstallTrueMethod(IsGeneratorsOfMagmaWithInverses,
DeclareRepresentation("IsWreathProductElementDefaultRep",
IsWreathProductElement and IsPositionalObjectRep,[]);
+
+#############################################################################
+##
+#F ListWreathProductElement
+#O ListWreathProductElementNC
+##
+## <#GAPDoc Label="ListWreathProductElement">
+##
+##
+##
+##
+##
+## Let x be an element of a wreath product G
+## where G = K \wr H and H acts
+## as a finite permutation group of degree m.
+## We can identify the element x with a tuple (f_1, \ldots, f_m; h),
+## where f_i \in K is the i-th base component of x
+## and h \in H is the top component of x.
+##
+## returns a list [f_1, \ldots, f_m, h]
+## containing the components of x or fail if x cannot be decomposed in the wreath product.
+##
+## If ommited, the argument testDecomposition defaults to true.
+## If testDecomposition is true, makes additional tests to ensure
+## that the computed decomposition of x is correct,
+## i.e. it checks that x is an element of the parent wreath product of G:
+##
+## If K \leq \mathop{Sym}(l), this ensures that x \in \mathop{Sym}(l) \wr \mathop{Sym}(m)
+## where the parent wreath product is considered in the same action as G,
+## i.e. either in imprimitive action or product action.
+##
+## If K \leq \mathop{GL}(n,q), this ensures that x \in \mathop{GL}(n,q) \wr \mathop{Sym}(m).
+##
+##
+## <#/GAPDoc>
+##
+DeclareGlobalFunction( "ListWreathProductElement" );
+DeclareOperation( "ListWreathProductElementNC", [HasWreathProductInfo, IsObject, IsBool] );
+
+#############################################################################
+##
+#F WreathProductElementList
+#O WreathProductElementListNC
+##
+## <#GAPDoc Label="WreathProductElementList">
+##
+##
+##
+##
+##
+## Let list be equal to [f_1, \ldots, f_m, h] and G be a wreath product
+## where G = K \wr H, H acts
+## as a finite permutation group of degree m,
+## f_i \in K and h \in H.
+##
+## returns the element x \in G
+## identified by the tuple (f_1, \ldots, f_m; h).
+##
+##
+## <#/GAPDoc>
+##
+DeclareGlobalFunction( "WreathProductElementList" );
+DeclareOperation( "WreathProductElementListNC", [HasWreathProductInfo, IsList] );
diff --git a/lib/gprd.gi b/lib/gprd.gi
index 398c4fc8ff..06ab2d7a0d 100644
--- a/lib/gprd.gi
+++ b/lib/gprd.gi
@@ -896,6 +896,73 @@ local I,n,fam,typ,gens,hgens,id,i,e,info,W,p,dom;
end);
+#############################################################################
+##
+#M ListWreathProductElement(, [, ])
+##
+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: 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(, )
+##
+InstallGlobalFunction( WreathProductElementList,
+function(G, list)
+ local info, i;
+
+ if not HasWreathProductInfo(G) then
+ ErrorNoReturn("usage: must be a wreath product");
+ fi;
+ info := WreathProductInfo(G);
+ if Length(list) <> info.degI + 1 then
+ ErrorNoReturn("usage: must have ",
+ "length 1 + ");
+ fi;
+ for i in [1 .. info.degI] do
+ if not list[i] in info.groups[1] then
+ ErrorNoReturn("usage: must contain ",
+ "elements of ");
+ fi;
+ od;
+ if not list[info.degI + 1] in info.groups[2] then
+ ErrorNoReturn("usage: must be ",
+ "an element of ");
+ 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()
diff --git a/lib/gprdmat.gi b/lib/gprdmat.gi
index e48fa5b799..e9797831cc 100644
--- a/lib/gprdmat.gi
+++ b/lib/gprdmat.gi
@@ -406,14 +406,97 @@ end );
InstallOtherMethod( Projection,"matrix wreath product", true,
[ IsMatrixGroup and HasWreathProductInfo ],0,
function( W )
-local info,proj,H;
+local info, degI, dimA, zero, projFunc;
info := WreathProductInfo( W );
if IsBound( info.projection ) then return info.projection; fi;
- proj:=Error("TODO");
+ degI := info.degI;
+ dimA := info.dimA;
+ zero := Zero(info.field);
+
+ projFunc := function(x)
+ local topImages, k, l, a;
+ topImages := [];
+ for k in [1 .. degI] do
+ for l in [1 .. degI] do
+ for a in [1 .. dimA] do
+ if x[dimA * (k - 1) + a, dimA * (l - 1) + a] <> zero then
+ Add(topImages, l);
+ break;
+ fi;
+ od;
+ if Length(topImages) = k then
+ break;
+ fi;
+ od;
+ if Length(topImages) <> k then
+ return fail;
+ fi;
+ od;
+ return PermList(topImages);
+ end;
+
+ info.projection := GroupHomomorphismByFunction(W, info.groups[2], projFunc);
+ return info.projection;
+end);
+
+#############################################################################
+##
+#M ListWreathProductElementNC( , )
+##
+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(, )
+##
+InstallMethod( WreathProductElementListNC, "matrix wreath product", true,
+ [ IsMatrixGroup and HasWreathProductInfo, IsList ], 0,
+function(G, list)
+ local info;
- info.projection:=proj;
- return proj;
+ 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
diff --git a/lib/gprdperm.gi b/lib/gprdperm.gi
index 1d0de379a5..d3eb190f47 100644
--- a/lib/gprdperm.gi
+++ b/lib/gprdperm.gi
@@ -805,18 +805,50 @@ end );
InstallOtherMethod( Projection,"perm wreath product", true,
[ IsPermGroup and HasWreathProductInfo ],0,
function( W )
-local info,proj,H;
+local info, proj, H, degI, degK, constPoints, projFunc;
info := WreathProductInfo( W );
if IsBound( info.projection ) then return info.projection; fi;
+ # Imprimitive Action, tuple (i, j) corresponds
+ # to point i + degK * (j - 1)
if IsBound(info.permimpr) and info.permimpr=true then
proj:=ActionHomomorphism(W,info.components,OnSets,"surjective");
+ # Primitive Action, tuple (t_1, ..., t_degI) corresponds
+ # to point Sum_{i=1}^degI t_i * degK ^ (i - 1)
else
- H:=info.groups[2];
- proj:=List(info.basegens,i->One(H));
- proj:=GroupHomomorphismByImagesNC(W,H,
- Concatenation(info.basegens,info.hgens),
- Concatenation(proj,GeneratorsOfGroup(H)));
+ degI := info.degI;
+ degK := NrMovedPoints(info.groups[1]);
+ # constPoints correspond to [1, 1, ...] and the one-vectors with a 2 in each position,
+ # i.e. [2, 1, 1, ...], [1, 2, 1, ...], [1, 1, 2, ...], ...
+ constPoints := Concatenation([0], List([0 .. degI - 1], i -> degK ^ i)) + 1;
+ projFunc := function(x)
+ local imageComponents, i, comp, topImages;
+ # Let x = (f_1, ..., f_m; h).
+ # imageComponents = [ [1 ^ f_1, 1 ^ f_2, 1 ^ f_3, ...] ^ (1, h)
+ # [2 ^ f_1, 1 ^ f_2, 1 ^ f_3, ...] ^ (1, h),
+ # [1 ^ f_1, 2 ^ f_2, 1 ^ f_3, ...] ^ (1, h), ... ]
+ # So we just need to check where the bit differs from the first point
+ # in order to compute the action of the top element h.
+ imageComponents := List(OnTuples(constPoints, x) - 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 .. degI + 1] do
+ comp := imageComponents[i];
+ Append(comp, ListWithIdenticalEntries(degI - Length(comp), 1));
+ od;
+ # For some reason, the action of the top component is in reverse order,
+ # i.e. [ p[m], ..., p[1] ] ^ (1, h) = [ p[m ^ (h ^ -1)], ..., p[1 ^ (h ^ -1)] ]
+ topImages := List([0 .. degI - 1], i -> PositionProperty([0 .. degI - 1],
+ j -> imageComponents[1, degI - j] <>
+ imageComponents[degI - i + 1, degI - j]));
+ return PermList(topImages);
+ end;
+ proj := GroupHomomorphismByFunction(W, info.groups[2], projFunc);
fi;
SetKernelOfMultiplicativeGeneralMapping(proj,info.base);
@@ -824,6 +856,82 @@ local info,proj,H;
return proj;
end);
+#############################################################################
+##
+#M ListWreathProductElementNC( , )
+##
+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(, )
+##
+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( , ) wreath product in product action
diff --git a/lib/matobj.gi b/lib/matobj.gi
index e485781bdf..0f69b17489 100644
--- a/lib/matobj.gi
+++ b/lib/matobj.gi
@@ -620,6 +620,21 @@ InstallMethod( ExtractSubMatrix,
[ IsMatrixObj, IsList, IsList ],
{ M, rowpos, colpos } -> Matrix( Unpack( M ){ rowpos }{ colpos }, M ) );
+# Hack from recog package
+InstallOtherMethod( ExtractSubMatrix, "hack: for lists of compressed vectors",
+[ IsList, IsList, IsList ],
+function( m, poss1, poss2 )
+ local i,n;
+ n := [];
+ for i in poss1 do
+ Add(n,ShallowCopy(m[i]{poss2}));
+ od;
+ if IsFFE(m[1,1]) then
+ ConvertToMatrixRep(n);
+ fi;
+ return n;
+end );
+
InstallMethod( CopySubVector,
"generic method for vector objects",
[ IsVectorObj, IsVectorObj and IsMutable, IsList, IsList ],
diff --git a/tst/testinstall/opers/ListWreathProductElement.tst b/tst/testinstall/opers/ListWreathProductElement.tst
new file mode 100644
index 0000000000..3f990630b9
--- /dev/null
+++ b/tst/testinstall/opers/ListWreathProductElement.tst
@@ -0,0 +1,215 @@
+#
+gap> START_TEST("ListWreathProductElement.tst");
+
+#
+# Perm Wreath Product In Imprimitive Action
+#
+
+#
+gap> K := SymmetricGroup(3);;
+gap> H := SymmetricGroup(5);;
+gap> G := WreathProduct(K, H);;
+
+#
+gap> list := [(1,2), (1,2,3), (), (1,2,3), (), (1,2)(3,4)];;
+gap> x := WreathProductElementList(G, list);;
+gap> list = ListWreathProductElement(G, x);
+true
+
+#
+gap> list := [(1,2), (1,2,3), (), (1,2,3), (), (1,2,3)];;
+gap> x := WreathProductElementList(G, list);;
+gap> list = ListWreathProductElement(G, x);
+true
+
+#
+gap> x := (1,5,9,12,13)(2,4,8,11,15,3,6,7,10,14);;
+gap> list := ListWreathProductElement(G, x);;
+gap> x = WreathProductElementList(G, list);
+true
+
+# Top Component fails
+gap> x := (1,5);;
+gap> x ^ Projection(G);
+fail
+gap> ListWreathProductElement(G, x);
+fail
+
+# Base Component fails
+gap> x := (1,2,3,4,5);;
+gap> x ^ Projection(G);
+()
+gap> ListWreathProductElement(G, x);
+fail
+
+#
+# Perm Wreath Product In Product Action
+#
+
+#
+gap> K := SymmetricGroup(3);;
+gap> H := SymmetricGroup(5);;
+gap> G := WreathProductProductAction(K, H);;
+
+#
+gap> list := [(1,2), (1,2,3), (), (1,2,3), (), (1,2)(3,4)];;
+gap> x := WreathProductElementList(G, list);;
+gap> list = ListWreathProductElement(G, x);
+true
+
+#
+gap> list := [(1,2), (1,2,3), (), (1,2,3), (), (1,2,3)];;
+gap> x := WreathProductElementList(G, list);;
+gap> list = ListWreathProductElement(G, x);
+true
+
+#
+gap> x :=
+> ( 1, 25, 24, 12, 17, 5)( 2, 7, 22, 21, 18, 14)( 3, 16, 23)( 4, 19, 27, 15, 11, 8)( 6, 10, 26)( 9, 13, 20)
+> ( 28,106, 78,174, 44, 86, 55,187, 51, 93, 71,167)( 29, 88, 76,183, 45, 95, 56,169, 49,102, 72,176)
+> ( 30, 97, 77,165, 43,104, 57,178, 50, 84, 70,185)( 31,100, 81,177, 38, 89, 58,181, 54, 96, 65,170)
+> ( 32, 82, 79,186, 39, 98, 59,163, 52,105, 66,179)( 33, 91, 80,168, 37,107, 60,172, 53, 87, 64,188)
+> ( 34,103, 75,180, 41, 83, 61,184, 48, 99, 68,164)( 35, 85, 73,189, 42, 92, 62,166, 46,108, 69,173)
+> ( 36, 94, 74,171, 40,101, 63,175, 47, 90, 67,182)(109,160,240,201,125,140,217,214,132,147,233,194)
+> (110,142,238,210,126,149,218,196,130,156,234,203)(111,151,239,192,124,158,219,205,131,138,232,212)
+> (112,154,243,204,119,143,220,208,135,150,227,197)(113,136,241,213,120,152,221,190,133,159,228,206)
+> (114,145,242,195,118,161,222,199,134,141,226,215)(115,157,237,207,122,137,223,211,129,153,230,191)
+> (116,139,235,216,123,146,224,193,127,162,231,200)(117,148,236,198,121,155,225,202,128,144,229,209);;
+gap> list := ListWreathProductElement(G, x);;
+gap> x = WreathProductElementList(G, list);
+true
+
+# Top Projection fails
+gap> x := (4,16);;
+gap> x ^ Projection(G);
+fail
+gap> ListWreathProductElement(G, x);
+fail
+
+# Base Decomposition fails
+gap> x := (1,2,3,4,5);;
+gap> x ^ Projection(G);
+()
+gap> ListWreathProductElement(G, x);
+fail
+
+#
+# Matrix Wreath Product
+#
+
+#
+gap> K := GL(3,3);;
+gap> H := SymmetricGroup(5);;
+gap> G := WreathProduct(K, H);;
+
+#
+gap> list := [K.1, K.2, One(K), K.2, One(K), (1,2)(3,4)];;
+gap> x := WreathProductElementList(G, list);;
+gap> list = ListWreathProductElement(G, x);
+true
+
+#
+gap> list := [K.1, K.2, One(K), K.2, One(K), (1,2,3)];;
+gap> x := WreathProductElementList(G, list);;
+gap> list = ListWreathProductElement(G, x);
+true
+
+#
+gap> x := [
+> [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), Z(3)^0, Z(3)^0 ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ Z(3)^0, Z(3)^0, Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), Z(3)^0, Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ] ];;
+gap> list := ListWreathProductElement(G, x);;
+gap> x = WreathProductElementList(G, list);
+true
+gap> ConvertToMatrixRep(x);;
+gap> list := ListWreathProductElement(G, x);;
+gap> x = WreathProductElementList(G, list);
+true
+
+# Top Projection fails
+gap> x := [
+> [ Z(3), 0*Z(3), Z(3)^0, Z(3), Z(3)^0, Z(3)^0, Z(3)^0, Z(3), Z(3), Z(3)^0, 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3)^0 ],
+> [ Z(3), Z(3), Z(3)^0, 0*Z(3), Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, Z(3), Z(3)^0, 0*Z(3), Z(3)^0, Z(3), Z(3) ],
+> [ 0*Z(3), Z(3)^0, 0*Z(3), Z(3)^0, Z(3)^0, Z(3)^0, Z(3), 0*Z(3), Z(3)^0, Z(3), Z(3)^0, Z(3)^0, 0*Z(3), 0*Z(3), Z(3)^0 ],
+> [ Z(3), 0*Z(3), Z(3), 0*Z(3), Z(3), Z(3), Z(3)^0, Z(3), Z(3), Z(3), Z(3), Z(3), Z(3)^0, 0*Z(3), 0*Z(3) ],
+> [ Z(3)^0, Z(3), Z(3)^0, 0*Z(3), 0*Z(3), Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3), 0*Z(3), Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), Z(3)^0, 0*Z(3), Z(3)^0, Z(3), 0*Z(3), Z(3), Z(3)^0, 0*Z(3) ],
+> [ Z(3)^0, 0*Z(3), Z(3)^0, Z(3)^0, 0*Z(3), Z(3), Z(3)^0, Z(3)^0, 0*Z(3), Z(3), 0*Z(3), 0*Z(3), Z(3), Z(3), Z(3)^0 ],
+> [ Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3), Z(3)^0, Z(3), Z(3)^0, 0*Z(3), 0*Z(3), Z(3), Z(3)^0, Z(3)^0, Z(3), Z(3), 0*Z(3) ],
+> [ Z(3), Z(3)^0, Z(3)^0, Z(3), Z(3)^0, 0*Z(3), Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), Z(3)^0, 0*Z(3) ],
+> [ Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3), 0*Z(3), Z(3), Z(3), Z(3), Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3) ],
+> [ 0*Z(3), Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3), 0*Z(3), Z(3)^0, Z(3), Z(3), 0*Z(3), 0*Z(3), Z(3), Z(3), Z(3)^0, Z(3) ],
+> [ 0*Z(3), Z(3)^0, 0*Z(3), Z(3), Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3), Z(3), Z(3)^0, Z(3)^0, 0*Z(3), Z(3)^0, Z(3)^0, Z(3) ],
+> [ Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), Z(3), 0*Z(3), Z(3), 0*Z(3), Z(3), Z(3), 0*Z(3), Z(3)^0, Z(3)^0 ],
+> [ 0*Z(3), 0*Z(3), Z(3), Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3), Z(3)^0, Z(3), Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3)^0, Z(3) ],
+> [ 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), Z(3), 0*Z(3), Z(3)^0, Z(3), Z(3)^0, 0*Z(3), Z(3), Z(3)^0 ] ];;
+gap> x ^ Projection(G);
+fail
+gap> ListWreathProductElement(G, x);
+fail
+gap> ConvertToMatrixRep(x);;
+gap> x ^ Projection(G);
+fail
+gap> ListWreathProductElement(G, x);
+fail
+
+# Base Decomposition fails
+gap> x := [
+> [ Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3), Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), Z(3), 0*Z(3), Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), 0*Z(3), Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), Z(3)^0 ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), Z(3) ],
+> [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0 ] ];;
+gap> x ^ Projection(G);
+()
+gap> ListWreathProductElement(G, x);
+fail
+gap> ConvertToMatrixRep(x);;
+gap> x ^ Projection(G);
+()
+gap> ListWreathProductElement(G, x);
+fail
+
+#
+# Generic Wreath Product
+#
+
+#
+gap> K := DihedralGroup(12);;
+gap> H := SymmetricGroup(5);;
+gap> G := WreathProduct(K, H);;
+
+#
+gap> list := [K.1, K.2, One(K), K.2, One(K), (1,2)(3,4)];;
+gap> x := WreathProductElementList(G, list);;
+gap> list = ListWreathProductElement(G, x);
+true
+
+#
+gap> x := G.1 * G.5 * G.2 * G.5 ^ ((G.4 * G.5) ^ 2) * G.2;;
+gap> list := ListWreathProductElement(G, x);;
+gap> x = WreathProductElementList(G, list);
+true