# Braid groups¶

Braid groups are implemented as a particular case of finitely presented groups, but with a lot of specific methods for braids.

A braid group can be created by giving the number of strands, and the name of the generators:

sage: BraidGroup(3)
Braid group on 3 strands
sage: BraidGroup(3,'a')
Braid group on 3 strands
sage: BraidGroup(3,'a').gens()
(a0, a1)
sage: BraidGroup(3,'a,b').gens()
(a, b)


The elements can be created by operating with the generators, or by passing a list with the indices of the letters to the group:

sage: B.<s0,s1,s2> = BraidGroup(4)
sage: s0*s1*s0
s0*s1*s0
sage: B([1,2,1])
s0*s1*s0


The mapping class action of the braid group over the free group is also implemented, see MappingClassGroupAction for an explanation. This action is left multiplication of a free group element by a braid:

sage: B.<b0,b1,b2> = BraidGroup()
sage: F.<f0,f1,f2,f3> = FreeGroup()
sage: B.strands() == F.rank()   # necessary for the action to be defined
True
sage: f1 * b1
f1*f2*f1^-1
sage: f0 * b1
f0
sage: f1 * b1
f1*f2*f1^-1
sage: f1^-1 * b1
f1*f2^-1*f1^-1


AUTHORS:

• Miguel Angel Marco Buzunariz

• Volker Braun

• Søren Fuglede Jørgensen

• Robert Lipshitz

• Thierry Monteil: add a __hash__ method consistent with the word problem to ensure correct Cayley graph computations.

• Sebastian Oehms (July and Nov 2018): add other versions for burau_matrix (unitary + simple, see trac ticket #25760 and trac ticket #26657)

• Moritz Firsching (Sept 2021): Colored Jones polynomial

class sage.groups.braid.Braid(parent, x, check=True)

Bases: sage.groups.artin.FiniteTypeArtinGroupElement

An element of a braid group.

It is a particular case of element of a finitely presented group.

EXAMPLES:

sage: B.<s0,s1,s2> = BraidGroup(4)
sage: B
Braid group on 4 strands
sage: s0*s1/s2/s1
s0*s1*s2^-1*s1^-1
sage: B((1, 2, -3, -2))
s0*s1*s2^-1*s1^-1

LKB_matrix(variables='x,y')

Return the Lawrence-Krammer-Bigelow representation matrix.

The matrix is expressed in the basis $$\{e_{i, j} \mid 1\leq i < j \leq n\}$$, where the indices are ordered lexicographically. It is a matrix whose entries are in the ring of Laurent polynomials on the given variables. By default, the variables are 'x' and 'y'.

INPUT:

• variables – string (default: 'x,y'). A string containing the names of the variables, separated by a comma.

OUTPUT:

The matrix corresponding to the Lawrence-Krammer-Bigelow representation of the braid.

EXAMPLES:

sage: B = BraidGroup(3)
sage: b = B([1, 2, 1])
sage: b.LKB_matrix()
[             0 -x^4*y + x^3*y         -x^4*y]
[             0         -x^3*y              0]
[        -x^2*y  x^3*y - x^2*y              0]
sage: c = B([2, 1, 2])
sage: c.LKB_matrix()
[             0 -x^4*y + x^3*y         -x^4*y]
[             0         -x^3*y              0]
[        -x^2*y  x^3*y - x^2*y              0]


REFERENCES:

TL_matrix(drain_size, variab=None, sparse=True)

Return the matrix representation of the Temperley–Lieb–Jones representation of the braid in a certain basis.

The basis is given by non-intersecting pairings of $$(n+d)$$ points, where $$n$$ is the number of strands, $$d$$ is given by drain_size, and the pairings satisfy certain rules. See TL_basis_with_drain() for details.

We use the convention that the eigenvalues of the standard generators are $$1$$ and $$-A^4$$, where $$A$$ is a variable of a Laurent polynomial ring.

When $$d = n - 2$$ and the variables are picked appropriately, the resulting representation is equivalent to the reduced Burau representation.

INPUT:

• drain_size – integer between 0 and the number of strands (both inclusive)

• variab – variable (default: None); the variable in the entries of the matrices; if None, then use a default variable in $$\ZZ[A,A^{-1}]$$

• sparse – boolean (default: True); whether or not the result should be given as a sparse matrix

OUTPUT:

The matrix of the TL representation of the braid.

The parameter sparse can be set to False if it is expected that the resulting matrix will not be sparse. We currently make no attempt at guessing this.

EXAMPLES:

Let us calculate a few examples for $$B_4$$ with $$d = 0$$:

sage: B = BraidGroup(4)
sage: b = B([1, 2, -3])
sage: b.TL_matrix(0)
[1 - A^4   -A^-2]
[   -A^6       0]
sage: R.<x> = LaurentPolynomialRing(GF(2))
sage: b.TL_matrix(0, variab=x)
[1 + x^4    x^-2]
[    x^6       0]
sage: b = B([])
sage: b.TL_matrix(0)
[1 0]
[0 1]


Test of one of the relations in $$B_8$$:

sage: B = BraidGroup(8)
sage: d = 0
sage: B([4,5,4]).TL_matrix(d) == B([5,4,5]).TL_matrix(d)
True


An element of the kernel of the Burau representation, following [Big1999]:

sage: B = BraidGroup(6)
sage: psi1 = B([4, -5, -2, 1])
sage: psi2 = B([-4, 5, 5, 2, -1, -1])
sage: w1 = psi1^(-1) * B([3]) * psi1
sage: w2 = psi2^(-1) * B([3]) * psi2
sage: (w1 * w2 * w1^(-1) * w2^(-1)).TL_matrix(4)
[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 0]
[0 0 0 0 1]


REFERENCES:

alexander_polynomial(var='t', normalized=True)

Return the Alexander polynomial of the closure of the braid.

INPUT:

• var – string (default: 't'); the name of the variable in the entries of the matrix

• normalized – boolean (default: True); whether to return the normalized Alexander polynomial

OUTPUT:

The Alexander polynomial of the braid closure of the braid.

This is computed using the reduced Burau representation. The unnormalized Alexander polynomial is a Laurent polynomial, which is only well-defined up to multiplication by plus or minus times a power of $$t$$.

We normalize the polynomial by dividing by the largest power of $$t$$ and then if the resulting constant coefficient is negative, we multiply by $$-1$$.

EXAMPLES:

We first construct the trefoil:

sage: B = BraidGroup(3)
sage: b = B([1,2,1,2])
sage: b.alexander_polynomial(normalized=False)
1 - t + t^2
sage: b.alexander_polynomial()
t^-2 - t^-1 + 1


Next we construct the figure 8 knot:

sage: b = B([-1,2,-1,2])
sage: b.alexander_polynomial(normalized=False)
-t^-2 + 3*t^-1 - 1
sage: b.alexander_polynomial()
t^-2 - 3*t^-1 + 1


Our last example is the Kinoshita-Terasaka knot:

sage: B = BraidGroup(4)
sage: b = B([1,1,1,3,3,2,-3,-1,-1,2,-1,-3,-2])
sage: b.alexander_polynomial(normalized=False)
-t^-1
sage: b.alexander_polynomial()
1


REFERENCES:

Return the annular Khovanov complex of the closure of a braid, as defined in [BG2013]

INPUT:

• qagrad – tuple of quantum and annular grading for which to compute the chain complex. If not specified all gradings are computed.

• ring – (default: ZZ) the coefficient ring.

OUTPUT:

The annular Khovanov complex of the braid, given as a dictionary whose keys are tuples of quantum and annular grading. If qagrad is specified only return the chain complex of that grading.

EXAMPLES:

sage: B=BraidGroup(3)
sage: b=B([1,-2,1,-2])
sage: C=b.annular_khovanov_complex()
sage: C
{(-5, -1): Chain complex with at most 1 nonzero terms over Integer Ring,
(-3, -3): Chain complex with at most 1 nonzero terms over Integer Ring,
(-3, -1): Chain complex with at most 2 nonzero terms over Integer Ring,
(-3, 1): Chain complex with at most 1 nonzero terms over Integer Ring,
(-1, -1): Chain complex with at most 5 nonzero terms over Integer Ring,
(-1, 1): Chain complex with at most 2 nonzero terms over Integer Ring,
(1, -1): Chain complex with at most 2 nonzero terms over Integer Ring,
(1, 1): Chain complex with at most 5 nonzero terms over Integer Ring,
(3, -1): Chain complex with at most 1 nonzero terms over Integer Ring,
(3, 1): Chain complex with at most 2 nonzero terms over Integer Ring,
(3, 3): Chain complex with at most 1 nonzero terms over Integer Ring,
(5, 1): Chain complex with at most 1 nonzero terms over Integer Ring}
sage: C[1,-1].homology()
{1: Z x Z, 2: 0}


Return the annular Khovanov homology of a closure of a braid.

INPUT:

• qagrad – (optional) tuple of quantum and annular grading for which to compute the homology

• ring – (default: ZZ) the coefficient ring

OUTPUT:

If qagrad is None, return a dictionary of homogies in all gradings indexed by grading. If qagrad is specified, return homology of that grading.

Note

This is a simple wrapper around annular_khovanov_complex() to compute homology from it.

EXAMPLES:

sage: B = BraidGroup(4)
sage: b = B([1,3,-2])
sage: b.annular_khovanov_homology()
{(-3, -4): {0: Z},
(-3, -2): {-1: Z},
(-1, -2): {-1: 0, 0: Z x Z x Z, 1: 0},
(-1, 0): {-1: Z x Z},
(1, -2): {1: Z x Z},
(1, 0): {-1: 0, 0: Z x Z x Z x Z, 1: 0, 2: 0},
(1, 2): {-1: Z},
(3, 0): {1: Z x Z x Z, 2: 0},
(3, 2): {-1: 0, 0: Z x Z x Z, 1: 0},
(5, 0): {2: Z},
(5, 2): {1: Z x Z},
(5, 4): {0: Z}}

sage: B = BraidGroup(2)
sage: b = B([1,1,1])
sage: b.annular_khovanov_homology((7,0))
{2: 0, 3: C2}

burau_matrix(var='t', reduced=False)

Return the Burau matrix of the braid.

INPUT:

• var – string (default: 't'); the name of the variable in the entries of the matrix

• reduced – boolean (default: False); whether to return the reduced or unreduced Burau representation, can be one of the following:

• True or 'increasing' - returns the reduced form using the basis given by $$e_1 - e_i$$ for $$2 \leq i \leq n$$

• 'unitary' - the unitary form according to Squier [Squ1984]

• 'simple' - returns the reduced form using the basis given by simple roots $$e_i - e_{i+1}$$, which yields the matrices given on the Wikipedia page

OUTPUT:

The Burau matrix of the braid. It is a matrix whose entries are Laurent polynomials in the variable var. If reduced is True, return the matrix for the reduced Burau representation instead in the format specified. If reduced is 'unitary', a triple M, Madj, H is returned, where M is the Burau matrix in the unitary form, Madj the adjoined to M and H the hermitian form.

EXAMPLES:

sage: B = BraidGroup(4)
sage: B.inject_variables()
Defining s0, s1, s2
sage: b = s0*s1/s2/s1
sage: b.burau_matrix()
[       1 - t            0      t - t^2          t^2]
[           1            0            0            0]
[           0            0            1            0]
[           0         t^-2 -t^-2 + t^-1    -t^-1 + 1]
sage: s2.burau_matrix('x')
[    1     0     0     0]
[    0     1     0     0]
[    0     0 1 - x     x]
[    0     0     1     0]
sage: s0.burau_matrix(reduced=True)
[-t  0  0]
[-t  1  0]
[-t  0  1]


Using the different reduced forms:

sage: b.burau_matrix(reduced='simple')
[    1 - t -t^-1 + 1        -1]
[        1 -t^-1 + 1        -1]
[        1     -t^-1         0]

sage: M, Madj, H = b.burau_matrix(reduced='unitary')
sage: M
[-t^-2 + 1         t       t^2]
[ t^-1 - t   1 - t^2      -t^3]
[    -t^-2     -t^-1         0]
[  1 - t^2 -t^-1 + t      -t^2]
[     t^-1 -t^-2 + 1        -t]
[     t^-2     -t^-3         0]
sage: H
[t^-1 + t       -1        0]
[      -1 t^-1 + t       -1]
[       0       -1 t^-1 + t]
sage: M * H * Madj == H
True


REFERENCES:

centralizer()

Return a list of generators of the centralizer of the braid.

EXAMPLES:

sage: B = BraidGroup(4)
sage: b = B([2, 1, 3, 2])
sage: b.centralizer()
[s1*s0*s2*s1, s0*s2]

colored_jones_polynomial(N, variab=None, try_inverse=True)

Return the colored Jones polynomial of the trace closure of the braid.

INPUT:

• N – integer; the number of colors

• variab – (default: $$q$$) the variable in the resulting Laurent polynomial

• try_inverse – boolean (default: True); if True, attempt a faster calculation by using the inverse of the braid

ALGORITHM:

The algorithm used is described in [HL2018]. We follow their notation, but work in a suitable free algebra over a Laurent polynomial ring in one variable to simplify bookkeeping.

EXAMPLES:

sage: trefoil = BraidGroup(2)([1,1,1])
sage: trefoil.colored_jones_polynomial(2)
q + q^3 - q^4
sage: trefoil.colored_jones_polynomial(4)
q^3 + q^7 - q^10 + q^11 - q^13 - q^14 + q^15 - q^17
+ q^19 + q^20 - q^21
sage: trefoil.inverse().colored_jones_polynomial(4)
-q^-21 + q^-20 + q^-19 - q^-17 + q^-15 - q^-14 - q^-13
+ q^-11 - q^-10 + q^-7 + q^-3

sage: figure_eight = BraidGroup(3)([-1, 2, -1, 2])
sage: figure_eight.colored_jones_polynomial(2)
q^-2 - q^-1 + 1 - q + q^2
sage: figure_eight.colored_jones_polynomial(3, 'Q')
Q^-6 - Q^-5 - Q^-4 + 2*Q^-3 - Q^-2 - Q^-1 + 3 - Q - Q^2
+ 2*Q^3 - Q^4 - Q^5 + Q^6

components_in_closure()

Return the number of components of the trace closure of the braid.

OUTPUT:

Positive integer.

EXAMPLES:

sage: B = BraidGroup(5)
sage: b = B([1, -3])  # Three disjoint unknots
sage: b.components_in_closure()
3
sage: b = B([1, 2, 3, 4])  # The unknot
sage: b.components_in_closure()
1
sage: B = BraidGroup(4)
sage: K11n42 = B([1, -2, 3, -2, 3, -2, -2, -1, 2, -3, -3, 2, 2])
sage: K11n42.components_in_closure()
1

conjugating_braid(other)

Return a conjugating braid, if it exists.

INPUT:

• other – the other braid to look for conjugating braid

EXAMPLES:

sage: B = BraidGroup(3)
sage: a = B([2, 2, -1, -1])
sage: b = B([2, 1, 2, 1])
sage: c = b * a / b
sage: d = a.conjugating_braid(c)
sage: d * c / d == a
True
sage: d
s1*s0
sage: d * a / d == c
False

deformed_burau_matrix(variab='q')

Return the deformed Burau matrix of the braid.

INPUT:

• variab – variable (default: q); the variable in the resulting laurent polynomial, which is the base ring for the free algebra constructed

OUTPUT:

A matrix with elements in the free algebra $$self._algebra$$.

EXAMPLES:

sage: B = BraidGroup(4)
sage: b = B([1, 2, -3, -2, 3, 1])
sage: db = b.deformed_burau_matrix(); db
[                                ap_0*ap_5 ... bp_0*ap_1*cm_3*bp_4]
...
[                           bm_2*bm_3*cp_5 ...      bm_2*am_3*bp_4]


We check how this relates to the nondeformed Burau matrix:

sage: def subs_gen(gen, q):
....:     gen_str = str(gen)
....:     v = q if 'p' in gen_str else 1/q
....:     if 'b' in gen_str:
....:         return v
....:     elif 'a' in gen_str:
....:         return 1 - v
....:     else:
....:         return 1
sage: db_base = db.parent().base_ring()
sage: q = db_base.base_ring().gen()
sage: db_simp = db.subs({gen: subs_gen(gen, q)
....:                    for gen in db_base.gens()})
sage: db_simp
[ (1-2*q+q^2)      (q-q^2)  (q-q^2+q^3)    (q^2-q^3)]
[       (1-q)            q            0            0]
[           0            0        (1-q)            q]
[      (q^-2)            0 -(q^-2-q^-1)    -(q^-1-1)]
sage: burau = b.burau_matrix(); burau
[1 - 2*t + t^2       t - t^2 t - t^2 + t^3     t^2 - t^3]
[        1 - t             t             0             0]
[            0             0         1 - t             t]
[         t^-2             0  -t^-2 + t^-1     -t^-1 + 1]
sage: t = burau.parent().base_ring().gen()
sage: burau.subs({t:q}).change_ring(db_base) == db_simp
True

gcd(other)

Return the greatest common divisor of the two braids.

INPUT:

• other – the other braid with respect with the gcd is computed

EXAMPLES:

sage: B = BraidGroup(3)
sage: b = B([1, 2, -1, -2, -2, 1])
sage: c = B([1, 2, 1])
sage: b.gcd(c)
s0^-1*s1^-1*s0^-2*s1^2*s0
sage: c.gcd(b)
s0^-1*s1^-1*s0^-2*s1^2*s0

is_conjugated(other)

Check if the two braids are conjugated.

INPUT:

• other – the other braid to check for conjugacy

EXAMPLES:

sage: B = BraidGroup(3)
sage: a = B([2, 2, -1, -1])
sage: b = B([2, 1, 2, 1])
sage: c = b * a / b
sage: c.is_conjugated(a)
True
sage: c.is_conjugated(b)
False

is_periodic()

Check whether the braid is periodic.

EXAMPLES:

sage: B = BraidGroup(3)
sage: a = B([2, 2, -1, -1, 2, 2])
sage: b = B([2, 1, 2, 1])
sage: a.is_periodic()
False
sage: b.is_periodic()
True

is_pseudoanosov()

Check if the braid is pseudo-anosov.

EXAMPLES:

sage: B = BraidGroup(3)
sage: a = B([2, 2, -1, -1, 2, 2])
sage: b = B([2, 1, 2, 1])
sage: a.is_pseudoanosov()
True
sage: b.is_pseudoanosov()
False

is_reducible()

Check whether the braid is reducible.

EXAMPLES:

sage: B = BraidGroup(3)
sage: b = B([1, 2, -1])
sage: b.is_reducible()
True
sage: a = B([2, 2, -1, -1, 2, 2])
sage: a.is_reducible()
False

jones_polynomial(variab=None, skein_normalization=False)

Return the Jones polynomial of the trace closure of the braid.

The normalization is so that the unknot has Jones polynomial $$1$$. If skein_normalization is True, the variable of the result is replaced by a itself to the power of $$4$$, so that the result agrees with the conventions of [Lic1997] (which in particular differs slightly from the conventions used otherwise in this class), had one used the conventional Kauffman bracket variable notation directly.

If variab is None return a polynomial in the variable $$A$$ or $$t$$, depending on the value skein_normalization. In particular, if skein_normalization is False, return the result in terms of the variable $$t$$, also used in [Lic1997].

INPUT:

• variab – variable (default: None); the variable in the resulting polynomial; if unspecified, use either a default variable in $$ZZ[A,A^{-1}]$$ or the variable $$t$$ in the symbolic ring

• skein_normalization – boolean (default: False); determines the variable of the resulting polynomial

OUTPUT:

If skein_normalization if False, this returns an element in the symbolic ring as the Jones polynomial of the closure might have fractional powers when the closure of the braid is not a knot. Otherwise the result is a Laurent polynomial in variab.

EXAMPLES:

The unknot:

sage: B = BraidGroup(9)
sage: b = B([1, 2, 3, 4, 5, 6, 7, 8])
sage: b.jones_polynomial()
1


sage: B = BraidGroup(2)
sage: b = B([])
sage: b.jones_polynomial()
-sqrt(t) - 1/sqrt(t)


sage: B = BraidGroup(2)
sage: b = B([-1,-1])
sage: b.jones_polynomial()
-1/sqrt(t) - 1/t^(5/2)


Different representations of the trefoil and one of its mirror:

sage: B = BraidGroup(2)
sage: b = B([-1, -1, -1])
sage: b.jones_polynomial(skein_normalization=True)
-A^-16 + A^-12 + A^-4
sage: b.jones_polynomial()
1/t + 1/t^3 - 1/t^4
sage: B = BraidGroup(3)
sage: b = B([-1, -2, -1, -2])
sage: b.jones_polynomial(skein_normalization=True)
-A^-16 + A^-12 + A^-4
sage: R.<x> = LaurentPolynomialRing(GF(2))
sage: b.jones_polynomial(skein_normalization=True, variab=x)
x^-16 + x^-12 + x^-4
sage: B = BraidGroup(3)
sage: b = B([1, 2, 1, 2])
sage: b.jones_polynomial(skein_normalization=True)
A^4 + A^12 - A^16


K11n42 (the mirror of the “Kinoshita-Terasaka” knot) and K11n34 (the mirror of the “Conway” knot):

sage: B = BraidGroup(4)
sage: b11n42 = B([1, -2, 3, -2, 3, -2, -2, -1, 2, -3, -3, 2, 2])
sage: b11n34 = B([1, 1, 2, -3, 2, -3, 1, -2, -2, -3, -3])
sage: bool(b11n42.jones_polynomial() == b11n34.jones_polynomial())
True

lcm(other)

Return the least common multiple of the two braids.

INPUT:

• other – the other braid with respect with the lcm is computed

EXAMPLES:

sage: B = BraidGroup(3)
sage: b = B([1, 2, -1, -2, -2, 1])
sage: c = B([1, 2, 1])
sage: b.lcm(c)
(s0*s1)^2*s0

markov_trace(variab=None, normalized=True)

Return the Markov trace of the braid.

The normalization is so that in the underlying braid group representation, the eigenvalues of the standard generators of the braid group are $$1$$ and $$-A^4$$.

INPUT:

• variab – variable (default: None); the variable in the resulting polynomial; if None, then use the variable $$A$$ in $$\ZZ[A,A^{-1}]$$

• normalized - boolean (default: True); if specified to be False, return instead a rescaled Laurent polynomial version of the Markov trace

OUTPUT:

If normalized is False, return instead the Markov trace of the braid, normalized by a factor of $$(A^2+A^{-2})^n$$. The result is then a Laurent polynomial in variab. Otherwise it is a quotient of Laurent polynomials in variab.

EXAMPLES:

sage: B = BraidGroup(4)
sage: b = B([1, 2, -3])
sage: mt = b.markov_trace(); mt
A^4/(A^12 + 3*A^8 + 3*A^4 + 1)
sage: mt.factor()
A^4 * (A^4 + 1)^-3


We now give the non-normalized Markov trace:

sage: mt = b.markov_trace(normalized=False); mt
A^-4 + 1
sage: mt.parent()
Univariate Laurent Polynomial Ring in A over Integer Ring

mirror_image()

Return the image of self under the mirror involution (see BraidGroup_class.mirror_involution()). The link closure of it is mirrored to the closure of self (see the example below of a positive amphicheiral knot).

EXAMPLES:

sage: B5 = BraidGroup(5)
sage: b  = B5((-1, 2, -3, -1, -3, 4, 2, -3, 2, 4, 2, -3)) # closure K12a_427
sage: bm = b.mirror_image(); bm
s0*s1^-1*s2*s0*s2*s3^-1*s1^-1*s2*s1^-1*s3^-1*s1^-1*s2
sage: bm.is_conjugated(b)
True
sage: bm.is_conjugated(~b)
False

permutation()

Return the permutation induced by the braid in its strands.

OUTPUT:

A permutation.

EXAMPLES:

sage: B.<s0,s1,s2> = BraidGroup()
sage: b = s0*s1/s2/s1
sage: b.permutation()
[4, 1, 3, 2]
sage: b.permutation().cycle_string()
'(1,4,2)'

plot(color='rainbow', orientation='bottom-top', gap=0.05, aspect_ratio=1, axes=False, **kwds)

Plot the braid

The following options are available:

• color – (default: 'rainbow') the color of the strands. Possible values are:

• 'rainbow', uses rainbow() according to the number of strands.

• a valid color name for bezier_path() and line(). Used for all strands.

• a list or a tuple of colors for each individual strand.

• orientation – (default: 'bottom-top') determines how the braid is printed. The possible values are:

• 'bottom-top', the braid is printed from bottom to top

• 'top-bottom', the braid is printed from top to bottom

• 'left-right', the braid is printed from left to right

• gap – floating point number (default: 0.05). determines the size of the gap left when a strand goes under another.

• aspect_ratio – floating point number (default: 1). The aspect ratio.

• **kwds – other keyword options that are passed to bezier_path() and line().

EXAMPLES:

sage: B = BraidGroup(4, 's')
sage: b = B([1, 2, 3, 1, 2, 1])
sage: b.plot()
Graphics object consisting of 30 graphics primitives
sage: b.plot(color=["red", "blue", "red", "blue"])
Graphics object consisting of 30 graphics primitives

sage: B.<s,t> = BraidGroup(3)
sage: b = t^-1*s^2
sage: b.plot(orientation="left-right", color="red")
Graphics object consisting of 12 graphics primitives

plot3d(color='rainbow')

Plots the braid in 3d.

The following option is available:

• color – (default: 'rainbow') the color of the strands. Possible values are:

• 'rainbow', uses rainbow() according to the number of strands.

• a valid color name for bezier3d(). Used for all strands.

• a list or a tuple of colors for each individual strand.

EXAMPLES:

sage: B = BraidGroup(4, 's')
sage: b = B([1, 2, 3, 1, 2, 1])
sage: b.plot3d()
Graphics3d Object
sage: b.plot3d(color="red")
Graphics3d Object
sage: b.plot3d(color=["red", "blue", "red", "blue"])
Graphics3d Object

reverse()

Return the reverse of self obtained by reversing the order of the generators in its word. This defines an anti-involution on the braid group. The link closure of it has the reversed orientation (see the example below of a non reversible knot).

EXAMPLES:

sage: b  = BraidGroup(3)((1, 1, -2, 1, -2, 1, -2, -2))  # closure K8_17
sage: br = b.reverse(); br
s1^-1*(s1^-1*s0)^3*s0
sage: br.is_conjugated(b)
False

right_normal_form()

Return the right normal form of the braid.

EXAMPLES:

sage: B = BraidGroup(4)
sage: b = B([1, 2, 1, -2, 3, 1])
sage: b.right_normal_form()
(s1*s0, s0*s2, 1)

rigidity()

Return the rigidity of self.

EXAMPLES:

sage: B = BraidGroup(3)
sage: b = B([2, 1, 2, 1])
sage: a = B([2, 2, -1, -1, 2, 2])
sage: a.rigidity()
6
sage: b.rigidity()
0

sliding_circuits()

Return the sliding circuits of the braid.

OUTPUT:

A list of sliding circuits. Each sliding circuit is itself a list of braids.

EXAMPLES:

sage: B = BraidGroup(3)
sage: a = B([2, 2, -1, -1, 2, 2])
sage: a.sliding_circuits()
[[(s0^-1*s1^-1*s0^-1)^2*s1^3*s0^2*s1^3],
[s0^-1*s1^-1*s0^-2*s1^-1*s0^2*s1^2*s0^3],
[s0^-1*s1^-1*s0^-2*s1^-1*s0^3*s1^2*s0^2],
[(s0^-1*s1^-1*s0^-1)^2*s1^4*s0^2*s1^2],
[(s0^-1*s1^-1*s0^-1)^2*s1^2*s0^2*s1^4],
[s0^-1*s1^-1*s0^-2*s1^-1*s0*s1^2*s0^4],
[(s0^-1*s1^-1*s0^-1)^2*s1^5*s0^2*s1],
[s0^-1*s1^-1*s0^-2*s1^-1*s0^4*s1^2*s0],
[(s0^-1*s1^-1*s0^-1)^2*s1*s0^2*s1^5],
[s0^-1*s1^-1*s0^-2*s1*s0^5],
[(s0^-1*s1^-1*s0^-1)^2*s1*s0^6*s1],
[s0^-1*s1^-1*s0^-2*s1^5*s0]]
sage: b = B([2, 1, 2, 1])
sage: b.sliding_circuits()
[[s0*s1*s0^2, (s0*s1)^2]]

strands()

Return the number of strands in the braid.

EXAMPLES:

sage: B = BraidGroup(4)
sage: b = B([1, 2, -1, 3, -2])
sage: b.strands()
4

super_summit_set()

Return a list with the super summit set of the braid

EXAMPLES:

sage: B = BraidGroup(3)
sage: b = B([1, 2, -1, -2, -2, 1])
sage: b.super_summit_set()
[s0^-1*s1^-1*s0^-2*s1^2*s0^2,
(s0^-1*s1^-1*s0^-1)^2*s1^2*s0^3*s1,
(s0^-1*s1^-1*s0^-1)^2*s1*s0^3*s1^2,
s0^-1*s1^-1*s0^-2*s1^-1*s0*s1^3*s0]

thurston_type()

Return the thurston_type of self.

OUTPUT:

One of 'reducible', 'periodic' or 'pseudo-anosov'.

EXAMPLES:

sage: B = BraidGroup(3)
sage: b = B([1, 2, -1])
sage: b.thurston_type()
'reducible'
sage: a = B([2, 2, -1, -1, 2, 2])
sage: a.thurston_type()
'pseudo-anosov'
sage: c = B([2, 1, 2, 1])
sage: c.thurston_type()
'periodic'

tropical_coordinates()

Return the tropical coordinates of self in the braid group $$B_n$$.

OUTPUT:

• a list of $$2n$$ tropical integers

EXAMPLES:

sage: B = BraidGroup(3)
sage: b = B([1])
sage: tc = b.tropical_coordinates(); tc
[1, 0, 0, 2, 0, 1]
sage: tc[0].parent()
Tropical semiring over Integer Ring

sage: b = B([-2, -2, -1, -1, 2, 2, 1, 1])
sage: b.tropical_coordinates()
[1, -19, -12, 9, 0, 13]


REFERENCES:

ultra_summit_set()

Return a list with the orbits of the ultra summit set of self

EXAMPLES:

sage: B = BraidGroup(3)
sage: a = B([2, 2, -1, -1, 2, 2])
sage: b = B([2, 1, 2, 1])
sage: b.ultra_summit_set()
[[s0*s1*s0^2, (s0*s1)^2]]
sage: a.ultra_summit_set()
[[(s0^-1*s1^-1*s0^-1)^2*s1^3*s0^2*s1^3,
(s0^-1*s1^-1*s0^-1)^2*s1^2*s0^2*s1^4,
(s0^-1*s1^-1*s0^-1)^2*s1*s0^2*s1^5,
s0^-1*s1^-1*s0^-2*s1^5*s0,
(s0^-1*s1^-1*s0^-1)^2*s1^5*s0^2*s1,
(s0^-1*s1^-1*s0^-1)^2*s1^4*s0^2*s1^2],
[s0^-1*s1^-1*s0^-2*s1^-1*s0^2*s1^2*s0^3,
s0^-1*s1^-1*s0^-2*s1^-1*s0*s1^2*s0^4,
s0^-1*s1^-1*s0^-2*s1*s0^5,
(s0^-1*s1^-1*s0^-1)^2*s1*s0^6*s1,
s0^-1*s1^-1*s0^-2*s1^-1*s0^4*s1^2*s0,
s0^-1*s1^-1*s0^-2*s1^-1*s0^3*s1^2*s0^2]]

sage.groups.braid.BraidGroup(n=None, names='s')

Construct a Braid Group

INPUT:

• n – integer or None (default). The number of strands. If not specified the names are counted and the group is assumed to have one more strand than generators.

• names – string or list/tuple/iterable of strings (default: 'x'). The generator names or name prefix.

EXAMPLES:

sage: B.<a,b> = BraidGroup();  B
Braid group on 3 strands
sage: H = BraidGroup('a, b')
sage: B is H
True
sage: BraidGroup(3)
Braid group on 3 strands


The entry can be either a string with the names of the generators, or the number of generators and the prefix of the names to be given. The default prefix is 's'

sage: B = BraidGroup(3); B.generators()
(s0, s1)
sage: BraidGroup(3, 'g').generators()
(g0, g1)


Since the word problem for the braid groups is solvable, their Cayley graph can be locally obtained as follows (see trac ticket #16059):

sage: def ball(group, radius):
....:     ret = set()
....:     for length in range(1, radius):
....:         for w in Words(alphabet=group.gens(), length=length):
....:     return ret
sage: B = BraidGroup(4)
sage: GB = B.cayley_graph(elements=ball(B, 4), generators=B.gens()); GB
Digraph on 31 vertices


Since the braid group has nontrivial relations, this graph contains less vertices than the one associated to the free group (which is a tree):

sage: F = FreeGroup(3)
sage: GF = F.cayley_graph(elements=ball(F, 4), generators=F.gens()); GF
Digraph on 40 vertices

class sage.groups.braid.BraidGroup_class(names)

Bases: sage.groups.artin.FiniteTypeArtinGroup

The braid group on $$n$$ strands.

EXAMPLES:

sage: B1 = BraidGroup(5)
sage: B1
Braid group on 5 strands
sage: B2 = BraidGroup(3)
sage: B1==B2
False
sage: B2 is BraidGroup(3)
True

Element

alias of Braid

TL_basis_with_drain(drain_size)

Return a basis of a summand of the Temperley–Lieb–Jones representation of self.

The basis elements are given by non-intersecting pairings of $$n+d$$ points in a square with $$n$$ points marked ‘on the top’ and $$d$$ points ‘on the bottom’ so that every bottom point is paired with a top point. Here, $$n$$ is the number of strands of the braid group, and $$d$$ is specified by drain_size.

A basis element is specified as a list of integers obtained by considering the pairings as obtained as the ‘highest term’ of trivalent trees marked by Jones–Wenzl projectors (see e.g. [Wan2010]). In practice, this is a list of non-negative integers whose first element is drain_size, whose last element is $$0$$, and satisfying that consecutive integers have difference $$1$$. Moreover, the length of each basis element is $$n + 1$$.

Given these rules, the list of lists is constructed recursively in the natural way.

INPUT:

• drain_size – integer between 0 and the number of strands (both inclusive)

OUTPUT:

A list of basis elements, each of which is a list of integers.

EXAMPLES:

We calculate the basis for the appropriate vector space for $$B_5$$ when $$d = 3$$:

sage: B = BraidGroup(5)
sage: B.TL_basis_with_drain(3)
[[3, 4, 3, 2, 1, 0],
[3, 2, 3, 2, 1, 0],
[3, 2, 1, 2, 1, 0],
[3, 2, 1, 0, 1, 0]]


The number of basis elements hopefully corresponds to the general formula for the dimension of the representation spaces:

sage: B = BraidGroup(10)
sage: d = 2
sage: B.dimension_of_TL_space(d) == len(B.TL_basis_with_drain(d))
True

TL_representation(drain_size, variab=None)

Return representation matrices of the Temperley–Lieb–Jones representation of standard braid group generators and inverses of self.

The basis is given by non-intersecting pairings of $$(n+d)$$ points, where $$n$$ is the number of strands, and $$d$$ is given by drain_size, and the pairings satisfy certain rules. See TL_basis_with_drain() for details. This basis has the useful property that all resulting entries can be regarded as Laurent polynomials.

We use the convention that the eigenvalues of the standard generators are $$1$$ and $$-A^4$$, where $$A$$ is the generator of the Laurent polynomial ring.

When $$d = n - 2$$ and the variables are picked appropriately, the resulting representation is equivalent to the reduced Burau representation. When $$d = n$$, the resulting representation is trivial and 1-dimensional.

INPUT:

• drain_size – integer between 0 and the number of strands (both inclusive)

• variab – variable (default: None); the variable in the entries of the matrices; if None, then use a default variable in $$\ZZ[A,A^{-1}]$$

OUTPUT:

A list of matrices corresponding to the representations of each of the standard generators and their inverses.

EXAMPLES:

sage: B = BraidGroup(4)
sage: B.TL_representation(0)
[(
[   1    0]  [    1     0]
[ A^2 -A^4], [ A^-2 -A^-4]
),
(
[-A^4  A^2]  [-A^-4  A^-2]
[   0    1], [    0     1]
),
(
[   1    0]  [    1     0]
[ A^2 -A^4], [ A^-2 -A^-4]
)]
sage: R.<A> = LaurentPolynomialRing(GF(2))
sage: B.TL_representation(0, variab=A)
[(
[  1   0]  [   1    0]
[A^2 A^4], [A^-2 A^-4]
),
(
[A^4 A^2]  [A^-4 A^-2]
[  0   1], [   0    1]
),
(
[  1   0]  [   1    0]
[A^2 A^4], [A^-2 A^-4]
)]
sage: B = BraidGroup(8)
sage: B.TL_representation(8)
[([1], [1]),
([1], [1]),
([1], [1]),
([1], [1]),
([1], [1]),
([1], [1]),
([1], [1])]

an_element()

Return an element of the braid group.

This is used both for illustration and testing purposes.

EXAMPLES:

sage: B = BraidGroup(2)
sage: B.an_element()
s

as_permutation_group()

Return an isomorphic permutation group.

OUTPUT:

Raises a ValueError error since braid groups are infinite.

cardinality()

Return the number of group elements.

OUTPUT:

Infinity.

dimension_of_TL_space(drain_size)

Return the dimension of a particular Temperley–Lieb representation summand of self.

Following the notation of TL_basis_with_drain(), the summand is the one corresponding to the number of drains being fixed to be drain_size.

INPUT:

• drain_size – integer between 0 and the number of strands (both inclusive)

EXAMPLES:

Calculation of the dimension of the representation of $$B_8$$ corresponding to having $$2$$ drains:

sage: B = BraidGroup(8)
sage: B.dimension_of_TL_space(2)
28


The direct sum of endomorphism spaces of these vector spaces make up the entire Temperley–Lieb algebra:

sage: import sage.combinat.diagram_algebras as da
sage: B = BraidGroup(6)
sage: dimensions = [B.dimension_of_TL_space(d)**2 for d in [0, 2, 4, 6]]
sage: total_dim = sum(dimensions)
sage: total_dim == len(list(da.temperley_lieb_diagrams(6)))  # long time
True

mapping_class_action(F)

Return the action of self in the free group F as mapping class group.

This action corresponds to the action of the braid over the punctured disk, whose fundamental group is the free group on as many generators as strands.

In Sage, this action is the result of multiplying a free group element with a braid. So you generally do not have to construct this action yourself.

OUTPUT:

EXAMPLES:

sage: B = BraidGroup(3)
sage: B.inject_variables()
Defining s0, s1
sage: F.<a,b,c> = FreeGroup(3)
sage: A = B.mapping_class_action(F)
sage: A(a,s0)
a*b*a^-1
sage: a * s0    # simpler notation
a*b*a^-1

mirror_involution()

Return the mirror involution of self.

This automorphism maps a braid to another one by replacing each generator in its word by the inverse. In general this is different from the inverse of the braid since the order of the generators in the word is not reversed.

EXAMPLES:

sage: B = BraidGroup(4)
sage: mirr = B.mirror_involution()
sage: b = B((1,-2,-1,3,2,1))
sage: bm = mirr(b); bm
s0^-1*s1*s0*s2^-1*s1^-1*s0^-1
sage: bm == ~b
False
sage: bm.is_conjugated(b)
False
sage: bm.is_conjugated(~b)
True

order()

Return the number of group elements.

OUTPUT:

Infinity.

some_elements()

Return a list of some elements of the braid group.

This is used both for illustration and testing purposes.

EXAMPLES:

sage: B = BraidGroup(3)
sage: B.some_elements()
[s0, s0*s1, (s0*s1)^3]

strands()

Return the number of strands.

OUTPUT:

Integer.

EXAMPLES:

sage: B = BraidGroup(4)
sage: B.strands()
4

class sage.groups.braid.MappingClassGroupAction(G, M)

The right action of the braid group the free group as the mapping class group of the punctured disk.

That is, this action is the action of the braid over the punctured disk, whose fundamental group is the free group on as many generators as strands.

This action is defined as follows:

$\begin{split}x_j \cdot \sigma_i=\begin{cases} x_{j}\cdot x_{j+1}\cdot {x_j}^{-1} & \text{if i=j} \\ x_{j-1} & \text{if i=j-1} \\ x_{j} & \text{otherwise} \end{cases},\end{split}$

where $$\sigma_i$$ are the generators of the braid group on $$n$$ strands, and $$x_j$$ the generators of the free group of rank $$n$$.

You should left multiplication of the free group element by the braid to compute the action. Alternatively, use the mapping_class_action() method of the braid group to construct this action.

EXAMPLES:

sage: B.<s0,s1,s2> = BraidGroup(4)
sage: F.<x0,x1,x2,x3> = FreeGroup(4)
sage: x0 * s1
x0
sage: x1 * s1
x1*x2*x1^-1
sage: x1^-1 * s1
x1*x2^-1*x1^-1

sage: A = B.mapping_class_action(F)
sage: A
Right action by Braid group on 4 strands on Free Group on generators {x0, x1, x2, x3}
sage: A(x0, s1)
x0
sage: A(x1, s1)
x1*x2*x1^-1
sage: A(x1^-1, s1)
x1*x2^-1*x1^-1

class sage.groups.braid.RightQuantumWord(words)

Bases: object

A right quantum word as in Definition 4.1 of [HL2018].

INPUT:

• words – an element in a suitable free algebra over a Laurent polynomial ring in one variable; this input does not need to be in reduced form, but the monomials for the input can come in any order

EXAMPLES:

sage: from sage.groups.braid import RightQuantumWord
sage: fig_8 = BraidGroup(3)([-1, 2, -1, 2])
sage: (
....:  bp_1, cp_1, ap_1,
....:  bp_3, cp_3, ap_3,
....:  bm_0, cm_0, am_0,
....:  bm_2, cm_2, am_2
....: ) = fig_8.deformed_burau_matrix().parent().base_ring().gens()
sage: q = bp_1.base_ring().gen()
sage: RightQuantumWord(ap_1*cp_1 + q**3*bm_2*bp_1*am_0*cm_0)
The right quantum word represented by
q*cp_1*ap_1 + q^2*bp_1*cm_0*am_0*bm_2
reduced from ap_1*cp_1 + q^3*bm_2*bp_1*am_0*cm_0

eps(N)

Evaluate the map $$\mathcal{E}_N$$ for a braid.

INPUT:

• N – an integer; the number of colors

EXAMPLES:

sage: from sage.groups.braid import RightQuantumWord
sage: B = BraidGroup(3)
sage: b = B([1,-2,1,2])
sage: db = b.deformed_burau_matrix()[:, :]
sage: q = db.parent().base_ring().base_ring().gen()
sage: (bp_0, cp_0, ap_0,
....:  bp_2, cp_2, ap_2,
....:  bp_3, cp_3, ap_3,
....:  bm_1, cm_1, am_1) = db.parent().base_ring().gens()
sage: rqw = RightQuantumWord(
....:    q^3*bp_2*bp_0*ap_0 + q*ap_3*bm_1*am_1*bp_0)
sage: rqw.eps(3)
-q^-1 + 2*q - q^5
sage: rqw.eps(2)
-1 + 2*q - q^2 + q^3 - q^4


Todo

Paralellize this function, calculating all summands in the sum in parallel.

reduced_word()

Return the (reduced) right quantum word.

OUTPUT:

An element in the free algebra.

EXAMPLES:

sage: from sage.groups.braid import RightQuantumWord
sage: fig_8 = BraidGroup(3)([-1, 2, -1, 2])
sage: (
....:  bp_1, cp_1, ap_1,
....:  bp_3, cp_3, ap_3,
....:  bm_0, cm_0, am_0,
....:  bm_2, cm_2, am_2
....: ) = fig_8.deformed_burau_matrix().parent().base_ring().gens()
sage: q = bp_1.base_ring().gen()
sage: qw = RightQuantumWord(ap_1*cp_1 +
....:                            q**3*bm_2*bp_1*am_0*cm_0)
sage: qw.reduced_word()
q*cp_1*ap_1 + q^2*bp_1*cm_0*am_0*bm_2


Todo

Paralellize this function, calculating all summands in the sum in parallel.

tuples()

Get a representation of the right quantum word as a dict, with keys monomials in the free algebra represented as tuples and values in elements the Laurent polynomial ring in one variable.

This is in the reduced form as outlined in Definition 4.1 of [HL2018].

OUTPUT:

A dict of tuples of ints corresponding to the exponents in the generators with values in the algebra’s base ring.

EXAMPLES:

sage: from sage.groups.braid import RightQuantumWord
sage: fig_8 = BraidGroup(3)([-1, 2, -1, 2])
sage: (
....:  bp_1, cp_1, ap_1,
....:  bp_3, cp_3, ap_3,
....:  bm_0, cm_0, am_0,
....:  bm_2, cm_2, am_2
....: ) = fig_8.deformed_burau_matrix().parent().base_ring().gens()
sage: q = bp_1.base_ring().gen()
sage: qw = RightQuantumWord(ap_1*cp_1 +
....:                       q**3*bm_2*bp_1*am_0*cm_0)
sage: for key, value in qw.tuples.items():
....:     print(key, value)
(0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0) q
(1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0) q^2