Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  grppclat.gi   Sprache: unbekannt

 
#############################################################################
##
##  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)>2 then
    N:=arg[3];
    e:=[G,N];
    if Length(arg)>3 then
      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)=2 then
    dims:=[0..d];
  else
    dims:=arg[3];
  fi;

  if Length(dims)=0 then
    return [];
  fi;

  if Length(op)=0 then

    # 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<3 then 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>1 then
      compl:=[ShallowCopy(id)];
    else
      compl:=[];
    fi;
    if d>2 then
      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=0 then
            # 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:=GModuleByMats(ma,f);
    mat:=MTX.BasesSubmodules(ma);

    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)=2 then
    dims:=[0..d];
  else
    dims:=arg[3];
  fi;

  if Length(dims)=0 then
    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=2 then
    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<3 then compldim:=[]; fi;
  dodim:=Maximum(dodim);

  # enumerate spaces
  id:= Immutable( IdentityMat(d, one) );
  ma:=[[],[id[1]]];
  # the complements to ma
  if d>1 then
    compl:=[ShallowCopy(id)];
  else
    compl:=[];
  fi;
  if d>2 then
    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=0 then
          # 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=1 then
      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;

  ma:= GroupByGenerators( perms, () );
  #Assert(1,Group(perms)=Action(P,new));

  op:=GroupHomomorphismByImagesNC(P,ma,Concatenation(Pcgens,Pgens),
    Concatenation(List(Pcgens,i->()),perms));
#  Assert(1,Size(P)=Size(KernelOfMultiplicativeGeneralMapping(op))
#                   *Size(Image(op)));
  return [new,op];

end);

# 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;

    Assert(1,IsSubgroup(g,funcnorm));

    # compute <func> characteristic series
    e:=InvariantElementaryAbelianSeries(g,func);
  else
    func:=[];
    funcnorm:=g;
    e:=ElementaryAbelianSeriesLargeSteps(g);
  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)>0 then
      efnorm:=Image(epi,funcnorm);
    fi;

    if Length(efunc)=0 then
      ophom:=ActionSubspacesElementaryAbelianGroup(f,n);
      B:=ophom[1];
      Info(InfoPcSubgroup,2,"  ",Length(B)," normal subgroups");
      ophom:=ophom[2];

      ngrps:=[];
      ngrpsnorms:=[];
      oppcgs:=Pcgs(Source(ophom));
      oppcgsimg:=List(oppcgs,i->Image(ophom,i));
      ex:=[1..Length(B)];
      IsSSortedList(ex);
      ex:=ExternalSet(Source(ophom),ex,oppcgs,oppcgsimg,OnPoints);
      ex:=ExternalOrbitsStabilizers(ex);

      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);

    hom:= GroupHomomorphismByImagesNC(f,fa,GeneratorsOfGroup(f),
           List(GeneratorsOfGroup(f),i->
             Image(hom,PreImagesRepresentative(epi,i))));
    Assert(2,KernelOfMultiplicativeGeneralMapping(hom)=n);

    # lift the known groups
    for j in [1..Length(grps)] do

      gj:=grps[j];
      if Size(gj)>1 then
        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)>0 then
          # 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))>2 then
            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)>1 then
          # 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)>0 then
            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;

Assert(1,ForAll(bs,i->ForAll(efunc,j->Image(j,i)=i)));

        # 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)>0 then
            # 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)>0 then
            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

              z.factorGens:=z.generators;
              coboundbas:=Basis(z.oneCoboundaries);
              com:=BaseSteinitzVectors(BasisVectors(Basis(z.oneCocycles)),
                                       BasisVectors(coboundbas));
              field:=LeftActingDomain(z.oneCocycles);
              if Size(field)^Length(com.factorspace)>100000 then
                Info(InfoWarning,1, "Many (",
                  Size(field)^Length(com.factorspace),") complements!");
              fi;
              com:=Enumerator(VectorSpace(field,com.factorspace,
                                               Zero(z.oneCocycles)));
              Info(InfoPcSubgroup,3,"  ",Length(com),
                   " local complement classes");

              # 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;

                xo:=ExternalOrbitsStabilizers(
                     ExternalSet(bsnorms[bpos],com,opr));

                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)>0 then
                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);

                idmat:=conj[1]^0;
                mat:= GroupByGenerators( conj, idmat );
                chom:= GroupHomomorphismByImagesNC(a,mat,
                        GeneratorsOfGroup(a),conj);

                smats:=[];
                shoms:=[];

                fghom:=Concatenation(z.factorGens,GeneratorsOfGroup(n));
                bgids:=List(GeneratorsOfGroup(n),i->One(b));

                # 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;

                    else
                      # generic case

                      comproj:= GroupHomomorphismByImagesNC(a,a,fghom,
                                Concatenation(GeneratorsOfGroup(l),bgids));

                      # 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)));

                            mat:=List(nag,
                                  i->One(field)*ExponentsOfPcElement(nag,
                                  Image(shom,i)));
                            Add(smats[conjnr],mat);
                            Add(shoms[conjnr],shom);
                          od;
                        fi;

                        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;

      fi;
    od;

    grps:=ngrps;
    grpsnorms:=ngrpsnorms;
    Info(InfoPcSubgroup,5,List(grps,Size),List(grpsnorms,Size));
  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)<5 then
    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);

[ Dauer der Verarbeitung: 0.43 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge