Ticket #14234: trac_14234-review-ts.patch

File trac_14234-review-ts.patch, 90.0 KB (added by tscrim, 8 years ago)
  • doc/en/reference/combinat/algebra.rst

    # HG changeset patch
    # User Travis Scrimshaw <tscrim at ucdavis.edu>
    # Date 1374672188 -19800
    # Node ID 30fd0b638dd8bd1539eda8e15cecefbb72e0ad89
    # Parent 0fe1aa6825543229c38547a77aa541b471809eb9
    #14234: review patch.
    
    diff --git a/doc/en/reference/combinat/algebra.rst b/doc/en/reference/combinat/algebra.rst
    a b Combinatorial Algebras 
    66
    77   ../sage/combinat/free_module
    88   ../sage/combinat/combinatorial_algebra
     9   ../sage/combinat/diagram_algebras
    910   ../sage/combinat/symmetric_group_algebra
    1011   ../sage/combinat/symmetric_group_representations
    1112   ../sage/combinat/schubert_polynomial
  • sage/combinat/all.py

    diff --git a/sage/combinat/all.py b/sage/combinat/all.py
    a b from skew_partition import SkewPartition 
    5757from partition_algebra import SetPartitionsAk, SetPartitionsPk, SetPartitionsTk, SetPartitionsIk, SetPartitionsBk, SetPartitionsSk, SetPartitionsRk, SetPartitionsRk, SetPartitionsPRk
    5858
    5959#Diagram algebra
    60 from diagram_algebras import PartitionAlgebra, BrauerAlgebra, TemperleyLiebAlgebra, PlanarAlgebra, IdealAlgebra
     60from diagram_algebras import PartitionAlgebra, BrauerAlgebra, TemperleyLiebAlgebra, PlanarAlgebra, PropagatingIdeal
    6161
    6262#Vector Partitions
    6363from vector_partition import VectorPartition, VectorPartitions
  • sage/combinat/diagram_algebras.py

    diff --git a/sage/combinat/diagram_algebras.py b/sage/combinat/diagram_algebras.py
    a b  
    11r"""
    2 Diagram/Partition Algebras
     2Diagram and Partition Algebras
     3
     4AUTHORS:
     5
     6- Mike Hansen (2007): Initial version
     7- Stephen Doty, Aaron Lauve, George H. Seelinger (2012): Implementation of
     8  partition, Brauer, Temperley--Lieb, and ideal partition algebras
    39"""
     10
    411#*****************************************************************************
    512#  Copyright (C) 2007 Mike Hansen <mhansen@gmail.com>,
    613#                2012 Stephen Doty <doty@math.luc.edu>,
    Diagram/Partition Algebras 
    1017#  Distributed under the terms of the GNU General Public License (GPL)
    1118#                  http://www.gnu.org/licenses/
    1219#*****************************************************************************
     20
    1321from sage.categories.all import FiniteDimensionalAlgebrasWithBasis
    14 from sage.combinat.family import Family
     22from sage.structure.element import generic_power
    1523from sage.combinat.free_module import (CombinatorialFreeModule,
    1624    CombinatorialFreeModuleElement)
    17 from sage.combinat.set_partition import (SetPartitions, SetPartition)
     25from sage.combinat.set_partition import SetPartitions, SetPartition
    1826from sage.sets.set import Set
    1927from sage.graphs.graph import Graph
    2028from sage.misc.cachefunc import cached_method
    21 from sage.misc.latex import latex
    22 import collections
    23 import functools, math
     29from sage.rings.all import ZZ
     30import math
    2431
    2532def partition_diagrams(k):
    2633    r"""
    27     partition_diagrams(k) returns a list of all partition diagrams of order `k`,
    28     where we define a partition diagram of order `k` to be any set partition
    29     of the set `\{1, \dots, k, -1, \dots, -k\}`.
     34    Return a list of all partition diagrams of order ``k``.
     35
     36    A partition diagram of order `k \in \ZZ` to is a set partition of
     37    `\{1, \dots, k, -1, \ldots, -k\}`. If we have `k - 1/2 \in ZZ`, then
     38    a partition diagram of order `k \in 1/2 \ZZ` is a set partition of
     39    `\{1, \ldots, k+1/2, -1, \ldots, -(k+1/2)\}` with `k+1/2` and `-(k+1/2)`
     40    in the same block. See [HR2005]_.
    3041
    3142    INPUT:
    3243
    33     - ``k`` - integer or integer + 1/2. This is the order of the partition diagrams.
    34 
    35     OUTPUT:
    36 
    37     set partitions -- if k is an integer, set partitions of the set
    38     `\{1, \dots, k, -1, \dots, -k\}`. If k is an integer + 1/2, set
    39     partitions `\{1, \dots, k-0.5, -1, \dots, -(k-0.5)\}` with
    40     `\{k+0.5, -(k+0.5)\}` appended to each set partition.
     44    - ``k`` -- the order of the partition diagrams
    4145
    4246    EXAMPLES::
    4347
    4448        sage: import sage.combinat.diagram_algebras as da
    4549        sage: da.partition_diagrams(2)
    46         Set partitions of {1, 2, -1, -2}
    47         sage: da.partition_diagrams(1.5) #random order
    48         [{{2, -2}, {1, -1}}, {{-1}, {2, -2}, {1}}]
    49 
     50        [{{1, 2, -2, -1}}, {{2, -2, -1}, {1}}, {{1, -2, -1}, {2}},
     51         {{-2}, {1, 2, -1}}, {{1, 2, -2}, {-1}}, {{1, -2}, {2, -1}},
     52         {{2, -2}, {1, -1}}, {{-2, -1}, {1, 2}}, {{-2, -1}, {1}, {2}},
     53         {{-2}, {2, -1}, {1}}, {{2, -2}, {-1}, {1}}, {{-2}, {1, -1}, {2}},
     54         {{1, -2}, {-1}, {2}}, {{-2}, {-1}, {1, 2}}, {{-2}, {-1}, {1}, {2}}]
     55        sage: da.partition_diagrams(3/2)
     56        [{{1, 2, -1, -2}}, {{2, -1, -2}, {1}}, {{2, -2}, {1, -1}},
     57         {{1, 2, -2}, {-1}}, {{2, -2}, {-1}, {1}}]
    5058    """
    51     if int(k) == k:
    52         return SetPartitions( range(1,k+1) + [-j for j in range(1,k+1)] )
    53     if k - math.floor(k) == 0.5:
    54         L = []
    55         counter = 0
    56         for i in SetPartitions( range(1,int(k+0.5)) + [-j for j in range(1,int(k+0.5))] ):
    57             L.append(list(i))
    58             (L[counter]).append(Set([int(k)+1, -(int(k)+1)]))
    59             L[counter] = Set(L[counter])
    60             counter = counter+1
    61         return L
     59    if k in ZZ:
     60        return SetPartitions( range(1, k+1) + [-j for j in range(1, k+1)] ).list()
     61    # Else k in 1/2 ZZ
     62    L = []
     63    k += ZZ(1) / ZZ(2)
     64    for sp in SetPartitions( range(1, k+1) + [-j for j in range(1, k)] ):
     65        sp = list(sp)
     66        for i in range(len(sp)):
     67            if k in sp[i]:
     68                sp[i] += Set([-k])
     69                break
     70        L.append(SetPartition(sp))
     71    return L
    6272
    6373def brauer_diagrams(k):
    6474    r"""
    65     brauer_diagrams(k) returns a list of all Brauer diagrams of order `k`,
    66     where we define a Brauer diagram of order `k` to  be any set partition
    67     of the set`\{1, \dots, k, -1, \dots, -k\}` with block size 2.
     75    Return a list of all Brauer diagrams of order ``k``.
     76
     77    A Brauer diagram of order `k` is a partition diagram of order `k`
     78    with block size 2.
    6879
    6980    INPUT:
    7081
    71      - ``k`` - integer. This is the order of the Brauer diagrams.
    72 
    73     OUTPUT:
    74 
    75     set partitions -- set partitions of the set
    76     `\{1, \dots, k, -1, \dots, -k\}` with block size 2. If k is an
    77     integer + 1/2, set partitions
    78     `\{1, \dots, k-0.5, -1, \dots, -(k-0.5)\}` of block size 2 with
    79     `\{k+0.5, -(k+0.5)\}` appended to each set partition.
     82     - ``k`` -- the order of the Brauer diagrams
    8083
    8184    EXAMPLES::
    8285
    8386        sage: import sage.combinat.diagram_algebras as da
    8487        sage: da.brauer_diagrams(2)
    8588        [{{1, -2}, {2, -1}}, {{2, -2}, {1, -1}}, {{-2, -1}, {1, 2}}]
    86         sage: da.brauer_diagrams(2.5) #random order
    87         [{{1, 2}, {3, -3}, {-1, -2}}, {{2, -2}, {3, -3}, {1, -1}}, {{2, -1}, {3, -3}, {1, -2}}]
    88 
     89        sage: da.brauer_diagrams(5/2)
     90        [{{3, -3}, {1, -2}, {2, -1}}, {{3, -3}, {2, -2}, {1, -1}}, {{3, -3}, {-2, -1}, {1, 2}}]
    8991    """
    90     if int(k) == k:
    91         L = []
    92         for i in SetPartitions( range(1,k+1) + [-j for j in range(1,k+1)], [2 for j in range(1,k+1)] ):
    93             L.append(SetPartition(i))
    94         return L
    95     if k - math.floor(k) == 0.5:
    96         L = []
    97         counter = 0
    98         for i in SetPartitions( range(1,int(k+0.5)) + [-j for j in range(1,int(k+0.5))], [2 for j in range(1,k+0.5)] ).list():
    99             L.append(list(i))
    100             (L[counter]).append(Set([int(k)+1, -(int(k)+1)]))
    101             L[counter] = Set(L[counter])
    102             counter = counter+1
    103         return L
     92    if k in ZZ:
     93        return [SetPartition(list(x)) for x in
     94                SetPartitions( range(1,k+1) + [-j for j in range(1,k+1)],
     95                               [2 for j in range(1,k+1)] )]
     96    # Else k in 1/2 ZZ
     97    L = []
     98    k += ZZ(1) / ZZ(2)
     99    for i in SetPartitions( range(1, k) + [-j for j in range(1, k)],
     100                            [2 for j in range(1, k)] ):
     101        L.append(SetPartition(list(i) + [Set([k, -k])]))
     102    return L
    104103
    105104def temperley_lieb_diagrams(k):
    106105    r"""
    107     temperley_lieb_diagrams(k) returns a list of all Temperley-Lieb
    108     diagrams of order `k`, where we define a Temperley-Lieb diagram of
    109     order `k` to be any set partition of the set
    110     `\{1, \dots, k, -1, \dots, -k\}` with block size  2 and that is
    111     planar.
     106    Return a list of all Temperley--Lieb diagrams of order ``k``.
     107
     108    A Temperley--Lieb diagram of order `k` is a partition diagram of order `k`
     109    with block size  2 and is planar.
    112110
    113111    INPUT:
    114112
    115     - ``k`` - integer or integer + 1/2. This is the order of the
    116     Temperley-Lieb diagrams.
    117 
    118     OUTPUT:
    119 
    120     set partitions -- set partitions of the set
    121     `\{1, \dots, k, -1, \dots, -k\}` with block size 2 that are planar.
    122     If k is an integer + 1/2, set partitions
    123     `\{1, \dots, k-0.5, -1, \dots, -(k-0.5)\}` of block size 2 that are
    124     planar with `\{k+0.5, -(k+0.5)\}` appended to each set partition.
     113    - ``k`` -- the order of the Temperley--Lieb diagrams
    125114
    126115    EXAMPLES::
    127116
    128117        sage: import sage.combinat.diagram_algebras as da
    129         sage: da.temperley_lieb_diagrams(2) #random order
    130         [{{1, 2}, {-1, -2}}, {{2, -2}, {1, -1}}]
    131         sage: da.temperley_lieb_diagrams(2.5) #random order
    132         [{{1, 2}, {3, -3}, {-1, -2}}, {{2, -2}, {3, -3}, {1, -1}}]
     118        sage: da.temperley_lieb_diagrams(2)
     119        [{{2, -2}, {1, -1}}, {{-2, -1}, {1, 2}}]
     120        sage: da.temperley_lieb_diagrams(5/2)
     121        [{{3, -3}, {2, -2}, {1, -1}}, {{3, -3}, {-2, -1}, {1, 2}}]
    133122    """
    134123    B = brauer_diagrams(k)
    135124    T = []
    def temperley_lieb_diagrams(k): 
    140129
    141130def planar_diagrams(k):
    142131    r"""
    143     planar_diagrams(k) returns a list of all planar
    144     diagrams of order `k`, where we define a planar
    145     diagram as one that has no crossings.
     132    Return a list of all planar diagrams of order ``k``.
     133
     134    A planar diagram of order `k` is a partition diagram of order `k`
     135    that has no crossings.
    146136
    147137    EXAMPLES::
     138
    148139        sage: import sage.combinat.diagram_algebras as da
    149         sage: da.planar_diagrams(2) #random order
    150         [{{1, 2, -2, -1}}, {{2, -2, -1}, {1}}, {{1, -2, -1}, {2}}, {{-2}, {1, 2, -1}}, {{1, 2, -2}, {-1}}, {{2, -2}, {1, -1}}, {{-2, -1}, {1, 2}}, {{-2, -1}, {1}, {2}}, {{-2}, {2, -1}, {1}}, {{2, -2}, {-1}, {1}}, {{-2}, {1, -1}, {2}}, {{1, -2}, {-1}, {2}}, {{-2}, {-1}, {1, 2}}, {{-2}, {-1}, {1}, {2}}]
    151         sage: da.planar_diagrams(1.5) #random order
    152         [{{2, -2}, {1, -1}}, {{-1}, {2, -2}, {1}}]
     140        sage: da.planar_diagrams(2)
     141        [{{1, 2, -2, -1}}, {{2, -2, -1}, {1}}, {{1, -2, -1}, {2}},
     142         {{-2}, {1, 2, -1}}, {{1, 2, -2}, {-1}}, {{2, -2}, {1, -1}},
     143         {{-2, -1}, {1, 2}}, {{-2, -1}, {1}, {2}}, {{-2}, {2, -1},
     144         {1}}, {{2, -2}, {-1}, {1}}, {{-2}, {1, -1}, {2}}, {{1, -2},
     145         {-1}, {2}}, {{-2}, {-1}, {1, 2}}, {{-2}, {-1}, {1}, {2}}]
     146        sage: da.planar_diagrams(3/2)
     147        [{{1, 2, -1, -2}}, {{2, -1, -2}, {1}}, {{2, -2}, {1, -1}},
     148         {{1, 2, -2}, {-1}}, {{2, -2}, {-1}, {1}}]
    153149    """
    154150    A = partition_diagrams(k)
    155151    P = []
    def planar_diagrams(k): 
    160156
    161157def ideal_diagrams(k):
    162158    r"""
    163     ideal_diagrams(k) returns a list of all "ideal"
    164     diagrams of order `k`, where we define an ideal
    165     diagram as one with propogating number less than
    166     `k`.
     159    Return a list of all "ideal" diagrams of order ``k``.
     160
     161    An ideal diagram of order `k` is a partition diagram of order `k` with
     162    propagating number less than `k`.
    167163
    168164    EXAMPLES::
     165
    169166        sage: import sage.combinat.diagram_algebras as da
    170         sage: da.ideal_diagrams(2) #random order
    171         [{{1, 2, -2, -1}}, {{2, -2, -1}, {1}}, {{1, -2, -1}, {2}}, {{-2}, {1, 2, -1}}, {{1, 2, -2}, {-1}}, {{-2, -1}, {1, 2}}, {{-2, -1}, {1}, {2}}, {{-2}, {2, -1}, {1}}, {{2, -2}, {-1}, {1}}, {{-2}, {1, -1}, {2}}, {{1, -2}, {-1}, {2}}, {{-2}, {-1}, {1, 2}}, {{-2}, {-1}, {1}, {2}}]
    172         sage: da.ideal_diagrams(1.5) #random order
    173         [{{-1}, {2, -2}, {1}}]       
     167        sage: da.ideal_diagrams(2)
     168        [{{1, 2, -2, -1}}, {{2, -2, -1}, {1}}, {{1, -2, -1}, {2}}, {{-2}, {1, 2, -1}},
     169         {{1, 2, -2}, {-1}}, {{-2, -1}, {1, 2}}, {{-2, -1}, {1}, {2}},
     170         {{-2}, {2, -1}, {1}}, {{2, -2}, {-1}, {1}}, {{-2}, {1, -1}, {2}},
     171         {{1, -2}, {-1}, {2}}, {{-2}, {-1}, {1, 2}}, {{-2}, {-1}, {1}, {2}}]
     172        sage: da.ideal_diagrams(3/2)
     173        [{{1, 2, -1, -2}}, {{2, -1, -2}, {1}}, {{1, 2, -2}, {-1}}, {{2, -2}, {-1}, {1}}]     
    174174    """
    175175    A = partition_diagrams(k)
    176176    I = []
    def ideal_diagrams(k): 
    179179            I.append(i)
    180180    return I
    181181
    182 def is_partition_diagram(s,k):
    183     r"""
    184     is_partition_diagram(s,k) returns True if `s` is a partition diagram of order
    185     exactly `k` (i.e., a set partition on `\{1, \dots, k, -1, \dots ,-k\}`) and returns False
    186     otherwise.
    187     INPUT:
    188 
    189      - ``s`` - set partition. This is the set partition being tested.
    190      - ``k`` - integer. This is the test order.
    191 
    192     OUTPUT:
    193 
    194     boolean -- this is true if `s` has order `k` and false otherwise.
    195 
    196     EXAMPLES::
    197         sage: import sage.combinat.diagram_algebras as da
    198         sage: s = da.partition_diagrams(2)
    199         sage: da.is_partition_diagram(s.list()[2], 2)
    200         True
    201         sage: da.is_partition_diagram(s.list()[2], 3)
    202         False
    203 
    204     TODO: SHOULD BE MADE A METHOD OF THE SetPartitions CLASS ?
    205     """
    206     return s in partition_diagrams(k)
    207 
    208182class DiagramAlgebra(CombinatorialFreeModule):
    209183    r"""
    210     Abstract class designed not to be used directly.
    211     If used directly, the class could create an algebra
     184    Abstract class for diagram algebras and is not designed to be used
     185    directly. If used directly, the class could create an "algebra"
    212186    that is not actually an algebra.
    213187
    214188    TESTS::
    215189
    216190        sage: import sage.combinat.diagram_algebras as da
    217         sage: D = da.DiagramAlgebra(x, QQ[x], 'P', da.partition_diagrams(2))
     191        sage: R.<x> = QQ[]
     192        sage: D = da.DiagramAlgebra(2, x, R, 'P', da.partition_diagrams)
    218193        sage: D.basis()
    219         Lazy family (Term map from Set partitions of {1, 2, -1, -2} to Free module generated by Set partitions of {1, 2, -1, -2} over Univariate Polynomial Ring in x over Rational Field(i))_{i in Set partitions of {1, 2, -1, -2}}
     194        Finite family {{{1, -2}, {2, -1}}: P[{{1, -2}, {2, -1}}],
     195         {{1, 2, -2}, {-1}}: P[{{1, 2, -2}, {-1}}],
     196         {{2, -2, -1}, {1}}: P[{{2, -2, -1}, {1}}],
     197         {{-2}, {-1}, {1, 2}}: P[{{-2}, {-1}, {1, 2}}],
     198         {{1, -2, -1}, {2}}: P[{{1, -2, -1}, {2}}],
     199         {{-2}, {2, -1}, {1}}: P[{{-2}, {2, -1}, {1}}],
     200         {{1, 2, -2, -1}}: P[{{1, 2, -2, -1}}],
     201         {{2, -2}, {1, -1}}: P[{{2, -2}, {1, -1}}],
     202         {{-2, -1}, {1}, {2}}: P[{{-2, -1}, {1}, {2}}],
     203         {{-2}, {-1}, {1}, {2}}: P[{{-2}, {-1}, {1}, {2}}],
     204         {{-2, -1}, {1, 2}}: P[{{-2, -1}, {1, 2}}],
     205         {{-2}, {1, 2, -1}}: P[{{-2}, {1, 2, -1}}],
     206         {{2, -2}, {-1}, {1}}: P[{{2, -2}, {-1}, {1}}],
     207         {{-2}, {1, -1}, {2}}: P[{{-2}, {1, -1}, {2}}],
     208         {{1, -2}, {-1}, {2}}: P[{{1, -2}, {-1}, {2}}]}
     209    """
     210    def __init__(self, k, q, base_ring, prefix, diagrams, category=None):
     211        r"""
     212        Initialize ``self``.
    220213
    221     """
    222     def __init__(self, q, base_ring, prefix, diagrams):
    223         r"""
    224         See :class:`DiagramAlgebra` for full documentation.
     214        INPUT:
    225215
    226         TESTS::
    227             sage: import sage.combinat.diagram_algebras as da
    228             sage: D = da.DiagramAlgebra(x, QQ[x], 'P', da.partition_diagrams(2))
    229         """
    230         self._prefix = prefix
    231         self._q = base_ring(q)
    232         category = FiniteDimensionalAlgebrasWithBasis(base_ring)
    233         CombinatorialFreeModule.__init__(self, base_ring, diagrams,
    234                     category = category, prefix=prefix)
    235 
    236     def _element_constructor_(self, set_partition):
    237         r"""
    238         If D is a particular diagram algebra (previously defined) then
    239         D( sp ) returns the element of the algebra D corresponding to a
    240         given set partition sp.
     216        - ``k`` -- the rank
     217        - ``q`` -- the deformation parameter
     218        - ``base_ring`` -- the base ring
     219        - ``prefix`` -- the prefix of our monomials
     220        - ``diagrams`` -- the *function* which will generate all diagrams
     221          (i.e. indices for the basis elements)
    241222
    242223        TESTS::
    243224
    244225            sage: import sage.combinat.diagram_algebras as da
    245             sage: D = da.DiagramAlgebra(x, QQ[x], 'P', da.partition_diagrams(2))
    246             sage: sp = da.to_set_partition( [[1,2], [-1,-2]] )  # create a set partition
    247             sage: sp
    248             {{-1, -2}, {1, 2}}
    249             sage: D(sp)  # construct a basis element from it
    250             P[{{-1, -2}, {1, 2}}]
    251             sage: D(sp) in D
     226            sage: R.<x> = QQ[]
     227            sage: D = da.DiagramAlgebra(2, x, R, 'P', da.partition_diagrams)
     228            sage: TestSuite(D).run()
     229        """
     230        self._prefix = prefix
     231        self._q = base_ring(q)
     232        self._k = k
     233        if category is None:
     234            category = FiniteDimensionalAlgebrasWithBasis(base_ring)
     235        CombinatorialFreeModule.__init__(self, base_ring, diagrams(k),
     236                    category=category, prefix=prefix)
     237
     238    def _element_constructor_(self, set_partition):
     239        r"""
     240        Construct an element of ``self``.
     241
     242        TESTS::
     243
     244            sage: import sage.combinat.diagram_algebras as da
     245            sage: R.<x> = QQ[]
     246            sage: D = da.DiagramAlgebra(2, x, R, 'P', da.partition_diagrams)
     247            sage: sp = da.to_set_partition( [[1,2], [-1,-2]] )
     248            sage: b_elt = D(sp); b_elt
     249            P[{{-2, -1}, {1, 2}}]
     250            sage: b_elt in D
    252251            True
    253             sage: D([[1,2],[-1,-2]])
    254             P[{{-1, -2}, {1, 2}}]
    255             sage: D([{1,2},{-1,-2}])
    256             P[{{-1, -2}, {1, 2}}]
     252            sage: D([[1,2],[-1,-2]]) == b_elt
     253            True
     254            sage: D([{1,2},{-1,-2}]) == b_elt
     255            True
    257256        """
    258         if (set_partition in self.basis().keys()) and isinstance(set_partition, collections.Hashable):
     257        if set_partition in self.basis().keys():
    259258            return CombinatorialFreeModule._element_constructor_(self, set_partition)
    260             #return self.monomial(set_partition)
    261         elif isinstance(set_partition, list):
    262             sp = SetPartition(set_partition) # attempt coercion
    263             assert sp in self.basis().keys() # did it work?
    264             return CombinatorialFreeModule._element_constructor_(self, sp)
    265             #return self.monomial(sp)
    266         else:
    267             raise AssertionError, "%s invalid form" % set_partition
     259
     260        sp = SetPartition(set_partition) # attempt conversion
     261        if sp in self.basis().keys():
     262            return self.basis()[sp]
     263
     264        raise ValueError("invalid input of {0}".format(set_partition))
     265
     266    def __getitem__(self, i):
     267        """
     268        Get the basis item of ``self`` indexed by ``i``.
     269
     270        EXAMPLES::
     271
     272            sage: import sage.combinat.diagram_algebras as da
     273            sage: R.<x> = QQ[]
     274            sage: D = da.DiagramAlgebra(2, x, R, 'P', da.partition_diagrams)
     275            sage: sp = da.to_set_partition( [[1,2], [-1,-2]] )
     276            sage: D[sp]
     277            P[{{-2, -1}, {1, 2}}]
     278        """
     279        i = to_set_partition(i)
     280        if i in self.basis().keys():
     281            return self.basis()[i]
     282        raise ValueError("{0} is not an index of a basis element".format(i))
     283
     284    def order(self):
     285        r"""
     286        Return the order of ``self``.
     287
     288        The order of a partition algebra is defined as half of the number
     289        of nodes in the diagrams.
     290
     291        EXAMPLES::
     292
     293            sage: q = var('q')
     294            sage: PA = PartitionAlgebra(2, q)
     295            sage: PA.order()
     296            2
     297        """
     298        return self._k
     299
    268300    def set_partitions(self):
    269301        r"""
    270         This method returns the collection of underlying
    271         set partitions indexing the basis elements of a given
    272         diagram algebra.
     302        Return the collection of underlying set partitions indexing the
     303        basis elements of a given diagram algebra.
    273304
    274305        TESTS::
     306
    275307            sage: import sage.combinat.diagram_algebras as da
    276             sage: D = da.DiagramAlgebra(x, QQ[x], 'P', da.partition_diagrams(2))
    277             sage: D.set_partitions() == da.partition_diagrams(2)
     308            sage: R.<x> = QQ[]
     309            sage: D = da.DiagramAlgebra(2, x, R, 'P', da.partition_diagrams)
     310            sage: list(D.set_partitions()) == da.partition_diagrams(2)
    278311            True
    279312        """
    280313        return self.basis().keys()
    281314
    282315    def product_on_basis(self, d1, d2):
    283316        r"""
    284         This method defines the product of two basis diagrams. Usually
    285         it is not called directly, but indirectly through usualy arithmetic
    286         operators.
     317        Returns the product `D_{d_1} D_{d_2}` by two basis diagrams.
    287318
    288319        TESTS::
     320
    289321            sage: import sage.combinat.diagram_algebras as da
    290             sage: D = da.DiagramAlgebra(x, QQ[x], 'P', da.partition_diagrams(2));
    291             sage: D.product_on_basis(D([[1,2],[-1,-2]]), D([[1,2],[-1,-2]]))
    292             x*P[{{{{-1, -2}, {1, 2}}, 1}}]
     322            sage: R.<x> = QQ[]
     323            sage: D = da.DiagramAlgebra(2, x, R, 'P', da.partition_diagrams)
     324            sage: sp = SetPartition([[1,2],[-1,-2]])
     325            sage: D.product_on_basis(sp, sp)
     326            x*P[{{-2, -1}, {1, 2}}]
    293327        """
    294328        (composite_diagram, loops_removed) = set_partition_composition(d1, d2)
    295329        return self.term(composite_diagram, self._q**loops_removed)
     330
     331    @cached_method
     332    def one_basis(self):
     333        r"""
     334        The following constructs the identity element of the diagram algebra.
     335
     336        It is not called directly; instead one should use ``DA.one()`` if
     337        ``DA`` is a defined diagram algebra.
     338
     339        EXAMPLES::
     340
     341            sage: import sage.combinat.diagram_algebras as da
     342            sage: R.<x> = QQ[]
     343            sage: D = da.DiagramAlgebra(2, x, R, 'P', da.partition_diagrams)
     344            sage: D.one_basis()
     345            {{2, -2}, {1, -1}}
     346        """
     347        return identity_set_partition(self._k)
     348
    296349    # The following subclass provides a few additional methods for
    297     # partition algebra elements.  NOTE: Most element methods we need are
    298     # ALREADY implemented! Use the __dir__() builtin python function
    299     # to figure out what methods are defined.
    300 
     350    # partition algebra elements.
    301351    class Element(CombinatorialFreeModuleElement):
    302352        r"""
    303353        This subclass provides a few additional methods for
    304354        partition algebra elements. Most element methods are
    305355        already implemented elsewhere.
    306356        """
    307 
    308357        def diagram(self):
    309358            r"""
    310             This method returns the underlying diagram of a given
    311             basis element (or an error if not a basis element.)
     359            Return the underlying diagram of ``self`` if ``self`` is a basis
     360            element. Raises an error if ``self`` is not a basis element.
     361
     362            EXAMPLES::
     363
     364                sage: R.<x> = ZZ[]
     365                sage: P = PartitionAlgebra(2, x, R)
     366                sage: elt = 3*P([[1,2],[-2,-1]])
     367                sage: elt.diagram()
     368                {{-2, -1}, {1, 2}}
    312369            """
    313370            if len(self) != 1:
    314                 raise NotImplementedError("this works only for basis elements")
     371                raise ValueError("this is only defined for basis elements")
    315372            PA = self.parent()
    316373            ans = self.support_of_term()
    317             if is_partition_diagram(ans,PA.order()):
    318                 return ans
    319             raise NotImplementedError("element should be keyed by a diagram")
     374            if ans not in partition_diagrams(PA.order()):
     375                raise ValueError("element should be keyed by a diagram")
     376            return ans
    320377
    321378        def diagrams(self):
    322379            r"""
    323             this method returns the diagrams in the support of any
    324             given element. It is just a rename of "support" which already exists.
     380            Return the diagrams in the support of ``self``.
     381
     382            EXAMPLES::
     383
     384                sage: R.<x> = ZZ[]
     385                sage: P = PartitionAlgebra(2, x, R)
     386                sage: elt = 3*P([[1,2],[-2,-1]]) + P([[1,2],[-2], [-1]])
     387                sage: elt.diagrams()
     388                [{{-2}, {-1}, {1, 2}}, {{-2, -1}, {1, 2}}]
    325389            """
    326390            return self.support()
     391
    327392        def _latex_(self):
    328393            r"""
    329             This method returns latex code to draw single diagrams in latex using tikz.
     394            Return `\LaTeX` representation of ``self`` to draw single
     395            diagrams in latex using tikz.
    330396
    331             TODO: Put the latex.add_to_mathjax_avoid_list('tikzpicture') in a show method.
     397            EXAMPLES::
     398
     399                sage: R.<x> = ZZ[]
     400                sage: P = PartitionAlgebra(2, x, R)
     401                sage: latex(P([[1,2],[-2,-1]]))
     402                \begin{tikzpicture}[scale = 0.9,thick]
     403                \tikzstyle{vertex} = [shape = circle, minimum size = 9pt, inner sep = 1pt]
     404                \node[vertex] (G--2) at (1.5, -1) [shape = circle, draw] {};
     405                \node[vertex] (G--1) at (0.0, -1) [shape = circle, draw] {};
     406                \node[vertex] (G-1) at (0.0, 1) [shape = circle, draw] {};
     407                \node[vertex] (G-2) at (1.5, 1) [shape = circle, draw] {};
     408                \draw (G--2) .. controls +(-0.5, 0.5) and +(0.5, 0.5) .. (G--1);
     409                \draw (G-1) .. controls +(0.5, -0.5) and +(-0.5, -0.5) .. (G-2);
     410                \end{tikzpicture}
    332411            """
     412            # these allow the view command to work (maybe move them somewhere more appropriate?)
     413            from sage.misc.latex import latex
    333414            latex.add_to_mathjax_avoid_list('tikzpicture')
    334             latex.add_package_to_preamble_if_available('tikz') #these allow the view command to work. Should be moved?
     415            latex.add_package_to_preamble_if_available('tikz')
     416
     417            # Define the sign function
     418            def sgn(x):
     419                if x > 0:
     420                    return 1
     421                if x < 0:
     422                    return -1
     423                return 0
    335424            diagram = self.diagram()
    336425            l1 = [] #list of blocks
    337426            l2 = [] #lsit of nodes
    class DiagramAlgebra(CombinatorialFreeMo 
    339428                l1.append(list(i))
    340429                for j in list(i):
    341430                    l2.append(j)
    342             output = "\\begin{tikzpicture}[scale = 0.9,thick] \n\\tikzstyle{vertex} = [shape = circle, minimum size = 9pt, inner sep = 1pt] \n" #setup beginning of picture
     431            #setup beginning of picture
     432            output = "\\begin{tikzpicture}[scale = 0.9,thick] \n\\tikzstyle{vertex} = [shape = circle, minimum size = 9pt, inner sep = 1pt] \n"
    343433            for i in l2: #add nodes
    344434                output = output + "\\node[vertex] (G-%s) at (%s, %s) [shape = circle, draw] {}; \n" % (i, (abs(i)-1)*1.5, sgn(i))
    345435            for i in l1: #add edges
    class DiagramAlgebra(CombinatorialFreeMo 
    381471
    382472class PartitionAlgebra(DiagramAlgebra):
    383473    r"""
    384     INPUT:
     474    A partition algebra.
    385475
    386      -``k``-- rank of the algebra (equals half the number of nodes in the diagrams)
    387      -``q``-- a parameter.
    388 
    389     OPTIONAL ARGUMENTS:
    390 
    391      -``base_ring``-- a ring containing q (default q.parent())
    392      -``prefix``-- a label for the basis elements (default "P")
    393 
    394     The partition algebra of rank k is an algebra with basis indexed by the
    395     collection of set partitions of `\{1, \dots, k, -1, \dots, -k\}`. Each such set
    396     partition is regarded as a graph on nodes `\{1, \dots, k, -1, \dots, -k\}`
    397     arranged in two rows, with nodes `1, \dots, k` in the top row from left to
    398     right and with nodes `-1, \dots, -k` in the bottom row from left to right,
    399     and an edge connecting two nodes if and only if the nodes lie in the same
    400     subset of the set partition.
     476    The partition algebra of rank `k` is an algebra with basis indexed by the
     477    collection of set partitions of `\{1, \dots, k, -1, \ldots, -k\}`. Each
     478    such set partition is regarded as a graph on nodes `\{1, \ldots, k, -1,
     479    \ldots, -k\}` arranged in two rows, with nodes `1, \dots, k` in the top
     480    row from left to right and with nodes `-1, \ldots, -k` in the bottom row
     481    from left to right, and an edge connecting two nodes if and only if the
     482    nodes lie in the same subset of the set partition.
    401483
    402484    The partition algebra is regarded as an example of a "diagram algebra" due
    403485    to the fact that its natural basis is given by certain graphs often called
    404486    diagrams.
    405487
    406     The product of two basis elements is given by the rule  a.b = q^N (a o b),
    407     where a o b is the composite set partition obtained by placing diagram
    408     a above diagram b, identifying the bottom row nodes of a with the top row
    409     nodes of b, and omitting any closed "loops" in the middle. The number N
    410     is the number of connected components of the omitted loops.
     488    The product of two basis elements is given by the rule
     489    `a \cdot b = q^N (a \circ b)`, where `a \circ b` is the composite set
     490    partition obtained by placing diagram `a` above diagram `b`, identifying
     491    the bottom row nodes of `a` with the top row nodes of `b`, and omitting
     492    any closed "loops" in the middle. The number `N` is the number of
     493    connected components of the omitted loops.
    411494
    412     The parameter q is a deformation parameter. Taking `q=1` produces the
     495    The parameter `q` is a deformation parameter. Taking `q = 1` produces the
    413496    semigroup algebra (over the base ring) of the partition monoid, in which
    414497    the product of two set partitions is simply given by their composition.
    415498
    416     The Iwahori-Hecke algebra of type A (with a single parameter) is naturally
    417     a subalgebra of the partition algebra.
     499    The Iwahori--Hecke algebra of type `A` (with a single parameter) is
     500    naturally a subalgebra of the partition algebra.
    418501
    419502    An excellent reference for partition algebras and its various subalgebras
    420     (Brauer algebra, Temperley-Lieb algebra, etc) is the paper [HR]_.
     503    (Brauer algebra, Temperley--Lieb algebra, etc) is the paper [HR2005]_.
    421504
    422     REFERENCES:
     505    INPUT:
    423506
    424     .. [HR] Tom Halverson and Arun Ram, Partition algebras. European Journal of
    425             Combinatorics 26 (2005), 869--921.
     507    - ``k``-- rank of the algebra
     508
     509    - ``q``-- the deformation parameter `q`
     510
     511    OPTIONAL ARGUMENTS:
     512
     513    - ``base_ring``-- (default ``None``) a ring containing ``q``; if ``None``
     514      then just takes the parent of ``q``
     515
     516    - ``prefix``-- (default ``"P"``) a label for the basis elements
    426517
    427518    EXAMPLES:
    428519
    429520    The following shorthand simultaneously define the univariate polynomial
    430     ring over the rationals as well as the variable `x`::
     521    ring over the rationals as well as the variable ``x``::
    431522
    432523        sage: R.<x> = PolynomialRing(QQ)
    433524        sage: R
    class PartitionAlgebra(DiagramAlgebra): 
    437528        sage: x.parent() is R
    438529        True
    439530
    440     We now define the partition algebra of rank `2` with parameter `x` over the Integer ring::
     531    We now define the partition algebra of rank `2` with parameter ``x``
     532    over `\ZZ`::
    441533
    442         sage: P = PartitionAlgebra(2,x,ZZ['x'])
     534        sage: R.<x> = ZZ[]
     535        sage: P = PartitionAlgebra(2, x, R)
    443536        sage: P
    444         Partition Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring, with prefix P
    445         sage: P.basis()
    446         Lazy family (Term map from Set partitions of {1, 2, -1, -2} to Partition Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring, with prefix P(i))_{i in Set partitions of {1, 2, -1, -2}}
    447         sage: b = P.basis().list()
    448         sage: b #random order
    449         [P[{{1, 2, -1, -2}}], P[{{2, -1, -2}, {1}}], P[{{2}, {1, -1, -2}}], P[{{-1}, {1, 2, -2}}], P[{{-2}, {1, 2, -1}}], P[{{2, -1}, {1, -2}}], P[{{2, -2}, {1, -1}}], P[{{-2, -1}, {1, 2}}], P[{{2}, {-1, -2}, {1}}], P[{{-1}, {2, -2}, {1}}], P[{{-2}, {2, -1}, {1}}], P[{{-1}, {2}, {1, -2}}], P[{{-2}, {2}, {1, -1}}], P[{{-1}, {-2}, {1, 2}}], P[{{-1}, {-2}, {2}, {1}}]]
     537        Partition Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring
     538        sage: P.basis().list()
     539        [P[{{1, 2, -2, -1}}], P[{{2, -2, -1}, {1}}],
     540         P[{{1, -2, -1}, {2}}], P[{{-2}, {1, 2, -1}}],
     541         P[{{1, 2, -2}, {-1}}], P[{{1, -2}, {2, -1}}],
     542         P[{{2, -2}, {1, -1}}], P[{{-2, -1}, {1, 2}}],
     543         P[{{-2, -1}, {1}, {2}}], P[{{-2}, {2, -1}, {1}}],
     544         P[{{2, -2}, {-1}, {1}}], P[{{-2}, {1, -1}, {2}}],
     545         P[{{1, -2}, {-1}, {2}}], P[{{-2}, {-1}, {1, 2}}],
     546         P[{{-2}, {-1}, {1}, {2}}]]
    450547        sage: E = P([[1,2],[-2,-1]]); E
    451548        P[{{-2, -1}, {1, 2}}]
    452         sage: E in b
     549        sage: E in P.basis()
    453550        True
    454551        sage: E^2
    455552        x*P[{{-2, -1}, {1, 2}}]
    class PartitionAlgebra(DiagramAlgebra): 
    460557
    461558    One can work with partition algebras using a symbol for the parameter,
    462559    leaving the base ring unspecified. This implies that the underlying
    463     base ring is Sage's Symbolic Ring.
     560    base ring is Sage's symbolic ring.
    464561
    465562    ::
    466563
    467564        sage: q = var('q')
    468         sage: PA = PartitionAlgebra(2,q); PA
    469         Partition Algebra of rank 2 with parameter q over Symbolic Ring, with prefix P
    470         sage: P = PA.basis().list()
     565        sage: PA = PartitionAlgebra(2, q); PA
     566        Partition Algebra of rank 2 with parameter q over Symbolic Ring
    471567        sage: PA([[1,2],[-2,-1]])^2 == q*PA([[1,2],[-2,-1]])
    472568        True
    473         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]])
     569        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]])
    474570        True
    475        
    476571
    477572    The identity element of the partition algebra is the diagram whose set
    478     partition is `\{\{1,-1\}, \{2,-2\}, ..., \{k,-k\}\}`.
     573    partition is `\{\{1,-1\}, \{2,-2\}, \ldots, \{k,-k\}\}`::
    479574
    480     ::
    481 
    482         sage: PA.one() #random order from SetPartitions
     575        sage: P = PA.basis().list()
     576        sage: PA.one()
    483577        P[{{2, -2}, {1, -1}}]
    484578        sage: PA.one()*P[7] == P[7]
    485579        True
    486580        sage: P[7]*PA.one() == P[7]
    487581        True
    488582
    489         We now give some further examples of the use of the other arguments.
    490         One may wish to "specialize" the parameter to a chosen element of
    491         the base ring.
     583    We now give some further examples of the use of the other arguments.
     584    One may wish to "specialize" the parameter to a chosen element of
     585    the base ring::
    492586
    493     ::
    494 
    495         sage: PA = PartitionAlgebra(2, q, RR['q'], prefix='B')
     587        sage: R.<q> = RR[]
     588        sage: PA = PartitionAlgebra(2, q, R, prefix='B')
    496589        sage: PA
    497         Partition Algebra of rank 2 with parameter q over Univariate Polynomial Ring in q over Real Field with 53 bits of precision, with prefix B
    498         sage: PA([[1,2],[-1,-2]]) #random order due to set partitions.
     590        Partition Algebra of rank 2 with parameter q over
     591         Univariate Polynomial Ring in q over Real Field with 53 bits of precision
     592        sage: PA([[1,2],[-1,-2]])
    499593        1.00000000000000*B[{{-2, -1}, {1, 2}}]
    500594        sage: PA = PartitionAlgebra(2, 5, base_ring=ZZ, prefix='B')
    501595        sage: PA
    502         Partition Algebra of rank 2 with parameter 5 over Integer Ring, with prefix B
    503         sage: P = PA.basis().list()
     596        Partition Algebra of rank 2 with parameter 5 over Integer Ring
    504597        sage: (PA([[2, -2], [1, -1]]) - 2*PA([[-2, -1], [1, 2]]))^2 == 16*PA([[-2, -1], [1, 2]]) + PA([[2, -2], [1, -1]])
    505598        True
     599
     600    REFERENCES:
     601
     602    .. [HR2005] Tom Halverson and Arun Ram, *Partition algebras*. European
     603       Journal of Combinatorics **26** (2005), 869--921.
    506604    """
    507 
    508605    @staticmethod
    509606    def __classcall_private__(cls, k, q, base_ring=None, prefix="P"):
    510607        r"""
    511         This method gets the base_ring from the parent of the parameter q
    512         if no base_ring is given.
     608        Standardize the input by getting the base ring from the parent of
     609        the parameter ``q`` if no ``base_ring`` is given.
    513610
    514         TODO: Move these methods to the Diagram Algebra class.
     611        TESTS::
     612
     613            sage: R.<q> = QQ[]
     614            sage: PA1 = PartitionAlgebra(2, q)
     615            sage: PA2 = PartitionAlgebra(2, q, R, 'P')
     616            sage: PA1 is PA2
     617            True
    515618        """
    516619        if base_ring is None:
    517620            base_ring = q.parent()
    518         return super(PartitionAlgebra, cls).__classcall__(
    519             cls, k, q=q, base_ring = base_ring, prefix=prefix)
    520 
     621        return super(PartitionAlgebra, cls).__classcall__(cls, k, q, base_ring, prefix)
    521622
    522623    # The following is the basic constructor method for the class.
    523624    # The purpose of the "prefix" is to label the basis elements
    524625    def __init__(self, k, q, base_ring, prefix):
    525626        r"""
    526         See :class:`PartitionAlgebra` for full documentation.
     627        Initialize ``self``.
    527628
    528629        TESTS::
    529630
    530             sage: q = var('q')
    531             sage: PA = PartitionAlgebra(2, q, RR['q'])
     631            sage: R.<q> = QQ[]
     632            sage: PA = PartitionAlgebra(2, q, R)
    532633            sage: TestSuite(PA).run()
    533634        """
    534635        self._k = k
    535636        self._prefix = prefix
    536637        self._q = base_ring(q)
    537         category = FiniteDimensionalAlgebrasWithBasis(base_ring)
    538         DiagramAlgebra.__init__(self, q, base_ring, prefix, partition_diagrams(k))
     638        DiagramAlgebra.__init__(self, k, q, base_ring, prefix, partition_diagrams)
    539639
    540         #       CombinatorialFreeModule.__init__(self, base_ring, partition_diagrams(k),
    541         #            category = category, prefix=prefix)
    542 
    543     @cached_method
    544     def one_basis(self):
    545         r"""
    546         The following constructs the identity element of the partition algebra.
    547         It is not called directly; instead one should use PA.one() if PA is a
    548         previously defined partition algebra instance.
     640    def _repr_(self):
     641        """
     642        Return a string representation of ``self``.
    549643
    550644        EXAMPLES::
    551645
    552             sage: PA = PartitionAlgebra(2, x);
    553             sage: PA.one_basis()
    554             {{2, -2}, {1, -1}}
     646            sage: R.<q> = QQ[]
     647            sage: PartitionAlgebra(2, q, R)
     648            Partition Algebra of rank 2 with parameter q over Univariate Polynomial Ring in q over Rational Field
     649        """
     650        return "Partition Algebra of rank %s with parameter %s over %s"%(self._k,
     651                self._q, self.base_ring())
    555652
     653class SubPartitionAlgebra(DiagramAlgebra):
     654    """
     655    A subalgebra of the partition algebra indexed by a subset of the diagrams.
     656    """
     657    def __init__(self, k, q, base_ring, prefix, diagrams, category=None):
    556658        """
    557         return identity_set_partition(self._k)
    558 
    559     def _repr_(self):
    560         msg = "Partition Algebra of rank %s with parameter %s over %s, with prefix %s"
    561         return msg % (self._k, self._q, self.base_ring(), self._prefix)
    562 
    563     def order(self):
    564         r"""
    565         The method PA.order() returns the 'order' of the given partition algebra PA.
    566         This is defined as half of the number of nodes in the diagrams.
     659        Initialize ``self`` by adding a coercion to the ambient space.
    567660
    568661        EXAMPLES::
    569662
    570             sage: q = var('q')
    571             sage: PA = PartitionAlgebra(2,q)
    572             sage: PA.order()
    573             2
     663            sage: R.<x> = QQ[]
     664            sage: BA = BrauerAlgebra(2, x, R)
     665            sage: BA.ambient().has_coerce_map_from(BA)
     666            True
    574667        """
    575         return self._k
     668        DiagramAlgebra.__init__(self, k, q, base_ring, prefix, diagrams, category)
     669        amb = self.ambient()
     670        self.module_morphism(self.lift, codomain=amb,
     671                             category=self.category()).register_as_coercion()
    576672
    577 class BrauerAlgebra(DiagramAlgebra):
     673    #These methods allow for a sub algebra to be correctly identified in a partition algebra
     674    def ambient(self):
     675        r"""
     676        Return the partition algebra ``self`` is a sub-algebra of.
     677        Generally, this method is not called directly.
     678
     679        EXAMPLES::
     680
     681            sage: x = var('x')
     682            sage: BA = BrauerAlgebra(2, x)
     683            sage: BA.ambient()
     684            Partition Algebra of rank 2 with parameter x over Symbolic Ring
     685        """
     686        return PartitionAlgebra(self._k, self._q, self.base_ring(), prefix=self._prefix)
     687
     688    def lift(self, x):
     689        r"""
     690        Lift a diagram subalgebra element to the corresponding element
     691        in the ambient space. This method is not intended to be called
     692        directly.
     693
     694        EXAMPLES::
     695
     696            sage: R.<x> = QQ[]
     697            sage: BA = BrauerAlgebra(2, x, R)
     698            sage: E = BA([[1,2],[-1,-2]])
     699            sage: lifted = BA.lift(E); lifted
     700            B[{{-2, -1}, {1, 2}}]
     701            sage: lifted.parent() is BA.ambient()
     702            True
     703        """
     704        if x not in self:
     705            raise ValueError("{0} is not in {1}".format(x, self))
     706        monomial_indices = x.support()
     707        monomial_coefficients = x.coefficients()
     708        result = 0
     709        for i in xrange(len(monomial_coefficients)):
     710            result += monomial_coefficients[i]*self.ambient().monomial(monomial_indices[i])
     711        return result
     712
     713    def retract(self, x):
     714        r"""
     715        Retract an appropriate partition algebra element to the
     716        corresponding element in the partition subalgebra. This method
     717        is not intended to be called directly.
     718
     719        EXAMPLES::
     720
     721            sage: R.<x> = QQ[]
     722            sage: BA = BrauerAlgebra(2, x, R)
     723            sage: PA = BA.ambient()
     724            sage: E = PA([[1,2], [-1,-2]])
     725            sage: BA.retract(E) in BA
     726            True
     727        """
     728        if x not in self.ambient() or not set(x.support()).issubset(set(self.basis().keys())):
     729            raise ValueError("{0} cannot retract to {1}".format(x, self))
     730        monomial_indices = x.support()
     731        monomial_coefficients = x.coefficients()
     732        result = self.zero()
     733        for i in xrange(len(monomial_coefficients)):
     734            result += monomial_coefficients[i]*self.monomial(monomial_indices[i])
     735        return result
     736
     737class BrauerAlgebra(SubPartitionAlgebra):
    578738    r"""
     739    A Brauer algebra.
     740
     741    The Brauer algebra of rank `k` is an algebra with basis indexed by the
     742    collection of set partitions of `\{1, \ldots, k, -1, \ldots, -k\}`
     743    with block size 2.
     744
     745    This algebra is a subalgebra of the partition algebra.
     746    For more information, see :class:`PartitionAlgebra`.
     747
    579748    INPUT:
    580749
    581      -``k``-- rank of the algebra (equals half the number of nodes in the diagrams)
    582      -``q``-- a parameter.
     750    - ``k``-- rank of the algebra
     751
     752    - ``q``-- the deformation parameter `q`
    583753
    584754    OPTIONAL ARGUMENTS:
    585755
    586      -``base_ring``-- a ring containing q (default q.parent())
    587      -``prefix``-- a label for the basis elements (default "B")
     756    - ``base_ring``-- (default ``None``) a ring containing ``q``; if ``None``
     757      then just takes the parent of ``q``
    588758
    589     The Brauer algebra of rank k is an algebra with basis indexed by the
    590     collection of set partitions of `\{1, \dots, k, -1, \dots, -k\}`
    591     with block size 2. This algebra is thus a subalgebra of the
    592     partition algebra. For more information, see
    593     :class:`PartitionAlgebra`
     759    - ``prefix``-- (default ``"B"``) a label for the basis elements
    594760
    595761    EXAMPLES:
    596762
    597     The following shorthand simultaneously define the univariate polynomial
    598     ring over the rationals as well as the variable `x`::
     763    We now define the Brauer algebra of rank `2` with parameter ``x`` over
     764    `\ZZ`::
    599765
    600         sage: R.<x> = PolynomialRing(QQ)
    601         sage: R
    602         Univariate Polynomial Ring in x over Rational Field
    603         sage: x
    604         x
    605         sage: x.parent() is R
    606         True
    607 
    608     We now define the Brauer algebra of rank `2` with parameter `x` over the Integer ring::
    609 
    610         sage: B = BrauerAlgebra(2,x,ZZ[x])
     766        sage: R.<x> = ZZ[]
     767        sage: B = BrauerAlgebra(2, x, R)
    611768        sage: B
    612         Brauer Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring, with prefix B
     769        Brauer Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring
    613770        sage: B.basis()
    614771        Finite family {{{2, -2}, {1, -1}}: B[{{2, -2}, {1, -1}}], {{-2, -1}, {1, 2}}: B[{{-2, -1}, {1, 2}}], {{1, -2}, {2, -1}}: B[{{1, -2}, {2, -1}}]}
    615772        sage: b = B.basis().list()
    616         sage: b #random order
    617         [B[{{2, -1}, {1, -2}}], B[{{2, -2}, {1, -1}}], B[{{-2, -1}, {1, 2}}]]
     773        sage: b
     774        [B[{{1, -2}, {2, -1}}], B[{{2, -2}, {1, -1}}], B[{{-2, -1}, {1, 2}}]]
    618775        sage: b[2]
    619776        B[{{-2, -1}, {1, 2}}]
    620777        sage: b[2]^2
    class BrauerAlgebra(DiagramAlgebra): 
    625782    @staticmethod
    626783    def __classcall_private__(cls, k, q, base_ring=None, prefix="B"):
    627784        r"""
    628         This method gets the base_ring from the parent of the parameter q
    629         if no base_ring is given.
     785        Standardize the input by getting the base ring from the parent of
     786        the parameter ``q`` if no ``base_ring`` is given.
     787
     788        TESTS::
     789
     790            sage: R.<q> = QQ[]
     791            sage: BA1 = BrauerAlgebra(2, q)
     792            sage: BA2 = BrauerAlgebra(2, q, R, 'B')
     793            sage: BA1 is BA2
     794            True
    630795        """
    631796        if base_ring is None:
    632797            base_ring = q.parent()
    633         return super(BrauerAlgebra, cls).__classcall__(
    634                                                        cls, k, q=q, base_ring = base_ring, prefix=prefix)
    635     def __init__(self, k, q, base_ring, prefix = "B"):
     798        return super(BrauerAlgebra, cls).__classcall__(cls, k, q, base_ring, prefix)
     799
     800    def __init__(self, k, q, base_ring, prefix):
    636801        r"""
    637         See :class:`BrauerAlgebra` for full documentation.
     802        Initialize ``self``.
    638803
    639804        TESTS::
    640805
    641             sage: q = var('q')
    642             sage: BA = BrauerAlgebra(2, q, RR['q'])
     806            sage: R.<q> = QQ[]
     807            sage: BA = BrauerAlgebra(2, q, R)
    643808            sage: TestSuite(BA).run()
    644809        """
    645         self._k = k
    646         self._prefix = prefix
    647         self._q = base_ring(q)
    648         category = FiniteDimensionalAlgebrasWithBasis(base_ring)
    649         DiagramAlgebra.__init__(self, q, base_ring, prefix, brauer_diagrams(k))
     810        SubPartitionAlgebra.__init__(self, k, q, base_ring, prefix, brauer_diagrams)
    650811
    651     @cached_method
    652     def one_basis(self):
    653         r"""
    654         The following constructs the identity element of the Brauer algebra.
    655         It is not called directly; instead one should use BA.one() if BA is a
    656         previously defined Brauer algebra instance.
     812    def _repr_(self):
     813        """
     814        Return a string representation of ``self``.
    657815
    658816        EXAMPLES::
    659817
    660             sage: BA = BrauerAlgebra(2, x);
    661             sage: BA.one_basis()
    662             {{2, -2}, {1, -1}}
    663             sage: BA.one()
    664             B[{{2, -2}, {1, -1}}]
    665 
     818            sage: R.<q> = QQ[]
     819            sage: BrauerAlgebra(2, q, R)
     820            Brauer Algebra of rank 2 with parameter q over Univariate Polynomial Ring in q over Rational Field
    666821        """
    667         return identity_set_partition(self._k)
    668 
    669     def _repr_(self):
    670         msg = "Brauer Algebra of rank %s with parameter %s over %s, with prefix %s"
    671         return msg % (self._k, self._q, self.base_ring(), self._prefix)
     822        return "Brauer Algebra of rank %s with parameter %s over %s"%(self._k, self._q, self.base_ring())
    672823
    673824    def _element_constructor_(self, set_partition):
    674825        r"""
    675         If BA is a particular Brauer algebra (previously defined) then
    676         BA( sp ) returns the element of the algebra BA corresponding to a
    677         given set partition sp.
     826        Construct an element of ``self``.
    678827
    679828        EXAMPLES::
    680829
    681             sage: q = var('q')
    682             sage: BA = BrauerAlgebra(2,q,QQ['q'])
    683             sage: BA
    684             Brauer Algebra of rank 2 with parameter q over Univariate Polynomial Ring in q over Rational Field, with prefix B
    685             sage: import sage.combinat.diagram_algebras as da
    686             sage: sp = da.to_set_partition( [[1,2], [-1,-2]] )  # create a set partition
    687             sage: BA(sp)  # construct a basis element from it
     830            sage: R.<q> = QQ[]
     831            sage: BA = BrauerAlgebra(2, q, R)
     832            sage: sp = SetPartition([[1,2], [-1,-2]])
     833            sage: b_elt = BA(sp); b_elt
    688834            B[{{-2, -1}, {1, 2}}]
    689             sage: BA(sp) in BA
     835            sage: b_elt in BA
    690836            True
    691             sage: BA([[1,2],[-1,-2]]) in BA
     837            sage: BA([[1,2],[-1,-2]]) == b_elt
    692838            True
    693             sage: BA([{1,2},{-1,-2}]) in BA
     839            sage: BA([{1,2},{-1,-2}]) == b_elt
    694840            True
    695841        """
    696842        set_partition = to_Brauer_partition(set_partition, k = self.order())
    697843        return DiagramAlgebra._element_constructor_(self, set_partition)
    698844
    699     #These methods allow for BrauerAlgebra to be correctly identified as a sub-algebra of PartitionAlgebra
    700     #With the DiagramAlgebra superclass, are these really necessary?
    701     def ambient(self):
    702         r"""
    703         ambient returns the partition algebra the Brauer algebra is a sub-algebra of.
    704         Generally, this method is not called directly.
     845class TemperleyLiebAlgebra(SubPartitionAlgebra):
     846    r"""
     847    A Temperley--Lieb algebra.
    705848
    706         EXAMPLES::
    707             sage: BA = BrauerAlgebra(2, x);
    708             sage: P = BA.ambient()
    709             sage: P
    710             Partition Algebra of rank 2 with parameter x over Symbolic Ring, with prefix B
    711         """
    712         return PartitionAlgebra(self._k, self._q, self.base_ring(), prefix=self._prefix)
    713     def lift(self, x):
    714         r"""
    715         lift maps a Brauer algebra element to the corresponding element
    716         in the ambient space. This method is not intended
    717         to be called directly.
     849    The Temperley--Lieb algebra of rank `k` is an algebra with basis indexed
     850    by the collection of planar set partitions of `\{1, \ldots, k, -1,
     851    \ldots, -k\}` with block size 2.
    718852
    719         EXAMPLES::
    720             sage: BA = BrauerAlgebra(2, x);
    721             sage: E = BA([[1,2],[-1,-2]]);
    722             sage: BA.lift(E) in BA.ambient()
    723             True
    724             sage: BA.lift(E) in BA
    725             False
    726         """
    727         assert x in self
    728         monomial_indices = x.support()
    729         monomial_coefficients = x.coefficients()
    730         result = 0
    731         for i in xrange(len(monomial_coefficients)):
    732             result += monomial_coefficients[i]*self.ambient().monomial(monomial_indices[i])
    733         return result
    734     def retract(self, x):
    735         r"""
    736         retract maps an appropriate partition algebra element to the
    737         corresponding element in the Brauer algebra. This method
    738         is not intended to be called directly.
     853    This algebra is thus a subalgebra of the partition algebra.
     854    For more information, see :class:`PartitionAlgebra`.
    739855
    740         EXAMPLES::
    741             sage: BA = BrauerAlgebra(2, x)
    742             sage: PA = BA.ambient()
    743             sage: E = PA([[1,2],[-1,-2]])
    744             sage: BA.retract(E) in PA
    745             False
    746             sage: BA.retract(E) in BA
    747             True
    748         """
    749         assert x in self.ambient() and set(x.support()).issubset(set(self.basis().keys()))
    750         monomial_indices = x.support()
    751         monomial_coefficients = x.coefficients()
    752         result = self.zero()
    753         for i in xrange(len(monomial_coefficients)):
    754             result += monomial_coefficients[i]*self.monomial(monomial_indices[i])
    755         return result
    756 
    757     #These methods depend on the above three methods
    758     def order(self):
    759         r"""
    760         Returns the order of the Brauer Algebra
    761         EXAMPLES::
    762             sage: BA = BrauerAlgebra(2, x)
    763             sage: BA.order()
    764             2
    765         """
    766         return self.ambient().order()
    767 
    768 class TemperleyLiebAlgebra(DiagramAlgebra):
    769     r"""
    770856    INPUT:
    771857
    772      -``k``-- rank of the algebra (equals half the number of nodes in the diagrams)
    773      -``q``-- a parameter.
     858    - ``k``-- rank of the algebra
     859
     860    - ``q``-- the deformation parameter `q`
    774861
    775862    OPTIONAL ARGUMENTS:
    776863
    777      -``base_ring``-- a ring containing q (default q.parent())
    778      -``prefix``-- a label for the basis elements (default "T")
     864    - ``base_ring``-- (default ``None``) a ring containing ``q``; if ``None``
     865      then just takes the parent of ``q``
    779866
    780     The Temperley-Lieb algebra of rank k is an algebra with basis indexed by the
    781     collection of set partitions of `\{1, \dots, k, -1, \dots, -k\}`
    782     with block size 2 and each set partition is planar.
    783     This algebra is thus a subalgebra of the partition algebra. For more
    784     information, see :class:`PartitionAlgebra`
     867    - ``prefix``-- (default ``"T"``) a label for the basis elements
    785868
    786869    EXAMPLES:
    787870
    788     The following shorthand simultaneously define the univariate polynomial
    789     ring over the rationals as well as the variable `x`::
     871    We define the Temperley--Lieb algebra of rank `2` with parameter
     872    `x` over `\ZZ`::
    790873
    791         sage: R.<x> = PolynomialRing(QQ); R
    792         Univariate Polynomial Ring in x over Rational Field
    793         sage: x
    794         x
    795         sage: x.parent() is R
    796         True
    797 
    798     We now define the Temperley-Lieb algebra of rank `2` with parameter
    799     `x` over the Integer ring::
    800 
    801         sage: T = TemperleyLiebAlgebra(2, x); T
    802         Temperley-Lieb Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Rational Field, with prefix T
    803         sage: T.basis() #random order
     874        sage: R.<x> = ZZ[]
     875        sage: T = TemperleyLiebAlgebra(2, x, R); T
     876        Temperley-Lieb Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring
     877        sage: T.basis()
    804878        Finite family {{{2, -2}, {1, -1}}: T[{{2, -2}, {1, -1}}], {{-2, -1}, {1, 2}}: T[{{-2, -1}, {1, 2}}]}
    805879        sage: b = T.basis().list()
    806         sage: b #random order
     880        sage: b
    807881        [T[{{2, -2}, {1, -1}}], T[{{-2, -1}, {1, 2}}]]
    808882        sage: b[1]
    809883        T[{{-2, -1}, {1, 2}}]
    class TemperleyLiebAlgebra(DiagramAlgebr 
    811885        True
    812886        sage: b[1]^5 == x^4*b[1]
    813887        True
    814 
    815888    """
    816889    @staticmethod
    817890    def __classcall_private__(cls, k, q, base_ring=None, prefix="T"):
    818891        r"""
    819         This method gets the base_ring from the parent of the parameter q
    820         if no base_ring is given.
     892        Standardize the input by getting the base ring from the parent of
     893        the parameter ``q`` if no ``base_ring`` is given.
     894
     895        TESTS::
     896
     897            sage: R.<q> = QQ[]
     898            sage: T1 = TemperleyLiebAlgebra(2, q)
     899            sage: T2 = TemperleyLiebAlgebra(2, q, R, 'T')
     900            sage: T1 is T2
     901            True
    821902        """
    822903        if base_ring is None:
    823904            base_ring = q.parent()
    824         return super(TemperleyLiebAlgebra, cls).__classcall__(cls, k, q=q, base_ring = base_ring, prefix=prefix)
     905        return super(TemperleyLiebAlgebra, cls).__classcall__(cls, k, q, base_ring, prefix)
    825906
    826     def __init__(self, k, q, base_ring, prefix = "T"):
     907    def __init__(self, k, q, base_ring, prefix):
    827908        r"""
    828         See :class:`TemperleyLiebAlgebra` for full documentation.
     909        Initialize ``self``
    829910
    830911        TESTS::
    831912
    832             sage: q = var('q')
    833             sage: TL = TemperleyLiebAlgebra(2, q, RR['q'])
     913            sage: R.<q> = QQ[]
     914            sage: TL = TemperleyLiebAlgebra(2, q, R)
    834915            sage: TestSuite(TL).run()
    835916        """
    836         self._k = k
    837         self._prefix = prefix
    838         self._q = base_ring(q)
     917        SubPartitionAlgebra.__init__(self, k, q, base_ring, prefix, temperley_lieb_diagrams)
     918
     919    def _repr_(self):
     920        """
     921        Return a string represetation of ``self``.
     922
     923        EXAMPLES::
     924
     925            sage: R.<q> = QQ[]
     926            sage: TemperleyLiebAlgebra(2, q, R)
     927            Temperley-Lieb Algebra of rank 2 with parameter q over Univariate Polynomial Ring in q over Rational Field
     928        """
     929        return "Temperley-Lieb Algebra of rank %s with parameter %s over %s"%(self._k,
     930                self._q, self.base_ring())
     931
     932    def _element_constructor_(self, set_partition):
     933        r"""
     934        Construct an element of ``self``.
     935
     936        EXAMPLES::
     937
     938            sage: R.<q> = QQ[]
     939            sage: TL = TemperleyLiebAlgebra(2, q, R)
     940            sage: sp = SetPartition([[1,2], [-1,-2]])
     941            sage: b_elt = TL(sp); b_elt
     942            T[{{-2, -1}, {1, 2}}]
     943            sage: b_elt in TL
     944            True
     945            sage: TL([[1,2],[-1,-2]]) == b_elt
     946            True
     947            sage: TL([{1,2},{-1,-2}]) == b_elt
     948            True
     949        """
     950        set_partition = to_Brauer_partition(set_partition, k = self.order())
     951        return SubPartitionAlgebra._element_constructor_(self, set_partition)
     952
     953class PlanarAlgebra(SubPartitionAlgebra):
     954    """
     955    A planar algebra.
     956
     957    The planar algebra of rank `k` is an algebra with basis indexed by the
     958    collection of set partitions of `\{1, \ldots, k, -1, \ldots, -k\}`
     959    where each set partition is planar.
     960
     961    This algebra is thus a subalgebra of the partition algebra. For more
     962    information, see :class:`PartitionAlgebra`.
     963
     964    INPUT:
     965
     966    - ``k``-- rank of the algebra
     967
     968    - ``q``-- the deformation parameter `q`
     969
     970    OPTIONAL ARGUMENTS:
     971
     972    - ``base_ring``-- (default ``None``) a ring containing ``q``; if ``None``
     973      then just takes the parent of ``q``
     974
     975    - ``prefix``-- (default ``"Pl"``) a label for the basis elements
     976
     977    EXAMPLES:
     978
     979    We now define the planar algebra of rank `2` with parameter
     980    `x` over `\ZZ`::
     981
     982        sage: R.<x> = ZZ[]
     983        sage: Pl = PlanarAlgebra(2, x, R); Pl
     984        Planar Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring
     985        sage: Pl.basis().list()
     986        [Pl[{{1, 2, -2, -1}}], Pl[{{2, -2, -1}, {1}}],
     987         Pl[{{1, -2, -1}, {2}}], Pl[{{-2}, {1, 2, -1}}],
     988         Pl[{{1, 2, -2}, {-1}}], Pl[{{2, -2}, {1, -1}}],
     989         Pl[{{-2, -1}, {1, 2}}], Pl[{{-2, -1}, {1}, {2}}],
     990         Pl[{{-2}, {2, -1}, {1}}], Pl[{{2, -2}, {-1}, {1}}],
     991         Pl[{{-2}, {1, -1}, {2}}], Pl[{{1, -2}, {-1}, {2}}],
     992         Pl[{{-2}, {-1}, {1, 2}}], Pl[{{-2}, {-1}, {1}, {2}}]]
     993        sage: E = Pl([[1,2],[-1,-2]])
     994        sage: E^2 == x*E
     995        True
     996        sage: E^5 == x^4*E
     997        True
     998    """
     999    @staticmethod
     1000    def __classcall_private__(cls, k, q, base_ring=None, prefix="Pl"):
     1001        r"""
     1002        Standardize the input by getting the base ring from the parent of
     1003        the parameter ``q`` if no ``base_ring`` is given.
     1004
     1005        TESTS::
     1006
     1007            sage: R.<q> = QQ[]
     1008            sage: Pl1 = PlanarAlgebra(2, q)
     1009            sage: Pl2 = PlanarAlgebra(2, q, R, 'Pl')
     1010            sage: Pl1 is Pl2
     1011            True
     1012        """
     1013        if base_ring is None:
     1014            base_ring = q.parent()
     1015        return super(PlanarAlgebra, cls).__classcall__(cls, k, q, base_ring, prefix)
     1016
     1017    def __init__(self, k, q, base_ring, prefix):
     1018        r"""
     1019        Initialize ``self``.
     1020
     1021        TESTS::
     1022
     1023            sage: R.<q> = QQ[]
     1024            sage: PlA = PlanarAlgebra(2, q, R)
     1025            sage: TestSuite(PlA).run()
     1026        """
     1027        SubPartitionAlgebra.__init__(self, k, q, base_ring, prefix, planar_diagrams)
     1028
     1029    def _repr_(self):
     1030        """
     1031        Return a string representation of ``self``.
     1032
     1033        EXAMPLES::
     1034
     1035            sage: R.<x> = ZZ[]
     1036            sage: Pl = PlanarAlgebra(2, x, R); Pl
     1037            Planar Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Integer Ring
     1038        """
     1039        return "Planar Algebra of rank %s with parameter %s over %s"%(self._k,
     1040                self._q, self.base_ring())
     1041
     1042class PropagatingIdeal(SubPartitionAlgebra):
     1043    r"""
     1044    A propagating ideal.
     1045
     1046    The propagating ideal of rank `k` is a non-unital algebra with basis
     1047    indexed by the collection of ideal set partitions of `\{1, \ldots, k, -1,
     1048    \ldots, -k\}`. We say a set partition is *ideal* if its propagating
     1049    number is less than `k`.
     1050
     1051    This algebra is thus a subalgebra of the partition algebra.
     1052    For more information, see :class:`PartitionAlgebra`.
     1053
     1054    EXAMPLES:
     1055
     1056    We now define the propagating ideal of rank `2` with parameter
     1057    `x` over `\ZZ`::
     1058
     1059        sage: R.<x> = QQ[]
     1060        sage: I = PropagatingIdeal(2, x, R); I
     1061        Propagating Ideal of rank 2 with parameter x over Univariate Polynomial Ring in x over Rational Field
     1062        sage: I.basis().list()
     1063        [I[{{1, 2, -2, -1}}], I[{{2, -2, -1}, {1}}],
     1064         I[{{1, -2, -1}, {2}}], I[{{-2}, {1, 2, -1}}],
     1065         I[{{1, 2, -2}, {-1}}], I[{{-2, -1}, {1, 2}}],
     1066         I[{{-2, -1}, {1}, {2}}], I[{{-2}, {2, -1}, {1}}],
     1067         I[{{2, -2}, {-1}, {1}}], I[{{-2}, {1, -1}, {2}}],
     1068         I[{{1, -2}, {-1}, {2}}], I[{{-2}, {-1}, {1, 2}}],
     1069         I[{{-2}, {-1}, {1}, {2}}]]
     1070        sage: E = I([[1,2],[-1,-2]])
     1071        sage: E^2 == x*E
     1072        True
     1073        sage: E^5 == x^4*E
     1074        True
     1075    """
     1076    @staticmethod
     1077    def __classcall_private__(cls, k, q, base_ring=None, prefix="I"):
     1078        r"""
     1079        Standardize the input by getting the base ring from the parent of
     1080        the parameter ``q`` if no ``base_ring`` is given.
     1081
     1082        TESTS::
     1083
     1084            sage: R.<q> = QQ[]
     1085            sage: IA1 = PropagatingIdeal(2, q)
     1086            sage: IA2 = PropagatingIdeal(2, q, R, 'I')
     1087            sage: IA1 is IA2
     1088            True
     1089        """
     1090        if base_ring is None:
     1091            base_ring = q.parent()
     1092        return super(PropagatingIdeal, cls).__classcall__(cls, k, q, base_ring, prefix)
     1093
     1094    def __init__(self, k, q, base_ring, prefix):
     1095        r"""
     1096        Initialize ``self``.
     1097
     1098        TESTS::
     1099
     1100            sage: R.<q> = QQ[]
     1101            sage: I = PropagatingIdeal(2, q, R)
     1102            sage: TestSuite(I).run() # Not tested -- needs non-unital algebras category
     1103        """
     1104        # This should be the category of non-unital fin-dim algebras with basis
    8391105        category = FiniteDimensionalAlgebrasWithBasis(base_ring)
    840         DiagramAlgebra.__init__(self, q, base_ring, prefix, temperley_lieb_diagrams(k))
     1106        SubPartitionAlgebra.__init__(self, k, q, base_ring, prefix, ideal_diagrams, category)
    8411107
    8421108    @cached_method
    8431109    def one_basis(self):
    8441110        r"""
    845         The following constructs the identity element of the
    846         Temperley-Lieb algebra. It is not called directly;
    847         instead one should use TL.one() if TL is a
    848         previously defined Temperley-Lieb algebra instance.
     1111        The propagating ideal is a non-unital algebra, i.e. it does not have a
     1112        multiplicative identity.
    8491113
    8501114        EXAMPLES::
    8511115
    852             sage: TL = TemperleyLiebAlgebra(2, x);
    853             sage: TL.one_basis()
    854             {{2, -2}, {1, -1}}
    855             sage: TL.one()
    856             T[{{2, -2}, {1, -1}}]
    857 
     1116            sage: R.<q> = QQ[]
     1117            sage: I = PropagatingIdeal(2, q, R)
     1118            sage: I.one_basis()
     1119            Traceback (most recent call last):
     1120            ...
     1121            ValueError: The ideal partition algebra is not unital
     1122            sage: I.one()
     1123            Traceback (most recent call last):
     1124            ...
     1125            ValueError: The ideal partition algebra is not unital
    8581126        """
    859         return identity_set_partition(self._k)
     1127        raise ValueError("The ideal partition algebra is not unital")
     1128        #return identity_set_partition(self._k)
    8601129
    8611130    def _repr_(self):
    862         msg = "Temperley-Lieb Algebra of rank %s with parameter %s over %s, with prefix %s"
    863         return msg % (self._k, self._q, self.base_ring(), self._prefix)
    864 
    865     def _element_constructor_(self, set_partition):
    866         r"""
    867         If TL is a particular Temperley-Lieb algebra (previously defined)
    868         then TL( sp ) returns the element of the algebra TL corresponding
    869         to a given set partition sp.
     1131        """
     1132        Return a string representation of ``self``.
    8701133
    8711134        EXAMPLES::
    8721135
    873             sage: q = var('q')
    874             sage: TL = TemperleyLiebAlgebra(2,q,QQ['q'])
    875             sage: TL
    876             Temperley-Lieb Algebra of rank 2 with parameter q over Univariate Polynomial Ring in q over Rational Field, with prefix T
    877             sage: import sage.combinat.diagram_algebras as da
    878             sage: sp = da.to_set_partition( [[1,2], [-1,-2]] )  # create a set partition
    879             sage: sp
    880             {{-1, -2}, {1, 2}}
    881             sage: TL(sp)  # construct a basis element from it
    882             T[{{-2, -1}, {1, 2}}]
    883             sage: TL(sp) in TL
    884             True
    885             sage: TL([[1,2],[-1,-2]]) #random order
    886             T[{{-1, -2}, {1, 2}}]
    887             sage: TL([{1,2},{-1,-2}]) #random order
    888             T[{{-1, -2}, {1, 2}}]
     1136            sage: R.<x> = QQ[]
     1137            sage: PropagatingIdeal(2, x, R)
     1138            Propagating Ideal of rank 2 with parameter x over Univariate Polynomial Ring in x over Rational Field
    8891139        """
    890         set_partition = to_Brauer_partition(set_partition, k = self.order())
    891         return DiagramAlgebra._element_constructor_(self, set_partition)
     1140        return "Propagating Ideal of rank %s with parameter %s over %s"%(self._k,
     1141                self._q, self.base_ring())
    8921142
    893     def ambient(self):
    894         r"""
    895         ambient returns the partition algebra the Temperley-Lieb algebra
    896         is a sub-algebra of. Generally, this method is not called
    897         directly.
     1143    class Element(SubPartitionAlgebra.Element):
     1144        """
     1145        Need to take care of exponents since we are not unital.
     1146        """
     1147        def __pow__(self, n):
     1148            """
     1149            Return ``self`` to the `n`-th power.
    8981150
    899         EXAMPLES::
    900             sage: TL = TemperleyLiebAlgebra(2, x);
    901             sage: P = TL.ambient()
    902             sage: P
    903             Partition Algebra of rank 2 with parameter x over Symbolic Ring, with prefix T
    904         """
    905         return PartitionAlgebra(self._k, self._q, self.base_ring(), prefix=self._prefix)
    906     def lift(self, x):
    907         r"""
    908         lift maps a Temperley-Lieb algebra element to the corresponding
    909         element in the ambient space. This method is not intended
    910         to be called directly.
     1151            INPUT::
    9111152
    912         EXAMPLES::
    913             sage: TL = TemperleyLiebAlgebra(2, x);
    914             sage: E = TL([[1,2],[-1,-2]]);
    915             sage: TL.lift(E) in TL.ambient()
    916             True
    917             sage: TL.lift(E) in TL
    918             False
    919         """
    920         assert x in self
    921         monomial_indices = x.support()
    922         monomial_coefficients = x.coefficients()
    923         result = 0
    924         for i in xrange(len(monomial_coefficients)):
    925             result += monomial_coefficients[i]*self.ambient().monomial(monomial_indices[i])
    926         return result
     1153            - ``n`` -- a positive integer
    9271154
    928     def retract(self, x):
    929         r"""
    930         retract maps an appropriate partition algebra element to the
    931         corresponding element in the Temperley-Lieb algebra. This method
    932         is not intended to be called directly.
     1155            EXAMPLES::
    9331156
    934         EXAMPLES::
    935             sage: TL = TemperleyLiebAlgebra(2, x)
    936             sage: PA = TL.ambient()
    937             sage: E = PA([[1,2],[-1,-2]])
    938             sage: TL.retract(E) in PA
    939             False
    940             sage: TL.retract(E) in TL
    941             True
    942         """
    943         assert x in self.ambient() and set(x.support()).issubset(set(self.basis().keys()))
    944         monomial_indices = x.support()
    945         monomial_coefficients = x.coefficients()
    946         result = self.zero()
    947         for i in xrange(len(monomial_coefficients)):
    948             result += monomial_coefficients[i]*self.monomial(monomial_indices[i])
    949         return result
    950 
    951     def order(self):
    952         r"""
    953         Returns the order of the Temperley-Lieb Algebra
    954         EXAMPLES::
    955             sage: TL = TemperleyLiebAlgebra(2, x)
    956             sage: TL.order()
    957             2
    958         """
    959         return self.ambient().order()
    960 
    961 class PlanarAlgebra(DiagramAlgebra):
    962     r"""
    963     INPUT:
    964 
    965      -``k``-- rank of the algebra (equals half the number of nodes in the diagrams)
    966      -``q``-- a parameter.
    967 
    968     OPTIONAL ARGUMENTS:
    969 
    970      -``base_ring``-- a ring containing q (default q.parent())
    971      -``prefix``-- a label for the basis elements (default "Pl")
    972 
    973     The Planar algebra of rank k is an algebra with basis indexed by the
    974     collection of set partitions of `\{1, \dots, k, -1, \dots, -k\}`
    975     where each set partition is planar.
    976     This algebra is thus a subalgebra of the partition algebra. For more
    977     information, see :class:`PartitionAlgebra`
    978 
    979     EXAMPLES:
    980 
    981     The following shorthand simultaneously define the univariate polynomial
    982     ring over the rationals as well as the variable `x`::
    983 
    984         sage: R.<x> = PolynomialRing(QQ); R
    985         Univariate Polynomial Ring in x over Rational Field
    986         sage: x
    987         x
    988         sage: x.parent() is R
    989         True
    990 
    991     We now define the Temperley-Lieb algebra of rank `2` with parameter
    992     `x` over the Integer ring::
    993 
    994         sage: Pl = PlanarAlgebra(2, x); Pl
    995         Planar Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Rational Field, with prefix Pl
    996         sage: Pl.basis() #random order
    997         Finite family {{{1, 2, -1, -2}}: Pl[{{1, 2, -1, -2}}], {{-1}, {2, -2}, {1}}: Pl[{{-1}, {2, -2}, {1}}], {{2, -1, -2}, {1}}: Pl[{{2, -1, -2}, {1}}], {{2}, {1, -1, -2}}: Pl[{{2}, {1, -1, -2}}], {{-2}, {1, 2, -1}}: Pl[{{-2}, {1, 2, -1}}], {{-1}, {2}, {1, -2}}: Pl[{{-1}, {2}, {1, -2}}], {{-2}, {2}, {1, -1}}: Pl[{{-2}, {2}, {1, -1}}], {{-1, -2}, {1, 2}}: Pl[{{-1, -2}, {1, 2}}], {{-1}, {-2}, {2}, {1}}: Pl[{{-1}, {-2}, {2}, {1}}], {{2}, {-1, -2}, {1}}: Pl[{{2}, {-1, -2}, {1}}], {{-1}, {1, 2, -2}}: Pl[{{-1}, {1, 2, -2}}], {{2, -2}, {1, -1}}: Pl[{{2, -2}, {1, -1}}], {{-1}, {-2}, {1, 2}}: Pl[{{-1}, {-2}, {1, 2}}], {{-2}, {2, -1}, {1}}: Pl[{{-2}, {2, -1}, {1}}]}
    998         sage: b = Pl.basis().list()
    999         sage: b #random order
    1000         [Pl[{{1, 2, -1, -2}}], Pl[{{2, -1, -2}, {1}}], Pl[{{2}, {1, -1, -2}}], Pl[{{-1}, {1, 2, -2}}], Pl[{{-2}, {1, 2, -1}}], Pl[{{-1, -2}, {1, 2}}], Pl[{{2, -2}, {1, -1}}], Pl[{{2}, {-1, -2}, {1}}], Pl[{{-1}, {2, -2}, {1}}], Pl[{{-2}, {2, -1}, {1}}], Pl[{{-1}, {2}, {1, -2}}], Pl[{{-2}, {2}, {1, -1}}], Pl[{{-1}, {-2}, {1, 2}}], Pl[{{-1}, {-2}, {2}, {1}}]]
    1001         sage: E = Pl([[1,2],[-1,-2]]);
    1002         sage: E^2 == x*E
    1003         True
    1004         sage: E^5 == x^4*E
    1005         True
    1006 
    1007     """
    1008     @staticmethod
    1009     def __classcall_private__(cls, k, q, base_ring=None, prefix="Pl"):
    1010         r"""
    1011         This method gets the base_ring from the parent of the parameter q
    1012         if no base_ring is given.
    1013         """
    1014         if base_ring is None:
    1015             base_ring = q.parent()
    1016         return super(PlanarAlgebra, cls).__classcall__(cls, k, q=q, base_ring = base_ring, prefix=prefix)
    1017 
    1018     def __init__(self, k, q, base_ring, prefix = "Pl"):
    1019         r"""
    1020         See :class:`PlanarAlgebra` for full documentation.
    1021 
    1022         TESTS::
    1023 
    1024             sage: q = var('q')
    1025             sage: PlA = PlanarAlgebra(2, q, RR['q'])
    1026             sage: TestSuite(PlA).run()
    1027         """
    1028         self._k = k
    1029         self._prefix = prefix
    1030         self._q = base_ring(q)
    1031         category = FiniteDimensionalAlgebrasWithBasis(base_ring)
    1032         DiagramAlgebra.__init__(self, q, base_ring, prefix, planar_diagrams(k))
    1033 
    1034     @cached_method
    1035     def one_basis(self):
    1036         r"""
    1037         The following constructs the identity element of the
    1038         Temperley-Lieb algebra. It is not called directly;
    1039         instead one should use TL.one() if TL is a
    1040         previously defined Temperley-Lieb algebra instance.
    1041 
    1042         EXAMPLES::
    1043 
    1044             sage: PlA = PlanarAlgebra(2, x);
    1045             sage: PlA.one_basis()
    1046             {{2, -2}, {1, -1}}
    1047             sage: PlA.one()
    1048             Pl[{{2, -2}, {1, -1}}]
    1049 
    1050         """
    1051         return identity_set_partition(self._k)
    1052 
    1053     def _repr_(self):
    1054         msg = "Planar Algebra of rank %s with parameter %s over %s, with prefix %s"
    1055         return msg % (self._k, self._q, self.base_ring(), self._prefix)
    1056 
    1057     def ambient(self):
    1058         r"""
    1059         ambient returns the partition algebra the Planar algebra
    1060         is a sub-algebra of. Generally, this method is not called
    1061         directly.
    1062 
    1063         EXAMPLES::
    1064             sage: PlA = PlanarAlgebra(2, x);
    1065             sage: P = PlA.ambient()
    1066             sage: P
    1067             Partition Algebra of rank 2 with parameter x over Symbolic Ring, with prefix Pl
    1068         """
    1069         return PartitionAlgebra(self._k, self._q, self.base_ring(), prefix=self._prefix)
    1070     def lift(self, x):
    1071         r"""
    1072         lift maps a Planar algebra element to the corresponding
    1073         element in the ambient space. This method is not intended
    1074         to be called directly.
    1075 
    1076         EXAMPLES::
    1077             sage: PlA = PlanarAlgebra(2, x);
    1078             sage: E = PlA([[1,2],[-1,-2]]);
    1079             sage: PlA.lift(E) in PlA.ambient()
    1080             True
    1081             sage: PlA.lift(E) in PlA
    1082             False
    1083         """
    1084         assert x in self
    1085         monomial_indices = x.support()
    1086         monomial_coefficients = x.coefficients()
    1087         result = 0
    1088         for i in xrange(len(monomial_coefficients)):
    1089             result += monomial_coefficients[i]*self.ambient().monomial(monomial_indices[i])
    1090         return result
    1091 
    1092     def retract(self, x):
    1093         r"""
    1094         retract maps an appropriate partition algebra element to the
    1095         corresponding element in the planar algebra. This method
    1096         is not intended to be called directly.
    1097 
    1098         EXAMPLES::
    1099             sage: PlA = PlanarAlgebra(2, x)
    1100             sage: PA = PlA.ambient()
    1101             sage: E = PA([[1,2],[-1,-2]])
    1102             sage: PlA.retract(E) in PA
    1103             False
    1104             sage: PlA.retract(E) in PlA
    1105             True
    1106         """
    1107         assert x in self.ambient() and set(x.support()).issubset(set(self.basis().keys()))
    1108         monomial_indices = x.support()
    1109         monomial_coefficients = x.coefficients()
    1110         result = self.zero()
    1111         for i in xrange(len(monomial_coefficients)):
    1112             result += monomial_coefficients[i]*self.monomial(monomial_indices[i])
    1113         return result
    1114 
    1115     def order(self):
    1116         r"""
    1117         Returns the order of the Planar Algebra
    1118         EXAMPLES::
    1119             sage: PlA = PlanarAlgebra(2, x)
    1120             sage: PlA.order()
    1121             2
    1122         """
    1123         return self.ambient().order()
    1124 
    1125 class IdealAlgebra(DiagramAlgebra):
    1126     r"""
    1127     INPUT:
    1128 
    1129      -``k``-- rank of the algebra (equals half the number of nodes in the diagrams)
    1130      -``q``-- a parameter.
    1131 
    1132     OPTIONAL ARGUMENTS:
    1133 
    1134      -``base_ring``-- a ring containing q (default q.parent())
    1135      -``prefix``-- a label for the basis elements (default "I")
    1136 
    1137     The ideal algebra of rank k is an algebra with basis indexed by the
    1138     collection of set partitions of `\{1, \dots, k, -1, \dots, -k\}`
    1139     where each set partition has propogating number less than `k`.
    1140     This algebra is thus a subalgebra of the partition algebra. For more
    1141     information, see :class:`PartitionAlgebra`
    1142 
    1143     EXAMPLES:
    1144 
    1145     The following shorthand simultaneously define the univariate polynomial
    1146     ring over the rationals as well as the variable `x`::
    1147 
    1148         sage: R.<x> = PolynomialRing(QQ); R
    1149         Univariate Polynomial Ring in x over Rational Field
    1150         sage: x
    1151         x
    1152         sage: x.parent() is R
    1153         True
    1154 
    1155     We now define the Temperley-Lieb algebra of rank `2` with parameter
    1156     `x` over the Integer ring::
    1157 
    1158         sage: I = IdealAlgebra(2, x); I
    1159         Ideal Algebra of rank 2 with parameter x over Univariate Polynomial Ring in x over Rational Field, with prefix I
    1160         sage: I.basis() #random order
    1161         Finite family {{{1, 2, -1, -2}}: I[{{1, 2, -1, -2}}], {{-1}, {2, -2}, {1}}: I[{{-1}, {2, -2}, {1}}], {{2, -1, -2}, {1}}: I[{{2, -1, -2}, {1}}], {{2}, {1, -1, -2}}: I[{{2}, {1, -1, -2}}], {{-2}, {1, 2, -1}}: I[{{-2}, {1, 2, -1}}], {{-1}, {2}, {1, -2}}: I[{{-1}, {2}, {1, -2}}], {{-2}, {2}, {1, -1}}: I[{{-2}, {2}, {1, -1}}], {{-1, -2}, {1, 2}}: I[{{-1, -2}, {1, 2}}], {{-1}, {-2}, {2}, {1}}: I[{{-1}, {-2}, {2}, {1}}], {{2}, {-1, -2}, {1}}: I[{{2}, {-1, -2}, {1}}], {{-1}, {1, 2, -2}}: I[{{-1}, {1, 2, -2}}], {{-1}, {-2}, {1, 2}}: I[{{-1}, {-2}, {1, 2}}], {{-2}, {2, -1}, {1}}: I[{{-2}, {2, -1}, {1}}]}
    1162         sage: b = I.basis().list()
    1163         sage: b #random order
    1164         [I[{{1, 2, -1, -2}}], I[{{2, -1, -2}, {1}}], I[{{2}, {1, -1, -2}}], I[{{-1}, {1, 2, -2}}], I[{{-2}, {1, 2, -1}}], I[{{-1, -2}, {1, 2}}], I[{{2}, {-1, -2}, {1}}], I[{{-1}, {2, -2}, {1}}], I[{{-2}, {2, -1}, {1}}], I[{{-1}, {2}, {1, -2}}], I[{{-2}, {2}, {1, -1}}], I[{{-1}, {-2}, {1, 2}}], I[{{-1}, {-2}, {2}, {1}}]]
    1165         sage: E = I([[1,2],[-1,-2]]);
    1166         sage: E^2 == x*E
    1167         True
    1168         sage: E^5 == x^4*E
    1169         True
    1170 
    1171     """
    1172     @staticmethod
    1173     def __classcall_private__(cls, k, q, base_ring=None, prefix="I"):
    1174         r"""
    1175         This method gets the base_ring from the parent of the parameter q
    1176         if no base_ring is given.
    1177         """
    1178         if base_ring is None:
    1179             base_ring = q.parent()
    1180         return super(IdealAlgebra, cls).__classcall__(cls, k, q=q, base_ring = base_ring, prefix=prefix)
    1181 
    1182     def __init__(self, k, q, base_ring, prefix = "I"):
    1183         r"""
    1184         See :class:`IdealAlgebra` for full documentation.
    1185 
    1186         TESTS::
    1187 
    1188             sage: q = var('q')
    1189             sage: I = IdealAlgebra(2, q, RR['q'])
    1190             sage: TestSuite(I).run()
    1191         """
    1192         self._k = k
    1193         self._prefix = prefix
    1194         self._q = base_ring(q)
    1195         category = FiniteDimensionalAlgebrasWithBasis(base_ring)
    1196         DiagramAlgebra.__init__(self, q, base_ring, prefix, ideal_diagrams(k))
    1197 
    1198     @cached_method
    1199     def one_basis(self):
    1200         r"""
    1201         The following constructs the identity element of the
    1202         Ideal algebra. It is not called directly;
    1203         instead one should use I.one() if I is a
    1204         previously defined Ideal algebra instance.
    1205 
    1206         Technically speaking, the Ideal algebra is an algebra
    1207         without a multiplicative identity. This has to be fixed
    1208         by the creation of a new category, such as
    1209         FiniteDimensionalAlgebraWithBasisWithoutUnity.
    1210 
    1211         TODO:
    1212         Make this method correct.
    1213 
    1214         EXAMPLES::
    1215 
    1216             sage: I = IdealAlgebra(2, x);
    1217             sage: I.one_basis()
    1218             {{2, -2}, {1, -1}}
    1219             sage: I.one()
    1220             I[{{2, -2}, {1, -1}}]
    1221 
    1222         """
    1223         return identity_set_partition(self._k)
    1224 
    1225     def _repr_(self):
    1226         msg = "Ideal Algebra of rank %s with parameter %s over %s, with prefix %s"
    1227         return msg % (self._k, self._q, self.base_ring(), self._prefix)
    1228 
    1229     def ambient(self):
    1230         r"""
    1231         ambient returns the partition algebra the Ideal algebra
    1232         is a sub-algebra of. Generally, this method is not called
    1233         directly.
    1234 
    1235         EXAMPLES::
    1236             sage: I = IdealAlgebra(2, x);
    1237             sage: P = I.ambient()
    1238             sage: P
    1239             Partition Algebra of rank 2 with parameter x over Symbolic Ring, with prefix I
    1240         """
    1241         return PartitionAlgebra(self._k, self._q, self.base_ring(), prefix=self._prefix)
    1242     def lift(self, x):
    1243         r"""
    1244         lift maps a Ideal algebra element to the corresponding
    1245         element in the ambient space. This method is not intended
    1246         to be called directly.
    1247 
    1248         EXAMPLES::
    1249             sage: I = IdealAlgebra(2, x);
    1250             sage: E = I([[1,2],[-1,-2]]);
    1251             sage: I.lift(E) in I.ambient()
    1252             True
    1253             sage: I.lift(E) in I
    1254             False
    1255         """
    1256         assert x in self
    1257         monomial_indices = x.support()
    1258         monomial_coefficients = x.coefficients()
    1259         result = 0
    1260         for i in xrange(len(monomial_coefficients)):
    1261             result += monomial_coefficients[i]*self.ambient().monomial(monomial_indices[i])
    1262         return result
    1263 
    1264     def retract(self, x):
    1265         r"""
    1266         retract maps an appropriate partition algebra element to the
    1267         corresponding element in the Ideal algebra. This method
    1268         is not intended to be called directly.
    1269 
    1270         EXAMPLES::
    1271             sage: I = IdealAlgebra(2, x)
    1272             sage: PA = I.ambient()
    1273             sage: E = PA([[1,2],[-1,-2]])
    1274             sage: I.retract(E) in PA
    1275             False
    1276             sage: I.retract(E) in I
    1277             True
    1278         """
    1279         assert x in self.ambient() and set(x.support()).issubset(set(self.basis().keys()))
    1280         monomial_indices = x.support()
    1281         monomial_coefficients = x.coefficients()
    1282         result = self.zero()
    1283         for i in xrange(len(monomial_coefficients)):
    1284             result += monomial_coefficients[i]*self.monomial(monomial_indices[i])
    1285         return result
    1286 
    1287     def order(self):
    1288         r"""
    1289         Returns the order of the Temperley-Lieb Algebra
    1290         EXAMPLES::
    1291             sage: I = IdealAlgebra(2, x)
    1292             sage: I.order()
    1293             2
    1294         """
    1295         return self.ambient().order()
     1157                sage: R.<x> = QQ[]
     1158                sage: I = PropagatingIdeal(2, x, R)
     1159                sage: E = I([[1,2],[-1,-2]])
     1160                sage: E^2
     1161                x*I[{{-2, -1}, {1, 2}}]
     1162                sage: E^0
     1163                Traceback (most recent call last):
     1164                ...
     1165                ValueError: can only take positive integer powers
     1166            """
     1167            if n <= 0:
     1168                raise ValueError("can only take positive integer powers")
     1169            return generic_power(self, n)
    12961170
    12971171#########################################################################
    12981172# START BORROWED CODE
    class IdealAlgebra(DiagramAlgebra): 
    13041178
    13051179def is_planar(sp):
    13061180    r"""
    1307     Returns True if the diagram corresponding to the set partition is
    1308     planar; otherwise, it returns False.
     1181    Return ``True`` if the diagram corresponding to the set partition ``sp``
     1182    is planar; otherwise, it return ``False``.
    13091183
    13101184    EXAMPLES::
    13111185
    def is_planar(sp): 
    13221196    n = len(to_consider)
    13231197
    13241198    for i in range(n):
    1325         #Get the positive and negative entries of this
    1326         #part
     1199        #Get the positive and negative entries of this part
    13271200        ap = filter(lambda x: x>0, to_consider[i])
    13281201        an = filter(lambda x: x<0, to_consider[i])
    13291202        an = map(abs, an)
    1330         #print a, ap, an
    1331 
    13321203
    13331204        #Check if a includes numbers in both the top and bottom rows
    13341205        if len(ap) > 0 and len(an) > 0:
    1335 
    13361206            for j in range(n):
    13371207                if i == j:
    13381208                    continue
    def is_planar(sp): 
    13521222                    if min(bn) < min(an):
    13531223                        return False
    13541224
    1355 
    13561225        #Go through the bottom and top rows
    13571226        for row in [ap, an]:
    13581227            if len(row) > 1:
    def is_planar(sp): 
    13611230                    if row[s] + 1 == row[s+1]:
    13621231                        #No gap, continue on
    13631232                        continue
    1364                     else:
    1365                         rng = range(row[s] + 1, row[s+1])
    13661233
    1367                         #Go through and make sure any parts that
    1368                         #contain numbers in this range are completely
    1369                         #contained in this range
    1370                         for j in range(n):
    1371                             if i == j:
    1372                                 continue
     1234                    rng = range(row[s] + 1, row[s+1])
    13731235
    1374                             #Make sure we make the numbers negative again
    1375                             #if we are in the bottom row
    1376                             if row is ap:
    1377                                 sr = Set(rng)
    1378                             else:
    1379                                 sr = Set(map(lambda x: -1*x, rng))
     1236                    #Go through and make sure any parts that
     1237                    #contain numbers in this range are completely
     1238                    #contained in this range
     1239                    for j in range(n):
     1240                        if i == j:
     1241                            continue
    13801242
     1243                        #Make sure we make the numbers negative again
     1244                        #if we are in the bottom row
     1245                        if row is ap:
     1246                            sr = Set(rng)
     1247                        else:
     1248                            sr = Set(map(lambda x: -1*x, rng))
    13811249
    1382                             sj = Set(to_consider[j])
    1383                             intersection = sr.intersection(sj)
    1384                             if intersection:
    1385                                 if sj != intersection:
    1386                                     return False
     1250                        sj = Set(to_consider[j])
     1251                        intersection = sr.intersection(sj)
     1252                        if intersection:
     1253                            if sj != intersection:
     1254                                return False
    13871255
    13881256    return True
    13891257
    13901258
    13911259def to_graph(sp):
    13921260    r"""
    1393     Returns a graph representing the set partition sp.
     1261    Return a graph representing the set partition ``sp``.
    13941262
    13951263    EXAMPLES::
    13961264
    def to_graph(sp): 
    13981266        sage: g = da.to_graph( da.to_set_partition([[1,-2],[2,-1]])); g
    13991267        Graph on 4 vertices
    14001268
    1401     ::
    1402 
    1403         sage: g.vertices() #random
    1404         [1, 2, -2, -1]
    1405         sage: g.edges() #random
    1406         [(1, -2, None), (2, -1, None)]
     1269        sage: g.vertices()
     1270        [-2, -1, 1, 2]
     1271        sage: g.edges()
     1272        [(-2, 1, None), (-1, 2, None)]
    14071273    """
    14081274    g = Graph()
    14091275    for part in sp:
    def to_graph(sp): 
    14171283
    14181284def pair_to_graph(sp1, sp2):
    14191285    r"""
    1420     Returns a graph consisting of the graphs of set partitions sp1 and
    1421     sp2 along with edges joining the bottom row (negative numbers) of
    1422     sp1 to the top row (positive numbers) of sp2.
     1286    Return a graph consisting of the graphs of set partitions ``sp1`` and
     1287    ``sp2`` along with edges joining the bottom row (negative numbers) of
     1288    ``sp1`` to the top row (positive numbers) of ``sp2``.
    14231289
    14241290    EXAMPLES::
    14251291
    def pair_to_graph(sp1, sp2): 
    14291295        sage: g = da.pair_to_graph( sp1, sp2 ); g
    14301296        Graph on 8 vertices
    14311297
    1432     ::
    1433 
    1434         sage: g.vertices() #random
    1435         [(1, 2), (-1, 1), (-2, 2), (-1, 2), (-2, 1), (2, 1), (2, 2), (1, 1)]
    1436         sage: g.edges() #random
    1437         [((1, 2), (-1, 1), None),
    1438          ((1, 2), (-2, 2), None),
    1439          ((-1, 1), (2, 1), None),
    1440          ((-1, 2), (2, 2), None),
    1441          ((-2, 1), (1, 1), None),
    1442          ((-2, 1), (2, 2), None)]
     1298        sage: g.vertices()
     1299        [(-2, 1), (-2, 2), (-1, 1), (-1, 2), (1, 1), (1, 2), (2, 1), (2, 2)]
     1300        sage: g.edges()
     1301        [((-2, 1), (1, 1), None), ((-2, 1), (2, 2), None),
     1302         ((-2, 2), (1, 2), None), ((-1, 1), (1, 2), None),
     1303         ((-1, 1), (2, 1), None), ((-1, 2), (2, 2), None)]
    14431304    """
    14441305    g = Graph()
    14451306
    def pair_to_graph(sp1, sp2): 
    14511312
    14521313            #Add the edge to the second part of the graph
    14531314            if part_list[0] < 0 and len(part_list) > 1:
    1454                 g.add_edge( (part_list[0], 1), (abs(part_list[0]),2)  )
     1315                g.add_edge( (part_list[0], 1), (abs(part_list[0]), 2)  )
    14551316
    14561317        for i in range(1, len(part_list)):
    14571318            g.add_vertex( (part_list[i],1) )
    def pair_to_graph(sp1, sp2): 
    14761337
    14771338def propagating_number(sp):
    14781339    r"""
    1479     Returns the propagating number of the set partition sp. The
    1480     propagating number is the number of blocks with both a positive and
     1340    Return the propagating number of the set partition ``sp``.
     1341
     1342    The propagating number is the number of blocks with both a positive and
    14811343    negative number.
    14821344
    14831345    EXAMPLES::
    def propagating_number(sp): 
    14961358            pn += 1
    14971359    return pn
    14981360
    1499 # def to_set_partition(l):
    1500 #     return SetPartition(l)
    1501 
    1502 def to_set_partition(l,k=None): #deprecated
     1361def to_set_partition(l, k=None):
    15031362    r"""
    1504     Converts a list of a list of numbers to a set partitions. Each list
     1363    Convert a list of a list of numbers to a set partitions. Each list
    15051364    of numbers in the outer list specifies the numbers contained in one
    15061365    of the blocks in the set partition.
    15071366
    1508     If k is specified, then the set partition will be a set partition
    1509     of 1, ..., k, -1, ..., -k. Otherwise, k will default to the minimum
    1510     number needed to contain all of the specified numbers.
     1367    If `k` is specified, then the set partition will be a set partition
     1368    of `\{1, \ldots, k, -1, \ldots, -k\}`. Otherwise, `k` will default to
     1369    the minimum number needed to contain all of the specified numbers.
    15111370
    15121371    EXAMPLES::
    15131372
    1514         sage: import sage.combinat.diagram_algebras as da #TODO: change this
     1373        sage: import sage.combinat.diagram_algebras as da
    15151374        sage: da.to_set_partition([[1,-1],[2,-2]]) == da.identity_set_partition(2)
    15161375        True
    15171376    """
    def to_set_partition(l,k=None): #depreca 
    15331392        sp.append(Set([singleton]))
    15341393
    15351394    return SetPartition(sp)
    1536 def to_Brauer_partition(l,k=None): #Not borrowed
     1395
     1396def to_Brauer_partition(l, k=None):
    15371397    r"""
    1538     Works like to_set_partition but assumes ommitted elements are
     1398    Same as :func:`to_set_partition` but assumes omitted elements are
    15391399    connected straight through.
    15401400
    15411401    EXAMPLES::
    def to_Brauer_partition(l,k=None): #Not  
    15741434
    15751435def identity_set_partition(k):
    15761436    """
    1577     Returns the identity set partition 1, -1, ..., k, -k
     1437    Return the identity set partition `\{\{1, -1\}, \ldots, \{k, -k\}\}`
    15781438
    15791439    EXAMPLES::
    15801440
    15811441        sage: import sage.combinat.diagram_algebras as da
    1582         sage: da.identity_set_partition(2) #random order
     1442        sage: da.identity_set_partition(2)
    15831443        {{2, -2}, {1, -1}}
    15841444    """
    1585     if k == int(k):
     1445    if k in ZZ:
    15861446        return SetPartition( [[i,-i] for i in range(1, k + 1)] )
    1587     if k - math.floor(k) == 0.5:
    1588         return SetPartition( [[i, -i] for i in range(1, k + 1.5)] )
     1447    # Else k in 1/2 ZZ
     1448    return SetPartition( [[i, -i] for i in range(1, k + ZZ(3)/ZZ(2))] )
    15891449
    15901450def set_partition_composition(sp1, sp2):
    15911451    r"""
    1592     Returns a tuple consisting of the composition of the set partitions
    1593     sp1 and sp2 and the number of components removed from the middle
     1452    Return a tuple consisting of the composition of the set partitions
     1453    ``sp1`` and ``sp2`` and the number of components removed from the middle
    15941454    rows of the graph.
    15951455
    15961456    EXAMPLES::
    def set_partition_composition(sp1, sp2): 
    16161476        else:
    16171477            res.append( Set(map(lambda x: x[0], new_cc)) )
    16181478
    1619 
    1620     return ( SetPartition(Set(res)), total_removed )
     1479    return (SetPartition(Set(res)), total_removed)
    16211480
    16221481##########################################################################
    16231482# END BORROWED CODE