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


Quelle  permutat.g   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Thomas Breuer, 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 deals with permutations.
##

#############################################################################
##
##  <#GAPDoc Label="[1]{permutat}">
##  Internally, &GAP; stores a permutation as a list of the <M>d</M> images
##  of the integers <M>1, \ldots, d</M>, where the <Q>internal degree</Q>
##  <M>d</M> is the largest integer moved by the permutation or bigger.
##  When a permutation is read in cycle notation, <M>d</M> is always set
##  to the largest moved integer, but a bigger <M>d</M> can result from a
##  multiplication of two permutations, because the product is not shortened
##  if it fixes <M>d</M>.
##  The images are stored all as <M>16</M>-bit integers or all as
##  <M>32</M>-bit integers, depending on whether <M>d \leq 65536</M> or not.
##  For example, if <M>m\geq 65536</M>, the permutation
##  <M>(1, 2, \ldots, m)</M> has internal degree <M>d=m</M> and takes
##  <M>4m</M> bytes of memory for storage. But --- since the internal degree
##  is not reduced  --- this
##  means that the identity permutation <C>()</C> calculated as
##  <M>(1, 2, \ldots, m) * (1, 2, \ldots, m)^{{-1}}</M> also
##  takes <M>4m</M> bytes of storage.
##  It can take even more because the internal list has sometimes room for
##  more than <M>d</M> images.
##  <P/> On 32-bit systems, the limit on the degree of permutations is, for
##  technical reasons, <M>2^{28}-1</M>.
##  On 64-bit systems, it is <M>2^{32}-1</M> because only a 32-bit integer
##  is used to represent each image internally. Error messages should be given
##  if any command would require creating a permutation exceeding this limit.
##  <P/>
##  The operation <Ref Oper="RestrictedPerm"/> reduces the storage degree of
##  its result and therefore can be used to save memory if intermediate
##  calculations in large degree result in a small degree result.
##  <P/>
##  Permutations do not belong to a specific group.
##  That means that one can work with permutations without defining
##  a permutation group that contains them.
##  <P/>
##  <Example><![CDATA[
##  gap> (1,2,3);
##  (1,2,3)
##  gap> (1,2,3) * (2,3,4);
##  (1,3)(2,4)
##  gap> 17^(2,5,17,9,8);
##  9
##  gap> OnPoints(17,(2,5,17,9,8));
##  9
##  ]]></Example>
##  <P/>
##  The operation <Ref Oper="Permuted"/> can be used to permute the entries
##  of a list according to a permutation.
##  <#/GAPDoc>
##


#############################################################################
##
#C  IsPerm( <obj> )
##
##  <#GAPDoc Label="IsPerm">
##  <ManSection>
##  <Filt Name="IsPerm" Arg='obj' Type='Category'/>
##
##  <Description>
##  Each <E>permutation</E> in &GAP; lies in the category
##  <Ref Filt="IsPerm"/>.
##  Basic operations for permutations are
##  <Ref Attr="LargestMovedPoint" Label="for a permutation"/>,
##  multiplication of two permutations via <C>*</C>,
##  and exponentiation <C>^</C> with first argument a positive integer
##  <M>i</M> and second argument a permutation <M>\pi</M>,
##  the result being the image <M>i^{\pi}</M> of the point <M>i</M>
##  under <M>\pi</M>.
##  <!-- other arith. ops.?-->
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareCategoryKernel( "IsPerm",
    IsMultiplicativeElementWithInverse and IsAssociativeElement and
    IsFiniteOrderElement,
    IS_PERM );


#############################################################################
##
#C  IsPermCollection( <obj> )
#C  IsPermCollColl( <obj> )
##
##  <#GAPDoc Label="IsPermCollection">
##  <ManSection>
##  <Filt Name="IsPermCollection" Arg='obj' Type='Category'/>
##  <Filt Name="IsPermCollColl" Arg='obj' Type='Category'/>
##
##  <Description>
##  are the categories for collections of permutations and collections of
##  collections of permutations, respectively.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareCategoryCollections( "IsPerm" );
DeclareCategoryCollections( "IsPermCollection" );


#############################################################################
##
#F  SmallestGeneratorPerm( <perm> )
##
##  <#GAPDoc Label="SmallestGeneratorPerm">
##  <ManSection>
##  <Attr Name="SmallestGeneratorPerm" Arg='perm'/>
##
##  <Description>
##  is the smallest permutation that generates the same cyclic group
##  as the permutation <A>perm</A>.
##  This is very efficient, even when <A>perm</A> has large order.
##  <Example><![CDATA[
##  gap> SmallestGeneratorPerm( (1,4,3,2) );
##  (1,2,3,4)
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "SmallestGeneratorPerm",IsPerm);

InstallMethod( SmallestGeneratorPerm,"for internally represented permutation",
    [ IsPerm and IsInternalRep ],
    SMALLEST_GENERATOR_PERM );


#############################################################################
##
#A  SmallestMovedPoint( <perm> )
#A  SmallestMovedPoint( <C> )
##
##  <#GAPDoc Label="SmallestMovedPoint">
##  <ManSection>
##  <Attr Name="SmallestMovedPoint" Arg='perm' Label="for a permutation"/>
##  <Attr Name="SmallestMovedPoint" Arg='C'
##   Label="for a list or collection of permutations"/>
##
##  <Description>
##  is the smallest positive integer that is moved by <A>perm</A>
##  if such an integer exists, and <Ref Var="infinity"/> if
##  <A>perm</A> is the identity.
##  For <A>C</A> a collection or list of permutations,
##  the smallest value of
##  <Ref Attr="SmallestMovedPoint" Label="for a permutation"/> for the
##  elements of <A>C</A> is returned
##  (and <Ref Var="infinity"/> if <A>C</A> is empty).
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "SmallestMovedPoint", IsPerm );
DeclareAttribute( "SmallestMovedPoint", IsPermCollection );
DeclareAttribute( "SmallestMovedPoint", IsList and IsEmpty );

DeclareSynonymAttr( "SmallestMovedPointPerm", SmallestMovedPoint );


#############################################################################
##
#A  LargestMovedPoint( <perm> ) . . . . . . . . . . . . . . largest point
#A  LargestMovedPoint( <C> )
##
##  <#GAPDoc Label="LargestMovedPoint">
##  <ManSection>
##  <Attr Name="LargestMovedPoint" Arg='perm' Label="for a permutation"/>
##  <Attr Name="LargestMovedPoint" Arg='C'
##   Label="for a list or collection of permutations"/>
##
##  <Description>
##  For a permutation <A>perm</A>, this attribute contains
##  the largest positive integer which is moved by <A>perm</A>
##  if such an integer exists, and <C>0</C> if <A>perm</A> is the identity.
##  For <A>C</A> a collection or list of permutations,
##  the largest value of
##  <Ref Attr="LargestMovedPoint" Label="for a permutation"/> for the
##  elements of <A>C</A> is returned (and <C>0</C> if <A>C</A> is empty).
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "LargestMovedPoint", IsPerm );
DeclareAttribute( "LargestMovedPoint", IsPermCollection );
DeclareAttribute( "LargestMovedPoint", IsList and IsEmpty );

DeclareSynonymAttr( "LargestMovedPointPerm", LargestMovedPoint );


#############################################################################
##
#A  NrMovedPoints( <perm> )
#A  NrMovedPoints( <C> )
##
##  <#GAPDoc Label="NrMovedPoints">
##  <ManSection>
##  <Attr Name="NrMovedPoints" Arg='perm' Label="for a permutation"/>
##  <Attr Name="NrMovedPoints" Arg='C'
##   Label="for a list or collection of permutations"/>
##
##  <Description>
##  is the number of positive integers that are moved by <A>perm</A>,
##  respectively by at least one element in the collection <A>C</A>.
##  (The actual moved points are returned by
##  <Ref Attr="MovedPoints" Label="for a permutation"/>.)
##  <Example><![CDATA[
##  gap> SmallestMovedPointPerm((4,5,6)(7,2,8));
##  2
##  gap> LargestMovedPointPerm((4,5,6)(7,2,8));
##  8
##  gap> NrMovedPointsPerm((4,5,6)(7,2,8));
##  6
##  gap> MovedPoints([(2,3,4),(7,6,3),(5,47)]);
##  [ 2, 3, 4, 5, 6, 7, 47 ]
##  gap> NrMovedPoints([(2,3,4),(7,6,3),(5,47)]);
##  7
##  gap> SmallestMovedPoint([(2,3,4),(7,6,3),(5,47)]);
##  2
##  gap> LargestMovedPoint([(2,3,4),(7,6,3),(5,47)]);
##  47
##  gap> LargestMovedPoint([()]);
##  0
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "NrMovedPoints", IsPerm );
DeclareAttribute( "NrMovedPoints", IsPermCollection );
DeclareAttribute( "NrMovedPoints", IsList and IsEmpty );

DeclareSynonymAttr( "NrMovedPointsPerm", NrMovedPoints );
DeclareSynonymAttr( "DegreeAction", NrMovedPoints );
DeclareSynonymAttr( "DegreeOperation", NrMovedPoints );


#############################################################################
##
#A  MovedPoints( <perm> )
#A  MovedPoints( <C> )
##
##  <#GAPDoc Label="MovedPoints">
##  <ManSection>
##  <Attr Name="MovedPoints" Arg='perm' Label="for a permutation"/>
##  <Attr Name="MovedPoints" Arg='C'
##   Label="for a list or collection of permutations"/>
##
##  <Description>
##  is the proper set of the positive integers moved by at least one
##  permutation in the collection <A>C</A>, respectively by the permutation
##  <A>perm</A>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "MovedPoints", IsPerm);
DeclareAttribute( "MovedPoints", IsPermCollection );
DeclareAttribute( "MovedPoints", IsList and IsEmpty );


#############################################################################
##
#A  SignPerm( <perm> )
##
##  <#GAPDoc Label="SignPerm">
##  <ManSection>
##  <Attr Name="SignPerm" Arg='perm'/>
##
##  <Description>
##  The <E>sign</E> of a permutation <A>perm</A> is defined as <M>(-1)^k</M>
##  where <M>k</M> is the number of cycles of <A>perm</A> of even length.
##  <P/>
##  The sign is a homomorphism from the symmetric group onto the
##  multiplicative  group <M>\{ +1, -1 \}</M>,
##  the kernel of which is the alternating group.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "SignPerm", IsPerm );

InstallMethod( SignPerm,
    "for internally represented permutation",
    [ IsPerm and IsInternalRep ],
    SIGN_PERM );


#############################################################################
##
#A  CycleStructurePerm( <perm> )  . . . . . . . . . . . . . . cycle structure
##
##  <#GAPDoc Label="CycleStructurePerm">
##  <ManSection>
##  <Attr Name="CycleStructurePerm" Arg='perm'/>
##
##  <Description>
##  is the cycle structure (i.e. the numbers of cycles of different lengths)
##  of the permutation <A>perm</A>.
##  This is encoded in a list <M>l</M> in the following form:
##  The <M>i</M>-th entry of <M>l</M> contains the number of cycles of
##  <A>perm</A> of length <M>i+1</M>.
##  If <A>perm</A> contains no cycles of length <M>i+1</M> it is not
##  bound.
##  Cycles of length 1 are ignored.
##  <Example><![CDATA[
##  gap> SignPerm((1,2,3)(4,5));
##  -1
##  gap> CycleStructurePerm((1,2,3)(4,5,9,7,8));
##  [ , 1,, 1 ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "CycleStructurePerm", IsPerm );


#############################################################################
##
#R  IsPerm2Rep  . . . . . . . . . . . . . .  permutation with 2 bytes entries
##
##  <ManSection>
##  <Filt Name="IsPerm2Rep" Arg='obj' Type='Representation'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareRepresentation( "IsPerm2Rep", IsInternalRep );


#############################################################################
##
#R  IsPerm4Rep  . . . . . . . . . . . . . .  permutation with 4 bytes entries
##
##  <ManSection>
##  <Filt Name="IsPerm4Rep" Arg='obj' Type='Representation'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareRepresentation( "IsPerm4Rep", IsInternalRep );


#############################################################################
##
#V  PermutationsFamily  . . . . . . . . . . . . .  family of all permutations
##
##  <#GAPDoc Label="PermutationsFamily">
##  <ManSection>
##  <Fam Name="PermutationsFamily"/>
##
##  <Description>
##  is the family of all permutations.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BIND_GLOBAL( "PermutationsFamily",
    NewFamily( "PermutationsFamily",
    IsPerm,CanEasilySortElements,CanEasilySortElements ) );
#    IsMultiplicativeElementWithOne,CanEasilySortElements,CanEasilySortElements ) );


#############################################################################
##
#V  TYPE_PERM2  . . . . . . . . . .  type of permutation with 2 bytes entries
##
##  <ManSection>
##  <Var Name="TYPE_PERM2"/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
BIND_GLOBAL( "TYPE_PERM2",
    NewType( PermutationsFamily, IsPerm and IsPerm2Rep ) );


#############################################################################
##
#V  TYPE_PERM4  . . . . . . . . . .  type of permutation with 4 bytes entries
##
##  <ManSection>
##  <Var Name="TYPE_PERM4"/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
BIND_GLOBAL( "TYPE_PERM4",
    NewType( PermutationsFamily, IsPerm and IsPerm4Rep ) );


#############################################################################
##
#v  One . . . . . . . . . . . . . . . . . . . . . . . . .  one of permutation
##
SetOne( PermutationsFamily, () );


#############################################################################
##
#F  PermList( <list> )
##
##  <#GAPDoc Label="PermList">
##  <ManSection>
##  <Func Name="PermList" Arg='list'/>
##
##  <Description>
##  is the permutation <M>\pi</M> that moves points as described by the
##  list <A>list</A>.
##  That means that <M>i^{\pi} =</M> <A>list</A><C>[</C><M>i</M><C>]</C> if
##  <M>i</M> lies between <M>1</M> and the length of <A>list</A>,
##  and <M>i^{\pi} = i</M> if <M>i</M> is
##  larger than the length of the list <A>list</A>.
##  <Ref Func="PermList"/> will return <K>fail</K>
##  if <A>list</A> does not define a permutation,
##  i.e., if <A>list</A> is not dense,
##  or if <A>list</A> contains a positive integer twice,
##  or if <A>list</A> contains an
##  integer not in the range <C>[ 1 .. Length( <A>list</A> ) ]</C>,
##  or if <A>list</A> contains non-integer entries, etc.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##


#############################################################################
##
#F  ListPerm( <perm>[, <n>] )  . . . . . . . . . . . . .  list of images
##
##  <#GAPDoc Label="ListPerm">
##  <ManSection>
##  <Func Name="ListPerm" Arg='perm[, n]'/>
##
##  <Description>
##  is a list <M>l</M> that contains the images of the positive integers
##  from 1 to <A>n</A> under the permutation <A>perm</A>.
##  That means that
##  <M>l</M><C>[</C><M>i</M><C>]</C> <M>= i</M><C>^</C><A>perm</A>,
##  where <M>i</M> lies between 1 and <A>n</A>.
##  <P/>
##  If the optional second argument <A>n</A> is omitted then the largest
##  point moved by <A>perm</A> is used
##  (see <Ref Attr="LargestMovedPoint" Label="for a permutation"/>).
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##


#############################################################################
##
#F  CycleFromList( <list> )  . . . . . . . . . . . cycle defined from a list
##
##  <#GAPDoc Label="CycleFromList">
##  <ManSection>
##  <Func Name="CycleFromList" Arg='list'/>
##
##  <Description>
##  For the given dense, duplicate-free list of positive integers
##  <M>[a_1, a_2, ..., a_n]</M>
##  return the <M>n</M>-cycle <M>(a_1,a_2,...,a_n)</M>. For the empty list
##  the trivial permutation <M>()</M> is returned.
##  <P/>
##  If the given <A>list</A> contains duplicates or holes, return <K>fail</K>.
##  <P/>
##  <Example><![CDATA[
##  gap> CycleFromList( [1,2,3,4] );
##  (1,2,3,4)
##  gap> CycleFromList( [3,2,6,4,5] );
##  (2,6,4,5,3)
##  gap> CycleFromList( [2,3,2] );
##  fail
##  gap> CycleFromList( [1,,3] );
##  fail
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BIND_GLOBAL( "CycleFromList", function( list )
    local max, images, set, i;

    # Trivial case
    if Length(list) = 0 then
        return ();
    fi;

    if ForAny( list, i -> not IsPosInt(i) ) then
        Error("CycleFromList: List must only contain positive integers.");
    fi;

    set := Set(list);
    if Length(set) <> Length(list) then
        # we found duplicates (or list was not dense)
        return fail;
    fi;
    max := Maximum( set );
    images := [1..max];
    for i in [1..Length(list)-1] do
        images[ list[i] ] := list[i+1];
    od;
    images[ Last(list) ] := list[1];

    return PermList(images);
end );


#############################################################################
##
#O  RestrictedPerm(<perm>,<list>)  restriction of a perm. to an invariant set
#O  RestrictedPermNC(<perm>,<list>)  restriction of a perm. to an invariant set
##
##  <#GAPDoc Label="RestrictedPerm">
##  <ManSection>
##  <Oper Name="RestrictedPerm" Arg='perm, list'/>
##  <Oper Name="RestrictedPermNC" Arg='perm, list'/>
##
##  <Description>
##  <Ref Oper="RestrictedPerm"/> returns the new permutation
##  that acts on the points in the list <A>list</A> in the same way as
##  the permutation <A>perm</A>,
##  and that fixes those points that are not in <A>list</A>. The resulting
##  permutation is stored internally of degree given by the maximal entry of
##  <A>list</A>.
##  <A>list</A> must be a list of positive integers such that for each
##  <M>i</M> in <A>list</A> the image <M>i</M><C>^</C><A>perm</A> is also in
##  <A>list</A>,
##  i.e., <A>list</A> must be the union of cycles of <A>perm</A>.
##  <P/>
##  <Ref Oper="RestrictedPermNC"/> does not check whether <A>list</A>
##  is a union of cycles.
##  <P/>
##  <Example><![CDATA[
##  gap> ListPerm((3,4,5));
##  [ 1, 2, 4, 5, 3 ]
##  gap> PermList([1,2,4,5,3]);
##  (3,4,5)
##  gap> MappingPermListList([2,5,1,6],[7,12,8,2]);
##  (1,8,5,12,6,2,7)
##  gap> RestrictedPerm((1,2)(3,4),[3..5]);
##  (3,4)
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "RestrictedPerm", [ IsPerm, IsList ] );
DeclareOperation( "RestrictedPermNC", [ IsPerm, IsList ] );

InstallMethod(RestrictedPermNC,"kernel method",true,
  [IsPerm and IsInternalRep, IsList],0,
function(g,D)
local p;
  p:=RESTRICTED_PERM(g,D,false);
  if p=fail then
    Error("<g> must be a permutation and <D> a plain list or range,\n",
          "   consisting of a union of cycles of <g>");
  fi;
  return p;
end);

InstallMethod( RestrictedPerm,"use kernel method, test",true,
  [IsPerm and IsInternalRep, IsList],0,
function(g,D)
  local p;
  p:=RESTRICTED_PERM(g,D,true);
  if p=fail then
    Error("<g> must be a permutation and <D> a plain list or range,\n",
          "   consisting of a union of cycles of <g>");
  fi;
  return p;
end);

#############################################################################
##
#F  MappingPermListList( <src>, <dst> ) . . perm. mapping one list to another
##
##  <#GAPDoc Label="MappingPermListList">
##  <ManSection>
##  <Func Name="MappingPermListList" Arg='src, dst'/>
##
##  <Description>
##  Let <A>src</A> and <A>dst</A> be lists of positive integers of the same
##  length, such that there is a permutation <M>\pi</M> such that
##  <C>OnTuples(<A>src</A>,</C> <M>\pi</M><C>) = <A>dst</A></C>.
##  <Ref Func="MappingPermListList"/> returns such a permutation
##  (i. e., <A>src</A><C>[</C><M>i</M><C>]^</C><M>\pi =</M>
##  <A>dst</A><C>[</C><M>i</M><C>]</C> holds),
##  with the property that <M>\pi</M> fixes any point which is not in
##  <A>src</A> or <A>dst</A>.
##  If there are several such permutations, it is not specified which of them
##  <Ref Func="MappingPermListList"/> returns. If there is no such
##  permutation, then <Ref Func="MappingPermListList"/> returns <K>fail</K>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##

#############################################################################
##
#m  SmallestMovedPoint( <perm> )  . . . . . . . . . . .  for permutations
##
InstallMethod( SmallestMovedPoint,
    "for a permutation",
    [ IsPerm ],
    function( p )
    local   i;

    if IsOne(p)  then
        return infinity;
    fi;
    i := 1;
    while i ^ p = i  do
        i := i + 1;
    od;
    return i;
end );


InstallMethod( SmallestMovedPoint,
    "for an internal permutation",
    [ IsPerm and IsInternalRep ],
    SMALLEST_MOVED_POINT_PERM );


#############################################################################
##
#m  LargestMovedPoint( <perm> ) . . . . . . . .  for internal permutation
##
InstallMethod( LargestMovedPoint,
    "for an internal permutation",
    [ IsPerm and IsInternalRep ],
    LARGEST_MOVED_POINT_PERM );


#############################################################################
##
#m  NrMovedPoints( <perm> ) . . . . . . . . . . . . . . . for permutation
##
InstallMethod( NrMovedPoints,
    "for a permutation",
    [ IsPerm ],
    function( perm )
    local mov, pnt;
    mov:= 0;
    if not IsOne( perm ) then
      for pnt in [ SmallestMovedPoint( perm )
                   .. LargestMovedPoint( perm ) ] do
        if pnt ^ perm <> pnt then
          mov:= mov + 1;
        fi;
      od;
    fi;
    return mov;
    end );


#############################################################################
##
#m  CycleStructurePerm( <perm> )  . . . . . . . . .  length of cycles of perm
##
InstallMethod( CycleStructurePerm, "internal", [ IsPerm and IsInternalRep],0,
  CYCLE_STRUCT_PERM);

InstallMethod( CycleStructurePerm, "generic method", [ IsPerm ],0,
function ( perm )
    local   cys,    # collected cycle lengths, result
            degree, # degree of perm
            mark,   # boolean list to mark elements already processed
            i,j,    # loop variables
            len,    # length of a cycle
            cyc;    # a cycle of perm

    if IsOne(perm) then
        cys := [];
    else
        degree := LargestMovedPoint(perm);
        mark := BlistList([1..degree], []);
        cys := [];
        for i in [1..degree] do
            if not mark[i] then
               cyc := CYCLE_PERM_INT( perm, i );
               len := Length(cyc) - 1;
               if 0 < len  then
                  if IsBound(cys[len])  then
                     cys[len] := cys[len]+1;
                  else
                     cys[len] := 1;
                  fi;
               fi;
               for j in cyc do
                  mark[j] := true;
               od;
            fi;
        od;
    fi;
    return cys;
end );


#############################################################################
##
#m  String( <perm> )  . . . . . . . . . . . . . . . . . . . for a permutation
##
BIND_GLOBAL("DoStringPerm",function( perm,hint )
local   str,  i,  j, maxpnt, blist;

  if IsOne( perm ) then
      str := "()";
  else
      str := "";
      maxpnt := LargestMovedPoint( perm );
      blist := BlistList([1..maxpnt], []);
      for i  in [ 1 .. LargestMovedPoint( perm ) ]  do
      if not blist[i] and i ^ perm <> i  then
          blist[i] := true;
          Append( str, "(" );
          Append( str, String( i ) );
          j := i ^ perm;
          while j > i do
          blist[j] := true;
          Append( str, "," );
          if hint then Append(str,"\<\>"); fi;
          Append( str, String( j ) );
          j := j ^ perm;
          od;
          Append( str, ")" );
          if hint then Append(str,"\<\<\>\>"); fi;
      fi;
      od;
      if Length(str)>4 and str{[Length(str)-3..Length(str)]}="\<\<\>\>" then
          str:=str{[1..Length(str)-4]}; # remove tailing line breaker
      fi;
      ConvertToStringRep( str );
  fi;
  return str;
end );

InstallMethod( String, "for a permutation", [ IsPerm ],function(perm)
  return DoStringPerm(perm,false);
end);

InstallMethod( ViewString, "for a permutation", [ IsPerm ],function(perm)
  return DoStringPerm(perm,true);
end);




#############################################################################
##
#M  Order( <perm> ) . . . . . . . . . . . . . . . . .  order of a permutation
##
InstallMethod( Order,
    "for a permutation",
    [ IsPerm ],
    ORDER_PERM );


#############################################################################
##
#O  DistancePerms( <perm1>, <perm2> ) . returns NrMovedPoints( <perm1>/<perm2> )
##        but possibly faster
##
##  <#GAPDoc Label="DistancePerms">
##  <ManSection>
##  <Oper Name="DistancePerms" Arg="perm1, perm2"/>
##
##  <Description>
##  returns the number of points for which <A>perm1</A> and <A>perm2</A>
##  have different images. This should always produce the same result as
##  <C>NrMovedPoints(<A>perm1</A>/<A>perm2</A>)</C> but some methods may be
##  much faster than this form, since no new permutation needs to be created.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>

DeclareOperation( "DistancePerms", [IsPerm, IsPerm] );


#############################################################################
##
#M  DistancePerms( <perm1>, <perm2> ) . returns NrMovedPoints( <perm1>/<perm2> )
##    for kernel permutations
##
InstallMethod( DistancePerms, "for kernel permutations",
        [ IsPerm and IsInternalRep, IsPerm and IsInternalRep ],
        DISTANCE_PERMS);

#############################################################################
##
#M  DistancePerms( <perm1>, <perm2> ) . returns NrMovedPoints( <perm1>/<perm2> )
##    generic
##

InstallMethod( DistancePerms, "for general permutations",
        [ IsPerm, IsPerm ],
        function(x,y)
    return NrMovedPoints(x/y); end);

#############################################################################
##
#V  PERM_INVERSE_THRESHOLD . . . . cut off for when inverses are computed
##                                 eagerly
##
##  <#GAPDoc Label="PERM_INVERSE_THRESHOLD">
##  <ManSection>
##  <Var Name="PERM_INVERSE_THRESHOLD"/>
##
##  <Description>
##  For permutations of degree up to <C>PERM_INVERSE_THRESHOLD</C> whenever
##  the inverse image of a point under a permutations is needed, the entire
##  inverse is computed and stored. Otherwise, if the inverse is not stored,
##  the point is traced around the cycle it is part of to find the inverse
##  image. This takes time when it happens, and uses memory, but saves time
##  on a variety of subsequent computations. This threshold can be adjusted
##  by simply assigning to the variable. The default is 10000.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>

PERM_INVERSE_THRESHOLD := 10000;



#############################################################################
##
#m  ViewObj( <perm> )  . . . . . . . . . . . . . . . . . . . for a permutation
##
InstallMethod( ViewObj, "for a permutation", [ IsPerm ],
function( perm )
local dom,l,i,n,p,c;
  dom:=[];
  l:=LargestMovedPoint(perm);
  i:=SmallestMovedPoint(perm);
  n:=0;
  while n<200 and i<l do
    p:=i;
    if p^perm<>p and not p in dom then
      c:=false;
      while not p in dom do
        AddSet(dom,p);
        n:=n+1;
        # deliberately *no ugly blanks* printed!
        if c then
          Print(",",p);
        else
          Print(Concatenation("(",String(p)));
        fi;
        p:=p^perm;
        c:=true;
      od;
      Print(")");
    fi;
    i:=i+1;
  od;
  if i<l and ForAny([i..l],j->j^perm<>j and not j in dom) then
    Print("( [...] )");
  elif i>l+1 then
    Print("()");
  fi;
end );

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