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.

  • Travis Scrimshaw (2024): Implemented the Potts representation of the partition algebra.

class sage.combinat.diagram_algebras.AbstractPartitionDiagram(parent, d, check=True)[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.AbstractPartitionDiagrams(Integer(2))
>>> pd1 = da.AbstractPartitionDiagram(pd, [[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
>>> pd2 = da.AbstractPartitionDiagram(pd, [[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
>>> pd1
{{-2, -1}, {1, 2}}
>>> pd1 == pd2
True
>>> pd1 == [[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]
True
>>> pd1 == ((-Integer(2),-Integer(1)),(Integer(2),Integer(1)))
True
>>> pd1 == SetPartition([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
True
>>> pd3 = da.AbstractPartitionDiagram(pd, [[Integer(1),-Integer(2)],[-Integer(1),Integer(2)]])
>>> pd1 == pd3
False
>>> pd4 = da.AbstractPartitionDiagram(pd, [[Integer(1),Integer(2)],[Integer(3),Integer(4)]])
Traceback (most recent call last):
...
ValueError: {{1, 2}, {3, 4}} does not represent two rows of vertices of order 2
base_diagram()[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.AbstractPartitionDiagrams(Integer(2))
>>> pd([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]).base_diagram() == ((-Integer(2),-Integer(1)),(Integer(1),Integer(2)))
True
check()[source]

Check the validity of the input for the diagram.

compose(other, check=True)[source]

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)
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.AbstractPartitionDiagrams(Integer(2))
>>> pd([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]).compose(pd([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]))
({{-2, -1}, {1, 2}}, 1)
count_blocks_of_size(n)[source]

Count the number of blocks of a given size.

INPUT:

  • n – 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
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import PartitionDiagram
>>> pd = PartitionDiagram([[Integer(1),-Integer(3),-Integer(5)],[Integer(2),Integer(4)],[Integer(3),-Integer(1),-Integer(2)],[Integer(5)],[-Integer(4)]])
>>> pd.count_blocks_of_size(Integer(1))
2
>>> pd.count_blocks_of_size(Integer(2))
1
>>> pd.count_blocks_of_size(Integer(3))
2
diagram()[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.AbstractPartitionDiagrams(Integer(2))
>>> pd([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]).base_diagram() == ((-Integer(2),-Integer(1)),(Integer(1),Integer(2)))
True
dual()[source]

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}}
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import PartitionDiagram
>>> D = PartitionDiagram([[Integer(1),-Integer(1)],[Integer(2),-Integer(2),-Integer(3)],[Integer(3)]])
>>> D.dual()
{{-3}, {-2, 2, 3}, {-1, 1}}
is_planar()[source]

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
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import BrauerDiagram
>>> BrauerDiagram([[Integer(1),-Integer(2)],[Integer(2),-Integer(1)]]).is_planar()
False
>>> BrauerDiagram([[Integer(1),-Integer(1)],[Integer(2),-Integer(2)]]).is_planar()
True
order()[source]

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
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import PartitionDiagram
>>> PartitionDiagram([[Integer(1),-Integer(1)],[Integer(2),-Integer(2),-Integer(3)],[Integer(3)]]).order()
3
>>> PartitionDiagram([[Integer(1),-Integer(1)]]).order()
1
>>> PartitionDiagram([[Integer(1),-Integer(3),-Integer(5)],[Integer(2),Integer(4)],[Integer(3),-Integer(1),-Integer(2)],[Integer(5)],[-Integer(4)]]).order()
5
propagating_number()[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.AbstractPartitionDiagrams(Integer(2))
>>> d1 = pd([[Integer(1),-Integer(2)],[Integer(2),-Integer(1)]])
>>> d1.propagating_number()
2
>>> d2 = pd([[Integer(1),Integer(2)],[-Integer(2),-Integer(1)]])
>>> d2.propagating_number()
0
set_partition()[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.AbstractPartitionDiagrams(Integer(2))
>>> X = pd([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]).set_partition(); X
{{-2, -1}, {1, 2}}
>>> X.parent()
Set partitions
class sage.combinat.diagram_algebras.AbstractPartitionDiagrams(order, category=None)[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.PartitionDiagrams(Integer(2))
>>> pd
Partition diagrams of order 2
>>> pd.an_element() in pd
True
>>> elm = pd([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
>>> elm in pd
True
Element[source]

alias of AbstractPartitionDiagram

class sage.combinat.diagram_algebras.BrauerAlgebra(k, q, base_ring, prefix)[source]

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\)

  • 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}}
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> B = BrauerAlgebra(Integer(2), x, R)
>>> B
Brauer Algebra of rank 2 with parameter x
 over Univariate Polynomial Ring in x over Integer Ring
>>> 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}
>>> B.basis().keys()
Brauer diagrams of order 2
>>> B.basis().keys()([[-Integer(2), Integer(1)], [Integer(2), -Integer(1)]])
{{-2, 1}, {-1, 2}}
>>> b = B.basis().list(); b
[B{{-2, -1}, {1, 2}}, B{{-2, 1}, {-1, 2}}, B{{-2, 2}, {-1, 1}}]
>>> b[Integer(0)]
B{{-2, -1}, {1, 2}}
>>> b[Integer(0)]**Integer(2)
x*B{{-2, -1}, {1, 2}}
>>> b[Integer(0)]**Integer(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}}
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> B = BrauerAlgebra(Integer(2), x, R)
>>> S = SymmetricGroupAlgebra(R, Integer(2))
>>> S([Integer(2),Integer(1)])*B([[Integer(1),-Integer(1)],[Integer(2),-Integer(2)]])
B{{-2, 1}, {-1, 2}}
jucys_murphy(j)[source]

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: # needs sage.symbolic
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}}
>>> from sage.all import *
>>> # needs sage.symbolic
>>> z = var('z')
>>> B = BrauerAlgebra(Integer(3),z)
>>> B.jucys_murphy(Integer(1))
(1/2*z-1/2)*B{{-3, 3}, {-2, 2}, {-1, 1}}
>>> B.jucys_murphy(Integer(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[source]
class sage.combinat.diagram_algebras.BrauerDiagram(parent, d, check=True)[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(2))
>>> bd1 = bd([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
>>> bd2 = bd([[Integer(1),Integer(2),-Integer(1),-Integer(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)[source]

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]]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(3))
>>> elm = bd([[Integer(1),Integer(2)],[-Integer(2),-Integer(3)],[Integer(3),-Integer(1)]])
>>> elm.bijection_on_free_nodes()
[[3, -1]]
>>> elm2 = bd([[Integer(1),-Integer(2)],[Integer(2),-Integer(3)],[Integer(3),-Integer(1)]])
>>> elm2.bijection_on_free_nodes(two_line=True)
[[1, 2, 3], [-2, -3, -1]]
check()[source]

Check the validity of the input for self.

involution_permutation_triple(curt=True)[source]

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 – boolean (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]])
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(3))
>>> elm = bd([[Integer(1),Integer(2)],[-Integer(2),-Integer(3)],[Integer(3),-Integer(1)]])
>>> elm.involution_permutation_triple()
([(1, 2)], [(-3, -2)], [1])
>>> elm.involution_permutation_triple(curt=False)
([(1, 2)], [(-3, -2)], [[3, -1]])
is_elementary_symmetric()[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(3))
>>> elm = bd([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)],[Integer(3),-Integer(3)]])
>>> elm.is_elementary_symmetric()
True
>>> elm2 = bd([[Integer(1),Integer(2)],[-Integer(1),-Integer(3)],[Integer(3),-Integer(2)]])
>>> elm2.is_elementary_symmetric()
False
options = Current options for Brauer diagram   - display: normal[source]
perm()[source]

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]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(3))
>>> elm = bd([[Integer(1),Integer(2)],[-Integer(2),-Integer(3)],[Integer(3),-Integer(1)]])
>>> elm.perm()
[1]
class sage.combinat.diagram_algebras.BrauerDiagrams(order, category=None)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(2)); bd
Brauer diagrams of order 2
>>> bd.list()
[{{-2, -1}, {1, 2}}, {{-2, 1}, {-1, 2}}, {{-2, 2}, {-1, 1}}]

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

alias of BrauerDiagram

cardinality()[source]

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 sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(3))
>>> bd.cardinality()
15

>>> bd = da.BrauerDiagrams(Integer(7)/Integer(2))
>>> bd.cardinality()
15
from_involution_permutation_triple(D1_D2_pi)[source]

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 – 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}}
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(4))
>>> bd.from_involution_permutation_triple([[[Integer(1),Integer(2)]],[[Integer(3),Integer(4)]],[Integer(2),Integer(1)]])
{{-4, -3}, {-2, 3}, {-1, 4}, {1, 2}}
options = Current options for Brauer diagram   - display: normal[source]
symmetric_diagrams(l=None, perm=None)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> bd = da.BrauerDiagrams(Integer(4))
>>> bd.symmetric_diagrams(l=Integer(1), perm=[Integer(2),Integer(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)[source]

Bases: CombinatorialFreeModule

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

class Element[source]

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()[source]

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}}
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> P = PartitionAlgebra(Integer(2), x, R)
>>> elt = Integer(3)*P([[Integer(1),Integer(2)],[-Integer(2),-Integer(1)]])
>>> elt.diagram()
{{-2, -1}, {1, 2}}
diagrams()[source]

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}}]
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> P = PartitionAlgebra(Integer(2), x, R)
>>> elt = Integer(3)*P([[Integer(1),Integer(2)],[-Integer(2),-Integer(1)]]) + P([[Integer(1),Integer(2)],[-Integer(2)], [-Integer(1)]])
>>> sorted(elt.diagrams(), key=str)
[{{-2, -1}, {1, 2}}, {{-2}, {-1}, {1, 2}}]
order()[source]

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')                                                          # needs sage.symbolic
sage: PA = PartitionAlgebra(2, q)                                           # needs sage.symbolic
sage: PA.order()                                                            # needs sage.symbolic
2
>>> from sage.all import *
>>> q = var('q')                                                          # needs sage.symbolic
>>> PA = PartitionAlgebra(Integer(2), q)                                           # needs sage.symbolic
>>> PA.order()                                                            # needs sage.symbolic
2
set_partitions()[source]

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)[source]

Bases: DiagramAlgebra

Abstract base class for diagram algebras in the diagram basis.

product_on_basis(d1, d2)[source]

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

class sage.combinat.diagram_algebras.HalfTemperleyLiebDiagrams(order, defects)[source]

Bases: UniqueRepresentation, Parent

Half diagrams for the Temperley-Lieb algebra cell modules.

class Element(parent, d, check=True)[source]

Bases: AbstractPartitionDiagram

check()[source]

Check the validity of the input of self.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: htld = da.HalfTemperleyLiebDiagrams(7, 3)
sage: htld([[1,2], [3,4]])  # indirect doctest
{{1, 2}, {3, 4}}
sage: htld([[1,2], [-1, -2]])  # indirect doctest
Traceback (most recent call last):
...
ValueError: {{-2, -1}, {1, 2}} does not represent a half TL diagram of order 7
sage: htld([[1,2,3], [4,5]])  # indirect doctest
Traceback (most recent call last):
...
ValueError: all blocks of {{1, 2, 3}, {4, 5}} must be of size 2
sage: htld([[1,2], [3,4], [5,6]])  # indirect doctest
Traceback (most recent call last):
...
ValueError: {{1, 2}, {3, 4}, {5, 6}} does not have 3 defects
sage: htld([[1,3], [2,4]])  # indirect doctest
Traceback (most recent call last):
...
ValueError: {{1, 3}, {2, 4}} is not planar
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> htld = da.HalfTemperleyLiebDiagrams(Integer(7), Integer(3))
>>> htld([[Integer(1),Integer(2)], [Integer(3),Integer(4)]])  # indirect doctest
{{1, 2}, {3, 4}}
>>> htld([[Integer(1),Integer(2)], [-Integer(1), -Integer(2)]])  # indirect doctest
Traceback (most recent call last):
...
ValueError: {{-2, -1}, {1, 2}} does not represent a half TL diagram of order 7
>>> htld([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5)]])  # indirect doctest
Traceback (most recent call last):
...
ValueError: all blocks of {{1, 2, 3}, {4, 5}} must be of size 2
>>> htld([[Integer(1),Integer(2)], [Integer(3),Integer(4)], [Integer(5),Integer(6)]])  # indirect doctest
Traceback (most recent call last):
...
ValueError: {{1, 2}, {3, 4}, {5, 6}} does not have 3 defects
>>> htld([[Integer(1),Integer(3)], [Integer(2),Integer(4)]])  # indirect doctest
Traceback (most recent call last):
...
ValueError: {{1, 3}, {2, 4}} is not planar
defects()[source]

Return the defects of self.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: htld = da.HalfTemperleyLiebDiagrams(7, 3)
sage: d = htld([[1, 2], [4, 5]])
sage: d.defects()
frozenset({3, 6, 7})
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> htld = da.HalfTemperleyLiebDiagrams(Integer(7), Integer(3))
>>> d = htld([[Integer(1), Integer(2)], [Integer(4), Integer(5)]])
>>> d.defects()
frozenset({3, 6, 7})
cardinality()[source]

Return the cardinality of self.

EXAMPLES:

sage: import sage.combinat.diagram_algebras as da
sage: htld = da.HalfTemperleyLiebDiagrams(7, 3)
sage: htld.cardinality()
14
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> htld = da.HalfTemperleyLiebDiagrams(Integer(7), Integer(3))
>>> htld.cardinality()
14
class sage.combinat.diagram_algebras.IdealDiagram(parent, d, check=True)[source]

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
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import IdealDiagrams as IDs
>>> IDs(Integer(2))
Ideal diagrams of order 2
>>> IDs(Integer(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}}]

>>> from sage.combinat.diagram_algebras import PartitionDiagrams as PDs
>>> PDs(Integer(4)).cardinality() == factorial(Integer(4)) + IDs(Integer(4)).cardinality()
True
check()[source]

Check the validity of the input for self.

class sage.combinat.diagram_algebras.IdealDiagrams(order, category=None)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> id = da.IdealDiagrams(Integer(3))
>>> id.an_element() in id
True
>>> id.cardinality() == len(id.list())
True
>>> da.IdealDiagrams(Integer(3)/Integer(2)).list()
[{{-2, -1, 1, 2}},
 {{-2, 1, 2}, {-1}},
 {{-2, -1, 2}, {1}},
 {{-2, 2}, {-1}, {1}}]
Element[source]

alias of IdealDiagram

class sage.combinat.diagram_algebras.OrbitBasis(alg)[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P2 = PartitionAlgebra(Integer(2), x, R)
>>> 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
>>> oa = O2([[Integer(1)],[-Integer(1)],[Integer(2),-Integer(2)]]); ob = O2([[-Integer(1),-Integer(2),Integer(2)],[Integer(1)]]); oa, ob
(O{{-2, 2}, {-1}, {1}}, O{{-2, -1, 2}, {1}})
>>> 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}}
>>> from sage.all import *
>>> 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}}
>>> pa * ob
(-x+2)*P{{-2, -1, 1, 2}} + (x-2)*P{{-2, -1, 2}, {1}}
>>> _ == pa * P2(ob)
True
>>> 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
>>> from sage.all import *
>>> P2.one()
P{{-2, 2}, {-1, 1}}
>>> O2.one()
O{{-2, -1, 1, 2}} + O{{-2, 2}, {-1, 1}}
>>> O2.one() == P2.one()
True
class Element[source]

Bases: Element

to_diagram_basis()[source]

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
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P = PartitionAlgebra(Integer(2), x, R)
>>> O = P.orbit_basis()
>>> elt = O.an_element(); elt
3*O{{-2}, {-1, 1, 2}} + 2*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
>>> elt.to_diagram_basis()
3*P{{-2}, {-1, 1, 2}} - 3*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
>>> pp = P.an_element(); pp
3*P{{-2}, {-1, 1, 2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
>>> op = pp.to_orbit_basis(); op
3*O{{-2}, {-1, 1, 2}} + 7*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
>>> pp == op.to_diagram_basis()
True
diagram_basis()[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> O2 = PartitionAlgebra(Integer(2), x, R).orbit_basis()
>>> P2 = O2.diagram_basis(); P2
Partition Algebra of rank 2 with parameter x over Univariate
Polynomial Ring in x over Rational Field
>>> o2 = O2.an_element(); o2
3*O{{-2}, {-1, 1, 2}} + 2*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
>>> P2(o2)
3*P{{-2}, {-1, 1, 2}} - 3*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
one()[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P2 = PartitionAlgebra(Integer(2), x, R)
>>> O2 = P2.orbit_basis()
>>> O2.one()
O{{-2, -1, 1, 2}} + O{{-2, 2}, {-1, 1}}
product_on_basis(d1, d2)[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> OP = PartitionAlgebra(Integer(2), x, R).orbit_basis()
>>> SP = OP.basis().keys(); sp = SP([[-Integer(2), -Integer(1), Integer(1), Integer(2)]])
>>> OP.product_on_basis(sp, sp)
O{{-2, -1, 1, 2}}
>>> o1 = OP.one(); o2 = OP([]); o3 = OP.an_element()
>>> o2 == o1
False
>>> o1 * o1 == o1
True
>>> o3 * o1 == o1 * o3 and o3 * o1 == o3
True
>>> o4 = (Integer(3)*OP([[-Integer(2), -Integer(1), Integer(1)], [Integer(2)]]) + Integer(2)*OP([[-Integer(2), -Integer(1), Integer(1), Integer(2)]])
...       + Integer(2)*OP([[-Integer(2), -Integer(1), Integer(2)], [Integer(1)]]))
>>> 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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P = PartitionAlgebra(Integer(3),x); O = P.orbit_basis()
>>> O[[Integer(1),Integer(2),Integer(3)],[-Integer(1),-Integer(2),-Integer(3)]] * O[[Integer(1),Integer(2),Integer(3)],[-Integer(1),-Integer(2),-Integer(3)]]
(x-2)*O{{-3, -2, -1}, {1, 2, 3}} + (x-1)*O{{-3, -2, -1, 1, 2, 3}}

>>> P = PartitionAlgebra(Integer(4),x); O = P.orbit_basis()
>>> O[[Integer(1)],[-Integer(1)],[Integer(2),Integer(3)],[Integer(4),-Integer(2)],[-Integer(3),-Integer(4)]] * O[[Integer(1)],[Integer(2),-Integer(2)],[Integer(3),Integer(4)],[-Integer(1),-Integer(3)],[-Integer(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}}

>>> O[[Integer(1),-Integer(1)],[Integer(2),-Integer(2)],[Integer(3)],[Integer(4),-Integer(3)],[-Integer(4)]] * O[[Integer(1),-Integer(2)],[Integer(2)],[Integer(3),-Integer(1)],[Integer(4)],[-Integer(3)],[-Integer(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}}

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

>>> (O[[Integer(1),-Integer(2)],[Integer(2),-Integer(3)],[Integer(3),Integer(5)],[Integer(4),-Integer(5)],[Integer(6),-Integer(4)],[-Integer(1)],[-Integer(6)]]
...  * O[[Integer(1),-Integer(2)],[Integer(2),-Integer(1)],[Integer(3),-Integer(4)],[Integer(4),-Integer(6)],[Integer(5),-Integer(3)],[Integer(6),-Integer(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)[source]

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}}
>>> from sage.all import *
>>> P = PartitionAlgebra(Integer(4), Integer(0))
>>> P.a(Integer(2))
P{{-4, 4}, {-3, -2}, {-1, 1}, {2, 3}}
>>> P.e(Integer(3)/Integer(2))
P{{-4, 4}, {-3, 3}, {-2}, {-1, 1}, {2}}
>>> P.e(Integer(2))
P{{-4, 4}, {-3, -2, 2, 3}, {-1, 1}}
>>> P.e(Integer(5)/Integer(2))
P{{-4, 4}, {-3}, {-2, 2}, {-1, 1}, {3}}
>>> P.s(Integer(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\)

  • 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
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> R
Univariate Polynomial Ring in x over Rational Field
>>> x
x
>>> 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}}
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> A2 = PartitionAlgebra(Integer(2), x, R)
>>> A2
Partition Algebra of rank 2 with parameter x
 over Univariate Polynomial Ring in x over Integer Ring
>>> A2.basis().keys()
Partition diagrams of order 2
>>> A2.basis().keys()([[-Integer(2), Integer(1), Integer(2)], [-Integer(1)]])
{{-2, 1, 2}, {-1}}
>>> 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}}]
>>> E = A2([[Integer(1),Integer(2)],[-Integer(2),-Integer(1)]]); E
P{{-2, -1}, {1, 2}}
>>> E in A2.basis().list()
True
>>> E**Integer(2)
x*P{{-2, -1}, {1, 2}}
>>> E**Integer(5)
x^4*P{{-2, -1}, {1, 2}}
>>> (A2([[Integer(2),-Integer(2)],[-Integer(1),Integer(1)]]) - Integer(2)*A2([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]))**Integer(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}}
>>> from sage.all import *
>>> 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}}
>>> from sage.all import *
>>> A4 = PartitionAlgebra(Integer(4), x, R)
>>> 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}}
>>> from sage.all import *
>>> A4([])
P{{-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}}
>>> A4(Integer(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}}
>>> from sage.all import *
>>> S3 = SymmetricGroupAlgebra(ZZ, Integer(3))
>>> s3 = S3.an_element(); s3
[1, 2, 3] + 2*[1, 3, 2] + 3*[2, 1, 3] + [3, 1, 2]
>>> 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}}
>>> A4([Integer(2),Integer(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}}
>>> from sage.all import *
>>> A4([[Integer(2),Integer(1)]])
P{{-4, 4}, {-3, 3}, {-2}, {-1}, {1, 2}}
>>> A4([[-Integer(1),Integer(3)],[-Integer(2),-Integer(3),Integer(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}}
>>> from sage.all import *
>>> B3 = BrauerAlgebra(Integer(3), x, R)
>>> 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}}
>>> from sage.all import *
>>> O2 = A2.orbit_basis()
>>> o2 = O2([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]) + O2([[Integer(1),Integer(2),-Integer(1),-Integer(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}}
>>> from sage.all import *
>>> 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}}
>>> from sage.all import *
>>> o2 = O2.an_element(); o2
3*O{{-2}, {-1, 1, 2}} + 2*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
>>> 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: # needs sage.symbolic
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
>>> from sage.all import *
>>> # needs sage.symbolic
>>> q = var('q')
>>> PA = PartitionAlgebra(Integer(2), q); PA
Partition Algebra of rank 2 with parameter q over Symbolic Ring
>>> PA([[Integer(1),Integer(2)],[-Integer(2),-Integer(1)]])**Integer(2) == q*PA([[Integer(1),Integer(2)],[-Integer(2),-Integer(1)]])
True
>>> ((PA([[Integer(2), -Integer(2)], [Integer(1), -Integer(1)]]) - Integer(2)*PA([[-Integer(2), -Integer(1)], [Integer(1), Integer(2)]]))**Integer(2)
...   == (Integer(4)*q-Integer(4))*PA([[Integer(1), Integer(2)], [-Integer(2), -Integer(1)]]) + PA([[Integer(2), -Integer(2)], [Integer(1), -Integer(1)]]))
True

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

sage: # needs sage.symbolic
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
>>> from sage.all import *
>>> # needs sage.symbolic
>>> P = PA.basis().list()
>>> PA.one()
P{{-2, 2}, {-1, 1}}
>>> PA.one() * P[Integer(7)] == P[Integer(7)]
True
>>> P[Integer(7)] * PA.one() == P[Integer(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
>>> from sage.all import *
>>> R = RR['q']; (q,) = R._first_ngens(1)
>>> PA = PartitionAlgebra(Integer(2), q, R, prefix='B')
>>> PA
Partition Algebra of rank 2 with parameter q over
 Univariate Polynomial Ring in q over Real Field with 53 bits of precision
>>> PA([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
1.00000000000000*B{{-2, -1}, {1, 2}}
>>> PA = PartitionAlgebra(Integer(2), Integer(5), base_ring=ZZ, prefix='B')
>>> PA
Partition Algebra of rank 2 with parameter 5 over Integer Ring
>>> ((PA([[Integer(2), -Integer(2)], [Integer(1), -Integer(1)]]) - Integer(2)*PA([[-Integer(2), -Integer(1)], [Integer(1), Integer(2)]]))**Integer(2)
...   == Integer(16)*PA([[-Integer(2), -Integer(1)], [Integer(1), Integer(2)]]) + PA([[Integer(2), -Integer(2)], [Integer(1), -Integer(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: # needs sage.symbolic
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}}
>>> from sage.all import *
>>> # needs sage.symbolic
>>> S = SymmetricGroupAlgebra(SR, Integer(2))
>>> B = BrauerAlgebra(Integer(2), x, SR)
>>> A = PartitionAlgebra(Integer(2), x, SR)
>>> S([Integer(2),Integer(1)]) * A([[Integer(1),-Integer(1)],[Integer(2),-Integer(2)]])
P{{-2, 1}, {-1, 2}}
>>> B([[-Integer(1),-Integer(2)],[Integer(2),Integer(1)]]) * A([[Integer(1)],[-Integer(1)],[Integer(2),-Integer(2)]])
P{{-2}, {-1}, {1, 2}}
>>> A([[Integer(1)],[-Integer(1)],[Integer(2),-Integer(2)]]) * B([[-Integer(1),-Integer(2)],[Integer(2),Integer(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}}
>>> from sage.all import *
>>> R = FractionField(ZZ['q']); q = R.gen()
>>> S = SymmetricGroupAlgebra(ZZ, Integer(2))
>>> B = BrauerAlgebra(Integer(2), q, ZZ[q])
>>> A = PartitionAlgebra(Integer(3), q, R)
>>> S([Integer(2),Integer(1)]) * A([[Integer(1),-Integer(1)],[Integer(2),-Integer(3)],[Integer(3),-Integer(2)]])
P{{-3, 1}, {-2, 3}, {-1, 2}}
>>> A(B([[-Integer(1),-Integer(2)],[Integer(2),Integer(1)]]))
P{{-3, 3}, {-2, -1}, {1, 2}}
class Element[source]

Bases: Element

dual()[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P = PartitionAlgebra(Integer(2), x, R)
>>> elt = P.an_element(); elt
3*P{{-2}, {-1, 1, 2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
>>> elt.dual()
3*P{{-2, -1, 1}, {2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, -1, 2}, {1}}
to_orbit_basis()[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P = PartitionAlgebra(Integer(2), x, R)
>>> pp = P.an_element();
>>> pp.to_orbit_basis()
3*O{{-2}, {-1, 1, 2}} + 7*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
>>> pp = (Integer(3)*P([[-Integer(2)], [-Integer(1), Integer(1), Integer(2)]]) + Integer(2)*P([[-Integer(2), -Integer(1), Integer(1), Integer(2)]])
...       + Integer(2)*P([[-Integer(2), Integer(1), Integer(2)], [-Integer(1)]])); pp
3*P{{-2}, {-1, 1, 2}} + 2*P{{-2, -1, 1, 2}} + 2*P{{-2, 1, 2}, {-1}}
>>> pp.to_orbit_basis()
3*O{{-2}, {-1, 1, 2}} + 7*O{{-2, -1, 1, 2}} + 2*O{{-2, 1, 2}, {-1}}
L(i)[source]

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

INPUT:

  • i – 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
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.jucys_murphy_element(Integer(1)/Integer(2))
0
>>> P3.jucys_murphy_element(Integer(1))
P{{-3, 3}, {-2, 2}, {-1}, {1}}
>>> P3.jucys_murphy_element(Integer(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}}
>>> P3.jucys_murphy_element(Integer(3)/Integer(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}}
>>> P3.L(Integer(3)/Integer(2)) * P3.L(Integer(2)) == P3.L(Integer(2)) * P3.L(Integer(3)/Integer(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, y in Subsets(L, 2))  # 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
>>> from sage.all import *
>>> k = Integer(4)
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P = PartitionAlgebra(k, n)
>>> L = [P.L(i/Integer(2)) for i in range(Integer(1),Integer(2)*k+Integer(1))]
>>> all(x.dual() == x for x in L)
True
>>> all(x * y == y * x for x, y in Subsets(L, Integer(2)))  # long time
True
>>> Lsum = sum(L)
>>> gens = [P.s(i) for i in range(Integer(1),k)]
>>> gens += [P.e(i/Integer(2)) for i in range(Integer(1),Integer(2)*k)]
>>> 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
>>> from sage.all import *
>>> all(P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.sigma(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2))
...     == (n - P.L((Integer(2)*i-Integer(1))/Integer(2))) * P.e((Integer(2)*i+Integer(1))/Integer(2)) for i in range(Integer(1),k))
True
>>> all(P.e(i/Integer(2)) * (P.L(i/Integer(2)) + P.L((i+Integer(1))/Integer(2)))
...     == (P.L(i/Integer(2)) + P.L((i+Integer(1))/Integer(2))) * P.e(i/Integer(2))
...     == n * P.e(i/Integer(2)) for i in range(Integer(1),Integer(2)*k))
True
>>> all(P.sigma(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i-Integer(1))/Integer(2)) * P.e(Integer(2)*i/Integer(2))
...     == P.L(Integer(2)*i/Integer(2)) * P.e(Integer(2)*i/Integer(2)) for i in range(Integer(1),k))
True
>>> all(P.e(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i-Integer(1))/Integer(2)) * P.sigma(Integer(2)*i/Integer(2))
...     == P.e(Integer(2)*i/Integer(2)) * P.L(Integer(2)*i/Integer(2)) for i in range(Integer(1),k))
True
>>> all(P.sigma((Integer(2)*i+Integer(1))/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.e(Integer(2)*i/Integer(2))
...     == P.L(Integer(2)*i/Integer(2)) * P.e(Integer(2)*i/Integer(2)) for i in range(Integer(1),k))
True
>>> all(P.e(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.sigma((Integer(2)*i+Integer(1))/Integer(2))
...     == P.e(Integer(2)*i/Integer(2)) * P.L(Integer(2)*i/Integer(2)) for i in range(Integer(1),k))
True

The same tests for a half integer partition algebra:

sage: k = 7/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, y in Subsets(L, 2))  # 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
>>> from sage.all import *
>>> k = Integer(7)/Integer(2)
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P = PartitionAlgebra(k, n)
>>> L = [P.L(i/Integer(2)) for i in range(Integer(1),Integer(2)*k+Integer(1))]
>>> all(x.dual() == x for x in L)
True
>>> all(x * y == y * x for x, y in Subsets(L, Integer(2)))  # long time
True
>>> Lsum = sum(L)
>>> gens = [P.s(i) for i in range(Integer(1),k-Integer(1)/Integer(2))]
>>> gens += [P.e(i/Integer(2)) for i in range(Integer(1),Integer(2)*k)]
>>> all(x * Lsum == Lsum * x for x in gens)
True
>>> all(P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.sigma(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2))
...     == (n - P.L((Integer(2)*i-Integer(1))/Integer(2))) * P.e((Integer(2)*i+Integer(1))/Integer(2)) for i in range(Integer(1),floor(k)))
True
>>> all(P.e(i/Integer(2)) * (P.L(i/Integer(2)) + P.L((i+Integer(1))/Integer(2)))
...     == (P.L(i/Integer(2)) + P.L((i+Integer(1))/Integer(2))) * P.e(i/Integer(2))
...     == n * P.e(i/Integer(2)) for i in range(Integer(1),Integer(2)*k))
True
>>> all(P.sigma(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i-Integer(1))/Integer(2)) * P.e(Integer(2)*i/Integer(2))
...     == P.L(Integer(2)*i/Integer(2)) * P.e(Integer(2)*i/Integer(2)) for i in range(Integer(1),ceil(k)))
True
>>> all(P.e(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i-Integer(1))/Integer(2)) * P.sigma(Integer(2)*i/Integer(2))
...     == P.e(Integer(2)*i/Integer(2)) * P.L(Integer(2)*i/Integer(2)) for i in range(Integer(1),ceil(k)))
True
>>> all(P.sigma((Integer(2)*i+Integer(1))/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.e(Integer(2)*i/Integer(2))
...     == P.L(Integer(2)*i/Integer(2)) * P.e(Integer(2)*i/Integer(2)) for i in range(Integer(1),floor(k)))
True
>>> all(P.e(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.sigma((Integer(2)*i+Integer(1))/Integer(2))
...     == P.e(Integer(2)*i/Integer(2)) * P.L(Integer(2)*i/Integer(2)) for i in range(Integer(1),floor(k)))
True
a(i)[source]

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 – 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
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.a(Integer(1))
P{{-3, 3}, {-2, -1}, {1, 2}}
>>> P3.a(Integer(2))
P{{-3, -2}, {-1, 1}, {2, 3}}

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

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 – 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}}]
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.e(Integer(1))
P{{-3, 3}, {-2, -1, 1, 2}}
>>> P3.e(Integer(2))
P{{-3, -2, 2, 3}, {-1, 1}}
>>> P3.e(Integer(1)/Integer(2))
P{{-3, 3}, {-2, 2}, {-1}, {1}}
>>> P3.e(Integer(5)/Integer(2))
P{{-3}, {-2, 2}, {-1, 1}, {3}}
>>> P3.e(Integer(0))
Traceback (most recent call last):
...
ValueError: i must be an (half) integer between 1/2 and 5/2
>>> P3.e(Integer(3))
Traceback (most recent call last):
...
ValueError: i must be an (half) integer between 1/2 and 5/2

>>> P2h = PartitionAlgebra(Integer(5)/Integer(2),n)
>>> [P2h.e(k/Integer(2)) for k in range(Integer(1),Integer(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)[source]

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 – 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
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.a(Integer(1))
P{{-3, 3}, {-2, -1}, {1, 2}}
>>> P3.a(Integer(2))
P{{-3, -2}, {-1, 1}, {2, 3}}

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

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 – 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}}]
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.e(Integer(1))
P{{-3, 3}, {-2, -1, 1, 2}}
>>> P3.e(Integer(2))
P{{-3, -2, 2, 3}, {-1, 1}}
>>> P3.e(Integer(1)/Integer(2))
P{{-3, 3}, {-2, 2}, {-1}, {1}}
>>> P3.e(Integer(5)/Integer(2))
P{{-3}, {-2, 2}, {-1, 1}, {3}}
>>> P3.e(Integer(0))
Traceback (most recent call last):
...
ValueError: i must be an (half) integer between 1/2 and 5/2
>>> P3.e(Integer(3))
Traceback (most recent call last):
...
ValueError: i must be an (half) integer between 1/2 and 5/2

>>> P2h = PartitionAlgebra(Integer(5)/Integer(2),n)
>>> [P2h.e(k/Integer(2)) for k in range(Integer(1),Integer(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)[source]

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 – 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}}
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.s(Integer(1))
P{{-3, 3}, {-2, 1}, {-1, 2}}
>>> P3.s(Integer(2))
P{{-3, 2}, {-2, 3}, {-1, 1}}

>>> R = ZZ['n']; (n,) = R._first_ngens(1)
>>> P2h = PartitionAlgebra(Integer(5)/Integer(2),n)
>>> P2h.s(Integer(1))
P{{-3, 3}, {-2, 1}, {-1, 2}}
jucys_murphy_element(i)[source]

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

INPUT:

  • i – 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
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.jucys_murphy_element(Integer(1)/Integer(2))
0
>>> P3.jucys_murphy_element(Integer(1))
P{{-3, 3}, {-2, 2}, {-1}, {1}}
>>> P3.jucys_murphy_element(Integer(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}}
>>> P3.jucys_murphy_element(Integer(3)/Integer(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}}
>>> P3.L(Integer(3)/Integer(2)) * P3.L(Integer(2)) == P3.L(Integer(2)) * P3.L(Integer(3)/Integer(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, y in Subsets(L, 2))  # 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
>>> from sage.all import *
>>> k = Integer(4)
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P = PartitionAlgebra(k, n)
>>> L = [P.L(i/Integer(2)) for i in range(Integer(1),Integer(2)*k+Integer(1))]
>>> all(x.dual() == x for x in L)
True
>>> all(x * y == y * x for x, y in Subsets(L, Integer(2)))  # long time
True
>>> Lsum = sum(L)
>>> gens = [P.s(i) for i in range(Integer(1),k)]
>>> gens += [P.e(i/Integer(2)) for i in range(Integer(1),Integer(2)*k)]
>>> 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
>>> from sage.all import *
>>> all(P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.sigma(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2))
...     == (n - P.L((Integer(2)*i-Integer(1))/Integer(2))) * P.e((Integer(2)*i+Integer(1))/Integer(2)) for i in range(Integer(1),k))
True
>>> all(P.e(i/Integer(2)) * (P.L(i/Integer(2)) + P.L((i+Integer(1))/Integer(2)))
...     == (P.L(i/Integer(2)) + P.L((i+Integer(1))/Integer(2))) * P.e(i/Integer(2))
...     == n * P.e(i/Integer(2)) for i in range(Integer(1),Integer(2)*k))
True
>>> all(P.sigma(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i-Integer(1))/Integer(2)) * P.e(Integer(2)*i/Integer(2))
...     == P.L(Integer(2)*i/Integer(2)) * P.e(Integer(2)*i/Integer(2)) for i in range(Integer(1),k))
True
>>> all(P.e(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i-Integer(1))/Integer(2)) * P.sigma(Integer(2)*i/Integer(2))
...     == P.e(Integer(2)*i/Integer(2)) * P.L(Integer(2)*i/Integer(2)) for i in range(Integer(1),k))
True
>>> all(P.sigma((Integer(2)*i+Integer(1))/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.e(Integer(2)*i/Integer(2))
...     == P.L(Integer(2)*i/Integer(2)) * P.e(Integer(2)*i/Integer(2)) for i in range(Integer(1),k))
True
>>> all(P.e(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.sigma((Integer(2)*i+Integer(1))/Integer(2))
...     == P.e(Integer(2)*i/Integer(2)) * P.L(Integer(2)*i/Integer(2)) for i in range(Integer(1),k))
True

The same tests for a half integer partition algebra:

sage: k = 7/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, y in Subsets(L, 2))  # 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
>>> from sage.all import *
>>> k = Integer(7)/Integer(2)
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P = PartitionAlgebra(k, n)
>>> L = [P.L(i/Integer(2)) for i in range(Integer(1),Integer(2)*k+Integer(1))]
>>> all(x.dual() == x for x in L)
True
>>> all(x * y == y * x for x, y in Subsets(L, Integer(2)))  # long time
True
>>> Lsum = sum(L)
>>> gens = [P.s(i) for i in range(Integer(1),k-Integer(1)/Integer(2))]
>>> gens += [P.e(i/Integer(2)) for i in range(Integer(1),Integer(2)*k)]
>>> all(x * Lsum == Lsum * x for x in gens)
True
>>> all(P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.sigma(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2))
...     == (n - P.L((Integer(2)*i-Integer(1))/Integer(2))) * P.e((Integer(2)*i+Integer(1))/Integer(2)) for i in range(Integer(1),floor(k)))
True
>>> all(P.e(i/Integer(2)) * (P.L(i/Integer(2)) + P.L((i+Integer(1))/Integer(2)))
...     == (P.L(i/Integer(2)) + P.L((i+Integer(1))/Integer(2))) * P.e(i/Integer(2))
...     == n * P.e(i/Integer(2)) for i in range(Integer(1),Integer(2)*k))
True
>>> all(P.sigma(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i-Integer(1))/Integer(2)) * P.e(Integer(2)*i/Integer(2))
...     == P.L(Integer(2)*i/Integer(2)) * P.e(Integer(2)*i/Integer(2)) for i in range(Integer(1),ceil(k)))
True
>>> all(P.e(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i-Integer(1))/Integer(2)) * P.sigma(Integer(2)*i/Integer(2))
...     == P.e(Integer(2)*i/Integer(2)) * P.L(Integer(2)*i/Integer(2)) for i in range(Integer(1),ceil(k)))
True
>>> all(P.sigma((Integer(2)*i+Integer(1))/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.e(Integer(2)*i/Integer(2))
...     == P.L(Integer(2)*i/Integer(2)) * P.e(Integer(2)*i/Integer(2)) for i in range(Integer(1),floor(k)))
True
>>> all(P.e(Integer(2)*i/Integer(2)) * P.e((Integer(2)*i+Integer(1))/Integer(2)) * P.sigma((Integer(2)*i+Integer(1))/Integer(2))
...     == P.e(Integer(2)*i/Integer(2)) * P.L(Integer(2)*i/Integer(2)) for i in range(Integer(1),floor(k)))
True
orbit_basis()[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P2 = PartitionAlgebra(Integer(2), x, R)
>>> 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
>>> pp = Integer(7) * P2[{-Integer(1)}, {-Integer(2), Integer(1), Integer(2)}] - Integer(2) * P2[{-Integer(2)}, {-Integer(1), Integer(1)}, {Integer(2)}]; pp
-2*P{{-2}, {-1, 1}, {2}} + 7*P{{-2, 1, 2}, {-1}}
>>> 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}}
>>> op == O2(op)
True
>>> 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}}
potts_representation(y=None)[source]

Return the PottsRepresentation with magnetic field direction y of self.

Note

The deformation parameter \(d\) of self must be a positive integer.

INPUT:

  • y – (optional) an integer between 1 and \(d\); ignored if the order of self is an integer, otherwise the default is \(1\)

EXAMPLES:

sage: PA = algebras.Partition(5/2, QQ(4))
sage: PR = PA.potts_representation()

sage: PA = algebras.Partition(5/2, 3/2)
sage: PA.potts_representation()
Traceback (most recent call last):
...
ValueError: the partition algebra deformation parameter must
 be a positive integer
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(5)/Integer(2), QQ(Integer(4)))
>>> PR = PA.potts_representation()

>>> PA = algebras.Partition(Integer(5)/Integer(2), Integer(3)/Integer(2))
>>> PA.potts_representation()
Traceback (most recent call last):
...
ValueError: the partition algebra deformation parameter must
 be a positive integer
s(i)[source]

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 – 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}}
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.s(Integer(1))
P{{-3, 3}, {-2, 1}, {-1, 2}}
>>> P3.s(Integer(2))
P{{-3, 2}, {-2, 3}, {-1, 1}}

>>> R = ZZ['n']; (n,) = R._first_ngens(1)
>>> P2h = PartitionAlgebra(Integer(5)/Integer(2),n)
>>> P2h.s(Integer(1))
P{{-3, 3}, {-2, 1}, {-1, 2}}
sigma(i)[source]

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

INPUT:

  • i – 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}}
>>> from sage.all import *
>>> R = QQ['n']; (n,) = R._first_ngens(1)
>>> P3 = PartitionAlgebra(Integer(3), n)
>>> P3.sigma(Integer(1))
P{{-3, 3}, {-2, 2}, {-1, 1}}
>>> P3.sigma(Integer(3)/Integer(2))
P{{-3, 3}, {-2, 1}, {-1, 2}}
>>> P3.sigma(Integer(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}}
>>> P3.sigma(Integer(5)/Integer(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
>>> from sage.all import *
>>> k = Integer(4)
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P = PartitionAlgebra(k, x)
>>> all(P.sigma(i/Integer(2)).dual() == P.sigma(i/Integer(2))
...     for i in range(Integer(1),Integer(2)*k))
True
>>> all(P.sigma(i)*P.sigma(i+Integer(1)/Integer(2)) == P.sigma(i+Integer(1)/Integer(2))*P.sigma(i) == P.s(i)
...     for i in range(Integer(1),floor(k)))
True
>>> all(P.sigma(i)*P.e(i) == P.e(i)*P.sigma(i) == P.e(i)
...     for i in range(Integer(1),floor(k)))
True
>>> all(P.sigma(i+Integer(1)/Integer(2))*P.e(i) == P.e(i)*P.sigma(i+Integer(1)/Integer(2)) == P.e(i)
...     for i in range(Integer(1),floor(k)))
True

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

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
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import PartitionDiagram, PartitionDiagrams
>>> PartitionDiagrams(Integer(1))
Partition diagrams of order 1
>>> PartitionDiagrams(Integer(1)).list()
[{{-1, 1}}, {{-1}, {1}}]
>>> PartitionDiagram([[Integer(1),-Integer(1)]])
{{-1, 1}}
>>> PartitionDiagram(((Integer(1),-Integer(2)),(Integer(2),-Integer(1)))).parent()
Partition diagrams of order 2
class sage.combinat.diagram_algebras.PartitionDiagrams(order, category=None)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.PartitionDiagrams(Integer(1)); pd
Partition diagrams of order 1
>>> pd.list()
[{{-1, 1}}, {{-1}, {1}}]

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

alias of PartitionDiagram

cardinality()[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pd = da.PartitionDiagrams(Integer(3))
>>> pd.cardinality()
203

>>> pd = da.PartitionDiagrams(Integer(7)/Integer(2))
>>> pd.cardinality()
877
class sage.combinat.diagram_algebras.PlanarAlgebra(k, q, base_ring, prefix)[source]

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\)

  • 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
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> Pl = PlanarAlgebra(Integer(2), x, R); Pl
Planar Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring
>>> Pl.basis().keys()
Planar diagrams of order 2
>>> Pl.basis().keys()([[-Integer(1), Integer(1)], [Integer(2), -Integer(2)]])
{{-2, 2}, {-1, 1}}
>>> 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}}]
>>> E = Pl([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
>>> E**Integer(2) == x*E
True
>>> E**Integer(5) == x**Integer(4)*E
True
class sage.combinat.diagram_algebras.PlanarDiagram(parent, d, check=True)[source]

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}}]
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import PlanarDiagrams
>>> PlanarDiagrams(Integer(2))
Planar diagrams of order 2
>>> PlanarDiagrams(Integer(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()[source]

Check the validity of the input for self.

class sage.combinat.diagram_algebras.PlanarDiagrams(order, category=None)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pld = da.PlanarDiagrams(Integer(1)); pld
Planar diagrams of order 1
>>> pld.list()
[{{-1, 1}}, {{-1}, {1}}]

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

alias of PlanarDiagram

cardinality()[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> pld = da.PlanarDiagrams(Integer(3))
>>> pld.cardinality()
132
class sage.combinat.diagram_algebras.PottsRepresentation(PA, y)[source]

Bases: CombinatorialFreeModule

The Potts representation of the partition algebra.

Let \(P_n(d)\) be the PartitionAlgebra over \(R\) with the deformation parameter \(d \in \ZZ_{>0}\) being a positive integer. Recall the multiplication convention of diagrams in \(P_n(d)\) computing \(D D'\) by placing \(D\) above \(D'\).

The Potts representation is the right \(P_n(d)\)-module on \(M = V^{\otimes n}\), with \(V = R^d\), with the action given as follows. We identify the natural basis vectors in \(M\) with words of length \(n\) in the alphabet \(\{1, \dotsc, d\}\) (which we call colors). For a basis vector \(w\) and diagram \(D\), define \(w \cdot D\) as the sum over all \(v\) such that every part in \(w D v\) (consider this as coloring the nodes of \(D\)) is given by the same color.

If \(n\) is a half integer, then there is an extra fixed color for the node \(\lceil n \rceil\), which is called the magnetic field direction from the physics interpretation of this representation.

EXAMPLES:

In this example, we consider \(R = \QQ\) and use the Potts representation to construct the centralizer algebra of the left \(S_{d-1}\)-action on \(V^{\otimes n}\) with \(V = \QQ^d\) being the permutation action.

sage: PA = algebras.Partition(5/2, QQ(2))
sage: PR = PA.potts_representation(2)
sage: mats = [PR.representation_matrix(x) for x in PA.basis()]
sage: MS = mats[0].parent()
sage: CM = MS.submodule(mats)
sage: CM.dimension()
16
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(5)/Integer(2), QQ(Integer(2)))
>>> PR = PA.potts_representation(Integer(2))
>>> mats = [PR.representation_matrix(x) for x in PA.basis()]
>>> MS = mats[Integer(0)].parent()
>>> CM = MS.submodule(mats)
>>> CM.dimension()
16

We check that this commutes with the \(S_{d-1}\)-action:

sage: all((g * v) * x == g * (v * x) for g in PR.symmetric_group()
....:     for v in PR.basis() for x in PA.basis())
True
>>> from sage.all import *
>>> all((g * v) * x == g * (v * x) for g in PR.symmetric_group()
...     for v in PR.basis() for x in PA.basis())
True

Next, we see that the centralizer of the \(S_d\)-action is smaller than the semisimple quotient of the partition algebra:

sage: PA.dimension()
52
sage: len(PA.radical_basis())
9
sage: SQ = PA.semisimple_quotient()
sage: SQ.dimension()
43
>>> from sage.all import *
>>> PA.dimension()
52
>>> len(PA.radical_basis())
9
>>> SQ = PA.semisimple_quotient()
>>> SQ.dimension()
43

Next, we get orthogonal idempotents that project onto the central orthogonal idempotents in the semisimple quotient and construct the corresponding Peirce summands \(e_i P_n(d) e_i\):

sage: # long time
sage: orth_idems = PA.orthogonal_idempotents_central_mod_radical()
sage: algs = [PA.peirce_summand(idm, idm) for idm in orth_idems]
sage: [A.dimension() for A in algs]
[16, 2, 1, 25]
>>> from sage.all import *
>>> # long time
>>> orth_idems = PA.orthogonal_idempotents_central_mod_radical()
>>> algs = [PA.peirce_summand(idm, idm) for idm in orth_idems]
>>> [A.dimension() for A in algs]
[16, 2, 1, 25]

We saw that we obtain the entire endomorphism algebra since \(d = 2\) and \(S_{d-1}\) is the trivial group. Hence, the 16 dimensional Peirce summand computed above is isomorphic to this endomorphism algebra (both are \(4 \times 4\) matrix algebras over \(\QQ\)). Hence, we have a natural quotient construction of the centralizer algebra from the partition algebra.

Next, we consider a case with a nontrivial \(S_d\)-action (now it is \(S_d\) since the partition algebra has integer rank). We perform the same computations as before:

sage: PA = algebras.Partition(2, QQ(2))
sage: PA.dimension()
15
sage: PA.semisimple_quotient().dimension()
10
sage: orth_idems = PA.orthogonal_idempotents_central_mod_radical()
sage: algs = [PA.peirce_summand(idm, idm) for idm in orth_idems]
sage: [A.dimension() for A in algs]
[4, 2, 4, 1]

sage: PR = PA.potts_representation()
sage: mats = [PR.representation_matrix(x) for x in PA.basis()]
sage: MS = mats[0].parent()
sage: cat = Algebras(QQ).WithBasis().Subobjects()
sage: CM = MS.submodule(mats, category=cat)
sage: CM.dimension()
8
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(2), QQ(Integer(2)))
>>> PA.dimension()
15
>>> PA.semisimple_quotient().dimension()
10
>>> orth_idems = PA.orthogonal_idempotents_central_mod_radical()
>>> algs = [PA.peirce_summand(idm, idm) for idm in orth_idems]
>>> [A.dimension() for A in algs]
[4, 2, 4, 1]

>>> PR = PA.potts_representation()
>>> mats = [PR.representation_matrix(x) for x in PA.basis()]
>>> MS = mats[Integer(0)].parent()
>>> cat = Algebras(QQ).WithBasis().Subobjects()
>>> CM = MS.submodule(mats, category=cat)
>>> CM.dimension()
8

To do the remainder of the computation, we need to monkey patch a product_on_basis method:

sage: CM.product_on_basis
NotImplemented
sage: CM.product_on_basis = lambda x,y: CM.retract(CM.basis()[x].lift() * CM.basis()[y].lift())
sage: CM.orthogonal_idempotents_central_mod_radical()
(1/2*B[0] + 1/2*B[3] + 1/2*B[5] + 1/2*B[6],
 1/2*B[0] - 1/2*B[3] + 1/2*B[5] - 1/2*B[6])
sage: CM.peirce_decomposition()
[[Free module generated by {0, 1, 2, 3} over Rational Field,
  Free module generated by {} over Rational Field],
 [Free module generated by {} over Rational Field,
  Free module generated by {0, 1, 2, 3} over Rational Field]]
>>> from sage.all import *
>>> CM.product_on_basis
NotImplemented
>>> CM.product_on_basis = lambda x,y: CM.retract(CM.basis()[x].lift() * CM.basis()[y].lift())
>>> CM.orthogonal_idempotents_central_mod_radical()
(1/2*B[0] + 1/2*B[3] + 1/2*B[5] + 1/2*B[6],
 1/2*B[0] - 1/2*B[3] + 1/2*B[5] - 1/2*B[6])
>>> CM.peirce_decomposition()
[[Free module generated by {0, 1, 2, 3} over Rational Field,
  Free module generated by {} over Rational Field],
 [Free module generated by {} over Rational Field,
  Free module generated by {0, 1, 2, 3} over Rational Field]]

Hence, we see that the centralizer algebra is isomorphic to a product of two \(2 \times 2\) matrix algebras (over \(\QQ\)), which are naturally a part of the partition algebra decomposition.

Lastly, we verify the commuting actions:

sage: all((g * v) * x == g * (v * x) for g in PR.symmetric_group()
....:     for v in PR.basis() for x in PA.basis())
True
>>> from sage.all import *
>>> all((g * v) * x == g * (v * x) for g in PR.symmetric_group()
...     for v in PR.basis() for x in PA.basis())
True

REFERENCES:

class Element[source]

Bases: IndexedFreeModuleElement

magnetic_field_direction()[source]

Return the magnetic field direction defining self.

EXAMPLES:

sage: PA = algebras.Partition(7/2, QQ(4))
sage: PR = PA.potts_representation(2)
sage: PR.magnetic_field_direction()
2
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(7)/Integer(2), QQ(Integer(4)))
>>> PR = PA.potts_representation(Integer(2))
>>> PR.magnetic_field_direction()
2
number_of_colors()[source]

Return the number of colors defining self.

EXAMPLES:

sage: PA = algebras.Partition(3, QQ(4))
sage: PR = PA.potts_representation()
sage: PR.number_of_colors()
4
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(3), QQ(Integer(4)))
>>> PR = PA.potts_representation()
>>> PR.number_of_colors()
4
number_of_factors()[source]

Return the number of factors defining self.

EXAMPLES:

sage: PA = algebras.Partition(7/2, QQ(4))
sage: PR = PA.potts_representation()
sage: PR.number_of_factors()
3
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(7)/Integer(2), QQ(Integer(4)))
>>> PR = PA.potts_representation()
>>> PR.number_of_factors()
3
partition_algebra()[source]

Return the partition algebra that self is a representation of.

EXAMPLES:

sage: PA = algebras.Partition(3, QQ(4))
sage: PR = PA.potts_representation()
sage: PR.partition_algebra() is PA
True
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(3), QQ(Integer(4)))
>>> PR = PA.potts_representation()
>>> PR.partition_algebra() is PA
True
representation_matrix(elt)[source]

Return the representation matrix of self in self.

EXAMPLES:

sage: PA = algebras.Partition(7/2, QQ(2))
sage: PR = PA.potts_representation()
sage: PR.representation_matrix(PA.an_element())
[7 0 3 0 2 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]

sage: all(b.to_vector() * PR.representation_matrix(x)  # long time
....:     == (b * x).to_vector()
....:     for b in PR.basis() for x in PA.basis())
True

sage: PA = algebras.Partition(2, QQ(2))
sage: PR = PA.potts_representation()
sage: [PR.representation_matrix(x) for x in PA.basis()]
[
[1 0 0 0]  [1 0 1 0]  [1 1 0 0]  [1 0 0 1]  [1 1 1 1]  [1 0 0 0]
[0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [1 0 0 0]
[0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 1]
[0 0 0 1], [0 1 0 1], [0 0 1 1], [1 0 0 1], [1 1 1 1], [0 0 0 1],

[1 0 0 0]  [1 0 1 0]  [1 0 0 0]  [1 0 0 0]  [1 0 1 0]  [1 1 0 0]
[0 0 1 0]  [1 0 1 0]  [0 1 0 0]  [0 0 0 1]  [0 1 0 1]  [1 1 0 0]
[0 1 0 0]  [0 1 0 1]  [0 0 1 0]  [1 0 0 0]  [1 0 1 0]  [0 0 1 1]
[0 0 0 1], [0 1 0 1], [0 0 0 1], [0 0 0 1], [0 1 0 1], [0 0 1 1],

[1 1 0 0]  [1 0 0 1]  [1 1 1 1]
[0 0 1 1]  [1 0 0 1]  [1 1 1 1]
[1 1 0 0]  [1 0 0 1]  [1 1 1 1]
[0 0 1 1], [1 0 0 1], [1 1 1 1]
]

sage: PA = algebras.Partition(5/2, QQ(2))
sage: PR = PA.potts_representation()
sage: all(PR.representation_matrix(x) * PR.representation_matrix(y)  # long time
....:     == PR.representation_matrix(x * y)
....:     for x in PA.basis() for y in PA.basis())
True

sage: PA = algebras.Partition(2, QQ(4))
sage: PR = PA.potts_representation()
sage: all(PR.representation_matrix(x) * PR.representation_matrix(y)
....:     == PR.representation_matrix(x * y)
....:     for x in PA.basis() for y in PA.basis())
True
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(7)/Integer(2), QQ(Integer(2)))
>>> PR = PA.potts_representation()
>>> PR.representation_matrix(PA.an_element())
[7 0 3 0 2 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]

>>> all(b.to_vector() * PR.representation_matrix(x)  # long time
...     == (b * x).to_vector()
...     for b in PR.basis() for x in PA.basis())
True

>>> PA = algebras.Partition(Integer(2), QQ(Integer(2)))
>>> PR = PA.potts_representation()
>>> [PR.representation_matrix(x) for x in PA.basis()]
[
[1 0 0 0]  [1 0 1 0]  [1 1 0 0]  [1 0 0 1]  [1 1 1 1]  [1 0 0 0]
[0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [1 0 0 0]
[0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 0]  [0 0 0 1]
[0 0 0 1], [0 1 0 1], [0 0 1 1], [1 0 0 1], [1 1 1 1], [0 0 0 1],
<BLANKLINE>
[1 0 0 0]  [1 0 1 0]  [1 0 0 0]  [1 0 0 0]  [1 0 1 0]  [1 1 0 0]
[0 0 1 0]  [1 0 1 0]  [0 1 0 0]  [0 0 0 1]  [0 1 0 1]  [1 1 0 0]
[0 1 0 0]  [0 1 0 1]  [0 0 1 0]  [1 0 0 0]  [1 0 1 0]  [0 0 1 1]
[0 0 0 1], [0 1 0 1], [0 0 0 1], [0 0 0 1], [0 1 0 1], [0 0 1 1],
<BLANKLINE>
[1 1 0 0]  [1 0 0 1]  [1 1 1 1]
[0 0 1 1]  [1 0 0 1]  [1 1 1 1]
[1 1 0 0]  [1 0 0 1]  [1 1 1 1]
[0 0 1 1], [1 0 0 1], [1 1 1 1]
]

>>> PA = algebras.Partition(Integer(5)/Integer(2), QQ(Integer(2)))
>>> PR = PA.potts_representation()
>>> all(PR.representation_matrix(x) * PR.representation_matrix(y)  # long time
...     == PR.representation_matrix(x * y)
...     for x in PA.basis() for y in PA.basis())
True

>>> PA = algebras.Partition(Integer(2), QQ(Integer(4)))
>>> PR = PA.potts_representation()
>>> all(PR.representation_matrix(x) * PR.representation_matrix(y)
...     == PR.representation_matrix(x * y)
...     for x in PA.basis() for y in PA.basis())
True
symmetric_group()[source]

Return the symmetric group that naturally acts on self.

EXAMPLES:

sage: PA = algebras.Partition(3, QQ(4))
sage: PR = PA.potts_representation()
sage: PR.symmetric_group()
Symmetric group of order 4! as a permutation group

sage: PA = algebras.Partition(7/2, QQ(4))
sage: PR = PA.potts_representation()
sage: PR.symmetric_group().domain()
{2, 3, 4}
sage: PR = PA.potts_representation(2)
sage: PR.symmetric_group().domain()
{1, 3, 4}
sage: PR = PA.potts_representation(4)
sage: PR.symmetric_group().domain()
{1, 2, 3}
>>> from sage.all import *
>>> PA = algebras.Partition(Integer(3), QQ(Integer(4)))
>>> PR = PA.potts_representation()
>>> PR.symmetric_group()
Symmetric group of order 4! as a permutation group

>>> PA = algebras.Partition(Integer(7)/Integer(2), QQ(Integer(4)))
>>> PR = PA.potts_representation()
>>> PR.symmetric_group().domain()
{2, 3, 4}
>>> PR = PA.potts_representation(Integer(2))
>>> PR.symmetric_group().domain()
{1, 3, 4}
>>> PR = PA.potts_representation(Integer(4))
>>> PR.symmetric_group().domain()
{1, 2, 3}
class sage.combinat.diagram_algebras.PropagatingIdeal(k, q, base_ring, prefix)[source]

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
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> I = PropagatingIdeal(Integer(2), x, R); I
Propagating Ideal of rank 2 with parameter x
 over Univariate Polynomial Ring in x over Rational Field
>>> I.basis().keys()
Ideal diagrams of order 2
>>> 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}}]
>>> E = I([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
>>> E**Integer(2) == x*E
True
>>> E**Integer(5) == x**Integer(4)*E
True
class Element[source]

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)[source]

Bases: DiagramBasis

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

class Element[source]

Bases: Element

to_orbit_basis()[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> B = BrauerAlgebra(Integer(2), x, R)
>>> bb = B([[-Integer(2), -Integer(1)], [Integer(1), Integer(2)]]); bb
B{{-2, -1}, {1, 2}}
>>> bb.to_orbit_basis()
O{{-2, -1}, {1, 2}} + O{{-2, -1, 1, 2}}
ambient()[source]

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

EXAMPLES:

sage: x = var('x')                                                          # needs sage.symbolic
sage: BA = BrauerAlgebra(2, x)                                              # needs sage.symbolic
sage: BA.ambient()                                                          # needs sage.symbolic
Partition Algebra of rank 2 with parameter x over Symbolic Ring
>>> from sage.all import *
>>> x = var('x')                                                          # needs sage.symbolic
>>> BA = BrauerAlgebra(Integer(2), x)                                              # needs sage.symbolic
>>> BA.ambient()                                                          # needs sage.symbolic
Partition Algebra of rank 2 with parameter x over Symbolic Ring
lift()[source]

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
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> BA = BrauerAlgebra(Integer(2), x, R)
>>> E = BA([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
>>> lifted = BA.lift(E); lifted
B{{-2, -1}, {1, 2}}
>>> lifted.parent() is BA.ambient()
True
retract(x)[source]

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
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> BA = BrauerAlgebra(Integer(2), x, R)
>>> PA = BA.ambient()
>>> E = PA([[Integer(1),Integer(2)], [-Integer(1),-Integer(2)]])
>>> BA.retract(E) in BA
True
sage.combinat.diagram_algebras.TL_diagram_ascii_art(diagram, use_unicode=False, blobs=[])[source]

Return ascii art for a Temperley-Lieb diagram diagram.

INPUT:

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

  • use_unicode – boolean (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)])
 ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬
 │ ╰─╯ ╰─╯ │ │ │ ╰─╯ │ ╰─╯ │ │ │ │ ╰─╯ │
 │         │ │ │     ╰─────╯ │ │ ╰─────╯
 │         │ │ ╰─────────────╯ │
 ╰───●───╮ │ │ ╭───────────────╯
         │ │ │ │ ╭─────────────────────╮
         │ │ │ │ │ ╭─────────────────╮ │
         │ │ │ │ │ │ ╭─────────────╮ │ │
         │ │ │ │ │ │ │ ╭─────╮     │ │ │
 ╭●╮ ╭─╮ │ │ │ │ │ │ │ │ ╭─╮ │ ╭─╮ │ │ │
 ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import TL_diagram_ascii_art
>>> TL = [(-Integer(15),-Integer(12)), (-Integer(14),-Integer(13)), (-Integer(11),Integer(15)), (-Integer(10),Integer(14)), (-Integer(9),-Integer(6)),
...       (-Integer(8),-Integer(7)), (-Integer(5),-Integer(4)), (-Integer(3),Integer(1)), (-Integer(2),-Integer(1)), (Integer(2),Integer(3)), (Integer(4),Integer(5)),
...       (Integer(6),Integer(11)), (Integer(7), Integer(8)), (Integer(9),Integer(10)), (Integer(12),Integer(13))]
>>> 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
>>> TL_diagram_ascii_art(TL, use_unicode=True)
 ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬
 │ ╰─╯ ╰─╯ │ ╰─╯ ╰─╯ │ ╰─╯ │ │
 │         ╰─────────╯     │ │
 │                 ╭───────╯ │
 ╰───╮             │ ╭───────╯
     │     ╭─────╮ │ │ ╭─────╮
 ╭─╮ │ ╭─╮ │ ╭─╮ │ │ │ │ ╭─╮ │
 ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬ ⚬

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

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\)

  • 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
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> T = TemperleyLiebAlgebra(Integer(2), x, R); T
Temperley-Lieb Algebra of rank 2 with parameter x
 over Univariate Polynomial Ring in x over Integer Ring
>>> 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}
>>> T.basis().keys()
Temperley Lieb diagrams of order 2
>>> T.basis().keys()([[-Integer(1), Integer(1)], [Integer(2), -Integer(2)]])
{{-2, 2}, {-1, 1}}
>>> b = T.basis().list(); b
[T{{-2, -1}, {1, 2}}, T{{-2, 2}, {-1, 1}}]
>>> b[Integer(0)]
T{{-2, -1}, {1, 2}}
>>> b[Integer(0)]**Integer(2) == x*b[Integer(0)]
True
>>> b[Integer(0)]**Integer(5) == x**Integer(4)*b[Integer(0)]
True

The Temperley-Lieb algebra is a cellular algebra, and we verify that the dimensions of the simple modules at \(q = 0\) is given by OEIS sequence A050166:

sage: for k in range(1,5):
....:     TL = TemperleyLiebAlgebra(2*k, 0, QQ)
....:     print("".join("{:3}".format(TL.cell_module(la).simple_module().dimension())
....:                   for la in reversed(TL.cell_poset()) if la != 0))
  1
  1  2
  1  4  5
  1  6 14 14
sage: for k in range(1,4):
....:     TL = TemperleyLiebAlgebra(2*k+1, 0, QQ)
....:     print("".join("{:3}".format(TL.cell_module(la).simple_module().dimension())
....:                   for la in reversed(TL.cell_poset()) if la != 0))
  1  2
  1  4  5
  1  6 14 14
>>> from sage.all import *
>>> for k in range(Integer(1),Integer(5)):
...     TL = TemperleyLiebAlgebra(Integer(2)*k, Integer(0), QQ)
...     print("".join("{:3}".format(TL.cell_module(la).simple_module().dimension())
...                   for la in reversed(TL.cell_poset()) if la != Integer(0)))
  1
  1  2
  1  4  5
  1  6 14 14
>>> for k in range(Integer(1),Integer(4)):
...     TL = TemperleyLiebAlgebra(Integer(2)*k+Integer(1), Integer(0), QQ)
...     print("".join("{:3}".format(TL.cell_module(la).simple_module().dimension())
...                   for la in reversed(TL.cell_poset()) if la != Integer(0)))
  1  2
  1  4  5
  1  6 14 14

Additional examples when the Temperley-Lieb algebra is not semisimple:

sage: TL = TemperleyLiebAlgebra(8, -1, QQ)
sage: for la in TL.cell_poset():
....:     CM = TL.cell_module(la)
....:     if not CM.nonzero_bilinear_form():
....:         continue
....:     print(la, CM.dimension(), CM.simple_module().dimension())
....:
0 14 1
2 28 28
4 20 13
6 7 7
8 1 1
sage: for k in range(1,5):
....:     TL = TemperleyLiebAlgebra(2*k, -1, QQ)
....:     print("".join("{:3}".format(TL.cell_module(la).simple_module().dimension())
....:                   for la in reversed(TL.cell_poset())
....:                    if TL.cell_module(la).nonzero_bilinear_form()))
  1  1
  1  3  1
  1  4  9  1
  1  7 13 28  1
sage: C5.<z5> = CyclotomicField(5)
sage: for k in range(1,5):
....:     TL = TemperleyLiebAlgebra(2*k, z5+~z5, C5)
....:     print("".join("{:3}".format(TL.cell_module(la).simple_module().dimension())
....:                   for la in reversed(TL.cell_poset())
....:                    if TL.cell_module(la).nonzero_bilinear_form()))
  1  1
  1  3  2
  1  5  8  5
  1  7 20 21 13
>>> from sage.all import *
>>> TL = TemperleyLiebAlgebra(Integer(8), -Integer(1), QQ)
>>> for la in TL.cell_poset():
...     CM = TL.cell_module(la)
...     if not CM.nonzero_bilinear_form():
...         continue
...     print(la, CM.dimension(), CM.simple_module().dimension())
....:
0 14 1
2 28 28
4 20 13
6 7 7
8 1 1
>>> for k in range(Integer(1),Integer(5)):
...     TL = TemperleyLiebAlgebra(Integer(2)*k, -Integer(1), QQ)
...     print("".join("{:3}".format(TL.cell_module(la).simple_module().dimension())
...                   for la in reversed(TL.cell_poset())
...                    if TL.cell_module(la).nonzero_bilinear_form()))
  1  1
  1  3  1
  1  4  9  1
  1  7 13 28  1
>>> C5 = CyclotomicField(Integer(5), names=('z5',)); (z5,) = C5._first_ngens(1)
>>> for k in range(Integer(1),Integer(5)):
...     TL = TemperleyLiebAlgebra(Integer(2)*k, z5+~z5, C5)
...     print("".join("{:3}".format(TL.cell_module(la).simple_module().dimension())
...                   for la in reversed(TL.cell_poset())
...                    if TL.cell_module(la).nonzero_bilinear_form()))
  1  1
  1  3  2
  1  5  8  5
  1  7 20 21 13
cell_module_indices(la)[source]

Return the indices of the cell module of self indexed by la .

This is the finite set \(M(\lambda)\).

EXAMPLES:

sage: R.<q> = QQ[]
sage: TL = TemperleyLiebAlgebra(8, q, R)
sage: TL.cell_module_indices(4)
Half Temperley-Lieb diagrams of order 8 with 4 defects
>>> from sage.all import *
>>> R = QQ['q']; (q,) = R._first_ngens(1)
>>> TL = TemperleyLiebAlgebra(Integer(8), q, R)
>>> TL.cell_module_indices(Integer(4))
Half Temperley-Lieb diagrams of order 8 with 4 defects
cell_poset()[source]

Return the cell poset of self.

EXAMPLES:

sage: R.<q> = QQ[]
sage: TL = TemperleyLiebAlgebra(7, q, R)
sage: TL.cell_poset().cover_relations()
[[1, 3], [3, 5], [5, 7]]

sage: TL = TemperleyLiebAlgebra(8, q, R)
sage: TL.cell_poset().cover_relations()
[[0, 2], [2, 4], [4, 6], [6, 8]]
>>> from sage.all import *
>>> R = QQ['q']; (q,) = R._first_ngens(1)
>>> TL = TemperleyLiebAlgebra(Integer(7), q, R)
>>> TL.cell_poset().cover_relations()
[[1, 3], [3, 5], [5, 7]]

>>> TL = TemperleyLiebAlgebra(Integer(8), q, R)
>>> TL.cell_poset().cover_relations()
[[0, 2], [2, 4], [4, 6], [6, 8]]
cellular_involution(x)[source]

Return the cellular involution of x in self.

EXAMPLES:

sage: TL = TemperleyLiebAlgebra(4, QQ.zero(), QQ)
sage: ascii_art(TL.an_element())
                o o o o       o o o o
   o o o o      | `-` |       | `-` |
2* `-` `-` + 2* `-----`  + 3* `---. |
   .-. .-.      .-. .-.       .-. | |
   o o o o      o o o o       o o o o
sage: ascii_art(TL.cellular_involution(TL.an_element()))
                o o o o       o o o o
   o o o o      `-` `-`       `-` | |
2* `-` `-` + 2* .-----.  + 3* .---` |
   .-. .-.      | .-. |       | .-. |
   o o o o      o o o o       o o o o
>>> from sage.all import *
>>> TL = TemperleyLiebAlgebra(Integer(4), QQ.zero(), QQ)
>>> ascii_art(TL.an_element())
                o o o o       o o o o
   o o o o      | `-` |       | `-` |
2* `-` `-` + 2* `-----`  + 3* `---. |
   .-. .-.      .-. .-.       .-. | |
   o o o o      o o o o       o o o o
>>> ascii_art(TL.cellular_involution(TL.an_element()))
                o o o o       o o o o
   o o o o      `-` `-`       `-` | |
2* `-` `-` + 2* .-----.  + 3* .---` |
   .-. .-.      | .-. |       | .-. |
   o o o o      o o o o       o o o o
class sage.combinat.diagram_algebras.TemperleyLiebDiagram(parent, d, check=True)[source]

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}}]
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import TemperleyLiebDiagrams
>>> TemperleyLiebDiagrams(Integer(2))
Temperley Lieb diagrams of order 2
>>> TemperleyLiebDiagrams(Integer(2)).list()
[{{-2, -1}, {1, 2}}, {{-2, 2}, {-1, 1}}]
check()[source]

Check the validity of the input for self.

class sage.combinat.diagram_algebras.TemperleyLiebDiagrams(order, category=None)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> td = da.TemperleyLiebDiagrams(Integer(3)); td
Temperley Lieb diagrams of order 3
>>> 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}}]

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

alias of TemperleyLiebDiagram

cardinality()[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> td = da.TemperleyLiebDiagrams(Integer(3))
>>> td.cardinality()
5
class sage.combinat.diagram_algebras.UnitDiagramMixin[source]

Bases: object

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

one_basis()[source]

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}}
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> P = PartitionAlgebra(Integer(2), x, R)
>>> P.one_basis()
{{-2, 2}, {-1, 1}}
sage.combinat.diagram_algebras.brauer_diagrams(k)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> [SetPartition(p) for p in da.brauer_diagrams(Integer(2))]
[{{-2, -1}, {1, 2}}, {{-2, 1}, {-1, 2}}, {{-2, 2}, {-1, 1}}]
>>> [SetPartition(p) for p in da.brauer_diagrams(Integer(5)/Integer(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)[source]

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}
>>> from sage.all import *
>>> from sage.combinat.diagram_algebras import PartitionDiagrams, diagram_latex
>>> P = PartitionDiagrams(Integer(2))
>>> D = P([[Integer(1),Integer(2)],[-Integer(2),-Integer(1)]])
>>> 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)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> all_diagrams = da.partition_diagrams(Integer(2))
>>> [SetPartition(p) for p in all_diagrams if p not in da.ideal_diagrams(Integer(2))]
[{{-2, 1}, {-1, 2}}, {{-2, 2}, {-1, 1}}]

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

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}}
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> SetPartition(da.identity_set_partition(Integer(2)))
{{-2, 2}, {-1, 1}}
sage.combinat.diagram_algebras.is_planar(sp)[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> da.is_planar( da.to_set_partition([[Integer(1),-Integer(2)],[Integer(2),-Integer(1)]]))
False
>>> da.is_planar( da.to_set_partition([[Integer(1),-Integer(1)],[Integer(2),-Integer(2)]]))
True
sage.combinat.diagram_algebras.pair_to_graph(sp1, sp2)[source]

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)]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> sp1 = da.to_set_partition([[Integer(1),-Integer(2)],[Integer(2),-Integer(1)]])
>>> sp2 = da.to_set_partition([[Integer(1),-Integer(2)],[Integer(2),-Integer(1)]])
>>> g = da.pair_to_graph( sp1, sp2 ); g
Graph on 8 vertices

>>> g.vertices(sort=True)
[(-2, 1), (-2, 2), (-1, 1), (-1, 2), (1, 1), (1, 2), (2, 1), (2, 2)]
>>> 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 Issue #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)]
>>> from sage.all import *
>>> sp3 = da.to_set_partition([[Integer(1), -Integer(1)], [Integer(2)], [-Integer(2)]])
>>> sp4 = da.to_set_partition([[Integer(1)], [-Integer(1)], [Integer(2)], [-Integer(2)]])
>>> g = da.pair_to_graph( sp3, sp4 ); g
Graph on 8 vertices

>>> g.vertices(sort=True)
[(-2, 1), (-2, 2), (-1, 1), (-1, 2), (1, 1), (1, 2), (2, 1), (2, 2)]
>>> 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)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> [SetPartition(p) for p in da.partition_diagrams(Integer(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}}]
>>> [SetPartition(p) for p in da.partition_diagrams(Integer(3)/Integer(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)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> all_diagrams = [SetPartition(p) for p in da.partition_diagrams(Integer(2))]
>>> da2 = [SetPartition(p) for p in da.planar_diagrams(Integer(2))]
>>> [p for p in all_diagrams if p not in da2]
[{{-2, 1}, {-1, 2}}]
>>> all_diagrams = [SetPartition(p) for p in da.partition_diagrams(Integer(5)/Integer(2))]
>>> da5o2 = [SetPartition(p) for p in da.planar_diagrams(Integer(5)/Integer(2))]
>>> [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)[source]

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],)]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> list(da.planar_partitions_rec([Integer(1),Integer(2),Integer(3)]))
[([1, 2], [3]), ([1], [2], [3]), ([2], [1, 3]), ([1], [2, 3]), ([1, 2, 3],)]
sage.combinat.diagram_algebras.propagating_number(sp)[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> sp1 = da.to_set_partition([[Integer(1),-Integer(2)],[Integer(2),-Integer(1)]])
>>> sp2 = da.to_set_partition([[Integer(1),Integer(2)],[-Integer(2),-Integer(1)]])
>>> da.propagating_number(sp1)
2
>>> da.propagating_number(sp2)
0
sage.combinat.diagram_algebras.temperley_lieb_diagrams(k)[source]

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}}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> [SetPartition(p) for p in da.temperley_lieb_diagrams(Integer(2))]
[{{-2, -1}, {1, 2}}, {{-2, 2}, {-1, 1}}]
>>> [SetPartition(p) for p in da.temperley_lieb_diagrams(Integer(5)/Integer(2))]
[{{-3, 3}, {-2, -1}, {1, 2}}, {{-3, 3}, {-2, 2}, {-1, 1}}]
sage.combinat.diagram_algebras.to_Brauer_partition(l, k=None)[source]

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
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> f = lambda sp: SetPartition(da.to_Brauer_partition(sp))
>>> f([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]]) == SetPartition([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]])
True
>>> f([[Integer(1),Integer(3)],[-Integer(1),-Integer(3)]]) == SetPartition([[Integer(1),Integer(3)],[-Integer(3),-Integer(1)],[Integer(2),-Integer(2)]])
True
>>> f([[Integer(1),-Integer(4)],[-Integer(3),-Integer(1)],[Integer(3),Integer(4)]]) == SetPartition([[-Integer(3),-Integer(1)],[Integer(2),-Integer(2)],[Integer(1),-Integer(4)],[Integer(3),Integer(4)]])
True
>>> p = SetPartition([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)],[Integer(3),-Integer(3)],[Integer(4),-Integer(4)]])
>>> SetPartition(da.to_Brauer_partition([[Integer(1),Integer(2)],[-Integer(1),-Integer(2)]], k=Integer(4))) == p
True
sage.combinat.diagram_algebras.to_graph(sp)[source]

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)]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> g = da.to_graph( da.to_set_partition([[Integer(1),-Integer(2)],[Integer(2),-Integer(1)]])); g
Graph on 4 vertices

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

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 – list of lists of integers

  • k – integer (default: None)

OUTPUT: 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}]
>>> from sage.all import *
>>> import sage.combinat.diagram_algebras as da
>>> f = lambda sp: SetPartition(da.to_set_partition(sp))
>>> f([[Integer(1),-Integer(1)],[Integer(2),-Integer(2)]]) == SetPartition(da.identity_set_partition(Integer(2)))
True
>>> da.to_set_partition([[Integer(1)]])
[{1}, {-1}]
>>> da.to_set_partition([[Integer(1),-Integer(1)],[-Integer(2),Integer(3)]],Integer(9)/Integer(2))
[{-1, 1}, {-2, 3}, {2}, {-4, 4}, {-5, 5}, {-3}]