Covering construction#

Permutation cover

This module deals with combinatorial data for covering of connected components of strata of Abelian and quadratic differentials. The main feature is to be able to compute Lyapunov exponents.

class surface_dynamics.interval_exchanges.cover.PermutationCover(base, degree, perms)[source]#

Bases: object

An interval exchange permutation together with covering data.

Let pi be the combinatorial data of an interval exchange transformation (or linear involution) on the alphabet {1, 2, ldots, m}. A cover of degree d is given by a list of permutations sigma_i in S_d for each i in {1, 2, ldots, m}.

In order to do so, each interval on the base surface should come with an orientation. This orientation is automatically chosen by convention according to a clockwise orientation of the surface. The two copies of any interval have to be oriented alternatively in this chosen orientation and in the opposite to it.

This convention is made such that the permutation associated to each interval is the action of the path going into the interval oriented according to the clockwise orientation and going out of the other one.

This class store three attributes

  • _base – combinatorial data of an i.e.t. or a l.i.

  • _degree_cover – (integer) degree of the cover

  • _permut_cover – list of permutations describing the cover

  • _inv_permut_cover – list of inverses of _permut_cover

automorphism_group[source]#

File: /usr/share/miniconda3/envs/test/lib/python3.10/site-packages/surface_dynamics/interval_exchanges/cover.py (starting at line 621)

Return the Deck group of the cover.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: p.cover(['(1,2,3)', '(1,3,2)', '']).automorphism_group()
Permutation Group with generators [(1,2,3), (1,3,2)]
sage: p.cover(['(1,2)', '(1,3)', '']).automorphism_group()
Permutation Group with generators [()]
base()[source]#

Return the combinatorial data corresponding to the base of this cover

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a b b','c c a')
sage: c = p.cover(['(1,2,3)','(1,3)','(1,2)'])
sage: q = c.base()
sage: q
a b b
c c a
sage: q == p
True
covering_data(label)[source]#

Returns the permutation associated to the given label.

EXAMPLES:

sage: from surface_dynamics import *

sage: p = QuadraticStratum([1,1,-1,-1]).components()[0].permutation_representative()
sage: pc = p.orientation_cover()
sage: pc
Covering of degree 2 of the permutation:
0 1 2 3 3
2 1 4 4 0

sage: pc.covering_data(1)
()
sage: pc.covering_data(3)
(1,2)
covering_data_tuple(label)[source]#

Returns the permutation associated to the given label as a tuple on {0, 1, ldots, d-1} where d is the degree of the cover.

EXAMPLES:

sage: from surface_dynamics import *

sage: p = QuadraticStratum([1,1,-1,-1]).components()[0].permutation_representative()
sage: pc = p.orientation_cover()
sage: pc
Covering of degree 2 of the permutation:
0 1 2 3 3
2 1 4 4 0

sage: pc.covering_data_tuple(1)
[0, 1]
sage: pc.covering_data_tuple(3)
[1, 0]
degree()[source]#
genus()[source]#

Genus of the covering translation surface

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: p.cover(['(1,2)', '()', '(1,2)']).genus()
1
sage: p.cover(['(1,2)', '(1,2)', '(1,2)']).genus()
0

TESTS:

sage: from surface_dynamics import *
sage: o = AbelianStratum([1,2,3,4]).one_component().one_origami()
sage: assert(o.genus() == AbelianStratum([1,2,3,4]).genus())
sage: qc = QuadraticStratum([1,2,3,4,-1,-1]).one_component()
sage: p = qc.permutation_representative()
sage: assert(p.orientation_cover().genus() == qc.orientation_cover_component().genus())
group#

File: /usr/share/miniconda3/envs/test/lib/python3.10/site-packages/surface_dynamics/interval_exchanges/cover.py (starting at line 621)

Return the Deck group of the cover.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: p.cover(['(1,2,3)', '(1,3,2)', '']).automorphism_group()
Permutation Group with generators [(1,2,3), (1,3,2)]
sage: p.cover(['(1,2)', '(1,3)', '']).automorphism_group()
Permutation Group with generators [()]
interval_diagram(sign=False)[source]#

Return the interval diagram.

This is the permutation induced on the subintervals of this cover while we turn around the singularities. This is mainly used to compute the stratum of this permutation.

OUTPUT:

A list of lists of pairs (label, index of interval) if sign=False or a list of triples (label, index of interval, sign).

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: c = p.cover(['(1,2)','(1,3)','(1,4)'])
sage: c.interval_diagram()
[[('a', 1), ('a', 0)],
 [('a', 2)],
 [('a', 3)],
 [('a', 0), ('b', 1), ('a', 1), ('b', 0), ('a', 2), ('b', 2)],
 [('a', 3), ('b', 3)],
 [('b', 2), ('c', 2), ('b', 0), ('c', 0), ('b', 3), ('c', 3)],
 [('b', 1), ('c', 1)],
 [('c', 3), ('c', 0)],
 [('c', 1)],
 [('c', 2)]]

sage: c.interval_diagram(sign=True)
    [[('a', 1, -1), ('a', 0, -1)],
     [('a', 2, -1)],
     [('a', 3, -1)],
     [('a', 0, 1), ('b', 1, 1), ..., ('b', 2, 1)],
     [('a', 3, 1), ('b', 3, 1)],
     [('b', 2, -1), ('c', 2, 1), ..., ('c', 3, 1)],
     [('b', 1, -1), ('c', 1, 1)],
     [('c', 3, -1), ('c', 0, -1)],
     [('c', 1, -1)],
     [('c', 2, -1)]]
is_orientable()[source]#

Test whether this permutation cover has an orientable foliation.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: from itertools import product
sage: it = iter(product(('()', '(1,2)'), repeat=3))
sage: next(it)
('()', '()', '()')

sage: for cov in it:
....:     c = p.cover(cov)
....:     print("%28s %s" % (cov, c.is_orientable()))
('()', '()', '(1,2)') False
('()', '(1,2)', '()') False
('()', '(1,2)', '(1,2)') False
('(1,2)', '()', '()') False
('(1,2)', '()', '(1,2)') True
('(1,2)', '(1,2)', '()') False
('(1,2)', '(1,2)', '(1,2)') False
isotypic_projection_matrix(i, floating_point=False)[source]#

TESTS:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a b b','c c a')
sage: c = p.cover(['(1,2,3)','(1,3,2)','()'])
sage: c.isotypic_projection_matrix(0)
[1/3   0   0 1/3   0   0 1/3   0   0]
[  0 1/3   0   0 1/3   0   0 1/3   0]
[  0   0 1/3   0   0 1/3   0   0 1/3]
[1/3   0   0 1/3   0   0 1/3   0   0]
[  0 1/3   0   0 1/3   0   0 1/3   0]
[  0   0 1/3   0   0 1/3   0   0 1/3]
[1/3   0   0 1/3   0   0 1/3   0   0]
[  0 1/3   0   0 1/3   0   0 1/3   0]
[  0   0 1/3   0   0 1/3   0   0 1/3]
sage: c.isotypic_projection_matrix(0, True)
array([[0.33333333, 0.        , 0.        , 0.33333333, 0.        ,
        0.        , 0.33333333, 0.        , 0.        ],
       [0.        , 0.33333333, 0.        , 0.        , 0.33333333,
        0.        , 0.        , 0.33333333, 0.        ],
       [0.        , 0.        , 0.33333333, 0.        , 0.        ,
        0.33333333, 0.        , 0.        , 0.33333333],
       [0.33333333, 0.        , 0.        , 0.33333333, 0.        ,
        0.        , 0.33333333, 0.        , 0.        ],
       [0.        , 0.33333333, 0.        , 0.        , 0.33333333,
        0.        , 0.        , 0.33333333, 0.        ],
       [0.        , 0.        , 0.33333333, 0.        , 0.        ,
        0.33333333, 0.        , 0.        , 0.33333333],
       [0.33333333, 0.        , 0.        , 0.33333333, 0.        ,
        0.        , 0.33333333, 0.        , 0.        ],
       [0.        , 0.33333333, 0.        , 0.        , 0.33333333,
        0.        , 0.        , 0.33333333, 0.        ],
       [0.        , 0.        , 0.33333333, 0.        , 0.        ,
        0.33333333, 0.        , 0.        , 0.33333333]])

TESTS:

sage: from surface_dynamics import *
sage: import numpy as np
sage: p = iet.Permutation('a b', 'b a')

sage: Q = QuaternionGroup()
sage: a,b = Q.gens()
sage: pp = p.regular_cover(Q, [a, b])
sage: for i in range(5):
....:     m1 = pp.isotypic_projection_matrix(i, True)
....:     m2 = pp.isotypic_projection_matrix(i, False).n().numpy()
....:     assert m1.shape == m2.shape and np.allclose(m1, m2)

sage: G = SL(2, 4)
sage: a, b = G.gens()
sage: pp = p.regular_cover(G, [a, b])
sage: for i in range(5):
....:     m1 = pp.isotypic_projection_matrix(i, True)
....:     m2 = pp.isotypic_projection_matrix(i, False).n().numpy()
....:     assert m1.shape == m2.shape and np.allclose(m1, m2)
isotypic_projectors(characters=None, floating_point=True)[source]#

Return the list of projectors on isotypical components in the canonical basis as well as the half ranks of the projection in absolute homology.

INPUT:

  • characters - (default None), if set to None compute projectors for all characters, otherwise if set to a list of characters return only the projectors for these characters.

  • floating_point - (default True) if set to True then all computations are performed over floating point numbers. Otherwise, exact cyclotomic elements are kept until the very last steps of the computation.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.Permutation('a b', 'b a')
sage: Q = QuaternionGroup()
sage: a,b = Q.gens()
sage: pp = p.regular_cover(Q, [a, b])
sage: X = pp.isotypic_projectors()
sage: X[0][0]
array([[0.125, 0.   , 0.125, 0.   , 0.125, 0.   , 0.125, 0.   , 0.125,
        0.   , 0.125, 0.   , 0.125, 0.   , 0.125, 0.   ],
       [0.   , 0.125, 0.   , 0.125, 0.   , 0.125, 0.   , 0.125, 0.   ,
        0.125, 0.   , 0.125, 0.   , 0.125, 0.   , 0.125],
...
        [0.   , 0.125, 0.   , 0.125, 0.   , 0.125, 0.   , 0.125, 0.   ,
         0.125, 0.   , 0.125, 0.   , 0.125, 0.   , 0.125]])
sage: import numpy as np
sage: Y = pp.isotypic_projectors(floating_point=False)
sage: np.allclose(X[0], Y[0])
True

sage: X[1]
[1, 0, 0, 0, 2]
sage: sum(X[1]) == pp.genus()
True

TESTS:

sage: from surface_dynamics import iet
sage: p = iet.GeneralizedPermutation('c a a', 'b b c', alphabet='abc')
sage: def cyclic(n,a):
....:     return [(i+a)%n + 1 for i in range(n)]
sage: def cyclic_cover(n, a, b, c):
....:     return p.cover([cyclic(n,c), cyclic(n,a), cyclic(n, b)])
sage: def cyclic_cover_regular(n, a, b, c):
....:     return p.regular_cover(Zmod(n), [c, a, b])

sage: for (dat, ans) in [((7,1,1,2), [0,2,2,2]),
....:                    ((7,1,3,3), [0,1,1,1]),
....:                    ((8,1,2,4), [0,0,1,2,2])]:
....:     c1 = cyclic_cover(*dat)
....:     c2 = cyclic_cover_regular(*dat)
....:     assert c1.isotypic_projectors(floating_point=True)[1] == ans
....:     assert c1.isotypic_projectors(floating_point=False)[1] == ans
....:     assert c2.isotypic_projectors(floating_point=True)[1] == ans
....:     assert c2.isotypic_projectors(floating_point=False)[1] == ans
....:     assert c1.genus() == sum(ans)
lyapunov_exponents_H_plus(nb_vectors=None, nb_experiments=10, nb_iterations=65536, output_file=None, return_speed=False, isotypic_decomposition=False, return_char=False, verbose=False, floating_point=True)[source]#

Compute the H^+ Lyapunov exponents in the covering locus.

This method calls a C-library that performs renormalization (i.e. Rauzy induction and orthogonalization of vectors under the Kontsevich-Zorich cocycle). The computation might be significantly faster if nb_vectors=1 (or if it is not provided but genus is 1) as in this case no orthogonalization is needed.

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.

  • 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.

  • return_speed – whether or not return the lyapunov exponents list in a pair with the speed of the geodesic.

  • isotypic_decomposition – either a boolean or a character or a list of characters.

  • return_char – whether or not return the character corresponding to the isotypic component.

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

  • float – whether the isotypical decomposition and projectors are computed over exact or floating point numbers

EXAMPLES:

sage: from surface_dynamics import *

sage: q = QuadraticStratum([1,1,-1,-1]).one_component()
sage: q.lyapunov_exponents_H_plus(nb_iterations=2**19)  # abs tol 0.1
[0.666666]
sage: p = q.permutation_representative(reduced=False).orientation_cover()
sage: c = p.lyapunov_exponents_H_plus(isotypic_decomposition=True, nb_iterations=2**19)[0]
sage: c[0]  # abs tol 0.1
1.000000

sage: p = iet.GeneralizedPermutation('e a a', 'b b c c d d e')
sage: p.stratum()
Q_0(1, -1^5)
sage: p.alphabet()
{'e', 'a', 'b', 'c', 'd'}
sage: c = p.cover(['()', '(1,2)', '()', '(1,2)', '(1,2)'])
sage: c.stratum(fake_zeros=True)
Q_1(1^2, 0^4, -1^2)
sage: c.lyapunov_exponents_H_plus(nb_iterations=2**19)  # abs tol 0.1
[0.666666]

Some cyclic covers (see [EskKonZor11] for the formulas):

sage: p = iet.GeneralizedPermutation('c a a', 'b b c', alphabet='abc')
sage: def cyclic(n,a):
....:     return [(i+a)%n + 1 for i in range(n)]
sage: def cyclic_cover(n, a, b, c):
....:     return p.cover([cyclic(n,c), cyclic(n,a), cyclic(n, b)])
sage: def cyclic_cover_regular(n, a, b, c):
....:     G = groups.misc.MultiplicativeAbelian([n])
....:     x, = G.gens()
....:     return p.regular_cover(G, [x**c, x**a, x**b])

sage: c = cyclic_cover(7,1,1,2)
sage: lexp = c.lyapunov_exponents_H_plus(isotypic_decomposition=True, nb_iterations=2**19)
sage: lexp  # abs tol 0.1
[[],
 [0.2857, 0.2857],
 [0.5714, 0.5714],
 [0.2857, 0.2857]]

sage: c = cyclic_cover(7, 1, 2, 3)
sage: lexp = c.lyapunov_exponents_H_plus(isotypic_decomposition=True, return_char=True, nb_iterations=2**19)
sage: lexp[0]
([], (1, 1, 1, 1, 1, 1, 1))
sage: lexp[1][0]  # abs tol 0.1
[0.2857, 0.2857]
sage: lexp[1][1]
(2, E(7) + E(7)^6, ..., E(7) + E(7)^6)
sage: lexp[2][0]  # abs tol 0.1
[0.2857, 0.2857]
sage: lexp[2][1]
(2, E(7)^2 + E(7)^5, ...,  E(7)^2 + E(7)^5)
sage: lexp[3][0]  # abs tol 0.1
[0.5714, 0.5714]
sage: lexp[3][1]
(2, E(7)^3 + E(7)^4, ..., E(7)^3 + E(7)^4)

The Eierlegendewollmilchsau as a quaternionic cover of the once punctured torus:

sage: p = iet.Permutation('a b', 'b a')
sage: Q = QuaternionGroup()
sage: a,b = Q.gens()
sage: c = p.cover([a, b])
sage: c.lyapunov_exponents_H_plus(nb_iterations=2**19)  # abs tol 0.05
[1.0, 0.0, 0.0]
masur_polygon(lengths, heights)[source]#

Return the Masur polygon for the given lengths and heights.

EXAMPLES:

sage: from surface_dynamics import iet

sage: p = iet.Permutation('a b c', 'c b a').cover(['(1,2)','(1,3)','(1,4)'])
sage: S = p.masur_polygon([1,4,2], [2,0,-1])  # optional: sage_flatsurf
sage: S.stratum()                             # optional: sage_flatsurf
H_4(3^2)
sage: p.stratum()                             # optional: sage_flatsurf
H_4(3^2)
monodromy[source]#

File: /usr/share/miniconda3/envs/test/lib/python3.10/site-packages/surface_dynamics/interval_exchanges/cover.py (starting at line 602)

Return the monodromy of this covering.

That it to say the permutation group generated by the action of the fundamental group.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: p.cover(['(1,2,3)', '(1,3,2)', '']).monodromy()
Permutation Group with generators [(1,2,3), (1,3,2), ()]
sage: p.cover(['(1,2)', '(1,3)', '']).monodromy()
Permutation Group with generators [(1,2), (1,3), ()]
profile()[source]#

Return the profile of the surface.

The profile of a translation surface is the list of angles of singularities in the surface divided by pi.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.Permutation('a b', 'b a')
sage: p.cover(['(1,2)', '(1,3)']).profile()
[6]
sage: p.cover(['(1,2,3)','(1,4)']).profile()
[6, 2]
sage: p.cover(['(1,2,3)(4,5,6)','(1,4,7)(2,5)(3,6)']).profile()
[6, 2, 2, 2, 2]

sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: p.cover(['(1,2)', '()', '(1,2)']).profile()
[2, 2, 2, 2]
stratum(fake_zeros=True)[source]#

Return the stratum of the covering translation surface.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')

sage: p.cover(['(1,2)', '()', '(1,2)']).stratum()
H_1(0^4)
sage: p.cover(['(1,2)', '()', '(1,2)']).stratum(fake_zeros=False)
H_1(0)

sage: p.cover(['(1,2)', '(1,2)', '(1,2)']).stratum()
Q_0(0^2, -1^4)
sage: p.cover(['(1,2)', '(1,2)', '(1,2)']).stratum(fake_zeros=False)
Q_0(-1^4)

TESTS:

sage: from surface_dynamics import *
sage: p1 = Permutation('(1,2,3)(4,5,6,7,8,9)(10,11)')
sage: p2 = Permutation('(1,3,5,7,9)(6,10)')
sage: Origami(p1, p2).stratum()
H_6(10)
sage: iet.Permutation('a b', 'b a').cover([p1, p2]).stratum()
H_6(10)

sage: p1 = Permutation('(1,2)(3,4)(5,6)(7,8,9,10)')
sage: p2 = Permutation('(2,3)(4,5)(6,7)')
sage: Origami(p1, p2).stratum()
H_4(3^2)
sage: iet.Permutation('a b', 'b a').cover([p1, p2]).stratum(fake_zeros=False)
H_4(3^2)

sage: p1 = Permutation('(1,2,3,4)(5,6,7,8,9,10)')
sage: p2 = Permutation('(4,5)(8,10)')
sage: Origami(p1, p2).stratum()
H_3(2, 1^2)
sage: iet.Permutation('a b', 'b a').cover([p1, p2]).stratum(fake_zeros=False)
H_3(2, 1^2)
class surface_dynamics.interval_exchanges.cover.RegularCover(base, grp, elts, check=True)[source]#

Bases: PermutationCover

An interval exchange permutation together with a regular covering data.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.Permutation('a b c', 'c b a')
sage: G = Zmod(3)
sage: p.regular_cover(G, [1, 0, 2])
Regular cover of degree 3 with group Multiplicative Abelian group isomorphic to C3 of the permutation:
a b c
c b a
sage: G = AbelianGroup([2,4])
sage: p.regular_cover(G, [(1,0), (0,0), (0,1)])
Regular cover of degree 8 with group Multiplicative Abelian group isomorphic to C2 x C4 of the permutation:
a b c
c b a

sage: G = GL(2, 3)
sage: g1, g2 = G.gens()
sage: p.regular_cover(G, [g1, g2, g1 * g2])
Regular cover of degree 48 with group General Linear Group of degree 2 over Finite Field of size 3 of the permutation:
a b c
c b a

An example using a semi-direct product built with GAP:

sage: C1 = libgap.CyclicGroup(2^5)
sage: C2 = libgap.CyclicGroup(2)
sage: gens1 = libgap.GeneratorsOfGroup(C1)
sage: gens2 = libgap.GeneratorsOfGroup(C2)
sage: alpha = libgap.GroupHomomorphismByImages(C1, C1, [gens1[0]], [gens1[0]^(-1)])
sage: phi = libgap.GroupHomomorphismByImages(C2, libgap.AutomorphismGroup(C1), [gens2[0]], [alpha])
sage: G = libgap.SemidirectProduct(C2, phi, C1)
sage: x = libgap.Image(libgap.eval("Embedding")(G, 2), gens1[0])
sage: y = libgap.Image(libgap.eval("Embedding")(G, 1), gens2[0])
sage: p = iet.Permutation('a b', 'b a')
sage: pp = p.regular_cover(G, [x, y])
sage: pp
Regular cover of degree 64 with group <pc group of size 64 with 6 generators> of the permutation:
a b
b a
sage: pp.isotypic_projectors()[1]
[1, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
sage: pp.lyapunov_exponents_H_plus(isotypic_decomposition=True)  # not tested (too long)
[[1.000],
 [],
 [],
 [],
 [0.5065137173173205, 0.5064242515256905],
 [0.25364063157823696, 0.25344903617958725],
 [0.7562155727190676, 0.7562259157608896],
 [0.1267784864027805, 0.12676433404844129],
 [0.3806034038221321, 0.38056305175722355],
 [0.6287868199859215, 0.6287551837770511],
 [0.8797056039630107, 0.8797049392731162],
 [0.06522712186764967, 0.06491210232533576],
 [0.1903390673409358, 0.19013594965668126],
 [0.3173095347090416, 0.3171889234380455],
 [0.44497853721724967, 0.444804933849061],
 [0.5662613367551405, 0.5662491535341443],
 [0.6906239438432811, 0.6905716259455005],
 [0.8165503109407333, 0.8164624067719244],
 [0.9385523471932377, 0.9383981565833286]]
degree()[source]#
group()[source]#

File: /usr/share/miniconda3/envs/test/lib/python3.10/site-packages/surface_dynamics/interval_exchanges/cover.py (starting at line 621)

Return the Deck group of the cover.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: p.cover(['(1,2,3)', '(1,3,2)', '']).automorphism_group()
Permutation Group with generators [(1,2,3), (1,3,2)]
sage: p.cover(['(1,2)', '(1,3)', '']).automorphism_group()
Permutation Group with generators [()]
is_orientable()[source]#

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b c d', 'b e d c f f e')
sage: G = Zmod(2)
sage: p.regular_cover(G, [1, 1, 1, 1, 1, 1]).is_orientable()
False
sage: p.regular_cover(G, [0, 1, 1, 1, 0, 0]).is_orientable()
False
sage: p.regular_cover(G, [1, 0, 0, 0, 1, 1]).is_orientable()
True

sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: G = GL(2, GF(3))
sage: g1 = G([[2,0],[0,1]])
sage: g2 = G([[2,1],[2,0]])
sage: p.regular_cover(G, [g1, g2, g1]).is_orientable()
True
monodromy()[source]#

File: /usr/share/miniconda3/envs/test/lib/python3.10/site-packages/surface_dynamics/interval_exchanges/cover.py (starting at line 602)

Return the monodromy of this covering.

That it to say the permutation group generated by the action of the fundamental group.

EXAMPLES:

sage: from surface_dynamics import *
sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: p.cover(['(1,2,3)', '(1,3,2)', '']).monodromy()
Permutation Group with generators [(1,2,3), (1,3,2), ()]
sage: p.cover(['(1,2)', '(1,3)', '']).monodromy()
Permutation Group with generators [(1,2), (1,3), ()]
profile()[source]#

TESTS:

sage: from surface_dynamics import *
sage: from surface_dynamics.interval_exchanges.cover import PermutationCover
sage: p = iet.GeneralizedPermutation('a a b c d', 'b e d c f f e')
sage: G = Zmod(2)
sage: pp = p.regular_cover(G, [1, 1, 1, 1, 1, 1])
sage: pp.profile()
[4, 4, 3, 3, 2, 2, 1, 1]
sage: PermutationCover.profile(pp)
[4, 4, 3, 3, 2, 2, 1, 1]

sage: pp = p.regular_cover(G, [0, 1, 1, 1, 0, 0])
sage: pp.profile()
[6, 4, 4, 2, 1, 1, 1, 1]
sage: PermutationCover.profile(pp)
[6, 4, 4, 2, 1, 1, 1, 1]

sage: p = iet.GeneralizedPermutation('a a b', 'b c c')
sage: G = GL(2, GF(3))
sage: g1 = G([[2,0],[0,1]])
sage: g2 = G([[2,1],[2,0]])
sage: pp = p.regular_cover(G, [g1, g2, g1])
sage: pp.profile() == PermutationCover.profile(pp)
True
sage: pp = p.regular_cover(G, [g1, g1*~g2, g2])
sage: pp.profile() == PermutationCover.profile(pp)
True
surface_dynamics.interval_exchanges.cover.to_gap(g)[source]#