#############################################################################
##
#W img.gd                                                   Laurent Bartholdi
##
#H   @(#)$Id: img.gd,v 1.9 2007/12/20 22:37:44 gap Exp $
##
#Y Copyright (C) 2006, Laurent Bartholdi
##
#############################################################################
##
##  Iterated monodromy groups
##
#############################################################################

#############################################################################
##
#M IMGFRMachine
##
## <#GAPDoc Label="IMGFRMachine">
## <ManSection>
##   <Oper Name="IMGFRMachine" Arg="m[,w]" Label="FR machine"/>
##   <Returns>An IMG FR machine.</Returns>
##   <Description>
##     This function creates a new IMG FR machine, starting from a group
##     FR machine <A>m</A>. If a state <A>w</A> is specified, it is used
##     as IMG relator; otherwise, if some ordering of the generators is
##     trivial, it is used as a relator; in other cases, an additional
##     generator is added to the machine in such a way that a product of
##     generators is trivial.
##
##     <P/> A standard FR machine can be recovered from an IMG FR machine
##     by <Ref Oper="AsGroupFRMachine"/>, <Ref Oper="AsMonoidFRMachine"/>,
##     and <Ref Oper="AsSemigroupFRMachine"/>.
## <Example><![CDATA[
## !!!
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="IMGRelator" Arg="m"/>
##   <Returns>The relator of the IMG FR machine.</Returns>
##   <Description>
##     This attribute stores the product of generators that is trivial.
##     In essence, it records an ordering of the generators whose
##     product is trivial in the punctured sphere's fundamental group.
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="Mating" Arg="m1,m2[,w1,w2]"/>
##   <Returns>An IMG FR machine.</Returns>
##   <Description>
##     This function mates two IMG FR machines. The arguments <A>w1,w2</A>
##     are IMG FR elements that represent adding elements; they may be
##     omitted if <A>m1,m2</A> contain pre-specified adding machines
##     (through the attribute <Ref Attr="AddingElement"/>). The elements
##     <A>w1</A> and <A>w2</A> must satisfy the same recursion.
##
##     <P/> The mating is defined as follows: one removes a disc around
##     the adding machine in <A>m1</A> and <A>m2</A>; one applies complex
##     conjugation to <A>m2</A>; and one glues the hollowed spheres along
##     their boundary circle.
## <Example><![CDATA[
## !!!
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="PolynomialFRMachine" Arg="d,per,pre"/>
##   <Oper Name="PolynomialIMGMachine" Arg="d,per,pre"/>
##   <Oper Name="PolynomialMealyMachine" Arg="d,per,pre"/>
##   <Returns>An IMG FR machine.</Returns>
##   <Description>
##     This function creates a group, IMG or Mealy machine that describes
##     a topological polynomial. The polynomial is described symbolically
##     in the language of <E>external angles</E>. For more details, see
##     <Cite Key="MR762431"/> and <Cite Key="MR812271"/> (in the quadratic
##      case), <Cite Key="MR1149891"/> (in the preperiodic case), and
##     <Cite Key="math.DS/9305207"/> (in the general case).
##
##     <P/> <A>d</A> is the degree of the polynomial. <A>per</A> and
##     <A>pre</A> are lists of angles or preangles. In what follows,
##     angles are rational numbers, considered modulo 1.  Each entry in
##     <A>per</A> or <A>pre</A> is either a rational (interpreted as an
##     angle), or a list of angles <M>[a_1,\dots,a_i]</M> such that
##     <M>da_1=\dots=da_i</M>.
## <Example><![CDATA[
## gap> PolynomialIMGMachine(2,[0],[]); # the adding machine
## <FR machine with alphabet [ 1 .. 2 ] on Group( [ f1, f2 ] )/[ f2*f1 ]>
## gap> Display(last);
##  G  |     1        2
## ----+--------+--------+
##  f1 | <id>,2     f1,1
##  f2 |   f2,2   <id>,1
## ----+--------+--------+
## Relator: f2*f1
## gap> Display(PolynomialIMGMachine(2,[1/3],[])); # the Basilica
##  G  |      1         2
## ----+---------+---------+
##  f1 | f1^-1,2   f2*f1,1
##  f2 |    f1,1    <id>,2
##  f3 |    f3,2    <id>,1
## ----+---------+---------+
## Relator: f3*f2*f1
## gap> Display(PolynomialIMGMachine(2,[],[1/6])); # z^2+I
##  G  |            1         2
## ----+---------------+---------+
##  f1 | f1^-1*f2^-1,2   f2*f1,1
##  f2 |          f1,1      f3,2
##  f3 |          f2,1    <id>,2
##  f4 |          f4,2    <id>,1
## ----+---------------+---------+
## Relator: f4*f3*f2*f1
## gap> PolynomialIMGMachine(3,[[0,1/3],[5/9,8/9]],[]);
## <FR machine with alphabet [ 1 .. 3 ] on Group( [ f1, f2, f3 ] )/[ f3*f2*f1 ]>
## gap> PolynomialIMGMachine(3,[[0,1/3]],[[5/9,8/9]]);
## <FR machine with alphabet [ 1 .. 3 ] on Group( [ f1, f2, f3, f4 ] )/[ f4*f3*f2*f1 ]>
## ]]></Example>
##     The following construct the examples in Poirier's paper:
## <Listing><![CDATA[
## PoirierExamples := function(arg)
##     if arg=[1] then
##         return PolynomialIMGMachine(2,[1/7],[]);
##     elif arg=[2] then
##         return PolynomialIMGMachine(2,[],[1/2]);
##     elif arg=[3,1] then
##         return PolynomialIMGMachine(2,[],[5/12]);
##     elif arg=[3,2] then
##         return PolynomialIMGMachine(2,[],[7/12]);
##     elif arg=[4,1] then
##         return PolynomialIMGMachine(3,[[3/4,1/12],[1/4,7/12]],[]);
##     elif arg=[4,2] then
##         return PolynomialIMGMachine(3,[[7/8,5/24],[5/8,7/24]],[]);
##     elif arg=[4,3] then
##         return PolynomialIMGMachine(3,[[1/8,19/24],[3/8,17/24]],[]);
##     elif arg=[5] then
##         return PolynomialIMGMachine(3,[[3/4,1/12],[3/8,17/24]],[]);
##     elif arg=[6,1] then
##         return PolynomialIMGMachine(4,[],[[1/4,3/4],[1/16,13/16],[5/16,9/16]]);
##     elif arg=[6,2] then
##         return PolynomialIMGMachine(4,[],[[1/4,3/4],[3/16,15/16],[7/16,11/16]]);
##     elif arg=[7] then
##         return PolynomialIMGMachine(5,[[0,4/5],[1/5,2/5,3/5]],[[1/5,4/5]]);
##     elif arg=[9,1] then
##         return PolynomialIMGMachine(3,[[0,1/3],[5/9,8/9]],[]);
##     elif arg=[9,2] then
##         return PolynomialIMGMachine(3,[[0,1/3]],[[5/9,8/9]]);
##     fi;
## end;
## ]]></Listing>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
BindGlobal("IMGRelator",NewAttribute("IMGRelator",IsGroupFRMachine));
DeclareSynonym("IsIMGFRMachine",IsGroupFRMachine and Tester(IMGRelator));
DeclareAttribute("AsGroupFRMachine",IsGroupHomomorphism);
DeclareAttribute("AsMonoidFRMachine",IsMagmaHomomorphism);
DeclareAttribute("AsSemigroupFRMachine",IsMagmaHomomorphism);
DeclareOperation("IMGFRMachine",[IsFRMachine,IsWord]);
DeclareOperation("IMGFRMachine",[IsFRMachine]);
DeclareProperty("IsKneadingMachine",IsFRMachine);
DeclareProperty("IsPlanarKneadingMachine",IsFRMachine);
InstallTrueMethod(IsBoundedFRMachine,IsKneadingMachine);
InstallTrueMethod(IsLevelTransitive,IsKneadingMachine);

DeclareOperation("Mating",[IsIMGFRMachine,IsIMGFRMachine,IsFRElement,IsFRElement]);
DeclareOperation("Mating",[IsIMGFRMachine,IsIMGFRMachine]);

DeclareOperation("PolynomialMealyMachine",[IsPosInt,IsList,IsList]);
DeclareOperation("PolynomialFRMachine",[IsPosInt,IsList,IsList]);
DeclareOperation("PolynomialIMGMachine",[IsPosInt,IsList,IsList]);

DeclareCategory("IsIMGFRElement",IsGroupFRElement);
DeclareAttribute("AsIMGFRElement",IsGroupFRElement);
#############################################################################

#############################################################################
##
#M ChangeFRMachineBasis
##
## <#GAPDoc Label="ChangeFRMachineBasis">
## <ManSection>
##   <Attr Name="ChangeFRMachineBasis" Arg="m[,l]"/>
##   <Returns>An equivalent FR machine, in a new basis.</Returns>
##   <Description>
##     This function constructs a new group FR machine, given a group
##     FR machine <A>m</A> and a list of states <A>l</A> (as elements of
##     the free object <C>StateSet(m)</C>).
##
##     <P/> The new machine
##     has the following transitions: if alphabet letter <C>a</C> is mapped
##     to <C>b</C> by state <C>s</C> in <A>m</A>, leading to state <C>t</C>,
##     then in the new machine the new state is <C>l[a]&circum;-1*t*l[b]</C>.
##
##     <P/> The group generated by the new machine is isomorphic to the
##     group generated by <A>m</A>. This command amounts to a change of
##     basis of the associated bimodule (see <Cite Key="MR2162164"
##     Where="Section 2.2"/>). It amounts to conjugation by the automorphism
##     <C>c=FRElement("c",[l[1]*c,...,l[n]*c],[()],1)</C>.
##
##     <P/> If the second argument is absent, this command attempts to
##     choose one that makes many entries of the recursion trivial.
## <Example><![CDATA[
## gap> n := FRMachine(["tau","mu"],[[[],[1]],[[],[-2]]],[(1,2),(1,2)]);;
## gap> Display(n);
##  G   |     1         2
## -----+--------+---------+
##  tau | <id>,2     tau,1
##   mu | <id>,2   mu^-1,1
## -----+--------+---------+
## gap> nt := ChangeFRMachineBasis(n,GeneratorsOfFRMachine(n){[1,1]});;
## gap> Display(nt);
##  G   |     1                    2
## -----+--------+--------------------+
##  tau | <id>,2                tau,1
##   mu | <id>,2   tau^-1*mu^-1*tau,1
## -----+--------+--------------------+
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation("ChangeFRMachineBasis", [IsFRMachine, IsCollection]);
DeclareOperation("ChangeFRMachineBasis", [IsFRMachine]);
#############################################################################

#############################################################################
##
#E Spiders
##
## <#GAPDoc Label="Spiders">
## <ManSection>
##   <Oper Name="RationalFunction" Arg="m"/>
##   <Returns>A rational function.</Returns>
##   <Description>
##   !!!
## <Example><![CDATA[
## !!!
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="IMGFRMachine" Arg="m" Label="rational function"/>
##   <Returns>An IMG FR machine.</Returns>
##   <Description>
##   !!!
## <Example><![CDATA[
## !!!
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation("RationalFunction", [IsIMGFRMachine]);
DeclareOperation("IMGFRMachine", [IsRationalFunction]);
DeclareAttribute("Spider", IsIMGFRMachine);
DeclareAttribute("Spider", IsRationalFunction);
#############################################################################

#############################################################################
##
#E DBRationalIMGGroup
##
## <#GAPDoc Label="DBRationalIMGGroup">
## <ManSection>
##   <Func Name="DBRationalIMGGroup" Arg="sequence or rational map"/>
##   <Returns>An IMG group from Dau's database.</Returns>
##   <Description>
##     This function returns the iterated monodromy group from a database
##     of groups associated to quadratic rational maps. This database has
##     been compiled by Dau Truong Tan <Cite Key="tan:database"/>.
##
##     <P/> When called with no arguments, this command returns the database
##     contents in raw form.
##
##     <P/> The argments can be a sequence; the first integer is the size
##     of the postcritical set, the second argument is an index for the
##     postcritical graph, and sometimes a third argument distinguishes
##     between maps with same post-critical graph.
##
##     <P/> If the argument is a rational map, the command returns the
##     IMG group of that map, assuming its
##     <Ref Func="CanonicalQuadraticRational"/> form exists in the
##     database.
## <Example><![CDATA[
## gap> DBRationalIMGGroup(z^2-1);
## IMG((z-1)^2)
## gap> DBRationalIMGGroup(z^2+1); # not post-critically finite
## fail
## gap> DBRationalIMGGroup(4,1,1);
## IMG((z/h+1)^2|2h^3+2h^2+2h+1=0,h~-0.64)
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Func Name="ValueRational" Arg="f,x"/>
##   <Returns>The value of <A>f</A> at <A>x</A>.</Returns>
##   <Description>
##     This function is almost identical to <C>Value(f,x)</C>. It accepts
##     <K>infinity</K> as an argument, and may return <K>infinity</K> as
##     a value.
## <Example><![CDATA[
## gap> z := Indeterminate(Rationals,"z");;
## gap> ValueRational(1/z,infinity);
## 0
## gap> ValueRational(1/z,0);
## infinity
## gap> ValueRational(1/z,1/2);
## 2
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Func Name="CriticalValuesQuadraticRational" Arg="f"/>
##   <Returns>The critical values of <A>f</A>.</Returns>
##   <Description>
##     This function returns, as a list, the values of <A>f</A> at places
##     where the derivative of <A>f</A> vanishes.
## <Example><![CDATA[
## gap> z := Indeterminate(Rationals,"z");;
## gap> CriticalValuesQuadraticRational(z^2);
## [ 0, infinity ]
## gap> CriticalValuesQuadraticRational(z^2+1);
## [ 1, infinity ]
## gap> CriticalValuesQuadraticRational((z^2+1)/(z^2-1));
## [ -1, 1 ]
## gap> CriticalValuesQuadraticRational((z^2+1)/(z^2-z-1));
## [ 2/5*E(5)-2/5*E(5)^2-2/5*E(5)^3+2/5*E(5)^4, -2/5*E(5)+2/5*E(5)^2+2/5*E(5)^3-2/5*E(5)^4 ]
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Func Name="CanonicalQuadraticRational" Arg="f"/>
##   <Returns>The canonical forms of the quadratic rational map <A>f</A>.</Returns>
##   <Description>
##     This function puts the quadratic rational map <A>f</A> in canonical
##     form, that is, in form <M>((az+b)/(cz+d))^2</M>, such that its
##     critical values are <K>0</K> and <K>infinity</K>. Furthermore, it
##     attempts to make <C>f(infinity)=1</C>, and if this is impossible
##     to make <C>f(0)=1</C>.
##
##     <P/> The command returns the set of all maps with these properties.
## <Example><![CDATA[
## gap> z := Indeterminate(Rationals,"z");;
## gap> CanonicalQuadraticRational(z^2);
## [ z^2 ]
## gap> CanonicalQuadraticRational(z^2+1);
## [ (z^2)/(z^2+2*z+1), z^2+2*z+1 ]
## gap> CanonicalQuadraticRational((z^2+1)/(z^2-1));
## [ (1/2*z^2+z+1/2)/(1/2*z^2-z+1/2), (-1/2*z^2+z-1/2)/(-1/2*z^2-z-1/2) ]
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Func Name="PostCriticalMachine" Arg="f"/>
##   <Returns>The Mealy machine of <A>f</A>'s post-critical orbit.</Returns>
##   <Description>
##     This function constructs a Mealy machine <C>P</C> on the alphabet
##     <C>[1]</C>, which describes the post-critical set of <A>f</A>.
##     It is in fact an oriented graph with constant out-degree 1. It is
##     most conveniently passed to <Ref Oper="Draw"/>.
##
##     <P/> The attribute <C>Correspondence(P)</C> is the list of values
##     associated with the stateset of <C>P</C>.
## <Example><![CDATA[
## gap> z := Indeterminate(Rationals,"z");;
## gap> m := PostCriticalMachine(z^2);
## <Mealy machine on alphabet [ 1 ] with 2 states>
## gap> Display(m);
##    |  1
## ---+-----+
##  a | a,1
##  b | b,1
## ---+-----+
## gap> Correspondence(m);
## [ 0, infinity ]
## gap> m := PostCriticalMachine(z^2-1);; Display(m); Correspondence(m);
##    |  1
## ---+-----+
##  a | c,1
##  b | b,1
##  c | a,1
## ---+-----+
## [ -1, infinity, 0 ]
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction("ValueRational");
DeclareGlobalFunction("CriticalValuesQuadraticRational");
DeclareGlobalFunction("CanonicalQuadraticRational");
DeclareGlobalFunction("PostCriticalMachine");
DeclareGlobalFunction("DBRationalIMGGroup");
#############################################################################

#E img.gd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
