def test_layered_parents(sig, quiet = False): tri, angle = isosig_to_tri_angle(sig) branch = upper_branched_surface(tri, angle) loops = find_flow_cycles(tri, branch) tri_loops = [flow_cycle_to_triangle_loop(tri, branch, loop) for loop in loops] no_of_layered_parents = 0 # drillings through some simple cycles is not implemented so might get 0 even if there is a simple cycle which gives a layered parent for tri_loop in tri_loops: if tri_loop != False: # False means that tri_loop goes more than once along the same triangle - not currently implemented tri, angle = isosig_to_tri_angle(sig) if tri_loop_is_boundary_parallel(tri_loop, tri) == False: # if a loop is boundary parallel then we don't drill tri, angle = isosig_to_tri_angle(sig) branch = upper_branched_surface(tri, angle) if quiet == False: print ("drilling", sig, "along", tri_loop) drill(tri, tri_loop, angle, branch) if quiet == False: print("drilled:", tri.isoSig(), angle, branch) print("is layered:", is_layered(tri, angle)) if is_layered(tri, angle): no_of_layered_parents = no_of_layered_parents + 1 if no_of_layered_parents == 0: print (sig, "does not have a layered parent")
def test_semiflow_on_drillings(sig): tri, angle = isosig_to_tri_angle(sig) branch = upper_branched_surface(tri, angle) loops = find_flow_cycles(tri, branch) tri_loops = [flow_cycle_to_triangle_loop(tri, branch, loop) for loop in loops] for tri_loop in tri_loops: if tri_loop != False: # False means that tri_loop goes more than once along the same triangle - not currently implemented tri, angle = isosig_to_tri_angle(sig) if tri_loop_is_boundary_parallel(tri_loop, tri) == False: # if a loop is boundary parallel then we don't drill tri, angle = isosig_to_tri_angle(sig) branch = upper_branched_surface(tri, angle) drill(tri, tri_loop, angle, branch) assert has_non_sing_semiflow(tri, branch)
def compute_order_of_euler_classes(file_in, number=None, file_out=None): data_in = parse_data_file(file_in) data_in = [line.split(" ") for line in data_in] if number != None: data_in = data_in[:number] data_out = [] evil = [] for i, line in enumerate(data_in): if i % 50 == 0: print( ((1.0*i)/(1.0*len(data_in)), len(data_out)) ) sig = line[0] tri, angle = isosig_to_tri_angle(sig) # angle = [int(letter) for letter in angle_s] curr_euler = order_of_euler_class(coboundary(tri, angle), euler_cocycle(tri, angle)) if curr_euler == "non-torsion": evil.append(sig) print(sig + " has non-torsion Euler class!!!!") elif curr_euler == 1: # order is one so [E] = 0. Boring. pass else: line_out = [sig, str(curr_euler)] line_out.extend(line[1:]) data_out.append(line_out) if file_out != None: write_data_file(data_out, file_out) print( ("list of evil:", evil) ) return data_out
def main(): # for i in range(4): # print(i) # # tri, angle = isosig_to_tri_angle('cPcbbbiht_12') # sigs = ['dLQacccjsnk_200', 'dLQbccchhfo_122','dLQbccchhsj_122'] # for sig in sigs: # print(sig) # tri, angle = isosig_to_tri_angle(sig) # for branch in all_branched_surfaces(tri): # print(lex_smallest_branched_surface(tri, branch)) sig = 'dLQacccjsnk_200' for i in range(6): # print(i) tri, angle = isosig_to_tri_angle(sig) tri_original = regina.Triangulation3(tri) #copy out = twoThreeMove(tri, [4, 11, 0], i, return_edge=True) if out != False: tri, possible_branches, edge_num = out # print('possible_branches', possible_branches) # print('all branches', all_branched_surfaces(tri)) tri, branch = threeTwoMove(tri, possible_branches[0], edge_num) all_isoms = tri.findAllIsomorphisms(tri_original) all_branches = [ apply_isom_to_branched_surface(branch, isom) for isom in all_isoms ] assert [4, 11, 0] in all_branches
def try_all_drillings(sig): tri_loops = find_tri_loops(sig) for tri_loop in tri_loops: if tri_loop != False: tri, angle = isosig_to_tri_angle(sig) print(sig, tri_loop) find_veering_after_drilling(tri, angle, tri_loop)
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 perform_all_mutations(tri, angle, weights, tet_vert_coorientations=None, print_stratum=True): if tet_vert_coorientations == None: tet_vert_coorientations = is_transverse_taut( tri, angle, return_type="tet_vert_coorientations") surface, edge_colours = build_surface(tri, angle, weights, return_edge_colours=True) if print_stratum == True: this_stratum = stratum(tri, angle, weights) print('stratum:', this_stratum) veering_isoms = veering_symmetry_group(surface, edge_colours) if len(veering_isoms) > 1: sig = isosig_from_tri_angle(tri, angle) for i in range(1, len(veering_isoms)): isom = veering_isoms[i] tri, angle = isosig_to_tri_angle(sig) mutate(tri, angle, weights, isom) else: print('surface has no veering symmetries')
def go_deep(): sig = 'dLQacccjsnk_200' branch = [4, 11, 0] tri, angle = isosig_to_tri_angle(sig) for j in range(20): print(j) tri, branch = go_deeper(tri, branch) if not has_non_sing_semiflow(tri, branch): print(tri, branch)
def make_continent_naive(veering_isosig, max_num_tetrahedra=50): tri, angle = isosig_to_tri_angle(veering_isosig) vt = veering_triangulation(tri, angle) #, tet_shapes = tet_shapes) initial_tet_face = tet_face(vt, 0, 0, verts_pos=[None, None, None, None]) con = continent(vt, initial_tet_face) #, desired_vertices = desired_vertices ) con.build_naive(max_num_tetrahedra=max_num_tetrahedra) con.make_convex() print(len(con.triangles), len(con.vertices), len(con.tetrahedra)) return con
def test(): # sig = 'cPcbbbiht_12' # sig = 'dLQacccjsnk_200' # sig = 'dLQbccchhsj_122' # sig = 'eLAkaccddjsnak_2001' # sig = 'eLAkbccddhhsqs_1220' # sig = 'eLMkbcddddedde_2100' # sig = 'eLMkbcdddhhhdu_1221' # sig = 'eLMkbcdddhhhml_1221' # sig = 'eLMkbcdddhhqqa_1220' # eLMkbcdddhhqxh_1220 # eLMkbcdddhxqdu_1200 # eLMkbcdddhxqlm_1200 # eLPkaccddjnkaj_2002 # eLPkbcdddhrrcv_1200 # sig = 'gLLAQbecdfffhhnkqnc_120012' sigs = parse_data_file('Data/veering_census.txt') for j, sig in enumerate(sigs[:5]): if j%100 == 0: print(j) tri, angle = isosig_to_tri_angle(sig) # tri.save(sig + '.rga') branch = upper_branched_surface(tri, angle) ### also checks for veering and transverse taut found_loops = find_flow_cycles(tri, branch) # print(len(found_loops)) # for loop in found_loops: # print(loop) # print('found_loops', found_loops) # print(sig) for loop in found_loops: tri, angle = isosig_to_tri_angle(sig) branch = upper_branched_surface(tri, angle) tri_loop = flow_cycle_to_triangle_loop(tri, branch, loop) if tri_loop != False: if not tri_loop_is_boundary_parallel(tri_loop, tri): print('sig', isosig_from_tri_angle_branch(tri, angle, branch), 'loop', loop, 'tri_loop', tri_loop) drill(tri, tri_loop, angle = angle, branch = branch, sig = sig) print('new angle, branch', angle, branch) print(isosig_from_tri_angle_branch(tri, angle, branch))
def main(): tri, angle = isosig_to_tri_angle('jLLAvQQbcdeihhiihtsfxedxhdt_201021201') # tri, angle = isosig_to_tri_angle('cPcbbbiht_12') for i in range(tri.countTriangles()): print('triangle_num', i) tri2 = regina.Triangulation3(tri) angle2 = angle[:] tri3, angle3, edge_num = twoThreeMove(tri2, angle2, i, return_edge = True) print('angle3', angle3, 'edge_num', edge_num) threeTwoMove(tri3, angle3, edge_num)
def find_veering_from_drilled(start_isoSig, name=None, search_depth=100, ceiling=8, check_property=False, property=None, save_dir=None): #first check if the first one is not veering tri, angle = isosig_to_tri_angle(start_isoSig) if is_veering(tri, angle): print('start_isoSig is veering') else: start_node = taut_pachner_node(start_isoSig, ceiling=ceiling) start_node.came_from = None big_dict_of_nodes = {start_isoSig: start_node} frontier_isoSigs = set([start_isoSig]) print(len(big_dict_of_nodes), len(frontier_isoSigs)) for counter in range(search_depth): if len(frontier_isoSigs) == 0: #we are done... break new_frontier_isoSigs = set([]) # for each element in the frontier check to see if it appears on the big_list_of_sigs if not we add it to the big list for cur_isoSig in frontier_isoSigs: current_node = big_dict_of_nodes[cur_isoSig] neighbour_isoSigs = current_node.all_neighbour_isoSigs() for nb_isoSig in neighbour_isoSigs: if not nb_isoSig in big_dict_of_nodes: nb_tri, nb_angle = current_node.neighbour_moves_tri_angles[ nb_isoSig] new_node = taut_pachner_node(nb_isoSig, tri=nb_tri, angle=nb_angle, ceiling=ceiling) new_node.came_from = cur_isoSig if counter == search_depth - 1: #last layer new_node.is_frontier = True new_frontier_isoSigs.add(nb_isoSig) big_dict_of_nodes[nb_isoSig] = new_node if is_veering(nb_tri, nb_angle): print_path(nb_isoSig, big_dict_of_nodes) print('veering:', isosig_from_tri_angle(nb_tri, nb_angle)) break frontier_isoSigs = new_frontier_isoSigs print(len(big_dict_of_nodes), len(frontier_isoSigs)) return None
def main(): tri, angle = isosig_to_tri_angle('cPcbbbdxm_10') branch = upper_branched_surface(tri, angle) print(branch) tl = flow_cycle_to_triangle_loop(tri, branch, [(0, 2)]) drill(tri, tl, angle=angle, branch=branch) print(branch) # sig_taut, isom1 = isosig_from_tri_angle(tri, angle, return_isom = True) # tri2, angle2, isom2 = isosig_to_tri_angle(sig_taut, return_isom = True) # combined_isom = isom2 * isom1 # tri3 = combined_isom.apply(tri) # print(isom1) # print(isom2) # print(combined_isom) # assert tri.isIsomorphicTo(tri3) # sig = isosig_from_tri_angle_branch(tri, angle, branch) # # print(sig, angle, branch) # # tri3, angle3, branch3 = isosig_to_tri_angle_branch(sig) # tri, angle = isosig_to_tri_angle('cPcbbbdxm_10') # branch = upper_branched_surface(tri, angle) # print('original tri', tri, tri.countTetrahedra()) # print('original angle, branch', angle, branch) # assert is_taut(tri, angle) # assert is_branched(tri, branch) # all_isoms = tri.findAllIsomorphisms(tri) # for isom in all_isoms: # print(isom) # new_angle = apply_isom_to_angle_struct_list(angle, isom) # new_branch = apply_isom_to_branched_surface(branch, isom) # new_tri = isom.apply(tri) # not in place # print('new_angle, new_branch', new_angle, new_branch) # assert is_taut(tri, new_angle) # assert is_taut(new_tri, new_angle) # assert is_branched(tri, new_branch) # assert is_branched(new_tri, new_branch) isosig, isosig_isom = tri.isoSigDetail( ) # isom is the mapping from the original triangulation to the isosig triangulation isosig_tri = regina.Triangulation3.fromIsoSig(isosig) isosig_branch = apply_isom_to_branched_surface(branch, isosig_isom) assert is_branched(isosig_tri, isosig_branch)
def isosig_to_tri_angle_branch(isosig): """ Given a taut branched isosig, returns an oriented regina triangulation, the list of angles for the taut angle structure, and the branched surface for the new labelling. """ sig_parts = isosig.split("_") tri, angle, isom = isosig_to_tri_angle(sig_parts[0] + '_' + sig_parts[1], return_isom=True) branch = list(sig_parts[2]) branch = [ord(letter) - 97 for letter in branch] assert all([0 <= l and l <= 11 for l in branch]) branch = apply_isom_to_branched_surface(branch, isom) assert is_branched(tri, branch) return tri, angle, branch
def shapes_to_pickle(isosigs, filename, progress = 100): shapes = {} for i, sig in enumerate(isosigs): if i % progress == 0: print((i, sig)) tri, angle = isosig_to_tri_angle(sig) N = snappy.Manifold(tri) N_shapes = [complex(shape['rect']) for shape in N.tetrahedra_shapes()] # N = snappy.ManifoldHP(tri) # N_shapes = [shape['rect'] for shape in N.tetrahedra_shapes()] shapes[sig] = N_shapes output_to_pickle(shapes, filename) return None
def analyze_sig(sig): # print(sig) tri, angle = isosig_to_tri_angle(sig) surfs = regina.NormalSurfaces.enumerate(tri, regina.NS_QUAD_CLOSED, regina.NS_FUNDAMENTAL) if surfs != None: two_quad_type_surfs = [] for i in range(surfs.size()): surf = surfs.surface(i) if count_quad_types(surf) <= 2: two_quad_type_surfs.append(surf) # print(count_quads(surf), sig, surf) if len(two_quad_type_surfs) > 2: print(sig) for surf in two_quad_type_surfs: print(surf)
def test(num_to_check = 1000): veering_isosigs = parse_data_file("Data/veering_census.txt") # for sig in veering_isosigs[:2000]: ### random.sample(veering_isosigs, num_to_check): # tri, angle = taut.isosig_to_tri_angle(sig) # face_num = random.randrange(tri.countTriangles()) # result = twoThreeMove(tri, face_num, angle = angle, return_edge = True, return_vertex_perm = True) # if result != False: # tri2, angle2, edge_num, vertex_perm2 = result # tri3, angle3, vertex_perm3 = threeTwoMove(tri2, edge_num, angle = angle2, return_vertex_perm = True) # assert taut.isosig_from_tri_angle(tri, angle) == taut.isosig_from_tri_angle(tri3, angle3) sig = 'gLLPQceeffefiiaellu_012110' tri, angle = taut.isosig_to_tri_angle(sig) for face_num in range(tri.countTriangles()): result = twoThreeMove(tri, face_num, angle = angle, return_edge = True, return_vertex_perm = True) if result != False: tri2, angle2, edge_num, vertex_perm2 = result tri3, angle3, vertex_perm3 = threeTwoMove(tri2, edge_num, angle = angle2, return_vertex_perm = True) assert taut.isosig_from_tri_angle(tri, angle) == taut.isosig_from_tri_angle(tri3, angle3)
def draw_ladders_and_geometric_boundary_for_veering_isosig(sig, args={}): if args == {}: args = { 'draw_boundary_triangulation': True, 'draw_triangles_near_poles': False, 'ct_depth': -1, 'ct_epsilon': 0.03, 'global_drawing_scale': 4, 'delta': 0.2, 'ladder_width': 10.0, 'ladder_height': 20.0, 'draw_labels': True } out_dir_ladders = 'Images/Ladders' out_dir_geometric = 'Images/Geometric' output_filename = sig + '.pdf' tri, angle = isosig_to_tri_angle(sig) M = Manifold(tri) tet_shapes = M.tetrahedra_shapes() tet_shapes = [complex(shape["rect"]) for shape in tet_shapes] args['tet_shapes'] = tet_shapes B = generate_boundary_triangulation(tri, angle, args=args, output_filename=output_filename) args_ladder = args.copy() args_ladder['style'] = 'ladders' output_filename_ladders = out_dir_ladders + '/' + output_filename B.draw(output_filename_ladders, args=args_ladder) args_geometric = args.copy() args_geometric['style'] = 'geometric' output_filename_geometric = out_dir_geometric + '/' + output_filename B.draw(output_filename_geometric, args=args_geometric)
def main(): depth = 100 ceiling = 8 print('depth', depth) print('ceiling', ceiling) target_isoSig = 'gLLPQceeffefiiaellu_012110' ### drilled start_isoSig = 'gLLPQccdfeffhggaagb_201022' ### veering tri, angle = isosig_to_tri_angle(start_isoSig) branch = upper_branched_surface(tri, angle) start_isoSig = isosig_from_tri_angle_branch(tri, angle, branch) graph = search_Pachner_graph_for_shortest_path(start_isoSig, tri, angle, branch, target_isoSig, name=None, search_depth=depth, ceiling=ceiling, check_property=False, property=None, save_dir=None)
def run_tests(num_to_check=10, smaller_num_to_check = 10): import taut veering_isosigs = parse_data_file("Data/veering_census.txt") print("testing is_taut") for sig in random.sample(veering_isosigs, num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) assert taut.is_taut(tri, angle), sig print("testing isosig round trip") for sig in random.sample(veering_isosigs, num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) recovered_sig = taut.isosig_from_tri_angle(tri, angle) assert sig == recovered_sig, sig # we only test this round trip - the other round trip does not # make sense because tri->isosig is many to one. import transverse_taut print("testing is_transverse_taut") for sig in random.sample(veering_isosigs, num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) assert transverse_taut.is_transverse_taut(tri, angle), sig non_transverse_taut_isosigs = parse_data_file("Data/veering_non_transverse_taut_examples.txt") print("testing not is_transverse_taut") for sig in non_transverse_taut_isosigs: tri, angle = taut.isosig_to_tri_angle(sig) assert not transverse_taut.is_transverse_taut(tri, angle), sig import veering print("testing is_veering") for sig in random.sample(veering_isosigs, num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) assert veering.is_veering(tri, angle), sig # tri, angle = taut.isosig_to_tri_angle("cPcbbbdxm_10") # explore_mobius_surgery_graph(tri, angle, max_tetrahedra = 12) # # tests to see that it makes only veering triangulations as it goes import veering_dehn_surgery print("testing veering_dehn_surgery") for sig in random.sample(veering_isosigs, num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) for face_num in veering_dehn_surgery.get_mobius_strip_indices(tri): (tri_s, angle_s, face_num_s) = veering_dehn_surgery.veering_mobius_dehn_surgery(tri, angle, face_num) assert veering.is_veering(tri_s, angle_s), sig import veering_fan_excision print("testing veering_fan_excision") m003, _ = taut.isosig_to_tri_angle('cPcbbbdxm_10') m004, _ = taut.isosig_to_tri_angle('cPcbbbiht_12') for sig in random.sample(veering_isosigs, num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) tet_types = veering.is_veering(tri, angle, return_type = "tet_types") if tet_types.count("toggle") == 2: excised_tri, _ = veering_fan_excision.excise_fans(tri, angle) assert ( excised_tri.isIsomorphicTo(m003) != None or excised_tri.isIsomorphicTo(m004) != None ), sig import pachner print("testing pachner with taut structure") for sig in random.sample(veering_isosigs, num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) face_num = random.randrange(tri.countTriangles()) result = pachner.twoThreeMove(tri, face_num, angle = angle, return_edge = True) if result != False: tri2, angle2, edge_num = result tri3, angle3 = pachner.threeTwoMove(tri2, edge_num, angle = angle2) assert taut.isosig_from_tri_angle(tri, angle) == taut.isosig_from_tri_angle(tri3, angle3), sig import branched_surface import regina print("testing branched_surface and pachner with branched surface") for sig in random.sample(veering_isosigs, num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) tri_original = regina.Triangulation3(tri) #copy branch = branched_surface.upper_branched_surface(tri, angle, return_lower = random.choice([True, False])) ### test branch isosig round trip sig_with_branch = branched_surface.isosig_from_tri_angle_branch(tri, angle, branch) tri2, angle2, branch2 = branched_surface.isosig_to_tri_angle_branch(sig_with_branch) assert (branch == branch2) and (angle == angle2), sig branch_original = branch[:] #copy face_num = random.randrange(tri.countTriangles()) out = pachner.twoThreeMove(tri, face_num, branch = branch, return_edge = True) if out != False: tri, possible_branches, edge_num = out tri, branch = pachner.threeTwoMove(tri, edge_num, branch = possible_branches[0]) all_isoms = tri.findAllIsomorphisms(tri_original) all_branches = [branched_surface.apply_isom_to_branched_surface(branch, isom) for isom in all_isoms] assert branch_original in all_branches, sig import flow_cycles import drill print("testing taut and branched drill + semiflows on drillings") for sig in random.sample(veering_isosigs, smaller_num_to_check): tri, angle = taut.isosig_to_tri_angle(sig) branch = branched_surface.upper_branched_surface(tri, angle) ### also checks for veering and transverse taut found_loops = flow_cycles.find_flow_cycles(tri, branch) for loop in random.sample(found_loops, min(len(found_loops), 5)): ## drill along at most 5 loops tri, angle = taut.isosig_to_tri_angle(sig) branch = branched_surface.upper_branched_surface(tri, angle) tri_loop = flow_cycles.flow_cycle_to_triangle_loop(tri, branch, loop) if tri_loop != False: if not flow_cycles.tri_loop_is_boundary_parallel(tri_loop, tri): drill.drill(tri, tri_loop, angle = angle, branch = branch, sig = sig) assert branched_surface.has_non_sing_semiflow(tri, branch), sig print("all basic tests passed") try: import snappy import snappy_util snappy_working = True except: print("failed to import from snappy?") snappy_working = False if snappy_working: print("testing algebraic intersection") census = snappy.OrientableCuspedCensus() # not a set or list, so can't use random.sample for i in range(10): M = random.choice(census) n = M.num_cusps() peripheral_curves = M.gluing_equations()[-2*n:] for i in range(2*n): for j in range(i, 2*n): alg_int = snappy_util.algebraic_intersection(peripheral_curves[i], peripheral_curves[j]) if i % 2 == 0 and j == i + 1: assert alg_int == 1, M.name() else: assert alg_int == 0, M.name() if snappy_working: import veering_drill_midsurface_bdy print("testing veering drilling and filling") for sig in random.sample(veering_isosigs[:3000], num_to_check): T, per = veering_drill_midsurface_bdy.drill_midsurface_bdy(sig) M = snappy.Manifold(T.snapPea()) M.set_peripheral_curves("shortest") L = snappy_util.get_slopes_from_peripherals(M, per) M.dehn_fill(L) N = snappy.Manifold(sig.split("_")[0]) assert M.is_isometric_to(N), sig if snappy_working: print("all tests depending on snappy passed") # try: # from hashlib import md5 # from os import remove # import pyx # from boundary_triangulation import draw_triangulation_boundary_from_veering_isosig # pyx_working = True # except: # print("failed to import from pyx?") # pyx_working = False # ladders_style_sigs = { # "cPcbbbiht_12": "f34c1fdf65db9d02994752814803ae01", # "gLLAQbecdfffhhnkqnc_120012": "091c85b4f4877276bfd8a955b769b496", # "kLALPPzkcbbegfhgijjhhrwaaxnxxn_1221100101": "a0f15a8454f715f492c74ce1073a13a4", # } # geometric_style_sigs = { # "cPcbbbiht_12": "1e74d0b68160c4922e85a5adb20a0f1d", # "gLLAQbecdfffhhnkqnc_120012": "856a1fce74eb64f519bcda083303bd8f", # "kLALPPzkcbbegfhgijjhhrwaaxnxxn_1221100101": "33bd23b34c5d977a103fa50ffe63120a", # } # args = { # "draw_boundary_triangulation":True, # "draw_triangles_near_poles": False, # "ct_depth":-1, # "ct_epsilon":0.03, # "global_drawing_scale": 4, # "delta": 0.2, # "ladder_width": 10.0, # "ladder_height": 20.0, # "draw_labels": True, # } # shapes_data = read_from_pickle("Data/veering_shapes_up_to_ten_tetrahedra.pkl") # if pyx_working: # for sig in ladders_style_sigs: # print("testing boundary triangulation pictures, ladder style", sig) # args["tet_shapes"] = shapes_data[sig] # args["style"] = "ladders" # file_name = draw_triangulation_boundary_from_veering_isosig(sig, args = args) # f = open(file_name, "rb") # file_hash = md5(f.read()) # assert file_hash.hexdigest() == ladders_style_sigs[sig] # f.close() # remove(file_name) # if pyx_working: # for sig in geometric_style_sigs: # print("testing boundary triangulation pictures, ladder style", sig) # args["tet_shapes"] = shapes_data[sig] # args["style"] = "geometric" # file_name = draw_triangulation_boundary_from_veering_isosig(sig, args = args) # f = open(file_name, "rb") # file_hash = md5(f.read()) # assert file_hash.hexdigest() == geometric_style_sigs[sig] # f.close() # remove(file_name) # if pyx_working: # print("all tests depending on pyx passed") veering_polys = { "cPcbbbiht_12": [-4, -1, 1, 4], "eLMkbcddddedde_2100": [-2, -2, -2, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 2, 2], "gLLAQbecdfffhhnkqnc_120012": [-1, -1, -1, -1, 1, 1, 1, 1], "gLLPQcdfefefuoaaauo_022110": [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1], } # veering_polys = { ### old # "cPcbbbiht_12": "a^3 - 4*a^2 + 4*a - 1", # "eLMkbcddddedde_2100": "a^6*b - a^6 - 2*a^5*b - a^4*b^2 + a^5 + 2*a^4*b + a^3*b^2 - 2*a^3*b + a^3 + 2*a^2*b + a*b^2 - a^2 - 2*a*b - b^2 + b", # "gLLAQbecdfffhhnkqnc_120012": "a^7 + a^6 + a^5 + a^4 - a^3 - a^2 - a - 1", # "gLLPQcdfefefuoaaauo_022110": "a^12*b^3 - a^11*b^2 - a^10*b^3 - a^10*b^2 - a^7*b^3 - a^7*b^2 - a^6*b^3 + a^7*b + a^5*b^2 - a^6 - a^5*b - a^5 - a^2*b - a^2 - a*b + 1", # } taut_polys = { "cPcbbbiht_12": [-3, 1, 1], "eLMkbcddddedde_2100": [-1, -1, -1, 1, 1], "iLLAwQcccedfghhhlnhcqeesr_12001122": [], } # taut_polys = { ### old # "cPcbbbiht_12": "a^2 - 3*a + 1", # "eLMkbcddddedde_2100": "a^2*b - a^2 - a*b - b^2 + b", # "iLLAwQcccedfghhhlnhcqeesr_12001122": "0", # } torus_bundles = [ "cPcbbbiht_12", "eLMkbcdddhhqqa_1220", "gLMzQbcdefffhhqqqdl_122002", ] measured = [ "gLLAQbecdfffhhnkqnc_120012", "iLLALQcccedhgghhlnxkxrkaa_12001112", "iLLAwQcccedfghhhlnhcqeesr_12001122", ] empties = [ "fLAMcaccdeejsnaxk_20010", "gLALQbcbeeffhhwsras_211220", "hLALAkbcbeefgghhwsraqj_2112202", ] try: from sage.rings.integer_ring import ZZ sage_working = True except: print("failed to import from sage?") sage_working = False if sage_working: import taut_polytope print("testing is_layered") for sig in veering_isosigs[:17]: assert taut_polytope.is_layered(sig), sig for sig in veering_isosigs[17:21]: assert not taut_polytope.is_layered(sig), sig if sage_working: import fibered print("testing is_fibered") mflds = parse_data_file("Data/mflds_which_fiber.txt") mflds = [line.split("\t")[0:2] for line in mflds] for (name, kind) in random.sample(mflds, num_to_check): assert fibered.is_fibered(name) == (kind == "fibered"), name if sage_working: import veering_polynomial import taut_polynomial print("testing veering poly") for sig in veering_polys: p = veering_polynomial.veering_polynomial(sig) assert check_polynomial_coefficients(p, veering_polys[sig]), sig ### Nov 2021: sage 9.4 changed how smith normal form works, which changed our polynomials ### to equivalent but not equal polynomials. To avoid this kind of change breaking things ### in the future, we changed to comparing the list of coefficients. # assert p.__repr__() == veering_polys[sig] print("testing taut poly") for sig in taut_polys: p = taut_polynomial.taut_polynomial_via_tree(sig) assert check_polynomial_coefficients(p, taut_polys[sig]), sig # assert p.__repr__() == taut_polys[sig] print("testing divide") for sig in random.sample(veering_isosigs[:3000], num_to_check): p = veering_polynomial.veering_polynomial(sig) q = taut_polynomial.taut_polynomial_via_tree(sig) if q == 0: assert p == 0, sig else: assert q.divides(p), sig if sage_working: print("testing alex") for sig in random.sample(veering_isosigs[:3000], num_to_check): snap_sig = sig.split("_")[0] M = snappy.Manifold(snap_sig) if M.homology().betti_number() == 1: assert taut_polynomial.taut_polynomial_via_tree(sig, mode = "alexander") == M.alexander_polynomial(), sig if sage_working: # would be nice to automate this - need to fetch the angle # structure say via z_charge.py... print("testing is_torus_bundle") for sig in torus_bundles: assert taut_polytope.is_torus_bundle(sig), sig if sage_working: # ditto print("testing is_layered") for sig in torus_bundles: assert taut_polytope.is_layered(sig), sig print("testing measured") for sig in measured: assert taut_polytope.LMN_tri_angle(sig) == "M", sig print("testing empty") for sig in empties: assert taut_polytope.LMN_tri_angle(sig) == "N", sig if sage_working: # warning - this takes random amounts of time! print("testing hom dim") for sig in random.sample(veering_isosigs[:3000], 3): # magic number # dimension = zero if and only if nothing is carried. assert (taut_polytope.taut_cone_homological_dim(sig) == 0) == (taut_polytope.LMN_tri_angle(sig) == "N"), sig if sage_working: boundary_cycles = { ("eLMkbcddddedde_2100",(2,5,5,1,3,4,7,1)): "((-7, -7, 0, 0, 4, -3, 7, 0), (7, 7, 0, 0, -4, 3, -7, 0))", ("iLLLQPcbeegefhhhhhhahahha_01110221",(0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,0)): "((0, 0, -1, 1, 1, 0, 1, 1, -1, 0, 0, 0, 0, 1, 0, 1), (0, 0, 1, -1, -1, 0, -1, -1, 1, 0, 0, 0, 0, -1, 0, -1))", ("ivvPQQcfhghgfghfaaaaaaaaa_01122000",(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)): "((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2), (1, 1, 0, 2, -1, 0, -3, 1, 2, -1, -2, 0, 3, -2, -1, 0), (-2, 0, -3, 1, 2, -1, 0, 2, -1, 0, 3, 1, -2, 1, 0, -1), (0, -2, 1, -3, 0, -1, 2, 0, -1, 2, -1, 1, 0, 1, -2, 3))", } taut_polys_with_cycles = { ("eLMkbcddddedde_2100", ((7, 7, 0, 0, -4, 3, -7, 0),)): [-1, -1, -1, 1, 1], ("iLLLQPcbeegefhhhhhhahahha_01110221", ((0, 0, 1, -1, -1, 0, -1, -1, 1, 0, 0, 0, 0, -1, 0, -1),)): [1, 1, 2], ("ivvPQQcfhghgfghfaaaaaaaaa_01122000", ((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2), (1, 1, 0, 2, -1, 0, -3, 1, 2, -1, -2, 0, 3, -2, -1, 0))): [-4, -1, -1, 1, 1], } # taut_polys_with_cycles = { # ("eLMkbcddddedde_2100", ((7, 7, 0, 0, -4, 3, -7, 0),)): "a^14 - a^8 - a^7 - a^6 + 1", # ("iLLLQPcbeegefhhhhhhahahha_01110221", ((0, 0, 1, -1, -1, 0, -1, -1, 1, 0, 0, 0, 0, -1, 0, -1),)): "a^2 + 2*a + 1", # ("ivvPQQcfhghgfghfaaaaaaaaa_01122000", ((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2), (1, 1, 0, 2, -1, 0, -3, 1, 2, -1, -2, 0, 3, -2, -1, 0))): "a*b^2 - a^2 - 4*a*b - b^2 + a", # } taut_polys_image = { ('eLMkbcddddedde_2100', ((7, 8, -1, 0, -4, 4, -8, 0),)):[-1, -1, -1, 1, 1], ('ivvPQQcfhghgfghfaaaaaaaaa_01122000', ((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2),)):[-2, -2, -1, -1, 1, 1], ('ivvPQQcfhghgfghfaaaaaaaaa_01122000', ((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2), (1, 1, 0, 2, -1, 0, -3, 1, 2, -1, -2, 0, 3, -2, -1, 0))):[-4, -1, -1, 1, 1] } # taut_polys_image = { # ('eLMkbcddddedde_2100', ((7, 8, -1, 0, -4, 4, -8, 0),)):"a^16 - a^9 - a^8 - a^7 + 1", # ('ivvPQQcfhghgfghfaaaaaaaaa_01122000', ((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2),)):"a*b^2*c - 2*a*b*c - b^2*c - a^2 - 2*a*b + a", # ('ivvPQQcfhghgfghfaaaaaaaaa_01122000', ((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2), (1, 1, 0, 2, -1, 0, -3, 1, 2, -1, -2, 0, 3, -2, -1, 0))):"a*b^2 - a^2 - 4*a*b - b^2 + a" # } alex_polys_with_cycles = { ("eLMkbcddddedde_2100",((7, 7, 0, 0, -4, 3, -7, 0),)): [-2, -1, -1, -1, 1, 1, 1, 2], ("iLLLQPcbeegefhhhhhhahahha_01110221", ((0, 0, 1, -1, -1, 0, -1, -1, 1, 0, 0, 0, 0, -1, 0, -1),)): [-3, -1, 1, 3], ("ivvPQQcfhghgfghfaaaaaaaaa_01122000", ((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2), (1, 1, 0, 2, -1, 0, -3, 1, 2, -1, -2, 0, 3, -2, -1, 0))): [-1, -1, 1, 1], } # alex_polys_with_cycles = { # ("eLMkbcddddedde_2100",((7, 7, 0, 0, -4, 3, -7, 0),)): "a^15 - a^14 + a^9 - 2*a^8 + 2*a^7 - a^6 + a - 1", # ("iLLLQPcbeegefhhhhhhahahha_01110221", ((0, 0, 1, -1, -1, 0, -1, -1, 1, 0, 0, 0, 0, -1, 0, -1),)): "3*a^3 - a^2 + a - 3", # ("ivvPQQcfhghgfghfaaaaaaaaa_01122000", ((1, 1, 2, 0, -1, 2, 1, -3, 0, -1, 0, -2, -1, 0, 3, -2), (1, 1, 0, 2, -1, 0, -3, 1, 2, -1, -2, 0, 3, -2, -1, 0))): "a*b^2 - a^2 - b^2 + a", # } if sage_working: import taut_carried print("testing boundary cycles") for sig, surface in boundary_cycles: surface_list = list(surface) cycles = taut_carried.boundary_cycles_from_surface(sig, surface_list) cycles = tuple(tuple(cycle) for cycle in cycles) assert cycles.__repr__() == boundary_cycles[(sig, surface)], sig if sage_working: print("testing taut with cycles") for sig, cycles in taut_polys_with_cycles: cycles_in = [list(cycle) for cycle in cycles] p = taut_polynomial.taut_polynomial_via_tree(sig, cycles_in) assert check_polynomial_coefficients(p, taut_polys_with_cycles[(sig, cycles)]), sig # assert p.__repr__() == taut_polys_with_cycles[(sig, cycles)] if sage_working: print("testing taut with images") for sig, cycles in taut_polys_image: cycles_in = [list(cycle) for cycle in cycles] p = taut_polynomial.taut_polynomial_image(sig, cycles_in) assert check_polynomial_coefficients(p, taut_polys_image[(sig, cycles)]), sig # assert p.__repr__() == taut_polys_image[(sig, cycles)] if sage_working: print("testing alex with cycles") for sig, cycles in alex_polys_with_cycles: cycles_in = [list(cycle) for cycle in cycles] p = taut_polynomial.taut_polynomial_via_tree(sig, cycles_in, mode = "alexander") assert check_polynomial_coefficients(p, alex_polys_with_cycles[(sig, cycles)]), sig # assert p.__repr__() == alex_polys_with_cycles[(sig, cycles)] if sage_working: import edge_orientability import taut_euler_class print("testing euler and edge orientability") for sig in random.sample(veering_isosigs[:3000], 3): # Theorem: If (tri, angle) is edge orientable then e = 0. assert not ( edge_orientability.is_edge_orientable(sig) and (taut_euler_class.order_of_euler_class_wrapper(sig) == 2) ), sig if sage_working: # Theorem: If (tri, angle) is edge orientable then taut poly = alex poly. # taut_polynomial.taut_polynomial_via_tree(sig, mode = "alexander") == # taut_polynomial.taut_polynomial_via_tree(sig, mode = "taut") pass if sage_working: print("testing exotics") for sig in random.sample(veering_isosigs[:3000], 3): tri, angle = taut.isosig_to_tri_angle(sig) T = veering.veering_triangulation(tri, angle) is_eo = T.is_edge_orientable() for angle in T.exotic_angles(): assert taut_polytope.taut_cone_homological_dim(tri, angle) == 0, sig assert is_eo == transverse_taut.is_transverse_taut(tri, angle), sig ### test for drill_midsurface_bdy: drill then fill, check you get the same manifold if sage_working: from sage.combinat.words.word_generators import words from sage.modules.free_module_integer import IntegerLattice from sage.modules.free_module import VectorSpace from sage.matrix.constructor import Matrix import z_charge import z2_taut import regina ZZ2 = ZZ.quotient(ZZ(2)) sig_starts = ["b+-LR", "b++LR"] print("testing lattice for punc torus bundle") for i in range(3): for sig_start in sig_starts: sig = sig_start + str(words.RandomWord(8, 2, "LR")) # 8 is a magic number M = snappy.Manifold(sig) tri = regina.Triangulation3(M) t, A = z_charge.sol_and_kernel(M) B = z_charge.leading_trailing_deformations(M) C = z2_taut.cohomology_loops(tri) AA = IntegerLattice(A) BB = IntegerLattice(B) assert AA == BB.saturation(), sig dim = 3*M.num_tetrahedra() V = VectorSpace(ZZ2, dim) AA = V.subspace(A) BB = V.subspace(B) CM = Matrix(ZZ2, C) CC = CM.right_kernel() assert AA.intersection(CC) == BB , sig ## so l-t defms are the part of the kernel that doesn't flip over if sage_working: print("testing charges for punc torus bundle") for i in range(3): for sig_start in sig_starts: sig = sig_start + str(words.RandomWord(8, 2, "LR")) # 8 is a magic number M = snappy.Manifold(sig) assert z_charge.can_deal_with_reduced_angles(M), sig if sage_working: import carried_surface import mutation print("testing building carried surfaces and mutations") sigs_weights = [ ['iLLLPQccdgefhhghqrqqssvof_02221000', (0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0)], ['jLLAvQQcedehihiihiinasmkutn_011220000', (2, 0, 1, 0, 0, 0, 1, 2, 0, 2, 0, 2, 1, 0, 0, 0, 1, 0)], ['jLLAvQQcedehihiihiinasmkutn_011220000', (0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)], ['jLLLMPQcdgfhfhiiihshassspiq_122201101', (0, 0, 4, 0, 4, 1, 0, 2, 2, 0, 1, 0, 0, 4, 0, 4, 0, 0)] ] strata = [ ((1, 2), [2, 2]), ((2, 4), [5, 5, 1, 1]), ((0, 3), [2, 0, 0]), ((6, 1), [22]) ] orders_of_veering_symmetry_groups = [4, 2, 2, 2] for i in range(len(sigs_weights)): tri, angle = taut.isosig_to_tri_angle(sigs_weights[i][0]) weights = sigs_weights[i][1] surface, edge_colours = carried_surface.build_surface(tri, angle, weights, return_edge_colours = True) assert strata[i] == carried_surface.stratum_from_weights_surface(weights, surface) veering_isoms = carried_surface.veering_symmetry_group(surface, edge_colours) assert len(veering_isoms) == orders_of_veering_symmetry_groups[i] isom = veering_isoms[1] mutation.mutate(tri, angle, weights, isom, quiet = True) if i == 0: assert tri.isoSig() == 'ivLLQQccfhfeghghwadiwadrv' #print('svof to wadrv passed') elif i == 1: assert tri.isoSig() == 'jvLLAQQdfghhfgiiijttmtltrcr' #print('smkutn to tltrcr passed') elif i == 2: assert tri.isoSig() == 'jLLMvQQcedehhiiihiikiwnmtxk' #print('smkutn to mtxk passed') elif i == 3: assert tri.isoSig() == 'jLLALMQcecdhggiiihqrwqwrafo' #print('spiq to rafo passed') if sage_working: print("all tests depending on sage passed")
def getTriang(self): # return regina.Triangulation3(self.isoSig) return isosig_to_tri_angle(self.isoSig)
def main(): depth = 100 # ceiling = 10 extra_ceiling = 5 ### above how many tetrahedra we start with # print('depth', depth) # print('ceiling', ceiling) # # sig = 'cPcbbbdxm_10' # # sig = 'dLQacccjsnk_200' # # sig = 'dLQbccchhfo_122' # sig = 'eLAkbccddhhsqs_1220' # tri, angle = isosig_to_tri_angle(sig) # branch = upper_branched_surface(tri, angle) # # tl = flow_cycle_to_triangle_loop(tri, branch, [(0, 2)]) # # drilled_cusp_index = drill(tri, tl, angle = angle, branch = branch) # # print('angle', angle, 'branch', branch, 'drilled_cusp_index', drilled_cusp_index) # # # assert has_non_sing_semiflow(tri, branch) # # # start veering: cPcbbbdxm_10_dl loop [(0, 2)] tri_loop [(2, 102)] # # # drill: eLMkbbddddhapu_2100_fjek # # start_isoSig = isosig_from_tri_angle_branch(tri, angle, branch) # # assert start_isoSig == 'eLMkbbddddhapu_2100_fjek' # # tri, angle, branch = isosig_to_tri_angle_branch(start_isoSig) ### fails?? # # graph = search_Pachner_graph_for_shortest_path(start_isoSig, tri, angle, branch, name=None, search_depth = depth, ceiling = ceiling, drilled_cusp_index = drilled_cusp_index, check_property = False, property = None, save_dir = None) # loops = find_flow_cycles(tri, branch) # tri_loops = [flow_cycle_to_triangle_loop(tri, branch, loop) for loop in loops] # for i, tri_loop in enumerate(tri_loops): # if tri_loop != False: # False means that tri_loop goes more than once along the same triangle - not currently implemented # tri, angle = isosig_to_tri_angle(sig) # if tri_loop_is_boundary_parallel(tri_loop, tri) == False: # if a loop is boundary parallel then we don't drill # branch = upper_branched_surface(tri, angle) # drilled_cusp_index = drill(tri, tri_loop, angle = angle, branch = branch) # print('loop', loops[i], 'tri_loop', tri_loop, 'has_essential_torus', has_essential_torus(tri)) # # start_isoSig = isosig_from_tri_angle_branch(tri, angle, branch) # # print(start_isoSig, 'angle', angle, 'branch', branch, 'drilled_cusp_index', drilled_cusp_index) # # graph = search_Pachner_graph_for_shortest_path(start_isoSig, tri, angle, branch, name=None, search_depth = depth, ceiling = ceiling, drilled_cusp_index = drilled_cusp_index, check_property = False, property = None, save_dir = None) sigs = parse_data_file('Data/veering_census.txt') for j, sig in enumerate(sigs[:5]): if j % 100 == 0: print(j) tri, angle = isosig_to_tri_angle(sig) branch = upper_branched_surface(tri, angle) loops = find_flow_cycles(tri, branch) tri_loops = [ flow_cycle_to_triangle_loop(tri, branch, loop) for loop in loops ] for i, tri_loop in enumerate(tri_loops): if tri_loop != False: # False means that tri_loop goes more than once along the same triangle - not currently implemented tri, angle = isosig_to_tri_angle(sig) if tri_loop_is_boundary_parallel( tri_loop, tri ) == False: # if a loop is boundary parallel then we don't drill branch = upper_branched_surface(tri, angle) drilled_cusp_index = drill(tri, tri_loop, angle=angle, branch=branch) if has_essential_torus(tri): print('sig', sig, 'has_essential_torus', has_essential_torus(tri), 'loop', loops[i], 'tri_loop', tri_loop) else: print('sig', sig, 'has_essential_torus', has_essential_torus(tri), 'loop', loops[i], 'tri_loop', tri_loop) ceiling = tri.countTetrahedra() + extra_ceiling print('ceiling', ceiling) start_isoSig = isosig_from_tri_angle_branch( tri, angle, branch) print(start_isoSig, 'angle', angle, 'branch', branch, 'drilled_cusp_index', drilled_cusp_index) graph = search_Pachner_graph_for_shortest_path( start_isoSig, tri, angle, branch, name=None, search_depth=depth, ceiling=ceiling, drilled_cusp_index=drilled_cusp_index, check_property=False, property=None, save_dir=None)
def find_tri_loops(sig): tri, angle = isosig_to_tri_angle(sig) branch = upper_branched_surface(tri, angle) loops = find_flow_cycles(tri, branch) return [flow_cycle_to_triangle_loop(tri, branch, loop) for loop in loops]
@liberal def non_tree_edge_cycles(tri, angle): """ Returns the (dual) one-cycles associated to the non-tree edges. In other words: Suppose that T is the dual spanning tree. Then, for every non-tree edge e, we return a vector of length 2*n (num faces) with entries from {-1, 0, +1}, which tells us how the transverse orientation (angle) agrees or disagrees with the unique oriented loop in T union e. """ cycles = [] oriented_loops, all_signs = non_tree_edge_loops_oriented(tri, angle) n = tri.countTetrahedra() for loop, signs in zip(oriented_loops, all_signs): cycle = [0] * 2 * n for face, sign in zip(loop, signs): cycle[face] = sign cycles.append(cycle) return cycles if __name__ == '__main__': from taut import isosig_to_tri_angle tri, angle = isosig_to_tri_angle('gLLAQbecdfffhhnkqnc_120012') loops = non_tree_edge_loops(tri, include_tetrahedra=True) for (faces, tets) in loops: print('faces', faces) print('tets', [t.index() for t in tets])
def make_continent_drill_flow_cycle(veering_isosig, flow_cycle, num_steps): tri, angle = isosig_to_tri_angle(veering_isosig) vt = veering_triangulation(tri, angle) #, tet_shapes = tet_shapes) ### format for loops: it is a list of tuples, ### each tuple is (tet_index, edge_index within this tet that we exit through) tet_0 = flow_cycle[0][0] face_0 = 0 ### only used for initial numbering of vertices of the continent, so who cares initial_tet_face = tet_face(vt, tet_0, face_0, verts_pos=[None, None, None, None]) con = continent(vt, initial_tet_face) side_face_collections, side_tet_collections = edge_side_face_collections( vt.tri, vt.angle, tet_vert_coorientations=vt.coorientations, return_tets=True, order_bottom_to_top=False) # print('sfc', side_face_collections) # print('stc', side_tet_collections) ### identify the next edge in the cycle init_tetrahedron = con.tetrahedra[0] init_edge = flow_edge_in_continent(init_tetrahedron, flow_cycle[0][1]) flow_tetrahedra = [init_tetrahedron] flow_edges = [init_edge] ### both in the continent upwards_flow_index = 0 downwards_flow_index = 0 for i in range(num_steps): # print(i) if i % 2 == 0: ### go up edge = flow_edges[-1] last_tet = None while True: con.update_boundary() upper_boundary_triangles = [ t for t in edge.boundary_triangles if t.is_upper ] if len(upper_boundary_triangles) == 0: break ## out of while loop last_tet = con.bury(upper_boundary_triangles[0]) assert last_tet != None upwards_flow_index = (upwards_flow_index + 1) % len(flow_cycle) assert last_tet.index == flow_cycle[upwards_flow_index][0] flow_tetrahedra.append(last_tet) flow_edges.append( flow_edge_in_continent(last_tet, flow_cycle[upwards_flow_index][1])) con.make_convex( ) ### could this take us further up dual_cycle? We don't think so else: ### go down tet = flow_tetrahedra[0] edge = tet.lower_edge() flow_edges = [edge] + flow_edges ### now build the continent to get new_lowest_tet manifold_edge = tri.edge(edge.index) downwards_flow_index = (downwards_flow_index - 1) % len(flow_cycle) ### is the flow cycle vertical through the tetrahedron? tet_below = get_tet_above_edge( vt.tri, vt.angle, manifold_edge, tet_vert_coorientations=vt.coorientations, get_tet_below_edge=True) tet_below_num = tet_below.index() top_vert_nums = get_tet_top_vert_nums(vt.coorientations, tet_below_num) top_edge_num = vert_pair_to_edge_num[tuple(top_vert_nums)] if (tet_below_num, top_edge_num) == flow_cycle[ downwards_flow_index]: ### flow cycle went straight up while True: con.update_boundary() lower_boundary_triangles = [ t for t in edge.boundary_triangles if not t.is_upper ] if len(lower_boundary_triangles) == 0: break ## out of while loop last_tet = con.bury(lower_boundary_triangles[0]) else: ### find which side of the edge our tet is in # print('edge index', edge.index) side_tet_collections_at_edge = side_tet_collections[ edge.index] ## index in the manifold side_face_collections_at_edge = side_face_collections[ edge.index] downward_path = None flow_step = flow_cycle[downwards_flow_index] for i, side_tet_collection in enumerate( side_tet_collections_at_edge): if flow_step in side_tet_collection: downward_path = side_tet_collection[: side_tet_collection .index(flow_step) + 1] downward_path_faces = side_face_collections_at_edge[ i][:side_tet_collection.index(flow_step) + 1] assert downward_path != None for j, (tet_num, edge_num) in enumerate(downward_path): con.update_boundary() lower_boundary_triangles = [ t for t in edge.boundary_triangles if not t.is_upper and t.index == downward_path_faces[j][0] ] assert len(lower_boundary_triangles) == 1 last_tet = con.bury(lower_boundary_triangles[0]) assert last_tet != None flow_tetrahedra = [last_tet] + flow_tetrahedra con.make_convex( ) ### could this take us further down dual_cycle? We don't think so con.update_boundary() return con, flow_tetrahedra, flow_edges
def make_continent_drill_dual_cycle(veering_isosig, dual_cycle, num_steps): tri, angle = isosig_to_tri_angle(veering_isosig) vt = veering_triangulation(tri, angle) #, tet_shapes = tet_shapes) ### initial tetrahedron is above face 0 of the dual cycle face0 = vt.tri.triangles()[dual_cycle[0]] embeds = face0.embeddings() tet_0, face_0 = None, None for embed in embeds: tet_num = embed.simplex().index() face_num = embed.face() if vt.coorientations[tet_num][face_num] == -1: ## into the tet tet_0, face_0 = tet_num, face_num break assert tet_0 != None and face_0 != None initial_tet_face = tet_face(vt, tet_0, face_0, verts_pos=[None, None, None, None]) con = continent(vt, initial_tet_face) ### identify the triangle corresponding to dual_cycle[1] for triangle in con.triangles: if not triangle.is_upper and triangle.index == dual_cycle[0]: lowest_triangle = triangle if triangle.is_upper and triangle.index == dual_cycle[1]: highest_triangle = triangle triangle_path = [lowest_triangle, highest_triangle] lowest_path_index = 0 highest_path_index = 1 # for i in range(num_steps): # last_added_tet = con.bury(highest_triangle) # ### find next_triangle # highest_triangle = None # for triangle in last_added_tet.upper_triangles: # if triangle.index == dual_cycle[(path_index + 1) % len(dual_cycle)]: # highest_triangle = triangle # break # assert highest_triangle != None # triangle_path.append(highest_triangle) # path_index = path_index + 1 # con.make_convex() ### could this take us further up dual_cycle? for i in range(num_steps): if i % 2 == 0: last_added_tet = con.bury(triangle_path[-1]) ## go up for triangle in last_added_tet.upper_triangles: if triangle.index == dual_cycle[(highest_path_index + 1) % len(dual_cycle)]: triangle_path.append(triangle) break highest_path_index = highest_path_index + 1 else: last_added_tet = con.bury(triangle_path[0]) ## go down for triangle in last_added_tet.lower_triangles: if triangle.index == dual_cycle[(lowest_path_index - 1) % len(dual_cycle)]: triangle_path.insert(0, triangle) break lowest_path_index = lowest_path_index - 1 con.make_convex() ### could this take us further up dual_cycle? con.update_boundary() con.triangle_path = triangle_path return con
return out def explore_mobius_surgery_graph(tri, angle, max_tetrahedra=4): # apply veering mobius dehn surgery recursively out = [] frontier = [(tri, angle, face_num) for face_num in get_mobius_strip_indices(tri)] while len(frontier) > 0: tri, angle, face_num = frontier.pop() tri_s, angle_s, face_num_s = veering_mobius_dehn_surgery( tri, angle, face_num) new_isosig = isosig_from_tri_angle(tri_s, angle_s) if new_isosig not in out: out.append(new_isosig) if tri_s.countTetrahedra() < max_tetrahedra: frontier.extend([ (tri_s, angle_s, face_num) for face_num in get_mobius_strip_indices(tri_s) ]) out.sort() return out if __name__ == "__main__": tri, angle = isosig_to_tri_angle("cPcbbbdxm_10") out = explore_mobius_surgery_graph(tri, angle, max_tetrahedra=6) for sig in out: print(sig)
if __name__ == '__main__': # tet_shapes = [complex(0.5,math.sqrt(3)*0.5), complex(0.5,math.sqrt(3)*0.5)] # tri, angle = isosig_to_tri_angle('cPcbbbiht_12') # tet_shapes = [(0.9231422157742049+0.9853733543905342j), (-0.29947574053100134+0.44832432157891566j), (0.07867777692993604+1.0087070002132608j), (0.07867777692993473+1.0087070002132614j), (0.7378949835259692+0.13340505745111064j), (-0.29947574053100123+0.4483243215789155j)] # tri, angle = isosig_to_tri_angle('gLLAQbecdfffhhnkqnc_120012') # make_cannon_thurston(tri, angle, tet_shapes, max_depth = 30, epsilon = 0.02) data = read_from_pickle('Data/veering_shapes_up_to_ten_tetrahedra.pkl') names = list(data.keys()) names.sort() # for name in names: name = 'gLLAQbecdfffhhnkqnc_120012' # name = names[1] print(name) tri, angle = isosig_to_tri_angle(name) tet_shapes = data[name] # print 'tet_shapes', tet_shapes # make_cannon_thurston(tri, angle, tet_shapes, name = 'Cannon-Thurston_images/' + name, max_depth = 25, epsilon = 0.05, verbose = 0.0) # sideways = initial_path_sideways(tri, angle, tet_shapes) # draw_path(sideways, name = name + '_sideways', verbose = 0.0) # make_cannon_thurston(tri, angle, tet_shapes, init_function = initial_path_sideways, name = name + '_sideways', max_depth = 0, epsilon = 0.05, verbose = 5.0) # make_cannon_thurston(tri, angle, tet_shapes, name = name, max_depth = 5, epsilon = 0.05, verbose = 5.0) # make_cannon_thurston(tri, angle, tet_shapes, init_function = initial_path_one_ladderpole, name = name + '_one_ladderpole', max_depth = 25, epsilon = 0.005, lw = 0.002, verbose = 0.0) make_cannon_thurston(tri, angle, tet_shapes, init_function=initial_path_up_ladderpole, name='Images/Cannon-Thurston/' + name +