def generate_neighbour_isoSigs(self, ceiling, floor):
        # tri, angle = self.getTriang()
        tri, angle, branch = self.tri, self.angle, self.branch
        num_tetrahedra = tri.countTetrahedra()
        assert num_tetrahedra <= ceiling
        assert num_tetrahedra >= floor

        if num_tetrahedra < ceiling:
            for face_index in range(tri.countTriangles()):
                # print('face_index', face_index)
                tri_copy = regina.Triangulation3(tri)
                angle_copy = angle[:]
                output_taut = taut_pachner.twoThreeMove(
                    tri_copy, angle_copy, face_index)
                # print('output_taut', output_taut)
                tri_copy2 = regina.Triangulation3(tri)
                branch_copy = branch[:]
                output_branch = branched_pachner.twoThreeMove(
                    tri_copy2, branch_copy, face_index)
                # print('output_branch', output_branch)
                if output_taut != False and output_branch != False:
                    tri_new, angle_new = output_taut
                    _, branch_new_list = output_branch
                    for branch_new in branch_new_list:
                        new_isosig = isosig_from_tri_angle_branch(
                            tri_new, angle_new, branch_new)
                        # print('new_isosig', new_isosig)
                        self.neighbour_moves_up_faces[new_isosig] = 'f' + str(
                            face_index)
                        self.neighbour_moves_up_tri_angle_branches[
                            new_isosig] = (tri_new, angle_new, branch_new)

        if num_tetrahedra > floor:
            # print('now do threeTwoMove')
            for edge_index in range(tri.countEdges()):
                # print('edge_index', edge_index)
                tri_copy = regina.Triangulation3(tri)
                angle_copy = angle[:]
                output_taut = taut_pachner.threeTwoMove(
                    tri_copy, angle_copy, edge_index)
                # print('output_taut', output_taut)
                tri_copy2 = regina.Triangulation3(tri)
                branch_copy = branch[:]
                output_branch = branched_pachner.threeTwoMove(
                    tri_copy2, branch_copy, edge_index)
                # print('output_branch', output_branch)
                if output_taut != False and output_branch != False:
                    tri_new, angle_new = output_taut
                    _, branch_new = output_branch
                    new_isosig = isosig_from_tri_angle_branch(
                        tri_new, angle_new, branch_new)
                    # print('new_isosig', new_isosig)
                    self.neighbour_moves_down_edges[new_isosig] = 'e' + str(
                        edge_index)
                    self.neighbour_moves_down_tri_angle_branches[
                        new_isosig] = (tri_new, angle_new, branch_new)
        self.neighbour_moves_tri_angle_branches = {
            **self.neighbour_moves_up_tri_angle_branches,
            **self.neighbour_moves_down_tri_angle_branches
        }  ## union of the dictionaries
Example #2
0
def find_veering_after_drilling(tri,
                                angle,
                                tri_loop,
                                extra_ceiling=4,
                                depth=100):
    branch = upper_branched_surface(tri, angle)

    if tri_loop_is_boundary_parallel(
            tri_loop,
            tri):  # if a loop is boundary parallel then we don't drill
        print('loop is boundary parallel')
    else:
        drilled_cusp_index = drill(tri, tri_loop, angle=angle, branch=branch)
        if has_essential_torus(tri):
            print('sig', tri.isoSig(), 'has_essential_torus')
        else:
            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)
Example #3
0
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():
    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)
Example #5
0
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")
Example #6
0
    def generate_neighbour_isoSigs(self, ceiling, floor):
        # tri, angle = self.getTriang()
        tri, angle, branch = self.tri, self.angle, self.branch
        num_tetrahedra = tri.countTetrahedra()
        assert num_tetrahedra <= ceiling
        assert num_tetrahedra >= floor

        if num_tetrahedra < ceiling:
            for face_index in range(tri.countTriangles()):
                ### only go this way if it expands the drilled cusp
                face = tri.triangles()[face_index]
                embed0 = face.embedding(0)
                tet0 = embed0.simplex()
                tet_0_face_num = embed0.face()
                embed1 = face.embedding(1)
                tet1 = embed1.simplex()
                tet_1_face_num = embed1.face()
                if (tet0.vertex(tet_0_face_num).index()
                        == self.drilled_cusp_index) or (
                            tet1.vertex(tet_1_face_num).index()
                            == self.drilled_cusp_index):
                    tri_copy = regina.Triangulation3(tri)
                    angle_copy = angle[:]
                    branch_copy = branch[:]
                    output = twoThreeMove(tri_copy,
                                          face_index,
                                          angle=angle_copy,
                                          branch=branch_copy,
                                          return_vertex_perm=True)
                    # print('2-3', face_index, output)
                    if output != False:
                        tri_new, angle_new, branches_new, vertex_perm = output
                        drilled_cusp_index_new = vertex_perm[
                            self.drilled_cusp_index]
                        for branch_new in branches_new:
                            sig_new = isosig_from_tri_angle_branch(
                                tri_new, angle_new, branch_new)
                            self.neighbour_moves_up_faces[sig_new] = 'f' + str(
                                face_index)
                            self.neighbour_moves_up_tri_angle_branch[
                                sig_new] = (tri_new, angle_new, branch_new,
                                            drilled_cusp_index_new)

        if num_tetrahedra > floor:
            for edge_index in range(tri.countEdges()):
                ### only go this way if it expands the drilled cusp
                edge = tri.edges()[edge_index]
                if (edge.vertex(0).index() != self.drilled_cusp_index) and (
                        edge.vertex(1).index() != self.drilled_cusp_index):
                    tri_copy = regina.Triangulation3(tri)
                    angle_copy = angle[:]
                    branch_copy = branch[:]
                    output = threeTwoMove(tri_copy,
                                          edge_index,
                                          angle=angle_copy,
                                          branch=branch_copy,
                                          return_vertex_perm=True)
                    if output != False:
                        tri_new, angle_new, branch_new, vertex_perm = output
                        drilled_cusp_index_new = vertex_perm[
                            self.drilled_cusp_index]
                        sig_new = isosig_from_tri_angle_branch(
                            tri_new, angle_new, branch_new)
                        self.neighbour_moves_down_edges[sig_new] = 'e' + str(
                            edge_index)
                        self.neighbour_moves_down_tri_angle_branch[sig_new] = (
                            tri_new, angle_new, branch_new,
                            drilled_cusp_index_new)
        self.neighbour_moves_tri_angle_branch = {
            **self.neighbour_moves_up_tri_angle_branch,
            **self.neighbour_moves_down_tri_angle_branch
        }  ## union of the dictionaries
Example #7
0
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)
Example #8
0
def search_Pachner_graph_for_shortest_path(start_isoSig,
                                           tri,
                                           angle,
                                           branch,
                                           name=None,
                                           search_depth=3,
                                           ceiling=5,
                                           drilled_cusp_index=None,
                                           check_property=False,
                                           property=None,
                                           save_dir=None):
    start_node = pachner_node(start_isoSig,
                              tri,
                              angle,
                              branch,
                              drilled_cusp_index=drilled_cusp_index,
                              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...
            # print('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, nb_branch, nb_drilled_cusp_index = current_node.neighbour_moves_tri_angle_branch[
                        nb_isoSig]
                    #print('nb drilled cusp', nb_drilled_cusp_index)
                    new_node = pachner_node(
                        nb_isoSig,
                        nb_tri,
                        nb_angle,
                        nb_branch,
                        drilled_cusp_index=nb_drilled_cusp_index,
                        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(
                            'veering!',
                            isosig_from_tri_angle_branch(
                                nb_tri, nb_angle, nb_branch))
                        upper_branch = upper_branched_surface(
                            nb_tri, nb_angle, return_lower=False)
                        lower_branch = upper_branched_surface(
                            nb_tri, nb_angle, return_lower=True)
                        print(
                            'upper:',
                            isosig_from_tri_angle_branch(
                                nb_tri, nb_angle, upper_branch))
                        print(
                            'lower:',
                            isosig_from_tri_angle_branch(
                                nb_tri, nb_angle, lower_branch))
                        print_path(nb_isoSig, big_dict_of_nodes)
                        ## break
                        return None

        frontier_isoSigs = new_frontier_isoSigs
        # print(len(big_dict_of_nodes), len(frontier_isoSigs))

    print('did not find veering')
    return None