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


Quelle  pcgsmodu.gi   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Frank Celler.
##
##  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   methods for polycyclic generating  systems modulo
##  another such system.
##


#############################################################################
##
#R  IsModuloPcgsRep
##
DeclareRepresentation( "IsModuloPcgsRep", IsPcgsDefaultRep,
    [ "moduloDepths", "moduloMap", "numerator", "denominator",
      "depthMap" ] );


#############################################################################
##
#R  IsModuloTailPcgsRep
##
DeclareRepresentation( "IsModuloTailPcgsRep", IsModuloPcgsRep,
    [ "moduloDepths", "moduloMap", "numerator", "denominator",
      "depthMap" ] );

#############################################################################
##
#R  IsSubsetInducedNumeratorModuloTailPcgsRep(<obj>)
##
DeclareRepresentation( "IsSubsetInducedNumeratorModuloTailPcgsRep",
    IsModuloTailPcgsRep,
    [ "moduloDepths", "moduloMap", "numerator", "denominator",
      "depthMap","depthsInParent","numeratorParent","parentZeroVector" ] );

#############################################################################
##
#R  IsModuloTailPcgsByListRep(<obj>)
##
DeclareRepresentation( "IsModuloTailPcgsByListRep", IsModuloTailPcgsRep,
    [ "moduloDepths", "moduloMap", "numerator", "denominator",
      "depthMap","depthsInParent","numeratorParent","parentZeroVector" ] );

#############################################################################
##
#R  IsNumeratorParentForExponentsRep(<obj>)
##
##  modulo pcgs in this representation can use the numerator parent for
##  computing exponents
DeclareRepresentation( "IsNumeratorParentForExponentsRep",
    IsModuloPcgsRep,
    [ "moduloDepths", "moduloMap", "numerator", "denominator",
      "depthMap","depthsInParent","numeratorParent","parentZeroVector" ] );

#############################################################################
##
#R  IsNumeratorParentLayersForExponentsRep(<obj>)
##
##  modulo pcgs in this representation can use the numerator parent for
##  computing exponents by working in elementary abelian layers (but not in
##  one chunk, as there are cofactors).
DeclareRepresentation( "IsNumeratorParentLayersForExponentsRep",
    IsModuloPcgsRep,
    [ "moduloDepths", "moduloMap", "numerator", "denominator",
      "depthMap","depthsInParent","numeratorParent","parentZeroVector" ] );

#############################################################################
##
#M  IsBound[ <pos> ]
##
InstallMethod( IsBound\[\],
    true,
    [ IsModuloPcgs,
      IsPosInt ],
    0,

function( pcgs, pos )
    return pos <= Length(pcgs);
end );


#############################################################################
##
#M  Length( <pcgs> )
##
InstallMethod( Length,"modulo pcgs",
    true,
    [ IsModuloPcgs ],
    0,
    pcgs -> Length(pcgs!.pcSequence) );


#############################################################################
##
#M  Position( <pcgs>, <elm>, <from> )
##
InstallMethod( Position,"modulo pcgs",
    true,
    [ IsModuloPcgs ,
      IsObject,
      IsInt ],
    0,

function( pcgs, obj, from )
    return Position( pcgs!.pcSequence, obj, from );
end );


#############################################################################
##
#M  PrintObj( <modulo-pcgs> )
##
InstallMethod( PrintObj,"modulo pcgs",
    true,
    [ IsModuloPcgs ],
    0,

function( obj )
    Print( "(", NumeratorOfModuloPcgs(obj), " mod ",
           DenominatorOfModuloPcgs(obj), ")" );
end );


#############################################################################
##
#M  <pcgs> [ <pos> ]
##
InstallMethod( \[\],"modulo pcgs",
    true,
    [ IsModuloPcgs,
      IsPosInt ],
    0,

function( pcgs, pos )
    return pcgs!.pcSequence[pos];
end );

#############################################################################
##
#M  ModuloTailPcgsByList( <home>, <list>, <taildepths> )
##
InstallGlobalFunction( ModuloTailPcgsByList,
function( home, factor, wm )
local   wd,  filter,  new,  i;

  if IsSubset(home,factor) then
    wd:=List(factor,i->Position(home,i));
  else
    wd:=List(factor,i->DepthOfPcElement(home,i));
  fi;

  # check which filter to use
  filter := IsModuloPcgs and IsModuloTailPcgsRep
            and IsModuloTailPcgsByListRep;

  if IsSubset(home,factor) then
    filter:=filter and IsSubsetInducedNumeratorModuloTailPcgsRep;
  fi;

  if Length(wd)=Length(Set(wd)) then
    # the depths are all different. We can get the exponetnts from the
    # parent pcgs
    filter:=filter and IsNumeratorParentForExponentsRep;
  fi;

  # this can be more messy -- do not use
  if HasIsFamilyPcgs(home)
      and IsFamilyPcgs(home) then
    filter:=filter and IsNumeratorParentPcgsFamilyPcgs;
  fi;

  if IsPrimeOrdersPcgs(home)  then
      filter := filter and HasIsPrimeOrdersPcgs and IsPrimeOrdersPcgs
                       and HasIsFiniteOrdersPcgs and IsFiniteOrdersPcgs;
  elif IsFiniteOrdersPcgs(home)  then
      filter := filter and HasIsFiniteOrdersPcgs and IsFiniteOrdersPcgs;
  fi;

  # construct a pcgs from <pcs>
  new := PcgsByPcSequenceCons(
              IsPcgsDefaultRep,
              filter,
              FamilyObj(OneOfPcgs(home)),
              factor,[]);

  SetRelativeOrders(new,RelativeOrders(home){wd});
  # store other useful information
  new!.moduloDepths := wm;

  # setup the maps
  new!.moduloMap := [];
  for i  in [ 1 .. Length(wm) ]  do
      new!.moduloMap[wm[i]] := i;
  od;
  new!.depthMap := [];
  for i  in [ 1 .. Length(wd) ]  do
      new!.depthMap[wd[i]] := i;
  od;

  new!.numeratorParent:=home;
  new!.depthsInParent:=wd;
  new!.parentZeroVector:=home!.zeroVector;

  # and return
  return new;
end);

#############################################################################
##
#M  ModuloPcgsByPcSequenceNC( <home>, <pcs>, <modulo> )
##
InstallMethod( ModuloPcgsByPcSequenceNC, "generic method for pcgs mod pcgs",
    true, [ IsPcgs, IsList, IsPcgs ], 0,

function( home, list, modulo )
    local   pcgs,  wm,  wp,  wd,  pcs,  filter,  new,
    i,depthsInParent,dd,par,sel,
    pcsexp,denexp,bascha,idx,sep,sed,mat;

    # <list> is a pcgs for the sum of <list> and <modulo>
    if IsPcgs(list) and (ParentPcgs(modulo) = list or IsSubset(list,modulo))
      then
        pcgs := list;
        wm   := List( modulo, x -> DepthOfPcElement( pcgs, x ) );
        wp   := [ 1 .. Length(list) ];
        wd   := Difference( wp, wm );
        pcs  := list{wd};

    # otherwise compute the sum
    else
        pcgs := SumPcgs( home, modulo, list );
        wm   := List( modulo, x -> DepthOfPcElement( pcgs, x ) );
        wp   := List( list,   x -> DepthOfPcElement( pcgs, x ) );
        if not IsSubset( pcgs, list )  then
            pcgs := List(pcgs);
            for i  in [ 1 .. Length(list) ]  do
                pcgs[wp[i]] := list[i];
            od;
            pcgs := InducedPcgsByPcSequenceNC( home, pcgs );
        fi;
        wd   := Difference( wp, wm );
        pcs  := list{ List( wd, x -> Position( wp, x ) ) };
    fi;

    # check which filter to use
    filter := IsModuloPcgs and
              HasDenominatorOfModuloPcgs and HasNumeratorOfModuloPcgs;

    depthsInParent:=fail; # do not set by default
    dd:=fail; # do not set by default
    if IsEmpty(wd) or Last(wd) = Length(wd)  then
        filter := filter and IsModuloTailPcgsRep;
        # are we even: tail mod further tail?
        if IsSubsetInducedPcgsRep(pcgs) and IsModuloTailPcgsRep(pcgs)
          and IsBound(pcgs!.depthsInParent) then
          filter:=filter and IsSubsetInducedNumeratorModuloTailPcgsRep;
          depthsInParent:=pcgs!.depthsInParent{wd};
          # is everything even family induced?
          if HasIsParentPcgsFamilyPcgs(pcgs)
             and IsParentPcgsFamilyPcgs(pcgs) then
            filter:=filter and IsNumeratorParentPcgsFamilyPcgs;
          fi;
        elif HasIsFamilyPcgs(pcgs) and IsFamilyPcgs(pcgs) then
          # the same if the enumerator is not induced but actually the
          # familypcgs
          filter:=filter and IsSubsetInducedNumeratorModuloTailPcgsRep
                  and IsNumeratorParentPcgsFamilyPcgs;
          depthsInParent:=[1..Length(pcgs)]; # not stored in FamilyPcgs
          depthsInParent:=depthsInParent{wd};
        fi;
    else
      if Length(wd)=Length(Set(wd)) and IsSubset(list,modulo) then
        # the depths are all different and the modulus is just a tail. We
        # can get the exponents from the parent pcgs.
        filter:=filter and IsNumeratorParentForExponentsRep;
        if not IsBound(pcgs!.depthsInParent) then
          pcgs!.depthsInParent:=List(pcgs,i->DepthOfPcElement(Parent(pcgs),i));
        fi;
        depthsInParent:=pcgs!.depthsInParent{wd};
      else
        if HasParentPcgs(pcgs) and
          IsPcgsElementaryAbelianSeries(ParentPcgs(pcgs)) then
          par:=ParentPcgs(pcgs);
          depthsInParent:=List(pcs,x->DepthOfPcElement(par,x));
          dd:=List(modulo,x->DepthOfPcElement(par,x));
          if
            Length(Union(depthsInParent,dd))=Length(depthsInParent)+Length(dd)
            then

            # we can use the parent layers to calculate exponents
            filter:=filter and IsNumeratorParentLayersForExponentsRep;
          else
            depthsInParent:=fail;
          fi;

        fi;

        filter := filter and IsModuloPcgsRep;
      fi;
    fi;
    if IsPrimeOrdersPcgs(home)  then
        filter := filter and HasIsPrimeOrdersPcgs and IsPrimeOrdersPcgs
                        and HasIsFiniteOrdersPcgs and IsFiniteOrdersPcgs;
    elif IsFiniteOrdersPcgs(home)  then
        filter := filter and HasIsFiniteOrdersPcgs and IsFiniteOrdersPcgs;
    fi;

    # store the one and other information

    # construct a pcgs from <pcs>
    new := PcgsByPcSequenceCons(
               IsPcgsDefaultRep,
               filter,
               FamilyObj(OneOfPcgs(pcgs)),
               pcs,
               [DenominatorOfModuloPcgs, modulo,
                NumeratorOfModuloPcgs, pcgs ]);

    SetRelativeOrders(new,RelativeOrders(pcgs){wd});
    # store other useful information
    new!.moduloDepths := wm;

    # setup the maps
    new!.moduloMap := [];
    for i  in [ 1 .. Length(wm) ]  do
        new!.moduloMap[wm[i]] := i;
    od;
    new!.depthMap := [];
    for i  in [ 1 .. Length(wd) ]  do
        new!.depthMap[wd[i]] := i;
    od;

    if depthsInParent<>fail then
      new!.numeratorParent:=ParentPcgs(pcgs);
      new!.depthsInParent:=depthsInParent;
      new!.parentZeroVector:=ParentPcgs(pcgs)!.zeroVector;
    fi;

    if dd<>fail then
      new!.denpardepths:=dd;
      wm:=[];
      for i in [1..Length(dd)] do
        wm[dd[i]]:=i;
      od;
      new!.parentDenomMap:=wm;

      wm:=[];
      for i in [1..Length(depthsInParent)] do
        wm[depthsInParent[i]]:=i;
      od;
      new!.parentDepthMap:=wm;

      if HasIndicesEANormalSteps(par) then
        i:=IndicesEANormalSteps(par);
      else
        i:=IndicesNormalSteps(par);
      fi;
      new!.layranges:=List([1..Length(i)-1],x->[i[x]..i[x+1]-1]);

      pcsexp:=List(pcs,x->ExponentsOfPcElement(par,x));
      denexp:=List(modulo,x->ExponentsOfPcElement(par,x));
      bascha:=List(new!.layranges,x->fail);
      new!.basechange:=bascha;
      idx:=[];
      new!.indices:=idx;
      for i in [1..Length(new!.layranges)] do
        if new!.layranges[i][1]<=Length(wm) then
          dd:=GF(RelativeOrders(par)[new!.layranges[i][1]]);
          sep:=Filtered([1..Length(pcs)],
            x->PositionNonZero(pcsexp[x]) in new!.layranges[i]);
          sed:=Filtered([1..Length(modulo)],
            x->PositionNonZero(denexp[x]) in new!.layranges[i]);
          if Length(sep)>0 or Length(sed)>0 then
            mat:=Concatenation(pcsexp{sep}{new!.layranges[i]},
                  denexp{sed}{new!.layranges[i]})*One(dd);
            mat:=ImmutableMatrix(dd,mat);
            if Length(mat)<Length(mat[1]) then
              # add identity mat vectors at non-pivot positions
              sel:=List(TriangulizedMat(mat),PositionNonZero);
              sel:=Difference([1..Length(mat[1])],sel);
              mat:=Concatenation(mat,IdentityMat(Length(mat[1]),dd){sel});
              mat:=ImmutableMatrix(dd,mat);
            fi;;
            bascha[i]:=mat^-1;
            idx[i]:=[sep,sed];
          fi;
        fi;
      od;

    fi;

    # and return
    return new;

end );


#############################################################################
##
#M  ModuloPcgsByPcSequence( <home>, <pcs>, <modulo> )
##
InstallMethod( ModuloPcgsByPcSequence,
    "generic method",
    true,
    [ IsPcgs,
      IsList,
      IsInducedPcgs ],
    0,

function( home, list, modulo )
    return ModuloPcgsByPcSequenceNC( home, list, modulo );
end );


#############################################################################
##
#M  <pcgs1> mod <induced-pcgs2>
##
InstallMethod( MOD,"parent pcgs mod induced pcgs",
    IsIdenticalObj,
    [ IsPcgs,
      IsInducedPcgs ],
    0,

function( pcgs, modulo )
    if ParentPcgs(modulo) <> pcgs  then
        TryNextMethod();
    fi;
    return ModuloPcgsByPcSequenceNC( pcgs, pcgs, modulo );
end );

#############################################################################
##
#M  <pcgs1> mod <pcgs2>
##
InstallMethod( MOD,"two parent pcgs",
    IsIdenticalObj,
    [ IsPcgs,
      IsPcgs ],
    0,

function( pcgs, modulo )
    if modulo <> pcgs  then
        TryNextMethod();
    fi;
    return ModuloPcgsByPcSequenceNC( pcgs, pcgs, modulo );
end );


#############################################################################
##
#M  <induced-pcgs1> mod <induced-pcgs2>
##
InstallMethod( MOD,"two induced pcgs",
    IsIdenticalObj,
    [ IsInducedPcgs,
      IsInducedPcgs ],
    0,

function( pcgs, modulo )
    if ParentPcgs(modulo) <> ParentPcgs(pcgs)  then
        TryNextMethod();
    fi;
    return ModuloPcgsByPcSequenceNC( ParentPcgs(pcgs), pcgs, modulo );
end );


#############################################################################
##
#M  <modulo-pcgs1> mod <modulo-pcgs2>
##
InstallMethod( MOD,"two modulo pcgs",
    IsIdenticalObj,
    [ IsModuloPcgs,
      IsModuloPcgs ],
    0,

function( pcgs, modulo )
    if DenominatorOfModuloPcgs(pcgs) <> DenominatorOfModuloPcgs(modulo)  then
        Error( "denominators of <pcgs> and <modulo> are not equal" );
    fi;
    return NumeratorOfModuloPcgs(pcgs) mod NumeratorOfModuloPcgs(modulo);
end );


#############################################################################
##
#M  <(induced)pcgs1> mod <(induced)pcgs 2>
##
InstallMethod( MOD,"two induced pcgs",
    IsIdenticalObj, [ IsPcgs, IsPcgs ], 0,
function( pcgs, modulo )

  # enforce the same parent pcgs
  if ParentPcgs(modulo) <> ParentPcgs(pcgs)  then
    modulo:=InducedPcgsByGeneratorsNC(ParentPcgs(pcgs),AsList(modulo));
  fi;

  return ModuloPcgsByPcSequenceNC( ParentPcgs(pcgs), pcgs, modulo );
end);

#############################################################################
##
#M  DepthOfPcElement( <modulo-pcgs>, <elm>, <min> )
##
InstallOtherMethod( DepthOfPcElement,
    "pcgs modulo pcgs, ignoring <min>",
    function(a,b,c) return IsCollsElms(a,b); end,
    [ IsModuloPcgs,
      IsObject,
      IsInt ],
    0,

function( pcgs, elm, min )
    local   dep;

    dep := DepthOfPcElement( pcgs, elm );
    if dep < min  then
        Error( "minimal depth <min> is incorrect" );
    fi;
    return dep;
end );


#############################################################################
##
#M  ExponentOfPcElement( <modulo-pcgs>, <elm>, <pos> )
##
InstallOtherMethod( ExponentOfPcElement,
    "pcgs modulo pcgs, ExponentsOfPcElement", IsCollsElmsX,
    [ IsModuloPcgs, IsObject, IsPosInt ], 0,
function( pcgs, elm, pos )
    return ExponentsOfPcElement(pcgs,elm)[pos];
end );


#############################################################################
##
#M  ExponentsOfPcElement( <pcgs>, <elm>, <poss> )
##
InstallOtherMethod( ExponentsOfPcElement,
  "pcgs mod. pcgs,range, falling back to Exp.OfPcElement", IsCollsElmsX,
    [ IsModuloPcgs, IsObject, IsList ], 0,
function( pcgs, elm, pos )
    return ExponentsOfPcElement(pcgs,elm){pos};
end );


#############################################################################
##
#M  IsFiniteOrdersPcgs( <modulo-pcgs> )
##
InstallOtherMethod( IsFiniteOrdersPcgs, true, [ IsModuloPcgs ], 0,
function( pcgs )
    return ForAll( RelativeOrders(pcgs), x -> x <> 0 and x <> infinity );
end );


#############################################################################
##
#M  IsPrimeOrdersPcgs( <modulo-pcgs> )
##
InstallOtherMethod( IsPrimeOrdersPcgs,
    true,
    [ IsModuloPcgs ],
    0,

function( pcgs )
    return ForAll( RelativeOrders(pcgs), IsPrimeInt );
end );



#############################################################################
##
#M  LeadingExponentOfPcElement( <modulo-pcgs>, <elm> )
##
InstallOtherMethod( LeadingExponentOfPcElement,
    "pcgs modulo pcgs, use ExponentsOfPcElement", IsCollsElms,
    [ IsModuloPcgs, IsObject ], 0,
function( pcgs, elm )
    local   exp,  dep;

    exp := ExponentsOfPcElement( pcgs, elm );
    dep := PositionNonZero( exp );
    if Length(exp) < dep  then
        return fail;
    else
        return exp[dep];
    fi;
end );



#############################################################################
##
#M  PcElementByExponentsNC( <pcgs>, <empty-list> )
##
InstallOtherMethod( PcElementByExponentsNC, "generic method for empty lists",
    true, [ IsModuloPcgs, IsList and IsEmpty ], 0,
function( pcgs, list )
    return OneOfPcgs(pcgs);
end );


#############################################################################
##
#M  PcElementByExponentsNC( <pcgs>, <list> )
##

InstallOtherMethod( PcElementByExponentsNC, "generic method: modulo", true,
    [ IsModuloPcgs, IsRowVector and IsCyclotomicCollection ], 0,
function( pcgs, list )
  return DoPcElementByExponentsGeneric(pcgs,pcgs,list);
end);


#############################################################################
##
#M  PcElementByExponentsNC( <pcgs>, <ffe-list> )
##
InstallOtherMethod( PcElementByExponentsNC, "generic method: modulo, FFE",
    true, [ IsModuloPcgs, IsRowVector and IsFFECollection ], 0,
function( pcgs, list )
  return DoPcElementByExponentsGeneric(pcgs,pcgs,list);
end);


#############################################################################
##
#M  PcElementByExponentsNC( <pcgs>, <basis>, <empty-list> )
##
InstallOtherMethod( PcElementByExponentsNC,
    "generic method for empty list as basis or basisindex, modulo", true,
    [ IsModuloPcgs, IsList and IsEmpty, IsList ],
    SUM_FLAGS, #this is better than everything else

function( pcgs, basis, list )
    return OneOfPcgs(pcgs);
end );


#############################################################################
##
#M  PcElementByExponentsNC( <pcgs>, <basis>, <list> )
##
InstallOtherMethod( PcElementByExponentsNC, "generic method: modulo, basis",
    IsFamFamX, [IsModuloPcgs,IsList,IsRowVector and IsCyclotomicCollection], 0,
    DoPcElementByExponentsGeneric );


#############################################################################
##
#M  PcElementByExponentsNC( <pcgs>, <basis>, <list> )
##
InstallOtherMethod( PcElementByExponentsNC,
    "generic method: modulo, basis, FFE", IsFamFamX,
    [ IsModuloPcgs, IsList, IsRowVector and IsFFECollection ], 0,
    DoPcElementByExponentsGeneric );


#############################################################################
##
#M  ReducedPcElement( <pcgs>, <left>, <right> )
##
InstallOtherMethod( ReducedPcElement,
    "pcgs modulo pcgs",
    IsCollsElmsElms,
    [ IsModuloPcgs,
      IsObject,
      IsObject ],
    0,

function( pcgs, left, right )
    # Avoid infinite recursion
    if IsIdenticalObj(NumeratorOfModuloPcgs(pcgs),pcgs) then
      TryNextMethod();
    fi;
    return ReducedPcElement( NumeratorOfModuloPcgs(pcgs), left, right );
end );


#############################################################################
##
#M  RelativeOrderOfPcElement( <pcgs>, <elm> )
##
InstallOtherMethod( RelativeOrderOfPcElement,
    "pcgs modulo pcgs",
    IsCollsElms,
    [ IsModuloPcgs and IsPrimeOrdersPcgs,
      IsObject ],
    # as we fall back on the code for pcgs, we must be sure that the method
    # has lower value
    {} -> RankFilter(IsModuloPcgs)
    -RankFilter(IsModuloPcgs and IsPrimeOrdersPcgs),

function( pcgs, elm )
    # Avoid infinite recursion
    if IsIdenticalObj(NumeratorOfModuloPcgs(pcgs),pcgs) then
      TryNextMethod();
    fi;
    return RelativeOrderOfPcElement( NumeratorOfModuloPcgs(pcgs), elm );
end );

#############################################################################
##
#M  DepthOfPcElement( <modulo-pcgs>, <elm> )
##
InstallOtherMethod( DepthOfPcElement,
    "pcgs modulo pcgs",
    IsCollsElms,
    [ IsModuloPcgs and IsModuloPcgsRep,
      IsObject ],
    0,

function( pcgs, elm )
    local   d,  num;
    # Avoid infinite recursion
    if IsIdenticalObj(NumeratorOfModuloPcgs(pcgs),pcgs) then
      TryNextMethod();
    fi;

    num := NumeratorOfModuloPcgs(pcgs);
    d := DepthOfPcElement( num, elm );
    if d > Length(num)  then
        return Length(pcgs)+1;
    elif d in pcgs!.moduloDepths  then
        return PositionNonZero( ExponentsOfPcElement( pcgs, elm ) );
    else
        return pcgs!.depthMap[d];
    fi;
end );

#############################################################################
##
#M  ExponentsOfPcElement( <modulo-pcgs>, <elm> )
##
InstallOtherMethod( ExponentsOfPcElement, "pcgs modulo pcgs", IsCollsElms,
    [ IsModuloPcgs and IsModuloPcgsRep, IsObject ], 0,
function( pcgs, elm )
    local   id,  exp,  ros,  den,  num,  mm,  pm,  d,  ll,  lr,lede;

    # Avoid infinite recursion
    if IsIdenticalObj(NumeratorOfModuloPcgs(pcgs),pcgs) then
      TryNextMethod();
    fi;

    id  := OneOfPcgs(pcgs);
    exp := ListWithIdenticalEntries(Length(pcgs),0);
    if not IsBound(pcgs!.lede) then pcgs!.lede:=[];fi;
    lede:=pcgs!.lede;
    den := DenominatorOfModuloPcgs(pcgs);
    num := NumeratorOfModuloPcgs(pcgs);
    if not IsPrimeOrdersPcgs(num)  then TryNextMethod();  fi;

    mm  := pcgs!.moduloMap;
    pm  := pcgs!.depthMap;
    ros := RelativeOrders(num);

    while elm <> id  do
        d := DepthOfPcElement( num, elm );
        if d>Length(pm) then
          # all lower will only be in denominator
          return exp;
        fi;

        ll  := LeadingExponentOfPcElement( num, elm );
        if IsBound(mm[d])  then
            if not IsBound(lede[d]) then
              lede[d]:=LeadingExponentOfPcElement( num, den[mm[d]] );
            fi;
            lr  := lede[d];
            elm := LeftQuotient( den[mm[d]]^(ll / lr mod ros[d]), elm );
        else
            #ll := LeadingExponentOfPcElement( num, elm );
            if not IsBound(lede[d]) then
              lede[d]:=LeadingExponentOfPcElement( num, pcgs[pm[d]] );
            fi;
            lr := lede[d];
            exp[pm[d]] := ll / lr mod ros[d];
            elm := LeftQuotient( pcgs[pm[d]]^exp[pm[d]], elm );
        fi;
    od;
    return exp;
end );

#############################################################################
##
#M  ExponentsOfPcElement( <modulo-pcgs>, <elm> )
##
InstallOtherMethod( ExponentsOfPcElement, "modpcgs numerator parent layers",
   IsCollsElms,
    [ IsModuloPcgs and IsModuloPcgsRep and
      IsNumeratorParentLayersForExponentsRep, IsObject ], 0,
function( pcgs, elm )
local   id,exp,den,par,ll,lr,idx,bascha,e,ee,prd,i,la,lap,pm;

    #elm0:=elm;
    id  := OneOfPcgs(pcgs);
    exp := ListWithIdenticalEntries(Length(pcgs),0);
    if not IsBound(pcgs!.lede) then pcgs!.lede:=[];fi;
    den := DenominatorOfModuloPcgs(pcgs);
    par := ParentPcgs(NumeratorOfModuloPcgs(pcgs));
    if not IsPrimeOrdersPcgs(par)  then TryNextMethod();  fi;

    idx:=pcgs!.indices;
    bascha:=pcgs!.basechange;
    pm:=Length(pcgs!.parentDepthMap);

    for lap in [1..Length(pcgs!.layranges)] do
      if bascha[lap]<>fail then
        la:=pcgs!.layranges[lap];
        ee:=ExponentsOfPcElement(par,elm,la);
        ee:=ee*bascha[lap]; # coefficients as needed

        if lap<Length(pcgs!.layranges) and pcgs!.layranges[lap+1][1]<=pm then
          prd:=id;
        else
          prd:=fail;
        fi;
        ll:=idx[lap][1];
        for i in [1..Length(ll)] do
          e:=Int(ee[i]);
          exp[ll[i]]:=e;
          if prd<>fail and not IsZero(e) then
            prd:=prd*pcgs[ll[i]]^e;
          fi;
        od;

        if prd<>fail then
          ll:=Length(ll);
          lr:=idx[lap][2];
          for i in [1..Length(lr)] do
            e:=Int(ee[i+ll]);
            if not IsZero(e) then;
              prd:=prd*den[lr[i]]^e;
            fi;
          od;
        fi;

        if prd<>fail and not IsIdenticalObj(prd,id) then
          # divide off
          elm:=LeftQuotient(prd,elm);
        fi;
        if prd=fail then
  #if exp<>basiccmp(pcgs,elm0) then Error("err1");fi;
          return exp;
        fi;
      fi;

    od;
  #if exp<>basiccmp(pcgs,elm0) then Error("err2");fi;
    return exp;

end );

#############################################################################
##
#M  ExponentsOfPcElement( <modulo-pcgs>, <elm>, <subrange> )
##

# this methoid ought to be obsolete
InstallOtherMethod( ExponentsOfPcElement, "pcgs modulo pcgs, subrange",
    IsCollsElmsX, [ IsModuloPcgs and IsModuloPcgsRep, IsObject,IsList ], 0,
function( pcgs, elm,range )
    local   id,  exp,  ros,  den,  num,  mm,  pm,  d,  ll,  lr,max;

    # Avoid infinite recursion
    if IsIdenticalObj(NumeratorOfModuloPcgs(pcgs),pcgs) then
      TryNextMethod();
    fi;

    Info(InfoWarning,1,"Obsolete exponents method");
    if not IsSSortedList(range) then
      TryNextMethod(); # the range may be unsorted or contain duplicates,
      # then we would have to be more clever.
    fi;
    max:=Maximum(range);

    id  := OneOfPcgs(pcgs);
    exp := ListWithIdenticalEntries(Length(pcgs),0);
    den := DenominatorOfModuloPcgs(pcgs);
    num := NumeratorOfModuloPcgs(pcgs);
    if not IsPrimeOrdersPcgs(num)  then TryNextMethod();  fi;

    mm  := pcgs!.moduloMap;
    pm  := pcgs!.depthMap;
    ros := RelativeOrders(num);

    while elm <> id  do
      d := DepthOfPcElement( num, elm );
      if IsBound(pm[d]) and pm[d]>max then
        # we have reached the maximum of the range we asked for. Thus we
        # can stop calculating exponents now, all further exponents would
        # be discarded anyhow.
        # Note that the depthMap is sorted!
        elm:=id;
      else
        if IsBound(mm[d])  then
            ll  := LeadingExponentOfPcElement( num, elm );
            lr  := LeadingExponentOfPcElement( num, den[mm[d]] );
            elm := LeftQuotient( den[mm[d]]^(ll / lr mod ros[d]), elm );
        else
            ll := LeadingExponentOfPcElement( num, elm );
            lr := LeadingExponentOfPcElement( num, pcgs[pm[d]] );
            exp[pm[d]] := ll / lr mod ros[d];
            elm := LeftQuotient( pcgs[pm[d]]^exp[pm[d]], elm );
        fi;
      fi;
    od;
    exp:=exp{range};
    return exp;
end );


#############################################################################
##
#M  ExponentsOfPcElement( <tail-pcgs>, <elm> )
##
InstallOtherMethod( ExponentsOfPcElement, "pcgs modulo tail-pcgs", IsCollsElms,
    [ IsModuloPcgs and IsModuloTailPcgsRep, IsObject ], 0,
function( pcgs, elm )
    return ExponentsOfPcElement(
        NumeratorOfModuloPcgs(pcgs), elm, pcgs!.depthMap );
end );

#############################################################################
##
#M  ExponentsOfPcElement( <tail-pcgs>, <elm>, <subrange> )
##
InstallOtherMethod( ExponentsOfPcElement, "pcgs modulo tail-pcgs, subrange",
    IsCollsElmsX, [ IsModuloPcgs and IsModuloTailPcgsRep, IsObject,IsList ], 0,
function( pcgs, elm,range )
    return ExponentsOfPcElement(
        NumeratorOfModuloPcgs(pcgs), elm, pcgs!.depthMap{range} );
end );

#############################################################################
##
#M  ExponentOfPcElement( <tail-pcgs>, <elm>, <pos> )
##
InstallOtherMethod( ExponentOfPcElement,
    "pcgs modulo tail-pcgs, ExponentsOfPcElement",IsCollsElmsX,
    [ IsModuloPcgs and IsModuloTailPcgsRep,
      IsObject,
      IsPosInt ], 0,
function( pcgs, elm, pos )
    return ExponentOfPcElement(
        NumeratorOfModuloPcgs(pcgs), elm, pcgs!.depthMap[pos] );
end );

#############################################################################
##
#M  ExponentsConjugateLayer( <mpcgs>,<elm>,<e> )
##
InstallMethod( ExponentsConjugateLayer,"default: compute brute force",
  IsCollsElmsElms,[IsModuloPcgs,IsMultiplicativeElementWithInverse,
                   IsMultiplicativeElementWithInverse],0,
function(m,elm,e)
  return ExponentsOfPcElement(m,elm^e);
end);

#############################################################################
##
#M  PcGroupWithPcgs( <modulo-pcgs> )
##
InstallMethod( PcGroupWithPcgs, "pcgs modulo pcgs", true, [ IsModuloPcgs ], 0,

function( pcgs )

    # the following only works for finite orders
    if not IsFiniteOrdersPcgs(pcgs)  then
        TryNextMethod();
    fi;
    return GROUP_BY_PCGS_FINITE_ORDERS(pcgs);

end );


#############################################################################
##
#M  GroupOfPcgs( <modulo-pcgs> )
##
InstallOtherMethod( GroupOfPcgs, true, [ IsModuloPcgs ], 0,
function( pcgs )
  return GroupOfPcgs( NumeratorOfModuloPcgs( pcgs ) );
end );

#############################################################################
##
#M  NumeratorOfModuloPcgs( <modolo-tail-pcgs-by-list-rep> )
##
InstallMethod( NumeratorOfModuloPcgs,
    "modolo-tail-pcgs-by-list-rep", true,
    [ IsModuloPcgs and IsModuloTailPcgsByListRep],0,
function( mpcgs )
local home;
  home:=mpcgs!.numeratorParent;
  return InducedPcgsByPcSequenceNC(home,
           Concatenation(mpcgs!.pcSequence,home{mpcgs!.moduloDepths}));
end );

#############################################################################
##
#M  DenominatorOfModuloPcgs( <modolo-tail-pcgs-by-list-rep> )
##
InstallMethod( DenominatorOfModuloPcgs,
    "modolo-tail-pcgs-by-list-rep", true,
    [ IsModuloPcgs and IsModuloTailPcgsByListRep],0,
function( mpcgs )
local home;
  home:=mpcgs!.numeratorParent;
  return InducedPcgsByPcSequenceNC(home,home{mpcgs!.moduloDepths});
end );

#############################################################################
##
#M  NumeratorOfModuloPcgs( <pcgs> )
##
InstallMethod(NumeratorOfModuloPcgs,"for pcgs",true,[IsPcgs],0,
function(pcgs)
  if IsModuloPcgs(pcgs) and not IsPcgs(pcgs) then
    TryNextMethod();
  fi;
  return pcgs;
end);


#############################################################################
##
#M  DenominatorOfModuloPcgs( <pcgs> )
##
InstallMethod(DenominatorOfModuloPcgs,"for pcgs",true,[IsPcgs],0,
function(pcgs)
  if IsModuloPcgs(pcgs) and not IsPcgs(pcgs) then
    TryNextMethod();
  fi;
  return InducedPcgsByGeneratorsNC(pcgs,[]);
end);



#############################################################################
##
#M  ModuloPcgs( <G>,<H> )
##
InstallMethod(ModuloPcgs,"for groups",IsIdenticalObj,[IsGroup,IsGroup],0,
function(G,H)
local home;
  home:=HomePcgs(G);
  RelativeOrders(home);
  G:=InducedPcgs(home,G);
  return G mod InducedPcgs(home,H);
end);

#############################################################################
##
#M  PcElementByExponentsNC( <family pcgs modulo>, <list> )
##
InstallMethod( PcElementByExponentsNC,
    "modulo subset induced wrt family pcgs", true,
    [ IsModuloPcgs and
      IsSubsetInducedNumeratorModuloTailPcgsRep and IsPrimeOrdersPcgs
      and IsNumeratorParentPcgsFamilyPcgs,
      IsRowVector and IsCyclotomicCollection ], 0,
function( pcgs, list )
local exp;
  exp:=ShallowCopy(pcgs!.parentZeroVector);
  exp{pcgs!.depthsInParent}:=list;
  return ObjByVector(TypeObj(OneOfPcgs(pcgs)),exp);
end);

InstallOtherMethod( PcElementByExponentsNC,
    "modulo subset induced wrt family pcgs,index", true,
    [ IsModuloPcgs and
      IsSubsetInducedNumeratorModuloTailPcgsRep and IsPrimeOrdersPcgs
      and IsNumeratorParentPcgsFamilyPcgs,
      IsRowVector and IsCyclotomicCollection,
      IsRowVector and IsCyclotomicCollection ], 0,
function( pcgs,ind, list )
local exp;
  #Assert(1,ForAll(list,i->i>=0));
  exp:=ShallowCopy(pcgs!.parentZeroVector);
  exp{pcgs!.depthsInParent{ind}}:=list;
  return ObjByVector(TypeObj(OneOfPcgs(pcgs)),exp);
end);

#############################################################################
##
#M  PcElementByExponentsNC( <family pcgs modulo>, <list> )
##
InstallMethod( PcElementByExponentsNC,
    "modulo subset induced wrt family pcgs, FFE", true,
    [ IsModuloPcgs and
      IsSubsetInducedNumeratorModuloTailPcgsRep and IsPrimeOrdersPcgs
      and IsNumeratorParentPcgsFamilyPcgs,
      IsRowVector and IsFFECollection ], 0,
function( pcgs, list )
local exp;
  list:=IntVecFFE(list);
  exp:=ShallowCopy(pcgs!.parentZeroVector);
  exp{pcgs!.depthsInParent}:=list;
  return ObjByVector(TypeObj(OneOfPcgs(pcgs)),exp);
end);

InstallOtherMethod( PcElementByExponentsNC,
    "modulo subset induced wrt family pcgs, FFE, index", true,
    [ IsModuloPcgs and
      IsSubsetInducedNumeratorModuloTailPcgsRep and IsPrimeOrdersPcgs
      and IsNumeratorParentPcgsFamilyPcgs,
      IsRowVector and IsCyclotomicCollection,
      IsRowVector and IsFFECollection ], 0,
function( pcgs,ind, list )
local exp;
  list:=IntVecFFE(list);
  exp:=ShallowCopy(pcgs!.parentZeroVector);
  exp{pcgs!.depthsInParent{ind}}:=list;
  return ObjByVector(TypeObj(OneOfPcgs(pcgs)),exp);
end);

InstallMethod( ExponentsConjugateLayer,"subset induced modulo pcgs",
  IsCollsElmsElms,
  [ IsModuloPcgs and
    IsSubsetInducedNumeratorModuloTailPcgsRep and IsPrimeOrdersPcgs
    and IsNumeratorParentPcgsFamilyPcgs,
  IsMultiplicativeElementWithInverse,IsMultiplicativeElementWithInverse],0,
function(m,e,c)
  return DoExponentsConjLayerFampcgs(m!.numeratorParent,m,e,c);
end);

#############################################################################
##
#M  ExponentsOfPcElement( <subset-induced,modulo-tail-pcgs>,<elm>,<subrange> )
##
InstallOtherMethod( ExponentsOfPcElement,
    "subset induced pcgs modulo tail-pcgs, subrange",
    IsCollsElmsX,
    [ IsModuloPcgs and IsModuloTailPcgsRep
      and IsNumeratorParentForExponentsRep, IsObject,IsList ], 0,
function( pcgs, elm, range )
    return
      ExponentsOfPcElement(pcgs!.numeratorParent,elm,pcgs!.depthsInParent{range});
end );

#############################################################################
##
#M  ExponentsOfPcElement( <subset-induced,modulo-tail-pcgs>, <elm> )
##
InstallOtherMethod( ExponentsOfPcElement,
    "subset induced pcgs modulo tail-pcgs", IsCollsElms,
    [ IsModuloPcgs and IsModuloTailPcgsRep
      and IsNumeratorParentForExponentsRep, IsObject ], 0,
function( pcgs, elm )
    return
      ExponentsOfPcElement(pcgs!.numeratorParent,elm,pcgs!.depthsInParent);
end );

#############################################################################
##
#M  ExponentsOfConjugate( <subset-induced,modulo-tail-pcgs>, <> )
##
InstallOtherMethod( ExponentsOfConjugate,
    "subset induced pcgs modulo tail-pcgs", true,
    [ IsModuloPcgs and IsModuloTailPcgsRep
      and IsNumeratorParentForExponentsRep, IsPosInt,IsPosInt ], 0,
function( pcgs, i,j )
  return ExponentsOfConjugate(ParentPcgs(pcgs!.numeratorParent),
    pcgs!.depthsInParent[i], # depth of the element in the parent
    pcgs!.depthsInParent[j]) # depth of the element in the parent
                                {pcgs!.depthsInParent};
end );

#############################################################################
##
#M  ExponentsOfRelativePower( <subset-induced,modulo-tail-pcgs>, <> )
##
InstallOtherMethod( ExponentsOfRelativePower,
    "subset induced pcgs modulo tail-pcgs", true,
    [ IsModuloPcgs and IsModuloTailPcgsRep
      and IsNumeratorParentForExponentsRep, IsPosInt ], 0,
function( pcgs, ind )
  return ExponentsOfRelativePower(ParentPcgs(pcgs!.numeratorParent),
    pcgs!.depthsInParent[ind]) # depth of the element in the parent
                                {pcgs!.depthsInParent};
end );

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