############################################################################# ## ## 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 ## ## This file contains declarations for the subgroup lattice functions for ## pc groups. ##
############################################################################# ## #F InvariantElementaryAbelianSeries( <G>, <morph>, [ <N> ] ) ## find <morph> invariant EAS of G (through N) ##
InstallGlobalFunction(InvariantElementaryAbelianSeries,function(arg)
local G,morph,N,s,p,e,i,j,k,ise,fine,cor;
G:=arg[1];
morph:=arg[2];
fine:=false; if Length(arg)>2then
N:=arg[3];
e:=[G,N]; if Length(arg)>3then
fine:=arg[4]; fi; if fine then
e:=ElementaryAbelianSeries(e); else
e:=ElementaryAbelianSeriesLargeSteps(e); fi; else
N:=TrivialSubgroup(G);
e:=DerivedSeriesOfGroup(G);
e:=ElementaryAbelianSeriesLargeSteps(e); fi;
s:=[G];
i:=2; while i<=Length(e) do # intersect all images of normal subgroup to obtain invariant one # as G is invariant, we dont have to deal with special cases
ise:=[e[i]];
cor:=e[i]; for j in ise do for k in morph do
p:=Image(k,j); if not IsSubset(p,cor) then
Add(ise,p);
cor:=Intersection(cor,p); fi;
od;
od;
Assert(1,HasElementaryAbelianFactorGroup(Last(s),cor));
ise:=cor;
Add(s,ise);
p:=Position(e,ise); if p<>fail then
i:=p+1; elif fine then
e:=ElementaryAbelianSeries([G,ise,TrivialSubgroup(G)]);
i:=Position(e,ise)+1; else
e:=ElementaryAbelianSeriesLargeSteps([G,ise,TrivialSubgroup(G)]);
i:=Position(e,ise)+1; fi;
Assert(1,ise in e);
od;
return s; end);
############################################################################# ## #F InducedAutomorphism(<epi>,<aut>) ##
InstallGlobalFunction(InducedAutomorphism,function(epi,aut)
local f;
f:=Range(epi); if HasIsConjugatorAutomorphism( aut ) and IsConjugatorAutomorphism( aut )
and ConjugatorOfConjugatorIsomorphism( aut ) in Source( epi ) then
aut:= ConjugatorAutomorphismNC( f,
Image( epi, ConjugatorOfConjugatorIsomorphism( aut ) ) ); else
aut:= GroupHomomorphismByImagesNC(f,f,GeneratorsOfGroup(f),
List(GeneratorsOfGroup(f),
i->Image(epi,Image(aut,PreImagesRepresentative(epi,i)))));
SetIsInjective(aut,true);
SetIsSurjective(aut,true); fi;
return aut; end);
############################################################################# ## #F InvariantSubgroupsElementaryAbelianGroup(<G>,<homs>[,<dims]) submodules #F find all subgroups of el. ab. <G>, which are invariant under all <homs> #F which have dimension in dims ##
InstallGlobalFunction(InvariantSubgroupsElementaryAbelianGroup,function(arg)
local g,op,a,pcgs,ma,mat,d,f,i,j,new,newmat,id,p,dodim,compldim,compl,dims,nm;
g:=arg[1];
op:=arg[2]; if not IsElementaryAbelian(g) then
Error("<g> must be a vector space"); fi; if IsTrivial(g) then
return [g]; fi;
pcgs:=Pcgs(g);
d:=Length(pcgs);
p:=RelativeOrderOfPcElement(pcgs,pcgs[1]);
f:=GF(p); if Length(arg)=2then
dims:=[0..d]; else
dims:=arg[3]; fi;
if Length(dims)=0then
return []; fi;
if Length(op)=0then
# trivial operation: enumerate subspaces # check which dimensions we'll need
ma:=QuoInt(d,2);
dodim:=[];
compldim:=[]; for i in dims do if i<=ma then
AddSet(dodim,i); else
AddSet(dodim,d-i);
AddSet(compldim,d-i); fi;
od; if d<3then compldim:=[]; fi;
dodim:=Maximum(dodim);
# enumerate spaces
id:= Immutable( IdentityMat(d, One(f)) );
ma:=[[],[ShallowCopy(id[1])]];
ConvertToMatrixRep(ma[2],f); # the complements to ma if d>1then
compl:=[ShallowCopy(id)]; else
compl:=[]; fi; if d>2then
nm:=TriangulizedNullspaceMat(TransposedMat(id{[1]}));
ConvertToMatrixRep(nm,f);
Add(compl,nm); fi; for i in [2..d] do
new:=[]; for mat in ma do # subspaces of equal dimension for j in [0..p^Length(mat)-1] do if j=0then # special case for subspace of higher dimension if Length(mat)<dodim then
newmat:=Concatenation(mat,[id[i]]);
ConvertToMatrixRep(newmat,f); else
newmat:=false; fi; else # possible extension number d
a:=CoefficientsQadic(j,p)*One(f);
newmat:=List(mat,ShallowCopy); for j in [1..Length(a)] do
newmat[j][i]:=a[j];
od;
ConvertToMatrixRep(newmat,f); fi; if newmat<>false then # we will need the space for the next level
Add(new,newmat);
# note complements if necc. if Length(newmat) in compldim then
nm:=NullspaceMat(TransposedMat(newmat));
ConvertToMatrixRep(nm,f);
Add(compl,nm); #Add(compl,List(NullspaceMat(TransposedMat(newmat*One(f))), # i->List(i,IntFFE))); fi; fi;
od;
od;
ma:=Concatenation(ma,new);
od;
ma:=Concatenation(ma,compl);
# take only those of right dim
ma:=Filtered(ma,i->Length(i) in dims);
# convert to grps (noting also the triv. one)
new:=ma; for i in [1..Length(new)] do #a:=SubgroupNC(Parent(g),List(i,j->Product([1..d],k->pcgs[k]^j[k])));
ma:=new[i];
a:=SubgroupNC(Parent(g),List(ma,
j->PcElementByExponentsNC(pcgs,List(j,IntFFE)))); # a:=MySubgroupNC(Parent(g),List(i,j->PcElementByExponentsNC(pcgs,j)), # IsFinite and IsSubsetLocallyFiniteGroup and # IsSupersolvableGroup and IsNilpotentGroup and # IsCommutative and IsElementaryAbelian);
SetSize(a,p^Length(ma)); if Size(a)=Size(g) then a:=g;fi;
new[i]:=a;
od;
ma:=new;
else
# compute representation
ma:=[]; for i in op do
mat:=[]; for j in pcgs do
Add(mat,ExponentsOfPcElement(pcgs,Image(i,j))*One(f));
od;
mat:=ImmutableMatrix(f,mat);
Add(ma,mat);
od;
ma:=[]; for i in mat do
Add(ma,SubgroupNC(Parent(g),
List(i,j->PcElementByExponentsNC(pcgs,j)))); #List(i,j->Product([1..d],k->pcgs[k]^IntFFE(j[k])))));
od; fi;
SortBy(ma,x->-Size(x));
return ma; end);
############################################################################# ## #F ActionSubspacesElementaryAbelianGroup(<P>,<G>[,<dims>]) ## ## compute the permutation action of <P> on the subspaces of the ## elementary abelian subgroup <G> of <P>. Returns ## a list [<subspaces>,<action>], where <subspaces> is a list of all the ## subspaces (as groups) and <action> a homomorphism from <P> in a ## permutation group, which is equal to the action homomrophism for the ## action of <P> on <subspaces>. If <dims> is given, only subspaces of ## dimension <dims> are considered. Instead of <G> also a (modulo) pcgs ## may be given, in this case <subspaces> are pre-images of the subspaces. ##
InstallGlobalFunction(ActionSubspacesElementaryAbelianGroup,function(arg)
local P,g,op,act,a,pcgs,ma,mat,d,f,i,j,new,newmat,id,p,dodim,compldim,compl,
dims,Pgens,Pcgens,Pu,perms,one,par,ker,kersz,pcelm,pccache,asz;
P:=arg[1]; if IsModuloPcgs(arg[2]) then
pcgs:=arg[2];
g:=Group(NumeratorOfModuloPcgs(pcgs)); if not IsSubset(Parent(P),g) then# for matrix groups we need a parent here.
par:=ClosureGroup(Parent(P),g); else
par:=P; fi;
Pu:=AsSubgroup(par,g);
ker:=SubgroupNC(par,DenominatorOfModuloPcgs(pcgs));
kersz:=Size(ker); else
kersz:=1;
g:=arg[2];
par:=Parent(g);
Pu:=Centralizer(P,g); if not IsElementaryAbelian(g) then
Error("<g> must be a vector space"); fi; if IsTrivial(g) then
return [g]; fi;
pcgs:=Pcgs(g); fi;
d:=Length(pcgs);
p:=RelativeOrderOfPcElement(pcgs,pcgs[1]);
f:=GF(p);
one:=One(f); if Length(arg)=2then
dims:=[0..d]; else
dims:=arg[3]; fi;
if Length(dims)=0then
return []; fi;
# find representatives generating the acting factor
Pgens:=[];
Pcgens:=GeneratorsOfGroup(Pu); while Size(Pu)<Size(P) do
repeat
i:=Random(P);
until not i in Pu;
Add(Pgens,i);
Pu:=ClosureGroup(Pu,i);
od; if Length(Pgens)>2 and Length(Pgens)>Length(SmallGeneratingSet(P)) then
Pgens:=SmallGeneratingSet(P); fi;
# compute representation
op:=[]; for i in Pgens do
mat:=[]; for j in pcgs do
Add(mat,ExponentsConjugateLayer(pcgs,j,i)*One(f));
od;
mat:=ImmutableMatrix(f,mat);
Add(op,mat);
od;
# and action on canonical bases #act:=function(bas,m) # bas:=bas*m; # bas:=List(bas,ShallowCopy); # TriangulizeMat(bas); # bas:=List(bas,IntVecFFE); # return bas; #end; if p=2then
act:=OnSubspacesByCanonicalBasisGF2; else
act:=OnSubspacesByCanonicalBasis; fi;
# enumerate subspaces # check which dimensions we'll need
ma:=QuoInt(d,2);
dodim:=[];
compldim:=[]; for i in dims do if i<=ma then
AddSet(dodim,i); else
AddSet(dodim,d-i);
AddSet(compldim,d-i); fi;
od; if d<3then compldim:=[]; fi;
dodim:=Maximum(dodim);
# enumerate spaces
id:= Immutable( IdentityMat(d, one) );
ma:=[[],[id[1]]]; # the complements to ma if d>1then
compl:=[ShallowCopy(id)]; else
compl:=[]; fi; if d>2then
Add(compl,List(TriangulizedNullspaceMat(TransposedMat(id{[1]})),
ShallowCopy)); fi; for i in [2..d] do
new:=[]; for mat in ma do # subspaces of equal dimension for j in [0..p^Length(mat)-1] do if j=0then # special case for subspace of higher dimension if Length(mat)<dodim then
newmat:=Concatenation(mat,[id[i]]); else
newmat:=false; fi; else # possible extension number d
a:=CoefficientsQadic(j,p)*one;
newmat:=List(mat,ShallowCopy); for j in [1..Length(a)] do
newmat[j][i]:=a[j];
od; fi; if newmat<>false then # we will need the space for the next level
Add(new,Immutable(newmat));
# note complements if necc. if Length(newmat) in compldim then
a:=List(TriangulizedNullspaceMat(MutableTransposedMat(newmat)),
ShallowCopy);
Add(compl,Immutable(a)); fi; fi;
od;
od;
ma:=Concatenation(ma,new);
od;
ma:=Concatenation(ma,compl);
# take only those of right dim
ma:=Filtered(ma,i->Length(i) in dims);
perms:=List(Pgens,i->());
new:=[]; for i in dims do
mat:=Immutable(Set(Filtered(ma,j->Length(j)=i))); # compute action on mat if i>0 and i<d then for j in [1..Length(Pgens)] do #a:=Permutation(op[j],mat,act);
a:=List([1..Length(mat)],k->PositionSorted(mat,act(mat[k],op[j])));
a:=PermList(a);
perms[j]:=perms[j]*a^MappingPermListList([1..Length(mat)],
[Length(new)+1..Length(new)+Length(mat)]);
od; fi;
Append(new,mat);
od;
ma:=new;
# convert to grps
pccache:=[]; # avoid recerating different copies of same element
pcelm:=function(vec)
local e,p;
e:=Immutable([vec]);
p:=PositionSorted(pccache,e); if IsBound(pccache[p]) and pccache[p][1]=vec then
return pccache[p][2]; else
e:=Immutable([vec,PcElementByExponentsNC(pcgs,vec)]);
AddSet(pccache,e);
return e[2]; fi; end;
new:=[]; for i in ma do #a:=SubgroupNC(Parent(g),List(i,j->Product([1..d],k->pcgs[k]^j[k])));
asz:=kersz*p^Length(i); if kersz=1then
a:=SubgroupNC(par,List(i,pcelm)); else #a:=ClosureSubgroup(ker,List(i,pcelm):knownClosureSize:=asz);
a:=SubgroupNC(par,Concatenation(GeneratorsOfGroup(ker),
List(i,pcelm))); fi;
SetSize(a,asz);
Add(new,a);
od;
# test whether the c-conjugate of g is h-invariant, internal
BindGlobal( "HasInvariantConjugateSubgroup", function(g,c,h) # This should be done better!
g:=ConjugateSubgroup(g,c);
return ForAll(h,i->Image(i,g)=g); end );
############################################################################# ## #F SubgroupsSolvableGroup(<G>[,<opt>]) . classreps of subgrps of <G>, ## <homs>-inv. with options. ## Options are: ## actions: list of automorphisms: search for invariants ## funcnorm: N_G(actions) (speeds up calculation) ## normal: just search for normal subgroups ## consider: function(A,N,B,M) indicator function, whether ## complements of this type would be needed ## retnorm: return normalizers ##
InstallGlobalFunction(SubgroupsSolvableGroup,function(arg)
local g, # group
isom, # isomorphism onto AgSeries group
func, # automorphisms to be invariant under
funcs, # <func>
funcnorm, # N_G(funcs)
efunc, # induced automs on factor
efnorm, # funcnorm^epi
e, # EAS
len, # Length(e)
start, # last index with EA factor
i,j,k,l,
m,kp, # loop
kgens, # generators of k
kconh, # complemnt conjugacy storage
opt, # options record
normal, # flag for 'normal' option
consider, # optional 'consider' function
retnorm, # option: return all normalizers
f, # g/e[i]
home, # HomePcgs(f)
epi, # g -> f
lastepi, # epi of last step
n, # e[i-1]^epi
fa, # f/n = g/e[i-1]
hom, # f -> fa
B, # subgroups of n
ophom, # perm action of f on B (or false if not computed)
a, # preimg. of group over n
no, # N_f(a) # aop, # a^ophom # nohom, # ophom\rest no
oppcgs, # acting pcgs
oppcgsimg,# images under ophom
ex, # external set/orbits
bs, # b\in B normal under a, reps
bsp, # bs index
bsnorms, # respective normalizers
b, # in bs
bpos, # position in bs
hom2, # N_f(b) -> N_f(b)/b
nag, # AgGroup(n^hom2)
fghom, # assoc. epi
t,s, # dnk-transversals
z, # Cocycles
coboundbas,# Basis(OneCobounds)
field, # GF(Exponent(n))
com, # complements
comnorms, # normalizers supergroups
isTrueComnorm, # is comnorms the true normalizer or a supergroup
comproj, # projection onto complement
kgn,
kgim, # stored decompositions, translated to matrix language
kgnr, # assoc index
ncom, # dito, tested
idmat, # 1-matrix
mat, # matrix action
mats, # list of mats
conj, # matrix action
chom, # homom onto <conj>
shom, # by s induced autom
shoms, # list of these
smats, # dito, matrices
conjnr, # assoc. index
glsyl,
glsyr, # left and right side of eqn system
found, # indicator for success
grps, # list of subgroups
ngrps, # dito, new level
gj, # grps[j]
grpsnorms,# normalizers of grps
ngrpsnorms,# dito, new level
bgids, # generators of b many 1's (used for copro)
opr, # operation on complements
xo; # xternal orbits
g:=arg[1]; if Length(arg)>1 and IsRecord(Last(arg)) then
opt:=Last(arg); else
opt:=rec(); fi;
# parse options
retnorm:=IsBound(opt.retnorm) and opt.retnorm;
# handle trivial case if IsTrivial(g) then if retnorm then
return [[g],[g]]; else
return [g]; fi; fi;
normal:=IsBound(opt.normal) and opt.normal=true; if IsBound(opt.consider) then
consider:=opt.consider; else
consider:=false; fi;
isom:=fail;
# get automorphisms and compute their normalizer, if applicable if IsBound(opt.actions) then
func:=opt.actions;
hom2:= Filtered( func, HasIsConjugatorAutomorphism
and IsInnerAutomorphism );
hom2:= List( hom2, ConjugatorOfConjugatorIsomorphism );
if IsBound(opt.funcnorm) then # get the func. normalizer
funcnorm:=opt.funcnorm;
b:=g; else
funcs:= GroupByGenerators( Filtered( func,
i -> not ( HasIsConjugatorAutomorphism( i ) and
IsInnerAutomorphism( i ) ) ),
IdentityMapping(g));
IsGroupOfAutomorphismsFiniteGroup(funcs); # set filter if IsTrivial( funcs ) then
b:=ClosureGroup(Parent(g),List(func,ConjugatorOfConjugatorIsomorphism));
func:=hom2; else if IsSolvableGroup(funcs) then
a:=IsomorphismPcGroup(funcs); else
a:=IsomorphismPermGroup(funcs); fi;
hom:=InverseGeneralMapping(a);
IsTotal(hom); IsSingleValued(hom); # to be sure (should be set anyway)
b:=SemidirectProduct(Image(a),hom,g);
hom:=Embedding(b,1);
funcs:=List(GeneratorsOfGroup(funcs),i->Image(hom,Image(a,i)));
isom:=Embedding(b,2);
hom2:=List(hom2,i->Image(isom,i));
func:=Concatenation(funcs,hom2);
g:=Image(isom,g); fi;
# get the normalizer of <func>
funcnorm:=Normalizer(g,SubgroupNC(b,func));
func:=List(func,i->ConjugatorAutomorphism(b,i)); fi;
if IsBound(opt.series) then
e:=opt.series; else
f:=DerivedSeriesOfGroup(g); if Length(e)>Length(f) and
ForAll([1..Length(f)-1],i->IsElementaryAbelian(f[i]/f[i+1])) then
Info(InfoPcSubgroup,1," Preferring Derived Series");
e:=f; fi; fi;
# # check, if the series is compatible with the AgSeries and if g is a # # parent group. If not, enforce this # if not(IsParent(g) and ForAll(e,IsElementAgSeries)) then # Info(InfoPcSubgroup,1," computing better series"); # isom:=IsomorphismAgGroup(e); # g:=Image(isom,g); # e:=List(e,i->Image(isom,i)); # funcnorm:=Image(isom,funcnorm); # # #func:=List(func,i->isom^-1*i*isom); # hom:=[]; # for i in func do # hom2:=GroupHomomorphismByImagesNC(g,g,g.generators,List(g.generators, # j->Image(isom,Image(i,PreImagesRepresentative(isom,j))))); # hom2.isMapping:=true; # Add(hom,hom2); # od; # func:=hom; # else # isom:=false; # fi;
len:=Length(e);
if IsBound(opt.groups) then
start:=0; while start+1<=Length(e) and ForAll(opt.groups,i->IsSubgroup(e[start+1],i)) do
start:=start+1;
od;
Info(InfoPcSubgroup,1,"starting index ",start);
epi:=NaturalHomomorphismByNormalSubgroup(g,e[start]);
lastepi:=epi;
f:=Image(epi,g);
grps:=List(opt.groups,i->Image(epi,i)); if not IsBound(opt.grpsnorms) then
opt:=ShallowCopy(opt);
opt.grpsnorms:=List(opt.groups,i->Normalizer(e[1],i)); fi;
grpsnorms:=List(opt.grpsnorms,i->Image(epi,i)); else # search the largest elementary abelian quotient
start:=2; while start<len and IsElementaryAbelian(g/e[start+1]) do
start:=start+1;
od;
# compute all subgroups there if start<len then # form only factor groups if necessary
epi:=NaturalHomomorphismByNormalSubgroup(g,e[start]);
LockNaturalHomomorphismsPool(g,e[start]);
f:=Image(epi,g); else
f:=g;
epi:=IdentityMapping(f); fi;
lastepi:=epi;
efunc:=List(func,i->InducedAutomorphism(epi,i));
grps:=InvariantSubgroupsElementaryAbelianGroup(f,efunc);
Assert(1,ForAll(grps,i->ForAll(efunc,j->Image(j,i)=i)));
grpsnorms:=List(grps,i->f);
Info(InfoPcSubgroup,5,List(grps,Size),List(grpsnorms,Size));
fi;
for i in [start+1..len] do
Info(InfoPcSubgroup,1," step ",i,": ",Index(e[i-1],e[i]),", ",
Length(grps)," groups"); # compute modulo e[i] if i<len then # form only factor groups if necessary
epi:=NaturalHomomorphismByNormalSubgroup(g,e[i]);
f:=Image(epi,g); else
f:=g;
epi:=IdentityMapping(g); fi;
home:=HomePcgs(f); # we want to compute wrt. this pcgs
n:=Image(epi,e[i-1]);
# the induced factor automs
efunc:=List(func,i->InducedAutomorphism(epi,i)); # filter the non-trivial ones
efunc:=Filtered(efunc,i->ForAny(GeneratorsOfGroup(f),j->Image(i,j)<>j));
if Length(efunc)>0then
efnorm:=Image(epi,funcnorm); fi;
if Length(efunc)=0then
ophom:=ActionSubspacesElementaryAbelianGroup(f,n);
B:=ophom[1];
Info(InfoPcSubgroup,2," ",Length(B)," normal subgroups");
ophom:=ophom[2];
for j in ex do
Add(ngrps,B[Representative(j)]);
Add(ngrpsnorms,StabilizerOfExternalSet(j)); # Assert(1,Normalizer(f,B[j[1]])=ngrpsnorms[Length(ngrps)]);
od;
else
B:=InvariantSubgroupsElementaryAbelianGroup(n,efunc);
ophom:=false;
Info(InfoPcSubgroup,2," ",Length(B)," normal subgroups");
# note the groups in B
ngrps:=SubgroupsOrbitsAndNormalizers(f,B,false);
ngrpsnorms:=List(ngrps,i->i.normalizer);
ngrps:=List(ngrps,i->i.representative); fi;
# Get epi to the old factor group # as hom:=NaturalHomomorphism(f,fa); does not work, we have to play tricks
hom:=lastepi;
lastepi:=epi;
fa:=Image(hom,g);
# lift the known groups for j in [1..Length(grps)] do
gj:=grps[j]; if Size(gj)>1then
a:=PreImage(hom,gj);
Assert(1,Size(a)=Size(gj)*Size(n));
Add(ngrps,a);
no:=PreImage(hom,grpsnorms[j]);
Add(ngrpsnorms,no);
if Length(efunc)>0then # get the double cosets
t:=List(DoubleCosets(f,no,efnorm),Representative);
Info(InfoPcSubgroup,2," |t|=",Length(t));
t:=Filtered(t,i->HasInvariantConjugateSubgroup(a,i,efunc));
Info(InfoPcSubgroup,2,"invar:",Length(t)); fi;
# we have to extend with those b in B, that are normal in a if ophom<>false then #aop:=Image(ophom,a); #SetIsSolvableGroup(aop,true);
if Length(GeneratorsOfGroup(a))>2then
bs:=SmallGeneratingSet(a); else
bs:=GeneratorsOfGroup(a); fi;
bs:=List(bs,i->Image(ophom,i));
bsp:=Filtered([1..Length(B)],i->ForAll(bs,j->i^j=i)
and Size(B[i])<Size(n));
bs:=B{bsp}; else
bsp:=false;
bs:=Filtered(B,i->IsNormal(a,i) and Size(i)<Size(n)); fi;
if Length(efunc)>0 and Length(t)>1then # compute also the invariant ones under the conjugates: # equivalently: Take all equivalent ones and take those, whose # conjugates lie in a and are normal under a for k in Filtered(t,i->not i in no) do
bs:=Union(bs,Filtered(List(B,i->ConjugateSubgroup(i,k^(-1))),
i->IsSubset(a,i) and IsNormal(a,i) and Size(i)<Size(n) ));
od; fi;
# take only those bs which are valid if consider<>false then
Info(InfoPcSubgroup,2," ",Length(bs)," subgroups lead to "); if bsp<>false then
bsp:=Filtered(bsp,j->consider(no,a,n,B[j],e[i])<>false);
IsSSortedList(bsp);
bs:=bsp; # to get the 'Info' right else
bs:=Filtered(bs,j->consider(no,a,n,j,e[i])<>false); fi;
Info(InfoPcSubgroup,2,Length(bs)," valid ones"); fi;
if ophom<>false then #nohom:=List(GeneratorsOfGroup(no),i->Image(ophom,i)); #aop:=SubgroupNC(Image(ophom),nohom); #nohom:=GroupHomomorphismByImagesNC(no,aop, # GeneratorsOfGroup(no),nohom);
if Length(bsp)>0then
oppcgs:=Pcgs(no);
oppcgsimg:=List(oppcgs,i->Image(ophom,i));
ex:=ExternalSet(no,bsp,oppcgs,oppcgsimg,OnPoints);
ex:=ExternalOrbitsStabilizers(ex);
bs:=[];
bsnorms:=[]; for bpos in ex do
Add(bs,B[Representative(bpos)]);
Add(bsnorms,StabilizerOfExternalSet(bpos)); # Assert(1,Normalizer(no,B[bpos[1]])=Last(bsnorms));
od; fi;
else # fuse under the action of no and compute the local normalizers
bs:=SubgroupsOrbitsAndNormalizers(no,bs,true);
bsnorms:=List(bs,i->i.normalizer);
bs:=List(bs,i->i.representative); fi;
# now run through the b in bs for bpos in [1..Length(bs)] do
b:=bs[bpos];
Assert(2,IsNormal(a,b)); # test, whether we'll have to consider this case
# this test has basically be done before the orbit calculation already # if consider<>false and consider(a,n,b,e[i])=false then # Info(InfoPcSubgroup,2," Ignoring case"); # s:=[];
# test, whether b is invariant if Length(efunc)>0then # extend to dcs of bnormalizer
s:=RightTransversal(no,bsnorms[bpos]);
nag:=Length(s);
s:=Concatenation(List(s,i->List(t,j->i*j)));
z:=Length(s); #NOCH: Fusion # test, which ones are usable at all
s:=Filtered(s,i->HasInvariantConjugateSubgroup(b,i,efunc));
Info(InfoPcSubgroup,2," |s|=",nag,"-(m)>",z,"-(i)>",Length(s)); else
s:=[()]; fi;
if Length(s)>0then
nag:=InducedPcgs(home,n);
nag:=nag mod InducedPcgs(nag,b); # if Index(Parent(a),a.normalizer)>1 then # Info(InfoPcSubgroup,2," normalizer index ", # Index(Parent(a),a.normalizer)); # fi;
z:=rec(group:=a,
generators:=InducedPcgs(home,a) mod NumeratorOfModuloPcgs(nag),
modulePcgs:=nag);
OCOneCocycles(z,true); if IsBound(z.complement) and # normal complements exist, iff the coboundaries are trivial
(normal=false or Dimension(z.oneCoboundaries)=0) then # now fetch the complements
# compute fusion
kconh:=List([1..Length(com)],i->[i]); if i<len or retnorm then # we need to compute normalizers
comnorms:=[]; else
comnorms:=fail; fi;
if Length(com)>1 and Size(a)<Size(bsnorms[bpos]) then
opr:=function(cyc,elm)
local l,i;
l:=z.cocycleToList(cyc); for i in [1..Length(l)] do
l[i]:=(z.complementGens[i]*l[i])^elm;
od;
l:=CorrespondingGeneratorsByModuloPcgs(z.origgens,l); for i in [1..Length(l)] do
l[i]:=LeftQuotient(z.complementGens[i],l[i]);
od;
l:=z.listToCocycle(l);
return SiftedVector(coboundbas,l); end;
for k in xo do
l:=List(k,i->Position(com,i)); if comnorms<>fail then
comnorms[l[1]]:=StabilizerOfExternalSet(k);
isTrueComnorm:=false; fi;
l:=Set(l); for kp in l do
kconh[kp]:=l;
od;
od;
elif comnorms<>fail then if Size(a)=Size(bsnorms[bpos]) then
comnorms:=List(com,i->z.cocycleToComplement(i));
isTrueComnorm:=true;
comnorms:=List(comnorms,
i->ClosureSubgroup(CentralizerModulo(n,b,i),i)); else
isTrueComnorm:=false;
comnorms:=List(com,i->bsnorms[bpos]); fi; fi;
if Length(efunc)>0then
ncom:=[];
#search for invariant ones
# force exponents corresponding to vector space
# get matrices for the inner automorphisms # conj:=[]; # for k in GeneratorsOfGroup(a) do # mat:=[]; # for l in nag do # Add(mat,One(field)*ExponentsOfPcElement(nag,l^k)); # od; # Add(conj,mat); # od;
conj:=LinearOperationLayer(a,GeneratorsOfGroup(a),nag);
# now run through the complements for kp in [1..Length(com)] do
if kconh[kp]=fail then
Info(InfoPcSubgroup,3,"already conjugate"); else
l:=z.cocycleToComplement(com[kp]); # the projection on the complement
k:=ClosureSubgroup(b,l); if Length(s)=1 and IsOne(s[1]) then # special case -- no conjugates if ForAll(efunc,x->ForAll(GeneratorsOfGroup(l),
y->ImagesRepresentative(x,y) in k)) then
l:=rec(representative:=k); if comnorms<>fail then if IsBound(comnorms[kp]) then
l.normalizer:=comnorms[kp]; else
l.normalizer:=Normalizer(bsnorms[bpos],
ClosureSubgroup(b,k)); fi; fi;
Add(ncom,l);
# tag all conjugates for l in kconh[kp] do
kconh[l]:=fail;
od; fi;
# now run through the conjugating elements
conjnr:=1;
found:=false; while conjnr<=Length(s) and found=false do if not IsBound(smats[conjnr]) then # compute the matrix action for the induced, jugated # morphisms
m:=s[conjnr];
smats[conjnr]:=[];
shoms[conjnr]:=[]; for l in efunc do # the induced, jugated morphism
shom:= GroupHomomorphismByImagesNC(a,a,
GeneratorsOfGroup(a),
List(GeneratorsOfGroup(a),
i->Image(l,i^m)^Inverse(m)));
mats:=smats[conjnr]; # now test whether the complement k can be conjugated to # be invariant under the morphisms to mats
glsyl:=List(nag,i->[]);
glsyr:=[]; for l in [1..Length(efunc)] do
kgens:=GeneratorsOfGroup(k); for kgnr in [1..Length(kgens)] do
kgn:=Image(shoms[conjnr][l],kgens[kgnr]);
kgim:=Image(comproj,kgn);
Assert(2,kgim^-1*kgn in n); # nt part
kgn:=kgim^-1*kgn;
# translate into matrix terms
kgim:=Image(chom,kgim);
kgn:=One(field)*ExponentsOfPcElement(nag,kgn);
# the matrix action
mat:=idmat+(mats[l]-idmat)*kgim-mats[l];
# store action and vector for m in [1..Length(glsyl)] do
glsyl[m]:=Concatenation(glsyl[m],mat[m]);
od;
glsyr:=Concatenation(glsyr,kgn);
od;
od;
# a possible conjugating element is a solution of the # large LGS
l:= SolutionMat(glsyl,glsyr); if l <> fail then
m:=Product([1..Length(l)],
i->nag[i]^IntFFE(l[i])); # note that we found one!
found:=[s[conjnr],m]; fi;
conjnr:=conjnr+1;
od;
# there is an invariant complement? if found<>false then
found:=found[2]*found[1];
l:=ConjugateSubgroup(ClosureSubgroup(b,k),found);
Assert(1,ForAll(efunc,i->Image(i,l)=l));
l:=rec(representative:=l); if comnorms<>fail then if IsBound(comnorms[kp]) then
l.normalizer:=ConjugateSubgroup(comnorms[kp],found); else
l.normalizer:=ConjugateSubgroup(
Normalizer(bsnorms[bpos],
ClosureSubgroup(b,k)), found); fi; fi;
Add(ncom,l);
# tag all conjugates for l in kconh[kp] do
kconh[l]:=fail;
od;
fi;
fi;
fi; # if not already a conjugate
od;
# if invariance test needed else # get representatives of the fused complement classes
l:=Filtered([1..Length(com)],i->kconh[i][1]=i);
ncom:=[]; for kp in l do
m:=rec(representative:=
ClosureSubgroup(b,z.cocycleToComplement(com[kp]))); if comnorms<>fail then
m.normalizer:=comnorms[kp]; fi;
Add(ncom,m);
od; fi;
com:=ncom;
# take the preimages for k in com do
Assert(1,ForAll(efunc,i->Image(i,k.representative)
=k.representative));
Add(ngrps,k.representative); if IsBound(k.normalizer) then if isTrueComnorm then
Add(ngrpsnorms,k.normalizer); else
Add(ngrpsnorms,Normalizer(k.normalizer,k.representative)); fi; fi;
od; fi; fi;
od;
if isom<>fail then
grps:=List(grps,j->PreImage(isom,j)); if retnorm then
grpsnorms:=List(grpsnorms,j->PreImage(isom,j)); fi; fi;
if retnorm then
return [grps,grpsnorms]; else
return grps; fi; end);
############################################################################# ## #M CharacteristicSubgroups( <G> ) ##
InstallMethod(CharacteristicSubgroups,"solvable, automorphisms",true,
[IsGroup and IsSolvableGroup],0, function(G)
local A,s; if AbelianRank(G)<5then
TryNextMethod(); fi;
A:=AutomorphismGroup(G);
s:=SubgroupsSolvableGroup(G,rec(normal:=true,actions:=GeneratorsOfGroup(A)));
return Filtered(s,x->IsCharacteristicSubgroup(G,x)); end);
############################################################################# ## #M LatticeSubgroups(<G>) . . . . . . . . . . lattice of subgroups ##
InstallMethod(LatticeSubgroups,"elementary abelian extension",true,
[IsGroup and IsFinite and CanComputeFittingFree], # want to be better than cyclic extension. 1, function(G)
local s,i,c,classes, lattice,map,GI;
if Size(G)=1 or not IsSolvableGroup(G) then#or not CanEasilyComputePcgs(G) then
TryNextMethod(); fi; if not IsPcGroup(G) or IsPermGroup(G) then
map:=IsomorphismPcGroup(G);
GI:=Image(map,G); else
map:=fail;
GI:=G; fi;
s:=SubgroupsSolvableGroup(GI,rec(retnorm:=true));
classes:=[]; for i in [1..Length(s[1])] do if map=fail then
c:=ConjugacyClassSubgroups(G,s[1][i]);
SetStabilizerOfExternalSet(c,s[2][i]); else
c:=ConjugacyClassSubgroups(G,PreImage(map,s[1][i]));
SetStabilizerOfExternalSet(c,PreImage(map,s[2][i])); fi;
Add(classes,c);
od;
SortBy(classes, a -> Size(Representative(a)));
# create the lattice
lattice:=Objectify(NewType(FamilyObj(classes),IsLatticeSubgroupsRep),
rec());
lattice!.conjugacyClassesSubgroups:=classes;
lattice!.group :=G;
# return the lattice
return lattice;
end);
# ############################################################################# # ## # #M NormalSubgroups(<G>) . . . . . . . . . . list of normal subgroups # ## # InstallMethod(NormalSubgroups,"elementary abelian extension",true, # [CanEasilyComputePcgs],0, # function(G) # local n; # n:=SubgroupsSolvableGroup(G,rec( # actions:=List(GeneratorsOfGroup(G),i->InnerAutomorphism(G,i)), # normal:=true)); # # # sort the normal subgroups according to their size # SortBy(n, Size); # # return n; # end);
############################################################################# ## #F SizeConsiderFunction(<size>) returns auxiliary function for ## 'SubgroupsSolvableGroup' that allows one to discard all subgroups whose ## size is not divisible by <size> ##
InstallGlobalFunction(SizeConsiderFunction,function(size)
return function(c,a,n,b,m)
return IsInt(Size(a)/Size(n)*Size(b)*Size(m)/size); end; end);
############################################################################# ## #F ExactSizeConsiderFunction(<size>) returns auxiliary function for ## 'SubgroupsSolvableGroup' that allows one to discard all subgroups whose ## size is not <size> ##
InstallGlobalFunction(ExactSizeConsiderFunction,function(size)
return function(c,a,n,b,m)
local result;
result:=IsInt(Size(a)/Size(n)*Size(b)*Size(m)/size)
and not (Size(a)/Size(n)*Size(b))>size;
return result; end; end);
BindGlobal("ElementaryAbelianConsider", function(c,a,n,b,m)
return HasElementaryAbelianFactorGroup(a,n) and
ForAll(GeneratorsOfGroup(a),x->ForAll(GeneratorsOfGroup(b),y->Comm(x,y)
in m)); end);
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.