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


Quelle  farey.gi   Sprache: unbekannt

 
#############################################################################
##
#W farey.gi                The Congruence package                   Ann Dooms
#W                                                               Eric Jespers
#W                                                         Olexandr Konovalov
##
##
#############################################################################
    

#############################################################################
##
## IsFareySymbolDefaultRep
##
DeclareRepresentation( "IsFareySymbolDefaultRep", 
    IsPositionalObjectRep,
    [ 1, 2 ] );
    
    
#############################################################################
##
## FareySymbolByData( <gfs>, <labels> )
##
## This constructor creates Farey symbol with the given generalized Farey 
## sequence and list of labels. It also checks conditions from the definition
## of Farey symbol and returns an error if they are not satisfied
##
InstallMethod( FareySymbolByData, 
 "for two lists that are g.F.S. and labels for Farey symbol",
 [ IsList, IsList ],
 0,
 function( gfs, labels)
 local fs;
 fs :=Objectify( NewType( NewFamily("FareySymbolsFamily", IsFareySymbol), 
                          IsFareySymbol), [ gfs, labels ] );
 if IsValidFareySymbol(fs) then                         
   return fs;   
 else
   Error("<fs> is not a valid Farey symbol !!! \n");
 fi;                          
 end);


#############################################################################
##
## GeneralizedFareySequence( <fs> )
## LabelsOfFareySymbol( <fs> )
##
## The data used to create the Farey symbol are stored as its attributes
##
InstallMethod( GeneralizedFareySequence,
    "for Farey symbol in default representation",
    [ IsFareySymbol ],
    fs -> fs![1]);

InstallMethod( LabelsOfFareySymbol,
    "for Farey symbol in default representation",
    [ IsFareySymbol ],
    fs -> fs![2] );     


#############################################################################
##
## ViewObj( fs )
## PrintObj( fs )
##    
InstallMethod( ViewObj,
    "for Farey symbol",
    [ IsFareySymbol ],
    0,
    function(fs)
    Print( GeneralizedFareySequence(fs), "\n",
           LabelsOfFareySymbol(fs) );
    end); 
    
InstallMethod( PrintObj,
    "for Farey symbol",
    [ IsFareySymbol ],
    0,
    function(fs)
    Print( "FareySymbolByData( ", GeneralizedFareySequence(fs), 
           ", ", LabelsOfFareySymbol(fs), " ) " );
    end);    
   
    
#############################################################################
##
## FareySymbol( <G> )
##
## For a subgroup of a finite index G, this attribute stores the 
## corresponding Farey symbol. The algorithm for its computation must work
## with any matrix group for which the membership test is available
##     
InstallMethod( FareySymbol,
 "for a congruence subgroup",
 [ IsCongruenceSubgroup ],
 0,
 function( G )
local    gfs, # generalized Farey sequence (g.F.S.)
      labels, # labels of this g.F.S.
          fs, # resulting Farey symbol
  i, j, k, t, # counters
      stepnr, # number of the inductive ste
   newvertex, # new vertex to be inserted on the current inductive step
  unpairednr, # number of the 1st vertex of the unpaired side 
   lastlabel, # last used label
         mat, # matrix by free pair of intervals
     unpairednumbers, # list of positions with assigned labels
        denominators, # denominators of current g.F.S. elements
possibledenominators, # list of denominators arising from these positions
              minden, # minimum of possible denominators
                 pos, # chosen position of minden in possibledenominators
            nrlabels, # number of labels assigned
              range1, # range for the search of odd and even labels 
              range2, # range for the search of free (i.e.numerical) labels
 isfirstlabelssearch; # flag for determining of the range1 and range2
#
# Initial data setup
#
if LevelOfCongruenceSubgroup(G)=1 then
  return FareySymbolByData( [ infinity, 0, infinity ], ["even","odd"]) ;
fi;
gfs := [ infinity, 0, infinity ];
labels:=[];
nrlabels:=0;
stepnr:=0;
lastlabel:=0;
isfirstlabelssearch:=true;
#
# we perform the next loop until we will have fully labeled gfs
#
while nrlabels < Length( gfs ) - 1 do
  stepnr:=stepnr+1;
  Info( InfoCongruence, 2, "Step ", stepnr, 
                           " : g.F.S. of length ", Length(gfs), 
                           " with ", nrlabels, " labels");   
  Info( InfoCongruence, 3, "   gfs = ", gfs );
  Info( InfoCongruence, 3, "labels = ", labels ); 
  #
  # 1. Choose any of the unpaired sides and insert new vertex
  #
  # 1.1. Find unpaired side that will give us a new vertex 
  #      with the minimal denominator (on the first step we
  #      do some trick to get [infinity,0,1,infinity])
  unpairednumbers := Filtered( [ 1 .. Length(gfs)-1 ], i -> 
                               not IsBound( labels[ i ] ) );
  Info( InfoCongruence, 3, "Positions of unpaired labels : ", unpairednumbers );
  # to avoid repeated calls of DenominatorOfGFSElement, we are caching
  # values of denominators from required positions  
  denominators := [];   
  for i in unpairednumbers do 
    if not IsBound(denominators[i]) then
      denominators[i]:=DenominatorOfGFSElement(gfs,i);
    fi;  
    denominators[i+1]:=DenominatorOfGFSElement(gfs,i+1);
  od;                          
  possibledenominators := List( unpairednumbers, i -> 
                                denominators[i] + denominators[i+1] );
  Info( InfoCongruence, 3, "Possible denominators : ", possibledenominators ); 
  minden := Minimum(possibledenominators);
  # we give priority to positive numbers in g.F.S. 
  pos:=PositionProperty( [ 1 .. Length(unpairednumbers) ], i -> 
                         ( possibledenominators[i] = minden ) and 
                         ( NumeratorOfGFSElement( gfs, unpairednumbers[i] ) >=0 ) );
  if pos=fail then
    pos:=PositionProperty( [ 1 .. Length(unpairednumbers) ], i -> 
                           possibledenominators[i] = minden );
  fi;                       
  unpairednr := unpairednumbers[ pos ]; 
  #i:=1;
  #repeat
  #  pos := PositionNthOccurrence( possibledenominators, minden, i );
  #  i := i+1;
  #  unpairednr := unpairednumbers[ pos ]; 
  #until NumeratorOfGFSElement(gfs, unpairednr) >= 0;
  #
  # 1.2. Compute new vertex by the Farey sequence rule
  #
  newvertex := ( NumeratorOfGFSElement(gfs, unpairednr) + 
                 NumeratorOfGFSElement(gfs, unpairednr+1) ) / minden;
  #
  # 1.3. Insert this new vertex and an empty spot for the label
  #      
  Info( InfoCongruence, 2, "Inserting ", newvertex, 
                           " at position ", unpairednr+1);
  Add( gfs, newvertex, unpairednr+1);
  Add( unpairednumbers, unpairednr, pos );
  for i in [ pos+1 .. Length(unpairednumbers) ] do
    unpairednumbers[i] := unpairednumbers[i]+1;
  od;
  Add( labels, "hole" , unpairednr );
  Unbind(labels[unpairednr]);
  #
  # 2. For each of new sides, we check if they are paired and
  #    assign labels, if this is the case
  #
  if isfirstlabelssearch then
    range1 := [ 1 .. Length(gfs)-1 ];
    range2 := [ 1 .. Length(gfs)-1 ];
  else
    # if we already checked all cases for all possible labels, 
    # on each new step it is enough to check only new intervals
    range1 := [ unpairednr, unpairednr+1 ];
    # Slower but more obvious options for range2 could be:
    # range2 := [ 1 .. Length(gfs)-1 ];
    # range2:= Filtered( [ 1 .. Length(gfs)-1 ], i -> not IsBound( labels[ i ] ) );
    # but we use the fastest one
    range2 := unpairednumbers;
  fi; 
  if not ( IsPrincipalCongruenceSubgroup(G) and 
           LevelOfCongruenceSubgroup(G) > 2 ) then
    for i in range1 do
      # we do not check that labels[i] is not bound because this is
      # guaranteed by the algorithm
      mat := MatrixByOddInterval( gfs, i );
      if mat in G or -mat in G then
        labels[i]:="odd";
        nrlabels:=nrlabels+1;
        Info( InfoCongruence, 2, "Putting label ", lastlabel,
                                 " at position ", i );      
      else
        mat := MatrixByEvenInterval( gfs, i );
        if mat in G or -mat in G then
          labels[i]:="even";
          nrlabels:=nrlabels+1;
          Info( InfoCongruence, 2, "Putting label ", lastlabel,
                                   " at position ", i );  
        fi;                               
      fi;
    od;
  fi;
  for i in range1 do
    for j in range2 do
      # we eliminate the case i=j since we always check different intervals
      # now we check that both labels[i] and labels[j] are not bound for a case
      # if they were already assigned during the search for odd/even labels
      if i<>j and not IsBound( labels[i] ) and not IsBound( labels[j] ) then
        mat := MatrixByFreePairOfIntervals( gfs, i, j );
        if mat in G or -mat in G then
          lastlabel := lastlabel+1;
          labels[i]:=lastlabel;
          labels[j]:=lastlabel;
          nrlabels:=nrlabels+2;
          Info( InfoCongruence, 2, "Putting label ", lastlabel,
            " at positions ", i, " and ", j );
          # since i-th interval can be paired only with one j-th interval,
          # we quit from inner loop and go to the next i
          break;  
        fi; 
      fi;
    od;  
  od;
  isfirstlabelssearch:=false;
  if stepnr mod 25000 = 0 then
    Error("You reached the checkpoint on the ", stepnr, "th iteration \n",
          "Currently you have g.F.S. of length ", Length(gfs), 
          " with ", nrlabels, " labels assigned \n",
          "Use the index of the subgroup to get an idea about possible length of the g.F.S.:\n",
          "it will be equal to the index of <G> in PSL_2Z minus the number of odd intervals in g.F.S.\n");
  fi;
od;
fs := FareySymbolByData( gfs, labels) ;
return fs;
end);    


#############################################################################
#
# GeneratorsByFareySymbol( fs )
#
InstallGlobalFunction( GeneratorsByFareySymbol,
function( fs )
local gfs, labels, usedlabels, gens, i, j, m;
gfs := GeneralizedFareySequence(fs);
labels := LabelsOfFareySymbol(fs);
usedlabels:=[];
gens:=[];
for i in [ 1 .. Length(labels) ] do
  if labels[i]="even" then
    Info( InfoCongruence, 2, "labels[", i, "] = ", labels[i] );
    m := MatrixByEvenInterval( gfs, i );
    Add( gens, m );
    if InfoLevel( InfoCongruence ) = 2 then
      Display(m);
    fi;  
  elif labels[i]="odd" then
    Info( InfoCongruence, 2, "labels[", i, "] = ", labels[i] );
    m := MatrixByOddInterval( gfs, i );
    Add( gens, m );
    if InfoLevel( InfoCongruence ) = 2 then
      Display(m);
    fi;     
  elif not labels[i] in usedlabels then
    j := PositionNthOccurrence( labels, labels[i], 2 );
    Info( InfoCongruence, 2, "labels[", i, "] = ", labels[i], 
                          " = labels[", j, "]" );
    m := MatrixByFreePairOfIntervals( gfs, i, j );
    Add( gens, m );
    Add( usedlabels, labels[i] );
    if InfoLevel( InfoCongruence ) = 2 then
      Display(m);
    fi;    
  fi;
od;
return gens;
end);


#############################################################################
#
# IndexInPSL2ZByFareySymbol( fs )
#
# By the proposition 7.2 [Kulkarni], for the Farey symbol with underlying
# generalized Farey sequence { infinity, x0, x1, ..., xn, infinity }, the
# index in PSL_2(Z) is given by the formula d = 3*n + e3, where e3 is the 
# number of odd intervals.
#
InstallGlobalFunction( IndexInPSL2ZByFareySymbol,
function( fs )
local n, e3, x, d; 
n := Length( GeneralizedFareySequence(fs) ) - 3;
e3:= Number( LabelsOfFareySymbol(fs), x -> x = "odd" );
d := 3 * n + e3;
return d;
end);


#############################################################################
##
#E
##

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