############################################################################# ## ## This file is part of GAP, a system for computational discrete algebra. ## This file's authors include Werner Nickel, 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 ## ## This file contains the implementation of the methods for SchurMultiplier ## and Darstellungsgruppen. ##
## Take a finite presentation F/R for a group G and compute a presentation ## of one of G's representation groups (Darstellungsgruppen, Schur covers). ## This is done by assembling a presentation for F/[R,F] and then finding a ## generating set for a complement C/[R,F] for the intersection of R and ## [F,F] in R/[R,F]. ## ## No attempt is made to reduce the number of generators in the ## presentation. This can be done using the Tietze routines from the GAP ## library.
BindGlobal("SchurCoverFP",function( G )
local g, i, m, n, r, D, M, M2,fgens,rels,gens,Drels,nam;
fgens:=FreeGeneratorsOfFpGroup(G);
rels:=RelatorsOfFpGroup(G);
n := Length( fgens );
m := Length( rels );
nam:=List(fgens,String); if not ForAny(nam,x->'k' in x) then
r:="k"; else
r:=First(Concatenation(CHARS_LALPHA,CHARS_UALPHA),
x->not ForAny(nam,y->x in y)); if r=fail then
r:="extra"; # unlikely to have the same name, will just print weirdly # but not calculate wrongly else
r:=[r]; fi; fi;
for i in [1..m] do
Add(nam,Concatenation(r,String(i)));
od;
D := FreeGroup(nam);
gens:=GeneratorsOfGroup(D);
Drels := []; for i in [1..m] do
r := rels[i];
Add(Drels, MappedWord( r, fgens, gens{[1..n]} ) / gens[n+i] );
od; for g in gens{[1..n]} do for r in gens{[n+1..n+m]} do
Add( Drels, Comm( r, g ) );
od;
od;
M := []; for r in rels do
Add( M, List( fgens, g->ExponentSumWord( r, g ) ) );
od;
M{[1..m]}{[n+1..n+m]} := IdentityMat(m);
M := HermiteNormalFormIntegerMat( M );
M:=Filtered(M,i->not IsZero(i));
r := 1; i := 1; while r <= m and i <= n do while i <= n and M[r][i] = 0do
i := i+1;
od; if i <= n then r := r+1; fi;
od;
r := r-1;
if r > 0then
M2 := M{[1..r]}{[n+1..n+m]};
M2 := HermiteNormalFormIntegerMat( M2 );
M2:=Filtered(M2,i->not IsZero(i)); for i in [1..Length(M2)] do
Add(Drels,LinearCombinationPcgs(gens{[n+1..n+m]},M2[i]));
od; fi;
InstallMethod(EpimorphismSchurCover,"generic, via fp group",true,[IsGroup],1, function(G)
local iso,
hom,
F,D,p,gens,Fgens,Dgens;
## Check to see if G is trivial -- if so then just return ## the map from the trivial FP group and G. if IsTrivial(G) then
F := FreeGroup(1);
D := F/[F.1];
return GroupHomomorphismByImages(
D, G,
GeneratorsOfGroup(D), AsSSortedList(G)); fi; ## ##
iso:=IsomorphismFpGroup(G);
F:=ImagesSource(iso);
Fgens:=GeneratorsOfGroup(F);
D:=SchurCoverFP(F);
# simplify the fp group
p:=PresentationFpGroup(D);
Dgens:=GeneratorsOfPresentation(p);
TzInitGeneratorImages(p);
TzOptions(p).printLevel:=0;
TzGo(p);
D:=FpGroupPresentation(p);
gens:=TzPreImagesNewGens(p);
Dgens:=List(gens,i->MappedWord(i,Dgens,
Concatenation(Fgens,List([1..(Length(Dgens)-Length(Fgens))],
j->One(F)))));
# compute commutators and their images so that we know the image on `mul', # create out relations v=v^g.
BindGlobal("CommutGenImgs",function(pcgs,g,h,mul)
local u,a,b,i,j,c,x,y;
u:=TrivialSubgroup(mul);
a:=[];
b:=[];
x:=One(mul);
y:=One(h[1]);
repeat for i in [1..Length(g)] do for j in [1..i-1] do
c:=Comm(g[i],g[j]^x); if not c in u then
Add(a,c);
Add(b,Comm(h[i],h[j]^y));
u:=ClosureGroup(u,c); if IsSubgroup(u,mul) then
a:=CanonicalPcgsByGeneratorsWithImages(pcgs,a,b);
return List(GeneratorsOfGroup(mul),
i->i/PcElementByExponentsNC(a[2],ExponentsOfPcElement(a[1],i))); fi; fi;
od;
od; #in rare cases we also need commutators of conjugates. if Size(mul)=1then
return []; else
Info(InfoSchur,2,"the commutators do not generate!");
i:=Random(1,Length(g));
x:=x*g[i];
y:=y*h[i]; fi;
until false; end);
InstallGlobalFunction(SchuMu,function(g,p)
local s,pcgs,n,l,cov,pco,ng,gens,imgs,ran,zer,i,j,e,a,
rels,de,epi,mul,hom,dc,q,qs;
s:=SylowSubgroup(g,p); if IsCyclic(s) then
return InverseGeneralMapping(IsomorphismPcGroup(s)); fi;
# compute a Darstellungsgruppe as PC-Group
de:=EpimorphismSchurCover(s);
# exponent of M(G) is at most p^(n/2)
epi:=EpimorphismPGroup(Source(de),p,PClassPGroup(s)+Int(l/2));
cov:=Range(epi);
mul:=Image(epi,KernelOfMultiplicativeGeneralMapping(de)); if Size(mul)=1then
return InverseGeneralMapping(IsomorphismPcGroup(s)); fi;
# get a decent pcgs for the cover
pco:=List(pcgs,i->Image(epi,PreImagesRepresentative(de,i)));
Append(pco,Pcgs(mul));
pco:=PcgsByPcSequenceNC(FamilyObj(One(cov)),pco);
# the induced action of n on the derived subgroup of the cover: # we prescribe images on the commutator factor group. These may not be # entirely correct -- multiplicator elements are missing. However on [G,G] # they are unique -- the wrong central parts cancel out # (use Burnside's basis theorem)
ng:=GeneratorsOfGroup(n);
gens:=[];
imgs:=List(ng,i->[]);;
ran:=[1..Length(pcgs)];
zer:=ListWithIdenticalEntries(Length(pco)-Length(pcgs),0); for i in pco do
Add(gens,i);
a:=PcElementByExponentsNC(pcgs,ExponentsOfPcElement(pco,i){ran}); for j in [1..Length(ng)] do
e:=ExponentsOfPcElement(pcgs,a^ng[j]);
Append(e,zer);
Add(imgs[j],PcElementByExponentsNC(pco,e));
od;
od;
# now we add new relators: x^g=x for all central x
rels:=TrivialSubgroup(cov); for j in [1..Length(ng)] do # extend homomorphically
rels:=ClosureGroup(rels,CommutGenImgs(pco,gens,imgs[j],mul));
od;
if Size(rels)=Size(mul) then # total vanish
return InverseGeneralMapping(IsomorphismPcGroup(s)); fi;
# form the quotient, make it the new cover and the new multiplicator.
hom:=NaturalHomomorphismByNormalSubgroupNC(cov,rels);
mul:=Image(hom,mul);
cov:=Image(hom,cov);
pco:=List(pco{[1..Length(pcgs)]},i->Image(hom,i));
Append(pco,Pcgs(mul));
pco:=PcgsByPcSequenceNC(FamilyObj(One(cov)),pco);
epi:=GroupHomomorphismByImagesNC(cov,s,pco,
Concatenation(pcgs,List(Pcgs(mul),i->One(s))));
SetKernelOfMultiplicativeGeneralMapping(epi,mul);
# now extend to the full group
rels:=TrivialSubgroup(cov);
dc:=List(DoubleCosetRepsAndSizes(g,n,n),i->i[1]);
i:=1; while i<=Length(dc) and Index(mul,rels)>1do if Order(dc[i])>1then# the trivial element will not do anything
q:=Intersection(s,ConjugateSubgroup(s,dc[i]^-1)); if Size(q)>1then
qs:=PreImage(epi,q); # factor generators
gens:=GeneratorsOfGroup(qs); # their conjugates
imgs:=List(gens,j->PreImagesRepresentative(epi,Image(epi,j)^dc[i]));
rels:=ClosureGroup(rels,CommutGenImgs(pco,gens,imgs,
Intersection(mul,DerivedSubgroup(qs)))); fi; fi;
i:=i+1;
od;
hom:=NaturalHomomorphismByNormalSubgroupNC(cov,rels);
mul:=Image(hom,mul);
cov:=Image(hom,cov);
pco:=List(pco{[1..Length(pcgs)]},i->Image(hom,i));
Append(pco,Pcgs(mul));
pco:=PcgsByPcSequenceNC(FamilyObj(One(cov)),pco);
epi:=GroupHomomorphismByImagesNC(cov,s,pco,
Concatenation(pcgs,List(Pcgs(mul),i->One(s))));
SetKernelOfMultiplicativeGeneralMapping(epi,mul);
return epi;
InstallMethod(AbelianInvariantsMultiplier,"via Sylow Subgroups",true,
[IsGroup],0, function(G)
local a,f,i;
Info(InfoWarning,1,"Warning: AbelianInvariantsMultiplier via Sylow subgroups is under construction");
a:=[];
f:=Filtered(Collected(Factors(Size(G))),i->i[2]>1); for i in f do
Append(a,AbelianInvariants(KernelOfMultiplicativeGeneralMapping(
SchuMu(G,i[1]))));
od;
return a; end);
# <hom> is a homomorphism from a finite group onto an fp group. It returns # an isomorphism from the same group onto an isomorphic fp group <F>, such # that no negative exponent occurs in the relators of <F>. #
BindGlobal("PositiveExponentsPresentationFpHom",function(hom)
local G,F,geni,ro,fam,r,i,j,rel,n,e;
G:=Image(hom);
F:=FreeGeneratorsOfFpGroup(G);
geni:=List(GeneratorsOfGroup(G),i->PreImagesRepresentative(hom,i));
ro:=List(geni,Order);
fam:=FamilyObj(F[1]);
r:=[]; for i in RelatorsOfFpGroup(G) do
rel:=[]; for j in [1..NrSyllables(i)] do
n:=GeneratorSyllable(i,j);
Add(rel,n);
e:=ExponentSyllable(i,j); if e<0then
e:=e mod ro[n]; fi;
Add(rel,e);
od;
Add(r,ObjByExtRep(fam,rel));
od; # ensure the relative orders are relators. for i in [1..Length(ro)] do if not F[i]^ro[i] in r then
Add(r,F[i]^ro[i]); fi;
od; # new fp group
F:=FreeGroupOfFpGroup(G)/r;
hom:=GroupHomomorphismByImagesNC(Source(hom),F,geni,GeneratorsOfGroup(F));
return hom; end);
InstallGlobalFunction(CorestEval,function(FG,s) # This has plenty of space for optimization.
local G,H,D,T,i,j,k,l,a,h,nk,evals,rels,gens,r,np,g,invlist,el,elp,TL,rp,pos;
G:=Image(FG);
H:=Image(s);
D:=Source(s);
Info(InfoSchur,2,"lift index:",Index(G,H));
T:=RightTransversal(G,H);
TL:=List(T,i->i); # we need to refer to the elements very often
# this will guarantee we always take the same preimages
el:=AsSSortedListNonstored(H);
elp:=List(el,i->PreImagesRepresentative(s,i)); #ensure the preimage of identity is one if IsOne(el[1]) then
pos:=1; else
pos:=Position(el,One(H)); fi;
elp[pos]:=One(elp[pos]);
# deal with inverses
invlist:=[]; for g in gens do
h:=One(D); for k in T do
np:=k*g;
nk:=TL[PositionCanonical(T,np)];
h:= h*elp[Position(el,np/nk)]*elp[Position(el,nk/g/k)];;
od;
Add(invlist,h);
od;
# take care of inverses for l in [1..Length(i)] do if i[l]<0then #i[l]:=-i[l];
a:=a*invlist[-i[l]]; fi;
od;
for j in [1..Length(T)] do
k:=T[j];
h:=One(D); for l in i do if l<0then
g:=Inverse(gens[-l]); else
g:=gens[l]; fi;
np:=k*g;
nk:=TL[PositionCanonical(T,np)]; #h:=h*PreImagesRepresentative(s,np/nk);
h:=h*elp[Position(el,np/nk)];
k:=nk;
od;
# now rel is a list of relators and their images in M(B). # find relator relations in F/F' and evaluate these in M(B) to find # M_R(B).
bas := [];
basr := [];
mat:=[]; for rel in ri do
row := ListWithIdenticalEntries(rank,0); for i in [1..NrSyllables(rel[1])] do
j := GeneratorSyllable(rel[1],i);
row[j]:=row[j]+ExponentSyllable(rel[1],i);
od;
Add(mat,row);
od; # SNF
snf:=NormalFormIntMat(mat,15);
mat:=mat*snf.coltrans; # changed coordinates (parent presentation)
bas:=snf.rowtrans*mat;
v:=Filtered([1..Length(bas)],i-> not IsZero(bas[i])); # express the basis elements
bas:=bas{v};
basr:=[]; for i in v do
rel:=One(Source(s)); for j in [1..Length(mat)] do
rel:=rel*ri[j][2]^snf.rowtrans[i][j];
od;
Add(basr,rel);
od;
# now collect relations
v:=TrivialSubgroup(D); for i in [1..Length(mat)] do
sol:=SolutionMat(bas,mat[i]);
rel:=ri[i][2]; for j in [1..Length(sol)] do
rel:=rel/basr[j]^sol[j];
od; if not rel in v then #NC is safe
v:=ClosureSubgroupNC(v,rel); fi;
od;
for i in basr do for j in basr do # NC is safe
v:=ClosureSubgroupNC(v,Comm(i,j));
od;
od;
Info(InfoSchur,1,"Extra central part:",
Index(KernelOfMultiplicativeGeneralMapping(s),v)); # form the quotient
j:=NaturalHomomorphismByNormalSubgroupNC(D,v);
i:=GeneratorsOfGroup(Image(j));
i:=GroupHomomorphismByImagesNC(Image(j),P,i,
List(i,k->ImageElm(s,PreImagesRepresentative(j,k))));
SetKernelOfMultiplicativeGeneralMapping(i,
Image(j,KernelOfMultiplicativeGeneralMapping(s)));
return i;
sl:=[];
ngl:=[ng];
pll:=[];
ms:=1; for p in pl do
s:=SchuMu(G,p); if Size(KernelOfMultiplicativeGeneralMapping(s))>1then
Add(pll,p);
Add(sl,SchuMu(G,p));
ab:=AbelianInvariants(KernelOfMultiplicativeGeneralMapping(s));
ms:=ms*Product(ab);
Add(ngl,Last(ngl)+Length(ab)); fi;
od;
Info(InfoSchur,1,"Relevant primes:",pll);
Info(InfoSchur,1,"Multiplicator size:",ms); if Length(pll)=0then
return IdentityMapping(G); fi;
rels:=[];
rel2:=[]; for pp in [1..Length(pll)] do
p:=pll[pp];
Info(InfoSchur,2,"Cohomology for prime :",p);
s:=sl[pp];
mg:=IsomorphismPermGroup(KernelOfMultiplicativeGeneralMapping(s));
mg:=List(IndependentGeneratorsOfAbelianGroup(Image(mg)),
i->PreImagesRepresentative(mg,i));
sdc:=ListWithIdenticalEntries(Last(ngl),One(Source(s)));
sdc{[ngl[pp]+1..ngl[pp+1]]}:=mg;
for i in gens do
Add(rels,i^Order(Image(sdc,i))); for j in GeneratorsOfGroup(F) do if i<>j then
Add(rels,Comm(i,j)); fi;
od;
od;
q:=[]; for i in ce do
Add(q,PreImagesRepresentative(sdc,i[2]));
od;
rel2[pp]:=q;
od;
# now run through the last ce
gens:=GeneratorsOfGroup(F){[1..ng]};
free:=FreeGeneratorsOfFpGroup(Source(hom)); for i in [1..Length(ce)] do
q:=One(F); for j in [1..Length(pll)] do
q:=q*rel2[j][i];
od;
Add(rels,MappedWord(ce[i][1],free,gens)/q);
od;
q:=F/rels; if AssertionLevel()>0then if Size(q)<>Size(G)*ms then
Error("oops!"); fi; else
SetSize(q,Size(G)*ms); fi;
qhom:=GroupHomomorphismByImages(q,G,GeneratorsOfGroup(q),
Concatenation(List(GeneratorsOfGroup(Source(hom)),i->Image(hom,i)),
List([ng+1..Length(GeneratorsOfGroup(q))],
i->One(G)) ));
SetIsSurjective(qhom,true);
SetSize(Source(qhom),Size(G)*ms);
return qhom; end);
BindGlobal( "DoMulExt", function(arg)
local G,pl;
G:=arg[1]; if not IsFinite(G) then
Error("cover is only defined for finite groups"); elif IsTrivial(G) then
return IdentityMapping(G); fi;
Info(InfoWarning,1,"Warning: EpimorphismSchurCover via Holt's algorithm is under construction"); if Length(arg)>1then
pl:=arg[2]; else
pl:=PrimeDivisors(Size(G)); fi;
return MulExt(G,pl); end );
############################################################################ ############################################################################ ## ## Additional attributes and properties Robert F. Morse ## derived from computing the Schur Cover ## of a group. ## ## A Epicentre ## O NonabelianExteriorSquare ## O EpimorphismNonabelianExteriorSquare ## P IsCapable ## ############################################################################ ## #A Epicentre(<G>) ## ## There are various ways of describing the epicentre of a group. It is ## the smallest normal subgroup $N$ of $G$ such that $G/N$ is a central ## quotient of some group $H$. It is also the exterior center of a group. ##
InstallMethod(Epicentre,"Naive Method",true,[IsGroup],0, function(G)
local epi;
epi := EpimorphismSchurCover(G);
return Image(epi,Center(Source(epi))); end
);
############################################################################# ## #A Epicentre(G,N) ## ## Place holder attribute for computing the epicentre relative to a normal ## subgroup $N$. This is an attribute of $N$. ##
InstallOtherMethod(Epicentre,"Naive method",true,[IsGroup,IsGroup],0, function(G,N)
TryNextMethod(); end
);
############################################################################# ## #O NonabelianExteriorSquare ## ## Computes the Nonabelian Exterior Square $G\wedge G$ of a group $G$. ## For finitely generated groups this is the derived subgroup of the ## Schur cover -- which is an invariant for all Schur covers of group. ##
InstallMethod(NonabelianExteriorSquare, "Naive method", true, [IsGroup],0,
G->DerivedSubgroup(SchurCover(G)));
############################################################################# ## #O EpimorphismNonabelianExteriorSquare(<G>) ## ## Computes the mapping $G\wedge G \to G$. The kernel of this ## mapping is isomorphic to the Schur Multiplicator. ##
InstallMethod(EpimorphismNonabelianExteriorSquare, "Naive method", true,
[IsGroup],0, function(G)
local epi, ## Epimorphism from the Schur cover to G
D; ## Derived subgroup of the Schur Cover
epi := EpimorphismSchurCover(G);
D := DerivedSubgroup(Source(epi));
## Compute the restricted mapping of epi from ## D --> G ## ## Need to check that D is trivial i.e. has no generators. ## In this case we create the homomorphism using the group's ## elements rather than generators. ## if IsTrivial(D) then
############################################################################# ## #P IsCentralFactor(<G>) ## ## Dertermines if $G$ is a central factor of some group $H$ or not. ##
InstallMethod(IsCentralFactor, "Naive method", true, [IsGroup], 0,
G -> IsTrivial(Epicentre(G)));
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.