def braid_word(self, as_sage_braid=False):
        """
        Return a list of integers which defines a braid word whose closure is the 
        given link.  The natural numbers 1, 2, 3, etc are the generators and the
        negatives are the inverses.
        
        >>> L = Link('K8n1')
        >>> word = L.braid_word(); word
        [1, -2, 3, 2, 4, -3, 2, -1, 2, 2, 3, 2, -4, -3, -2, -2]

        >>> Link(braid_closure=word).exterior().identify()    # doctest: +SNAPPY
        [m222(0,0), 8_20(0,0), K5_12(0,0), K8n1(0,0)]

        Within Sage, you can get the answer as an element of the
        appropriate BraidGroup::

            sage: Link('K6a2').braid_word(as_sage_braid=True)
            (s0^-1*s1)^2*s0^-2
        
        Implementation follows P. Vogel, "Representation of links by
        braids, a new algorithm".
        """
        from . import seifert
        word = seifert.braid_word(self)
        if as_sage_braid:
            if not _within_sage:
                raise ValueError('Requested Sage braid outside of Sage.')
            n = max([abs(a) for a in word]) + 1
            word = BraidGroup(n)(word)
        return word
Beispiel #2
0
    def braid_word(self, as_sage_braid=False):
        """
        Return a list of integers which defines a braid word whose closure is the
        given link.  The natural numbers 1, 2, 3, etc are the generators and the
        negatives are the inverses.

        >>> L = Link('K6a2')
        >>> word = L.braid_word()
        >>> B = Link(braid_closure=word)
        >>> B.exterior().identify()    # doctest: +SNAPPY
        [m289(0,0), 6_2(0,0), K5_19(0,0), K6a2(0,0)]

        Within Sage, you can get the answer as an element of the
        appropriate BraidGroup and also check our earlier work::

            sage: Link('K6a2').braid_word(as_sage_braid=True)
            (s0*s1^-1)^2*s0^2
            sage: L.signature(), B.signature()
            (-2, -2)

        Implementation follows P. Vogel, "Representation of links by
        braids, a new algorithm".
        """
        from . import seifert
        word = seifert.braid_word(self)
        if as_sage_braid:
            if not _within_sage:
                raise ValueError('Requested Sage braid outside of Sage.')
            n = max(abs(a) for a in word) + 1
            word = BraidGroup(n)(word)
        return word
Beispiel #3
0
    def __classcall_private__(cls, coxeter_data, names=None):
        """
        Normalize input to ensure a unique representation.

        TESTS::

            sage: A1 = ArtinGroup(['B',3])
            sage: A2 = ArtinGroup(['B',3], 's')
            sage: A3 = ArtinGroup(['B',3],  ['s1','s2','s3'])
            sage: A1 is A2 and A2 is A3
            True

            sage: A1 = ArtinGroup(['B',2], 'a,b')
            sage: A2 = ArtinGroup([[1,4],[4,1]], 'a,b')
            sage: A3.<a,b> = ArtinGroup('B2')
            sage: A1 is A2 and A2 is A3
            True

            sage: ArtinGroup(['A',3]) is BraidGroup(4, 's1,s2,s3')
            True

            sage: G = graphs.PathGraph(3)
            sage: CM = CoxeterMatrix([[1,-1,2],[-1,1,-1],[2,-1,1]], index_set=G.vertices())
            sage: A = groups.misc.Artin(CM)
            sage: Ap = groups.misc.RightAngledArtin(G, 's')
            sage: A is Ap
            True
        """
        coxeter_data = CoxeterMatrix(coxeter_data)
        if names is None:
            names = 's'
        if isinstance(names, six.string_types):
            if ',' in names:
                names = [x.strip() for x in names.split(',')]
            else:
                names = [names + str(i) for i in coxeter_data.index_set()]
        names = tuple(names)
        if len(names) != coxeter_data.rank():
            raise ValueError("the number of generators must match"
                             " the rank of the Coxeter type")
        if all(m == Infinity
               for m in coxeter_data.coxeter_graph().edge_labels()):
            from sage.groups.raag import RightAngledArtinGroup
            return RightAngledArtinGroup(coxeter_data.coxeter_graph(), names)
        if not coxeter_data.is_finite():
            raise NotImplementedError
        if coxeter_data.coxeter_type().cartan_type().type() == 'A':
            from sage.groups.braid import BraidGroup
            return BraidGroup(coxeter_data.rank() + 1, names)
        return FiniteTypeArtinGroup(coxeter_data, names)
Beispiel #4
0
def braid_from_piecewise(strands):
    r"""
    Compute the braid corresponding to the piecewise linear curves strands.

    INPUT:

    - ``strands`` -- a list of lists of tuples ``(t, c)``, where ``t``
      is a number bewteen 0 and 1, and ``c`` is a complex number

    OUTPUT:

    The braid formed by the piecewise linear strands.

    EXAMPLES::

        sage: from sage.schemes.curves.zariski_vankampen import braid_from_piecewise # optional - sirocco
        sage: paths = [[(0, I), (0.2, -1 - 0.5*I), (0.8, -1), (1, -I)],
        ....:          [(0, -1), (0.5, -I), (1, 1)],
        ....:          [(0, 1), (0.5, 1 + I), (1, I)]]
        sage: braid_from_piecewise(paths) # optional - sirocco
        s0*s1
    """
    L = strands
    i = min(val[1][0] for val in L)
    totalpoints = [[[a[0][1].real(), a[0][1].imag()]] for a in L]
    indices = [1 for a in range(len(L))]
    while i < 1:
        for j, val in enumerate(L):
            if val[indices[j]][0] > i:
                xaux = val[indices[j] - 1][1]
                yaux = val[indices[j]][1]
                aaux = val[indices[j] - 1][0]
                baux = val[indices[j]][0]
                interpola = xaux + (yaux - xaux)*(i - aaux)/(baux - aaux)
                totalpoints[j].append([interpola.real(), interpola.imag()])
            else:
                totalpoints[j].append([val[indices[j]][1].real(), val[indices[j]][1].imag()])
                indices[j] = indices[j] + 1
        i = min(val[indices[k]][0] for k,val in enumerate(L))

    for j, val in enumerate(L):
         totalpoints[j].append([val[-1][1].real(), val[-1][1].imag()])

    braid = []
    G = SymmetricGroup(len(totalpoints))
    def sgn(x, y): # Opposite sign of cmp
        if x < y:
            return 1
        if x > y:
            return -1
        return 0
    for i in range(len(totalpoints[0]) - 1):
        l1 = [totalpoints[j][i] for j in range(len(L))]
        l2 = [totalpoints[j][i+1] for j in range(len(L))]
        M = [[l1[s], l2[s]] for s in range(len(l1))]
        M.sort()
        l1 = [a[0] for a in M]
        l2 = [a[1] for a in M]
        cruces = []
        for j in range(len(l2)):
            for k in range(j):
                if l2[j] < l2[k]:
                    t = (l1[j][0] - l1[k][0])/(l2[k][0] - l1[k][0] + l1[j][0] - l2[j][0])
                    s = sgn(l1[k][1]*(1 - t) + t*l2[k][1], l1[j][1]*(1 - t) + t*l2[j][1])
                    cruces.append([t, k, j, s])
        if cruces:
            cruces.sort()
            P = G(Permutation([]))
            while cruces:
                # we select the crosses in the same t
                crucesl = [c for c in cruces if c[0]==cruces[0][0]]
                crossesl = [(P(c[2]+1) - P(c[1]+1),c[1],c[2],c[3]) for c in crucesl]
                cruces = cruces[len(crucesl):]
                while crossesl:
                    crossesl.sort()
                    c = crossesl.pop(0)
                    braid.append(c[3]*min(map(P, [c[1] + 1, c[2] + 1])))
                    P = G(Permutation([(c[1] + 1, c[2] + 1)]))*P
                    crossesl = [(P(c[2]+1) - P(c[1]+1),c[1],c[2],c[3]) for c in crossesl]

    B = BraidGroup(len(L))
    return B(braid)
Beispiel #5
0
    def from_table(self, n, k):
        """
        Return a knot from its index in the Rolfsen table.

        INPUT:

        - ``n`` -- the crossing number
        - ``k`` -- a positive integer

        OUTPUT:

        the knot `K_{n,k}` in the Rolfsen table

        EXAMPLES::

            sage: K1 = Knots().from_table(6,3); K1
            Knot represented by 6 crossings
            sage: K1.alexander_polynomial()
            t^-2 - 3*t^-1 + 5 - 3*t + t^2

            sage: K2 = Knots().from_table(8,4); K2
            Knot represented by 9 crossings
            sage: K2.determinant()
            19
            sage: K2.signature()
            2

            sage: K3 = Knots().from_table(10,56); K3
            Knot represented by 11 crossings
            sage: K3.jones_polynomial()
            t^10 - 3*t^9 + 6*t^8 - 9*t^7 + 10*t^6 - 11*t^5 + 10*t^4 - 7*t^3
            + 5*t^2 - 2*t + 1

            sage: K4 = Knots().from_table(10,100)
            sage: K4.genus()
            4

        TESTS::

            sage: Knots().from_table(6,6)
            Traceback (most recent call last):
            ...
            ValueError: not found in the knot table

            sage: Knots().from_table(12,6)
            Traceback (most recent call last):
            ...
            ValueError: more than 10 crossings, not in the knot table

        REFERENCES:

        - KnotAtlas, http://katlas.math.toronto.edu/wiki/The_Rolfsen_Knot_Table
        """
        if n > 10:
            raise ValueError('more than 10 crossings, not in the knot table')
        from sage.groups.braid import BraidGroup
        if (n, k) in small_knots_table:
            m, word = small_knots_table[(n, k)]
            G = BraidGroup(m)
            return Knot(G(word))
        else:
            raise ValueError('not found in the knot table')
Beispiel #6
0
def braid_from_piecewise(strands):
    """
    Compute the braid corresponding to the piecewise linear curves strands.
    strands is a list whose elements are a list of pairs (x,y), where x is
    a real number between 0 and 1, and y is a complex number.
    
    INPUT: 
    
    - A list of lists of tuples (t, c), where t is a number bewteen 0 and 1,
    and c is a complex number.
    
    OUTPUT: 
    
    The braid formed by the piecewise linear strands.
    
    EXAMPLES::
    
        sage: paths = [[(0, I), (0.2, -1 - 0.5*I), (0.8, -1), (1, -I)], [(0, -1), (0.5, -I), (1, 1)], [(0, 1), (0.5, 1 + I), (1, I)]]
        sage: braid_from_piecewise(paths)
        s0*s1

    """
    L = strands
    i = min([L[k][1][0] for k in range(len(L))])
    totalpoints = [[[a[0][1].real(), a[0][1].imag()]] for a in L]
    indices = [1 for a in range(len(L))]
    while i < 1:
        for j in range(len(L)):
            if L[j][indices[j]][0] > i:
                xaux = L[j][indices[j] - 1][1]
                yaux = L[j][indices[j]][1]
                aaux = L[j][indices[j] - 1][0]
                baux = L[j][indices[j]][0]
                interpola = xaux + (yaux - xaux) * (i - aaux) / (baux - aaux)
                totalpoints[j].append([interpola.real(), interpola.imag()])
            else:
                totalpoints[j].append(
                    [L[j][indices[j]][1].real(), L[j][indices[j]][1].imag()])
                indices[j] = indices[j] + 1
        i = min([L[k][indices[k]][0] for k in range(len(L))])
    for j in range(len(L)):
        totalpoints[j].append([L[j][-1][1].real(), L[j][-1][1].imag()])
    braid = []
    G = SymmetricGroup(len(totalpoints))
    for i in range(len(totalpoints[0]) - 1):
        l1 = [totalpoints[j][i] for j in range(len(L))]
        l2 = [totalpoints[j][i + 1] for j in range(len(L))]
        M = [[l1[s], l2[s]] for s in range(len(l1))]
        M.sort()
        l1 = [a[0] for a in M]
        l2 = [a[1] for a in M]
        cruces = []
        for j in range(len(l2)):
            for k in range(j):
                if l2[j] < l2[k]:
                    t = (l1[j][0] - l1[k][0]) / (l2[k][0] - l1[k][0] +
                                                 l1[j][0] - l2[j][0])
                    s = cmp(l1[k][1] * (1 - t) + t * l2[k][1],
                            l1[j][1] * (1 - t) + t * l2[j][1])
                    cruces.append([t, k, j, -s])
        if len(cruces) > 0:
            cruces.sort()
            P = G(Permutation([]))
            while cruces:
                # we select the crosses in the same t
                crucesl = [c for c in cruces if c[0] == cruces[0][0]]
                crossesl = [(P(c[2] + 1) - P(c[1] + 1), c[1], c[2], c[3])
                            for c in crucesl]
                cruces = cruces[len(crucesl):]
                while crossesl:
                    crossesl.sort()
                    c = crossesl.pop(0)
                    braid.append(c[3] * min(map(P, [c[1] + 1, c[2] + 1])))
                    P = G(Permutation([(c[1] + 1, c[2] + 1)])) * P
                    crossesl = [(P(c[2] + 1) - P(c[1] + 1), c[1], c[2], c[3])
                                for c in crossesl]
    B = BraidGroup(len(L))
    return B(braid)
Beispiel #7
0
    def connected_sum(self, other):
        r"""
        Return the oriented connected sum of ``self`` and ``other``.

        .. NOTE::

            We give the knots an orientation based upon the braid
            representation.

        INPUT:

        - ``other`` -- a knot

        OUTPUT:

        A knot equivalent to the connected sum of ``self`` and ``other``.

        EXAMPLES::

            sage: B = BraidGroup(2)
            sage: trefoil = Knot(B([1,1,1]))
            sage: K = trefoil.connected_sum(trefoil); K
            Knot represented by 7 crossings
            sage: K.braid()
            s0^3*s2^3*s1

        .. PLOT::
            :width: 300 px

            B = BraidGroup(2)
            trefoil = Knot(B([1,1,1]))
            K = trefoil.connected_sum(trefoil)
            sphinx_plot(K.plot())

        ::

            sage: rev_trefoil = Knot(B([-1,-1,-1]))
            sage: K = trefoil.connected_sum(rev_trefoil); K
            Knot represented by 7 crossings
            sage: K.braid()
            s0^3*s2^-3*s1

        .. PLOT::
            :width: 300 px

            B = BraidGroup(2)
            t = Knot(B([1,1,1]))
            tr = Knot(B([-1,-1,-1]))
            K = t.connected_sum(tr)
            sphinx_plot(K.plot())

        REFERENCES:

        - :wikipedia:`Connected_sum`
        """
        from sage.groups.braid import BraidGroup
        b1 = self.braid()
        b2 = other.braid()

        b1s = b1.strands()
        b2s = b2.strands()

        B = BraidGroup(b1s + b2s)

        return Knot(
            B(
                list(b1.Tietze()) + [(abs(i) + b2s) * Integer(i).sign()
                                     for i in b2.Tietze()] + [b1s]))