Diagram and Partition Algebras#

AUTHORS:

  • Mike Hansen (2007): Initial version

  • Stephen Doty, Aaron Lauve, George H. Seelinger (2012): Implementation of partition, Brauer, Temperley–Lieb, and ideal partition algebras

  • Stephen Doty, Aaron Lauve, George H. Seelinger (2015): Implementation of *Diagram classes and other methods to improve diagram algebras.

  • Mike Zabrocki (2018): Implementation of individual element diagram classes

  • Aaron Lauve, Mike Zabrocki (2018): Implementation of orbit basis for Partition algebra.

class sage.combinat.diagram_algebras.AbstractPartitionDiagram(parent, d, check=True)#

Bases: AbstractSetPartition

Abstract base class for partition diagrams.

This class represents a single partition diagram, that is used as a basis key for a diagram algebra element. A partition diagram should be a partition of the set \(\{1, \ldots, k, -1, \ldots, -k\}\). Each such set partition is regarded as a graph on nodes \(\{1, \ldots, k, -1, \ldots, -k\}\) arranged in two rows, with nodes \(1, \ldots, k\) in the top row from left to right and with nodes \(-1, \ldots, -k\) in the bottom row from left to right, and an edge connecting two nodes if and only if the nodes lie in the same subset of the set partition.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.AbstractPartitionDiagrams(2)
sage: pd1 = da.AbstractPartitionDiagram(pd, [[1,2],[-1,-2]])
sage: pd2 = da.AbstractPartitionDiagram(pd, [[1,2],[-1,-2]])
sage: pd1
{{-2, -1}, {1, 2}}
sage: pd1 == pd2
True
sage: pd1 == [[1,2],[-1,-2]]
True
sage: pd1 == ((-2,-1),(2,1))
True
sage: pd1 == SetPartition([[1,2],[-1,-2]])
True
sage: pd3 = da.AbstractPartitionDiagram(pd, [[1,-2],[-1,2]])
sage: pd1 == pd3
False
sage: pd4 = da.AbstractPartitionDiagram(pd, [[1,2],[3,4]])
Traceback (most recent call last):
...
ValueError: {{1, 2}, {3, 4}} does not represent two rows of vertices of order 2
base_diagram()#

Return the underlying implementation of the diagram.

OUTPUT:

  • tuple of tuples of integers

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.AbstractPartitionDiagrams(2)
sage: pd([[1,2],[-1,-2]]).base_diagram() == ((-2,-1),(1,2))
True
check()#

Check the validity of the input for the diagram.

compose(other, check=True)#

Compose self with other.

The composition of two diagrams \(X\) and \(Y\) is given by placing \(X\) on top of \(Y\) and removing all loops.

OUTPUT:

A tuple where the first entry is the composite diagram and the second entry is how many loop were removed.

Note

This is not really meant to be called directly, but it works to call it this way if desired.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.AbstractPartitionDiagrams(2)
sage: pd([[1,2],[-1,-2]]).compose(pd([[1,2],[-1,-2]]))
({{-2, -1}, {1, 2}}, 1)
count_blocks_of_size(n)#

Count the number of blocks of a given size.

INPUT:

  • n – a positive integer

EXAMPLES:

sage: from sage.combinat.diagram_algebras import PartitionDiagram
sage: pd = PartitionDiagram([[1,-3,-5],[2,4],[3,-1,-2],[5],[-4]])
sage: pd.count_blocks_of_size(1)
2
sage: pd.count_blocks_of_size(2)
1
sage: pd.count_blocks_of_size(3)
2
diagram()#

Return the underlying implementation of the diagram.

OUTPUT:

  • tuple of tuples of integers

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.AbstractPartitionDiagrams(2)
sage: pd([[1,2],[-1,-2]]).base_diagram() == ((-2,-1),(1,2))
True
dual()#

Return the dual diagram of self by flipping it top-to-bottom.

EXAMPLES:

sage: from sage.combinat.diagram_algebras import PartitionDiagram
sage: D = PartitionDiagram([[1,-1],[2,-2,-3],[3]])
sage: D.dual()
{{-3}, {-2, 2, 3}, {-1, 1}}
is_planar()#

Test if the diagram self is planar.

A diagram element is planar if the graph of the nodes is planar.

EXAMPLES:

sage: from sage.combinat.diagram_algebras import BrauerDiagram
sage: BrauerDiagram([[1,-2],[2,-1]]).is_planar()
False
sage: BrauerDiagram([[1,-1],[2,-2]]).is_planar()
True
order()#

Return the maximum entry in the diagram element.

A diagram element will be a partition of the set \(\{-1, -2, \ldots, -k, 1, 2, \ldots, k\}\). The order of the diagram element is the value \(k\).

EXAMPLES:

sage: from sage.combinat.diagram_algebras import PartitionDiagram
sage: PartitionDiagram([[1,-1],[2,-2,-3],[3]]).order()
3
sage: PartitionDiagram([[1,-1]]).order()
1
sage: PartitionDiagram([[1,-3,-5],[2,4],[3,-1,-2],[5],[-4]]).order()
5
propagating_number()#

Return the propagating number of the diagram.

The propagating number is the number of blocks with both a positive and negative number.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.AbstractPartitionDiagrams(2)
sage: d1 = pd([[1,-2],[2,-1]])
sage: d1.propagating_number()
2
sage: d2 = pd([[1,2],[-2,-1]])
sage: d2.propagating_number()
0
set_partition()#

Return the underlying implementation of the diagram as a set of sets.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.AbstractPartitionDiagrams(2)
sage: X = pd([[1,2],[-1,-2]]).set_partition(); X
{{-2, -1}, {1, 2}}
sage: X.parent()
Set partitions
class sage.combinat.diagram_algebras.AbstractPartitionDiagrams(order, category=None)#

Bases: Parent, UniqueRepresentation

This is an abstract base class for partition diagrams.

The primary use of this class is to serve as basis keys for diagram algebras, but diagrams also have properties in their own right. Furthermore, this class is meant to be extended to create more efficient contains methods.

INPUT:

  • order – integer or integer \(+ 1/2\); the order of the diagrams

  • category – (default: FiniteEnumeratedSets()); the category

All concrete classes should implement attributes

  • _name – the name of the class

  • _diagram_func – an iterator function that takes the order as its only input

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.PartitionDiagrams(2)
sage: pd
Partition diagrams of order 2
sage: pd.an_element() in pd
True
sage: elm = pd([[1,2],[-1,-2]])
sage: elm in pd
True
Element#

alias of AbstractPartitionDiagram

class sage.combinat.diagram_algebras.BrauerAlgebra(k, q, base_ring, prefix)#

Bases: SubPartitionAlgebra, UnitDiagramMixin

A Brauer algebra.

The Brauer algebra of rank \(k\) is an algebra with basis indexed by the collection of set partitions of \(\{1, \ldots, k, -1, \ldots, -k\}\) with block size 2.

This algebra is a subalgebra of the partition algebra. For more information, see PartitionAlgebra.

INPUT:

  • k – rank of the algebra

  • q – the deformation parameter \(q\)

OPTIONAL ARGUMENTS:

  • base_ring – (default None) a ring containing q; if None then just takes the parent of q

  • prefix – (default "B") a label for the basis elements

EXAMPLES:

We now define the Brauer algebra of rank \(2\) with parameter x over \(\ZZ\):

sage: R.<x> = ZZ[]
sage: B = BrauerAlgebra(2, x, R)
sage: B
Brauer Algebra of rank 2 with parameter x
 over Univariate Polynomial Ring in x over Integer Ring
sage: B.basis()
Lazy family (Term map from Brauer diagrams of order 2 to Brauer Algebra
 of rank 2 with parameter x over Univariate Polynomial Ring in x
 over Integer Ring(i))_{i in Brauer diagrams of order 2}
sage: B.basis().keys()
Brauer diagrams of order 2
sage: B.basis().keys()([[-2, 1], [2, -1]])
{{-2, 1}, {-1, 2}}
sage: b = B.basis().list(); b
[B{{-2, -1}, {1, 2}}, B{{-2, 1}, {-1, 2}}, B{{-2, 2}, {-1, 1}}]
sage: b[0]
B{{-2, -1}, {1, 2}}
sage: b[0]^2
x*B{{-2, -1}, {1, 2}}
sage: b[0]^5
x^4*B{{-2, -1}, {1, 2}}

Note, also that since the symmetric group algebra is contained in the Brauer algebra, there is also a conversion between the two.

sage: R.<x> = ZZ[]
sage: B = BrauerAlgebra(2, x, R)
sage: S = SymmetricGroupAlgebra(R, 2)
sage: S([2,1])*B([[1,-1],[2,-2]])
B{{-2, 1}, {-1, 2}}
jucys_murphy(j)#

Return the j-th generalized Jucys-Murphy element of self.

The \(j\)-th Jucys-Murphy element of a Brauer algebra is simply the \(j\)-th Jucys-Murphy element of the symmetric group algebra with an extra \((z-1)/2\) term, where z is the parameter of the Brauer algebra.

REFERENCES:

[Naz96]

Maxim Nazarov, Young’s Orthogonal Form for Brauer’s Centralizer Algebra. Journal of Algebra 182 (1996), 664–693.

EXAMPLES:

sage: z = var('z')
sage: B = BrauerAlgebra(3,z)
sage: B.jucys_murphy(1)
(1/2*z-1/2)*B{{-3, 3}, {-2, 2}, {-1, 1}}
sage: B.jucys_murphy(3)
-B{{-3, -2}, {-1, 1}, {2, 3}} - B{{-3, -1}, {-2, 2}, {1, 3}}
 + B{{-3, 1}, {-2, 2}, {-1, 3}} + B{{-3, 2}, {-2, 3}, {-1, 1}}
 + (1/2*z-1/2)*B{{-3, 3}, {-2, 2}, {-1, 1}}
options = Current options for Brauer diagram   - display: normal#
class sage.combinat.diagram_algebras.BrauerDiagram(parent, d, check=True)#

Bases: AbstractPartitionDiagram

A Brauer diagram.

A Brauer diagram for an integer \(k\) is a partition of the set \(\{1, \ldots, k, -1, \ldots, -k\}\) with block size 2.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(2)
sage: bd1 = bd([[1,2],[-1,-2]])
sage: bd2 = bd([[1,2,-1,-2]])
Traceback (most recent call last):
...
ValueError: all blocks of {{-2, -1, 1, 2}} must be of size 2
bijection_on_free_nodes(two_line=False)#

Return the induced bijection - as a list of \((x,f(x))\) values - from the free nodes on the top at the Brauer diagram to the free nodes at the bottom of self.

OUTPUT:

If two_line is True, then the output is the induced bijection as a two-row list (inputs, outputs).

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(3)
sage: elm = bd([[1,2],[-2,-3],[3,-1]])
sage: elm.bijection_on_free_nodes()
[[3, -1]]
sage: elm2 = bd([[1,-2],[2,-3],[3,-1]])
sage: elm2.bijection_on_free_nodes(two_line=True)
[[1, 2, 3], [-2, -3, -1]]
check()#

Check the validity of the input for self.

involution_permutation_triple(curt=True)#

Return the involution permutation triple of self.

From Graham-Lehrer (see BrauerDiagrams), a Brauer diagram is a triple \((D_1, D_2, \pi)\), where:

  • \(D_1\) is a partition of the top nodes;

  • \(D_2\) is a partition of the bottom nodes;

  • \(\pi\) is the induced permutation on the free nodes.

INPUT:

  • curt – (default: True) if True, then return bijection on free nodes as a one-line notation (standardized to look like a permutation), else, return the honest mapping, a list of pairs \((i, -j)\) describing the bijection on free nodes

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(3)
sage: elm = bd([[1,2],[-2,-3],[3,-1]])
sage: elm.involution_permutation_triple()
([(1, 2)], [(-3, -2)], [1])
sage: elm.involution_permutation_triple(curt=False)
([(1, 2)], [(-3, -2)], [[3, -1]])
is_elementary_symmetric()#

Check if is elementary symmetric.

Let \((D_1, D_2, \pi)\) be the Graham-Lehrer representation of the Brauer diagram \(d\). We say \(d\) is elementary symmetric if \(D_1 = D_2\) and \(\pi\) is the identity.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(3)
sage: elm = bd([[1,2],[-1,-2],[3,-3]])
sage: elm.is_elementary_symmetric()
True
sage: elm2 = bd([[1,2],[-1,-3],[3,-2]])
sage: elm2.is_elementary_symmetric()
False
options = Current options for Brauer diagram   - display: normal#
perm()#

Return the induced bijection on the free nodes of self in one-line notation, re-indexed and treated as a permutation.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(3)
sage: elm = bd([[1,2],[-2,-3],[3,-1]])
sage: elm.perm()
[1]
class sage.combinat.diagram_algebras.BrauerDiagrams(order, category=None)#

Bases: AbstractPartitionDiagrams

This class represents all Brauer diagrams of integer or integer \(+1/2\) order. For more information on Brauer diagrams, see BrauerAlgebra.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(2); bd
Brauer diagrams of order 2
sage: bd.list()
[{{-2, -1}, {1, 2}}, {{-2, 1}, {-1, 2}}, {{-2, 2}, {-1, 1}}]

sage: bd = da.BrauerDiagrams(5/2); bd
Brauer diagrams of order 5/2
sage: bd.list()
[{{-3, 3}, {-2, -1}, {1, 2}},
 {{-3, 3}, {-2, 1}, {-1, 2}},
 {{-3, 3}, {-2, 2}, {-1, 1}}]
Element#

alias of BrauerDiagram

cardinality()#

Return the cardinality of self.

The number of Brauer diagrams of integer order \(k\) is \((2k-1)!!\).

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(3)
sage: bd.cardinality()
15

sage: bd = da.BrauerDiagrams(7/2)
sage: bd.cardinality()
15
from_involution_permutation_triple(D1_D2_pi)#

Construct a Brauer diagram of self from an involution permutation triple.

A Brauer diagram can be represented as a triple where the first entry is a list of arcs on the top row of the diagram, the second entry is a list of arcs on the bottom row of the diagram, and the third entry is a permutation on the remaining nodes. This triple is called the involution permutation triple. For more information, see [GL1996].

INPUT:

  • D1_D2_pi– a list or tuple where the first entry is a list of arcs on the top of the diagram, the second entry is a list of arcs on the bottom of the diagram, and the third entry is a permutation on the free nodes.

REFERENCES:

[GL1996]

J.J. Graham and G.I. Lehrer, Cellular algebras. Inventiones mathematicae 123 (1996), 1–34.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(4)
sage: bd.from_involution_permutation_triple([[[1,2]],[[3,4]],[2,1]])
{{-4, -3}, {-2, 3}, {-1, 4}, {1, 2}}
options = Current options for Brauer diagram   - display: normal#
symmetric_diagrams(l=None, perm=None)#

Return the list of Brauer diagrams with symmetric placement of \(l\) arcs, and with free nodes permuted according to \(perm\).

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: bd = da.BrauerDiagrams(4)
sage: bd.symmetric_diagrams(l=1, perm=[2,1])
[{{-4, -2}, {-3, 1}, {-1, 3}, {2, 4}},
 {{-4, -3}, {-2, 1}, {-1, 2}, {3, 4}},
 {{-4, -1}, {-3, 2}, {-2, 3}, {1, 4}},
 {{-4, 2}, {-3, -1}, {-2, 4}, {1, 3}},
 {{-4, 3}, {-3, 4}, {-2, -1}, {1, 2}},
 {{-4, 1}, {-3, -2}, {-1, 4}, {2, 3}}]
class sage.combinat.diagram_algebras.DiagramAlgebra(k, q, base_ring, prefix, diagrams, category=None)#

Bases: CombinatorialFreeModule

Abstract class for diagram algebras and is not designed to be used directly.

class Element#

Bases: IndexedFreeModuleElement

An element of a diagram algebra.

This subclass provides a few additional methods for partition algebra elements. Most element methods are already implemented elsewhere.

diagram()#

Return the underlying diagram of self if self is a basis element. Raises an error if self is not a basis element.

EXAMPLES:

sage: R.<x> = ZZ[]
sage: P = PartitionAlgebra(2, x, R)
sage: elt = 3*P([[1,2],[-2,-1]])
sage: elt.diagram()
{{-2, -1}, {1, 2}}
diagrams()#

Return the diagrams in the support of self.

EXAMPLES:

sage: R.<x> = ZZ[]
sage: P = PartitionAlgebra(2, x, R)
sage: elt = 3*P([[1,2],[-2,-1]]) + P([[1,2],[-2], [-1]])
sage: sorted(elt.diagrams(), key=str)
[{{-2, -1}, {1, 2}}, {{-2}, {-1}, {1, 2}}]
order()#

Return the order of self.

The order of a partition algebra is defined as half of the number of nodes in the diagrams.

EXAMPLES:

sage: q = var('q')
sage: PA = PartitionAlgebra(2, q)
sage: PA.order()
2
set_partitions()#

Return the collection of underlying set partitions indexing the basis elements of a given diagram algebra.

Todo

Is this really necessary? deprecate?

class sage.combinat.diagram_algebras.DiagramBasis(k, q, base_ring, prefix, diagrams, category=None)#

Bases: DiagramAlgebra

Abstract base class for diagram algebras in the diagram basis.

product_on_basis(d1, d2)#

Return the product \(D_{d_1} D_{d_2}\) by two basis diagrams.

class sage.combinat.diagram_algebras.IdealDiagram(parent, d, check=True)#

Bases: AbstractPartitionDiagram

The element class for a ideal diagram.

An ideal diagram for an integer \(k\) is a partition of the set \(\{1, \ldots, k, -1, \ldots, -k\}\) where the propagating number is strictly smaller than the order.

EXAMPLES:

sage: from sage.combinat.diagram_algebras import IdealDiagrams as IDs
sage: IDs(2)
Ideal diagrams of order 2
sage: IDs(2).list()
[{{-2, -1, 1, 2}},
 {{-2, 1, 2}, {-1}},
 {{-2}, {-1, 1, 2}},
 {{-2, -1}, {1, 2}},
 {{-2}, {-1}, {1, 2}},
 {{-2, -1, 1}, {2}},
 {{-2, 1}, {-1}, {2}},
 {{-2, -1, 2}, {1}},
 {{-2, 2}, {-1}, {1}},
 {{-2}, {-1, 1}, {2}},
 {{-2}, {-1, 2}, {1}},
 {{-2, -1}, {1}, {2}},
 {{-2}, {-1}, {1}, {2}}]

sage: from sage.combinat.diagram_algebras import PartitionDiagrams as PDs
sage: PDs(4).cardinality() == factorial(4) + IDs(4).cardinality()
True
check()#

Check the validity of the input for self.

class sage.combinat.diagram_algebras.IdealDiagrams(order, category=None)#

Bases: AbstractPartitionDiagrams

All “ideal” diagrams of integer or integer \(+1/2\) order.

If \(k\) is an integer then an ideal diagram of order \(k\) is a partition diagram of order \(k\) with propagating number less than \(k\).

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: id = da.IdealDiagrams(3)
sage: id.an_element() in id
True
sage: id.cardinality() == len(id.list())
True
sage: da.IdealDiagrams(3/2).list()
[{{-2, -1, 1, 2}},
 {{-2, 1, 2}, {-1}},
 {{-2, -1, 2}, {1}},
 {{-2, 2}, {-1}, {1}}]
Element#

alias of IdealDiagram

class sage.combinat.diagram_algebras.OrbitBasis(alg)#

Bases: DiagramAlgebra

The orbit basis of the partition algebra.

Let \(D_\pi\) represent the diagram basis element indexed by the partition \(\pi\), then (see equations (2.14), (2.17) and (2.18) of [BH2017])

\[D_\pi = \sum_{\tau \geq \pi} O_\tau,\]

where the sum is over all partitions \(\tau\) which are coarser than \(\pi\) and \(O_\tau\) is the orbit basis element indexed by the partition \(\tau\).

If \(\mu_{2k}(\pi,\tau)\) represents the Moebius function of the partition lattice, then

\[O_\pi = \sum_{\tau \geq \pi} \mu_{2k}(\pi, \tau) D_\tau.\]

If \(\tau\) is a partition of \(\ell\) blocks and the \(i^{th}\) block of \(\tau\) is a union of \(b_i\) blocks of \(\pi\), then

\[\mu_{2k}(\pi, \tau) = \prod_{i=1}^\ell (-1)^{b_i-1} (b_i-1)! .\]

EXAMPLES:

sage: R.<x> = QQ[]
sage: P2 = PartitionAlgebra(2, x, R)
sage: O2 = P2.orbit_basis(); O2
Orbit basis of Partition Algebra of rank 2 with parameter x over
 Univariate Polynomial Ring in x over Rational Field
sage: oa = O2([[1],[-1],[2,-2]]); ob = O2([[-1,-2,2],[1]]); oa, ob
(O{{-2, 2}, {-1}, {1}}, O{{-2, -1, 2}, {1}})
sage: oa * ob
(x-2)*O{{-2, -1, 2}, {1}}

We can convert between the two bases:

sage: pa = P2(oa); pa
2*P{{-2, -1, 1, 2}} - P{{-2, -1, 2}, {1}} - P{{-2, 1, 2}, {-1}}
 + P{{-2, 2}, {-1}, {1}} - P{{-2, 2}, {-1, 1}}
sage: pa * ob
(-x+2)*P{{-2, -1, 1, 2}} + (x-2)*P{{-2, -1, 2}, {1}}
sage: _ == pa * P2(ob)
True
sage: O2(pa * ob)
(x-2)*O{{-2, -1, 2}, {1}}

Note that the unit in the orbit basis is not a single diagram, in contrast to the natural diagram basis:

sage: P2.one()
P{{-2, 2}, {-1, 1}}
sage: O2.one()
O{{-2, -1, 1, 2}} + O{{-2, 2}, {-1, 1}}
sage: O2.one() == P2.one()
True
class Element#

Bases: Element

to_diagram_basis()#

Expand self in the natural diagram basis of the partition algebra.

EXAMPLES:

sage: R.<x> = QQ[]
sage: P = PartitionAlgebra(2, x, R)
sage: O = P.orbit_basis()
sage: elt = O.an_element(); elt
3*O{{-2}, {-1, 1, 2}} + 2*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
sage: elt.to_diagram_basis()
3*P{{-2}, {-1, 1, 2}} - 3*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
sage: pp = P.an_element(); pp
3*P{{-2}, {-1, 1, 2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
sage: op = pp.to_orbit_basis(); op
3*O{{-2}, {-1, 1, 2}} + 7*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
sage: pp == op.to_diagram_basis()
True
diagram_basis()#

Return the associated partition algebra of self in the diagram basis.

EXAMPLES:

sage: R.<x> = QQ[]
sage: O2 = PartitionAlgebra(2, x, R).orbit_basis()
sage: P2 = O2.diagram_basis(); P2
Partition Algebra of rank 2 with parameter x over Univariate
Polynomial Ring in x over Rational Field
sage: o2 = O2.an_element(); o2
3*O{{-2}, {-1, 1, 2}} + 2*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
sage: P2(o2)
3*P{{-2}, {-1, 1, 2}} - 3*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
one()#

Return the element \(1\) of the partition algebra in the orbit basis.

EXAMPLES:

sage: R.<x> = QQ[]
sage: P2 = PartitionAlgebra(2, x, R)
sage: O2 = P2.orbit_basis()
sage: O2.one()
O{{-2, -1, 1, 2}} + O{{-2, 2}, {-1, 1}}
product_on_basis(d1, d2)#

Return the product \(O_{d_1} O_{d_2}\) of two elements in the orbit basis self.

EXAMPLES:

sage: R.<x> = QQ[]
sage: OP = PartitionAlgebra(2, x, R).orbit_basis()
sage: SP = OP.basis().keys(); sp = SP([[-2, -1, 1, 2]])
sage: OP.product_on_basis(sp, sp)
O{{-2, -1, 1, 2}}
sage: o1 = OP.one(); o2 = OP([]); o3 = OP.an_element()
sage: o2 == o1
False
sage: o1 * o1 == o1
True
sage: o3 * o1 == o1 * o3 and o3 * o1 == o3
True
sage: o4 = (3*OP([[-2, -1, 1], [2]]) + 2*OP([[-2, -1, 1, 2]])
....:       + 2*OP([[-2, -1, 2], [1]]))
sage: o4 * o4
6*O{{-2, -1, 1}, {2}} + 4*O{{-2, -1, 1, 2}} + 4*O{{-2, -1, 2}, {1}}

We compute Examples 4.5 in [BH2017]:

sage: R.<x> = QQ[]
sage: P = PartitionAlgebra(3,x); O = P.orbit_basis()
sage: O[[1,2,3],[-1,-2,-3]] * O[[1,2,3],[-1,-2,-3]]
(x-2)*O{{-3, -2, -1}, {1, 2, 3}} + (x-1)*O{{-3, -2, -1, 1, 2, 3}}

sage: P = PartitionAlgebra(4,x); O = P.orbit_basis()
sage: O[[1],[-1],[2,3],[4,-2],[-3,-4]] * O[[1],[2,-2],[3,4],[-1,-3],[-4]]
(x^2-11*x+30)*O{{-4}, {-3, -1}, {-2, 4}, {1}, {2, 3}}
 + (x^2-9*x+20)*O{{-4}, {-3, -1, 1}, {-2, 4}, {2, 3}}
 + (x^2-9*x+20)*O{{-4}, {-3, -1, 2, 3}, {-2, 4}, {1}}
 + (x^2-9*x+20)*O{{-4, 1}, {-3, -1}, {-2, 4}, {2, 3}}
 + (x^2-7*x+12)*O{{-4, 1}, {-3, -1, 2, 3}, {-2, 4}}
 + (x^2-9*x+20)*O{{-4, 2, 3}, {-3, -1}, {-2, 4}, {1}}
 + (x^2-7*x+12)*O{{-4, 2, 3}, {-3, -1, 1}, {-2, 4}}

sage: O[[1,-1],[2,-2],[3],[4,-3],[-4]] * O[[1,-2],[2],[3,-1],[4],[-3],[-4]]
(x-6)*O{{-4}, {-3}, {-2, 1}, {-1, 4}, {2}, {3}}
 + (x-5)*O{{-4}, {-3, 3}, {-2, 1}, {-1, 4}, {2}}
 + (x-5)*O{{-4, 3}, {-3}, {-2, 1}, {-1, 4}, {2}}

sage: P = PartitionAlgebra(6,x); O = P.orbit_basis()
sage: (O[[1,-2,-3],[2,4],[3,5,-6],[6],[-1],[-4,-5]]
....:  * O[[1,-2],[2,3],[4],[5],[6,-4,-5,-6],[-1,-3]])
0

sage: (O[[1,-2],[2,-3],[3,5],[4,-5],[6,-4],[-1],[-6]]
....:  * O[[1,-2],[2,-1],[3,-4],[4,-6],[5,-3],[6,-5]])
O{{-6, 6}, {-5}, {-4, 2}, {-3, 4}, {-2}, {-1, 1}, {3, 5}}

REFERENCES:

class sage.combinat.diagram_algebras.PartitionAlgebra(k, q, base_ring, prefix)#

Bases: DiagramBasis, UnitDiagramMixin

A partition algebra.

A partition algebra of rank \(k\) over a given ground ring \(R\) is an algebra with (\(R\)-module) basis indexed by the collection of set partitions of \(\{1, \ldots, k, -1, \ldots, -k\}\). Each such set partition can be represented by a graph on nodes \(\{1, \ldots, k, -1, \ldots, -k\}\) arranged in two rows, with nodes \(1, \ldots, k\) in the top row from left to right and with nodes \(-1, \ldots, -k\) in the bottom row from left to right, and edges drawn such that the connected components of the graph are precisely the parts of the set partition. (This choice of edges is often not unique, and so there are often many graphs representing one and the same set partition; the representation nevertheless is useful and vivid. We often speak of “diagrams” to mean graphs up to such equivalence of choices of edges; of course, we could just as well speak of set partitions.)

There is not just one partition algebra of given rank over a given ground ring, but rather a whole family of them, indexed by the elements of \(R\). More precisely, for every \(q \in R\), the partition algebra of rank \(k\) over \(R\) with parameter \(q\) is defined to be the \(R\)-algebra with basis the collection of all set partitions of \(\{1, \ldots, k, -1, \ldots, -k\}\), where the product of two basis elements is given by the rule

\[a \cdot b = q^N (a \circ b),\]

where \(a \circ b\) is the composite set partition obtained by placing the diagram (i.e., graph) of \(a\) above the diagram of \(b\), identifying the bottom row nodes of \(a\) with the top row nodes of \(b\), and omitting any closed “loops” in the middle. The number \(N\) is the number of connected components formed by the omitted loops.

The parameter \(q\) is a deformation parameter. Taking \(q = 1\) produces the semigroup algebra (over the base ring) of the partition monoid, in which the product of two set partitions is simply given by their composition.

The partition algebra is regarded as an example of a “diagram algebra” due to the fact that its natural basis is given by certain graphs often called diagrams.

There are a number of predefined elements for the partition algebra. We define the cup/cap pair by a(). The simple transpositions are denoted s(). Finally, we define elements e(), where if \(i = (2r+1)/2\), then e(i) contains the blocks \(\{r+1\}\) and \(\{-r-1\}\) and if \(i \in \ZZ\), then \(e_i\) contains the block \(\{-i, -i-1, i, i+1\}\), with all other blocks being \(\{-j, j\}\). So we have:

sage: P = PartitionAlgebra(4, 0)
sage: P.a(2)
P{{-4, 4}, {-3, -2}, {-1, 1}, {2, 3}}
sage: P.e(3/2)
P{{-4, 4}, {-3, 3}, {-2}, {-1, 1}, {2}}
sage: P.e(2)
P{{-4, 4}, {-3, -2, 2, 3}, {-1, 1}}
sage: P.e(5/2)
P{{-4, 4}, {-3}, {-2, 2}, {-1, 1}, {3}}
sage: P.s(2)
P{{-4, 4}, {-3, 2}, {-2, 3}, {-1, 1}}

An excellent reference for partition algebras and their various subalgebras (Brauer algebra, Temperley–Lieb algebra, etc) is the paper [HR2005].

INPUT:

  • k – rank of the algebra

  • q – the deformation parameter \(q\)

OPTIONAL ARGUMENTS:

  • base_ring – (default None) a ring containing q; if None, then Sage automatically chooses the parent of q

  • prefix – (default "P") a label for the basis elements

EXAMPLES:

The following shorthand simultaneously defines the univariate polynomial ring over the rationals as well as the variable x:

sage: R.<x> = PolynomialRing(QQ)
sage: R
Univariate Polynomial Ring in x over Rational Field
sage: x
x
sage: x.parent() is R
True

We now define the partition algebra of rank \(2\) with parameter x over \(\ZZ\) in the usual (diagram) basis:

sage: R.<x> = ZZ[]
sage: A2 = PartitionAlgebra(2, x, R)
sage: A2
Partition Algebra of rank 2 with parameter x
 over Univariate Polynomial Ring in x over Integer Ring
sage: A2.basis().keys()
Partition diagrams of order 2
sage: A2.basis().keys()([[-2, 1, 2], [-1]])
{{-2, 1, 2}, {-1}}
sage: A2.basis().list()
[P{{-2, -1, 1, 2}}, P{{-2, 1, 2}, {-1}},
 P{{-2}, {-1, 1, 2}}, P{{-2, -1}, {1, 2}},
 P{{-2}, {-1}, {1, 2}}, P{{-2, -1, 1}, {2}},
 P{{-2, 1}, {-1, 2}}, P{{-2, 1}, {-1}, {2}},
 P{{-2, 2}, {-1, 1}}, P{{-2, -1, 2}, {1}},
 P{{-2, 2}, {-1}, {1}}, P{{-2}, {-1, 1}, {2}},
 P{{-2}, {-1, 2}, {1}}, P{{-2, -1}, {1}, {2}},
 P{{-2}, {-1}, {1}, {2}}]
sage: E = A2([[1,2],[-2,-1]]); E
P{{-2, -1}, {1, 2}}
sage: E in A2.basis().list()
True
sage: E^2
x*P{{-2, -1}, {1, 2}}
sage: E^5
x^4*P{{-2, -1}, {1, 2}}
sage: (A2([[2,-2],[-1,1]]) - 2*A2([[1,2],[-1,-2]]))^2
(4*x-4)*P{{-2, -1}, {1, 2}} + P{{-2, 2}, {-1, 1}}

Next, we construct an element:

sage: a2 = A2.an_element(); a2
3*P{{-2}, {-1, 1, 2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}

There is a natural embedding into partition algebras on more elements, by adding identity strands:

sage: A4 = PartitionAlgebra(4, x, R)
sage: A4(a2)
3*P{{-4, 4}, {-3, 3}, {-2}, {-1, 1, 2}}
 + 2*P{{-4, 4}, {-3, 3}, {-2, -1, 1, 2}}
 + 2*P{{-4, 4}, {-3, 3}, {-2, 1, 2}, {-1}}

Thus, the empty partition corresponds to the identity:

sage: A4([])
P{{-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}}
sage: A4(5)
5*P{{-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}}

The group algebra of the symmetric group is a subalgebra:

sage: S3 = SymmetricGroupAlgebra(ZZ, 3)
sage: s3 = S3.an_element(); s3
[1, 2, 3] + 2*[1, 3, 2] + 3*[2, 1, 3] + [3, 1, 2]
sage: A4(s3)
P{{-4, 4}, {-3, 1}, {-2, 3}, {-1, 2}}
 + 2*P{{-4, 4}, {-3, 2}, {-2, 3}, {-1, 1}}
 + 3*P{{-4, 4}, {-3, 3}, {-2, 1}, {-1, 2}}
 + P{{-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}}
sage: A4([2,1])
P{{-4, 4}, {-3, 3}, {-2, 1}, {-1, 2}}

Be careful not to confuse the embedding of the group algebra of the symmetric group with the embedding of partial set partitions. The latter are embedded by adding the parts \(\{i,-i\}\) if possible, and singletons sets for the remaining parts:

sage: A4([[2,1]])
P{{-4, 4}, {-3, 3}, {-2}, {-1}, {1, 2}}
sage: A4([[-1,3],[-2,-3,1]])
P{{-4, 4}, {-3, -2, 1}, {-1, 3}, {2}}

Another subalgebra is the Brauer algebra, which has perfect matchings as basis elements. The group algebra of the symmetric group is in fact a subalgebra of the Brauer algebra:

sage: B3 = BrauerAlgebra(3, x, R)
sage: b3 = B3(s3); b3
B{{-3, 1}, {-2, 3}, {-1, 2}} + 2*B{{-3, 2}, {-2, 3}, {-1, 1}}
 + 3*B{{-3, 3}, {-2, 1}, {-1, 2}} + B{{-3, 3}, {-2, 2}, {-1, 1}}

An important basis of the partition algebra is the orbit basis:

sage: O2 = A2.orbit_basis()
sage: o2 = O2([[1,2],[-1,-2]]) + O2([[1,2,-1,-2]]); o2
O{{-2, -1}, {1, 2}} + O{{-2, -1, 1, 2}}

The diagram basis element corresponds to the sum of all orbit basis elements indexed by coarser set partitions:

sage: A2(o2)
P{{-2, -1}, {1, 2}}

We can convert back from the orbit basis to the diagram basis:

sage: o2 = O2.an_element(); o2
3*O{{-2}, {-1, 1, 2}} + 2*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
sage: A2(o2)
3*P{{-2}, {-1, 1, 2}} - 3*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}

One can work with partition algebras using a symbol for the parameter, leaving the base ring unspecified. This implies that the underlying base ring is Sage’s symbolic ring.

sage: q = var('q')
sage: PA = PartitionAlgebra(2, q); PA
Partition Algebra of rank 2 with parameter q over Symbolic Ring
sage: PA([[1,2],[-2,-1]])^2 == q*PA([[1,2],[-2,-1]])
True
sage: (PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 == (4*q-4)*PA([[1, 2], [-2, -1]]) + PA([[2, -2], [1, -1]])
True

The identity element of the partition algebra is the set partition \(\{\{1,-1\}, \{2,-2\}, \ldots, \{k,-k\}\}\):

sage: P = PA.basis().list()
sage: PA.one()
P{{-2, 2}, {-1, 1}}
sage: PA.one() * P[7] == P[7]
True
sage: P[7] * PA.one() == P[7]
True

We now give some further examples of the use of the other arguments. One may wish to “specialize” the parameter to a chosen element of the base ring:

sage: R.<q> = RR[]
sage: PA = PartitionAlgebra(2, q, R, prefix='B')
sage: PA
Partition Algebra of rank 2 with parameter q over
 Univariate Polynomial Ring in q over Real Field with 53 bits of precision
sage: PA([[1,2],[-1,-2]])
1.00000000000000*B{{-2, -1}, {1, 2}}
sage: PA = PartitionAlgebra(2, 5, base_ring=ZZ, prefix='B')
sage: PA
Partition Algebra of rank 2 with parameter 5 over Integer Ring
sage: (PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 == 16*PA([[-2, -1], [1, 2]]) + PA([[2, -2], [1, -1]])
True

Symmetric group algebra elements and elements from other subalgebras of the partition algebra (e.g., BrauerAlgebra and TemperleyLiebAlgebra) can also be coerced into the partition algebra:

sage: S = SymmetricGroupAlgebra(SR, 2)
sage: B = BrauerAlgebra(2, x, SR)
sage: A = PartitionAlgebra(2, x, SR)
sage: S([2,1])*A([[1,-1],[2,-2]])
P{{-2, 1}, {-1, 2}}
sage: B([[-1,-2],[2,1]]) * A([[1],[-1],[2,-2]])
P{{-2}, {-1}, {1, 2}}
sage: A([[1],[-1],[2,-2]]) * B([[-1,-2],[2,1]])
P{{-2, -1}, {1}, {2}}

The same is true if the elements come from a subalgebra of a partition algebra of smaller order, or if they are defined over a different base ring:

sage: R = FractionField(ZZ['q']); q = R.gen()
sage: S = SymmetricGroupAlgebra(ZZ, 2)
sage: B = BrauerAlgebra(2, q, ZZ[q])
sage: A = PartitionAlgebra(3, q, R)
sage: S([2,1])*A([[1,-1],[2,-3],[3,-2]])
P{{-3, 1}, {-2, 3}, {-1, 2}}
sage: A(B([[-1,-2],[2,1]]))
P{{-3, 3}, {-2, -1}, {1, 2}}
class Element#

Bases: Element

dual()#

Return the dual of self.

The dual of an element in the partition algebra is formed by taking the dual of each diagram in the support.

EXAMPLES:

sage: R.<x> = QQ[]
sage: P = PartitionAlgebra(2, x, R)
sage: elt = P.an_element(); elt
3*P{{-2}, {-1, 1, 2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
sage: elt.dual()
3*P{{-2, -1, 1}, {2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, -1, 2}, {1}}
to_orbit_basis()#

Return self in the orbit basis of the associated partition algebra.

EXAMPLES:

sage: R.<x> = QQ[]
sage: P = PartitionAlgebra(2, x, R)
sage: pp = P.an_element();
sage: pp.to_orbit_basis()
3*O{{-2}, {-1, 1, 2}} + 7*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
sage: pp = (3*P([[-2], [-1, 1, 2]]) + 2*P([[-2, -1, 1, 2]])
....:       + 2*P([[-2, 1, 2], [-1]])); pp
3*P{{-2}, {-1, 1, 2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
sage: pp.to_orbit_basis()
3*O{{-2}, {-1, 1, 2}} + 7*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
L(i)#

Return the i-th Jucys-Murphy element \(L_i\) from [Eny2012].

INPUT:

  • i – a half integer between 1/2 and \(k\)

ALGORITHM:

We use the recursive definition for \(L_{2i}\) given in [Cre2020]. See also [Eny2012] and [Eny2013].

Note

\(L_{1/2}\) and \(L_1\) differs from [HR2005].

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.jucys_murphy_element(1/2)
0
sage: P3.jucys_murphy_element(1)
P{{-3, 3}, {-2, 2}, {-1}, {1}}
sage: P3.jucys_murphy_element(2)
P{{-3, 3}, {-2}, {-1, 1}, {2}} - P{{-3, 3}, {-2}, {-1, 1, 2}}
 + P{{-3, 3}, {-2, -1}, {1, 2}} - P{{-3, 3}, {-2, -1, 1}, {2}}
 + P{{-3, 3}, {-2, 1}, {-1, 2}}
sage: P3.jucys_murphy_element(3/2)
n*P{{-3, 3}, {-2, -1, 1, 2}} - P{{-3, 3}, {-2, -1, 2}, {1}}
 - P{{-3, 3}, {-2, 1, 2}, {-1}} + P{{-3, 3}, {-2, 2}, {-1, 1}}
sage: P3.L(3/2) * P3.L(2) == P3.L(2) * P3.L(3/2)
True

We test the relations in Lemma 2.2.3(2) in [Cre2020] (v1):

sage: k = 4
sage: R.<n> = QQ[]
sage: P = PartitionAlgebra(k, n)
sage: L = [P.L(i/2) for i in range(1,2*k+1)]
sage: all(x.dual() == x for x in L)
True
sage: all(x * y == y * x for x in L for y in L)  # long time
True
sage: Lsum = sum(L)
sage: gens = [P.s(i) for i in range(1,k)]
sage: gens += [P.e(i/2) for i in range(1,2*k)]
sage: all(x * Lsum == Lsum * x for x in gens)
True

Also the relations in Lemma 2.2.3(3) in [Cre2020] (v1):

sage: all(P.e((2*i+1)/2) * P.sigma(2*i/2) * P.e((2*i+1)/2)
....:     == (n - P.L((2*i-1)/2)) * P.e((2*i+1)/2) for i in range(1,k))
True
sage: all(P.e(i/2) * (P.L(i/2) + P.L((i+1)/2))
....:     == (P.L(i/2) + P.L((i+1)/2)) * P.e(i/2)
....:     == n * P.e(i/2) for i in range(1,2*k))
True
sage: all(P.sigma(2*i/2) * P.e((2*i-1)/2) * P.e(2*i/2)
....:     == P.L(2*i/2) * P.e(2*i/2) for i in range(1,k))
True
sage: all(P.e(2*i/2) * P.e((2*i-1)/2) * P.sigma(2*i/2)
....:     == P.e(2*i/2) * P.L(2*i/2) for i in range(1,k))
True
sage: all(P.sigma((2*i+1)/2) * P.e((2*i+1)/2) * P.e(2*i/2)
....:     == P.L(2*i/2) * P.e(2*i/2) for i in range(1,k))
True
sage: all(P.e(2*i/2) * P.e((2*i+1)/2) * P.sigma((2*i+1)/2)
....:     == P.e(2*i/2) * P.L(2*i/2) for i in range(1,k))
True

The same tests for a half integer partition algebra:

sage: k = 9/2
sage: R.<n> = QQ[]
sage: P = PartitionAlgebra(k, n)
sage: L = [P.L(i/2) for i in range(1,2*k+1)]
sage: all(x.dual() == x for x in L)
True
sage: all(x * y == y * x for x in L for y in L)  # long time
True
sage: Lsum = sum(L)
sage: gens = [P.s(i) for i in range(1,k-1/2)]
sage: gens += [P.e(i/2) for i in range(1,2*k)]
sage: all(x * Lsum == Lsum * x for x in gens)
True
sage: all(P.e((2*i+1)/2) * P.sigma(2*i/2) * P.e((2*i+1)/2)
....:     == (n - P.L((2*i-1)/2)) * P.e((2*i+1)/2) for i in range(1,floor(k)))
True
sage: all(P.e(i/2) * (P.L(i/2) + P.L((i+1)/2))
....:     == (P.L(i/2) + P.L((i+1)/2)) * P.e(i/2)
....:     == n * P.e(i/2) for i in range(1,2*k))
True
sage: all(P.sigma(2*i/2) * P.e((2*i-1)/2) * P.e(2*i/2)
....:     == P.L(2*i/2) * P.e(2*i/2) for i in range(1,ceil(k)))
True
sage: all(P.e(2*i/2) * P.e((2*i-1)/2) * P.sigma(2*i/2)
....:     == P.e(2*i/2) * P.L(2*i/2) for i in range(1,ceil(k)))
True
sage: all(P.sigma((2*i+1)/2) * P.e((2*i+1)/2) * P.e(2*i/2)
....:     == P.L(2*i/2) * P.e(2*i/2) for i in range(1,floor(k)))
True
sage: all(P.e(2*i/2) * P.e((2*i+1)/2) * P.sigma((2*i+1)/2)
....:     == P.e(2*i/2) * P.L(2*i/2) for i in range(1,floor(k)))
True
a(i)#

Return the element \(a_i\) in self.

The element \(a_i\) is the cap and cup at \((i, i+1)\), so it contains the blocks \(\{i, i+1\}\), \(\{-i, -i-1\}\). Other blocks are of the form \(\{-j, j\}\).

INPUT:

  • i – an integer between 1 and \(k-1\)

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.a(1)
P{{-3, 3}, {-2, -1}, {1, 2}}
sage: P3.a(2)
P{{-3, -2}, {-1, 1}, {2, 3}}

sage: P3 = PartitionAlgebra(5/2, n)
sage: P3.a(1)
P{{-3, 3}, {-2, -1}, {1, 2}}
sage: P3.a(2)
Traceback (most recent call last):
...
ValueError: i must be an integer between 1 and 1
e(i)#

Return the element \(e_i\) in self.

If \(i = (2r+1)/2\), then \(e_i\) contains the blocks \(\{r+1\}\) and \(\{-r-1\}\). If \(i \in \ZZ\), then \(e_i\) contains the block \(\{-i, -i-1, i, i+1\}\). Other blocks are of the form \(\{-j, j\}\).

INPUT:

  • i – a half integer between 1/2 and \(k-1/2\)

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.e(1)
P{{-3, 3}, {-2, -1, 1, 2}}
sage: P3.e(2)
P{{-3, -2, 2, 3}, {-1, 1}}
sage: P3.e(1/2)
P{{-3, 3}, {-2, 2}, {-1}, {1}}
sage: P3.e(5/2)
P{{-3}, {-2, 2}, {-1, 1}, {3}}
sage: P3.e(0)
Traceback (most recent call last):
...
ValueError: i must be an (half) integer between 1/2 and 5/2
sage: P3.e(3)
Traceback (most recent call last):
...
ValueError: i must be an (half) integer between 1/2 and 5/2

sage: P2h = PartitionAlgebra(5/2,n)
sage: [P2h.e(k/2) for k in range(1,5)]
[P{{-3, 3}, {-2, 2}, {-1}, {1}},
 P{{-3, 3}, {-2, -1, 1, 2}},
 P{{-3, 3}, {-2}, {-1, 1}, {2}},
 P{{-3, -2, 2, 3}, {-1, 1}}]
generator_a(i)#

Return the element \(a_i\) in self.

The element \(a_i\) is the cap and cup at \((i, i+1)\), so it contains the blocks \(\{i, i+1\}\), \(\{-i, -i-1\}\). Other blocks are of the form \(\{-j, j\}\).

INPUT:

  • i – an integer between 1 and \(k-1\)

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.a(1)
P{{-3, 3}, {-2, -1}, {1, 2}}
sage: P3.a(2)
P{{-3, -2}, {-1, 1}, {2, 3}}

sage: P3 = PartitionAlgebra(5/2, n)
sage: P3.a(1)
P{{-3, 3}, {-2, -1}, {1, 2}}
sage: P3.a(2)
Traceback (most recent call last):
...
ValueError: i must be an integer between 1 and 1
generator_e(i)#

Return the element \(e_i\) in self.

If \(i = (2r+1)/2\), then \(e_i\) contains the blocks \(\{r+1\}\) and \(\{-r-1\}\). If \(i \in \ZZ\), then \(e_i\) contains the block \(\{-i, -i-1, i, i+1\}\). Other blocks are of the form \(\{-j, j\}\).

INPUT:

  • i – a half integer between 1/2 and \(k-1/2\)

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.e(1)
P{{-3, 3}, {-2, -1, 1, 2}}
sage: P3.e(2)
P{{-3, -2, 2, 3}, {-1, 1}}
sage: P3.e(1/2)
P{{-3, 3}, {-2, 2}, {-1}, {1}}
sage: P3.e(5/2)
P{{-3}, {-2, 2}, {-1, 1}, {3}}
sage: P3.e(0)
Traceback (most recent call last):
...
ValueError: i must be an (half) integer between 1/2 and 5/2
sage: P3.e(3)
Traceback (most recent call last):
...
ValueError: i must be an (half) integer between 1/2 and 5/2

sage: P2h = PartitionAlgebra(5/2,n)
sage: [P2h.e(k/2) for k in range(1,5)]
[P{{-3, 3}, {-2, 2}, {-1}, {1}},
 P{{-3, 3}, {-2, -1, 1, 2}},
 P{{-3, 3}, {-2}, {-1, 1}, {2}},
 P{{-3, -2, 2, 3}, {-1, 1}}]
generator_s(i)#

Return the i-th simple transposition \(s_i\) in self.

Borrowing the notation from the symmetric group, the \(i\)-th simple transposition \(s_i\) has blocks of the form \(\{-i, i+1\}\), \(\{-i-1, i\}\). Other blocks are of the form \(\{-j, j\}\).

INPUT:

  • i – an integer between 1 and \(k-1\)

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.s(1)
P{{-3, 3}, {-2, 1}, {-1, 2}}
sage: P3.s(2)
P{{-3, 2}, {-2, 3}, {-1, 1}}

sage: R.<n> = ZZ[]
sage: P2h = PartitionAlgebra(5/2,n)
sage: P2h.s(1)
P{{-3, 3}, {-2, 1}, {-1, 2}}
jucys_murphy_element(i)#

Return the i-th Jucys-Murphy element \(L_i\) from [Eny2012].

INPUT:

  • i – a half integer between 1/2 and \(k\)

ALGORITHM:

We use the recursive definition for \(L_{2i}\) given in [Cre2020]. See also [Eny2012] and [Eny2013].

Note

\(L_{1/2}\) and \(L_1\) differs from [HR2005].

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.jucys_murphy_element(1/2)
0
sage: P3.jucys_murphy_element(1)
P{{-3, 3}, {-2, 2}, {-1}, {1}}
sage: P3.jucys_murphy_element(2)
P{{-3, 3}, {-2}, {-1, 1}, {2}} - P{{-3, 3}, {-2}, {-1, 1, 2}}
 + P{{-3, 3}, {-2, -1}, {1, 2}} - P{{-3, 3}, {-2, -1, 1}, {2}}
 + P{{-3, 3}, {-2, 1}, {-1, 2}}
sage: P3.jucys_murphy_element(3/2)
n*P{{-3, 3}, {-2, -1, 1, 2}} - P{{-3, 3}, {-2, -1, 2}, {1}}
 - P{{-3, 3}, {-2, 1, 2}, {-1}} + P{{-3, 3}, {-2, 2}, {-1, 1}}
sage: P3.L(3/2) * P3.L(2) == P3.L(2) * P3.L(3/2)
True

We test the relations in Lemma 2.2.3(2) in [Cre2020] (v1):

sage: k = 4
sage: R.<n> = QQ[]
sage: P = PartitionAlgebra(k, n)
sage: L = [P.L(i/2) for i in range(1,2*k+1)]
sage: all(x.dual() == x for x in L)
True
sage: all(x * y == y * x for x in L for y in L)  # long time
True
sage: Lsum = sum(L)
sage: gens = [P.s(i) for i in range(1,k)]
sage: gens += [P.e(i/2) for i in range(1,2*k)]
sage: all(x * Lsum == Lsum * x for x in gens)
True

Also the relations in Lemma 2.2.3(3) in [Cre2020] (v1):

sage: all(P.e((2*i+1)/2) * P.sigma(2*i/2) * P.e((2*i+1)/2)
....:     == (n - P.L((2*i-1)/2)) * P.e((2*i+1)/2) for i in range(1,k))
True
sage: all(P.e(i/2) * (P.L(i/2) + P.L((i+1)/2))
....:     == (P.L(i/2) + P.L((i+1)/2)) * P.e(i/2)
....:     == n * P.e(i/2) for i in range(1,2*k))
True
sage: all(P.sigma(2*i/2) * P.e((2*i-1)/2) * P.e(2*i/2)
....:     == P.L(2*i/2) * P.e(2*i/2) for i in range(1,k))
True
sage: all(P.e(2*i/2) * P.e((2*i-1)/2) * P.sigma(2*i/2)
....:     == P.e(2*i/2) * P.L(2*i/2) for i in range(1,k))
True
sage: all(P.sigma((2*i+1)/2) * P.e((2*i+1)/2) * P.e(2*i/2)
....:     == P.L(2*i/2) * P.e(2*i/2) for i in range(1,k))
True
sage: all(P.e(2*i/2) * P.e((2*i+1)/2) * P.sigma((2*i+1)/2)
....:     == P.e(2*i/2) * P.L(2*i/2) for i in range(1,k))
True

The same tests for a half integer partition algebra:

sage: k = 9/2
sage: R.<n> = QQ[]
sage: P = PartitionAlgebra(k, n)
sage: L = [P.L(i/2) for i in range(1,2*k+1)]
sage: all(x.dual() == x for x in L)
True
sage: all(x * y == y * x for x in L for y in L)  # long time
True
sage: Lsum = sum(L)
sage: gens = [P.s(i) for i in range(1,k-1/2)]
sage: gens += [P.e(i/2) for i in range(1,2*k)]
sage: all(x * Lsum == Lsum * x for x in gens)
True
sage: all(P.e((2*i+1)/2) * P.sigma(2*i/2) * P.e((2*i+1)/2)
....:     == (n - P.L((2*i-1)/2)) * P.e((2*i+1)/2) for i in range(1,floor(k)))
True
sage: all(P.e(i/2) * (P.L(i/2) + P.L((i+1)/2))
....:     == (P.L(i/2) + P.L((i+1)/2)) * P.e(i/2)
....:     == n * P.e(i/2) for i in range(1,2*k))
True
sage: all(P.sigma(2*i/2) * P.e((2*i-1)/2) * P.e(2*i/2)
....:     == P.L(2*i/2) * P.e(2*i/2) for i in range(1,ceil(k)))
True
sage: all(P.e(2*i/2) * P.e((2*i-1)/2) * P.sigma(2*i/2)
....:     == P.e(2*i/2) * P.L(2*i/2) for i in range(1,ceil(k)))
True
sage: all(P.sigma((2*i+1)/2) * P.e((2*i+1)/2) * P.e(2*i/2)
....:     == P.L(2*i/2) * P.e(2*i/2) for i in range(1,floor(k)))
True
sage: all(P.e(2*i/2) * P.e((2*i+1)/2) * P.sigma((2*i+1)/2)
....:     == P.e(2*i/2) * P.L(2*i/2) for i in range(1,floor(k)))
True
orbit_basis()#

Return the orbit basis of self.

EXAMPLES:

sage: R.<x> = QQ[]
sage: P2 = PartitionAlgebra(2, x, R)
sage: O2 = P2.orbit_basis(); O2
Orbit basis of Partition Algebra of rank 2 with parameter x over
 Univariate Polynomial Ring in x over Rational Field
sage: pp = 7 * P2[{-1}, {-2, 1, 2}] - 2 * P2[{-2}, {-1, 1}, {2}]; pp
-2*P{{-2}, {-1, 1}, {2}} + 7*P{{-2, 1, 2}, {-1}}
sage: op = pp.to_orbit_basis(); op
-2*O{{-2}, {-1, 1}, {2}} - 2*O{{-2}, {-1, 1, 2}}
 - 2*O{{-2, -1, 1}, {2}} + 5*O{{-2, -1, 1, 2}}
 + 7*O{{-2, 1, 2}, {-1}} - 2*O{{-2, 2}, {-1, 1}}
sage: op == O2(op)
True
sage: pp * op.leading_term()
4*P{{-2}, {-1, 1}, {2}} - 4*P{{-2, -1, 1}, {2}}
 + 14*P{{-2, -1, 1, 2}} - 14*P{{-2, 1, 2}, {-1}}
s(i)#

Return the i-th simple transposition \(s_i\) in self.

Borrowing the notation from the symmetric group, the \(i\)-th simple transposition \(s_i\) has blocks of the form \(\{-i, i+1\}\), \(\{-i-1, i\}\). Other blocks are of the form \(\{-j, j\}\).

INPUT:

  • i – an integer between 1 and \(k-1\)

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.s(1)
P{{-3, 3}, {-2, 1}, {-1, 2}}
sage: P3.s(2)
P{{-3, 2}, {-2, 3}, {-1, 1}}

sage: R.<n> = ZZ[]
sage: P2h = PartitionAlgebra(5/2,n)
sage: P2h.s(1)
P{{-3, 3}, {-2, 1}, {-1, 2}}
sigma(i)#

Return the element \(\sigma_i\) from [Eny2012] of self.

INPUT:

  • i – a half integer between 1/2 and \(k-1/2\)

Note

In [Cre2020] and [Eny2013], these are the elements \(\sigma_{2i}\).

EXAMPLES:

sage: R.<n> = QQ[]
sage: P3 = PartitionAlgebra(3, n)
sage: P3.sigma(1)
P{{-3, 3}, {-2, 2}, {-1, 1}}
sage: P3.sigma(3/2)
P{{-3, 3}, {-2, 1}, {-1, 2}}
sage: P3.sigma(2)
-P{{-3, -1, 1, 3}, {-2, 2}} + P{{-3, -1, 3}, {-2, 1, 2}}
 + P{{-3, 1, 3}, {-2, -1, 2}} - P{{-3, 3}, {-2, -1, 1, 2}}
 + P{{-3, 3}, {-2, 2}, {-1, 1}}
sage: P3.sigma(5/2)
-P{{-3, -1, 1, 2}, {-2, 3}} + P{{-3, -1, 2}, {-2, 1, 3}}
 + P{{-3, 1, 2}, {-2, -1, 3}} - P{{-3, 2}, {-2, -1, 1, 3}}
 + P{{-3, 2}, {-2, 3}, {-1, 1}}

We test the relations in Lemma 2.2.3(1) in [Cre2020] (v1):

sage: k = 4
sage: R.<x> = QQ[]
sage: P = PartitionAlgebra(k, x)
sage: all(P.sigma(i/2).dual() == P.sigma(i/2)
....:     for i in range(1,2*k))
True
sage: all(P.sigma(i)*P.sigma(i+1/2) == P.sigma(i+1/2)*P.sigma(i) == P.s(i)
....:     for i in range(1,floor(k)))
True
sage: all(P.sigma(i)*P.e(i) == P.e(i)*P.sigma(i) == P.e(i)
....:     for i in range(1,floor(k)))
True
sage: all(P.sigma(i+1/2)*P.e(i) == P.e(i)*P.sigma(i+1/2) == P.e(i)
....:     for i in range(1,floor(k)))
True

sage: k = 9/2
sage: R.<x> = QQ[]
sage: P = PartitionAlgebra(k, x)
sage: all(P.sigma(i/2).dual() == P.sigma(i/2)
....:     for i in range(1,2*k-1))
True
sage: all(P.sigma(i)*P.sigma(i+1/2) == P.sigma(i+1/2)*P.sigma(i) == P.s(i)
....:     for i in range(1,k-1/2))
True
sage: all(P.sigma(i)*P.e(i) == P.e(i)*P.sigma(i) == P.e(i)
....:     for i in range(1,floor(k)))
True
sage: all(P.sigma(i+1/2)*P.e(i) == P.e(i)*P.sigma(i+1/2) == P.e(i)
....:     for i in range(1,floor(k)))
True
class sage.combinat.diagram_algebras.PartitionDiagram(parent, d, check=True)#

Bases: AbstractPartitionDiagram

The element class for a partition diagram.

A partition diagram for an integer \(k\) is a partition of the set \(\{1, \ldots, k, -1, \ldots, -k\}\)

EXAMPLES:

sage: from sage.combinat.diagram_algebras import PartitionDiagram, PartitionDiagrams
sage: PartitionDiagrams(1)
Partition diagrams of order 1
sage: PartitionDiagrams(1).list()
[{{-1, 1}}, {{-1}, {1}}]
sage: PartitionDiagram([[1,-1]])
{{-1, 1}}
sage: PartitionDiagram(((1,-2),(2,-1))).parent()
Partition diagrams of order 2
class sage.combinat.diagram_algebras.PartitionDiagrams(order, category=None)#

Bases: AbstractPartitionDiagrams

This class represents all partition diagrams of integer or integer \(+ 1/2\) order.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.PartitionDiagrams(1); pd
Partition diagrams of order 1
sage: pd.list()
[{{-1, 1}}, {{-1}, {1}}]

sage: pd = da.PartitionDiagrams(3/2); pd
Partition diagrams of order 3/2
sage: pd.list()
[{{-2, -1, 1, 2}},
 {{-2, 1, 2}, {-1}},
 {{-2, 2}, {-1, 1}},
 {{-2, -1, 2}, {1}},
 {{-2, 2}, {-1}, {1}}]
Element#

alias of PartitionDiagram

cardinality()#

The cardinality of partition diagrams of half-integer order \(n\) is the \(2n\)-th Bell number.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pd = da.PartitionDiagrams(3)
sage: pd.cardinality()
203

sage: pd = da.PartitionDiagrams(7/2)
sage: pd.cardinality()
877
class sage.combinat.diagram_algebras.PlanarAlgebra(k, q, base_ring, prefix)#

Bases: SubPartitionAlgebra, UnitDiagramMixin

A planar algebra.

The planar algebra of rank \(k\) is an algebra with basis indexed by the collection of all planar set partitions of \(\{1, \ldots, k, -1, \ldots, -k\}\).

This algebra is thus a subalgebra of the partition algebra. For more information, see PartitionAlgebra.

INPUT:

  • k – rank of the algebra

  • q – the deformation parameter \(q\)

OPTIONAL ARGUMENTS:

  • base_ring – (default None) a ring containing q; if None then just takes the parent of q

  • prefix – (default "Pl") a label for the basis elements

EXAMPLES:

We define the planar algebra of rank \(2\) with parameter \(x\) over \(\ZZ\):

sage: R.<x> = ZZ[]
sage: Pl = PlanarAlgebra(2, x, R); Pl
Planar Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring
sage: Pl.basis().keys()
Planar diagrams of order 2
sage: Pl.basis().keys()([[-1, 1], [2, -2]])
{{-2, 2}, {-1, 1}}
sage: Pl.basis().list()
[Pl{{-2}, {-1}, {1, 2}},
 Pl{{-2}, {-1}, {1}, {2}},
 Pl{{-2, 1}, {-1}, {2}},
 Pl{{-2, 2}, {-1}, {1}},
 Pl{{-2, 1, 2}, {-1}},
 Pl{{-2, 2}, {-1, 1}},
 Pl{{-2}, {-1, 1}, {2}},
 Pl{{-2}, {-1, 2}, {1}},
 Pl{{-2}, {-1, 1, 2}},
 Pl{{-2, -1}, {1, 2}},
 Pl{{-2, -1}, {1}, {2}},
 Pl{{-2, -1, 1}, {2}},
 Pl{{-2, -1, 2}, {1}},
 Pl{{-2, -1, 1, 2}}]
sage: E = Pl([[1,2],[-1,-2]])
sage: E^2 == x*E
True
sage: E^5 == x^4*E
True
class sage.combinat.diagram_algebras.PlanarDiagram(parent, d, check=True)#

Bases: AbstractPartitionDiagram

The element class for a planar diagram.

A planar diagram for an integer \(k\) is a partition of the set \(\{1, \ldots, k, -1, \ldots, -k\}\) so that the diagram is non-crossing.

EXAMPLES:

sage: from sage.combinat.diagram_algebras import PlanarDiagrams
sage: PlanarDiagrams(2)
Planar diagrams of order 2
sage: PlanarDiagrams(2).list()
[{{-2}, {-1}, {1, 2}},
 {{-2}, {-1}, {1}, {2}},
 {{-2, 1}, {-1}, {2}},
 {{-2, 2}, {-1}, {1}},
 {{-2, 1, 2}, {-1}},
 {{-2, 2}, {-1, 1}},
 {{-2}, {-1, 1}, {2}},
 {{-2}, {-1, 2}, {1}},
 {{-2}, {-1, 1, 2}},
 {{-2, -1}, {1, 2}},
 {{-2, -1}, {1}, {2}},
 {{-2, -1, 1}, {2}},
 {{-2, -1, 2}, {1}},
 {{-2, -1, 1, 2}}]
check()#

Check the validity of the input for self.

class sage.combinat.diagram_algebras.PlanarDiagrams(order, category=None)#

Bases: AbstractPartitionDiagrams

All planar diagrams of integer or integer \(+1/2\) order.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pld = da.PlanarDiagrams(1); pld
Planar diagrams of order 1
sage: pld.list()
[{{-1, 1}}, {{-1}, {1}}]

sage: pld = da.PlanarDiagrams(3/2); pld
Planar diagrams of order 3/2
sage: pld.list()
[{{-2, 1, 2}, {-1}},
 {{-2, 2}, {-1}, {1}},
 {{-2, 2}, {-1, 1}},
 {{-2, -1, 2}, {1}},
 {{-2, -1, 1, 2}}]
Element#

alias of PlanarDiagram

cardinality()#

Return the cardinality of self.

The number of all planar diagrams of order \(k\) is the \(2k\)-th Catalan number.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: pld = da.PlanarDiagrams(3)
sage: pld.cardinality()
132
class sage.combinat.diagram_algebras.PropagatingIdeal(k, q, base_ring, prefix)#

Bases: SubPartitionAlgebra

A propagating ideal.

The propagating ideal of rank \(k\) is a non-unital algebra with basis indexed by the collection of ideal set partitions of \(\{1, \ldots, k, -1, \ldots, -k\}\). We say a set partition is ideal if its propagating number is less than \(k\).

This algebra is a non-unital subalgebra and an ideal of the partition algebra. For more information, see PartitionAlgebra.

EXAMPLES:

We now define the propagating ideal of rank \(2\) with parameter \(x\) over \(\ZZ\):

sage: R.<x> = QQ[]
sage: I = PropagatingIdeal(2, x, R); I
Propagating Ideal of rank 2 with parameter x
 over Univariate Polynomial Ring in x over Rational Field
sage: I.basis().keys()
Ideal diagrams of order 2
sage: I.basis().list()
[I{{-2, -1, 1, 2}},
 I{{-2, 1, 2}, {-1}},
 I{{-2}, {-1, 1, 2}},
 I{{-2, -1}, {1, 2}},
 I{{-2}, {-1}, {1, 2}},
 I{{-2, -1, 1}, {2}},
 I{{-2, 1}, {-1}, {2}},
 I{{-2, -1, 2}, {1}},
 I{{-2, 2}, {-1}, {1}},
 I{{-2}, {-1, 1}, {2}},
 I{{-2}, {-1, 2}, {1}},
 I{{-2, -1}, {1}, {2}},
 I{{-2}, {-1}, {1}, {2}}]
sage: E = I([[1,2],[-1,-2]])
sage: E^2 == x*E
True
sage: E^5 == x^4*E
True
class Element#

Bases: Element

An element of a propagating ideal.

We need to take care of exponents since we are not unital.

class sage.combinat.diagram_algebras.SubPartitionAlgebra(k, q, base_ring, prefix, diagrams, category=None)#

Bases: DiagramBasis

A subalgebra of the partition algebra in the diagram basis indexed by a subset of the diagrams.

class Element#

Bases: Element

to_orbit_basis()#

Return self in the orbit basis of the associated ambient partition algebra.

EXAMPLES:

sage: R.<x> = QQ[]
sage: B = BrauerAlgebra(2, x, R)
sage: bb = B([[-2, -1], [1, 2]]); bb
B{{-2, -1}, {1, 2}}
sage: bb.to_orbit_basis()
O{{-2, -1}, {1, 2}} + O{{-2, -1, 1, 2}}
ambient()#

Return the partition algebra self is a sub-algebra of.

EXAMPLES:

sage: x = var('x')
sage: BA = BrauerAlgebra(2, x)
sage: BA.ambient()
Partition Algebra of rank 2 with parameter x over Symbolic Ring
lift()#

Return the lift map from diagram subalgebra to the ambient space.

EXAMPLES:

sage: R.<x> = QQ[]
sage: BA = BrauerAlgebra(2, x, R)
sage: E = BA([[1,2],[-1,-2]])
sage: lifted = BA.lift(E); lifted
B{{-2, -1}, {1, 2}}
sage: lifted.parent() is BA.ambient()
True
retract(x)#

Retract an appropriate partition algebra element to the corresponding element in the partition subalgebra.

EXAMPLES:

sage: R.<x> = QQ[]
sage: BA = BrauerAlgebra(2, x, R)
sage: PA = BA.ambient()
sage: E = PA([[1,2], [-1,-2]])
sage: BA.retract(E) in BA
True
sage.combinat.diagram_algebras.TL_diagram_ascii_art(diagram, use_unicode=False, blobs=[])#

Return ascii art for a Temperley-Lieb diagram diagram.

INPUT:

  • diagram – a list of pairs of matchings of the set \(\{-1, \ldots, -n, 1, \ldots, n\}\)

  • use_unicode – (default: False): whether or not to use unicode art instead of ascii art

  • blobs – (optional) a list of matchings with blobs on them

EXAMPLES:

sage: from sage.combinat.diagram_algebras import TL_diagram_ascii_art
sage: TL = [(-15,-12), (-14,-13), (-11,15), (-10,14), (-9,-6),
....:       (-8,-7), (-5,-4), (-3,1), (-2,-1), (2,3), (4,5),
....:       (6,11), (7, 8), (9,10), (12,13)]
sage: TL_diagram_ascii_art(TL, use_unicode=False)
 o o o o o o o o o o o o o o o
 | `-` `-` | `-` `-` | `-` | |
 |         `---------`     | |
 |                 .-------` |
 `---.             | .-------`
     |     .-----. | | .-----.
 .-. | .-. | .-. | | | | .-. |
 o o o o o o o o o o o o o o o
sage: TL_diagram_ascii_art(TL, use_unicode=True)
 ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬
 │ ╰─╯ ╰─╯ │ ╰─╯ ╰─╯ │ ╰─╯ │ │
 │         ╰─────────╯     │ │
 │                 ╭───────╯ │
 ╰───╮             │ ╭───────╯
     │     ╭─────╮ │ │ ╭─────╮
 ╭─╮ │ ╭─╮ │ ╭─╮ │ │ │ │ ╭─╮ │
 ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬

sage: TL = [(-20,-9), (-19,-10), (-18,-11), (-17,-16), (-15,-12), (2,3),
....:       (-14,-13), (-8,16), (-7,7), (-6,6), (-5,1), (-4,-3), (-2,-1),
....:       (4,5), (8,15), (9,10), (11,14), (12,13), (17,20), (18,19)]
sage: TL_diagram_ascii_art(TL, use_unicode=False, blobs=[(-2,-1), (-5,1)])
 o o o o o o o o o o o o o o o o o o o o
 | `-` `-` | | | `-` | `-` | | | | `-` |
 |         | | |     `-----` | | `-----`
 |         | | `-------------` |
 `---0---. | | .---------------`
         | | | | .---------------------.
         | | | | | .-----------------. |
         | | | | | | .-------------. | |
         | | | | | | | .-----.     | | |
 .0. .-. | | | | | | | | .-. | .-. | | |
 o o o o o o o o o o o o o o o o o o o o
sage: TL_diagram_ascii_art(TL, use_unicode=True, blobs=[(-2,-1), (-5,1)])
 ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬
 │ ╰─╯ ╰─╯ │ │ │ ╰─╯ │ ╰─╯ │ │ │ │ ╰─╯ │
 │         │ │ │     ╰─────╯ │ │ ╰─────╯
 │         │ │ ╰─────────────╯ │
 ╰───●───╮ │ │ ╭───────────────╯
         │ │ │ │ ╭─────────────────────╮
         │ │ │ │ │ ╭─────────────────╮ │
         │ │ │ │ │ │ ╭─────────────╮ │ │
         │ │ │ │ │ │ │ ╭─────╮     │ │ │
 ╭●╮ ╭─╮ │ │ │ │ │ │ │ │ ╭─╮ │ ╭─╮ │ │ │
 ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬
class sage.combinat.diagram_algebras.TemperleyLiebAlgebra(k, q, base_ring, prefix)#

Bases: SubPartitionAlgebra, UnitDiagramMixin

A Temperley–Lieb algebra.

The Temperley–Lieb algebra of rank \(k\) is an algebra with basis indexed by the collection of planar set partitions of \(\{1, \ldots, k, -1, \ldots, -k\}\) with block size 2.

This algebra is thus a subalgebra of the partition algebra. For more information, see PartitionAlgebra.

INPUT:

  • k – rank of the algebra

  • q – the deformation parameter \(q\)

OPTIONAL ARGUMENTS:

  • base_ring – (default None) a ring containing q; if None then just takes the parent of q

  • prefix – (default "T") a label for the basis elements

EXAMPLES:

We define the Temperley–Lieb algebra of rank \(2\) with parameter \(x\) over \(\ZZ\):

sage: R.<x> = ZZ[]
sage: T = TemperleyLiebAlgebra(2, x, R); T
Temperley-Lieb Algebra of rank 2 with parameter x
 over Univariate Polynomial Ring in x over Integer Ring
sage: T.basis()
Lazy family (Term map from Temperley Lieb diagrams of order 2
 to Temperley-Lieb Algebra of rank 2 with parameter x over
 Univariate Polynomial Ring in x over Integer
 Ring(i))_{i in Temperley Lieb diagrams of order 2}
sage: T.basis().keys()
Temperley Lieb diagrams of order 2
sage: T.basis().keys()([[-1, 1], [2, -2]])
{{-2, 2}, {-1, 1}}
sage: b = T.basis().list(); b
[T{{-2, -1}, {1, 2}}, T{{-2, 2}, {-1, 1}}]
sage: b[0]
T{{-2, -1}, {1, 2}}
sage: b[0]^2 == x*b[0]
True
sage: b[0]^5 == x^4*b[0]
True
class sage.combinat.diagram_algebras.TemperleyLiebDiagram(parent, d, check=True)#

Bases: AbstractPartitionDiagram

The element class for a Temperley-Lieb diagram.

A Temperley-Lieb diagram for an integer \(k\) is a partition of the set \(\{1, \ldots, k, -1, \ldots, -k\}\) so that the blocks are all of size 2 and the diagram is planar.

EXAMPLES:

sage: from sage.combinat.diagram_algebras import TemperleyLiebDiagrams
sage: TemperleyLiebDiagrams(2)
Temperley Lieb diagrams of order 2
sage: TemperleyLiebDiagrams(2).list()
[{{-2, -1}, {1, 2}}, {{-2, 2}, {-1, 1}}]
check()#

Check the validity of the input for self.

class sage.combinat.diagram_algebras.TemperleyLiebDiagrams(order, category=None)#

Bases: AbstractPartitionDiagrams

All Temperley-Lieb diagrams of integer or integer \(+1/2\) order.

For more information on Temperley-Lieb diagrams, see TemperleyLiebAlgebra.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: td = da.TemperleyLiebDiagrams(3); td
Temperley Lieb diagrams of order 3
sage: td.list()
[{{-3, 3}, {-2, -1}, {1, 2}},
 {{-3, 1}, {-2, -1}, {2, 3}},
 {{-3, -2}, {-1, 1}, {2, 3}},
 {{-3, -2}, {-1, 3}, {1, 2}},
 {{-3, 3}, {-2, 2}, {-1, 1}}]

sage: td = da.TemperleyLiebDiagrams(5/2); td
Temperley Lieb diagrams of order 5/2
sage: td.list()
[{{-3, 3}, {-2, -1}, {1, 2}}, {{-3, 3}, {-2, 2}, {-1, 1}}]
Element#

alias of TemperleyLiebDiagram

cardinality()#

Return the cardinality of self.

The number of Temperley–Lieb diagrams of integer order \(k\) is the \(k\)-th Catalan number.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: td = da.TemperleyLiebDiagrams(3)
sage: td.cardinality()
5
class sage.combinat.diagram_algebras.UnitDiagramMixin#

Bases: object

Mixin class for diagram algebras that have the unit indexed by the identity_set_partition().

one_basis()#

The following constructs the identity element of self.

It is not called directly; instead one should use DA.one() if DA is a defined diagram algebra.

EXAMPLES:

sage: R.<x> = QQ[]
sage: P = PartitionAlgebra(2, x, R)
sage: P.one_basis()
{{-2, 2}, {-1, 1}}
sage.combinat.diagram_algebras.brauer_diagrams(k)#

Return a generator of all Brauer diagrams of order k.

A Brauer diagram of order \(k\) is a partition diagram of order \(k\) with block size 2.

INPUT:

  • k – the order of the Brauer diagrams

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: [SetPartition(p) for p in da.brauer_diagrams(2)]
[{{-2, -1}, {1, 2}}, {{-2, 1}, {-1, 2}}, {{-2, 2}, {-1, 1}}]
sage: [SetPartition(p) for p in da.brauer_diagrams(5/2)]
[{{-3, 3}, {-2, -1}, {1, 2}},
 {{-3, 3}, {-2, 1}, {-1, 2}},
 {{-3, 3}, {-2, 2}, {-1, 1}}]
sage.combinat.diagram_algebras.diagram_latex(diagram, fill=False, edge_options=None, edge_additions=None)#

Return latex code for the diagram diagram using tikz.

EXAMPLES:

sage: from sage.combinat.diagram_algebras import PartitionDiagrams, diagram_latex
sage: P = PartitionDiagrams(2)
sage: D = P([[1,2],[-2,-1]])
sage: print(diagram_latex(D)) # indirect doctest
\begin{tikzpicture}[scale = 0.5,thick, baseline={(0,-1ex/2)}]
\tikzstyle{vertex} = [shape = circle, minimum size = 7pt, inner sep = 1pt]
\node[vertex] (G--2) at (1.5, -1) [shape = circle, draw] {};
\node[vertex] (G--1) at (0.0, -1) [shape = circle, draw] {};
\node[vertex] (G-1) at (0.0, 1) [shape = circle, draw] {};
\node[vertex] (G-2) at (1.5, 1) [shape = circle, draw] {};
\draw[] (G--2) .. controls +(-0.5, 0.5) and +(0.5, 0.5) .. (G--1);
\draw[] (G-1) .. controls +(0.5, -0.5) and +(-0.5, -0.5) .. (G-2);
\end{tikzpicture}
sage.combinat.diagram_algebras.ideal_diagrams(k)#

Return a generator of all “ideal” diagrams of order k.

An ideal diagram of order \(k\) is a partition diagram of order \(k\) with propagating number less than \(k\).

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: all_diagrams = da.partition_diagrams(2)
sage: [SetPartition(p) for p in all_diagrams if p not in da.ideal_diagrams(2)]
[{{-2, 1}, {-1, 2}}, {{-2, 2}, {-1, 1}}]

sage: all_diagrams = da.partition_diagrams(3/2)
sage: [SetPartition(p) for p in all_diagrams if p not in da.ideal_diagrams(3/2)]
[{{-2, 2}, {-1, 1}}]
sage.combinat.diagram_algebras.identity_set_partition(k)#

Return the identity set partition \(\{\{1, -1\}, \ldots, \{k, -k\}\}\).

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: SetPartition(da.identity_set_partition(2))
{{-2, 2}, {-1, 1}}
sage.combinat.diagram_algebras.is_planar(sp)#

Return True if the diagram corresponding to the set partition sp is planar; otherwise, return False.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: da.is_planar( da.to_set_partition([[1,-2],[2,-1]]))
False
sage: da.is_planar( da.to_set_partition([[1,-1],[2,-2]]))
True
sage.combinat.diagram_algebras.pair_to_graph(sp1, sp2)#

Return a graph consisting of the disjoint union of the graphs of set partitions sp1 and sp2 along with edges joining the bottom row (negative numbers) of sp1 to the top row (positive numbers) of sp2.

The vertices of the graph sp1 appear in the result as pairs (k, 1), whereas the vertices of the graph sp2 appear as pairs (k, 2).

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: sp1 = da.to_set_partition([[1,-2],[2,-1]])
sage: sp2 = da.to_set_partition([[1,-2],[2,-1]])
sage: g = da.pair_to_graph( sp1, sp2 ); g
Graph on 8 vertices

sage: g.vertices(sort=True)
[(-2, 1), (-2, 2), (-1, 1), (-1, 2), (1, 1), (1, 2), (2, 1), (2, 2)]
sage: g.edges(sort=True)
[((-2, 1), (1, 1), None), ((-2, 1), (2, 2), None),
 ((-2, 2), (1, 2), None), ((-1, 1), (1, 2), None),
 ((-1, 1), (2, 1), None), ((-1, 2), (2, 2), None)]

Another example which used to be wrong until trac ticket #15958:

sage: sp3 = da.to_set_partition([[1, -1], [2], [-2]])
sage: sp4 = da.to_set_partition([[1], [-1], [2], [-2]])
sage: g = da.pair_to_graph( sp3, sp4 ); g
Graph on 8 vertices

sage: g.vertices(sort=True)
[(-2, 1), (-2, 2), (-1, 1), (-1, 2), (1, 1), (1, 2), (2, 1), (2, 2)]
sage: g.edges(sort=True)
[((-2, 1), (2, 2), None), ((-1, 1), (1, 1), None),
 ((-1, 1), (1, 2), None)]
sage.combinat.diagram_algebras.partition_diagrams(k)#

Return a generator of all partition diagrams of order k.

A partition diagram of order \(k \in \ZZ\) to is a set partition of \(\{1, \ldots, k, -1, \ldots, -k\}\). If we have \(k - 1/2 \in ZZ\), then a partition diagram of order \(k \in 1/2 \ZZ\) is a set partition of \(\{1, \ldots, k+1/2, -1, \ldots, -(k+1/2)\}\) with \(k+1/2\) and \(-(k+1/2)\) in the same block. See [HR2005].

INPUT:

  • k – the order of the partition diagrams

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: [SetPartition(p) for p in da.partition_diagrams(2)]
[{{-2, -1, 1, 2}},
 {{-2, 1, 2}, {-1}},
 {{-2}, {-1, 1, 2}},
 {{-2, -1}, {1, 2}},
 {{-2}, {-1}, {1, 2}},
 {{-2, -1, 1}, {2}},
 {{-2, 1}, {-1, 2}},
 {{-2, 1}, {-1}, {2}},
 {{-2, 2}, {-1, 1}},
 {{-2, -1, 2}, {1}},
 {{-2, 2}, {-1}, {1}},
 {{-2}, {-1, 1}, {2}},
 {{-2}, {-1, 2}, {1}},
 {{-2, -1}, {1}, {2}},
 {{-2}, {-1}, {1}, {2}}]
sage: [SetPartition(p) for p in da.partition_diagrams(3/2)]
[{{-2, -1, 1, 2}},
 {{-2, 1, 2}, {-1}},
 {{-2, 2}, {-1, 1}},
 {{-2, -1, 2}, {1}},
 {{-2, 2}, {-1}, {1}}]
sage.combinat.diagram_algebras.planar_diagrams(k)#

Return a generator of all planar diagrams of order k.

A planar diagram of order \(k\) is a partition diagram of order \(k\) that has no crossings.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: all_diagrams = [SetPartition(p) for p in da.partition_diagrams(2)]
sage: da2 = [SetPartition(p) for p in da.planar_diagrams(2)]
sage: [p for p in all_diagrams if p not in da2]
[{{-2, 1}, {-1, 2}}]
sage: all_diagrams = [SetPartition(p) for p in da.partition_diagrams(5/2)]
sage: da5o2 = [SetPartition(p) for p in da.planar_diagrams(5/2)]
sage: [p for p in all_diagrams if p not in da5o2]
[{{-3, -1, 3}, {-2, 1, 2}},
 {{-3, -2, 1, 3}, {-1, 2}},
 {{-3, -1, 1, 3}, {-2, 2}},
 {{-3, 1, 3}, {-2, -1, 2}},
 {{-3, 1, 3}, {-2, 2}, {-1}},
 {{-3, 1, 3}, {-2}, {-1, 2}},
 {{-3, -1, 2, 3}, {-2, 1}},
 {{-3, 3}, {-2, 1}, {-1, 2}},
 {{-3, -1, 3}, {-2, 1}, {2}},
 {{-3, -1, 3}, {-2, 2}, {1}}]
sage.combinat.diagram_algebras.planar_partitions_rec(X)#

Iterate over all planar set partitions of X by using a recursive algorithm.

ALGORITHM:

To construct the set partition \(\rho = \{\rho_1, \ldots, \rho_k\}\) of \([n]\), we remove the part of the set partition containing the last element of X, which, we consider to be \(\rho_k = \{i_1, \ldots, i_m\}\) without loss of generality. The remaining parts come from the planar set partitions of \(\{1, \ldots, i_1-1\}, \{i_1+1, \ldots, i_2-1\}, \ldots, \{i_m+1, \ldots, n\}\).

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: list(da.planar_partitions_rec([1,2,3]))
[([1, 2], [3]), ([1], [2], [3]), ([2], [1, 3]), ([1], [2, 3]), ([1, 2, 3],)]
sage.combinat.diagram_algebras.propagating_number(sp)#

Return the propagating number of the set partition sp.

The propagating number is the number of blocks with both a positive and negative number.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: sp1 = da.to_set_partition([[1,-2],[2,-1]])
sage: sp2 = da.to_set_partition([[1,2],[-2,-1]])
sage: da.propagating_number(sp1)
2
sage: da.propagating_number(sp2)
0
sage.combinat.diagram_algebras.temperley_lieb_diagrams(k)#

Return a generator of all Temperley–Lieb diagrams of order k.

A Temperley–Lieb diagram of order \(k\) is a partition diagram of order \(k\) with block size 2 and is planar.

INPUT:

  • k – the order of the Temperley–Lieb diagrams

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: [SetPartition(p) for p in da.temperley_lieb_diagrams(2)]
[{{-2, -1}, {1, 2}}, {{-2, 2}, {-1, 1}}]
sage: [SetPartition(p) for p in da.temperley_lieb_diagrams(5/2)]
[{{-3, 3}, {-2, -1}, {1, 2}}, {{-3, 3}, {-2, 2}, {-1, 1}}]
sage.combinat.diagram_algebras.to_Brauer_partition(l, k=None)#

Same as to_set_partition() but assumes omitted elements are connected straight through.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: f = lambda sp: SetPartition(da.to_Brauer_partition(sp))
sage: f([[1,2],[-1,-2]]) == SetPartition([[1,2],[-1,-2]])
True
sage: f([[1,3],[-1,-3]]) == SetPartition([[1,3],[-3,-1],[2,-2]])
True
sage: f([[1,-4],[-3,-1],[3,4]]) == SetPartition([[-3,-1],[2,-2],[1,-4],[3,4]])
True
sage: p = SetPartition([[1,2],[-1,-2],[3,-3],[4,-4]])
sage: SetPartition(da.to_Brauer_partition([[1,2],[-1,-2]], k=4)) == p
True
sage.combinat.diagram_algebras.to_graph(sp)#

Return a graph representing the set partition sp.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: g = da.to_graph( da.to_set_partition([[1,-2],[2,-1]])); g
Graph on 4 vertices

sage: g.vertices(sort=True)
[-2, -1, 1, 2]
sage: g.edges(sort=True)
[(-2, 1, None), (-1, 2, None)]
sage.combinat.diagram_algebras.to_set_partition(l, k=None)#

Convert input to a set partition of \(\{1, \ldots, k, -1, \ldots, -k\}\)

Convert a list of a list of numbers to a set partitions. Each list of numbers in the outer list specifies the numbers contained in one of the blocks in the set partition.

If \(k\) is specified, then the set partition will be a set partition of \(\{1, \ldots, k, -1, \ldots, -k\}\). Otherwise, \(k\) will default to the minimum number needed to contain all of the specified numbers.

INPUT:

  • l - a list of lists of integers

  • k - integer (optional, default None)

OUTPUT:

  • a list of sets

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: f = lambda sp: SetPartition(da.to_set_partition(sp))
sage: f([[1,-1],[2,-2]]) == SetPartition(da.identity_set_partition(2))
True
sage: da.to_set_partition([[1]])
[{1}, {-1}]
sage: da.to_set_partition([[1,-1],[-2,3]],9/2)
[{-1, 1}, {-2, 3}, {2}, {-4, 4}, {-5, 5}, {-3}]