Exemple #1
0
def num_veering_structs(M, angles=None, use_flipper=True):
    """
    Tries to count them (in a very naive way). 
    Tries to eliminate overcounting due to symmetries (in reduced_angles)
    but will fail if one of the symmetries is hidden by retriangulation. 
    If use_flipper = False then we get a (true) lower bound, since then it only
    counts veering structures on the given triangulation.
    """
    if angles == None:
        angles = reduced_angles(M)
    tri = regina.Triangulation3(M)
    for angle in angles:
        if not is_taut(tri, angle):
            return None
    for angle in angles:
        if not (is_veering(tri, angle) or is_layered(tri, angle)):
            return None
    total = 0
    for angle in angles:
        if is_veering(tri, angle):
            total = total + 1
        elif use_flipper:
            assert is_layered(tri, angle)
            print(M.name(), angle, "needs flipper")
            try:
                if not has_internal_singularities(tri, angle):
                    total = total + 1
            except:
                print("flipper failed")
    return total
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
Exemple #3
0
def upper_branched_surface(tri, angle, return_lower=False):
    """Returns the upper branched surface for a veering triangulation"""
    veering_colours = is_veering(tri, angle, return_type="veering_colours")
    tet_vert_coorientations = is_transverse_taut(
        tri, angle, return_type="tet_vert_coorientations")
    assert veering_colours != False and tet_vert_coorientations != False
    branch = []
    for i, a in enumerate(angle):
        assert tet_vert_coorientations[i][0] == tet_vert_coorientations[i][
            a + 1]  ### the other end of the pi edge at 0
        large_edge_num = vert_pair_to_edge_num[(0, a + 1)]
        tiny_edge_num = 5 - large_edge_num
        if (
                tet_vert_coorientations[i][0] == -1
        ) != return_lower:  ### into the tetrahedron through face 0, xor get lower branched surface
            large_edge_num, tiny_edge_num = tiny_edge_num, large_edge_num  # swap
        tiny_edge_colour = veering_colours[tri.tetrahedron(i).edge(
            tiny_edge_num).index()]
        mixed_edge_pair_num = (vert_pair_to_edge_num[(0, a + 1)] +
                               1) % 3  ### can view as an edge num too...
        if veering_colours[tri.tetrahedron(i).edge(
                mixed_edge_pair_num).index()] != tiny_edge_colour:
            mixed_edge_pair_num = (mixed_edge_pair_num +
                                   1) % 3  ### then its the other one
        branch.append(
            branch_num_from_large_edge_and_mixed_edge_pair_num(
                large_edge_num, mixed_edge_pair_num))
    # assert is_branched(tri, branch)
    assert has_non_sing_semiflow(tri, branch)
    return branch
Exemple #4
0
def num_toggles_red_blue(triang_data):
    tet_types = is_veering(triang_data['tri'],
                           [int(a) for a in triang_data['angle']],
                           return_type='tet_types')
    counts = [
        tet_types.count('toggle'),
        tet_types.count("red"),
        tet_types.count("blue")
    ]
    return '[' + ','.join([str(i) for i in counts]) + ']'
Exemple #5
0
def can_deal_with_reduced_angle(tri, angle):
    """
    Returns True or False, as our techniques can recognise the given
    reduced angle structure.
    """
    if not is_taut(tri, angle):
        return False
    if is_veering(tri, angle):
        return True
    if is_layered(tri,
                  angle):  # has_internal_singularities is not needed here.
        return True
    return False
Exemple #6
0
def triangle_is_red(tri, angle, face_index, tet_vert_coorientations=None):

    if tet_vert_coorientations == None:
        tet_vert_coorientations = is_transverse_taut(
            tri, angle, return_type="tet_vert_coorientations")

    edge_index_where_uppermost = where_faces_are_uppermost(
        tri, angle, tet_vert_coorientations
    )[face_index]  #face has the same colour as the edge where it is uppermost

    colour = is_veering(
        tri, angle, return_type='veering_colours')[edge_index_where_uppermost]

    return (colour == 'red')
Exemple #7
0
def mutate(tri,
           angle,
           weights,
           isom,
           tet_vert_coorientations=None,
           quiet=False):

    if tet_vert_coorientations == None:
        tet_vert_coorientations = is_transverse_taut(
            tri, angle, return_type="tet_vert_coorientations")

    regluing = surface_isom_to_regluing_pattern(tri, angle, weights, isom,
                                                tet_vert_coorientations)
    #print('regluing data:', regluing)

    # first unglue all faces that need to be unglued, then reglue them via isom
    # can't do both at the same step, because regina goes crazy when you try to glue a face to a face which is already glued somewhere else
    for x in regluing:
        tet_below_top_triangle = tri.tetrahedron(x[0])
        which_face = x[1]
        tet_below_top_triangle.unjoin(which_face)
        #print('unglued face', which_face, 'of tet', tet_below_top_triangle.index())

    for x in regluing:
        tet_below_top_triangle = tri.tetrahedron(x[0])
        which_face = x[1]
        tet_above_image_triangle = tri.tetrahedron(x[2])
        perm = x[3]
        tet_below_top_triangle.join(which_face, tet_above_image_triangle, perm)
        #print('glued face', which_face, 'of tet', tet_below_top_triangle.index(), 'to tet', tet_above_image_triangle.index(), 'via', perm)

    assert tri.isValid()
    assert tri.countBoundaryFacets() == 0

    if quiet == False:
        print('mutant isosig:', tri.isoSig())
        print('taut:', is_taut(tri, angle))
        if is_taut(tri, angle):
            print('transverse taut:', is_transverse_taut(tri, angle))
            print('veering:', is_veering(tri, angle))
        else:
            edge_num = tri.countEdges()
            print('Got', edge_num, 'edges out of', tri.countTetrahedra())
            totals = is_taut(tri, angle, return_totals=True)
            print('Angles:', totals)
    # sig = 'eLMkbcddddedde_2100'
    # sig = 'eLMkbcdddhxqlm_1200'
    # sig = 'eLAkaccddjsnak_2001'
    # sig = 'eLAkbbcdddhwqj_2102'
    # sig = 'fLLQcbcdeeelonlel_02211'  ## should have three different midsurface bdy components, so four total after drilling
    # sig = 'fLLQcbddeeehrcdui_12000' ## five boundary components
    # sig = 'fLAMcbbcdeedhwqqs_21020'
    # sig = 'qvvLPQwAPLQkfhgffijlkmnopoppoaaaaaaaaaaaaadddd_1020212200111100'
    # t = excise_fans(sig)
    # t.save('excise_fans_' + sig + '.rga')

    # t0, _ = isosig_to_tri_angle('cPcbbbdxm_10')
    # t1, _ = isosig_to_tri_angle('cPcbbbiht_12')

    # print t.isIsomorphicTo(t0) != None or t.isIsomorphicTo(t1) != None

    # print fan_stacks(sig)

    import veering
    import transverse_taut
    import taut
    from file_io import parse_data_file
    census = parse_data_file('Data/veering_census.txt')

    for sig in census[:200]:
        tri, angle = excise_fans(sig)
        print((sig, tri.countTetrahedra(), angle, taut.is_taut(tri, angle)))
        assert veering.is_veering(tri, angle)
        assert transverse_taut.is_transverse_taut(tri, angle)
        # print sig, fan_stacks(sig)
Exemple #9
0
def build_surface(tri,
                  angle,
                  weights,
                  tet_vert_coorientations=None,
                  return_edge_colours=False):

    if tet_vert_coorientations == None:
        tet_vert_coorientations = is_transverse_taut(
            tri, angle, return_type="tet_vert_coorientations")

    surface = regina.Triangulation2()
    n = tri.countTetrahedra()

    for i in range(2 * n):
        for j in range(weights[i]):
            surface.newTriangle()

    colours = is_veering(tri, angle, return_type='veering_colours')

    edge_colours_pairs = []  # red, blue or black (dual to large branches)

    for edge in tri.edges():
        pairings = pairing_of_faces_across_an_edge(tri, angle, weights,
                                                   edge.index(),
                                                   tet_vert_coorientations)
        height = len(pairings[0])
        #print('height', height)

        #now we get (face_index, index of e in the face) so have to pick the first one
        face_indices0 = [pairings[0][i][0] for i in range(height)]
        face_indices1 = [pairings[1][i][0] for i in range(height)]

        for i in range(height):
            #face0_index = pairings[0][i][0] #now we get (face_index, index of e in the face) so have to pick the first one
            face0_index = face_indices0[i]
            edge_index_in_face0 = pairings[0][i][1]
            #face1_index = pairings[1][i][0]
            face1_index = face_indices1[i]
            edge_index_in_face1 = pairings[1][i][1]

            which_copy0 = face_indices0[:i].count(face0_index)
            # check if not overcounting (if a face is both uppermost and lowermost on the same side)
            if is_uppermost(tri, angle, face0_index, edge_index_in_face0,
                            edge.index(), tet_vert_coorientations
                            ) and appears_twice_on_the_same_side(
                                tri, angle, face0_index, edge.index(),
                                tet_vert_coorientations):
                which_copy0 = which_copy0 - weights[face0_index]

            which_copy1 = face_indices1[:i].count(face1_index)
            if is_uppermost(tri, angle, face1_index, edge_index_in_face1,
                            edge.index(), tet_vert_coorientations
                            ) and appears_twice_on_the_same_side(
                                tri, angle, face1_index, edge.index(),
                                tet_vert_coorientations):
                which_copy1 = which_copy1 - weights[face1_index]

            #which_copy0 = face_indices0[:i].count(face0_index)
            #which_copy1 = face_indices1[:i].count(face1_index)

            which_triangle0 = sum(weights[:face0_index]) + which_copy0
            which_triangle1 = sum(weights[:face1_index]) + which_copy1

            #print('which triangle 0', which_triangle0)
            #print('which triangle 1', which_triangle1)

            if colours[edge.index(
            )] == 'red':  # gluing triangles across a red edge
                if is_uppermost(tri, angle, face0_index, edge_index_in_face0,
                                edge.index(), tet_vert_coorientations):
                    if is_uppermost(tri, angle,
                                    face1_index, edge_index_in_face1,
                                    edge.index(), tet_vert_coorientations):
                        surface.triangle(which_triangle0).join(
                            2, surface.triangle(which_triangle1),
                            regina.Perm3(1, 0, 2))
                        #first we append edge_colours with tuples [face_index, edge_index_in_face, colour]; after finishing the triangulation we will change it into a tuple of colours ordered by indices
                        edge_colours_pairs.append(
                            [which_triangle0, 2, 'black'])
                    else:  # middle and lowermost have the same permutation
                        surface.triangle(which_triangle0).join(
                            2, surface.triangle(which_triangle1),
                            regina.Perm3(0, 2, 1))
                        edge_colours_pairs.append([which_triangle0, 2, 'red'])
                else:  # middle or lowermost
                    if is_uppermost(tri, angle,
                                    face1_index, edge_index_in_face1,
                                    edge.index(), tet_vert_coorientations):
                        surface.triangle(which_triangle0).join(
                            1, surface.triangle(which_triangle1),
                            regina.Perm3(0, 2, 1))
                        edge_colours_pairs.append([which_triangle0, 1, 'red'])
                    else:
                        surface.triangle(which_triangle0).join(
                            1, surface.triangle(which_triangle1),
                            regina.Perm3(2, 1, 0))
                        edge_colours_pairs.append([which_triangle0, 1, 'red'])
            else:  # gluing triangles across a blue edge
                if is_uppermost(tri, angle, face0_index, edge_index_in_face0,
                                edge.index(), tet_vert_coorientations):
                    if is_uppermost(tri, angle,
                                    face1_index, edge_index_in_face1,
                                    edge.index(), tet_vert_coorientations):
                        surface.triangle(which_triangle0).join(
                            2, surface.triangle(which_triangle1),
                            regina.Perm3(1, 0, 2))
                        edge_colours_pairs.append(
                            [which_triangle0, 2, 'black'])
                    else:  # middle and lowermost have the same permutation
                        surface.triangle(which_triangle0).join(
                            2, surface.triangle(which_triangle1),
                            regina.Perm3(2, 1, 0))
                        edge_colours_pairs.append([which_triangle0, 2, 'blue'])
                else:  # middle or lowermost
                    if is_uppermost(tri, angle,
                                    face1_index, edge_index_in_face1,
                                    edge.index(), tet_vert_coorientations):
                        surface.triangle(which_triangle0).join(
                            0, surface.triangle(which_triangle1),
                            regina.Perm3(2, 1, 0))
                        edge_colours_pairs.append([which_triangle0, 0, 'blue'])
                    else:
                        surface.triangle(which_triangle0).join(
                            0, surface.triangle(which_triangle1),
                            regina.Perm3(0, 2, 1))
                        edge_colours_pairs.append([which_triangle0, 0, 'blue'])

    assert surface.isClosed()

    #print (edge_colours_pairs)

    if return_edge_colours == True:
        k = surface.countEdges()
        edge_colours = [None] * k
        for x in edge_colours_pairs:
            edge_index = surface.triangle(x[0]).edge(x[1]).index()
            edge_colours[edge_index] = x[2]
        return surface, edge_colours

    return surface
def veering_mobius_dehn_surgery(triangulation, angle_struct, face_num):
    tri = regina.Triangulation3(triangulation)  # make a copy
    angle = list(angle_struct)  # make a copy
    face = tri.triangle(face_num)
    assert face.isMobiusBand()
    # Note that dunce caps cannot appear in a veering triangulation

    # Find which vertex is on both copies of the identified edge of the face
    edges = [face.edge(i)
             for i in range(3)]  # edge i is opposite vertex i, i in [0, 1, 2]
    for j in range(3):
        if edges[j] == edges[(j + 1) % 3]:
            B = (j + 2) % 3
            break

    embed0 = face.embedding(0)
    embed1 = face.embedding(1)
    tet0 = embed0.tetrahedron()
    tet1 = embed1.tetrahedron()
    embed0_verts = embed0.vertices()
    embed1_verts = embed1.vertices()

    # In tet0: B gives "b".  Let "c" be the edge sharing a
    # pi with "b".  Let "d" be the vertex not meeting the given face.
    # Let "a" be the remaining vertex.

    b = embed0.vertices()[B]
    c = shares_pi_with(angle[tet0.index()], b)
    d = embed0.vertices()[3]  # ... use the face index
    a = [i for i in [0, 1, 2, 3]
         if i not in [b, c, d]].pop()  # ... whatever is left

    # similarly in tet1 - B gives "q".  Let "r" be the edge sharing a
    # pi with "q".  Let "s" be the vertex not meeting the given face.
    # Let "p" be the remaining vertex.

    q = embed1.vertices()[B]
    r = shares_pi_with(angle[tet1.index()], q)
    s = embed1.vertices()[3]  # ... use the face index
    p = [i for i in [0, 1, 2, 3]
         if i not in [q, r, s]].pop()  # ... whatever is left

    # get colour of mobius strip
    pair_a = [b, c]
    pair_a.sort()
    mob_edge_a = tet0.edge(vert_pair_to_edge_num[tuple(pair_a)])
    pair_c = [a, b]
    pair_c.sort()
    mob_edge_c = tet0.edge(vert_pair_to_edge_num[tuple(pair_c)])
    assert mob_edge_a == mob_edge_c

    veering_colours = is_veering(tri, angle, return_type="veering_colours")
    assert veering_colours != False  # otherwise the triangulation is not veering
    mob_colour = veering_colours[mob_edge_a.index()]

    # Now actually do the surgery
    tet0.unjoin(d)  # same as tet1.unjoin(s)
    tet_new = tri.newTetrahedron()
    if mob_colour == "red":
        tet_new.join(0, tet_new, regina.Perm4(3, 0, 1, 2))
        tet_new.join(1, tet0, regina.Perm4(c, d, a, b))
        tet_new.join(2, tet1, regina.Perm4(q, p, s, r))
    else:
        tet_new.join(1, tet_new, regina.Perm4(1, 3, 0, 2))
        tet_new.join(2, tet0, regina.Perm4(a, b, d, c))
        tet_new.join(0, tet1, regina.Perm4(s, r, p, q))

    angle.append(0)  # this is the correct taut angle for our new tetrahedron
    assert is_taut(tri, angle)
    assert is_veering(tri, angle)
    return tri, angle, tet_new.triangle(3).index()
Exemple #11
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")
Exemple #12
0
def edges_to_tetrahedra_matrix(triangulation, angle_structure, coorientations,
                               normalisation, ZH, P):

    edge_colours = is_veering(triangulation,
                              angle_structure,
                              return_type="veering_colours")
    if verbose > 0:
        print(("edge_colours", edge_colours))
    red_tetrahedra = []
    blue_tetrahedra = []

    for tet in triangulation.tetrahedra():
        if has_red_lower_edge(tet, coorientations, edge_colours):
            red_tetrahedra.append(tet)
        else:
            blue_tetrahedra.append(tet)
    if verbose > 0:
        print(("how many reds and blues", len(red_tetrahedra),
               len(blue_tetrahedra)))

    face_laurents = faces_in_laurent(triangulation, angle_structure, [],
                                     ZH)  # empty list of cycles.
    if verbose > 0:
        print(("face_laurents", face_laurents))

    ET_matrix = []  # now to find the tet coefficients relative to each edge
    for tet in triangulation.tetrahedra():
        if verbose > 0:
            print(("tet_index", tet.index()))
        edge = tet_lower_upper_edges(tet, coorientations)[1]
        if verbose > 0:
            print(("edge_index", edge.index()))
        edge_colour = edge_colours[edge.index()]
        if verbose > 0:
            print(("edge_colour", edge_colour))
        embeddings = list(edge.embeddings())
        tet_coeffs = [ZH(0)] * triangulation.countTetrahedra()
        tet_coeffs[tet.index()] = 1  # bottom tet around the edge gets a 1
        if verbose > 0:
            print(("initial tet_coeffs", tet_coeffs))
        current_coeff = ZH(1)

        # find index of bottom embedding in the list of embedding
        for i, embed in enumerate(embeddings):
            tet = embed.tetrahedron()
            if verbose > 0:
                print(("current_tet", tet.index()))
            vert_perm = embed.vertices()
            trailing_vert_num, leading_vert_num = vert_perm[2], vert_perm[3]

            if (coorientations[tet.index()][trailing_vert_num] == +1
                    and coorientations[tet.index()][leading_vert_num] == +1):
                bottom_index = i
                break

        embeddings = embeddings[bottom_index:] + embeddings[:bottom_index]
        sign = -1  # we are going up the left side of the edge
        for embed in embeddings[1:]:  # skipping the first
            tet = embed.tetrahedron()
            vert_perm = embed.vertices()
            trailing_vert_num, leading_vert_num = vert_perm[2], vert_perm[3]
            current_coeff = current_coeff * face_laurents[tet.face(
                2, leading_vert_num).index()]**sign

            if (coorientations[tet.index()][trailing_vert_num] == -1
                    and coorientations[tet.index()][leading_vert_num] == -1):
                # we are the top embed so:
                tet_coeffs[
                    tet.index()] = tet_coeffs[tet.index()] - current_coeff
                sign = 1  # now we go down the right side
            elif ((edge_colour == "blue" and tet in red_tetrahedra)
                  or (edge_colour == "red" and tet in blue_tetrahedra)):
                tet_coeffs[
                    tet.index()] = tet_coeffs[tet.index()] - current_coeff
            if verbose > 0:
                print(("current tet_coeffs", tet_coeffs))

        ET_matrix.append(tet_coeffs)

    if normalisation == True:
        # convert and return
        return matrix_laurent_to_poly(ET_matrix, ZH, P)
    else:
        return Matrix(ET_matrix)
Exemple #13
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
def is_edge_orientable(tri, angle, return_type="boolean"):
    """
    checks to see if this veering triangulation is edge orientable. 
    If return type is "tri angle" it returns the edge orientable double cover with its angle structure. 
    Note that this is disconnected if and only if the given triangulation is edge orientable
    """
    # return type can be "boolean", "veering_tet_vert_nums", or "tri angle"
    n = tri.countTetrahedra()
    veering_colours = is_veering(tri, angle, return_type="veering_colours")
    assert veering_colours != False  # so we are veering
    tet_vert_coorientations = is_transverse_taut(
        tri, angle, return_type="tet_vert_coorientations")

    ### assumption: the first n tetrahedra have upper edge oriented according to Regina, the last n have it against Regina

    ### build our own model vertex numbering for each tetrahedron as follows:
    ### the top edge e is oriented by regina numbering, and gets vert_nums 1 and 2 in our ordering
    ### an equatorial edge e' of the same colour as e shares a vertex v with it.
    ### e and e' both point away from v or towards it. If away then the other end of e' is 3,
    ### else, the other end is 0

    veering_tet_vert_nums = [
    ]  ### will populate with regina's vert nums, but our order.
    ### that is, veering_tet_vert_nums[1] and [2] will be the regina vert nums for the ends of the top edge

    for i in range(n):
        tet = tri.tetrahedron(i)
        veering_vert_nums = [None, None, None, None]
        top_vert_pair = get_tet_top_vert_nums(tet_vert_coorientations, i)
        # print(i, top_vert_pair)
        if not regina_edge_orientation_agrees(tet, top_vert_pair):
            top_vert_pair.reverse()
            assert regina_edge_orientation_agrees(tet, top_vert_pair)
        veering_vert_nums[1] = top_vert_pair[0]
        veering_vert_nums[2] = top_vert_pair[1]

        top_edge_num = vert_pair_to_edge_num[tuple(top_vert_pair)]
        top_edge_col = veering_colours[tet.edge(top_edge_num).index()]

        bottom_vert_pair = list(set(range(4)) - set(top_vert_pair))
        bv, bv2 = bottom_vert_pair  ## choose arbitrarily, now find which edge from the top vertices has same colour as bv
        for j, tv in enumerate(top_vert_pair):
            edge_col = veering_colours[tet.edge(
                vert_pair_to_edge_num[(bv, tv)]).index()]
            if edge_col == top_edge_col:
                if j == 0:  ### bv shares an edge of same colour as top with tail of top edge
                    veering_vert_nums[3] = bv
                    veering_vert_nums[0] = bv2
                else:  ### bv shares an edge of same colour as top with head of top edge
                    veering_vert_nums[0] = bv
                    veering_vert_nums[3] = bv2
        veering_tet_vert_nums.append(veering_vert_nums)
    # print('veering_tet_vert_nums', veering_tet_vert_nums)
    if return_type == "veering_tet_vert_nums":
        return veering_tet_vert_nums

    ### Now, when we glue two tetrahedra together along a face, the first of the three vertices in the veering_vert_num order
    ### on that tet's face glues to the first of the three vertices on the other tet's face, or to the third.
    ### depending on this, we go to the other part of the double cover, or not

    cover_tri = regina.Triangulation3()  ## starts empty
    for i in range(2 * n):
        cover_tri.newTetrahedron()
    tet_faces = []
    for i in range(n):
        for j in range(4):
            tet_faces.append((i, j))
    while len(tet_faces) > 0:
        i, j = tet_faces.pop()
        tet = tri.tetrahedron(i)
        adjtet, adjgluing = tet.adjacentTetrahedron(j), tet.adjacentGluing(j)
        iN, jN = adjtet.index(), adjgluing[j]
        tet_faces.remove((iN, jN))

        cover_tets = [cover_tri.tetrahedron(i), cover_tri.tetrahedron(i + n)]
        cover_tetsN = [
            cover_tri.tetrahedron(iN),
            cover_tri.tetrahedron(iN + n)
        ]
        ### find the veering indices for the verts in the gluing on this tet and on adjtet

        face_veering_nums = veering_tet_vert_nums[i][:]
        face_veering_nums.remove(j)
        a, b, c = face_veering_nums
        neighbour_face_veering_nums = veering_tet_vert_nums[iN][:]
        neighbour_face_veering_nums.remove(jN)
        aN, bN, cN = neighbour_face_veering_nums
        assert adjgluing[b] == bN  ### middles should match
        if adjgluing[a] == aN:  ### veering orderings agree across the gluing
            assert adjgluing[c] == cN
            for k in range(2):
                cover_tets[k].join(j, cover_tetsN[k], adjgluing)
        else:  ### veering orderings disagree across the gluing
            assert adjgluing[a] == cN and adjgluing[c] == aN
            for k in range(2):
                cover_tets[k].join(j, cover_tetsN[(k + 1) % 2], adjgluing)
    assert not cover_tri.hasBoundaryFacets()
    assert is_veering(cover_tri, angle + angle)

    if return_type == "boolean":
        return not cover_tri.isConnected(
        )  ### not connected if the original veering triangulation is edge orientable
    else:
        assert return_type == "tri angle"
        return cover_tri, angle + angle