Commit a114bfbb by Mark Bell

### Merge branch 'master' of gitlab.com:videlec/veerer

parents ffc997e9 e3dbe8e1
Pipeline #54081339 failed with stage
in 11 minutes and 44 seconds
 """ Look at nice patterns of vertex cycles on a train-track. We should probably be looking at nice patterns of *carried* curves! """ from veerer import * from surface_dynamics import * from sage.graphs.generic_graph_pyx import SubgraphSearch def longest_chain(T): '''Return the longest chain of vertex cycles on the veering triangulation T''' cycles = T.vertex_cycles() n = len(cycles) adj = [x.intersection(y) for y in cycles for x in cycles] I = matrix(ZZ, n, adj) J = matrix(ZZ, n, [bool(x) for x in adj]) G = Graph(J) m = 2 path = None while True: for V in SubgraphSearch(G, graphs.PathGraph(m), induced=True): P = G.subgraph(V) edges = P.edges(False) if all(I[i,j] == 1 for (i,j) in edges): print("found a path of length {}".format(m)) m += 1 path = edges[:] break else: print("no path of length {}".format(m)) return path
 r""" The pseudo-Anosov abC on the torus. The stratum is Q(1,1-,1,-1) but sadly we do not have the folded edges by default. Also, this example has a symmetry that makes it live on the sphere. We should figure out the quotient. """ import flipper from veerer.layout import FlatVeeringTriangulationLayout S = flipper.load("S_1_2") f = S.mapping_class("abC") V = FlatVeeringTriangulationLayout.from_pseudo_anosov(f) V.flip(4) V.flip(6) V.flip(10) V.flip(3) V.flip(11) V.flip(0)
 ... ... @@ -322,17 +322,7 @@ class Automaton(object): sage: from surface_dynamics import * sage: A = Automaton.from_stratum(AbelianStratum(2)) sage: A.statistics() {0: 24, 1: 4, 2: 4, 48: 2, 80: 2, 112: 24, 113: 5, 114: 5, 120: 10, 125: 3, 126: 3} {0: 24, 1: 4, 2: 4, 16: 28, 17: 5, 18: 5, 24: 10, 29: 3, 30: 3} """ from collections import defaultdict d = defaultdict(int) ... ...
 ... ... @@ -26,10 +26,8 @@ SQUARETILED = 1 << 2 QUADRANGULABLE = 1 << 3 CYLINDRICAL = RED | BLUE GEOMETRIC = 1 << 4 VBALANCED = 1 << 5 HBALANCED = 1 << 6 ST = SQUARETILED | GEOMETRIC | VBALANCED | HBALANCED ST = SQUARETILED | GEOMETRIC PROPERTIES_COLOURS = { NONE : '#FFFFFF', # white ... ... @@ -43,12 +41,10 @@ PROPERTIES_COLOURS = { } def key_property(p): return -((1<<8) * bool(p & BLUE) | \ (1<<7) * bool(p & RED) | \ (1<<6) * bool(p & SQUARETILED) | \ (1<<5) * bool(p & GEOMETRIC) | \ (1<<4) * bool(p & VBALANCED) | \ (1<<3) * bool(p & HBALANCED)) return -((1<<4) * bool(p & BLUE) | \ (1<<3) * bool(p & RED) | \ (1<<2) * bool(p & SQUARETILED) | \ (1<<1) * bool(p & GEOMETRIC)) def properties_to_string(p): r""" ... ... @@ -58,7 +54,7 @@ def properties_to_string(p): sage: from veerer.constants import * sage: T = VeeringTriangulation("(0,1,8)(2,~7,~1)(3,~0,~2)(4,~5,~3)(5,6,~4)(7,~8,~6)", "BRRRRBRBR") sage: properties_to_string(T.properties_code()) 'red geometric h-balanced' 'red geometric' sage: properties_to_string(ST|BLUE) 'blue square-tiled' ... ... @@ -92,13 +88,6 @@ def properties_to_string(p): if p & GEOMETRIC: s.append('geometric') if p & VBALANCED and p & HBALANCED: s.append('hv-balanced') elif p & HBALANCED: s.append('h-balanced') elif p & VBALANCED: s.append('v-balanced') if s: return ' '.join(s) else: ... ...
 ... ... @@ -604,25 +604,61 @@ def perm_orbit(p, i): j = p[j] return res def perm_on_list(p, t): def perm_on_list(p, a, n=None, swap=None): r""" Action of the permutation ``p`` on the list ``t``. Inplace action of permutation on list-like objects. INPUT: - ``p`` - permutation - ``a`` - list, array - ``n`` - (optional) size of permutation - ``swap`` - (optional) a swap function EXAMPLES:: sage: from veerer.permutation import perm_on_list sage: perm_on_list([2,1,3,0], [2,1,2,0]) [3, 1, 3, 2] sage: from veerer.permutation import * sage: l = [0,1,2,3,4] sage: p = [4,2,3,0,1] sage: perm_on_list(p,l) sage: l [3, 4, 1, 2, 0] Permutation action on matrix rows:: sage: m1 = matrix(ZZ, 5, 5, 1) sage: m2 = matrix(ZZ, 5, 5, 1) sage: m = matrix(ZZ, 5, 5, 1) sage: p1 = perm_init([4,1,3,2,0]) sage: p2 = perm_init([1,0,3,4,2]) sage: perm_on_list(p1, m1, swap=sage.matrix.matrix0.Matrix.swap_rows) sage: perm_on_list(p2, m2, swap=sage.matrix.matrix0.Matrix.swap_rows) sage: perm_on_list(perm_compose(p1, p2), m, swap=sage.matrix.matrix0.Matrix.swap_rows) sage: m == m2 * m1 True """ return [p[i] for i in t] def perm_on_array(p, a): n = len(p) b = array('l', [-1]*n) if n is None: n = len(p) seen = [False] * n for i in range(n): b[p[i]] = a[i] return b if seen[i]: continue seen[i] = True j = p[i] while seen[j] is False: if swap: swap(a, i, j) else: tmp = a[i] a[i] = a[j] a[j] = tmp seen[j] = True j = p[j] # WARNING: this is NOT inplace def perm_on_cyclic_list(p, t): r""" Action of the permutation ``p`` on the list ``t`` up to cyclic order. ... ...
 ... ... @@ -1145,7 +1145,7 @@ class Triangulation(object): ....: S.relabel(p) ....: assert S == T The sphere example (3 symmetries):: The sphere example (3 symmetries):: sage: fp = array('l', [1, 2, 0]) sage: ep = array('l', [0, 1, 2]) ... ... @@ -1160,12 +1160,24 @@ class Triangulation(object): ....: S = T.copy() ....: S.relabel(p) ....: assert S == T An example with no automorphism:: sage: T = Triangulation("(0,1,2)(3,4,5)(~0,~3,6)") sage: p = T._relabelling_from(0) sage: T.relabel(p) sage: for i in range(1, 9): ....: p = T._relabelling_from(i) ....: S = T.copy() ....: S.relabel(p) ....: S._check() ....: assert S != T """ n = self._n ep = self._ep vp = self._vp k = 0 # current available label at the front. k = 0 # current available label at the front. m = n - 1 # current available label at the back. relabelling = array('l', [-1] * n) relabelling[start_edge] = 0 ... ...
 ... ... @@ -54,6 +54,26 @@ def ppl_cone_from_hashable(args): P.add_constraint(sum(coeff * ppl.Variable(i) for i,coeff in enumerate(constraint)) >= 0) return P def relabel_on_edges(ep, r, n, m): r""" - ep - edge permutation - r - relabelling permutation - n - num half edges - m - num edges """ rr = [-1] * m for i in range(m): j = r[i] k = r[ep[i]] if j < k: rr[i] = j else: rr[i] = k return rr class VeeringTriangulation(Triangulation): r""" Veering triangulation. ... ... @@ -92,7 +112,7 @@ class VeeringTriangulation(Triangulation): sage: VeeringTriangulation.from_pseudo_anosov(h) VeeringTriangulation("(0,~3,~1)...(12,~14,~10)(~2,~9,~4)", "RBRBRRBRBBBBRBR") """ __slots__ = ['_colouring', '__curver'] __slots__ = ['_colouring'] def __init__(self, triangulation, colouring, check=True): Triangulation.__init__(self, triangulation, check=False) ... ... @@ -202,7 +222,7 @@ class VeeringTriangulation(Triangulation): sage: o = Origami('(1,2)', '(1,3)') sage: T = VeeringTriangulation.from_square_tiled(o) sage: T VeeringTriangulation("(0,1,2)(3,4,5)(6,7,8)(~8,~0,~7)(~6,~1,~5)(~4,~2,~3)", "RBBRBBRBB") VeeringTriangulation("(0,1,2)(3,4,5)(6,7,8)(~8,~0,~7)(~6,~1,~5)(~4,~2,~3)", "RRBRRBRRB") sage: o.stratum() H_2(2) sage: T.stratum() ... ... @@ -459,10 +479,6 @@ class VeeringTriangulation(Triangulation): sage: T.to_curver() [(~2, ~0, ~1), (0, 1, 2)] """ try: return self.__curver except AttributeError: pass require_package('curver', 'to_curver') ep = self._ep F = [] ... ... @@ -748,7 +764,6 @@ class VeeringTriangulation(Triangulation): print("Warning: alternating_square is not carefullly defined with GREEN/PURPLE edges") return all(colours[f] != colours[(f+1) % 4] for f in range(4)) def vertex_cycles(self, slope=VERTICAL): r""" Return the vertex cycles as curves on the (curver) triangulation. ... ... @@ -766,7 +781,7 @@ class VeeringTriangulation(Triangulation): """ require_package('curver', 'vertex_cycles') polytope = self.train_track_polytope(slope=slope) rays = [gen for gen in polytope.generators() if gen.is_ray()] rays = [g for g in polytope.generators() if g.is_ray()] T = self.to_curver() return [T.lamination([int(x) for x in ray.coefficients()]) for ray in rays] ... ... @@ -976,11 +991,16 @@ class VeeringTriangulation(Triangulation): sage: T, s, t = VeeringTriangulations.L_shaped_surface(2, 3, 4, 5, 1, 2) sage: Gx = matrix(ZZ, [s, t]) sage: for _ in range(10): ....: p = perm_random_centralizer(T.edge_permutation(copy=False)) ....: p = T._relabelling_from(choice(range(9))) ....: T.relabel(p, Gx=Gx) ....: T._set_switch_conditions(T._tt_check, Gx.row(0), VERTICAL) ....: T._set_switch_conditions(T._tt_check, Gx.row(1), VERTICAL) sage: from veerer.permutation import perm_random_centralizer sage: T, s, t = VeeringTriangulations.L_shaped_surface(2, 3, 4, 5, 1, 2) sage: Gx = matrix(ZZ, [s, t]) sage: p = [8, 7, 0, 6, 2, 5, 4, 3, 1] Composing relabelings and permutation composition:: sage: from veerer.permutation import perm_compose ... ... @@ -1024,19 +1044,13 @@ class VeeringTriangulation(Triangulation): if Lx: raise NotImplementedError if Gx: seen = [False] * self.num_edges() for c in perm_cycles(p): c0 = self._norm(c[0]) seen[c0] = True for i in range(1,len(c)): ci = self._norm(c[i]) if seen[ci]: break seen[ci] = True Gx.swap_columns(c0, ci) m = self.num_edges() rr = relabel_on_edges(self._ep, p, self._n, m) for c in perm_cycles(rr, False, m): for i in range(1, len(c)): Gx.swap_columns(c[0], c[i]) Triangulation.relabel(self, p) self._colouring = perm_on_array(p, self._colouring) perm_on_list(p, self._colouring) def _automorphism_good_starts(self): r""" ... ... @@ -1170,7 +1184,8 @@ class VeeringTriangulation(Triangulation): fp = perm_conjugate(self._fp, relabelling) ep = perm_conjugate(self._ep, relabelling) cols = perm_on_array(relabelling, self._colouring) cols = self._colouring[:] perm_on_list(relabelling, cols) T = (cols, fp, ep) if best is None or T == best: ... ... @@ -1189,6 +1204,31 @@ class VeeringTriangulation(Triangulation): def best_relabelling(self, all=False): r""" EXAMPLES:: sage: from veerer import * sage: T, s, t = VeeringTriangulations.L_shaped_surface(2, 3, 4, 5, 1, 2) sage: Gx = matrix(ZZ, [s,t]) sage: Gx.echelonize() sage: for i in range(9): ....: p = T._relabelling_from(i) ....: S = T.copy() ....: S.relabel(p) ....: S._check() TESTS:: sage: from veerer import * sage: from veerer.permutation import * sage: T, s, t = VeeringTriangulations.L_shaped_surface(2, 3, 4, 5, 1, 2) sage: Gx = matrix(ZZ, [s,t]) sage: Gx.echelonize() sage: T._set_switch_conditions(T._tt_check, Gx.row(0), VERTICAL) sage: T._set_switch_conditions(T._tt_check, Gx.row(1), VERTICAL) sage: p = T._relabelling_from(8) sage: T.relabel(p, Gx=Gx) sage: T._set_switch_conditions(T._tt_check, Gx.row(0), VERTICAL) sage: T._set_switch_conditions(T._tt_check, Gx.row(1), VERTICAL) """ best = None if all: ... ... @@ -1199,7 +1239,8 @@ class VeeringTriangulation(Triangulation): # relabelled data fp = perm_conjugate(self._fp, relabelling) ep = perm_conjugate(self._ep, relabelling) cols = perm_on_array(relabelling, self._colouring) cols = self._colouring[:] perm_on_list(relabelling, cols) T = (cols, fp, ep) if best is None or T < best: ... ... @@ -1419,16 +1460,36 @@ class VeeringTriangulation(Triangulation): ....: T.relabel(p) ....: T.set_canonical_labels() ....: assert s0 == T.to_string() When a linear space is passed, it is also set in canonical form:: sage: T, s, t = VeeringTriangulations.L_shaped_surface(2, 3, 4, 5, 1, 2) sage: Gx = matrix(ZZ, [s, t]) sage: T.set_canonical_labels(Gx=Gx) sage: T._set_switch_conditions(T._tt_check, Gx.row(0), VERTICAL) sage: T._set_switch_conditions(T._tt_check, Gx.row(1), VERTICAL) """ if Lx: raise NotImplementedError elif Gx: Gx.echelonize() R, (cols, fp, ep) = self.best_relabelling(all=True) self.relabel(R[0], Gx=Gx) if len(R) == 1: return rbest = perm_invert(R[0]) ibest = 0 Gbest = Gx.__copy__() Gtmp = Gx for i in range(2, len(R)): pass self.relabel(perm_compose_10(R[i-1], R[i]), Gx=Gtmp) Gtmp.echelonize() if Gtmp < Gbest: ibest = i Gtmp, Gbest = Gbest, Gtmp if ibest != len(R) - 1: Gx.relabel(perm_invert(R[-1]), rbest) else: r, (cols, fp, ep) = self.best_relabelling() self.relabel(r) ... ... @@ -1772,12 +1833,11 @@ class VeeringTriangulation(Triangulation): sage: from veerer.constants import properties_to_string sage: T = VeeringTriangulation("(0,1,8)(2,~7,~1)(3,~0,~2)(4,~5,~3)(5,6,~4)(7,~8,~6)", "BRRRRBRBR") sage: T.properties_code() 81 17 sage: properties_to_string(81) 'red geometric h-balanced' 'red geometric' """ from .constants import (BLUE, RED, SQUARETILED, SQUARETILED, QUADRANGULABLE, GEOMETRIC, VBALANCED, HBALANCED) from .constants import BLUE, RED, SQUARETILED, QUADRANGULABLE, GEOMETRIC code = 0 if self.is_square_tiled(RED): ... ... @@ -1794,22 +1854,14 @@ class VeeringTriangulation(Triangulation): code |= BLUE if self.is_geometric(): code |= GEOMETRIC if self.is_balanced(VERTICAL): code |= VBALANCED if self.is_balanced(HORIZONTAL): code |= HBALANCED if code & BLUE and code & RED: raise RuntimeError("found a blue and red triangulations!") if code & SQUARETILED: if not code & BLUE and not code & RED: raise RuntimeError("square-tiled should be colored") raise RuntimeError("square-tiled should be coloured") if not code & GEOMETRIC: raise RuntimeError("square-tiled should be geometric") if not code & VBALANCED: raise RuntimeError("square-tiled should be v-balanced") if not code & HBALANCED: raise RuntimeError("square-tiled should be h-balanced") return code ... ...
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!