Origamis¶
Individual origamis and Teichmüller curves¶
Dense origamis
An origami is a pair (r,u) of permutations up to conjugacy. The computation of canonic representative of an origami is performed by an independant C program in normal_form.c
A pillowcase cover is a quadruple (g_0, g_1, g_2, g_3) of permutations such that the product g_0 g_1 g_2 g_3 is the identity. It is sometimes called a 4-constellations. The computation of canonic representative is performed by an independant C program in noraml_form.c
-
class
surface_dynamics.flat_surfaces.origamis.origami_dense.
Origami_dense_pyx
¶ Bases:
object
Origami or square tiled surface.
An origami is a flat surface which is a covering of a one punctered torus. It can be described either by a couple of permutations up to conugacy (in the symmetric group) or by a subgroup of finite index of the free group on two generators.
EXAMPLES:
sage: from surface_dynamics.all import * sage: Origami([2,1,3], [3,2,1]) (1,2)(3) (1,3)(2)
-
absolute_period_generators
()¶ Return a generating set of the absolute periods of this origami.
To each curve on an origami, we can associate its holonomy (that is an element of ZZ times ZZ). This function returns a generating set of the module generated by holonomies of closed curves.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3,4)(5,6)', '(1,5)(2,6)') sage: o.absolute_period_generators() [(2, 0), (2, 0), (0, 1), (0, 1)]
-
as_graph
()¶ Return the graph associated to self
The graph associated to an origami is the graph on [1,...,N] for which the edges correspond to the action of the permutations r and u.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o=Origami('(1,2)','(1,3)') sage: G = o.as_graph(); G Looped multi-digraph on 3 vertices sage: G.vertices() [0, 1, 2] sage: G.edges() [(0, 1, 'r'), (0, 2, 'u'), (1, 0, 'r'), (1, 1, 'u'), (2, 0, 'u'), (2, 2, 'r')]
-
automorphism_group
()¶ Returns the automorphism group of the origami as a permutation group
The automorpism group of a translation surface is the set of affine diffeomorphisms which have a trivial linear part. For an origami, it corresponds combinatorially to the centralizer of the group generated by the permutations
r
andu
that define this origami.EXAMPLES:
sage: from surface_dynamics.all import *
The L with 3 squares has no automorphisms:
sage: o = Origami('(1,2)','(1,3)') sage: G = o.automorphism_group() sage: G.order() 1
The 4-squares square tiled surface in H(1,1) has non trivial automorphism for which the quotient is a torus with two squares:
sage: o = Origami('(1,2)(3,4)','(2,3)') sage: G = o.automorphism_group() sage: G.order() 2 sage: oo = o.quotient(G) sage: oo (1,2) (1)(2)
-
connected_components
()¶ Return the list of connected origami that composes this origami.
-
cover
()¶ Build the (ramified) cover of this origami by sr and su
INPUT:
- sr, su - two list of N permutations where N is the number of squares of this origami
- check - whether or not check the input
- as_tuple - assume that sr and su are list of tuples of the same length and corresponds to permutations of [0,...,d-1] (much more efficient in time)
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)'); o (1,2)(3) (1,3)(2) sage: o.cover(['(1,2)','',''],['','','']) (1,5,4,2)(3)(6) (1,3)(2)(4,6)(5)
-
cylinder_decomposition
()¶ Returns the cylinder decomposition of the standard form of this origami.
OUTPUT:
A list of cylinders where each cylinder is a 6-tuple
(bot,top,w,h,bot_twist,top_twist)
wherebot
andtop
are list of right squares adjacent to singularities (the order is in the direction of the permutation r of the origami)w
andh
are width and height of the cylinderbot_twist
andtop_twist
are twist between the minimum square number and the minimum square number adjacent to a singularity.
EXAMPLES:
sage: from surface_dynamics.all import * sage: r = '(1,2,3,4)(5,6)' sage: u0 = '(1,5)(2,6)(3)(4)' sage: u1 = '(1,5,2,6,3,4)' sage: Origami(r, u0).cylinder_decomposition() [([(1, 3)], [(3, 1)], 2, 1, 0, 0), ([(3, 1), (5, 5)], [(5, 5), (1, 3)], 4, 1, 0, 0)] sage: Origami(r, u1).cylinder_decomposition() [([(1, 6)], [(3, 1)], 2, 1, 0, 0), ([(3, 1), (5, 4)], [(1, 6), (5, 4)], 4, 1, 0, 1)]
-
cylinder_diagram
()¶ Returns the cylinder diagram corresponding to the horizontal direction. If
data
is True, returns as well the list of lengths of separatrices, the heigths of cylinders and the twists.The cylinder diagram of a completely periodic surface encodes the combinatorics of cylinders and saddle connections. From a cylinder diagram and its metric data, it is possible to build the surface back.
INPUT:
data
- boolean (default: False) - if True, return the cylinder diagrams, the lengths, the heights and twists.
EXAMPLES:
sage: from surface_dynamics.all import *
The two examples in the stratum H(2):
sage: o1 = Origami('(1,2,3)','(2,3)') sage: o1.stratum() H_2(2) sage: c1 = o1.cylinder_diagram() sage: c1.ncyls() 1 sage: c1.nseps() 3 sage: o2 = Origami('(1,2)','(1,3)') sage: o2.stratum() H_2(2) sage: c2 = o2.cylinder_diagram() sage: c2.ncyls() 2 sage: c2.nseps() 3 sage: r = (1,2,0,4,5,6,3) sage: u = (1,2,3,5,4,0,6) sage: o = Origami(r,u,as_tuple=True) sage: c,lengths,heights,twists = o.cylinder_diagram(True) sage: c.cylcoord_to_origami(lengths,heights,twists) == o True
TESTS:
Check consistency of cylinder data:
sage: r = '(1,2,3,4,5,6,7,8)(9,10,11,12,13,14,15,16)' sage: u = '(1,9,3,15,5,13,7,11)(2,14,8,16,6,10,4,12)' sage: o3 = Origami(r,u) sage: c3 = o3.cylinder_diagram() sage: c3.ncyls() 2 sage: c3.nseps() 8 sage: r = '(1,2,3,4)(5,6,7,8)(9,10,11,12)(13,14,15,16)' sage: u = '(1,5,3,10)(2,9,13,11)(4,8,15,6)(7,14,12,16)' sage: o4 = Origami(r,u) sage: c4 = o4.cylinder_diagram() sage: c4.ncyls() 4 sage: c4.nseps() 8
-
genus
()¶ Return the genus of the origami
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.genus() 2 sage: o = Origami('(1,2)(3,4)','(1,3)') sage: o.genus() 2
-
gl2z_edges
()¶ Return a couple of dictionnaries
(l_edges, i_edges)
associated to the action of GL(2,ZZ)The generators of GL(2,ZZ) considered are
BEWARE: Do not modify the output dictionnary!
\[\begin{split}L=\begin{pmatrix}1&1\\0&1\end{pmatrix} I=\begin{pmatrix}0&1\\1&0\end{pmatrix} \quad \text{and} \quad\end{split}\]EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: l,i = o.gl2z_edges() sage: for oo in l: print("(%s,%s) -> (%s,%s)" %(oo.r(),oo.u(),l[oo].r(),l[oo].u())) ((1,2,3),(2,3)) -> ((1,2,3),(2,3)) ((2,3),(1,2)) -> ((2,3),(1,2,3)) ((2,3),(1,2,3)) -> ((2,3),(1,2))
TESTS:
sage: o = Origami('(1,2,3,4)','(1,5)') sage: l,i = o.gl2z_edges() sage: ll,ii = o.gl2z_edges() sage: l is ll True sage: i is ii True
-
horizontal_symmetry
()¶ Return the origami (r, u^{-1}).
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3)(5,6)', '(1,4)(3,5,7)') sage: oh = o.horizontal_symmetry(); oh (1,2,3)(4)(5,6)(7) (1,4)(2)(3,7,5)(6)
We check that it commutes with vertical symmetry of the cylinder diagram:
sage: ch1 = o.cylinder_diagram().horizontal_symmetry() sage: ch2 = oh.cylinder_diagram() sage: ch1.is_isomorphic(ch2) True
-
horizontal_twist
()¶ Return the origami (r, ur^{-k}) which is obtained by the action of an horizontal twist of width
k
on this origamiINPUT:
width
- integer (default: 1) - the width of the twist
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3,4,5,6)','(1,7)') sage: o (1,2,3,4,5,6)(7) (1,7)(2)(3)(4)(5)(6) sage: o.horizontal_twist() (1,2,3,4,5,6)(7) (1,6,5,4,3,2,7) sage: o.horizontal_twist(-1) (1,2,3,4,5,6)(7) (1,2,3,4,5,6,7) sage: o.horizontal_twist(6) == o True
-
intermediate_covers
()¶ Return the list of intermediate covers of this origami.
If
degree
is specified, only intermediate covers of given degree are returned.EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(3,4,5)', '(1,2,3)(4,6,7)(5,8,9)') sage: for oo in o.intermediate_covers(): ....: print(oo.nb_squares()) ....: print(oo) ....: print("- - - - - -") 1 (1) (1) - - - - - - 3 (1)(2)(3) (1,2,3) - - - - - - 9 (1)(2)(3,4,5)(6)(7)(8)(9) (1,2,3)(4,6,7)(5,8,9) - - - - - - sage: o.intermediate_covers(degree=3) [(1)(2)(3) (1,2,3)]
-
inverse
()¶ Return the origami (r^{-1}, u^{-1}) which corresponds to the action of -Id on the origami.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3)','(1,2)') sage: o (1,2,3) (1,2)(3) sage: o.inverse() (1,3,2) (1,2)(3)
We check that it commutes with the inverse operation on cylinder diagrams:
sage: o = Origami('(1,2,3)(5,6)', '(1,4)(3,5,7)') sage: os = o.inverse(); os (1,3,2)(4)(5,6)(7) (1,4)(2)(3,7,5)(6) sage: c = o.cylinder_diagram() sage: cs1 = o.cylinder_diagram().inverse() sage: cs2 = os.cylinder_diagram() sage: cs1.is_isomorphic(cs2) True
-
is_connected
()¶ Check whether the origami is connected or not
It is equivalent to ask whether the group generated by r and u acts transitively on the {1,dots,n}.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.is_connected() True sage: o = Origami('(1,2)(3,4)','(1,2)',check=False) sage: o.is_connected() False
-
is_hyperelliptic
()¶ Return True if this origami is hyperelliptic
If
stratum
is set toTrue
, then returns also the corresponding stratum of quadratic differentials this origami is a cover from.EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.is_hyperelliptic() True sage: o.is_hyperelliptic(stratum=True) (True, Q_0(1, -1^5)) sage: o = origamis.Podium([3,3,2,1]) sage: o.is_hyperelliptic() False sage: o.is_hyperelliptic(stratum=True) (False, None)
-
is_isomorphic
()¶ Isomorphism test
EXAMPLES:
sage: from surface_dynamics.all import * sage: o1 = Origami('(1,2)','(1,3)') sage: o2 = Origami('(1,2)','(2,3)') sage: o3 = Origami('(1,3)','(1,2)') sage: o1.is_isomorphic(o2) and o2.is_isomorphic(o1) True sage: o1.is_isomorphic(o3) and o3.is_isomorphic(o1) True sage: o2.is_isomorphic(o3) and o3.is_isomorphic(o2) True
-
is_normal
()¶ Tests if this origami is a normal cover of the torus
An origami is normal if the subgroup of F_2 that defines the cover is normal. It is equivalent to say that the order of the automorphism group equals the number of squares or that the automorphism group acts transitively on the squares.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.is_normal() False sage: o.is_regular() False sage: o = origamis.Escalator(4) sage: o.is_normal() True sage: o.is_normal() == o.is_regular() True
-
is_orientation_cover
()¶ Return true if the origami is an orientation cover of a quadratic differential.
It is equivalent to say that -1 is in the Veech group.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.is_orientation_cover() True sage: r = '(1,2,3,4,5,6,7,8,9,10)' sage: u = '(3,5,7,9,4,8,10)' sage: o = Origami(r, u) sage: o.is_orientation_cover() False
-
is_primitive
()¶ An origami is primitive if it does not cover an other origami.
An origami is primitive if the action of the monodromy group has no non trivial block.
EXAMPLE:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.is_primitive() True sage: o = Origami('(1,2)(3,4)','(1,3,5,6)(2,4)') sage: o.is_primitive() False
-
is_quadratic_cover
()¶ Return true if the origami is an orientation cover of a quadratic differential.
It is equivalent to say that -1 is in the Veech group.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.is_orientation_cover() True sage: r = '(1,2,3,4,5,6,7,8,9,10)' sage: u = '(3,5,7,9,4,8,10)' sage: o = Origami(r, u) sage: o.is_orientation_cover() False
-
is_quasi_primitive
()¶ An origami is quasi primitive if it is reduced and all intermediate covers are of genus 1.
SEE ALSO:
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)(3,4)','(1,3)') sage: o.is_primitive() False sage: o.is_quasi_primitive() True sage: o = Origami('(1,2,3,4)(5)(6)','(1,5)(3,6)') sage: o.is_primitive() False sage: o.is_quasi_primitive() False
-
is_quasi_regular
()¶ An origami (r,u) is quasi-regular if the normal closure of the commutator c = rur^{-1}u^{-1} is contained in the automorphism group.
Equivalently, a quasi-regular origami is a translation surface which is a normal cover of a torus ramified over several rational points.
-
is_reduced
()¶ Test of reducibility
An origami is reduced, if it is not a ramified cover of a bigger torus with only one ramification point. In other terms, it is equivalent to say that the period of the origami generates ZZ^2.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.is_reduced() True sage: o = Origami('(1,2,3,4)(5,6)','(1,5)(2,6)') sage: o.is_reduced() False sage: o = Origami('(1,2)(3,4)','(1,3,5,6)(2,4)') sage: o.is_reduced() False sage: o = Origami('(1,2,3,4)(5,6)','(1,5)(2,6)') sage: o.is_reduced() False sage: o = Origami('(1,2,3,4)(5,6)','(1,5)(2,6)') sage: o.is_reduced() False sage: o = Origami('(1)(2)(3)','(1,2,3)') sage: o.is_reduced() False
-
is_regular
()¶ An origami is regular if its automorphism group acts transitively on the squares.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = origamis.EierlegendeWollmilchsau() sage: o.is_regular() True sage: o.is_normal() True
sage: o = Origami('(1,3,2,4,5,6)','(1,5)') sage: o.is_regular() False sage: o.is_normal() False
-
lattice_of_absolute_periods
()¶ Returns (a,t,u) where ((a,0),(t,u)) is a standard basis for the lattice of the absolute periods of self
The lattice of periods of an origami is the sublattice of ZZ^2 generated by the holonomy vectors of its saddle connections. Any sublattice of ZZ^2 has a standard basis consisting of a horizontal vector (a,0) and a nonhorizontal vector (t,u), where a, t, u are integers satisfying 0 <= t < a and 0 < t.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)(3,4)', '(2,3)') sage: o.lattice_of_absolute_periods() (2, 0, 1) sage: r = '(1,2)(3,4)(5,6)(7,8,9,10)(11,12)' sage: u = '(1,3,5,7)(2,4,6,8)(9,11,10,12)' sage: o = Origami(r,u) sage: o.lattice_of_absolute_periods() (2, 1, 2)
-
lattice_of_periods
()¶ Returns (a,t,u) where ((a,0),(t,u)) is a standard basis for the lattice of periods of self
The lattice of periods of an origami is the sublattice of ZZ^2 generated by the holonomy vectors of its saddle connections. Any sublattice of ZZ^2 has a standard basis consisting of a horizontal vector (a,0) and a nonhorizontal vector (t,u), where a, t, u are integers satisfying 0 <= t < a and 0 < t.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.lattice_of_periods() (1, 0, 1) sage: r = '(1,2,3,4,5,6,7,8,9)(10,11,12)(13,14,15,16,17,18,19,20,21)' sage: u = '(1,14,21,19,8,3,10,5,12,4,11,6)(2,15,16,17,18,7)(9,13,20)' sage: oy = Origami(r,u) sage: oy.lattice_of_periods() (3, 2, 1)
-
lattice_of_quotients
()¶ Return the lattice of quotients of this origami.
The set of quotients of an origami contain a maximal element (itself) and a minimal element (the 1-torus). More generally, it is organised as a lattice.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: P = o.normal_cover().lattice_of_quotients(); P Finite lattice containing 6 elements sage: for p in P: ....: print(p.nb_squares(), p.stratum_component()) 6 H_3(2^2)^odd 3 H_2(2)^hyp 3 H_2(2)^hyp 3 H_2(2)^hyp 2 H_1(0)^hyp 1 H_1(0)^hyp sage: o = Origami('(1,2)(3,4)','(1,3)') sage: o.lattice_of_quotients() Finite lattice containing 3 elements
-
lyapunov_exponents_approx
()¶ Approximation of Lyapunov exponents of the Kontsevich-Zorich cocycle.
An origami defines a Teichmuller curve in the moduli space of translation surfaces. The Kontsevich-Zorich cocycle above this Teichmuller curve (for the Haar measure) has the following form
\[1 = \lambda_1, \lambda_2, ... \lambda_g, -\lambda_g, ..., -\lambda_2, -\lambda_1 = -1\]This function return the approximations of lambda_2, lambda_3, ..., lambda_g) as a list.
INPUT:
nb_iterations
- integer (default: 2**17) - the number of iterations performed in the algorithmnb_experiments
- integer (default: 4) - the number of experiments to performonly_mean
- boolean (default:True
) - ifTrue
, returns the list of mean exponents, otherwise returns a list of lists.nb_vectors
- integer (default: genus-1) - the number of vectors to considerinvolution
- permutation or boolean - ifTrue
or an inan involution for the origami with derivative either 1.nb_vectors_p
,nb_vectors_m
- if involution is not None, then it will be interpreted as the number of + and - vectors to consider.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)(3,4)(5,6)','(2,3)(4,5)') sage: lexp = o.lyapunov_exponents_approx() sage: lexp # random [0.665250480769510, 0.332194948308155] sage: 0.6 < lexp[0] < 0.7 and 0.3 < lexp[1] < 0.4 True sage: o = Origami('(1,2)(3,4)(5,6)(7,8)(9,10)','(2,3)(4,5)(6,7)(8,9)') sage: s = SymmetricGroup(10)('(1,10)(2,9)(3,8)(4,7)(5,6)') sage: o.lyapunov_exponents_approx(involution=s) # random ([0.600372348286643, 0.199902392953331], [0.800242827363281, 0.399695139521823])
-
mirror
()¶ Return the origami (u,r)
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3,4)','(1,5)'); o (1,2,3,4)(5) (1,5)(2)(3)(4) sage: o.mirror() (1,5)(2)(3)(4) (1,2,3,4)(5)
-
monodromy
()¶ Return the monodromy group of the origami.
The monodromy group of an origami is the group generated by the permutations
r
andu
from which it is defined.INPUT:
relative
– ifTrue
return the monodromy relative to the largest torus over which this origami is a cover (possibly ramified over several points)
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: G = o.monodromy() sage: G Permutation Group with generators [(1,2), (1,3)] sage: G.order() 6
-
nb_squares
()¶ Return the number of squares.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)', '(1,3)') sage: o.nb_squares() 3
-
nb_vertices
()¶ Return the number of singularities of this origami
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.nb_vertices() 1 sage: o = Origami('(1,2,3)(4,5,6)','(3,4)') sage: o.nb_vertices() 2
-
normal_cover
()¶ Return the normal cover of this origami.
-
num_cylinders
()¶ Return the number of cylinders of this origami.
EXAMPLES:
sage: from surface_dynamics.all import * sage: Origami('(1,2)','(1,3)').num_cylinders() 2 sage: origamis.Stair(5).num_cylinders() 3 sage: Origami('(1,2)','(1)(2)').num_cylinders() 1
-
optimal_degree
()¶ The optimal degree of self is the degree of the map to the largest torus.
Any origami X to T factor as i circ pi_{opt} where i is an isogeny. The optimal degree is the degree of pi_{opt}.
EXAMPLES:
sage: from surface_dynamics.all import * sage: E = origamis.EierlegendeWollmilchsau() sage: E.optimal_degree() 2 sage: o = Origami('(1,2)(3,4)', '(2,3)') sage: o.optimal_degree() 2 sage: o = Origami('(1,2)', '(1,3)') sage: o.optimal_degree() 3
-
orientation_data
()¶ Return the list of quadratic stratum and ramification data associated to the orientation quotients of this origami. If the origami is primitive, then there is at most one orientation quotient.
Each element of the list is a 3-tuple containing:
- a quadratic stratum
- the list of degrees of zeros which are ramified in the covering (consider only integer points)
- the partition of half-integers points which are mapped to poles (middle of squares, horizontal edges, vertical edges)
INPUT:
points
- boolean (default: False) - return singularitiy tuples and not only degrees
EXAMPLES:
sage: from surface_dynamics.all import *
The stratum H(2) contains two families of primitive origamis for an odd number of squares. Every surface in H(2) is a covering of a quadratic differential in Q(1,-1^5). The ramification data gives an invariant for those families:
sage: o = Origami('(1,2,3,4,5)','(2,1)') sage: o.stratum_component() H_2(2)^hyp sage: o.orientation_data() [(Q_0(1, -1^5), (2,), (1, 3, 1))] sage: o = Origami('(1,2,3)','(1,4,5)') sage: o.stratum_component() H_2(2)^hyp sage: o.orientation_data() [(Q_0(1, -1^5), (2, 0, 0), (1, 1, 1))] sage: o = Origami('(1)(2)(3,4)(5,6,7)','(1,2,3)(4,5)(6)(7)') sage: o.stratum_component() H_3(4)^hyp sage: o.orientation_data() [(Q_0(3, -1^7), (0, 4, 0), (3, 1, 1))] sage: o = Origami('(1)(2)(3)(4,5)(6,7)','(1,2,3,4)(5,6,7)') sage: o.stratum_component() H_3(4)^hyp sage: o.orientation_data() [(Q_0(3, -1^7), (4,), (3, 1, 3))] sage: o = Origami('(1)(2)(3)(4,5)(6,7)','(1,2,3,4)(5,6)(7)') sage: o.stratum_component() H_3(4)^hyp sage: o.orientation_data() [(Q_0(3, -1^7), (4,), (5, 1, 1))] sage: o = Origami('(1,2,4)(3,6,5)','(1,3)(2,5)(4,6)') sage: for q,_,_ in o.orientation_data(): print(q) Q_1(4, -1^4) Q_1(4, -1^4) Q_0(1^2, -1^6) Q_1(4, -1^4)
-
period_generators
()¶ Return a list of periods that generate the lattice of periods.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,3,6)(2,5,7)(4)', '(1,2,4,3,5,6,7)') sage: sorted(o.period_generators()) [(-1, 2), (0, 1), (0, 2), (1, 0), (1, 0), (2, 0)] sage: r = '(1,17,6,18,10,8)(11,2,12,5,7,9)(15,16)(3,13)(14,4)' sage: u = '(1,11,15,3,14,10,7,6,12)(17,2,16,13,4,8,9,18,5)' sage: o = Origami(r,u) sage: o.stratum() H_2(2) sage: sorted(o.period_generators()) [(-2, 2), (0, 2), (0, 3), (2, 0), (2, 0), (4, 0)] sage: o = Origami('(1)(2)(3)','(1,2,3)') sage: o.period_generators() [(1, 0), (0, 3)] sage: o = Origami('(1,2)','(1,2)') sage: o.period_generators() [(2, 0), (-1, 1)]
-
pgl2z_edges
()¶ Action of PGL(2,ZZ)
Projective action of the matrices
L= 1 1 0 1
and
I= 0 1 1 0
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: l,i = o.pgl2z_edges() sage: len(l) 3 sage: len(i) 3
-
plot
(*args, **kwds)¶ Plot the normal form of self
The positions of each square follow a naive algorithm. If you belive that a better picture exists look at the method .set_positions()
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = origamis.Escalator(3) sage: o.plot() # not tested (problem with matplotlib font caches) Graphics object consisting of 71 graphics primitives
-
psl2z_edges
()¶ Return the action of PSL(2,ZZ)
The generators are
L= 1 1 0 1
R= 0 1 1 1
and
S= 0 -1 1 0
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: l,r,s = o.psl2z_edges() sage: len(l) 3 sage: len(r) 3 sage: len(s) 3
-
quotient
()¶ Returns a quotient of self by the group
H
.The group
H
must be a subgroup of the automorphism group of this origami. IfH
is None, it is set by default to the full automorphism group.EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)(3,4)','(2,3)') sage: G = o.automorphism_group() sage: G.order() 2 sage: oo = o.quotient(G) sage: print(oo) (1,2) (1)(2) sage: oo.genus() 1
-
r
()¶ Return the right permutation of the origami.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3)','(1,2)') sage: o.r() (1,2,3)
-
r_inv
()¶ Return the inverse of the right permutation
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3)','(1,2)') sage: o.r_inv() (1,3,2)
-
r_inv_tuple
()¶ Return the inverse of the right permutation as a tuple on {0,...,n-1}
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3)','(1,2)') sage: o.r_inv_tuple() (2, 0, 1)
-
r_tuple
()¶ Return the right permutation of the origami as a tuple on {0,...,n-1}
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.r_tuple() (1, 0, 2)
-
reduce
()¶ Return a reduced origami isomorphic (up to SL(2,QQ) action) to that origami.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)(3,4)','(1,3,5,6)(2,4)') sage: o.lattice_of_periods() (1, 0, 2) sage: o.reduce() (1,2)(3) (1,3)(2) sage: o = Origami('(1,2)(3,4,5,6)','(1,3,5)(2,4,6)') sage: o.lattice_of_periods() (2, 0, 1) sage: o.reduce() (1)(2,3) (1,2,3) sage: o = Origami('(1,2)(3,4,5,6)','(1,3,4,5)(2,6)') sage: o.lattice_of_periods() (2, 1, 1) sage: o.reduce() (1)(2,3) (1,2,3)
-
relabel
()¶ Relabel self
INPUT:
return_map
– return the labelizationinplace
– modify self, the default is False. It might be dangerous to set it True as an origami is hashable and the hash is modified by this operation.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3,4)(5,6)','(2,5)(3,6)') sage: o2,p = o.relabel(return_map=True) sage: old_r = o.r_tuple() sage: old_u = o.u_tuple() sage: new_r = o2.r_tuple() sage: new_u = o2.u_tuple() sage: all(p[old_r[i]] == new_r[p[i]] for i in xrange(6)) True sage: all(p[old_u[i]] == new_u[p[i]] for i in xrange(6)) True
-
rename
()¶
-
set_positions
()¶ Choose position of the squares for plotting
set self._positions set self._lr_frontiers set self._tb_frontiers
-
show
()¶ Show a picture of this origami.
-
sl2z_edges
()¶ Action of the matrices l,r,s
L = 1 1 0 1
R = 1 0 1 1
S = L~RL = 0 -1 1 0
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(2,3)') sage: l,r,s = o.sl2z_edges() sage: len(l) 3 sage: len(r) 3 sage: len(s) 3
-
stratum
()¶ Stratum of this origami.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.stratum() H_2(2)
-
stratum_component
()¶ Return the component of stratum this origami belongs to.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.stratum_component() H_2(2)^hyp sage: r = '(1)(2)(3,4)(5,6,7,8)(9,10)' sage: u = '(1,2,3,5,6,10)(4,9)(7,8)' sage: Origami(r,u).stratum_component() H_4(2^3)^even sage: Origami(u,r).stratum_component() H_4(2^3)^even sage: r = '(1,2,3,4,5)(6,7,8,9,10)' sage: u = '(1,6)(2,10)(3,9)(4,8)(5,7)' sage: o = Origami(r,u) sage: o.stratum_component() H_5(4^2)^odd
-
sum_of_lyapunov_exponents
()¶ Returns the sum of Lyapunov exponents for this origami
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.sum_of_lyapunov_exponents() 4/3 sage: o = Origami('(1,2)(3,4)','(2,3)') sage: o.sum_of_lyapunov_exponents() 3/2
TESTS:
An error is raised if the origami is not connected:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(3,4)') Warning: the origami is not connected sage: o.sum_of_lyapunov_exponents() Traceback (most recent call last): ... ValueError: the origami is not connected! The Veech group computation is disabled in that case.
-
teichmueller_curve
¶
-
to_standard_form
()¶ Return an isomorphic origami in standard form.
INPUT:
return_map
- boolean (default: False) - if True return the associated mapping
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: oo,m = o.to_standard_form(return_map=True) sage: ~m * o.r() * m == oo.r() True sage: ~m * o.u() * m == oo.u() True sage: o = Origami('(1,2,3)(4,5)(6)(7,8,9)','(1,6,3,8,2,7,4,9)') sage: oo,m = o.to_standard_form(return_map=True) sage: ~m * o.r() * m == oo.r() True sage: ~m * o.u() * m == oo.u() True
-
translation_group
()¶ Returns the automorphism group of the origami as a permutation group
The automorpism group of a translation surface is the set of affine diffeomorphisms which have a trivial linear part. For an origami, it corresponds combinatorially to the centralizer of the group generated by the permutations
r
andu
that define this origami.EXAMPLES:
sage: from surface_dynamics.all import *
The L with 3 squares has no automorphisms:
sage: o = Origami('(1,2)','(1,3)') sage: G = o.automorphism_group() sage: G.order() 1
The 4-squares square tiled surface in H(1,1) has non trivial automorphism for which the quotient is a torus with two squares:
sage: o = Origami('(1,2)(3,4)','(2,3)') sage: G = o.automorphism_group() sage: G.order() 2 sage: oo = o.quotient(G) sage: oo (1,2) (1)(2)
-
u
()¶ Return the up permutation of the origami
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,2,3,4)') sage: o.u() (1,2,3,4)
-
u_inv
()¶ Return the inverse of the up permutation of the origami
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,2,3,4)') sage: o.u_inv() (1,4,3,2)
-
u_inv_tuple
()¶ Return the inverse of the up permutation as a tuple on {0,...,n-1}
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,2,3)') sage: o.u_inv_tuple() (2, 0, 1)
-
u_tuple
()¶ Return the up permutation of the origami as a tuple on {0,...,n-1}
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.u_tuple() (2, 1, 0)
-
veech_group
()¶ Returns the Veech group of this origami.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: G = o.veech_group() sage: G Arithmetic subgroup with permutations of right cosets S2=(2,3) S3=(1,2,3) L=(1,2) R=(1,3)
Most geometric information on the quotient of the upper half plane by the Veech group can be recovered from
G
:sage: G.index() 3 sage: G.genus() 0 sage: G.ncusps() 2 sage: G.nu2() 1 sage: G.nu3() 0
As well as some arithmetic informations:
sage: G.is_congruence() True sage: G.generalised_level() 2
Note that the fact of being congruent is rather exceptional:
sage: o = Origami('(1,2,3,4)','(4,5)') sage: o.veech_group().is_congruence() False sage: o = Origami('(1,2,3,4,5)','(5,6)') sage: o.veech_group().is_congruence() False sage: o = Origami('(1,2,3,4,5,6)','(6,7)') sage: o.veech_group().is_congruence() False
TESTS:
An error is raised if the origami is not connected:
sage: o = Origami('(1,2)','(3,4)') Warning: the origami is not connected sage: o.veech_group() Traceback (most recent call last): ... ValueError: the origami is not connected! The Veech group computation is disabled in that case.
-
vertex_degrees
()¶ Return the list of degree of the vertices
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3,4,5)', '(1,5,3,2,4)') sage: o.vertex_degrees() [4] sage: o = origamis.ProjectiveLine(5) sage: o.vertex_degrees() [2, 2]
-
vertical_symmetry
()¶ Return the origami (r^{-1}, u).
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3)(5,6)', '(1,4)(3,5,7)') sage: ov = o.vertical_symmetry(); ov (1,3,2)(4)(5,6)(7) (1,4)(2)(3,5,7)(6)
We check that it commutes with vertical symmetry of the cylinder diagram:
sage: cv1 = o.cylinder_diagram().vertical_symmetry() sage: cv2 = ov.cylinder_diagram() sage: cv1.is_isomorphic(cv2) True
-
vertical_twist
()¶ Return the origami (ru^{-k},u) which is obtained by the action of a vertical twist of width k on this origami
INPUT:
width
- integer (default: 1) - the width of the twist
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2,3,4)','(4,5,6,7)') sage: o.vertical_twist() (1,2,3,4,7,6,5) (1)(2)(3)(4,5,6,7) sage: o.vertical_twist(-1) (1,2,3,4,5,6,7) (1)(2)(3)(4,5,6,7) sage: o.vertical_twist(4) == o True
-
vertices
()¶ INPUT:
register_automorphism_action
- (default isFalse
) whether the action of the automorphism group of the origami is registered on the vertices
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = origamis.Escalator(4) sage: o.vertices() [vertex (1, 5), vertex (2, 6), vertex (3, 7), vertex (4, 8)]
-
widths_and_heights
()¶ Return the list of widths and heigths of cylinder.
EXAMPLES:
sage: from surface_dynamics.all import * sage: Origami('(1,2)','(1,3)').widths_and_heights() [(1, 1), (2, 1)] sage: Origami('(1,2)(3,4)','(1,3,5)(2,4)').widths_and_heights() [(1, 1), (2, 2)] sage: Origami('(1,2)','(1,3,4)').widths_and_heights() [(1, 2), (2, 1)] sage: Origami('(1,2)(3,4)','(1,3,5,6)(2,4)').widths_and_heights() [(1, 2), (2, 2)]
-
-
class
surface_dynamics.flat_surfaces.origamis.origami_dense.
PillowcaseCover_dense_pyx
¶ Bases:
object
-
degree
()¶ The degree of the covering.
EXAMPLES:
sage: from surface_dynamics.all import * sage: p = PillowcaseCover([2,1,3,4],[3,2,1,4],[4,2,3,1]) sage: p.degree() 4
-
g_tuple
()¶ Return a tuple.
EXAMPLES:
sage: from surface_dynamics.all import * sage: p = PillowcaseCover([2,1,3,4],[3,2,1,4],[4,2,3,1]) sage: p.g_tuple(0) (1, 0, 2, 3) sage: p.g_tuple(1) (2, 1, 0, 3) sage: p.g_tuple(2) (3, 1, 2, 0) sage: p.g_tuple(3) (3, 0, 1, 2) sage: p.g_tuple(4) Traceback (most recent call last): ... IndexError: the index i (=4) must be in {0,1,2,3}
-
-
surface_dynamics.flat_surfaces.origamis.origami_dense.
lattice
()¶ Returns a triple
(a,t,u)
where ((a,0),(t,u)) is a basis for the integer lattice generated byvectors
.EXAMPLES:
sage: from surface_dynamics.flat_surfaces.origamis.origami_dense import lattice sage: lattice([(2,0), (3,1)]) (2, 1, 1) sage: lattice([(2,0), (3,1), (2,1)]) (1, 0, 1) sage: lattice([(1,2), (3,6), (5,10)]) Traceback (most recent call last): ... ValueError: all input vectors are collinear
TESTS:
sage: from surface_dynamics.flat_surfaces.origamis.origami_dense import lattice sage: m0 = matrix(ZZ,2,2,[50,51,49,50]) sage: m1 = matrix(ZZ,2,2,[-92,29,-73,23]) sage: m2 = matrix(ZZ,2,2,[-61,84,53,-73]) sage: m3 = matrix(ZZ,2,2,[-54,-71,-73,-96]) sage: m4 = matrix(ZZ,2,2,[91,-18,86,-17]) sage: m5 = matrix(ZZ,2,2,[-30,-53,47,83]) sage: m6 = matrix(ZZ,2,2,[11,-29,-25,66]) sage: m7 = matrix(ZZ,2,2,[31,9,-69,-20]) sage: matrices = [m0,m1,m2,m3,m4,m5,m6,m7] sage: b0 = matrix(ZZ,2,2,[1,0,0,2]) sage: b1 = matrix(ZZ,2,2,[2,0,0,1]) sage: b2 = matrix(ZZ,2,2,[2,0,1,1]) sage: b3 = matrix(ZZ,2,2,[2,0,1,3]) sage: for m in matrices: ....: assert lattice((m * b0).rows()) == (1,0,2) ....: assert lattice((m * b1).rows()) == (2,0,1) ....: assert lattice((m * b2).rows()) == (2,1,1) ....: assert lattice((m * b3).rows()) == (2,1,3) sage: lattice(sum(((m * b0).rows() for m in matrices), [])) (1, 0, 2) sage: lattice(sum(((m * b1).rows() for m in matrices), [])) (2, 0, 1) sage: lattice(sum(((m * b2).rows() for m in matrices), [])) (2, 1, 1) sage: lattice(sum(((m * b3).rows() for m in matrices), [])) (2, 1, 3)
-
surface_dynamics.flat_surfaces.origamis.origami_dense.
origami_from_gap_permutations
()¶ TESTS:
sage: from surface_dynamics.flat_surfaces.origamis.origami_dense import origami_from_gap_permutations sage: r = gap("(1,2)(3,4)") sage: u = gap("(2,3)") sage: origami_from_gap_permutations(r, u) (1,2)(3,4) (1)(2,3)(4)
-
surface_dynamics.flat_surfaces.origamis.origami_dense.
origami_unpickle
()¶
-
surface_dynamics.flat_surfaces.origamis.origami_dense.
sl2z_orbits
()¶ Action of the matrices l,r,s
EXAMPLES:
sage: from surface_dynamics.all import * sage: from surface_dynamics.flat_surfaces.origamis.origami_dense import sl2z_orbits sage: C = AbelianStratum(2,2).odd_component() sage: origamis = C.origamis(10) sage: len(origamis) 8955 sage: slorbits = sl2z_orbits(origamis, 10, 0) sage: len(slorbits) 19
-
surface_dynamics.flat_surfaces.origamis.origami_dense.
sl_orbit_from_gl_orbit
()¶ Compute the sl2z orbit of the origami
o
knowing the action of gl2z.TODO: this has nothing to do with origamis... but rather to the action of SL(2,Z)/GL(2,Z)/PSL(2,Z).
INPUT:
o
- an origamiL
- the action of the matrix lI
- the action of the matrix i
EXAMPLES:
sage: from surface_dynamics.all import *
On the following example, the SL(2,Z) action has two orbits whereas the GL(2,Z) action as only one:
sage: l_edges = {0:1,1:9,2:8,3:0,4:13,5:10,6:5,7:4,8:11,9:3,10:6,11:2,12:7,13:12} sage: i_edges = {0:10,1:5,2:12,3:4,4:3,5:1,6:11,7:9,8:13,9:7,10:0,11:6,12:2,13:8} sage: from surface_dynamics.flat_surfaces.origamis.origami_dense import sl_orbit_from_gl_orbit sage: s0 = sl_orbit_from_gl_orbit(0, l_edges, i_edges); s0 ({0: 1, 1: 9, 2: 8, 3: 0, 8: 11, 9: 3, 11: 2}, {0: 11, 1: 0, 2: 9, 3: 8, 8: 2, 9: 3, 11: 1}, {0: 2, 1: 8, 2: 0, 3: 9, 8: 1, 9: 3, 11: 11}) sage: s0 == sl_orbit_from_gl_orbit(1, l_edges, i_edges) True sage: s4 = sl_orbit_from_gl_orbit(4, l_edges, i_edges) sage: s0 == s4 False
Teichmueller curves of Origamis.
-
class
surface_dynamics.flat_surfaces.origamis.teichmueller_curve.
Cusp
(parent, origami, slope)[source]¶ Bases:
sage.structure.sage_object.SageObject
A cusp in a Teichmueller curve.
- width of the cusp
- cylinder decomposition
- lengths
- heights
- a representative
-
class
surface_dynamics.flat_surfaces.origamis.teichmueller_curve.
TeichmuellerCurve
[source]¶ Bases:
sage.structure.sage_object.SageObject
-
surface_dynamics.flat_surfaces.origamis.teichmueller_curve.
TeichmuellerCurveOfOrigami
(origami)[source]¶ Return the teichmueller curve for an origami
TESTS:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: o.teichmueller_curve() #indirect test Teichmueller curve of the origami (1)(2,3) (1,2)(3)
-
class
surface_dynamics.flat_surfaces.origamis.teichmueller_curve.
TeichmuellerCurveOfOrigami_class
(mapping, inv_mapping, l_edges, r_edges, s2_edges, s3_edges)[source]¶ Bases:
surface_dynamics.flat_surfaces.origamis.teichmueller_curve.TeichmuellerCurve
-
an_element
()¶ Returns an origmami in this teichmueller curve.
Beware that the labels of the initial origami may have changed.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: t = o.teichmueller_curve() sage: t.origami() (1)(2,3) (1,2)(3)
-
cusp_representative_iterator
()[source]¶ Iterator over the cusp of self.
Each term is a couple
(o,w)
whereo
is a representative of the cusp (an origami) andw
is the width of the cusp (an integer).
-
orbit_graph
(s2_edges=True, s3_edges=True, l_edges=False, r_edges=False, vertex_labels=True)[source]¶ Return the graph of action of PSL on this origami
INPUT:
return_map
- return the list of origamis in the orbit
-
origami
()[source]¶ Returns an origmami in this teichmueller curve.
Beware that the labels of the initial origami may have changed.
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: t = o.teichmueller_curve() sage: t.origami() (1)(2,3) (1,2)(3)
-
plot_graph
()[source]¶ Plot the graph of the veech group.
The graph corresponds to the action of the generators on the cosets determined by the Veech group in PSL(2,ZZ).
-
stratum
()[source]¶ Returns the stratum of the Teichmueller curve
EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: t = o.teichmueller_curve() sage: t.stratum() H_2(2)
-
sum_of_lyapunov_exponents
()[source]¶ Returns the sum of Lyapunov exponents for this origami
EXAMPLES:
sage: from surface_dynamics.all import *
Let us consider few examples in H(2) for which the sum is independant of the origami:
sage: o = Origami('(1,2)','(1,3)') sage: o.stratum() H_2(2) sage: o.sum_of_lyapunov_exponents() 4/3 sage: o = Origami('(1,2,3)(4,5,6)','(1,5,7)(2,6)(3,4)') sage: o.stratum() H_2(2) sage: o.sum_of_lyapunov_exponents() 4/3
This is true as well for the stratum H(1,1):
sage: o = Origami('(1,2)','(1,3)(2,4)') sage: o.stratum() H_2(1^2) sage: o.sum_of_lyapunov_exponents() 3/2 sage: o = Origami('(1,2,3,4,5,6,7)','(2,6)(3,7)') sage: o.stratum() H_2(1^2) sage: o.sum_of_lyapunov_exponents() 3/2
ALGORITHM:
Kontsevich-Zorich formula
-
-
surface_dynamics.flat_surfaces.origamis.teichmueller_curve.
TeichmuellerCurvesOfOrigamis
(origamis, assume_normal_form=False, limit=0, verbose_level=0)[source]¶ Return a set of Teichmueller curve from a set of origamis
INPUT:
origamis
- iterable of origamisassume_normal_form
- whether or not assume that each origami is in normal formlimit
- integer (default: 0) - if positive, then stop the computation if the size of an orbit is bigger thanlimit
.
Database¶
Database of reduced origamis.
Origamis are cover of the torus over one point. The group SL(2,ZZ) act on them
(as their mapping class group). This file contains the implementation of a
database of these SL(2,Z)-orbits. To do concrete computations with origamis see
origami
.
The database of origamis contain informations about SL(2,ZZ) orbits of the origamis that are arithmetic Teichmueller curves.
EXAMPLES:
sage: from surface_dynamics.all import *
The most useful way to explore the database through queries. We develop several
examples below and refer to the documentation in the method
OrigamiDatabase.query()
for the complete specifications.
Let us start by finding the two exceptional surfaces whose Teichmueller curves have a complete degenerate Lyapunov spectrum: the Eierlegende Wollmilchsau and the Ornythorinque:
sage: D = OrigamiDatabase()
sage: q = D.query(sum_of_L_exp=1)
sage: q.number_of()
2
sage: o0, o1 = q.list()
sage: o0
(1,2,3,4)(5,6,7,8)
(1,5,3,7)(2,8,4,6)
sage: o1
(1,2,3,4,5,6)(7,8,9,10,11,12)
(1,7,5,9,3,11)(2,8,4,12,6,10)
sage: o0.is_isomorphic(origamis.CyclicCover([1,1,1,1]))
True
sage: o1.is_isomorphic(origamis.CyclicCover([1,1,1,3]))
True
We show two methods to get information on a given query:
number_of()
and list()
. To simply
display the result on the screen in a table, one can use
show()
of OrigamiQuery
:
sage: q.show()
Origami
--------------------
r=1234 5678 u=1537 2846
r=123456 789abc u=17593b 284c6a
We can display much more informations by modifying the displayed columns:
sage: q.cols('nb_squares', 'stratum', 'component', 'regular', 'quasi_regular')
sage: q.show()
Nb squares Stratum Comp. Regular Quasi regular
----------------------------------------------------------------------------------------------------
8 H_3(1^4) c True True
12 H_4(2^3) even False True
And the complete list of columns in the database is obtained through:
sage: D.cols()
['representative',
'stratum',
'component',
'primitive',
'quasi_primitive',
'orientation_cover',
'hyperelliptic',
'regular',
'quasi_regular',
...
'relative_monodromy_nilpotent',
'relative_monodromy_gap_primitive_id',
'orientation_stratum',
'orientation_genus',
'pole_partition',
'automorphism_group_order',
'automorphism_group_name']
Now, we do some simple counting of the number of primitive arithmetic Teichmueller curves. Let us first check the classification of arithmetic Teichmueller curves in H(2) from Hubert-Lelievre and McMullen:
sage: A = AbelianStratum(2)
sage: for n in xrange(3, 17):
....: q = D.query(stratum=A, nb_squares=n)
....: print("%2d %d"%(n, q.number_of()))
3 1
4 1
5 2
6 1
7 2
8 1
9 2
10 1
11 2
12 1
13 2
14 1
15 2
16 1
And look at the conjecture of Delecroix-Lelievre in the stratum H(1,1):
sage: A = AbelianStratum(1,1)
sage: for n in xrange(4,20):
....: q = D.query(stratum=A, nb_squares=n, primitive=True)
....: print("%2d %d"%(n, q.number_of()))
4 1
5 1
6 2
7 2
8 2
9 2
10 2
11 2
12 2
13 2
14 2
15 2
16 2
17 2
18 2
19 2
You can get an overview of the content of the database:
sage: D.info()
genus 2
=======
H_2(2)^hyp : 79 T. curves (up to 55 squares)
H_2(1^2)^hyp : 259 T. curves (up to 52 squares)
genus 3
=======
H_3(4)^hyp : 163 T. curves (up to 51 squares)
...
genus 6
=======
H_6(10)^hyp : 46 T. curves (up to 15 squares)
H_6(10)^odd : 4 T. curves (up to 11 squares)
H_6(10)^even : 33 T. curves (up to 12 squares)
Total: 4369 Teichmueller curves
Here is a last example of the list of regular origamis (i.e. such that their group of translation acts transitively on the set of squares):
sage: q = D.query(regular=True)
sage: q.cols('nb_squares', 'stratum', 'automorphism_group_name')
sage: q.show()
Nb squares Stratum Automorphism
------------------------------------------------------------
6 H_3(2^2) S3
8 H_3(1^4) D8
8 H_3(1^4) Q8
10 H_5(4^2) D10
12 H_4(1^6) A4
AUTHOR:
- Vincent Delecroix (2011-2014): initial version
-
class
surface_dynamics.flat_surfaces.origamis.origami_database.
EnhancedSQLQuery
(query_string, database=None)[source]¶ Bases:
surface_dynamics.misc.sql_db.SQLQuery
-
surface_dynamics.flat_surfaces.origamis.origami_database.
L_exp_approx_to_data
(t)¶ Convert a tuple of real numbers with same precision into a string.
The output string is a list of numbers written in base 36 (0, 1, ..., 9, a, b, ..., z) separated by space ‘ ‘. The first number is the precision of the real field. Then each real number consists of three numbers as sign, mantissa, exponent.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: odb.real_tuple_to_data((1.23,-4.0)) '1h 1 1ijk9vqiyzy -1g -1 18ce53un18g -1e'
We may check that the first part consists of the precision:
sage: Integer('1h', 36) 53 sage: RR.precision() 53
And then of the two real numbers we input:
sage: sign = Integer('1', 36) sage: mantissa = Integer('1ijk9vqiyzy', 36) sage: exponent = Integer('-1g', 36) sage: RR(sign * mantissa * 2 ** exponent) 1.23000000000000 sage: sign = Integer('-1', 36) sage: mantissa = Integer('18ce53un18g', 36) sage: exponent = Integer('-1e', 36) sage: RR(sign * mantissa * 2 ** exponent) -4.00000000000000
TESTS:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: t = (RR(5.0), RR(pi)) sage: print(t) (5.00000000000000, 3.14159265358979) sage: s = odb.real_tuple_to_data(t) sage: isinstance(s,str) True sage: t == odb.data_to_real_tuple(s) True
-
class
surface_dynamics.flat_surfaces.origamis.origami_database.
OrigamiDatabase
(dblocation=None, read_only=True, force_creation=False, old_version=False)[source]¶ Bases:
surface_dynamics.misc.sql_db.SQLDatabase
Database of arithmetic Teichmueller curves.
EXAMPLES:
sage: from surface_dynamics.all import *
To query the database the main method is meth:query:
sage: D = OrigamiDatabase() sage: q = D.query(genus=3, nb_squares=12) sage: q.number_of() 146 sage: l = q.list() sage: o = l[0] sage: o.genus() 3 sage: o.nb_squares() 12
For the precise usage of the method query, see the documentation of that function. Here is an example to show how to found the Eierlegende Wollmilchsau in the database from its property of complete degenerate spectrum:
sage: q = D.query(sum_of_L_exp=1, stratum=AbelianStratum(1,1,1,1)) sage: len(q) 1 sage: o = q.list()[0] sage: o.is_isomorphic(origamis.EierlegendeWollmilchsau()) True
We check the classification of arithmetic Teichmueller curves in H(2) from Hubert-Lelievre and McMullen:
sage: A = AbelianStratum(2) sage: for n in xrange(3, 15): ....: q = D.query(stratum=A, nb_squares=n) ....: print("%2d %d"%(n, q.number_of())) 3 1 4 1 5 2 6 1 7 2 8 1 9 2 10 1 11 2 12 1 13 2 14 1
To know all entries of the database look at meth:cols, meth:info or meth:help. The latter also provides a summary description of the columns.
-
build
(comp, N, force_computation=False, verbose=False)[source]¶ Update the database for the given component
comp
up toN
squares.Note that in order to work the database should not be in read only mode.
INPUT:
comp
- stratum or component of stratumN
- integerforce_computation
- force computation of data which may be yet in the database.verbose
- boolean - if True, print useful interactive informations during the process.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import os sage: db_name = os.path.join(SAGE_TMP, 'my_db.db') sage: D = OrigamiDatabase(db_name, read_only=False) sage: D.build(AbelianStratum(4).odd_component(), 8) # optional - database_gap sage: D.info() # optional - database_gap genus 2 ======= genus 3 ======= H_3(4)^odd : 8 T. curves (up to 7 squares) Total: 8 Teichmueller curves
-
cols
()[source]¶ Returns the skeleton of self (which is the list of possible entries).
EXAMPLES:
sage: from surface_dynamics.all import * sage: O = OrigamiDatabase() sage: cols = O.cols() sage: "representative" in cols True sage: len(cols) 45
-
help
(cols=None)[source]¶ Print some help relative to the columns of the database.
If
cols
is provided then gives help only for these columns.
-
info
(genus=None, dimension=None, print_all=False)[source]¶ Print the list of connected components and the number of squares up to which the database is filled.
INPUT:
genus
- integer (default: None) - if not None, print only info for that genus.dimension
- Integer (default: None) - if not None, print only info for that dimension.print_all
- boolean (default: False) - print also the components for which nothing has been computed yet.
EXAMPLES:
sage: from surface_dynamics.all import * sage: O = OrigamiDatabase() sage: O.info() genus 2 ======= ...
-
max_nb_squares
(comp=None)[source]¶ Returns the maximum number of squares for which Teichmueller curves have been computed.
If
comp
is None (default), then returns the biggest integer for which the database contains all data up to that integer. Ifcomp
is a stratum or a component of stratum, then returns the maximum number of squares computed for that stratum.EXAMPLES:
sage: from surface_dynamics.all import * sage: O = OrigamiDatabase() sage: O.max_nb_squares(AbelianStratum(2)) 55 sage: O.max_nb_squares() 11
-
query
(*query_list, **kwds)[source]¶ From a list of restriction, returns a list of possible entry in the database. By default, returns only the found origamis.
Where to find the possible entries self.cols() then a sign among ‘=’ (equality), ‘<>’ (difference), ‘<’, ‘>’, ‘<=’, ‘>=’ (comparisons).
EXAMPLES:
sage: from surface_dynamics.all import * sage: D = OrigamiDatabase() sage: for o in D.query(stratum=AbelianStratum(1,1), nb_squares=6): ....: print(o) ....: print("---------------") (1)(2)(3,4,5,6) (1,2,3)(4,5,6) --------------- (1)(2)(3)(4,5,6) (1,2,3,4)(5,6) --------------- (1)(2)(3,4)(5)(6) (1,2,3)(4,5,6) --------------- (1)(2)(3)(4,5)(6) (1,2,3,4)(5,6) --------------- (1)(2,3)(4,5)(6) (1,2,4)(3,5,6) ---------------
-
rebuild
(q=None, local_data=False, lyapunov_exponents=False, global_data=False, nb_iterations=4096, nb_experiments=5, verbose=False)[source]¶ Rebuild some of the data for the origami in the query
q
.INPUT:
q
- a querylocal_data
- boolean - whether or not we rebuild local data.lyapunov_exponents
- boolean - whether or not rebuild lyapunov exponents approximation (time consuming).global_data
- boolean - whether or not rebuild global data (time and memory consuming).nb_experiments
,nb_iterations
- integers - option for the computation of Lyapunov exponents.verbose
- boolean - if True displays nice informations in real time.
-
update
(other, replace=False, verbose=False)[source]¶ Update the content of this database with the content of another one.
INPUT:
other
- a query, an origami database or a path to an origami databasereplace
- boolean - whether or not replace entries which are yet in the database.verbose
- boolean - if True, displays information during the transfer.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import os sage: db1_name = os.path.join(SAGE_TMP, 'the_first_one.db') sage: db2_name = os.path.join(SAGE_TMP, 'the_second_one.db') sage: D1 = OrigamiDatabase(db1_name, read_only=False) sage: D2 = OrigamiDatabase(db2_name, read_only=False) sage: D1.build(AbelianStratum(1,1).unique_component(), 7) # optional - database_gap sage: D2.build(AbelianStratum(2).unique_component(), 5) # optional - database_gap sage: D2.update(D1) # optional - database_gap sage: D2.info() # optional - database_gap genus 2 ======= H_2(2)^hyp : 2 T. curves (up to 4 squares) H_2(1^2)^hyp: 8 T. curves (up to 6 squares) Total: 10 Teichmueller curves
-
-
class
surface_dynamics.flat_surfaces.origamis.origami_database.
OrigamiQuery
(db, query_string, cols, **kwds)[source]¶ Origami database query.
A query for an instance of OrigamiDatabase. This class nicely wraps the SQLQuery class located in surface_dynamics.databases.database.py to make the query constraints intuitive and with as many pre-definitions as possible. (i.e.: since it has to be a OrigamiDatabase, we already know the table structure and types; and since it is immutable, we can treat these as a guarantee).
-
cols
(*cols)[source]¶ Get or modify columns.
In a sql query, it corresponds to the clause ‘SELECT’.
EXAMPLES:
sage: from surface_dynamics.all import * sage: O = OrigamiDatabase() sage: q = O.query() sage: q.cols() ['representative'] sage: q.cols("nb_squares") sage: q.cols() ['nb_squares'] sage: q.cols("veech_group_index","primitive") sage: q.cols() ['veech_group_index', 'primitive']
-
database
()[source]¶ Returns the database of that query.
EXAMPLES:
sage: from surface_dynamics.all import * sage: D = OrigamiDatabase() sage: q = D.query(stratum=AbelianStratum(6)) sage: q.database() Database of origamis sage: q.database() is D True
-
dict
()[source]¶ Returns a list of dictionnaries: col -> value.
EXAMPLES:
sage: from surface_dynamics.all import * sage: D = OrigamiDatabase() sage: q = D.query(stratum=AbelianStratum(1,1), nb_squares=8) sage: q.cols('teich_curve_genus') sage: q.dict() [{'teich_curve_genus': 1}, {'teich_curve_genus': 1}, {'teich_curve_genus': 0}, {'teich_curve_genus': 0}] sage: q.cols('pole_partition', 'primitive') sage: q.dict() [{'pole_partition': (0, 2, 2, 2), 'primitive': True}, {'pole_partition': (2, 0, 2, 2), 'primitive': True}, {'pole_partition': (0, 0, 2, 4), 'primitive': False}, {'pole_partition': (0, 0, 2, 4), 'primitive': False}]
-
get_query_string
()[source]¶ Output the query string in sql format.
This is the method where the attribute of this object are translated into a sql query.
EXAMPLES:
sage: from surface_dynamics.all import * sage: D = OrigamiDatabase() sage: q = D.query(('stratum','=',AbelianStratum(1,1)), ('nb_squares','<', 13)) sage: q.get_query_string() "SELECT representative FROM origamis WHERE stratum='1 1' AND nb_squares<13 ORDER BY nb_squares ASC" sage: q.order(("nb_squares",1),("pole_partition",-1)) sage: q.get_query_string() "SELECT representative FROM origamis WHERE stratum='1 1' AND nb_squares<13 ORDER BY nb_squares ASC,pole_partition DESC"
-
list
()[source]¶ Returns the list of entries of the query.
The output is either a list of objects if there is only one column for that query. Otherwise, it is a list of lists where each item is the entries of columns.
See also meth:dict to get a dictionnary output.
EXAMPLES:
sage: from surface_dynamics.all import * sage: S = OrigamiDatabase(read_only=False) sage: q = S.query(('stratum','=',AbelianStratum(1,1)),('nb_squares','=',6)) sage: q.list() [(1)(2)(3,4,5,6) (1,2,3)(4,5,6), (1)(2)(3)(4,5,6) (1,2,3,4)(5,6), (1)(2)(3,4)(5)(6) (1,2,3)(4,5,6), (1)(2)(3)(4,5)(6) (1,2,3,4)(5,6), (1)(2,3)(4,5)(6) (1,2,4)(3,5,6)]
-
order
(*args)[source]¶ Get or modify order.
Order should be a list (col_name, +1) or (col_name, -1). First one means ascending and the second one decending. In a sql query, it corresponds to the clause ‘ORDER BY’.
EXAMPLES:
sage: from surface_dynamics.all import * sage: O = OrigamiDatabase() sage: q = O.query() sage: q.order(("nb_squares",1),("pole_partition",1)) sage: q.get_query_string() 'SELECT representative FROM origamis ORDER BY nb_squares ASC,pole_partition ASC' sage: q.order(("nb_squares",-1)) sage: q.get_query_string() 'SELECT representative FROM origamis ORDER BY nb_squares DESC'
-
show
(**opts)[source]¶ Output a text array with the results of that query.
EXAMPLES:
sage: from surface_dynamics.all import *
There is a problem with show method the SQLQuery:
sage: O = OrigamiDatabase() sage: q = O.query(("nb_squares","=",6)) sage: q.cols(("stratum","sum_of_L_exp","L_exp_approx")) sage: q.show() Stratum Sum of L exp L exp approx ------------------------------------------------------------ ...
-
-
surface_dynamics.flat_surfaces.origamis.origami_database.
are_skeleton_equal
(sk1, sk2)[source]¶ Test whether the two skeleton
sk1
andsk2
are equals.EXAMPLES:
sage: from surface_dynamics.flat_surfaces.origamis.origami_database import are_skeleton_equal sage: sk1 = {'table1': {'col1': {'sql': 'TEXT', 'unique': True}, 'col2': {'sql': 'INTEGER'}}} sage: sk2 = {'table1': {'col1': {'sql': 'TEXT', 'unique': True}, 'col2': {'sql': 'INTEGER', 'unique': False}}} sage: are_skeleton_equal(sk1,sk2) True
-
surface_dynamics.flat_surfaces.origamis.origami_database.
build_global_data
(o, c=None)[source]¶ Compute the global data that are obtained from the Teichmueller curve of the origami
o
. If the Teichmueller curvec
is not provided, then it is recomputed from scratch (and may be long).EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)', '(1,3)') sage: from surface_dynamics.flat_surfaces.origamis.origami_database import build_global_data sage: data = build_global_data(o) sage: data {'max_hom_dim': 2, 'max_nb_of_cyls': 2, 'min_hom_dim': 1, 'min_nb_of_cyls': 1, 'minus_identity_invariant': True, 'sum_of_L_exp': 4/3, 'teich_curve_genus': 0, 'teich_curve_ncusps': 2, 'teich_curve_nu2': 1, 'teich_curve_nu3': 0, 'veech_group_congruence': True, 'veech_group_index': 3, 'veech_group_level': 2}
-
surface_dynamics.flat_surfaces.origamis.origami_database.
build_local_data
(o)[source]¶ Build local data for the origami
o
.The ouptut is a dictionnary that is intended to be used to feed the database of origamis. The local data are geometrical aspects (stratum, genus, ...) the monodromy group (primitivity, orientation cover, ...) and the automorphisms of
o
.See also
build_lyapunov_exponents()
to construct Lyapunov exponents andbuild_global_data()
.EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)','(1,3)') sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: data = odb.build_local_data(o) # optional - database_gap sage: data['stratum'] # optional - database_gap H_2(2) sage: data['nb_squares'] # optional - database_gap 3
-
surface_dynamics.flat_surfaces.origamis.origami_database.
build_lyapunov_exponents
(o, nb_iterations=65536, nb_experiments=10)[source]¶ Compute the lyapunov exponents for the origami
o
and update the database.EXAMPLES:
sage: from surface_dynamics.all import * sage: o = Origami('(1,2)', '(1,3)') sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: data = odb.build_lyapunov_exponents(o) sage: data # abs tol 1e-2 {'L_exp_approx': [0.333348091]}
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_L_exp_approx
(s)¶ Convert a string into a tuple of real numbers.
For the encoding convention, see meth:real_tuple_to_data.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: R = RealField(22) sage: t = (R(1), R(pi)) sage: s = odb.real_tuple_to_data(t) sage: tt = odb.data_to_real_tuple(s) sage: tt == t True sage: tt[0].parent() Real Field with 22 bits of precision sage: tt[1].parent() Real Field with 22 bits of precision
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_integer_tuple
(s)[source]¶ Convert a string into a tuple of integers.
For the encoding convention, see meth:integer_tuple_to_data.
EXAMPLES:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: t = (-12, 351234123, 45) sage: s = odb.integer_tuple_to_data(t) sage: odb.data_to_integer_tuple(s) == t True
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_nb_cyls_spectrum
(s)¶ Convert a string into a tuple of integers.
For the encoding convention, see meth:integer_tuple_to_data.
EXAMPLES:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: t = (-12, 351234123, 45) sage: s = odb.integer_tuple_to_data(t) sage: odb.data_to_integer_tuple(s) == t True
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_pole_partition
(s)[source]¶ TESTS:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: odb.data_to_pole_partition('0aFe') (0, 10, 15, 14) sage: odb.data_to_pole_partition('') is None True
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_rational
(s)[source]¶ Convert a string into a rational.
EXAMPLES:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: odb.data_to_rational('41/1806') 41/1806
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_real_tuple
(s)[source]¶ Convert a string into a tuple of real numbers.
For the encoding convention, see meth:real_tuple_to_data.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: R = RealField(22) sage: t = (R(1), R(pi)) sage: s = odb.real_tuple_to_data(t) sage: tt = odb.data_to_real_tuple(s) sage: tt == t True sage: tt[0].parent() Real Field with 22 bits of precision sage: tt[1].parent() Real Field with 22 bits of precision
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_representative
(s)[source]¶ Convert data to representative.
For encoding convention, see meth:representative_to_data.
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_small_positive_integer_tuple
(s)[source]¶ Convert a string into a tuple of Integer.
For encoding convention, see meth:small_positive_integer_tuple_to_data.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: odb.data_to_small_positive_integer_tuple('14m') (1, 4, 22) sage: odb.data_to_small_positive_integer_tuple('') ()
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_stratum
(s)[source]¶ Convert a string into a stratum.
For encoding convention, see meth:stratum_to_data.
EXAMPLES:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: odb.data_to_stratum('f f 2') H_17(15^2, 2)
-
surface_dynamics.flat_surfaces.origamis.origami_database.
data_to_sum_of_L_exp
(s)¶ Convert a string into a rational.
EXAMPLES:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: odb.data_to_rational('41/1806') 41/1806
-
surface_dynamics.flat_surfaces.origamis.origami_database.
format_pole_partition
(p)[source]¶ Format into a nice readble string the pole partition.
EXAMPLES:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: s = odb.pole_partition_to_data((0,3,5,1)) sage: odb.format_pole_partition(s) '0 (3,5,1)'
-
surface_dynamics.flat_surfaces.origamis.origami_database.
format_representative
(s)[source]¶ Convert a string that encodes an origami into a human readable string.
The output form consists of the concatenation of the cycles without the paranthesis. In other words the permutation (1,5)(2)(3,7,4) will be convert into ‘15 374’.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: o = Origami('(1,2)','(1,3)') sage: s = odb.representative_to_data(o) sage: odb.format_representative(s) 'r=12 u=13'
-
surface_dynamics.flat_surfaces.origamis.origami_database.
integer_tuple_to_data
(t)[source]¶ Convert a tuple of arbitrary integers into a string.
The encoding consists in a string that are representation of the integers in base 36 separated by space.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: t = (0,-12435123,3) sage: s = odb.integer_tuple_to_data(t) sage: s '0 -7ej03 3' sage: map(lambda x: Integer(x,36), s.split(' ')) [0, -12435123, 3]
-
surface_dynamics.flat_surfaces.origamis.origami_database.
nb_cyls_spectrum_to_data
(t)¶ Convert a tuple of arbitrary integers into a string.
The encoding consists in a string that are representation of the integers in base 36 separated by space.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: t = (0,-12435123,3) sage: s = odb.integer_tuple_to_data(t) sage: s '0 -7ej03 3' sage: map(lambda x: Integer(x,36), s.split(' ')) [0, -12435123, 3]
-
surface_dynamics.flat_surfaces.origamis.origami_database.
orientation_stratum_to_data
(q)[source]¶ TESTS:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: q = QuadraticStratum(2,2,0,-1,-1,-1,-1) sage: s = odb.orientation_stratum_to_data(q) sage: isinstance(s,str) True sage: q == odb.data_to_orientation_stratum(s) True
-
surface_dynamics.flat_surfaces.origamis.origami_database.
pole_partition_to_data
(t)¶ Convert a tuple of integers between 0 and 35 to a string.
The encoding consists of a string of the same length as
t
where each character is the representation of the number in base 36 (0, 1, ..., 9, a, b, ..., z).EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: t = (0, 35, 25, 2, 12) sage: s = odb.small_positive_integer_tuple_to_data(t) sage: s '0zp2c' sage: map(lambda x: Integer(x, 36), s) [0, 35, 25, 2, 12]
-
surface_dynamics.flat_surfaces.origamis.origami_database.
real_tuple_to_data
(t)[source]¶ Convert a tuple of real numbers with same precision into a string.
The output string is a list of numbers written in base 36 (0, 1, ..., 9, a, b, ..., z) separated by space ‘ ‘. The first number is the precision of the real field. Then each real number consists of three numbers as sign, mantissa, exponent.
EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: odb.real_tuple_to_data((1.23,-4.0)) '1h 1 1ijk9vqiyzy -1g -1 18ce53un18g -1e'
We may check that the first part consists of the precision:
sage: Integer('1h', 36) 53 sage: RR.precision() 53
And then of the two real numbers we input:
sage: sign = Integer('1', 36) sage: mantissa = Integer('1ijk9vqiyzy', 36) sage: exponent = Integer('-1g', 36) sage: RR(sign * mantissa * 2 ** exponent) 1.23000000000000 sage: sign = Integer('-1', 36) sage: mantissa = Integer('18ce53un18g', 36) sage: exponent = Integer('-1e', 36) sage: RR(sign * mantissa * 2 ** exponent) -4.00000000000000
TESTS:
sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: t = (RR(5.0), RR(pi)) sage: print(t) (5.00000000000000, 3.14159265358979) sage: s = odb.real_tuple_to_data(t) sage: isinstance(s,str) True sage: t == odb.data_to_real_tuple(s) True
-
surface_dynamics.flat_surfaces.origamis.origami_database.
representative_to_data
(o)[source]¶ Convert an origami into a string.
The maximum number of squares is 207. The encoding consists of the concatenation of the two permutations that define the origami.
TESTS:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: o = Origami('(1,2,3)','(3,2,1)') sage: odb.representative_to_data(o) '120201' sage: o = Origami('(1,2,4,3)(5,7,6)(10,9)','(10,8,6,2,4,3,1)') sage: s = odb.representative_to_data(o) sage: isinstance(s,str) True sage: o == odb.data_to_representative(s) True
-
surface_dynamics.flat_surfaces.origamis.origami_database.
small_positive_integer_tuple_to_data
(t)[source]¶ Convert a tuple of integers between 0 and 35 to a string.
The encoding consists of a string of the same length as
t
where each character is the representation of the number in base 36 (0, 1, ..., 9, a, b, ..., z).EXAMPLES:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: t = (0, 35, 25, 2, 12) sage: s = odb.small_positive_integer_tuple_to_data(t) sage: s '0zp2c' sage: map(lambda x: Integer(x, 36), s) [0, 35, 25, 2, 12]
-
surface_dynamics.flat_surfaces.origamis.origami_database.
stratum_to_data
(h)[source]¶ Encode the stratum entry.
TESTS:
sage: from surface_dynamics.all import * sage: import surface_dynamics.flat_surfaces.origamis.origami_database as odb sage: h = AbelianStratum(2,0) sage: s = odb.stratum_to_data(h) sage: isinstance(s,str) True sage: h == odb.data_to_stratum(s) True