Esempio n. 1
0
    def polygon(n):
        """
        This constructs a polygon with n sides.

        INPUT:
        A positive integer n, at least 1.

        OUTPUT:
        A closed ribbon graph.

        EXAMPLE:

        >>> RibbonGraph.polygon(4) # doctest:+ELLIPSIS
        <__main__.RibbonGraph object at 0x...>
        """

        if n<1: raise ValueError
        a =  [ ribbon.halfedge() for i in xrange(n) ]
        b1 = [ ribbon.halfedge() for i in xrange(n) ]
        b2 = [ ribbon.halfedge() for i in xrange(n) ]
        for i in xrange(n-1):
            b1[i].e = b2[i+1]
            b2[i+1].e = b1[i]
        b1[n-1].e = b2[0]
        b2[0].e = b1[n-1]
        for i in xrange(n):
            a[i].c = b1[i]
            b1[i].c = b2[i]
            b2[i].c = a[i]
        h = ribbon.justgraph(a+b1+b2)
        return RibbonGraph(h,a)
Esempio n. 2
0
def Artin_generator(n,k):
    """Constructs the Artin generator s_k of n string braif group.

    INPUT: n a positive integer, k an integer with 0 < |k| < n

    OUTPUT: A Morphism

    >>> s1 = Artin_generator(3,1)
    >>> s2 = Artin_generator(3,2)
    """
    if not 0 < abs(k) < n:
        raise ValueError

    # These are also defined in knots.py
    in_over = ribbon.Features('head','blue',True)
    in_under = ribbon.Features('head','blue',False)
    out_over = ribbon.Features('tail','blue',True)
    out_under = ribbon.Features('tail','blue',False)

    r = range(n)
    do = [ ribbon.halfedge() for i in r ]
    co = [ ribbon.halfedge() for i in r ]
    for a in do:
        a.decorations = in_over
        a.IsI = True
    for a in co:
        a.decorations = out_over
        a.IsI = True
    for i in r:
        do[i].c = co[i]
        co[i].c = do[i]
        
    p =abs(k)
    do[p-1].IsI = False
    do[p].IsI = False
    co[p-1].IsI = False
    co[p].IsI = False
    do[p-1].c = do[p]
    do[p].c = co[p]
    co[p].c = co[p-1]
    co[p-1].c = do[p-1]

    if k > 0:
        do[k-1].decorations = in_over
        do[k].decorations = in_under
        co[k-1].decorations = out_under
        co[k].decorations = out_over
    elif k < 0:
        do[p-1].decorations = in_under
        do[p].decorations = in_over
        co[p-1].decorations = out_over
        co[p].decorations = out_under
    else:
        raise RuntimeError

    g = ribbon.justgraph( set(do+co) )
    return Morphism(g, do, co)
Esempio n. 3
0
        def vogel_move(f,u,v):
            # This goes into an infinite loop
            phi = f.graph.copy()
            new = phi.codomain
            a = phi.map[u]
            b = a.e
            c = phi.map[v]
            d = c.e
            x = [ ribbon.halfedge() for i in range(4) ]
            for i in range(4):
                x[i-1].c = x[i]
            y = [ ribbon.halfedge() for i in range(4) ]
            for i in range(4):
                y[i-1].c = y[i]
            a.e = x[0]; x[0].e = a
            d.e = x[3]; x[3].e = d
            b.e = y[1]; y[1].e = b
            c.e = y[2]; y[2].e = c
            x[1].e = y[0]; y[0].e = x[1]
            x[2].e = y[3]; y[3].e = x[2]
            switch = {'head':'tail','neither':'neither','tail':'head'}
            ut = a.decorations.directed
            ot = switch[ut]

            if False:
                x[0].decorations._replace(a.decorations.colour)
                x[1].decorations._replace(c.decorations.colour)
                x[2].decorations._replace(a.decorations.colour)
                x[3].decorations._replace(c.decorations.colour)
                y[0].decorations._replace(d.decorations.colour)
                y[1].decorations._replace(b.decorations.colour)
                y[2].decorations._replace(d.decorations.colour)
                y[3].decorations._replace(b.decorations.colour)

            for a in x:
                a.decorations._replace(colour='red')
            for a in y:
                a.decorations._replace(colour='red')


            g = ribbon.justgraph( new.he.union( set(x+y) ) )

            u = phi.map[f.outside[0]]
            outside = [u]
            s = u.e.c
            while s != u:
                outside.append(s)
                s = s.e.c

            return LinkDiagram(g,outside)
Esempio n. 4
0
    def vertex(x):
        """
        Constructs a single vertex of valency n.
        INPUT:
        A positive integer n, at least 1 or a list of features.

        OUTPUT:
        A closed ribbon graph.

        EXAMPLES:

        >>> RibbonGraph.vertex(3) # doctest:+ELLIPSIS
        <__main__.RibbonGraph object at 0x...>

        """

        if isinstance(x, Iterable):
            n = len(x)
        else:
            n = x
        if n<1: raise ValueError("Not enough points.")

        a = [ ribbon.halfedge() for i in xrange(n) ]
        for i in xrange(n-1):
            a[i].c = a[i+1]
        a[n-1].c = a[0]
        if isinstance(x, Iterable):
            for i, r in zip(xrange(n),x):
                if not isinstance(r, ribbon.features):
                    raise ValueError
                a[i].decorations = r

        h = ribbon.justgraph(a)
        return RibbonGraph(h,a)
Esempio n. 5
0
    def from_PlanarDiagram(PD):
        """Produces a LinkDiagram from the planar diagram notation.

        INPUT: A list or set of 4-tuples

        OUTPUT: A closed justgraph

        EXAMPLES:

        >>> LinkDiagram.from_PlanarDiagram([[1,2,3,4],[4,3,6,5],[2,1,5,6]]) #doctest: +ELLIPSIS
        <__main__.LinkDiagram object at 0x...>

        >>> g = LinkDiagram.from_PlanarDiagram([[1,2,3,4],[4,3,6,5],[2,1,5,6]])
        >>> [ len(v) for v in g.vertices ]
        [4, 4, 4]
        >>> [ len(v) for v in g.edges ]
        [2, 2, 2, 2, 2, 2]
        >>> x = [ len(v) for v in g.faces ]
        >>> x.sort()
        >>> x
        [2, 2, 2, 3, 3]
        >>> x = [ len(v) for v in g.graph.get_orbits( lambda a: a.e.c ) ]
        >>> x.sort()
        >>> x
        [2, 2, 2, 3, 3]


        """
        if not all([ len(x) == 4 for x in PD ]):
            raise ValueError("Not a valid planar diagram code")
        for i in range(2*len(PD)):
            p = [ x for x in PD if i+1 in x ]
            if len(p) != 2:
                raise ValueError("Not a valid planar diagram code")

        D = dict()
        he = set()
        for x in PD:
            a = [ ribbon.halfedge() for i in range(4) ]
            for i in range(4):
                a[i-1].c = a[i]
            D[tuple(x)] = a
            he = he.union(set(a))

        for i in range(2*len(PD)):
            p = [ x for x in PD if i+1 in x ]
            a0 = D[tuple(p[0])][p[0].index(i+1)]
            a1 = D[tuple(p[1])][p[1].index(i+1)]
            a0.e = a1
            a1.e = a0

        g = ribbon.justgraph(he)
        outside = g.get_orbits( lambda a: a.e.c )[0]
        return LinkDiagram(g,outside)
    def map(self):
        labels = ('VE','VF','EV','EF','FV','FE',)
        flags = dict([])
        for l in labels:
            for i in range(self.degree):
                flags[(i,l,)] = ribbon.halfedge()

        for i in range(self.degree):
            flags[(i,'VE',)].e = flags[(i,'EV',)]
            flags[(i,'EV',)].e = flags[(i,'VE',)]
            flags[(i,'VF',)].e = flags[(i,'FV',)]
            flags[(i,'FV',)].e = flags[(i,'VF',)]
            flags[(i,'FE',)].e = flags[(i,'EF',)]
            flags[(i,'EF',)].e = flags[(i,'FE',)]

            #flags[(i,'VE',)]).c = flags[(self.sigma[i],'VF',)]
            flags[(self.sigma[i],'VE',)].c = flags[(i,'VF',)]
            flags[(i,'EV',)].c = flags[(i,'EF',)]
            flags[(i,'VF',)].c = flags[(i,'VE',)]
            flags[(self.phi[i],'FV',)].c = flags[(i,'FE',)]
            flags[(i,'FE',)].c = flags[(i,'FV',)]
            #flags[(i,'EF',)].c = flags[(self.alpha[i],'EV',)]
            flags[(self.alpha[i],'EF',)].c = flags[(i,'EV',)]

        for i in range(self.degree):
            flags[(i,'EV',)].decorations = ribbon.Features('neither','red',True)
            flags[(i,'VE',)].decorations = ribbon.Features('neither','red',True)
            flags[(i,'FV',)].decorations = ribbon.Features('neither','blue',True)
            flags[(i,'VF',)].decorations = ribbon.Features('neither','blue',True)
            flags[(i,'FE',)].decorations = ribbon.Features('neither','green',True)
            flags[(i,'EF',)].decorations = ribbon.Features('neither','green',True)
            
        g = ribbon.justgraph(set(flags.values()))

        a = self.faces[0]
        x = flags[(a[0],'FE',)]
        out = [x]
        y = x.c
        while y != x:
            out.append(y)
            y = y.c
        out.reverse()

        sut = [ flags[(i,'FE',)] for i in a ] + [ flags[(i,'FV',)] for i in a ]
        if set(sut) != set(out):
            raise RuntimeError

        return g, out
Esempio n. 7
0
    def closure(self, bv=None):
        """Construct the closure of a web.

        INPUT: A web and a boundary vector.

        OUTPUT: A closed web.

        EXAMPLES:

        >>> RibbonGraph.polygon(5).closure() #doctest: +ELLIPSIS
        <closedgraph.ClosedGraph object at 0x...>

        >>> RibbonGraph.polygon(5).closure().graph.count_vertices()
        [0, 0, 5, 10]

        """
        if bv == None:
            bv = [1] * len(self.bd)
        if sum(bv) != len(self.bd):
            raise ValueError("Boundary vector is not consistent with web.")
        if len(bv) < 3:
            raise ValueError("Not enough corners.")

        C = len(bv)
        B = len(self.bd)

        phi = self.jg.copy()
        he = phi.codomain.he

        rim = ribbon.Features('neither','black',True)
        switch = {'head':'tail','neither':'neither','tail':'head'}
        
        ci = [ ribbon.halfedge() for i in xrange(C) ]
        for a in ci:
            a.decorations = rim
        co = [ ribbon.halfedge() for i in xrange(C) ]
        for a in co:
            a.decorations = rim
        he = he.union(ci+co)
        bi = [ ribbon.halfedge() for i in xrange(B) ]
        for a in bi:
            a.decorations = rim
        bo = [ ribbon.halfedge() for i in xrange(B) ]
        for a in bo:
            a.decorations = rim
        bc = [ ribbon.halfedge() for i in xrange(B) ]
        he = he.union(bi+bo+bc)

        for i in xrange(C):
            ci[i].c = co[i]
            co[i].c = ci[i]

        nb = [ phi.map[a] for a in self.bd ]
        for i in xrange(B):
            bi[i].c = bo[i]
            bo[i].c = bc[i]
            bc[i].c = bi[i]
            bc[i].e = nb[i]
            nb[i].e = bc[i]

        for a in bc:
            f = a.e.decorations
            a.decorations = ribbon.Features(switch[f.directed],f.colour,True)

        p = 0
        for i, a in enumerate(bv):
            r = co[i-1]
            for j in xrange(a):
                bi[p].e = r
                r.e = bi[p]
                r = bo[p]
                p += 1
            r.e = ci[i]
            ci[i].e = r

        ng = ribbon.justgraph(he)

        u = co[0]
        outside = [u]
        s = u.e.c
        while s != u:
            outside.append(s)
            s = s.e.c

        return closedgraph.ClosedGraph(ng, outside)
Esempio n. 8
0
    def from_DT(DT):
        """Construct a knot diagram from the Dowker-Thistlewaite code.

        The theory is given in the original paper:

        Classification of knot projections
        C. H. Dowker & Morwen B. Thistlewaite
        Topology and its Applications 16 (1983), 19--31

        INPUT:
            A list of positive even integers

        OUTPUT:
            A closed justgraph

        EXAMPLES:
            >>> LinkDiagram.from_DT(DT([4,6,2])) #doctest: +ELLIPSIS
            <__main__.LinkDiagram object at 0x...>
            >>> LinkDiagram.from_DT(DT([4,6,8,2])) #doctest: +ELLIPSIS
            <__main__.LinkDiagram object at 0x...>
            >>> LinkDiagram.from_DT(DT([4,8,10,2,6])) #doctest: +ELLIPSIS
            <__main__.LinkDiagram object at 0x...>
            >>> LinkDiagram.from_DT(DT([6,8,10,2,4])) #doctest: +ELLIPSIS
            <__main__.LinkDiagram object at 0x...>

            >>> g = LinkDiagram.from_DT(DT([4,6,2]))
            >>> [ len(v) for v in g.vertices ]
            [4, 4, 4]
            >>> [ len(v) for v in g.edges ]
            [2, 2, 2, 2, 2, 2]
            >>> x = [ len(v) for v in g.faces ]
            >>> x.sort()
            >>> x
            [2, 2, 2, 3, 3]

            >>> g = LinkDiagram.from_DT(DT([4,6,8,2]))
            >>> [ len(v) for v in g.vertices ]
            [4, 4, 4, 4]
            >>> [ len(v) for v in g.edges ]
            [2, 2, 2, 2, 2, 2, 2, 2]
            >>> x = [ len(v) for v in g.faces ]
            >>> x.sort()
            >>> x
            [2, 2, 3, 3, 3, 3]
            >>> x = [ len(v) for v in g.graph.get_orbits( lambda a: a.c.e ) ]
            >>> x.sort()
            >>> x
            [2, 2, 3, 3, 3, 3]

            >>> g = LinkDiagram.from_DT(DT([4,8,10,2,6]))
            >>> [ len(v) for v in g.vertices ]
            [4, 4, 4, 4, 4]
            >>> [ len(v) for v in g.edges ]
            [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
            >>> x = [ len(v) for v in g.faces ]
            >>> x.sort()
            >>> x
            [2, 2, 2, 3, 3, 4, 4]
            >>> x = [ len(v) for v in g.graph.get_orbits( lambda a: a.c.e ) ]
            >>> x.sort()
            >>> x
            [2, 2, 2, 3, 3, 4, 4]

            >>> g = LinkDiagram.from_DT(DT([8,10,2,12,4,6]))
            >>> x = [ len(v) for v in g.vertices ]
            >>> x.sort()
            >>> x
            [4, 4, 4, 4, 4, 4]
            >>> [ len(v) for v in g.edges ]
            [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
            >>> x = [ len(v) for v in g.faces ]
            >>> x.sort()
            >>> x
            [2, 2, 2, 3, 3, 3, 4, 5]
            >>> x = [ len(v) for v in g.graph.get_orbits( lambda a: a.c.e ) ]
            >>> x.sort()
            >>> x
            [2, 2, 2, 3, 3, 3, 4, 5]

        REFS:
            http://katlas.org/wiki/DT_%28Dowker-Thistlethwaite%29_Codes
        """

        emb = DT.orientation

        m = 2 * len(emb)

        left =  [ ribbon.halfedge() for i in range(m) ]
        right = [ ribbon.halfedge() for i in range(m) ]
        for i in range(m):
            left[i].e = right[i-1]
            right[i-1].e = left[i]
        for i, k in enumerate(DT.code):
            a = abs(k)-1
            x = [ left[2*i], left[a], right[2*i], right[a] ]
            if k > 0:
                x[0].decorations = in_over
                x[1].decorations = in_under
                x[2].decorations = out_over
                x[3].decorations = out_under
            elif k < 0:
                x[0].decorations = in_under
                x[1].decorations = in_over
                x[2].decorations = out_under
                x[3].decorations = out_over
            else:
                raise ValueError("Not a valid Dowker-Thistlewaite code")
            if emb[i] == -1:
                x.reverse()
            elif emb[i] != 1:
                raise RuntimeError
            for i in xrange(4):
                x[i-1].c = x[i]

        g = ribbon.justgraph( set(left).union(set(right)) )
        outside = g.get_orbits( lambda a: a.e.c )[0]
        return LinkDiagram(g,outside)