diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index 2fd8b1e3d7a..037d37d74bb 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -43,7 +43,7 @@ from sage.misc.lazy_attribute import lazy_attribute from sage.misc.flatten import flatten from sage.misc.misc_c import prod -from sage.rings.all import ZZ +from sage.rings.all import ZZ, QQ from sage.functions.other import ceil import itertools @@ -112,6 +112,7 @@ def brauer_diagrams(k): [{{-3, 3}, {-2, 1}, {-1, 2}}, {{-3, 3}, {-2, 2}, {-1, 1}}, {{-3, 3}, {-2, -1}, {1, 2}}] """ if k in ZZ: + k = ZZ(k) S = SetPartitions(list(range(1,k+1)) + list(range(-k,0)), [2]*k) for i in S._iterator_part(S.parts): yield list(i) @@ -1073,11 +1074,12 @@ def __init__(self, order, category=None): if category is None: category = FiniteEnumeratedSets() Parent.__init__(self, category=category) - self.order = order if order in ZZ: + self.order = ZZ(order) base_set = frozenset(list(range(1,order+1)) + list(range(-order,0))) else: #order is a half-integer. + self.order = QQ(order) base_set = frozenset(list(range(1,ZZ(ZZ(1)/ZZ(2) + order)+1)) + list(range(ZZ(-ZZ(1)/ZZ(2) - order),0))) self._set = base_set @@ -1216,12 +1218,35 @@ class PartitionDiagrams(AbstractPartitionDiagrams): 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}}] + + TESTS:: + sage: import sage.combinat.diagram_algebras as da sage: pd = da.PartitionDiagrams(3) sage: pd.an_element() in pd True sage: pd.cardinality() == len(pd.list()) True + + sage: pd = da.PartitionDiagrams(5/2) + sage: pd.an_element() in pd + True + sage: pd.cardinality() == len(pd.list()) + True """ Element = PartitionDiagram _name = "Partition" @@ -1229,7 +1254,7 @@ class PartitionDiagrams(AbstractPartitionDiagrams): def cardinality(self): r""" - The cardinality of partition diagrams of integer order `n` is + The cardinality of partition diagrams of half-integer order `n` is the `2n`-th Bell number. EXAMPLES:: @@ -1238,10 +1263,12 @@ def cardinality(self): sage: pd = da.PartitionDiagrams(3) sage: pd.cardinality() 203 + + sage: pd = da.PartitionDiagrams(7/2) + sage: pd.cardinality() + 877 """ - if self.order in ZZ: - return bell_number(2*self.order) - return bell_number(2*(self.order-1/2)) + return bell_number(ZZ(2*self.order)) class BrauerDiagrams(AbstractPartitionDiagrams): r""" @@ -1251,6 +1278,21 @@ class BrauerDiagrams(AbstractPartitionDiagrams): 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, 2}, {-1, 1}}, {{-2, -1}, {1, 2}}] + + 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, 2}, {-1, 1}}, + {{-3, 3}, {-2, -1}, {1, 2}}] + + TESTS:: + sage: import sage.combinat.diagram_algebras as da sage: bd = da.BrauerDiagrams(3) sage: bd.an_element() in bd @@ -1258,6 +1300,12 @@ class BrauerDiagrams(AbstractPartitionDiagrams): sage: bd.cardinality() == len(bd.list()) True + sage: bd = da.BrauerDiagrams(5/2) + sage: bd.an_element() in bd + True + sage: bd.cardinality() == len(bd.list()) + True + These diagrams also come equipped with a compact representation based on their bipartition triple representation. See the :meth:`from_involution_permutation_triple` method for more information. @@ -1301,8 +1349,16 @@ def __contains__(self, obj): True sage: [[1,2,-1,-2]] in bd False + sage: bd = da.BrauerDiagrams(3/2) + sage: bd.an_element() in bd + True + """ - return super(BrauerDiagrams, self).__contains__(obj) and [len(i) for i in obj] == [2]*self.order + if self.order in ZZ: + r = ZZ(self.order) + else: + r = ZZ(self.order + ZZ(1)/ZZ(2)) + return super(BrauerDiagrams, self).__contains__(obj) and [len(i) for i in obj] == [2]*r def cardinality(self): r""" @@ -1316,11 +1372,15 @@ def cardinality(self): sage: bd = da.BrauerDiagrams(3) sage: bd.cardinality() 15 + + sage: bd = da.BrauerDiagrams(7/2) + sage: bd.cardinality() + 15 """ if self.order in ZZ: - return (2*self.order-1).multifactorial(2) + return (2*ZZ(self.order)-1).multifactorial(2) else: - return (2*(self.order-1/2)-1).multifactorial(2) + return (2*ZZ(self.order-1/2)-1).multifactorial(2) def symmetric_diagrams(self, l=None, perm=None): r""" @@ -1331,17 +1391,28 @@ def symmetric_diagrams(self, l=None, perm=None): sage: import sage.combinat.diagram_algebras as da sage: bd = da.BrauerDiagrams(4) - sage: bd.symmetric_diagrams(l=1,perm=[2,1]) + sage: bd.symmetric_diagrams(l=1, perm=[2,1]) [{{-4, -3}, {-2, 1}, {-1, 2}, {3, 4}}, {{-4, -2}, {-3, 1}, {-1, 3}, {2, 4}}, {{-4, 1}, {-3, -2}, {-1, 4}, {2, 3}}, {{-4, -1}, {-3, 2}, {-2, 3}, {1, 4}}, {{-4, 2}, {-3, -1}, {-2, 4}, {1, 3}}, {{-4, 3}, {-3, 4}, {-2, -1}, {1, 2}}] + + TESTS:: + + sage: import sage.combinat.diagram_algebras as da + sage: bd = da.BrauerDiagrams(3/2) + sage: bd.symmetric_diagrams(l=1, perm=[2,1]) + Traceback (most recent call last): + ... + NotImplementedError: symmetric_diagrams is only implemented for Brauer diagrams of integer order, not for order 3/2 """ # perm = permutation on free nodes # l = number of arcs - n = self.order + if self.order not in ZZ: + raise NotImplementedError("symmetric_diagrams is only implemented for Brauer diagrams of integer order, not for order %s" %(self.order)) + n = ZZ(self.order) if l is None: l = 0 if perm is None: @@ -1384,7 +1455,18 @@ def from_involution_permutation_triple(self, D1_D2_pi): 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}} + + TESTS:: + + sage: import sage.combinat.diagram_algebras as da + sage: bd = da.BrauerDiagrams(5/2) + sage: bd.from_involution_permutation_triple([[[1,2]],[[3,4]],[2,1]]) + Traceback (most recent call last): + ... + NotImplementedError: from_involution_permutation_triple is only implemented for Brauer diagrams of integer order, not for order 5/2 """ + if self.order not in ZZ: + raise NotImplementedError("from_involution_permutation_triple is only implemented for Brauer diagrams of integer order, not for order %s" %(self.order)) try: (D1,D2,pi) = tuple(D1_D2_pi) except ValueError: @@ -1413,12 +1495,35 @@ class TemperleyLiebDiagrams(AbstractPartitionDiagrams): 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, 1}, {-2, -1}, {2, 3}}, + {{-3, 3}, {-2, 2}, {-1, 1}}, + {{-3, 3}, {-2, -1}, {1, 2}}, + {{-3, -2}, {-1, 1}, {2, 3}}, + {{-3, -2}, {-1, 3}, {1, 2}}] + + sage: td = da.TemperleyLiebDiagrams(5/2); td + Temperley Lieb diagrams of order 5/2 + sage: td.list() + [{{-3, 3}, {-2, 2}, {-1, 1}}, {{-3, 3}, {-2, -1}, {1, 2}}] + + TESTS:: + sage: import sage.combinat.diagram_algebras as da sage: td = da.TemperleyLiebDiagrams(3) sage: td.an_element() in td True sage: td.cardinality() == len(td.list()) True + + sage: td = da.TemperleyLiebDiagrams(7/2) + sage: td.an_element() in td + True + sage: td.cardinality() == len(td.list()) + True """ Element = TemperleyLiebDiagram _name = "Temperley Lieb" @@ -1439,9 +1544,9 @@ def cardinality(self): 5 """ if self.order in ZZ: - return catalan_number(self.order) + return catalan_number(ZZ(self.order)) else: - return catalan_number(self.order-1/2) + return catalan_number(ZZ(self.order-1/2)) def __contains__(self, obj): r""" @@ -1463,11 +1568,7 @@ def __contains__(self, obj): obj = self._element_constructor_(obj) except (ValueError, TypeError): return False - if obj not in BrauerDiagrams(self.order): - return False - if not obj.is_planar(): - return False - return True + return obj in BrauerDiagrams(self.order) and obj.is_planar() class PlanarDiagrams(AbstractPartitionDiagrams): r""" @@ -1475,12 +1576,34 @@ class PlanarDiagrams(AbstractPartitionDiagrams): 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, 1, 2}}, + {{-2, 1, 2}, {-1}}, + {{-2, 2}, {-1, 1}}, + {{-2, -1, 2}, {1}}, + {{-2, 2}, {-1}, {1}}] + + TESTS:: + sage: import sage.combinat.diagram_algebras as da sage: pld = da.PlanarDiagrams(3) sage: pld.an_element() in pld True sage: pld.cardinality() == len(pld.list()) True + sage: pld = da.PlanarDiagrams(5/2) + sage: pld.an_element() in pld + True + sage: pld.cardinality() == len(pld.list()) + True """ Element = PlanarDiagram _name = "Planar" @@ -1500,10 +1623,7 @@ def cardinality(self): sage: pld.cardinality() 132 """ - if self.order in ZZ: - return catalan_number(2*self.order) - else: - return catalan_number(2*self.order-1) + return catalan_number(2*self.order) def __contains__(self, obj): r"""