def build_bundles(n): """ Builds (the snappy names of) oriented punctured torus bundles of length at most n-1. """ bundles = set() # perhaps more intelligent to enumerate fractions and find their # continued fractions. However, the code below is only too slow # by a factor of n, and generates the bundles in the correct # "order" (harmonic >> Lebesgue as we care about the number of # tetrahedra, not the number of syllables) for i in range(n): for s in cartesian_product([letters]*i): s = "".join(s) try: M = snappy.Manifold("b++" + s) for N in M.identify(): bundles.add(N.name()) except: pass try: M = snappy.Manifold("b+-" + s) for N in M.identify(): bundles.add(N.name()) except: pass return bundles
def fix_table(new_table, snappy_name): name = repr(new_table).split(' ')[0][5:] fixed_file = open(name+'fixed2.txt','w') notfixed_file = open(name+'notfixed2.txt','w') name = name.replace('Table', 'Exteriors') old_table = getattr(snappy, snappy_name) conn2 = new_table._connection2 c = conn2.cursor() for M_new in new_table: print(M_new.name()) id, isosig = c.execute("SELECT id,triangulation FROM {} WHERE name='{}'".format(new_table._table,M_new.name())).fetchall()[0] M_old = old_table[M_new.name()] if M_new.num_cusps()>4: print('Skipped: '+M_new.name()) notfixed_file.write(str(id)+','+M_new.name()+'\n') continue if same(M_new, M_old): assert same(snappy.Manifold(isosig),M_old) fixed_file.write(str(id)+','+M_new.name()+','+isosig+'\n') else: try: matching_iso = search_for_peripheral_match2(isosig,M_old) except ValueError: print("Klein thing") notfixed_file.write(str(id)+','+M_new.name()+'\n') continue if matching_iso: assert same(snappy.Manifold(matching_iso),M_old) fixed_file.write(str(id)+','+M_new.name()+','+matching_iso+'\n') else: print('No match found: '+ M_new.name()) notfixed_file.write(str(id)+','+M_new.name()+'\n') fixed_file.close() notfixed_file.close()
def graphics_failures(verbose): if cyopengl_works(): print("Testing graphics ...") import snappy.CyOpenGL result = doctest_modules([snappy.CyOpenGL], verbose=verbose).failed snappy.Manifold('m004').dirichlet_domain().view().test() snappy.Manifold('m125').cusp_neighborhood().view().test() if use_modernopengl: snappy.Manifold('m004').inside_view().test() snappy.Manifold('4_1').browse().test() snappy.ManifoldHP('m004').dirichlet_domain().view().test() snappy.ManifoldHP('m125').cusp_neighborhood().view().test() if use_modernopengl: snappy.ManifoldHP('m004').inside_view().test() if root_is_fake(): root = tk_root() if root: if windows: print('Close the root window to finish.') else: print('The windows will close in a few seconds.\n' 'Specify -w or --windows to avoid this.') root.after(7000, root.destroy) root.mainloop() else: print("***Warning***: CyOpenGL not installed, so not tested") result = 0 return result
def check_row(row): same = same_labeled_triangulation_and_peripheral_curves M_old = snappy.Manifold(row['name']) M_new = snappy.Manifold(row['triangulation']) if M_old.num_cusps() == 1: if not same(M_old, M_new): M_new.set_peripheral_curves([[[-1, 0], [0, -1]]]) if not same(M_new, M_old): print(row['name'], row['triangulation'])
def make_plot(row, params=plot_default, extra_plots=None): if row['trans_arcs_highres'] is not None: arcs = row['trans_arcs_highres'].unpickle() else: arcs = row['trans_arcs'].unpickle() title = '$' + row['name'] + '$: genus = ' + repr(row['alex_deg'] // 2) plot = params['plot_cls'](arcs, title=title) ax = plot.figure.axis if extra_plots: for x, y in extra_plots: ax.plot(x, y) k = order_of_longitude(snappy.Manifold(row['name'])) ax.plot((0, k), (0, 0)) ax.legend_.remove() ax.set_xbound(0, k) ax.get_xaxis().tick_bottom() yvals = [p.imag for arc in arcs for p in arc] ax.set_ybound(1.1 * min(yvals), 1.1 * max(yvals)) ytop = floor(1.1 * max(yvals)) if 1 <= ytop <= 10: ax.set_yticks(range(-ytop, ytop + 1)) elif 25 <= ytop <= 100: ticks = range(10, ytop, 10) ticks = [-y for y in ticks] + [0] + ticks ax.set_yticks(ticks) alex = PolynomialRing(QQ, 'a')(row['alex']) for z, e in unimodular_roots(alex): theta = k * rotation_angle(z) if e == 1: color = params['simple alex root'] else: color = params['mult alex root'] ax.plot([theta], [0], color=color, marker='o', markeredgecolor='black') M = snappy.Manifold(row['name']) for parabolic in eval(row['parabolic_PSL2R_details']): if len(parabolic) == 2: L, is_galois_conj_of_geom = parabolic points = [(0, L), (0, -L), (1, L), (1, -L)] else: x, y, is_galois_conj_of_geom = parabolic points = [(x, y)] if is_galois_conj_of_geom: color = params['galois of geom'] else: color = params['other parabolic'] for x, y in points: ax.plot([x], [y], color=color, marker='o', markeredgecolor='black') plot.figure.draw() return plot
def getNonHypList (manifoldName, cuspNum, coprimeList): nonHypList = [] M = snappy.Manifold(manifoldName) for [i,j] in coprimeList: M = snappy.Manifold(manifoldName) M.dehn_fill((i,j), cuspNum) if M.volume() < 0.5: nonHypList.append((i,j)) return nonHypList
def test_list_of_names(names, prec): for name in names: M = snappy.Manifold(name) ts = M.tetrahedra_field_gens() ans = ts.find_field(prec, 16, True, True) if ans is None: print M
def test_snappy(): for datum in snap_cusp_fields(): M = snappy.Manifold(datum.manifold) ts = M.tetrahedra_field_gens() ans = ts.find_field(300, 16) if ans is None: print M
def spinning_slopes(S): q_mat = quads_mat(S) T = S.triangulation() M = snappy.Manifold(T.snapPea()) pc_mats = peripheral_curve_mats(M, T) slopes = unoriented_spinning_slopes(S, pc_mats, q_mat) return slopes
def analyze_deeply(tri, angle): N = edge_equation_matrix_taut(tri, angle) N = Matrix(N) M = snappy.Manifold(tri.snappystring()) # look at it alex = alex_is_monic(M) hyper = hyper_is_monic(M) non_triv, non_triv_sol = non_trivial_solution(N) full, full_sol = fully_carried_solution(N) try: assert non_triv or not full # full => non_triv assert alex or not full # full => fibered => alex is monic assert hyper or not full # full => fibered => hyper is monic assert alex or not hyper # hyper is monic => alex is monic except AssertError: print("contradiction in maths") raise if full: pass elif non_triv: print("non-triv sol (but not full)") print((alex, hyper)) elif not alex or not hyper: print("no sol") print((alex, hyper)) return None
def onecuspgetexc(a, b, manifold): m = manifold.cusp_translations()[0][0] l = manifold.cusp_translations()[0][1] pairs = [] shortcurves = [] pairs.append([1, 0]) for y in range(2, 7): pairs.append([1, y]) pairs.append([-1, y]) for x in range(-7, 7): pairs.append([x, 1]) for y in range(2, 7): if x % y != 0 and y % x != 0: pairs.append([x, y]) for [x, y] in pairs: if abs(x * l + y * m) < 6: shortcurves.append([x, y]) hypshortcurves = [] nonhypshortcurves = [] for [c, d] in shortcurves: M = snappy.Manifold(mani) M.dehn_fill((a, b), 0) M.dehn_fill((c, d), 1) if hikmot.verify_hyperbolicity(M, False)[0]: hypshortcurves.append([a, b]) else: nonhypshortcurves.append((c, d)) return nonhypshortcurves
def triangulation_and_triangulation_skeleton(snappy_string): M = snappy.Manifold(snappy_string) # M.dehn_fill((1,0)) # MF = M.filled_triangulation() MC = snappy.snap.t3mlite.Mcomplex(M) return MC, TriangulationSkeleton(MC)
def unverifiedfromname(name): strname = str(name) pairs = [] pairs.append([1, 0]) for y in range(2, 7): pairs.append([1, y]) pairs.append([-1, y]) for x in range(-6, 7): pairs.append([x, 1]) for y in range(2, 7): if x % y != 0 and y % x != 0: pairs.append([x, y]) hypshortcurves = [] nonhypshortcurves = [] for [c, d] in pairs: thismanifold = snappy.Manifold(strname) thismanifold.dehn_fill((c, d), 0) #print thismanifold, hikmot.verify_hyperbolicity(thismanifold,False)[0] if thismanifold.volume() > 0.2: hypshortcurves.append([c, d]) else: nonhypshortcurves.append((c, d)) return nonhypshortcurves
def parabolic_psl2R(task): R = PolynomialRing(QQ, 'x') M = snappy.Manifold(task['name']) assert M.homology().elementary_divisors() == [0] ans = 0 obs_classes = M.ptolemy_obstruction_classes() assert len(obs_classes) == 2 for obs in obs_classes: V = M.ptolemy_variety(N=2, obstruction_class=obs) for sol in V.retrieve_solutions(): p = R(sol.number_field()) if p == 0: # Field is Q n = 1 else: n = num_real_roots(p) ans += n try: if sol.is_geometric(): task['real_places'] = n except: if obs._index > 0: task['real_places'] = n task['parabolic_PSL2R'] = ans if 'real_places' in task: task['done'] = True return task
def twocuspsgethypcurves(manifold): m = manifold.cusp_translations()[0][0] l = manifold.cusp_translations()[0][1] pairs = [] shortcurves = [] pairs.append([1, 0]) for y in range(2, 7): pairs.append([1, y]) pairs.append([-1, y]) for x in range(-7, 7): pairs.append([x, 1]) for y in range(2, 7): if x % y != 0 and y % x != 0: pairs.append([x, y]) for [x, y] in pairs: if abs(x * l + y * m) < 6: shortcurves.append([x, y]) hypshortcurves = [] nonhypshortcurves = [] for [a, b] in shortcurves: M = snappy.Manifold(mani) M.dehn_fill((a, b), 0) if hikmot.verify_hyperbolicity(M, False)[0]: hypshortcurves.append([a, b]) else: nonhypshortcurves.append((a, b)) print 'non hyp:' print nonhypshortcurves return hypshortcurves
def compute_census_data(filename_in, filename_out, functions, verbose=0): ### each function takes in data about the triangulation, returns a string census_data = parse_data_file(filename_in) out = [] for i, line in enumerate(census_data): line_data = line.split( ' ' ) ## 0th is taut_sig, then may be other data we dont want to lose. taut_sig = line_data[0] regina_sig = taut_sig.split('_')[0] tri, angle = isosig_to_tri_angle(taut_sig) snappy_triang = snappy.Manifold(regina_sig) # snappy_triang = None triang_data = { 'sig': taut_sig, 'angle': angle, 'tri': tri, 'snappy_triang': snappy_triang, 'old_data': line_data } line_out = [] for func in functions: line_out.append(func(triang_data)) out.append(line_out) if verbose > 0 and i % 1000 == 0: print(i, line_out) write_data_file(out, filename_out)
def analyzeManifold(manifoldName, cuspNum, coprimeList): greaterThan = [] lessThan = [] notHyp = [] miss = [] for [i, j] in coprimeList: M = snappy.Manifold(manifoldName) M.dehn_fill((i, j), cuspNum) if M.volume() > 0.5: try: C = M.cusp_neighborhood() C.set_displacement(100) cuspArea = C.volume() * 2 if cuspArea < 5.24: lessThan.append((i, j)) else: greaterThan.append((i, j)) except: # print 'Failed to construct cusp for ' + str((i,j)) +' surgery' miss.append((i, j)) pass else: notHyp.append((i, j)) return [len(lessThan), len(greaterThan), len(notHyp), len(miss)]
def test_handles(code): code = code.strip() encode = list(map(int, code.split(','))) M = DT_handles_surface(encode).splitting(gluing="", handles="h") N = snappy.Manifold('DT[%s]' % str(code)) assertManifoldsIsometric(M, N)
def test_link_invariant(): import snappy # DT codes of the same link but with different orientations of the # components dt_codes = [ [(-14, -46, -40, -28, -60, -70), (-32, -34, -38, -4, -52, -50, -48), (-44, -42, -64, -2, -16, -58), (-56, -54, -8), (-36, -26, -24, -22, -20, -6, -18), (-10, -66), (-72, -30, -62), (-12, -68)], [(-14, -46, -40, -28, -60, -70), (-36, -34, -30, -4, -52, -50, -48), (-42, -44, -58, -16, -2, -64), (-56, -54, -8), (-32, -26, -24, -22, -20, -6, -18), (-10, -66), (-72, -38, -62), (-12, -68)], [(14, 70, 64, 50, 36, 24), (18, 2), (26, 16, 72), (46, 44, 22, 6, 48, 54), (52, 62, 60, 58, 56, 12, 34), (68, 66, 32, 10, 42, 40, 38), (28, 30, 8), (20, 4)], [(-14, -46, -40, -28, -60, -70), (-32, -34, -38, -4, -52, -50, -48), (-44, -42, -64, -2, -16, -58), (-56, -54, -8), (-36, -26, -24, -22, -20, -6, -18), (-10, -68), (-30, -72, -62), (-12, -66)], [(14, 70, 64, 50, 36, 24), (2, 18), (34, 16, 72), (42, 40, 54, 38, 6, 22), (62, 52, 26, 12, 56, 58, 60), (68, 66, 28, 10, 44, 46, 48), (32, 30, 8), (20, 4)], [(-14, -46, -40, -28, -60, -70), (-34, -36, -58, -56, -54, -4, -30), (-42, -44, -48, -26, -2, -64), (-50, -52, -8), (-16, -32, -24, -6, -22, -20, -18), (-68, -10), (-38, -72, -62), (-66, -12)], [(-14, -46, -40, -28, -60, -70), (-34, -36, -58, -56, -54, -4, -30), (-42, -44, -48, -26, -2, -64), (-50, -52, -8), (-16, -32, -24, -6, -22, -20, -18), (-10, -66), (-72, -38, -62), (-68, -12)], [(14, 70, 64, 50, 36, 24), (2, 18), (16, 34, 72), (42, 40, 54, 38, 6, 20), (62, 52, 26, 12, 56, 58, 60), (68, 66, 28, 10, 44, 46, 48), (32, 30, 8), (4, 22)], [(-14, -46, -40, -28, -60, -70), (-32, -34, -38, -4, -52, -50, -48), (-44, -42, -64, -2, -16, -58), (-56, -54, -8), (-36, -26, -24, -22, -20, -6, -18), (-66, -10), (-72, -30, -62), (-68, -12)] ] # Get complement for each dt_code and complement with opposite orientation # for each dt_code mfds = [ snappy.Manifold('DT%s' % dt_code) for dt_code in (dt_codes + dt_codes) ] for mfd in mfds[:len(dt_codes)]: mfd.reverse_orientation() isometry_signatures = [ mfd.isometry_signature(of_link = True) for mfd in mfds ] # All the links only differ in orientation of complement or components, # should get the same isometry_signature assert len(set(isometry_signatures)) == 1 M = snappy.Manifold(isometry_signatures[0]) N = snappy.Manifold(M.isometry_signature(of_link = True)) # Instantiating a manifold from its decorated isometry_signature should # eventually yield to a fixed point assert same_peripheral_curves(M, N) # More sanity checks assert isometry_signatures[0] == M.isometry_signature(of_link = True) assert isometry_signatures[0] == N.isometry_signature(of_link = True) for mfd in mfds: assert mfd.is_isometric_to(M, True)[0].extends_to_link() assert mfd.is_isometric_to(N, True)[0].extends_to_link() print("Tested that decorated isometry_signature is a link invariant")
def splitting(self, gluing, handles, name=None, optimize=True, warnings=True, debugging_level=0, return_type='manifold'): ''' Generate a manifold with Heegaard splitting this surface from mapping class group data using the Twister program of Bell, Hall and Schleimer. Arguments: Required: gluing - the gluing used to join the upper and lower compression bodies handles - where to attach 2-handles Optional: name - name of the resulting manifold optimize - try to reduce the number of tetrahedra (default True) warnings - print Twister warnings (default True) debugging_level - specifies the amount of debugging information to be shown (default 0) return_type - specifies how to return the manifold, either as a 'manifold' (default), 'triangulation' or 'string' Gluing is a word of annulus and rectangle names (or their inverses). These are read from left to right and determine a sequence of (half) Dehn twists. When prefixed with an "!" the name specifies a drilling. For example, "a*B*a*B*A*A*!a*!b" will perform 6 twists and then drill twice. Handles is again a word of annulus names (or inverses). For example, 'a*c*A' means attach three 2-handles, two above and one below. Examples: The genus two splitting of the solid torus: >>> M = twister.Surface('S_2').splitting(gluing='', handles='a*B*c') ''' if name is None: name = gluing + ' ' + handles tri, messages = build_splitting(name, self.surface_contents, gluing, handles, optimize, True, warnings, debugging_level) # You might want to change what is done with any warning / error messages. # Perhaps they should be returned in the next block? if messages != '': print(messages) if tri is None: return None return_type = return_type.lower() if return_type == 'manifold': return snappy.Manifold(tri) if return_type == 'triangulation': return snappy.Triangulation(tri) if return_type == 'string': return tri raise TypeError( 'Return type must be \'manifold\', \'triangulation\' or \'string\'.' )
def signature(name): M = snappy.Manifold(name) N = snappy.HTLinkExteriors.identify(M) if N: K = N.link() E = K.exterior() sign = 1 if orientation_pres_isometric(M, E) else -1 return sign * K.signature()
def bundle(self, monodromy, name=None, optimize=True, warnings=True, debugging_level=0, return_type='manifold'): ''' Generate a surface bundle over a circle with fibre this surface from mapping class group data using the Twister program of Bell, Hall and Schleimer. Arguments: Required: monodromy - build a surface bundle with specified monodromy Optional: name - name of the resulting manifold optimize - try to reduce the number of tetrahedra (default True) warnings - print Twister warnings (default True) debugging_level - specifies the amount of debugging information to be shown (default 0) return_type - specifies how to return the manifold, either as a 'manifold' (default), 'triangulation' or 'string' Monodromy is a word of annulus and rectangle names (or their inverses). These are read from left to right and determine a sequence of (half) Dehn twists. When prefixed with an "!" the name specifies a drilling. For example, "a*B*a*B*A*A*!a*!b" will perform 6 twists and then drill twice. Examples: The figure eight knot complement: >>> M = twister.Surface((1,1)).bundle(monodromy='a_0*B1') The minimally twisted six chain link: >>> M = twister.Surface('S_1_1').bundles(monodromy='!a*!b*!a*!b*!a*!b') >>> M.set_peripheral_curves('shortest_meridians', 0) >>> M.dehn_fill((1,0),0) ''' if name is None: name = monodromy tri, messages = build_bundle(name, self.surface_contents, monodromy, optimize, True, warnings, debugging_level) # You might want to change what is done with any warning / error messages. # Perhaps they should be returned in the next block? if messages != '': print(messages) if tri is None: return None return_type = return_type.lower() if return_type == 'manifold': return snappy.Manifold(tri) if return_type == 'triangulation': return snappy.Triangulation(tri) if return_type == 'string': return tri raise TypeError( 'Return type must be \'manifold\', \'triangulation\' or \'string\'.' )
def children(manifold): M = snappy.Manifold(manifold) for cusp_num in range(M.num_cusps()): kids = (interesting_fillings(manifold, cusp_num)) for name in inquire_list: if name in kids: print str(name) + ' is ' + str( kids[name] ) + ' surgery on ' + manifold + ' cusp number ' + str(cusp_num)
def petaluma_complement(P): N = len(P) B = [(-1)**int(P[i * 2 % N] < P[(i + j) * 2 % N]) * j for i in range(N) for j in range(1, N / 2)] M = snappy.Manifold('Braid' + str(B)) M.dehn_fill((1, 0), 1) M = M.filled_triangulation() # print M.cusp_info() return M
def alexander(task): M = snappy.Manifold(task['name']) p = M.alexander_polynomial() task['alex'] = repr(p) task['alex_deg'] = p.degree() task['alex_monic'] = p.is_monic() uniroots = unimodular_roots(p) task['num_uniroots'] = len(uniroots) task['num_mult_uniroots'] = len([z for z, e in uniroots if e > 1]) task['done'] = True
def test_DT(dt, M2=None): if M2 is None: M2 = snappy.Manifold() dtc = spherogram.DTcodec(dt) L = dtc.link() M0, M1 = dtc.exterior(), L.exterior() L.view(M2.LE) #M2.LE.sorted_components() M2.LE.callback() return manifolds_match(M0, M1) and manifolds_match(M1, M2)
def all_isosigs(M, decorated=True): """ Starting with a Manifold from database, find all possible starting tetrahedra and labelings of that tetrahedron that results in an isosig giving the exact same triangulation (i.e. _gluing_data) as the original when constructed by snappy.Manifold """ s = M.name() original_gluing_data = M._gluing_data() seen_isosigs = set() for i in range(M.num_tetrahedra()): for j in range(24): isosig = snappy.Manifold(s)._permutation_isosig( i, j, decorated=decorated) if isosig not in seen_isosigs: if snappy.Manifold( isosig)._gluing_data() == original_gluing_data: yield isosig seen_isosigs.add(isosig)
def parabolic_psl2R_details(task, pari_prec=15): M = snappy.Manifold(task['name']) reps = real_parabolic_reps_from_ptolemy(M, pari_prec) ans = [] for rho in reps: ans.append((longitude_translation(rho), rho.is_galois_conj_of_geom)) ans.sort() task['parabolic_PSL2R_details'] = repr(ans) task['done'] = True return task
def test(manifold_with_DT, plink_manifold=None): L = link_from_manifold(manifold_with_DT) PM = plink_manifold if PM is None: PM = snappy.Manifold() PM.LE.load_from_spherogram(L, None, False) PM.LE.callback() if appears_hyperbolic(PM): assert abs(manifold_with_DT.volume() - PM.volume()) < 0.000001 assert manifold_with_DT.is_isometric_to(PM)
def basic(task): M = snappy.Manifold(task['name']) task['volume'] = M.volume() task['tets'] = M.num_tetrahedra() M.dehn_fill((1, 0)) if M.fundamental_group().num_generators() == 0: task['inS3'] = True else: task['inS3'] = False task['done'] = True