def __init__(self, base, degree, perms): r""" TESTS:: sage: from surface_dynamics.all import * sage: from surface_dynamics.interval_exchanges.cover import PermutationCover sage: p1 = iet.Permutation('a b c', 'c b a') sage: PermutationCover(p1, 2, [[0,1],[1,0],[1,0]]) Covering of degree 2 of the permutation: a b c c b a sage: PermutationCover(p1, 2, [[0,1],[0,1],[0,1]]) Traceback (most recent call last): ... ValueError: the cover is not connected sage: p1 = iet.Permutation('a b c d', 'b a d c') sage: PermutationCover(p1, 2, [[0,1],[1,0],[1,0]]) Traceback (most recent call last): ... ValueError: the base must be irreducible """ if not base.is_irreducible(): raise ValueError("the base must be irreducible") from surface_dynamics.misc.permutation import perms_are_transitive if not perms_are_transitive(perms): raise ValueError("the cover is not connected") from surface_dynamics.misc.permutation import perm_invert self._base = base.__copy__() self._degree_cover = degree self._permut_cover = perms[:] self._inv_permut_cover = [perm_invert(p) for p in perms]
def dual(self): r""" Returns the dual Ribbon graph. The *dual* ribbon graph of `(v,e,f)` is `(f^{-1}, e, v^{-1})`. EXAMPLES:: sage: from surface_dynamics import * sage: r = RibbonGraph(edges='(0,1)',faces='(0)(1)'); r Ribbon graph with 1 vertex, 1 edge and 2 faces sage: r.dual() Ribbon graph with 2 vertices, 1 edge and 1 face """ return RibbonGraph(vertices=perm_invert(self._faces), edges=self._edges, faces=perm_invert(self._vertices))
def dual(self): r""" Returns the dual Ribbon graph. The *dual* ribbon graph of `(v,e,f)` is `(f^{-1}, e, v^{-1})`. EXAMPLES:: sage: from surface_dynamics.all import * sage: r = RibbonGraph(edges='(0,1)',faces='(0)(1)'); r Ribbon graph with 1 vertex, 1 edge and 2 faces sage: r.dual() Ribbon graph with 2 vertices, 1 edge and 1 face """ return RibbonGraph( vertices=perm_invert(self._faces), edges=self._edges, faces=perm_invert(self._vertices))
def __reversed__(self): r""" TESTS:: sage: import itertools sage: from surface_dynamics import iet sage: p = iet.Permutation('a b c d e','d a e b c') sage: for tb, lr in itertools.product([False, True], repeat=2): ....: f = iet.FlipSequence(p, ['t','t','b','t','b'], tb, lr, "(0,1,3)") ....: l1 = [(copy(p), winner, side) for p, winner, side in f] ....: l2 = [(copy(p), winner, side) for p, winner, side in reversed(f)] ....: assert l2 == l1[::-1] """ p = copy(self._end) if self._top_bottom_inverse: p.top_bottom_inverse(inplace=True) if self._left_right_inverse: p.left_right_inverse(inplace=True) p.relabel(perm_invert(self._relabelling)) for winner, side in reversed(self._rauzy_moves): p.backward_rauzy_move(winner, side, inplace=True) yield (p, winner, side)
def orientation_cover(self): r""" Return the orientation cover as an origami. EXAMPLES: The pillowcase itself has cover a torus (made from 4 squares):: sage: from surface_dynamics import * sage: p0 = p1 = p2 = p3 = [0] sage: pc = PillowcaseCover(p0, p1, p2, p3, as_tuple=True) sage: pc.stratum() Q_0(-1^4) sage: o = pc.orientation_cover() sage: o (1,2)(3,4) (1,4)(2,3) sage: o.stratum() H_1(0) An example in Q(1,-1^5) whose cover belongs to H(2):: sage: p0 = [2,1,0] sage: p1 = [2,0,1] sage: p2 = [1,0,2] sage: p3 = [0,1,2] sage: pc = PillowcaseCover(p0, p1, p2, p3,as_tuple=True) sage: pc.stratum() Q_0(1, -1^5) sage: o = pc.orientation_cover() sage: o (1,2,3,4)(5,6)(7,10,9,8)(11,12) (1,10,5,12)(2,9)(3,8)(4,7,6,11) sage: o.stratum() H_2(2) A last example in Q(2^2):: sage: q = QuadraticCylinderDiagram('(0,1)-(2,3) (0,3)-(1,2)') sage: pc = q.cylcoord_to_pillowcase_cover([1,1,1,1], [2,2], [0,1]) sage: pc.orientation_cover().stratum() H_3(1^4) """ from surface_dynamics.misc.permutation import perm_invert from surface_dynamics.flat_surfaces.origamis.origami import Origami g0 = self.g_tuple(0) g1 = self.g_tuple(1) g2 = self.g_tuple(2) g3 = self.g_tuple(3) n = len(g0) r = [None] * (4 * n) u = [None] * (4 * n) h1 = perm_invert(g1) h2 = perm_invert(g2) for i in range(n): r[2 * i] = 2 * i + 1 r[2 * i + 1] = 2 * g3[g2[i]] r[2 * n + 2 * i + 1] = 2 * n + 2 * i r[2 * n + 2 * i] = 2 * n + 2 * g1[g0[i]] + 1 u[2 * i] = 2 * n + 2 * h2[i] + 1 u[2 * i + 1] = 2 * n + 2 * g2[i] u[2 * n + 2 * i] = 2 * g1[i] + 1 u[2 * n + 2 * i + 1] = 2 * h1[i] return Origami(r, u, as_tuple=True)
def clean_perm_data(vertices, edges, faces, check): r""" TESTS:: sage: from surface_dynamics.flat_surfaces.homology import clean_perm_data sage: clean_perm_data([2,1,0],[1,2,0],None, check=True) ([2, 1, 0], [1, 2, 0], [0, 2, 1]) sage: clean_perm_data([1,0,2],[2,1,0],None, check=True) ([1, None, 2], [2, None, 0], [2, None, 1]) """ if vertices is not None: vertices = init_perm(vertices) if check: perm_check(vertices) if edges is not None: edges = init_perm(edges) if check: perm_check(edges) if faces is not None: faces = init_perm(faces) if check: perm_check(faces) if edges is None: if vertices is None and faces is None: raise ValueError("at least vertices or faces should be not None") if not (vertices is None or faces is None): equalize_perms([vertices,faces]) edges = perm_compose(perm_invert(vertices),perm_invert(faces)) else: if vertices is None: n = len(faces) elif faces is None: n = len(vertices) if n%2: raise ValueError("there should be an even number of darts") edges = [] for i in xrange(n//2): edges.append(2*i+1) edges.append(2*i) if vertices is None: vertices = perm_compose(perm_invert(faces),perm_invert(edges)) elif faces is None: faces = perm_compose(perm_invert(edges),perm_invert(vertices)) elif vertices is None: if edges is None or faces is None: raise ValueError("at least two of the entries should be not None") equalize_perms([edges,faces]) vertices = perm_compose(perm_invert(faces),perm_invert(edges)) elif faces is None: if vertices is None or edges is None: raise ValueError("at least two of the entries should be not None") equalize_perms([vertices,edges]) faces = perm_compose(perm_invert(edges),perm_invert(vertices)) else: equalize_perms([vertices,edges,faces]) for i in range(len(edges)): if edges[i] == i: vertices[i] = edges[i] = faces[i] = None return (vertices, edges, faces)
def clean_perm_data(vertices, edges, faces, check): r""" TESTS:: sage: from surface_dynamics.flat_surfaces.homology import clean_perm_data sage: clean_perm_data([2,1,0],[1,2,0],None, check=True) ([2, 1, 0], [1, 2, 0], [0, 2, 1]) sage: clean_perm_data([1,0,2],[2,1,0],None, check=True) ([1, None, 2], [2, None, 0], [2, None, 1]) """ if vertices is not None: vertices = init_perm(vertices) if check: perm_check(vertices) if edges is not None: edges = init_perm(edges) if check: perm_check(edges) if faces is not None: faces = init_perm(faces) if check: perm_check(faces) if edges is None: if vertices is None and faces is None: raise ValueError("at least vertices or faces should be not None") if not (vertices is None or faces is None): equalize_perms([vertices, faces]) edges = perm_compose(perm_invert(vertices), perm_invert(faces)) else: if vertices is None: n = len(faces) elif faces is None: n = len(vertices) if n % 2: raise ValueError("there should be an even number of darts") edges = [] for i in xrange(n // 2): edges.append(2 * i + 1) edges.append(2 * i) if vertices is None: vertices = perm_compose(perm_invert(faces), perm_invert(edges)) elif faces is None: faces = perm_compose(perm_invert(edges), perm_invert(vertices)) elif vertices is None: if edges is None or faces is None: raise ValueError("at least two of the entries should be not None") equalize_perms([edges, faces]) vertices = perm_compose(perm_invert(faces), perm_invert(edges)) elif faces is None: if vertices is None or edges is None: raise ValueError("at least two of the entries should be not None") equalize_perms([vertices, edges]) faces = perm_compose(perm_invert(edges), perm_invert(vertices)) else: equalize_perms([vertices, edges, faces]) for i in range(len(edges)): if edges[i] == i: vertices[i] = edges[i] = faces[i] = None return (vertices, edges, faces)