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


Quelle  schur.gi   Sprache: unbekannt

 
#############################################################################
##
##  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] = 0 do
      i := i+1;
    od;
    if i <= n then  r := r+1; fi;
  od;
  r := r-1;

  if r > 0 then
    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;

  # make the group
  D:=D/Drels;
  return D;
end);

InstallMethod(SchurCover,"of fp group",true,[IsSubgroupFpGroup],0,
  SchurCoverFP);

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

  hom:=GroupHomomorphismByImagesNC(D,G,GeneratorsOfGroup(D),
   List(Dgens,i->PreImagesRepresentative(iso,i)));
  Dgens:=TzImagesOldGens(p);
  Dgens:=List(Dgens{[Length(Fgens)+1..Length(Dgens)]},
           i->MappedWord(i,p!.generators,GeneratorsOfGroup(D)));
  SetKernelOfMultiplicativeGeneralMapping(hom,SubgroupNC(D,Dgens));

  return hom;
end);


# 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)=1 then
      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;

  pcgs:=Pcgs(s);
  n:=Normalizer(g,s);
  l:=LogInt(Size(s),p);

  # 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)=1 then
    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)>1 do
    if Order(dc[i])>1 then # the trivial element will not do anything
      q:=Intersection(s,ConjugateSubgroup(s,dc[i]^-1));
      if Size(q)>1 then
        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;

end);

InstallMethod(AbelianInvariantsMultiplier,"naive",true,
  [IsGroup],1, G->AbelianInvariants(KernelOfMultiplicativeGeneralMapping(EpimorphismSchurCover(G))));

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

  rels:=RelatorsOfFpGroup(Source(FG));
  gens:=List(GeneratorsOfGroup(Source(FG)),i->Image(FG,i));

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

  evals:=[];

  for rp in [1..Length(rels)] do

    CompletionBar(InfoSchur,2,"Relator Loop: ",rp/Length(rels));
    r:=rels[rp];
    i:=LetterRepAssocWord(r);
    a:=One(D);

    # take care of inverses
    for l in [1..Length(i)] do
      if i[l]<0 then
        #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<0 then
          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;

      #Print(PreImagesRepresentative(s,Image(s,h))*h,"\n");
      #a:=a/PreImagesRepresentative(s,Image(s,h))*h;
      a:=a/h*elp[Position(el,Image(s,h))];

    od;
    Add(evals,[r,a]);
  od;
  CompletionBar(InfoSchur,2,"Relator Loop: ",false);
  return evals;
end);

InstallGlobalFunction(RelatorFixedMultiplier,function(hom,p)
local G,B,P,s,D,i,j,v,ri,rank,bas,basr,row,rel,sol,snf,mat;
  G:=Source(hom);
  rank:=Length(GeneratorsOfGroup(G));
  B:=ImagesSource(hom);
  P:=SylowSubgroup(B,p);

  s:=SchuMu(B,p);
  D:=Source(s);
  ri:=CorestEval(hom,s);

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

end);

BindGlobal("MulExt",function(G,pl)
local hom,      #isomorphism fp
      ng,ngl,   # nr generators,list
      s,sl,     # SchuMu,list
      ab,ms,    # abelian invariants, multiplier size
      pll,      # relevant primes
      F,        # free group
      rels,     # relators
      rel2,     # cohomology relators
      ce,       # corestriction
      p,pp,     # prime, index
      mg,       # multiplier generators
      sdc,      # decomposition function
      gens,free,# generators
      i,j,      # loop
      q,qhom;   # quotient



  # eliminate useless primes
  pl:=Intersection(pl,
        List(Filtered(Collected(Factors(Size(G))),i->i[2]>1),i->i[1]));

  hom:=IsomorphismFpGroup(G);
  hom:=hom*IsomorphismSimplifiedFpGroup(Image(hom));
  Info(InfoSchur,2,Length(RelatorsOfFpGroup(Range(hom)))," relators");

  # think positive...
  #if SYF then
  #  hom:=PositiveExponentsPresentationFpHom(hom);
  #fi;

  hom:=InverseGeneralMapping(hom);
  ng:=Length(GeneratorsOfGroup(Source(hom)));

  sl:=[];
  ngl:=[ng];
  pll:=[];
  ms:=1;
  for p in pl do
    s:=SchuMu(G,p);
    if Size(KernelOfMultiplicativeGeneralMapping(s))>1 then
      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)=0 then
    return IdentityMapping(G);
  fi;

  #F:=FreeGroup(List([1..Last(ngl)],x->Concatenation("@",String(x))));
  F:=FreeGroup(Last(ngl));

  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;

    sdc:=GroupHomomorphismByImagesNC(F,KernelOfMultiplicativeGeneralMapping(s),
          GeneratorsOfGroup(F),sdc);

    gens:=GeneratorsOfGroup(F){[ngl[pp]+1..ngl[pp+1]]};
    ce:=CorestEval(hom,s);

    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()>0 then
    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)>1 then
    pl:=arg[2];
  else
    pl:=PrimeDivisors(Size(G));
  fi;
  return MulExt(G,pl);
end );

InstallMethod(EpimorphismSchurCover,"Holt's algorithm",true,[IsGroup],0,
 DoMulExt);

InstallOtherMethod(EpimorphismSchurCover,"Holt's algorithm, primes",true,
  [IsGroup,IsList],0,DoMulExt);

InstallMethod(SchurCover,"general: Holt's algorithm",true,[IsGroup],0,
  G->Source(EpimorphismSchurCover(G)));

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

            return GroupHomomorphismByImages(
                       D, Image(epi,D),
                       AsSSortedList(D), AsSSortedList(Image(epi,D)));
        fi;

        return GroupHomomorphismByImages(
                   D, Image(epi,D),
                   GeneratorsOfGroup(D),
                   List(GeneratorsOfGroup(D),x->Image(epi,x)));

    end
);

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

[ Dauer der Verarbeitung: 0.6 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