Пример #1
0
def random_knot(n,
                method='close_under',
                alternate=False,
                bias=False,
                num_opportunities=1):
    if method == 'close_under':
        crossings, loose_cs, final_cs = random_open_string(n,
                                                           alternate=alternate,
                                                           bias=bias)
        connect_loose_strands(crossings, loose_cs, final_cs)
        return Link(crossings)
    elif method == 'close_on_opportunity':
        crossings = [Crossing('0')]
        crossings[0][2] = crossings[0][3]
        final_cs = crossings[0].crossing_strands()[0]
        loose_cs = crossings[0].crossing_strands()[1]
        i = 0
        while num_opportunities > 0:
            available = available_strands(loose_cs)
            strand_to_cross = choice(available)
            if alternate:
                over_or_under = 1 - (i % 2)
            else:
                over_or_under = randint(0, 1)
            loose_cs = cross_strand(crossings, loose_cs, strand_to_cross,
                                    str(i + 1), over_or_under)
            same_face = set(available_strands(loose_cs)) == set(
                available_strands(final_cs))
            if same_face:
                num_opportunities -= 1
            i += 1
            if i >= n:
                raise Exception('Not closeable after n crossings')
        connect_loose_strands(crossings, loose_cs, final_cs)
        return Link(crossings)
Пример #2
0
def open_string_alexander(crossings):
    crossings_copy = pickle.loads(pickle.dumps(crossings))
    loose = []
    for c in crossings_copy:
        for i in range(4):
            if c.adjacent[i] is None:
                loose.append(c.crossing_strands()[i])
    connect_loose_strands(crossings_copy, loose[0], loose[1])
    K = Link(crossings_copy)
    K.simplify(mode='level')
    return K.alexander_polynomial() if len(K) > 0 else 1
Пример #3
0
def open_string_evaluation(crossings, function, simplify='level'):
    crossings_copy = pickle.loads(pickle.dumps(crossings))
    loose = []
    for c in crossings_copy:
        for i in range(4):
            if c.adjacent[i] is None:
                loose.append(c.crossing_strands()[i])
    connect_loose_strands(crossings_copy, loose[0], loose[1])
    K = Link(crossings_copy)
    if simplify:
        K.simplify(mode=simplify)
    if len(K) > 0:
        return function(K)
Пример #4
0
 def link(self):
     active = dict()
     component_starts = []
     crossings = []
     for event in self.events:
         if event.kind == 'cup':
             S = Strand()
             crossings.append(S)
             active = insert_space(active, event.min)
             active[event.a] = S[0]
             active[event.b] = S[1]
         elif event.kind == 'cap':
             S = Strand()
             crossings.append(S)
             S[0] = active[event.a]
             S[1] = active[event.b]
             active = remove_space(active, event.min)
         elif event.kind == 'cross':
             C = Crossing()
             crossings.append(C)
             if event.a < event.b:
                 C[3] = active[event.a]
                 C[0] = active[event.b]
                 active[event.a] = C[2]
                 active[event.b] = C[1]
             else:
                 C[3] = active[event.a]
                 C[2] = active[event.b]
                 active[event.a] = C[0]
                 active[event.b] = C[1]
     return Link(crossings)
Пример #5
0
    def link(self):
        crossings = []
        curr_endpoints = self.width * [None]

        for x, y in self.bottom:
            s = Strand()
            crossings.append(s)
            curr_endpoints[x] = (s, 0)
            curr_endpoints[y] = (s, 1)

        for a, b in self.crossings:
            c = Crossing()
            crossings.append(c)
            if a < b:
                ins, outs = (3, 0), (2, 1)
            else:
                ins, outs = (0, 1), (3, 2)
                a, b = b, a

            c[ins[0]] = curr_endpoints[a]
            c[ins[1]] = curr_endpoints[b]
            curr_endpoints[a] = (c, outs[0])
            curr_endpoints[b] = (c, outs[1])

        for x, y in self.top:
            join_strands(curr_endpoints[x], curr_endpoints[y])

        return Link(crossings)
Пример #6
0
def open_string_volume(crossings):
    crossings_copy = pickle.loads(pickle.dumps(crossings))
    loose = []
    for c in crossings_copy:
        for i in range(4):
            if c.adjacent[i] is None:
                loose.append(c.crossing_strands()[i])
    connect_loose_strands(crossings_copy, loose[0], loose[1])
    return Link(crossings_copy).exterior().volume()
Пример #7
0
def mirror(link):
    """
    Create the mirror image of the link, preserving link orientations and
    component order.
    """
    # Basically, we just mirror every crossing, but the particular data 
    # structures used make this a little involved.
    
    new_crossings = dict()
    for C in link.crossings:
        C_new = Crossing(label=C.label)
        C_new.sign = -C.sign
        new_crossings[C] = C_new

    def convert(C, c):
        """
        Go from a crossing to the mirror, which requires the a rotation of the
        entry points; the direction of rotation depends on the sign of
        the crossing.
        """
        return new_crossings[C], (c + C.sign) % 4
        
    for A in link.crossings:
        entry_points = [CEP.entry_point for CEP in A.entry_points()]
        for a in entry_points:
            B, b = A.adjacent[a]
            B_new, b_new = convert(B, b)
            B_new[b_new] = convert(A, a)

    new_link = Link(new_crossings.values(),
                    check_planarity=False, build=False)

    # Build the link components, starting in the same place as
    # the original link.
    
    component_starts = []
    for component in link.link_components:
        C_new, c_new = convert(*component[0])
        component_starts.append( CrossingEntryPoint(C_new, c_new) )

    new_link._build_components(component_starts)
    return new_link
Пример #8
0
    def as_spherogram(self):
        '''
        Get a planar diagram class from the Spherogram module, which
        can be used to access SnapPy's manifold tools.

        This method requires that spherogram and SnapPy are installed.
        '''
        from spherogram import Crossing, Link
        scs = [Crossing() for crossing in self]

        indices = {}
        for i in range(len(self)):
            c = self[i]
            for j in range(len(c)):
                number = c[j]
                if number in indices:
                    otheri, otherj = indices.pop(number)
                    scs[i][j] = scs[otheri][otherj]
                else:
                    indices[number] = (i, j)
        return Link(scs)
Пример #9
0
 def link(self):
     G = self.fat_graph
     crossing_dict = {}
     for v in G.vertices:
         c = Crossing(v[0])
         c.make_tail(0)
         if G.sign(v) == 1:
             c.make_tail(3)
         else:
             c.make_tail(1)
         c.orient()
         crossing_dict[v] = c
     for edge in G.edges:
         if edge.slots[0] in edge[0].upper_pair():
             a = 1 if G.sign(edge[0]) == 1 else 3
         else:
             a = 2
         if edge.slots[1] in edge[1].upper_pair():
             b = 3 if G.sign(edge[1]) == 1 else 1
         else:
             b = 0
         crossing_dict[edge[0]][a] = crossing_dict[edge[1]][b]
     return Link(crossing_dict.values(), check_planarity=False)
Пример #10
0
 def link(self):
     G = self.fat_graph
     crossing_dict, slot_dict = {}, {}
     for v in G.vertices:
         c = Crossing(v[0])
         c.make_tail(0)
         if G.sign(v) == 1:
             c.make_tail(3)
         else:
             c.make_tail(1)
         c.orient()
         crossing_dict[v] = c
         if v.upper_pair() == (0, 2):
             slot_dict[v] = (3, 0, 1, 2)
         else:
             slot_dict[v] = (2, 3, 0, 1) if G.flipped(v) else (0, 1, 2, 3)
     for edge in G.edges:
         v0, v1 = edge
         s0, s1 = edge.slots
         a0, a1 = slot_dict[v0][s0], slot_dict[v1][s1]
         c0, c1 = crossing_dict[v0], crossing_dict[v1]
         c0[a0] = c1[a1]
     link = Link(list(crossing_dict.values()),
                 check_planarity=False,
                 build=False)
     assert link.all_crossings_oriented()
     component_starts = []
     i = 1
     for comp in self.code:
         c = self[i]
         if i == c[0]:
             e = slot_dict[c][2] if G.flipped(c) else slot_dict[c][0]
         else:
             e = slot_dict[c][1]
         ce = CrossingEntryPoint(crossing_dict[c], e)
         component_starts.append(ce)
         i += 2 * len(comp)
     link._build_components(component_starts)
     if not link.is_planar():
         raise ValueError(
             'DT code does not seem to define a *planar* diagram')
     return link
Пример #11
0
def test_jones():
    from spherogram import Link
    L = Link('L11a548')
    E = good_exhaustion(L, max_failed_tries=100)
    print(E.jones_polynomial())
Пример #12
0
def test_kauffman():
    from spherogram import Link
    L = Link('L11a548')
    E = good_exhaustion(L)
    return E.kauffman_bracket()
Пример #13
0
def random_knot(n):
    crossings, loose_cs, final_cs = random_open_string(n)
    flip_crossings(crossings, loose_cs, final_cs)
    #    print(open_string_faces(crossings, loose_cs, final_cs))
    connect_loose_strands(crossings, loose_cs, final_cs)
    return Link(crossings)
Пример #14
0
def basic_test():
    for M in snappy.LinkExteriors():
        if M.solution_type().startswith('all tetra'):
            L = Link(M.name())
            test_link(L)
Пример #15
0
from spherogram import Link, Crossing
from spherogram.links.links import CrossingEntryPoint
import snappy

L = Link('9^3_12')
#L = Link('4a1')

def mirror(link):
    """
    Create the mirror image of the link, preserving link orientations and
    component order.
    """
    # Basically, we just mirror every crossing, but the particular data 
    # structures used make this a little involved.
    
    new_crossings = dict()
    for C in link.crossings:
        C_new = Crossing(label=C.label)
        C_new.sign = -C.sign
        new_crossings[C] = C_new

    def convert(C, c):
        """
        Go from a crossing to the mirror, which requires the a rotation of the
        entry points; the direction of rotation depends on the sign of
        the crossing.
        """
        return new_crossings[C], (c + C.sign) % 4
        
    for A in link.crossings:
        entry_points = [CEP.entry_point for CEP in A.entry_points()]
Пример #16
0
def knot_from_turn_list(turn_list):
    crossings, loose_cs, final_cs = open_string_from_turn_list(turn_list)
    #    randomly_flip_crossings(crossings, loose_cs, final_cs)
    #    print(open_string_faces(crossings, loose_cs, final_cs))
    connect_loose_strands(crossings, loose_cs, final_cs)
    return Link(crossings)