Labelled permutations#

Labelled permutations

A labelled (generalized) permutation is better suited to study the dynamic of a translation surface than a reduced one (see the module surface_dynamics.interval_exchanges.reduced). The latter is more adapted to the study of strata. This kind of permutation was introduced by Yoccoz [Yoc06] (see also [MarMouYoc05]).

In fact, there is a geometric counterpart of labelled permutations. They correspond to translation surface with marked outgoing separatrices (i.e. we fi a label for each of them).

Remarks that Rauzy diagram of reduced objects are significantly smaller than the one for labelled object (for the permutation a b d b e / e d c a c the labelled Rauzy diagram contains 8760 permutations, and the reduced only 73). But, as it is in geometrical way, the labelled Rauzy diagram is a covering of the reduced Rauzy diagram.

AUTHORS:

  • Vincent Delecroix (2009-09-29) : initial version

  • Vincent Delecroix (2010-02-11) : correction and simplification of datatypes

TESTS:

sage: from surface_dynamics.interval_exchanges.labelled import LabelledPermutationIET
sage: LabelledPermutationIET([['a','b','c'],['c','b','a']])
a b c
c b a
sage: LabelledPermutationIET([[1,2,3,4],[4,1,2,3]])
1 2 3 4
4 1 2 3
sage: from surface_dynamics.interval_exchanges.labelled import LabelledPermutationLI
sage: LabelledPermutationLI([[1,1],[2,2,3,3,4,4]])
1 1
2 2 3 3 4 4
sage: LabelledPermutationLI([['a','a','b','b','c','c'],['d','d']])
a a b b c c
d d
sage: from surface_dynamics.interval_exchanges.labelled import FlippedLabelledPermutationIET
sage: FlippedLabelledPermutationIET([[1,2,3],[3,2,1]],flips=[1,2])
-1 -2  3
 3 -2 -1
sage: FlippedLabelledPermutationIET([['a','b','c'],['b','c','a']],flips='b')
 a -b  c
-b  c  a
sage: from surface_dynamics.interval_exchanges.labelled import FlippedLabelledPermutationLI
sage: FlippedLabelledPermutationLI([[1,1],[2,2,3,3,4,4]], flips=[1,4])
-1 -1
 2  2  3  3 -4 -4
sage: FlippedLabelledPermutationLI([['a','a','b','b'],['c','c']],flips='ac')
-a -a  b  b
-c -c
sage: from surface_dynamics.interval_exchanges.labelled import LabelledRauzyDiagram
sage: p = LabelledPermutationIET([[1,2,3],[3,2,1]])
sage: d1 = LabelledRauzyDiagram(p)
sage: p = LabelledPermutationIET([['a','b'],['b','a']])
sage: d = p.rauzy_diagram()
sage: g1 = d.path(p, 'top', 'bottom')
sage: g1.matrix()
[1 1]
[1 2]
sage: g2 = d.path(p, 'bottom', 'top')
sage: g2.matrix()
[2 1]
[1 1]
sage: p = LabelledPermutationIET([['a','b','c','d'],['d','c','b','a']])
sage: d = p.rauzy_diagram()
sage: g = d.path(p, 't', 't', 'b', 't', 'b', 'b', 't', 'b')
sage: g
Path of length 8 in a Rauzy diagram
sage: g.is_loop()
True
sage: g.is_full()
True
sage: s1 = g.orbit_substitution()
sage: print(s1)
a->adbd, b->adbdbd, c->adccd, d->adcd
sage: s2 = g.interval_substitution()
sage: print(s2)
a->abcd, b->bab, c->cdc, d->dcbababcd
sage: s1.incidence_matrix() == s2.incidence_matrix().transpose()
True
class surface_dynamics.interval_exchanges.labelled.FlippedLabelledPermutationIET(intervals=None, alphabet=None, reduced=False, flips=None)[source]#

Bases: FlippedPermutationIET, LabelledPermutationIET

Flipped labelled permutation from iet.

EXAMPLES:

sage: from surface_dynamics import *

Reducibility testing (does not depends of flips):

sage: p = iet.Permutation('a b c', 'c b a',flips='a')
sage: p.is_irreducible()
True
sage: q = iet.Permutation('a b c d', 'b a d c', flips='bc')
sage: q.is_irreducible()
False

Rauzy movability and Rauzy move:

sage: p = iet.Permutation('a b c', 'c b a',flips='a')
sage: p
-a  b  c
 c  b -a
sage: p.rauzy_move(1)
-c -a  b
-c  b -a
sage: p.rauzy_move(0)
-a  b  c
 c -a  b

Rauzy diagrams:

sage: d = iet.RauzyDiagram('a b c d','d a b c',flips='a')
rauzy_diagram(**kargs)[source]#

Returns the Rauzy diagram associated to this permutation.

For more information, try help(iet.RauzyDiagram)

OUTPUT:

RauzyDiagram – the Rauzy diagram of self

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b c', 'c b a',flips='a')
sage: p.rauzy_diagram()
Rauzy diagram with 3 permutations
reduced()[source]#

The associated reduced permutation.

OUTPUT:

permutation – the associated reduced permutation

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b c','c b a',flips='a')
sage: q = iet.Permutation('a b c','c b a',flips='a',reduced=True)
sage: p.reduced() == q
True
class surface_dynamics.interval_exchanges.labelled.FlippedLabelledPermutationLI(intervals=None, alphabet=None, reduced=False, flips=None)[source]#

Bases: FlippedPermutationLI, LabelledPermutationLI

Flipped labelled quadratic (or generalized) permutation.

EXAMPLES:

sage: from surface_dynamics import *

Rauzy movability and Rauzy move:

sage: p = iet.GeneralizedPermutation('a a b b c c', 'd d', flips='d')
sage: p.has_rauzy_move(0)
False
sage: p.has_rauzy_move(1)
True
sage: p = iet.GeneralizedPermutation('a a b','b c c',flips='c')
sage: p.has_rauzy_move(0)
True
sage: p.has_rauzy_move(1)
True
left_rauzy_move(winner)[source]#

Perform a Rauzy move on the left.

INPUT:

  • winner - either ‘top’ or ‘bottom’ (‘t’ or ‘b’ for short)

OUTPUT:

– a permutation

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b','b c c')
sage: p.left_rauzy_move(0)
a a b b
c c
sage: p.left_rauzy_move(1)
a a b
b c c
sage: p = iet.GeneralizedPermutation('a b b','c c a')
sage: p.left_rauzy_move(0)
a b b
c c a
sage: p.left_rauzy_move(1)
b b
c c a a
rauzy_diagram(**kargs)[source]#

Returns the associated Rauzy diagram.

For more information, try help(RauzyDiagram)

OUTPUT :

– a RauzyDiagram

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.GeneralizedPermutation('a b b a', 'c d c d')
sage: d = p.rauzy_diagram()
reduced()[source]#

The associated reduced permutation.

OUTPUT:

permutation – the associated reduced permutation

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.GeneralizedPermutation('a a','b b c c',flips='a')
sage: q = iet.GeneralizedPermutation('a a','b b c c',flips='a',reduced=True)
sage: p.reduced() == q
True
right_rauzy_move(winner)[source]#

Perform a Rauzy move on the right (the standard one).

INPUT:

  • winner - either ‘top’ or ‘bottom’ (‘t’ or ‘b’ for short)

OUTPUT:

permutation – the Rauzy move of self

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.GeneralizedPermutation('a a b','b c c',flips='c')
sage: p.right_rauzy_move(0)
 a  a  b
-c  b -c
sage: p.right_rauzy_move(1)
 a  a
-b -c -b -c
sage: p = iet.GeneralizedPermutation('a b b','c c a',flips='ab')
sage: p.right_rauzy_move(0)
 a -b  a -b
 c  c
sage: p.right_rauzy_move(1)
 b -a  b
 c  c -a
class surface_dynamics.interval_exchanges.labelled.FlippedLabelledRauzyDiagram(p, right_induction=True, left_induction=False, left_right_inversion=False, top_bottom_inversion=False, symmetric=False)[source]#

Bases: FlippedRauzyDiagram, LabelledRauzyDiagram

Rauzy diagram of flipped labelled permutations

class surface_dynamics.interval_exchanges.labelled.LabelledPermutation[source]#

Bases: SageObject

General template for labelled objects.

Warning

Internal class! Do not use directly!

list(flips=False)[source]#

Returns a list of two lists corresponding to the intervals.

INPUT:

  • flips - boolean (default: False) - if True returns instead of letters use pair of letter and flip.

OUTPUT: two lists of labels (or labels with flips)

EXAMPLES:

sage: from surface_dynamics import *

The list of an permutation from iet:

sage: p1 = iet.Permutation('1 2 3', '3 1 2')
sage: p1.list()
[['1', '2', '3'], ['3', '1', '2']]
sage: p1.alphabet("abc")
sage: p1.list()
[['a', 'b', 'c'], ['c', 'a', 'b']]

Recovering the permutation from this list (and the alphabet):

sage: q1 = iet.Permutation(p1.list(),alphabet=p1.alphabet())
sage: p1 == q1
True

The list of a quadratic permutation:

sage: p2 = iet.GeneralizedPermutation('g o o', 'd d g')
sage: p2.list()
[['g', 'o', 'o'], ['d', 'd', 'g']]

Recovering the permutation:

sage: q2 = iet.GeneralizedPermutation(p2.list(),alphabet=p2.alphabet())
sage: p2 == q2
True

Some non-orientable examples:

sage: p = iet.GeneralizedPermutation('0 0 1 2 2 1', '3 3', flips='1')
sage: p.list(flips=True)
[[('0', 1), ('0', 1), ('1', -1), ('2', 1), ('2', 1), ('1', -1)], [('3', 1), ('3', 1)]]
sage: p.list(flips=False)
[['0', '0', '1', '2', '2', '1'], ['3', '3']]

sage: iet.Permutation('a b c', 'c b a').list(flips=True)
[[('a', 1), ('b', 1), ('c', 1)], [('c', 1), ('b', 1), ('a', 1)]]

The list can be used to reconstruct the permutation:

sage: p = iet.Permutation('a b c','c b a',flips='ab')
sage: p == iet.Permutation(p.list(), flips=p.flips())
True
sage: p = iet.GeneralizedPermutation('a b b c','c d d a',flips='ad')
sage: p == iet.GeneralizedPermutation(p.list(), flips=p.flips())
True
rauzy_move_loser(winner=None, side=None)[source]#

Returns the loser of a Rauzy move

INPUT:

  • winner - either ‘top’ or ‘bottom’ (‘t’ or ‘b’ for short)

  • side - either ‘left’ or ‘right’ (‘l’ or ‘r’ for short)

OUTPUT:

– a label

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b c d','b d a c')
sage: p.rauzy_move_loser('top','right')
'c'
sage: p.rauzy_move_loser('bottom','right')
'd'
sage: p.rauzy_move_loser('top','left')
'b'
sage: p.rauzy_move_loser('bottom','left')
'a'
rauzy_move_matrix(winner=None, side='right')[source]#

Returns the Rauzy move matrix.

This matrix corresponds to the action of a Rauzy move on the vector of lengths. By convention (to get a positive matrix), the matrix is define as the inverse transformation on the length vector.

OUTPUT:

matrix – a square matrix of positive integers

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: p.rauzy_move_matrix('t')
[1 0]
[1 1]
sage: p.rauzy_move_matrix('b')
[1 1]
[0 1]
sage: p = iet.Permutation('a b c d','b d a c')
sage: q = p.left_right_inverse()
sage: m0 = p.rauzy_move_matrix(winner='top',side='right')
sage: n0 = q.rauzy_move_matrix(winner='top',side='left')
sage: m0 == n0
True
sage: m1 = p.rauzy_move_matrix(winner='bottom',side='right')
sage: n1 = q.rauzy_move_matrix(winner='bottom',side='left')
sage: m1 == n1
True
rauzy_move_winner(winner=None, side=None)[source]#

Returns the winner of a Rauzy move.

INPUT:

  • winner - either ‘top’ or ‘bottom’ (‘t’ or ‘b’ for short)

  • side - either ‘left’ or ‘right’ (‘l’ or ‘r’ for short)

OUTPUT:

– a label

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b c d','b d a c')
sage: p.rauzy_move_winner('top','right')
'd'
sage: p.rauzy_move_winner('bottom','right')
'c'
sage: p.rauzy_move_winner('top','left')
'a'
sage: p.rauzy_move_winner('bottom','left')
'b'
sage: p = iet.GeneralizedPermutation('a b b c','d c a e d e')
sage: p.rauzy_move_winner('top','right')
'c'
sage: p.rauzy_move_winner('bottom','right')
'e'
sage: p.rauzy_move_winner('top','left')
'a'
sage: p.rauzy_move_winner('bottom','left')
'd'
relabel(p)[source]#

Relabel this permutation according to p.

EXAMPLES:

sage: from surface_dynamics import iet
sage: p = iet.Permutation('a b c \n c b a')
sage: p.relabel([2, 1, 0])
sage: p
c b a
a b c
class surface_dynamics.interval_exchanges.labelled.LabelledPermutationIET(intervals=None, alphabet=None, reduced=False, flips=None)[source]#

Bases: LabelledPermutation, OrientablePermutationIET

Labelled permutation for iet

EXAMPLES:

sage: from surface_dynamics import *

Reducibility testing:

sage: p = iet.Permutation('a b c', 'c b a')
sage: p.is_irreducible()
True

sage: q = iet.Permutation('a b c d', 'b a d c')
sage: q.is_irreducible()
False

Rauzy movability and Rauzy move:

sage: p = iet.Permutation('a b c', 'c b a')
sage: p.has_rauzy_move('top')
True
sage: p.rauzy_move('bottom')
a c b
c b a
sage: p.has_rauzy_move('top')
True
sage: p.rauzy_move('top')
a b c
c a b

Rauzy diagram:

sage: p = iet.Permutation('a b c', 'c b a')
sage: d = p.rauzy_diagram()
sage: p in d
True
lyapunov_exponents_approx(nb_vectors=None, nb_experiments=10, nb_iterations=65536, return_speed=False, verbose=False, output_file=None)[source]#

Return approximate Lyapunov exponents of the KZ-cocycle.

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation([1,2,3],[3,2,1])
sage: p.lyapunov_exponents_approx()  # abs tol .1
[1.000]
rauzy_diagram(**args)[source]#

Returns the associated Rauzy diagram.

For more information try help(iet.RauzyDiagram).

OUTPUT:

Rauzy diagram – the Rauzy diagram of the permutation

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b c', 'c b a')
sage: d = p.rauzy_diagram()
rauzy_move_interval_substitution(winner=None, side=None)[source]#

Returns the interval substitution associated.

INPUT:

  • winner - the winner interval (‘top’ or ‘bottom’)

  • side - (default: ‘right’) the side (‘left’ or ‘right’)

OUTPUT:

WordMorphism – a substitution on the alphabet of the permutation

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: print(p.rauzy_move_interval_substitution('top','right'))
a->a, b->ba
sage: print(p.rauzy_move_interval_substitution('bottom','right'))
a->ab, b->b
sage: print(p.rauzy_move_interval_substitution('top','left'))
a->ba, b->b
sage: print(p.rauzy_move_interval_substitution('bottom','left'))
a->a, b->ab
rauzy_move_orbit_substitution(winner=None, side=None)[source]#

Return the action of the rauzy_move on the orbit.

INPUT:

  • i - integer

  • winner - the winner interval (‘top’ or ‘bottom’)

  • side - (default: ‘right’) the side (‘right’ or ‘left’)

OUTPUT:

WordMorphism – a substitution on the alphabet of self

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: print(p.rauzy_move_orbit_substitution('top','right'))
a->ab, b->b
sage: print(p.rauzy_move_orbit_substitution('bottom','right'))
a->a, b->ab
sage: print(p.rauzy_move_orbit_substitution('top','left'))
a->a, b->ba
sage: print(p.rauzy_move_orbit_substitution('bottom','left'))
a->ba, b->b

TESTS:

sage: p = iet.Permutation('a1 a2', 'a2 a1')
sage: p.rauzy_move_orbit_substitution('top','right').codomain().alphabet()
{'a1', 'a2'}
reduced()[source]#

Returns the associated reduced abelian permutation.

OUTPUT:

a reduced permutation – the underlying reduced permutation

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation(“a b c d”,”d c a b”) sage: q = iet.Permutation(“a b c d”,”d c a b”,reduced=True) sage: p.reduced() == q True

class surface_dynamics.interval_exchanges.labelled.LabelledPermutationLI(intervals=None, alphabet=None, reduced=False, flips=None)[source]#

Bases: LabelledPermutation, OrientablePermutationLI

Labelled quadratic (or generalized) permutation

EXAMPLES:

sage: from surface_dynamics import *

Reducibility testing:

sage: p = iet.GeneralizedPermutation('a b b', 'c c a')
sage: p.is_irreducible()
True

Reducibility testing with associated decomposition:

sage: p = iet.GeneralizedPermutation('a b c a', 'b d d c')
sage: p.is_irreducible()
False
sage: test, decomposition = p.is_irreducible(return_decomposition = True)
sage: test
False
sage: decomposition
(['a'], ['c', 'a'], [], ['c'])

Rauzy movability and Rauzy move:

sage: p = iet.GeneralizedPermutation('a a b b c c', 'd d')
sage: p.has_rauzy_move(0)
False
sage: p.has_rauzy_move(1)
True
sage: q = p.rauzy_move(1)
sage: q
a a b b c
c d d
sage: q.has_rauzy_move(0)
True
sage: q.has_rauzy_move(1)
True

Rauzy diagrams:

sage: p = iet.GeneralizedPermutation('0 0 1 1','2 2')
sage: r = p.rauzy_diagram()
sage: p in r
True
has_right_rauzy_move(winner)[source]#

Test of Rauzy movability with a specified winner)

A quadratic (or generalized) permutation is rauzy_movable type depending on the possible length of the last interval. It’s dependent of the length equation.

INPUT:

  • winner - ‘top’ (or ‘t’ or 0) or ‘bottom’ (or ‘b’ or 1)

OUTPUT:

bool – True if self has a Rauzy move

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.GeneralizedPermutation('a a','b b')
sage: p.has_right_rauzy_move('top')
False
sage: p.has_right_rauzy_move('bottom')
False
sage: p = iet.GeneralizedPermutation('a a b','b c c')
sage: p.has_right_rauzy_move('top')
True
sage: p.has_right_rauzy_move('bottom')
True
sage: p = iet.GeneralizedPermutation('a a','b b c c')
sage: p.has_right_rauzy_move('top')
True
sage: p.has_right_rauzy_move('bottom')
False
sage: p = iet.GeneralizedPermutation('a a b b','c c')
sage: p.has_right_rauzy_move('top')
False
sage: p.has_right_rauzy_move('bottom')
True
left_rauzy_move(winner)[source]#

Perform a Rauzy move on the left.

INPUT:

  • winner - ‘top’ or ‘bottom’

OUTPUT:

permutation – the Rauzy move of self

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.GeneralizedPermutation('a a b','b c c')
sage: p.left_rauzy_move(0)
a a b b
c c
sage: p.left_rauzy_move(1)
a a b
b c c
sage: p = iet.GeneralizedPermutation('a b b','c c a')
sage: p.left_rauzy_move(0)
a b b
c c a
sage: p.left_rauzy_move(1)
b b
c c a a

TESTS:

sage: p = iet.GeneralizedPermutation('a a b','b c c')
sage: q = p.top_bottom_inverse()
sage: q = q.left_rauzy_move(0)
sage: q = q.top_bottom_inverse()
sage: q == p.left_rauzy_move(1)
True
sage: q = p.top_bottom_inverse()
sage: q = q.left_rauzy_move(1)
sage: q = q.top_bottom_inverse()
sage: q == p.left_rauzy_move(0)
True
sage: q = p.left_right_inverse()
sage: q = q.right_rauzy_move(0)
sage: q = q.left_right_inverse()
sage: q == p.left_rauzy_move(0)
True
sage: q = p.left_right_inverse()
sage: q = q.right_rauzy_move(1)
sage: q = q.left_right_inverse()
sage: q == p.left_rauzy_move(1)
True
lyapunov_exponents_H_minus(nb_vectors=None, nb_experiments=10, nb_iterations=65536, return_speed=False, verbose=False, output_file=None)[source]#

Compute the H^+ Lyapunov exponents of the stratum associated to this permutation.

This method calls a C library. It might be significantly faster if nb_vectors=1 (or if it is not provided but genus is 1).

INPUT:

  • nb_vectors – the number of exponents to compute. The number of vectors must not exceed the dimension of the space!

  • nb_experiments – the number of experiments to perform. It might be around 100 (default value) in order that the estimation of confidence interval is accurate enough.

  • nb_iterations – the number of iteration of the Rauzy-Zorich algorithm to perform for each experiments. The default is 2^16=65536 which is rather small but provide a good compromise between speed and quality of approximation.

  • verbose – if True provide additional information rather than returning only the Lyapunov exponents (i.e. elapsed time, confidence intervals, …)

  • output_file – if provided (as a file object or a string) output the additional information in the given file rather than on the standard output.

EXAMPLES:

sage: from surface_dynamics import *
sage: Q = QuadraticStratum([1,1,-1,-1]).unique_component()
sage: p = Q.permutation_representative(reduced=False)
sage: lexp = p.lyapunov_exponents_H_minus(nb_iterations=2**20)
sage: lexp  # random
[1.000, 0.333]
sage: len(lexp)
2
sage: sum(lexp)  # abs tol .1
1.333

sage: Q_reg = QuadraticStratum([12]).regular_component()
sage: p_reg = Q_reg.permutation_representative(reduced=False)
sage: lexp = p_reg.lyapunov_exponents_H_minus(nb_iterations=2**19)
sage: lexp  # random
[1.000, 0.309, 0.119]
sage: len(lexp)
3
sage: sum(lexp)  # abs tol .1
1.428

sage: Q_irr = QuadraticStratum([12]).irregular_component()
sage: p_irr = Q_irr.permutation_representative(reduced=False)
sage: lexp = p_irr.lyapunov_exponents_H_minus(nb_iterations=2**19)
sage: lexp  # random
[1.000, 0.444, 0.128]
sage: len(lexp)
3
sage: sum(lexp)  # abs tol .1
1.5725
lyapunov_exponents_H_plus(nb_vectors=None, nb_experiments=10, nb_iterations=65536, return_speed=False, verbose=False, output_file=None)[source]#

Compute the H^+ Lyapunov exponents of the stratum associated to this permutation.

This method calls a C library. It might be significantly faster if nb_vectors=1 (or if it is not provided but genus is 1).

INPUT:

  • nb_vectors – the number of exponents to compute. The number of vectors must not exceed the dimension of the space!

  • nb_experiments – the number of experiments to perform. It might be around 100 (default value) in order that the estimation of confidence interval is accurate enough.

  • nb_iterations – the number of iteration of the Rauzy-Zorich algorithm to perform for each experiments. The default is 2^15=32768 which is rather small but provide a good compromise between speed and quality of approximation.

  • verbose – if True provide additional information rather than returning only the Lyapunov exponents (i.e. elapsed time, confidence intervals, …)

  • output_file – if provided (as a file object or a string) output the additional information in the given file rather than on the standard output.

EXAMPLES:

sage: from surface_dynamics import *
sage: Q = QuadraticStratum([1,1,-1,-1]).unique_component()
sage: p = Q.permutation_representative(reduced=False)
sage: p.lyapunov_exponents_H_plus(nb_iterations=2**20)  # abs tol .1
[0.6666]

sage: Q_reg = QuadraticStratum([12]).regular_component()
sage: p_reg = Q_reg.permutation_representative(reduced=False)
sage: lexp = p_reg.lyapunov_exponents_H_plus(nb_iterations=2**20)
sage: lexp  # random
[0.662, 0.448, 0.230, 0.087]
sage: len(lexp)
4
sage: sum(lexp)  # abs tol .1
1.428

sage: Q_irr = QuadraticStratum([12]).irregular_component()
sage: p_irr = Q_irr.permutation_representative(reduced=False)
sage: lexp = p_irr.lyapunov_exponents_H_plus(nb_iterations=2**20)
sage: lexp  # random
[0.747, 0.491, 0.245, 0.090]
sage: len(lexp)
4
sage: sum(lexp)  # abs tol .1
1.572
rauzy_diagram(**kargs)[source]#

Returns the associated RauzyDiagram.

OUTPUT:

Rauzy diagram – the Rauzy diagram of the permutation

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.GeneralizedPermutation('a b c b', 'c d d a')
sage: d = p.rauzy_diagram()
sage: p in d
True

For more information, try help(iet.RauzyDiagram)

reduced()[source]#

Returns the associated reduced quadratic permutations.

OUTPUT:

permutation – the underlying reduced permutation

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.GeneralizedPermutation('a a','b b c c')
sage: q = p.reduced()
sage: q
a a
b b c c
sage: p.rauzy_move(0).reduced() == q.rauzy_move(0)
True
right_rauzy_move(winner)[source]#

Perform a Rauzy move on the right (the standard one).

INPUT:

  • winner - ‘top’ (or ‘t’ or 0) or ‘bottom’ (or ‘b’ or 1)

OUTPUT:

boolean – True if self has a Rauzy move

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.GeneralizedPermutation('a a b','b c c')
sage: p.right_rauzy_move(0)
a a b
b c c
sage: p.right_rauzy_move(1)
a a
b b c c
sage: p = iet.GeneralizedPermutation('a b b','c c a')
sage: p.right_rauzy_move(0)
a a b b
c c
sage: p.right_rauzy_move(1)
a b b
c c a

TESTS:

sage: p = iet.GeneralizedPermutation('a a b','b c c')
sage: q = p.top_bottom_inverse()
sage: q = q.right_rauzy_move(0)
sage: q = q.top_bottom_inverse()
sage: q == p.right_rauzy_move(1)
True
sage: q = p.top_bottom_inverse()
sage: q = q.right_rauzy_move(1)
sage: q = q.top_bottom_inverse()
sage: q == p.right_rauzy_move(0)
True
sage: p = p.left_right_inverse()
sage: q = q.left_rauzy_move(0)
sage: q = q.left_right_inverse()
sage: q == p.right_rauzy_move(0)
True
sage: q = p.left_right_inverse()
sage: q = q.left_rauzy_move(1)
sage: q = q.left_right_inverse()
sage: q == p.right_rauzy_move(1)
True
surface_dynamics.interval_exchanges.labelled.LabelledPermutationsIET_iterator(nintervals=None, irreducible=True, alphabet=None)[source]#

Returns an iterator over labelled permutations.

INPUT:

  • nintervals - integer or None

  • irreducible - boolean (default: True)

  • alphabet - something that should be converted to an alphabet of at least nintervals letters

OUTPUT:

iterator – an iterator over permutations

TESTS:

sage: from surface_dynamics import iet

sage: for p in sorted(iet.Permutations_iterator(2, alphabet="ab")):
....:     print("%s\n****" % p)  #indirect doctest
a b
b a
****
b a
a b
****
sage: for p in iet.Permutations_iterator(3, alphabet="abc"):
....:     print("%s\n*****" %p)   #indirect doctest
a b c
b c a
*****
a b c
c a b
*****
a b c
c b a
*****
a c b
b a c
*****
a c b
b c a
*****
a c b
c b a
*****
b a c
a c b
*****
b a c
c a b
*****
b a c
c b a
*****
b c a
a b c
*****
b c a
a c b
*****
b c a
c a b
*****
c a b
a b c
*****
c a b
b a c
*****
c a b
b c a
*****
c b a
a b c
*****
c b a
a c b
*****
c b a
b a c
*****
class surface_dynamics.interval_exchanges.labelled.LabelledRauzyDiagram(p, right_induction=True, left_induction=False, left_right_inversion=False, top_bottom_inversion=False, symmetric=False)[source]#

Bases: RauzyDiagram

Template for Rauzy diagrams of labelled permutations.

…DO NOT USE…

class Path(parent, *data)[source]#

Bases: Path

Path in Labelled Rauzy diagram.

dual_substitution()#

Returns the substitution of intervals obtained.

OUTPUT:

WordMorphism – the word morphism corresponding to the interval

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: r = p.rauzy_diagram()
sage: p0 = r.path(p,0)
sage: s0 = p0.interval_substitution()
sage: print(s0)
a->a, b->ba
sage: p1 = r.path(p,1)
sage: s1 = p1.interval_substitution()
sage: print(s1)
a->ab, b->b
sage: (p0 + p1).interval_substitution() == s1 * s0
True
sage: (p1 + p0).interval_substitution() == s0 * s1
True
interval_substitution()[source]#

Returns the substitution of intervals obtained.

OUTPUT:

WordMorphism – the word morphism corresponding to the interval

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: r = p.rauzy_diagram()
sage: p0 = r.path(p,0)
sage: s0 = p0.interval_substitution()
sage: print(s0)
a->a, b->ba
sage: p1 = r.path(p,1)
sage: s1 = p1.interval_substitution()
sage: print(s1)
a->ab, b->b
sage: (p0 + p1).interval_substitution() == s1 * s0
True
sage: (p1 + p0).interval_substitution() == s0 * s1
True
is_full()[source]#

Tests the fullness.

A path is full if all intervals win at least one time.

OUTPUT:

boolean – True if the path is full and False else

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b c','c b a')
sage: r = p.rauzy_diagram()
sage: g0 = r.path(p,'t','b','t')
sage: g1 = r.path(p,'b','t','b')
sage: g0.is_full()
False
sage: g1.is_full()
False
sage: (g0 + g1).is_full()
True
sage: (g1 + g0).is_full()
True
matrix()[source]#

Returns the matrix associated to a path.

The matrix associated to a Rauzy induction, is the linear application that allows to recover the lengths of self from the lengths of the induced.

OUTPUT:

matrix – a square matrix of integers

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a1 a2','a2 a1')
sage: d = p.rauzy_diagram()
sage: g = d.path(p,'top')
sage: g.matrix()
[1 0]
[1 1]
sage: g = d.path(p,'bottom')
sage: g.matrix()
[1 1]
[0 1]
sage: p = iet.Permutation('a b c','c b a')
sage: d = p.rauzy_diagram()
sage: g = d.path(p)
sage: g.matrix() == identity_matrix(3)
True
sage: g = d.path(p,'top')
sage: g.matrix()
[1 0 0]
[0 1 0]
[1 0 1]
sage: g = d.path(p,'bottom')
sage: g.matrix()
[1 0 1]
[0 1 0]
[0 0 1]
orbit_substitution()[source]#

Returns the substitution on the orbit of the left extremity.

OUTPUT:

WordMorphism – the word morphism corresponding to the orbit

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: d = p.rauzy_diagram()
sage: g0 = d.path(p,'top')
sage: s0 = g0.orbit_substitution()
sage: print(s0)
a->ab, b->b
sage: g1 = d.path(p,'bottom')
sage: s1 = g1.orbit_substitution()
sage: print(s1)
a->a, b->ab
sage: (g0 + g1).orbit_substitution() == s0 * s1
True
sage: (g1 + g0).orbit_substitution() == s1 * s0
True
self_similar_iet(name='a')[source]#

Return the self-similar interval exchange transformation associated to this path

INPUT:

  • name - an optional name for the generator of the number field

EXAMPLES:

sage: from surface_dynamics import *

The golden rotation:

sage: p = iet.Permutation('a b', 'b a')
sage: R = p.rauzy_diagram()
sage: g = R.path(p, 't', 'b')
sage: T = g.self_similar_iet()
sage: T.lengths().parent()
Vector space of dimension 2 over Number Field ...
sage: T.lengths().n()
(1.00000000000000, 1.61803398874989)

An example from Do-Schmidt:

sage: code = [1,0,1,0,1,0,0,0,1,0,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,0]
sage: p = iet.Permutation([0,1,2,3,4,5,6],[6,5,4,3,2,1,0])
sage: R = p.rauzy_diagram()
sage: g = R.path(p, *code)
sage: T = g.self_similar_iet()
sage: T.sah_arnoux_fathi_invariant()
(0, 0, 0)
substitution()#

Returns the substitution on the orbit of the left extremity.

OUTPUT:

WordMorphism – the word morphism corresponding to the orbit

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: d = p.rauzy_diagram()
sage: g0 = d.path(p,'top')
sage: s0 = g0.orbit_substitution()
sage: print(s0)
a->ab, b->b
sage: g1 = d.path(p,'bottom')
sage: s1 = g1.orbit_substitution()
sage: print(s1)
a->a, b->ab
sage: (g0 + g1).orbit_substitution() == s0 * s1
True
sage: (g1 + g0).orbit_substitution() == s1 * s0
True
edge_to_interval_substitution(p=None, edge_type=None)[source]#

Returns the interval substitution associated to an edge

OUTPUT:

WordMorphism – the WordMorphism corresponding to the edge

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b c','c b a')
sage: r = p.rauzy_diagram()
sage: print(r.edge_to_interval_substitution(None,None))
a->a, b->b, c->c
sage: print(r.edge_to_interval_substitution(p,0))
a->a, b->b, c->ca
sage: print(r.edge_to_interval_substitution(p,1))
a->ac, b->b, c->c
edge_to_orbit_substitution(p=None, edge_type=None)[source]#

Returns the interval substitution associated to an edge

OUTPUT:

WordMorphism – the word morphism corresponding to the edge

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b c','c b a')
sage: r = p.rauzy_diagram()
sage: print(r.edge_to_orbit_substitution(None,None))
a->a, b->b, c->c
sage: print(r.edge_to_orbit_substitution(p,0))
a->ac, b->b, c->c
sage: print(r.edge_to_orbit_substitution(p,1))
a->a, b->b, c->ac

TESTS:

sage: from surface_dynamics import *

sage: pi0 = iet.Permutation('A1 A2 B', 'B A1 A2')
sage: G = pi0.rauzy_diagram()
sage: s1 = G.edge_to_orbit_substitution(pi0,0)
sage: s1.domain().alphabet()
{'A1', 'A2', 'B'}
sage: s1.codomain().alphabet()
{'A1', 'A2', 'B'}
full_loop_iterator(start=None, max_length=1)[source]#

Returns an iterator over all full path starting at start.

INPUT:

  • start - the start point

  • max_length - a limit on the length of the paths

OUTPUT:

iterator – iterator over full loops

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: r = p.rauzy_diagram()
sage: for g in r.full_loop_iterator(p,2):
....:     print("%s\n*****" % g.matrix())
[1 1]
[1 2]
*****
[2 1]
[1 1]
*****
full_nloop_iterator(start=None, length=1)[source]#

Returns an iterator over all full loops of given length.

INPUT:

  • start - the initial permutation

  • length - the length to consider

OUTPUT:

iterator – an iterator over the full loops of given length

EXAMPLES:

sage: from surface_dynamics import *

sage: p = iet.Permutation('a b','b a')
sage: d = p.rauzy_diagram()
sage: for g in d.full_nloop_iterator(p,2):
....:     print("%s\n*****" % g.matrix())
[1 1]
[1 2]
*****
[2 1]
[1 1]
*****