|
#############################################################################
##
## This file is part of GAP, a system for computational discrete algebra.
## This file's authors include Alexander Hulpke.
##
## 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
##
# to ensure this specific method can be called
DeclareGlobalFunction("MatDirectProduct");
InstallGlobalFunction(MatDirectProduct,function(arg)
local l,f,dim,gens,off,g,d,m,a,range,rans,G,compgens,cg;
l:=arg;
if Length(l)=1 and IsList(l[1]) and ForAll(l[1],IsGroup) then
l:=l[1];
fi;
# Check the arguments.
if not ForAll(l,IsGroup) then
TryNextMethod();
fi;
f:=DefaultFieldOfMatrixGroup(l[1]);
for a in [2..Length(l)] do
d:=DefaultFieldOfMatrixGroup(l[a]);
if not IsSubset(f,d) then
if IsSubset(d,f) then
f:=d;
elif PrimeField(d)<>PrimeField(f) then
TryNextMethod();
else
f:=DefaultField(Concatenation(GeneratorsOfField(d),GeneratorsOfField(f)));
fi;
fi;
od;
dim:=Sum(l,DimensionOfMatrixGroup);
gens:=[];
compgens:=[];
rans:=[];
off:=0;
# loop over the groups
for g in l do
cg:=[];
Add(compgens,cg);
d:=DimensionOfMatrixGroup(g);
range:=[off+1..off+d];
for m in GeneratorsOfGroup(g) do
a:=IdentityMat(dim,f);
a{range}{range}:=m;
a:=ImmutableMatrix(f,a);
Add(gens,a);
Add(cg,a);
od;
Add(rans,range);
off:=off+d;
od;
G:= Group(gens);
SetDirectProductInfo(G,rec(groups:=ShallowCopy(l),
dimension:=dim,field:=f,
compgens:=compgens,
rans:=rans,
embeddings:=[],
projections:=[]));
return G;
end);
InstallMethod(DirectProductOp,"matrix groups",IsCollsElms,
[IsList,IsMatrixGroup],0,
function(grps,G)
return MatDirectProduct(grps);
end);
#############################################################################
##
#M Size(<D>) . . . . . . . . . . . . . . . . . . . . . . of direct product
##
InstallMethod(Size,"for a matrix group that knows to be a direct product",
true,[ IsMatrixGroup and HasDirectProductInfo ],0,
D -> Product(List(DirectProductInfo(D).groups,Size)));
#############################################################################
##
#R IsEmbeddingDirectProductMatrixGroup(<hom>) . embedding of direct factor
##
DeclareRepresentation("IsEmbeddingDirectProductMatrixGroup",
IsAttributeStoringRep and
IsGroupHomomorphism and IsInjective and
IsSPGeneralMapping,[ "component" ]);
#############################################################################
##
#M Embedding(<D>,<i>) . . . . . . . . . . . . . . . . . . make embedding
##
InstallMethod(Embedding,"matrix direct product",true,
[ IsMatrixGroup and HasDirectProductInfo,IsPosInt ],0,
function(D,i)
local emb,info;
info := DirectProductInfo(D);
if IsBound(info.embeddings[i]) then return info.embeddings[i]; fi;
emb := Objectify(NewType(GeneralMappingsFamily(FamilyObj(One(D)),
FamilyObj(One(D))),
IsEmbeddingDirectProductMatrixGroup),
rec(component := i,info:=info,range:=info.rans[i]));
SetRange(emb,D);
SetSource(emb,info.groups[i]);
info.embeddings[i] := emb;
return emb;
end);
#############################################################################
##
#M PrintObj(<emb>) . . . . . . . . . . . . . . . . . . . . print embedding
##
InstallMethod(PrintObj,"for embedding into direct product",true,
[ IsEmbeddingDirectProductMatrixGroup ],0,
function(emb)
Print("Embedding(",Range(emb),",",emb!.component,")");
end);
#############################################################################
##
#M ImagesRepresentative(<emb>,<g>) . . . . . . . . . . . . of embedding
##
InstallMethod(ImagesRepresentative,"matrix direct product embedding",
FamSourceEqFamElm,[ IsEmbeddingDirectProductMatrixGroup,
IsMultiplicativeElementWithInverse ],0,
function(emb,m)
local info,a;
info:=emb!.info;
a:=IdentityMat(info.dimension,info.field);
a{emb!.range}{emb!.range}:=m;
return ImmutableMatrix(info.field,a);
end);
#############################################################################
##
#M PreImagesRepresentative(<emb>,<g>) . . . . . . . . . . . of embedding
##
InstallMethod(PreImagesRepresentative,"matrix direct product embedding",
FamRangeEqFamElm,
[ IsEmbeddingDirectProductMatrixGroup,
IsMultiplicativeElementWithInverse ],
function(emb,g)
local info,a,b;
info := emb!.info;
b:=g{emb!.range}{emb!.range};
a:=IdentityMat(info.dimension,info.field);
a{emb!.range}{emb!.range}:=b;
if g=a then
return b;
else
return fail;
fi;
end);
#############################################################################
##
#R IsProjectionDirectProductMatrixGroup(<hom>) projection onto direct factor
##
DeclareRepresentation("IsProjectionDirectProductMatrixGroup",
IsAttributeStoringRep and
IsGroupHomomorphism and IsSurjective and
IsSPGeneralMapping,[ "component" ]);
#############################################################################
##
#M Projection(<D>,<i>) . . . . . . . . . . . . . . . . . make projection
##
InstallMethod(Projection,"matrix direct product",true,
[ IsMatrixGroup and HasDirectProductInfo,IsPosInt ],0,
function(D,i)
local prj,info;
info := DirectProductInfo(D);
if IsBound(info.projections[i]) then return info.projections[i]; fi;
prj := Objectify(NewType(GeneralMappingsFamily(FamilyObj(One(D)),
FamilyObj(One(D))),
IsProjectionDirectProductMatrixGroup),
rec(component := i,info:=info,range:=info.rans[i]));
SetSource(prj,D);
SetRange(prj,info.groups[i]);
info.projections[i] := prj;
return prj;
end);
#############################################################################
##
#M ImagesRepresentative(<prj>,<g>) . . . . . . . . . . . . of projection
##
InstallMethod(ImagesRepresentative,"matrix direct product projection",
FamSourceEqFamElm,
[ IsProjectionDirectProductMatrixGroup,
IsMultiplicativeElementWithInverse ],0,
function(prj,g)
return g{prj!.range}{prj!.range};
end);
#############################################################################
##
#M PreImagesRepresentative(<prj>,<g>) . . . . . . . . . . . of projection
##
InstallMethod(PreImagesRepresentative,"matrix direct product projection",
FamRangeEqFamElm,
[ IsProjectionDirectProductMatrixGroup,
IsMultiplicativeElementWithInverse ],0,
function(prj,m)
local info,a;
info:=prj!.info;
a:=IdentityMat(info.dimension,info.field);
a{prj!.range}{prj!.range}:=m;
return ImmutableMatrix(info.field,a);
end);
#############################################################################
##
#M KernelOfMultiplicativeGeneralMapping(<prj>) . . . . . . . of projection
##
InstallMethod(KernelOfMultiplicativeGeneralMapping,
"matrix direct product projection",
true,[ IsProjectionDirectProductMatrixGroup ],0,
function(prj)
local D, gens, K,info;
D := Source(prj);
gens :=Concatenation(prj!.info.compgens{
Difference([1..Length(prj!.info.compgens)],[prj!.component])});
K := SubgroupNC(D,gens);
SetIsNormalInParent(K,true);
return K;
end);
#############################################################################
##
#M PrintObj(<prj>) . . . . . . . . . . . . . . . . . . . print projection
##
InstallMethod(PrintObj,"for projection from a direct product",
true,
[ IsProjectionDirectProductMatrixGroup ],0,
function(prj)
Print("Projection(",Source(prj),",",prj!.component,")");
end);
# to ensure this specific method can be called
DeclareGlobalFunction("MatWreathProduct");
InstallGlobalFunction(MatWreathProduct,function(A,B)
local f,n,m,Agens,Bgens,emb,i,j,a,g,dim,rans,range,orbs;
f:=DefaultFieldOfMatrixGroup(A);
n:=DimensionOfMatrixGroup(A);
# force trivial top group to act on one point
m:=Maximum(1, LargestMovedPoint(B));
dim:=n*m;
emb:=[];
rans:=[];
for j in [1..m] do
Agens:=[];
range:=[(j-1)*n+1..j*n];
Add(rans,range);
for i in GeneratorsOfGroup(A) do
a:=IdentityMat(n*m,f);
a{range}{range}:=i;
Add(Agens,a);
od;
emb[j]:=Agens;
od;
orbs := OrbitsDomain(B);
# force trivial top group to act on one point
if IsEmpty(orbs) then
orbs := [[1]];
fi;
# generators for the cases where one component is trivial
if IsTrivial(A) and IsTrivial(B) then
g := A;
elif IsTrivial(A) then
Bgens:=List(GeneratorsOfGroup(B), x -> PermutationMat(x,m,f));
g := Group(Bgens);
elif IsTrivial(B) then
Agens := Concatenation(List(orbs, orb -> emb[orb[1]]));
g := Group(Agens);
else
Agens := Concatenation(List(orbs, orb -> emb[orb[1]]));
Bgens:=List(GeneratorsOfGroup(B),
x->KroneckerProduct(PermutationMat(x,m,f),One(A)));
g:=Group(Concatenation(Agens,Bgens));
fi;
if HasSize(A) then
SetSize(g,Size(A)^m*Size(B));
fi;
SetWreathProductInfo(g,rec(groups:=[A,B],
dimA:=n,
degI:=m,
dimension:=dim,field:=f,
compgens:=emb,
rans:=rans,
embeddings:=[]));
return g;
end);
InstallMethod( WreathProduct,"imprimitive matrix group",
true, [ IsMatrixGroup, IsPermGroup ], 0, MatWreathProduct);
#############################################################################
##
#M Size(<D>) . . . . . . . . . . . . . . . . . . . . . . of direct product
##
InstallMethod(Size,"for a matrix group that knows to be a wreath product",
true,[ IsMatrixGroup and HasWreathProductInfo ],0,
function(W)
local info;
info:=WreathProductInfo(W);
return Size(info.groups[1])^info.degI*Size(info.groups[2]);
end);
#############################################################################
##
#R IsEmbeddingImprimitiveWreathProductMatrixGroup( <hom> )
##
## special for case of imprimitive wreath product
DeclareRepresentation( "IsEmbeddingImprimitiveWreathProductMatrixGroup",
IsAttributeStoringRep and
IsGroupHomomorphism and IsInjective and
IsSPGeneralMapping, [ "component" ] );
#############################################################################
##
#M Embedding( <W>, <i> ) . . . . . . . . . . . . . . . . . . make embedding
##
InstallMethod( Embedding,"matrix wreath product", true,
[ IsMatrixGroup and HasWreathProductInfo, IsPosInt ], 0,
function( W, i )
local emb, info;
info := WreathProductInfo( W );
if IsBound( info.embeddings[i] ) then return info.embeddings[i]; fi;
if i<=info.degI then
emb := Objectify( NewType(
GeneralMappingsFamily(FamilyObj(One(W)),FamilyObj(One(W))),
IsEmbeddingImprimitiveWreathProductMatrixGroup),
rec( component := i,range:=info.rans[i],info:=info ) );
SetSource(emb,info.groups[1]);
elif i=info.degI+1 then
emb:=GroupHomomorphismByFunction(info.groups[2],W,
x->KroneckerProduct(PermutationMat(x,info.degI,info.field),
One(info.groups[1])) );
SetIsInjective(emb,true);
else
Error("no embedding <i> defined");
fi;
SetRange( emb, W );
info.embeddings[i] := emb;
return emb;
end );
#############################################################################
##
#M ImagesRepresentative( <emb>, <g> ) . . . . . . . . . . . . of embedding
##
InstallMethod( ImagesRepresentative,
"imprim matrix wreath product embedding",FamSourceEqFamElm,
[ IsEmbeddingImprimitiveWreathProductMatrixGroup,
IsMultiplicativeElementWithInverse ], 0,
function( emb, m )
local info,a;
info:=emb!.info;
a:=IdentityMat(info.dimension,info.field);
a{emb!.range}{emb!.range}:=m;
return ImmutableMatrix(info.field,a);
end);
#############################################################################
##
#M PreImagesRepresentative( <emb>, <g> ) . . . . . . . . . . . of embedding
##
InstallMethod( PreImagesRepresentative,
"imprim matrix wreath product embedding", FamRangeEqFamElm,
[ IsEmbeddingImprimitiveWreathProductMatrixGroup,
IsMultiplicativeElementWithInverse ], 0,
function( emb, g )
local info,a,b;
info := emb!.info;
b:=g{emb!.range}{emb!.range};
a:=IdentityMat(info.dimension,info.field);
a{emb!.range}{emb!.range}:=b;
if g=a then
return b;
else
return fail;
fi;
end);
#############################################################################
##
#M PrintObj( <emb> ) . . . . . . . . . . . . . . . . . . . . print embedding
##
InstallMethod( PrintObj,
"for embedding into wreath product",
true,
[ IsEmbeddingImprimitiveWreathProductMatrixGroup], 0,
function( emb )
Print( "Embedding( ", Range( emb ), ", ", emb!.component, " )" );
end );
#############################################################################
##
#M Projection( <W> ) . . . . . . . . . . . . . . projection of wreath on top
##
InstallOtherMethod( Projection,"matrix wreath product", true,
[ IsMatrixGroup and HasWreathProductInfo ],0,
function( W )
local info, degI, dimA, projFunc;
info := WreathProductInfo( W );
if IsBound( info.projection ) then return info.projection; fi;
degI := info.degI;
dimA := info.dimA;
projFunc := function(x)
local topImages, i, j, zeroMat;
# ZeroMatrix does not accept IsPlistRep
if IsPlistRep(x) then
zeroMat := NullMat(dimA, dimA, info.field);
else
zeroMat := ZeroMatrix(dimA, dimA, x);
fi;
topImages := EmptyPlist(degI);
for i in [1 .. degI] do
for j in [1 .. degI] do
if ExtractSubMatrix(x, [dimA * (i - 1) + 1 .. dimA * i], [dimA * (j - 1) + 1 .. dimA * j]) <> zeroMat then
topImages[i] := j;
break;
fi;
od;
if not IsBound(topImages[i]) then
return fail;
fi;
od;
return PermList(topImages);
end;
info.projection := GroupHomomorphismByFunction(W, info.groups[2], 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");
InstallGlobalFunction(TensorWreathProduct,function(M,P)
local d,e,f,s,dim,gens,mimgs,pimgs,tup,act,a,g,i;
d:=Length(One(M));
f:=DefaultFieldOfMatrixGroup(M);
e:=LargestMovedPoint(P);
s:=SymmetricGroup(e);
dim:=d^e;
gens:=[];
mimgs:=[];
for g in GeneratorsOfGroup(M) do
a:=NullMat(dim,dim,f);
for i in [1..dim/d] do
tup:=[1..d]+(i-1)*d;
a{tup}{tup}:=g;
od;
a:=ImmutableMatrix(f,a);
Add(gens,a);
Add(mimgs,a);
od;
tup:=List(Tuples([1..d],e),Reversed); # reverse to be consistent with Magma
act:=ActionHomomorphism(s,tup,Permuted,"surjective");
pimgs:=[];
for g in GeneratorsOfGroup(P) do
a:=PermutationMat(Image(act,g),dim,f);
a:=ImmutableMatrix(f,a);
Add(gens,a);
Add(pimgs,a);
od;
return Group(gens);
end);
[ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet)
]
|