Set partitions - Combinatorics

Skip to content
Back to top
View this page
Edit this page

# Set partitions

This module defines a class for immutable partitioning of a set. For mutable version see `DisjointSet()`.

AUTHORS:

- Mike Hansen

- MuPAD-Combinat developers (for algorithms and design inspiration).

- Travis Scrimshaw (2013-02-28): Removed `CombinatorialClass` and added entry point through `SetPartition`.

- Martin Rubey (2017-10-10): Cleanup, add crossings and nestings, add random generation.

class sage.combinat.set_partition.AbstractSetPartition

  Bases: `ClonableArray`

  Methods of set partitions which are independent of the base set

  base_set()

    Return the base set of `self`, which is the union of all parts of `self`.

    EXAMPLES:

    Sage

        sage: SetPartition([[1], [2,3], [4]]).base_set()
        {1, 2, 3, 4}
        sage: SetPartition([[1,2,3,4]]).base_set()
        {1, 2, 3, 4}
        sage: SetPartition([]).base_set()
        {}

    Python

        >>> from sage.all import *
        >>> SetPartition([[Integer(1)], [Integer(2),Integer(3)], [Integer(4)]]).base_set()
        {1, 2, 3, 4}
        >>> SetPartition([[Integer(1),Integer(2),Integer(3),Integer(4)]]).base_set()
        {1, 2, 3, 4}
        >>> SetPartition([]).base_set()
        {}

  base_set_cardinality()

    Return the cardinality of the base set of `self`, which is the sum of the sizes of the parts of `self`.

    This is also known as the size (sometimes the weight) of a set partition.

    EXAMPLES:

    Sage

        sage: SetPartition([[1], [2,3], [4]]).base_set_cardinality()
        4
        sage: SetPartition([[1,2,3,4]]).base_set_cardinality()
        4

    Python

        >>> from sage.all import *
        >>> SetPartition([[Integer(1)], [Integer(2),Integer(3)], [Integer(4)]]).base_set_cardinality()
        4
        >>> SetPartition([[Integer(1),Integer(2),Integer(3),Integer(4)]]).base_set_cardinality()
        4

  coarsenings()

    Return a list of coarsenings of `self`.

    See also

    `refinements()`

    EXAMPLES:

    Sage

        sage: SetPartition([[1,3],[2,4]]).coarsenings()
        [{{1, 2, 3, 4}}, {{1, 3}, {2, 4}}]
        sage: SetPartition([[1],[2,4],[3]]).coarsenings()
        [{{1, 2, 3, 4}},
         {{1, 2, 4}, {3}},
         {{1, 3}, {2, 4}},
         {{1}, {2, 3, 4}},
         {{1}, {2, 4}, {3}}]
        sage: SetPartition([]).coarsenings()
        [{}]

    Python

        >>> from sage.all import *
        >>> SetPartition([[Integer(1),Integer(3)],[Integer(2),Integer(4)]]).coarsenings()
        [{{1, 2, 3, 4}}, {{1, 3}, {2, 4}}]
        >>> SetPartition([[Integer(1)],[Integer(2),Integer(4)],[Integer(3)]]).coarsenings()
        [{{1, 2, 3, 4}},
         {{1, 2, 4}, {3}},
         {{1, 3}, {2, 4}},
         {{1}, {2, 3, 4}},
         {{1}, {2, 4}, {3}}]
        >>> SetPartition([]).coarsenings()
        [{}]

  conjugate()

    An involution exchanging singletons and circular adjacencies.

    This method implements the definition of the conjugate of a set partition defined in [Cal2005].

    INPUT:

    - `self` – set partition of an ordered set

    OUTPUT: a set partition

    EXAMPLES:

    Sage

        sage: SetPartition([[1,6,7],[2,8],[3,4,5]]).conjugate()
        {{1, 4, 7}, {2, 8}, {3}, {5}, {6}}
        sage: all(sp.conjugate().conjugate()==sp for sp in SetPartitions([1,3,5,7]))
        True
        sage: SetPartition([]).conjugate()
        {}

    Python

        >>> from sage.all import *
        >>> SetPartition([[Integer(1),Integer(6),Integer(7)],[Integer(2),Integer(8)],[Integer(3),Integer(4),Integer(5)]]).conjugate()
        {{1, 4, 7}, {2, 8}, {3}, {5}, {6}}
        >>> all(sp.conjugate().conjugate()==sp for sp in SetPartitions([Integer(1),Integer(3),Integer(5),Integer(7)]))
        True
        >>> SetPartition([]).conjugate()
        {}

  inf(other)

    The product of the set partitions `self` and `other`.

    The product of two set partitions \(B\) and \(C\) is defined as the set partition whose parts are the nonempty intersections between each part of \(B\) and each part of \(C\). This product is also the infimum of \(B\) and \(C\) in the classical set partition lattice (that is, the coarsest set partition which is finer than each of \(B\) and \(C\)). Consequently, `inf` acts as an alias for this method.

    See also

    `sup()`

    EXAMPLES:

    Sage

        sage: x = SetPartition([ [1,2], [3,5,4] ])
        sage: y = SetPartition(( (3,1,2), (5,4) ))
        sage: x * y
        {{1, 2}, {3}, {4, 5}}

        sage: S = SetPartitions(4)
        sage: sp1 = S([[2,3,4], [1]])
        sage: sp2 = S([[1,3], [2,4]])
        sage: s = S([[2,4], [3], [1]])
        sage: sp1.inf(sp2) == s
        True

    Python

        >>> from sage.all import *
        >>> x = SetPartition([ [Integer(1),Integer(2)], [Integer(3),Integer(5),Integer(4)] ])
        >>> y = SetPartition(( (Integer(3),Integer(1),Integer(2)), (Integer(5),Integer(4)) ))
        >>> x * y
        {{1, 2}, {3}, {4, 5}}

        >>> S = SetPartitions(Integer(4))
        >>> sp1 = S([[Integer(2),Integer(3),Integer(4)], [Integer(1)]])
        >>> sp2 = S([[Integer(1),Integer(3)], [Integer(2),Integer(4)]])
        >>> s = S([[Integer(2),Integer(4)], [Integer(3)], [Integer(1)]])
        >>> sp1.inf(sp2) == s
        True

  max_block_size()

    The maximum block size of the diagram.

    EXAMPLES:

    Sage

        sage: # needs sage.modules
        sage: from sage.combinat.diagram_algebras import PartitionDiagram, PartitionDiagrams
        sage: pd = PartitionDiagram([[1,-3,-5],[2,4],[3,-1,-2],[5],[-4]])
        sage: pd.max_block_size()
        3
        sage: sorted(d.max_block_size() for d in PartitionDiagrams(2))
        [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4]
        sage: sorted(sp.max_block_size() for sp in SetPartitions(3))
        [1, 2, 2, 2, 3]

    Python

        >>> from sage.all import *
        >>> # needs sage.modules
        >>> from sage.combinat.diagram_algebras import PartitionDiagram, PartitionDiagrams
        >>> pd = PartitionDiagram([[Integer(1),-Integer(3),-Integer(5)],[Integer(2),Integer(4)],[Integer(3),-Integer(1),-Integer(2)],[Integer(5)],[-Integer(4)]])
        >>> pd.max_block_size()
        3
        >>> sorted(d.max_block_size() for d in PartitionDiagrams(Integer(2)))
        [1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4]
        >>> sorted(sp.max_block_size() for sp in SetPartitions(Integer(3)))
        [1, 2, 2, 2, 3]

  standard_form()

    Return `self` as a list of lists.

    When the ground set is totally ordered, the elements of each block are listed in increasing order.

    This is not related to standard set partitions (which simply means set partitions of \([n] = \{ 1, 2, \ldots , n \}\) for some integer \(n\)) or standardization (`standardization()`).

    EXAMPLES:

    Sage

        sage: [x.standard_form() for x in SetPartitions(4, [2,2])]                  # needs sage.graphs sage.rings.finite_rings
        [[[1, 2], [3, 4]], [[1, 4], [2, 3]], [[1, 3], [2, 4]]]

    Python

        >>> from sage.all import *
        >>> [x.standard_form() for x in SetPartitions(Integer(4), [Integer(2),Integer(2)])]                  # needs sage.graphs sage.rings.finite_rings
        [[[1, 2], [3, 4]], [[1, 4], [2, 3]], [[1, 3], [2, 4]]]

  sup(t)

    Return the supremum of `self` and `t` in the classical set partition lattice.

    The supremum of two set partitions \(B\) and \(C\) is obtained as the transitive closure of the relation which relates \(i\) to \(j\) if and only if \(i\) and \(j\) are in the same part in at least one of the set partitions \(B\) and \(C\).

    See also

    `__mul__()`

    EXAMPLES:

    Sage

        sage: S = SetPartitions(4)
        sage: sp1 = S([[2,3,4], [1]])
        sage: sp2 = S([[1,3], [2,4]])
        sage: s = S([[1,2,3,4]])
        sage: sp1.sup(sp2) == s
        True

    Python

        >>> from sage.all import *
        >>> S = SetPartitions(Integer(4))
        >>> sp1 = S([[Integer(2),Integer(3),Integer(4)], [Integer(1)]])
        >>> sp2 = S([[Integer(1),Integer(3)], [Integer(2),Integer(4)]])
        >>> s = S([[Integer(1),Integer(2),Integer(3),Integer(4)]])
        >>> sp1.sup(sp2) == s
        True

class sage.combinat.set_partition.SetPartition(parent, s, check=True)

  Bases: `AbstractSetPartition`

  A partition of a set.

  A set partition \(p\) of a set \(S\) is a partition of \(S\) into subsets called parts and represented as a set of sets. By extension, a set partition of a nonnegative integer \(n\) is the set partition of the integers from 1 to \(n\). The number of set partitions of \(n\) is called the \(n\)-th Bell number.

  There is a natural integer partition associated with a set partition, namely the nonincreasing sequence of sizes of all its parts.

  There is a classical lattice associated with all set partitions of \(n\). The infimum of two set partitions is the set partition obtained by intersecting all the parts of both set partitions. The supremum is obtained by transitive closure of the relation \(i\) related to \(j\) if and only if they are in the same part in at least one of the set partitions.

  We will use terminology from partitions, in particular the length of a set partition \(A = \{A_1, \ldots, A_k\}\) is the number of parts of \(A\) and is denoted by \(|A| := k\). The size of \(A\) is the cardinality of \(S\). We will also sometimes use the notation \([n] := \{1, 2, \ldots, n\}\).

  EXAMPLES:

  There are 5 set partitions of the set \(\{1,2,3\}\):

  Sage

      sage: SetPartitions(3).cardinality()                                            # needs sage.libs.flint
      5

  Python

      >>> from sage.all import *
      >>> SetPartitions(Integer(3)).cardinality()                                            # needs sage.libs.flint
      5

  Here is the list of them:

  Sage

      sage: SetPartitions(3).list()                                                   # needs sage.graphs
      [{{1, 2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2, 3}}, {{1}, {2}, {3}}]

  [Python]

      >>> from sage.all import *
      >>> SetPartitions(Integer(3)).list()                                                   # needs sage.graphs
      [{{1, 2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2, 3}}, {{1}, {2}, {3}}]

  There are 6 set partitions of \(\{1,2,3,4\}\) whose underlying partition is \([2, 1, 1]\):

  Sage

      sage: SetPartitions(4, [2,1,1]).list()                                          # needs sage.graphs sage.rings.finite_rings
      [{{1}, {2, 4}, {3}},
       {{1}, {2}, {3, 4}},
       {{1, 4}, {2}, {3}},
       {{1, 3}, {2}, {4}},
       {{1, 2}, {3}, {4}},
       {{1}, {2, 3}, {4}}]

  Python

      >>> from sage.all import *
      >>> SetPartitions(Integer(4), [Integer(2),Integer(1),Integer(1)]).list()                                          # needs sage.graphs sage.rings.finite_rings
      [{{1}, {2, 4}, {3}},
       {{1}, {2}, {3, 4}},
       {{1, 4}, {2}, {3}},
       {{1, 3}, {2}, {4}},
       {{1, 2}, {3}, {4}},
       {{1}, {2, 3}, {4}}]

  Since Issue #14140, we can create a set partition directly by `SetPartition`, which creates the base set by taking the union of the parts passed in:

  Sage

      sage: s = SetPartition([[1,3],[2,4]]); s
      {{1, 3}, {2, 4}}
      sage: s.parent()
      Set partitions

  [Python]

      >>> from sage.all import *
      >>> s = SetPartition([[Integer(1),Integer(3)],[Integer(2),Integer(4)]]); s
      {{1, 3}, {2, 4}}
      >>> s.parent()
      Set partitions

  apply_permutation(p)

    Apply `p` to the underlying set of `self`.

    INPUT:

    - `p` – a permutation

    EXAMPLES:

    Sage

        sage: x = SetPartition([[1,2], [3,5,4]])
        sage: p = Permutation([2,1,4,5,3])
        sage: x.apply_permutation(p)
        {{1, 2}, {3, 4, 5}}
        sage: q = Permutation([3,2,1,5,4])
        sage: x.apply_permutation(q)
        {{1, 4, 5}, {2, 3}}

        sage: m = PerfectMatching([(1,4),(2,6),(3,5)])
        sage: m.apply_permutation(Permutation([4,1,5,6,3,2]))
        [(1, 2), (3, 5), (4, 6)]

    Python

        >>> from sage.all import *
        >>> x = SetPartition([[Integer(1),Integer(2)], [Integer(3),Integer(5),Integer(4)]])
        >>> p = Permutation([Integer(2),Integer(1),Integer(4),Integer(5),Integer(3)])
        >>> x.apply_permutation(p)
        {{1, 2}, {3, 4, 5}}
        >>> q = Permutation([Integer(3),Integer(2),Integer(1),Integer(5),Integer(4)])
        >>> x.apply_permutation(q)
        {{1, 4, 5}, {2, 3}}

        >>> m = PerfectMatching([(Integer(1),Integer(4)),(Integer(2),Integer(6)),(Integer(3),Integer(5))])
        >>> m.apply_permutation(Permutation([Integer(4),Integer(1),Integer(5),Integer(6),Integer(3),Integer(2)]))
        [(1, 2), (3, 5), (4, 6)]

  arcs()

    Return `self` as a list of arcs.

    Assuming that the blocks are sorted, the arcs are the pairs of consecutive elements in the blocks.

    EXAMPLES:

    Sage

        sage: A = SetPartition([[1],[2,3],[4]])
        sage: A.arcs()
        [(2, 3)]
        sage: B = SetPartition([[1,3,6,7],[2,5],[4]])
        sage: B.arcs()
        [(1, 3), (3, 6), (6, 7), (2, 5)]

    Python

        >>> from sage.all import *
        >>> A = SetPartition([[Integer(1)],[Integer(2),Integer(3)],[Integer(4)]])
        >>> A.arcs()
        [(2, 3)]
        >>> B = SetPartition([[Integer(1),Integer(3),Integer(6),Integer(7)],[Integer(2),Integer(5)],[Integer(4)]])
        >>> B.arcs()
        [(1, 3), (3, 6), (6, 7), (2, 5)]

  cardinality()

    Return the `len` of `self`.

    EXAMPLES:

    Sage

        sage: from sage.structure.list_clone_demo import IncreasingArrays
        sage: len(IncreasingArrays()([1,2,3]))
        3

    Python

        >>> from sage.all import *
        >>> from sage.structure.list_clone_demo import IncreasingArrays
        >>> len(IncreasingArrays()([Integer(1),Integer(2),Integer(3)]))
        3

  check()

    Check that we are a valid set partition.

    EXAMPLES:

    Sage

        sage: S = SetPartitions(4)
        sage: s = S([[1, 3], [2, 4]])
        sage: s.check()

    Python

        >>> from sage.all import *
        >>> S = SetPartitions(Integer(4))
        >>> s = S([[Integer(1), Integer(3)], [Integer(2), Integer(4)]])
        >>> s.check()

  closers()

    Return the maximal elements of the blocks.

    EXAMPLES:

    Sage

        sage: P = SetPartition([[1,2,4,7],[3,9],[5,6,10,11,13],[8],[12]])
        sage: P.closers()
        [7, 8, 9, 12, 13]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(2),Integer(4),Integer(7)],[Integer(3),Integer(9)],[Integer(5),Integer(6),Integer(10),Integer(11),Integer(13)],[Integer(8)],[Integer(12)]])
        >>> P.closers()
        [7, 8, 9, 12, 13]

  crossings()

    Return the crossing arcs of a set partition on a totally ordered set.

    OUTPUT:

    We place the elements of the ground set in order on a line and draw the set partition by linking consecutive elements of each block in the upper half-plane. This function returns a list of the pairs of crossing lines (as a line correspond to a pair, it returns a list of pairs of pairs).

    EXAMPLES:

    Sage

        sage: p = SetPartition([[1,4],[2,5,7],[3,6]])
        sage: p.crossings()
        [((1, 4), (2, 5)), ((1, 4), (3, 6)), ((2, 5), (3, 6)), ((3, 6), (5, 7))]

    Python

        >>> from sage.all import *
        >>> p = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(5),Integer(7)],[Integer(3),Integer(6)]])
        >>> p.crossings()
        [((1, 4), (2, 5)), ((1, 4), (3, 6)), ((2, 5), (3, 6)), ((3, 6), (5, 7))]

  crossings_iterator()

    Return the crossing arcs of a set partition on a totally ordered set.

    OUTPUT:

    We place the elements of the ground set in order on a line and draw the set partition by linking consecutive elements of each block in the upper half-plane. This function returns an iterator over the pairs of crossing lines (as a line correspond to a pair, the iterator produces pairs of pairs).

    EXAMPLES:

    Sage

        sage: p = SetPartition([[1,4],[2,5,7],[3,6]])
        sage: next(p.crossings_iterator())
        ((1, 4), (2, 5))

    Python

        >>> from sage.all import *
        >>> p = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(5),Integer(7)],[Integer(3),Integer(6)]])
        >>> next(p.crossings_iterator())
        ((1, 4), (2, 5))

  is_atomic()

    Return if `self` is an atomic set partition.

    A (standard) set partition \(A\) can be split if there exist \(j < i\) such that \(\max(A_j) < \min(A_i)\) where \(A\) is ordered by minimal elements. This means we can write \(A = B | C\) for some nonempty set partitions \(B\) and \(C\). We call a set partition atomic if it cannot be split and is nonempty. Here, the pipe symbol \(|\) is as defined in method `pipe()`.

    EXAMPLES:

    Sage

        sage: SetPartition([[1,3], [2]]).is_atomic()
        True
        sage: SetPartition([[1,3], [2], [4]]).is_atomic()
        False
        sage: SetPartition([[1], [2,4], [3]]).is_atomic()
        False
        sage: SetPartition([[1,2,3,4]]).is_atomic()
        True
        sage: SetPartition([[1, 4], [2], [3]]).is_atomic()
        True
        sage: SetPartition([]).is_atomic()
        False

    Python

        >>> from sage.all import *
        >>> SetPartition([[Integer(1),Integer(3)], [Integer(2)]]).is_atomic()
        True
        >>> SetPartition([[Integer(1),Integer(3)], [Integer(2)], [Integer(4)]]).is_atomic()
        False
        >>> SetPartition([[Integer(1)], [Integer(2),Integer(4)], [Integer(3)]]).is_atomic()
        False
        >>> SetPartition([[Integer(1),Integer(2),Integer(3),Integer(4)]]).is_atomic()
        True
        >>> SetPartition([[Integer(1), Integer(4)], [Integer(2)], [Integer(3)]]).is_atomic()
        True
        >>> SetPartition([]).is_atomic()
        False

  is_noncrossing()

    Check if `self` is noncrossing.

    OUTPUT:

    We place the elements of the ground set in order on a line and draw the set partition by linking consecutive elements of each block in the upper half-plane. This function returns `True` if the picture obtained this way has no crossings.

    EXAMPLES:

    Sage

        sage: p = SetPartition([[1,4],[2,5,7],[3,6]])
        sage: p.is_noncrossing()
        False

        sage: n = PerfectMatching([3,8,1,7,6,5,4,2]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        sage: n.is_noncrossing()
        False
        sage: PerfectMatching([(1, 4), (2, 3), (5, 6)]).is_noncrossing()
        True

    Python

        >>> from sage.all import *
        >>> p = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(5),Integer(7)],[Integer(3),Integer(6)]])
        >>> p.is_noncrossing()
        False

        >>> n = PerfectMatching([Integer(3),Integer(8),Integer(1),Integer(7),Integer(6),Integer(5),Integer(4),Integer(2)]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        >>> n.is_noncrossing()
        False
        >>> PerfectMatching([(Integer(1), Integer(4)), (Integer(2), Integer(3)), (Integer(5), Integer(6))]).is_noncrossing()
        True

  is_nonnesting()

    Return if `self` is nonnesting or not.

    OUTPUT:

    We place the elements of the ground set in order on a line and draw the set partition by linking consecutive elements of each block in the upper half-plane. This function returns `True` if the picture obtained this way has no nestings.

    EXAMPLES:

    Sage

        sage: n = PerfectMatching([3,8,1,7,6,5,4,2]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        sage: n.is_nonnesting()
        False
        sage: PerfectMatching([(1, 3), (2, 5), (4, 6)]).is_nonnesting()
        True

    Python

        >>> from sage.all import *
        >>> n = PerfectMatching([Integer(3),Integer(8),Integer(1),Integer(7),Integer(6),Integer(5),Integer(4),Integer(2)]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        >>> n.is_nonnesting()
        False
        >>> PerfectMatching([(Integer(1), Integer(3)), (Integer(2), Integer(5)), (Integer(4), Integer(6))]).is_nonnesting()
        True

  latex_options()

    Return the latex options for use in the `_latex_` function as a dictionary. The default values are set using the global options.

    Options can be found in `set_latex_options()`

    EXAMPLES:

    Sage

        sage: SP = SetPartition([[1,6], [3,5,4]]); SP.latex_options()
        {'angle': 0,
         'color': 'black',
         'fill': False,
         'plot': None,
         'radius': '1cm',
         'show_labels': True,
         'tikz_scale': 1}

    Python

        >>> from sage.all import *
        >>> SP = SetPartition([[Integer(1),Integer(6)], [Integer(3),Integer(5),Integer(4)]]); SP.latex_options()
        {'angle': 0,
         'color': 'black',
         'fill': False,
         'plot': None,
         'radius': '1cm',
         'show_labels': True,
         'tikz_scale': 1}

  nestings()

    Return the nestings of `self`.

    OUTPUT:

    We place the elements of the ground set in order on a line and draw the set partition by linking consecutive elements of each block in the upper half-plane. This function returns the list of the pairs of nesting lines (as a line correspond to a pair, it returns a list of pairs of pairs).

    EXAMPLES:

    Sage

        sage: m = PerfectMatching([(1, 6), (2, 7), (3, 5), (4, 8)])
        sage: m.nestings()
        [((1, 6), (3, 5)), ((2, 7), (3, 5))]

        sage: n = PerfectMatching([3,8,1,7,6,5,4,2]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        sage: n.nestings()
        [((2, 8), (4, 7)), ((2, 8), (5, 6)), ((4, 7), (5, 6))]

    Python

        >>> from sage.all import *
        >>> m = PerfectMatching([(Integer(1), Integer(6)), (Integer(2), Integer(7)), (Integer(3), Integer(5)), (Integer(4), Integer(8))])
        >>> m.nestings()
        [((1, 6), (3, 5)), ((2, 7), (3, 5))]

        >>> n = PerfectMatching([Integer(3),Integer(8),Integer(1),Integer(7),Integer(6),Integer(5),Integer(4),Integer(2)]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        >>> n.nestings()
        [((2, 8), (4, 7)), ((2, 8), (5, 6)), ((4, 7), (5, 6))]

  nestings_iterator()

    Iterate over the nestings of `self`.

    OUTPUT:

    We place the elements of the ground set in order on a line and draw the set partition by linking consecutive elements of each block in the upper half-plane. This function returns an iterator over the pairs of nesting lines (as a line correspond to a pair, the iterator produces pairs of pairs).

    EXAMPLES:

    Sage

        sage: n = PerfectMatching([(1, 6), (2, 7), (3, 5), (4, 8)])
        sage: it = n.nestings_iterator()
        sage: next(it)
        ((1, 6), (3, 5))
        sage: next(it)
        ((2, 7), (3, 5))
        sage: next(it)
        Traceback (most recent call last):
        ...
        StopIteration

    Python

        >>> from sage.all import *
        >>> n = PerfectMatching([(Integer(1), Integer(6)), (Integer(2), Integer(7)), (Integer(3), Integer(5)), (Integer(4), Integer(8))])
        >>> it = n.nestings_iterator()
        >>> next(it)
        ((1, 6), (3, 5))
        >>> next(it)
        ((2, 7), (3, 5))
        >>> next(it)
        Traceback (most recent call last):
        ...
        StopIteration

  number_of_crossings()

    Return the number of crossings.

    OUTPUT:

    We place the elements of the ground set in order on a line and draw the set partition by linking consecutive elements of each block in the upper half-plane. This function returns the number the pairs of crossing lines.

    EXAMPLES:

    Sage

        sage: p = SetPartition([[1,4],[2,5,7],[3,6]])
        sage: p.number_of_crossings()
        4

        sage: n = PerfectMatching([3,8,1,7,6,5,4,2]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        sage: n.number_of_crossings()
        1

    Python

        >>> from sage.all import *
        >>> p = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(5),Integer(7)],[Integer(3),Integer(6)]])
        >>> p.number_of_crossings()
        4

        >>> n = PerfectMatching([Integer(3),Integer(8),Integer(1),Integer(7),Integer(6),Integer(5),Integer(4),Integer(2)]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        >>> n.number_of_crossings()
        1

  number_of_nestings()

    Return the number of nestings of `self`.

    OUTPUT:

    We place the elements of the ground set in order on a line and draw the set partition by linking consecutive elements of each block in the upper half-plane. This function returns the number the pairs of nesting lines.

    EXAMPLES:

    Sage

        sage: n = PerfectMatching([3,8,1,7,6,5,4,2]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        sage: n.number_of_nestings()
        3

    Python

        >>> from sage.all import *
        >>> n = PerfectMatching([Integer(3),Integer(8),Integer(1),Integer(7),Integer(6),Integer(5),Integer(4),Integer(2)]); n
        [(1, 3), (2, 8), (4, 7), (5, 6)]
        >>> n.number_of_nestings()
        3

  openers()

    Return the minimal elements of the blocks.

    EXAMPLES:

    Sage

        sage: P = SetPartition([[1,2,4,7],[3,9],[5,6,10,11,13],[8],[12]])
        sage: P.openers()
        [1, 3, 5, 8, 12]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(2),Integer(4),Integer(7)],[Integer(3),Integer(9)],[Integer(5),Integer(6),Integer(10),Integer(11),Integer(13)],[Integer(8)],[Integer(12)]])
        >>> P.openers()
        [1, 3, 5, 8, 12]

  ordered_set_partition_action(s)

    Return the action of an ordered set partition `s` on `self`.

    Let \(A = \{A_1, A_2, \ldots, A_k\}\) be a set partition of some set \(S\) and \(s\) be an ordered set partition (i.e., set composition) of a subset of \([k]\). Let \(A^{\downarrow}\) denote the standardization of \(A\), and \(A_{\{ i_1, i_2, \ldots, i_m \}}\) denote the sub-partition \(\{A_{i_1}, A_{i_2}, \ldots, A_{i_m}\}\) for any subset \(\{i_1, \ldots, i_m\}\) of \(\{1, \ldots, k\}\). We define the set partition \(s(A)\) by

    \[s(A) = A_{s_1}^{\downarrow} | A_{s_2}^{\downarrow} | \cdots | A_{s_q}^{\downarrow}.\]

    where \(s = (s_1, s_2, \ldots, s_q)\). Here, the pipe symbol \(|\) is as defined in method `pipe()`.

    This is \(s[A]\) in section 2.3 in [LM2011].

    INPUT:

    - `s` – an ordered set partition with base set a subset of \(\{1, \ldots, k\}\)

    EXAMPLES:

    Sage

        sage: A = SetPartition([[1], [2,4], [3]])
        sage: s = OrderedSetPartition([[1,3], [2]])
        sage: A.ordered_set_partition_action(s)
        {{1}, {2}, {3, 4}}
        sage: s = OrderedSetPartition([[2,3], [1]])
        sage: A.ordered_set_partition_action(s)
        {{1, 3}, {2}, {4}}

    Python

        >>> from sage.all import *
        >>> A = SetPartition([[Integer(1)], [Integer(2),Integer(4)], [Integer(3)]])
        >>> s = OrderedSetPartition([[Integer(1),Integer(3)], [Integer(2)]])
        >>> A.ordered_set_partition_action(s)
        {{1}, {2}, {3, 4}}
        >>> s = OrderedSetPartition([[Integer(2),Integer(3)], [Integer(1)]])
        >>> A.ordered_set_partition_action(s)
        {{1, 3}, {2}, {4}}

    We create Figure 1 in [LM2011] (we note that there is a typo in the lower-left corner of the table in the published version of the paper, whereas the arXiv version gives the correct partition):

    Sage

        sage: A = SetPartition([[1,3], [2,9], [4,5,8], [7]])
        sage: B = SetPartition([[1,3], [2,8], [4,5,6], [7]])
        sage: C = SetPartition([[1,5], [2,8], [3,4,6], [7]])
        sage: s = OrderedSetPartition([[1,3], [2]])
        sage: t = OrderedSetPartition([[2], [3,4]])
        sage: u = OrderedSetPartition([[1], [2,3,4]])
        sage: A.ordered_set_partition_action(s)
        {{1, 2}, {3, 4, 5}, {6, 7}}
        sage: A.ordered_set_partition_action(t)
        {{1, 2}, {3, 4, 6}, {5}}
        sage: A.ordered_set_partition_action(u)
        {{1, 2}, {3, 8}, {4, 5, 7}, {6}}
        sage: B.ordered_set_partition_action(s)
        {{1, 2}, {3, 4, 5}, {6, 7}}
        sage: B.ordered_set_partition_action(t)
        {{1, 2}, {3, 4, 5}, {6}}
        sage: B.ordered_set_partition_action(u)
        {{1, 2}, {3, 8}, {4, 5, 6}, {7}}
        sage: C.ordered_set_partition_action(s)
        {{1, 4}, {2, 3, 5}, {6, 7}}
        sage: C.ordered_set_partition_action(t)
        {{1, 2}, {3, 4, 5}, {6}}
        sage: C.ordered_set_partition_action(u)
        {{1, 2}, {3, 8}, {4, 5, 6}, {7}}

    [Python]

        >>> from sage.all import *
        >>> A = SetPartition([[Integer(1),Integer(3)], [Integer(2),Integer(9)], [Integer(4),Integer(5),Integer(8)], [Integer(7)]])
        >>> B = SetPartition([[Integer(1),Integer(3)], [Integer(2),Integer(8)], [Integer(4),Integer(5),Integer(6)], [Integer(7)]])
        >>> C = SetPartition([[Integer(1),Integer(5)], [Integer(2),Integer(8)], [Integer(3),Integer(4),Integer(6)], [Integer(7)]])
        >>> s = OrderedSetPartition([[Integer(1),Integer(3)], [Integer(2)]])
        >>> t = OrderedSetPartition([[Integer(2)], [Integer(3),Integer(4)]])
        >>> u = OrderedSetPartition([[Integer(1)], [Integer(2),Integer(3),Integer(4)]])
        >>> A.ordered_set_partition_action(s)
        {{1, 2}, {3, 4, 5}, {6, 7}}
        >>> A.ordered_set_partition_action(t)
        {{1, 2}, {3, 4, 6}, {5}}
        >>> A.ordered_set_partition_action(u)
        {{1, 2}, {3, 8}, {4, 5, 7}, {6}}
        >>> B.ordered_set_partition_action(s)
        {{1, 2}, {3, 4, 5}, {6, 7}}
        >>> B.ordered_set_partition_action(t)
        {{1, 2}, {3, 4, 5}, {6}}
        >>> B.ordered_set_partition_action(u)
        {{1, 2}, {3, 8}, {4, 5, 6}, {7}}
        >>> C.ordered_set_partition_action(s)
        {{1, 4}, {2, 3, 5}, {6, 7}}
        >>> C.ordered_set_partition_action(t)
        {{1, 2}, {3, 4, 5}, {6}}
        >>> C.ordered_set_partition_action(u)
        {{1, 2}, {3, 8}, {4, 5, 6}, {7}}

    REFERENCES:

    - [LM2011]

  pipe(other)

    Return the pipe of the set partitions `self` and `other`.

    The pipe of two set partitions is defined as follows:

    For any integer \(k\) and any subset \(I\) of \(\ZZ\), let \(I + k\) denote the subset of \(\ZZ\) obtained by adding \(k\) to every element of \(k\).

    If \(B\) and \(C\) are set partitions of \([n]\) and \([m]\), respectively, then the pipe of \(B\) and \(C\) is defined as the set partition

    \[\{ B_1, B_2, \ldots, B_b, C_1 + n, C_2 + n, \ldots, C_c + n \}\]

    of \([n+m]\), where \(B = \{ B_1, B_2, \ldots, B_b \}\) and \(C = \{ C_1, C_2, \ldots, C_c \}\). This pipe is denoted by \(B | C\).

    EXAMPLES:

    Sage

        sage: SetPartition([[1,3],[2,4]]).pipe(SetPartition([[1,3],[2]]))
        {{1, 3}, {2, 4}, {5, 7}, {6}}
        sage: SetPartition([]).pipe(SetPartition([[1,2],[3,5],[4]]))
        {{1, 2}, {3, 5}, {4}}
        sage: SetPartition([[1,2],[3,5],[4]]).pipe(SetPartition([]))
        {{1, 2}, {3, 5}, {4}}
        sage: SetPartition([[1,2],[3]]).pipe(SetPartition([[1]]))
        {{1, 2}, {3}, {4}}

    Python

        >>> from sage.all import *
        >>> SetPartition([[Integer(1),Integer(3)],[Integer(2),Integer(4)]]).pipe(SetPartition([[Integer(1),Integer(3)],[Integer(2)]]))
        {{1, 3}, {2, 4}, {5, 7}, {6}}
        >>> SetPartition([]).pipe(SetPartition([[Integer(1),Integer(2)],[Integer(3),Integer(5)],[Integer(4)]]))
        {{1, 2}, {3, 5}, {4}}
        >>> SetPartition([[Integer(1),Integer(2)],[Integer(3),Integer(5)],[Integer(4)]]).pipe(SetPartition([]))
        {{1, 2}, {3, 5}, {4}}
        >>> SetPartition([[Integer(1),Integer(2)],[Integer(3)]]).pipe(SetPartition([[Integer(1)]]))
        {{1, 2}, {3}, {4}}

  plot(angle=None, color='black', base_set_dict=None)

    Return a plot of `self`.

    INPUT:

    - `angle` – (default: \(\pi/4\)) the angle at which the arcs take off (if angle is negative, the arcs are drawn below the horizontal line)

    - `color` – (default: `'black'`) color of the arcs

    - `base_set_dict` – (optional) dictionary with keys elements of `base_set()` and values as integer or float

    EXAMPLES:

    Sage

        sage: p = SetPartition([[1,10,11],[2,3,7],[4,5,6],[8,9]])
        sage: p.plot()                                                              # needs sage.plot sage.symbolic
        Graphics object consisting of 29 graphics primitives

    Python

        >>> from sage.all import *
        >>> p = SetPartition([[Integer(1),Integer(10),Integer(11)],[Integer(2),Integer(3),Integer(7)],[Integer(4),Integer(5),Integer(6)],[Integer(8),Integer(9)]])
        >>> p.plot()                                                              # needs sage.plot sage.symbolic
        Graphics object consisting of 29 graphics primitives

    Sage

        sage: p = SetPartition([[1,3,4],[2,5]])
        sage: print(p.plot().description())                                         # needs sage.plot sage.symbolic
        Point set defined by 1 point(s):    [(0.0, 0.0)]
        Point set defined by 1 point(s):    [(1.0, 0.0)]
        Point set defined by 1 point(s):    [(2.0, 0.0)]
        Point set defined by 1 point(s):    [(3.0, 0.0)]
        Point set defined by 1 point(s):    [(4.0, 0.0)]
        Text '1' at the point (0.0,-0.1)
        Text '2' at the point (1.0,-0.1)
        Text '3' at the point (2.0,-0.1)
        Text '4' at the point (3.0,-0.1)
        Text '5' at the point (4.0,-0.1)
        Arc with center (1.0,-1.0) radii (1.41421356237...,1.41421356237...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        Arc with center (2.5,-0.5) radii (0.70710678118...,0.70710678118...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        Arc with center (2.5,-1.5) radii (2.1213203435...,2.1213203435...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        sage: p = SetPartition([['a','c'],['b','d'],['e']])
        sage: print(p.plot().description())                                         # needs sage.plot sage.symbolic
        Point set defined by 1 point(s):  [(0.0, 0.0)]
        Point set defined by 1 point(s):    [(1.0, 0.0)]
        Point set defined by 1 point(s):    [(2.0, 0.0)]
        Point set defined by 1 point(s):    [(3.0, 0.0)]
        Point set defined by 1 point(s):    [(4.0, 0.0)]
        Text 'a' at the point (0.0,-0.1)
        Text 'b' at the point (1.0,-0.1)
        Text 'c' at the point (2.0,-0.1)
        Text 'd' at the point (3.0,-0.1)
        Text 'e' at the point (4.0,-0.1)
        Arc with center (1.0,-1.0) radii (1.41421356237...,1.41421356237...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        Arc with center (2.0,-1.0) radii (1.41421356237...,1.41421356237...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        sage: p = SetPartition([['a','c'],['b','d'],['e']])
        sage: print(p.plot(base_set_dict={'a':0,'b':1,'c':2,                        # needs sage.plot sage.symbolic
        ....:                             'd':-2.3,'e':5.4}).description())
        Point set defined by 1 point(s):    [(-2.3, 0.0)]
        Point set defined by 1 point(s):    [(0.0, 0.0)]
        Point set defined by 1 point(s):    [(1.0, 0.0)]
        Point set defined by 1 point(s):    [(2.0, 0.0)]
        Point set defined by 1 point(s):    [(5.4, 0.0)]
        Text 'a' at the point (0.0,-0.1)
        Text 'b' at the point (1.0,-0.1)
        Text 'c' at the point (2.0,-0.1)
        Text 'd' at the point (-2.3,-0.1)
        Text 'e' at the point (5.4,-0.1)
        Arc with center (-0.6...,-1.65) radii (2.3334523779...,2.3334523779...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        Arc with center (1.0,-1.0) radii (1.4142135623...,1.4142135623...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)

    [Python]

        >>> from sage.all import *
        >>> p = SetPartition([[Integer(1),Integer(3),Integer(4)],[Integer(2),Integer(5)]])
        >>> print(p.plot().description())                                         # needs sage.plot sage.symbolic
        Point set defined by 1 point(s):    [(0.0, 0.0)]
        Point set defined by 1 point(s):    [(1.0, 0.0)]
        Point set defined by 1 point(s):    [(2.0, 0.0)]
        Point set defined by 1 point(s):    [(3.0, 0.0)]
        Point set defined by 1 point(s):    [(4.0, 0.0)]
        Text '1' at the point (0.0,-0.1)
        Text '2' at the point (1.0,-0.1)
        Text '3' at the point (2.0,-0.1)
        Text '4' at the point (3.0,-0.1)
        Text '5' at the point (4.0,-0.1)
        Arc with center (1.0,-1.0) radii (1.41421356237...,1.41421356237...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        Arc with center (2.5,-0.5) radii (0.70710678118...,0.70710678118...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        Arc with center (2.5,-1.5) radii (2.1213203435...,2.1213203435...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        >>> p = SetPartition([['a','c'],['b','d'],['e']])
        >>> print(p.plot().description())                                         # needs sage.plot sage.symbolic
        Point set defined by 1 point(s):  [(0.0, 0.0)]
        Point set defined by 1 point(s):    [(1.0, 0.0)]
        Point set defined by 1 point(s):    [(2.0, 0.0)]
        Point set defined by 1 point(s):    [(3.0, 0.0)]
        Point set defined by 1 point(s):    [(4.0, 0.0)]
        Text 'a' at the point (0.0,-0.1)
        Text 'b' at the point (1.0,-0.1)
        Text 'c' at the point (2.0,-0.1)
        Text 'd' at the point (3.0,-0.1)
        Text 'e' at the point (4.0,-0.1)
        Arc with center (1.0,-1.0) radii (1.41421356237...,1.41421356237...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        Arc with center (2.0,-1.0) radii (1.41421356237...,1.41421356237...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        >>> p = SetPartition([['a','c'],['b','d'],['e']])
        >>> print(p.plot(base_set_dict={'a':Integer(0),'b':Integer(1),'c':Integer(2),                        # needs sage.plot sage.symbolic
        ...                             'd':-RealNumber('2.3'),'e':RealNumber('5.4')}).description())
        Point set defined by 1 point(s):    [(-2.3, 0.0)]
        Point set defined by 1 point(s):    [(0.0, 0.0)]
        Point set defined by 1 point(s):    [(1.0, 0.0)]
        Point set defined by 1 point(s):    [(2.0, 0.0)]
        Point set defined by 1 point(s):    [(5.4, 0.0)]
        Text 'a' at the point (0.0,-0.1)
        Text 'b' at the point (1.0,-0.1)
        Text 'c' at the point (2.0,-0.1)
        Text 'd' at the point (-2.3,-0.1)
        Text 'e' at the point (5.4,-0.1)
        Arc with center (-0.6...,-1.65) radii (2.3334523779...,2.3334523779...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)
        Arc with center (1.0,-1.0) radii (1.4142135623...,1.4142135623...)
         angle 0.0 inside the sector (0.785398163397...,2.35619449019...)

  refinements()

    Return a list of refinements of `self`.

    See also

    `coarsenings()`

    EXAMPLES:

    Sage

        sage: SetPartition([[1,3],[2,4]]).refinements()                             # needs sage.graphs sage.libs.flint
        [{{1, 3}, {2, 4}},
         {{1, 3}, {2}, {4}},
         {{1}, {2, 4}, {3}},
         {{1}, {2}, {3}, {4}}]
        sage: SetPartition([[1],[2,4],[3]]).refinements()                           # needs sage.graphs sage.libs.flint
        [{{1}, {2, 4}, {3}}, {{1}, {2}, {3}, {4}}]
        sage: SetPartition([]).refinements()                                        # needs sage.graphs sage.libs.flint
        [{}]

    Python

        >>> from sage.all import *
        >>> SetPartition([[Integer(1),Integer(3)],[Integer(2),Integer(4)]]).refinements()                             # needs sage.graphs sage.libs.flint
        [{{1, 3}, {2, 4}},
         {{1, 3}, {2}, {4}},
         {{1}, {2, 4}, {3}},
         {{1}, {2}, {3}, {4}}]
        >>> SetPartition([[Integer(1)],[Integer(2),Integer(4)],[Integer(3)]]).refinements()                           # needs sage.graphs sage.libs.flint
        [{{1}, {2, 4}, {3}}, {{1}, {2}, {3}, {4}}]
        >>> SetPartition([]).refinements()                                        # needs sage.graphs sage.libs.flint
        [{}]

  restriction(I)

    Return the restriction of `self` to a subset `I` (which is given as a set or list or any other iterable).

    EXAMPLES:

    Sage

        sage: A = SetPartition([[1], [2,3]])
        sage: A.restriction([1,2])
        {{1}, {2}}
        sage: A.restriction([2,3])
        {{2, 3}}
        sage: A.restriction([])
        {}
        sage: A.restriction([4])
        {}

    Python

        >>> from sage.all import *
        >>> A = SetPartition([[Integer(1)], [Integer(2),Integer(3)]])
        >>> A.restriction([Integer(1),Integer(2)])
        {{1}, {2}}
        >>> A.restriction([Integer(2),Integer(3)])
        {{2, 3}}
        >>> A.restriction([])
        {}
        >>> A.restriction([Integer(4)])
        {}

  set_latex_options(**kwargs)

    Set the latex options for use in the `_latex_` function.

    - `tikz_scale` – (default: 1) scale for use with tikz package

    - `plot` – (default: `None`) `None` returns the set notation, `linear` returns a linear plot, `cyclic` returns a cyclic plot

    - `color` – (default: `'black'`) the arc colors

    - `fill` – boolean (default: `False`); if `True` then fills `color`, else you can pass in a color to alter the fill color - only works with cyclic plot

    - `show_labels` – boolean (default: `True`); if `True` shows labels (only works with plots)

    - `radius` – (default: `'1cm'`) radius of circle for cyclic plot - only works with cyclic plot

    - `angle` – (default: 0) angle for linear plot

    EXAMPLES:

    Sage

        sage: SP = SetPartition([[1,6], [3,5,4]])
        sage: SP.set_latex_options(tikz_scale=2,plot='linear',fill=True,color='blue',angle=45)
        sage: SP.set_latex_options(plot='cyclic')
        sage: SP.latex_options()
        {'angle': 45,
         'color': 'blue',
         'fill': True,
         'plot': 'cyclic',
         'radius': '1cm',
         'show_labels': True,
         'tikz_scale': 2}

    Python

        >>> from sage.all import *
        >>> SP = SetPartition([[Integer(1),Integer(6)], [Integer(3),Integer(5),Integer(4)]])
        >>> SP.set_latex_options(tikz_scale=Integer(2),plot='linear',fill=True,color='blue',angle=Integer(45))
        >>> SP.set_latex_options(plot='cyclic')
        >>> SP.latex_options()
        {'angle': 45,
         'color': 'blue',
         'fill': True,
         'plot': 'cyclic',
         'radius': '1cm',
         'show_labels': True,
         'tikz_scale': 2}

  shape()

    Return the integer partition whose parts are the sizes of the sets in `self`.

    EXAMPLES:

    Sage

        sage: S = SetPartitions(5)
        sage: x = S([[1,2], [3,5,4]])
        sage: x.shape()
        [3, 2]
        sage: y = S([[2], [3,1], [5,4]])
        sage: y.shape()
        [2, 2, 1]

    Python

        >>> from sage.all import *
        >>> S = SetPartitions(Integer(5))
        >>> x = S([[Integer(1),Integer(2)], [Integer(3),Integer(5),Integer(4)]])
        >>> x.shape()
        [3, 2]
        >>> y = S([[Integer(2)], [Integer(3),Integer(1)], [Integer(5),Integer(4)]])
        >>> y.shape()
        [2, 2, 1]

  shape_partition()

    alias of `shape()`.

  size()

    alias of `base_set_cardinality()`.

  standardization()

    Return the standardization of `self`.

    Given a set partition \(A = \{A_1, \ldots, A_n\}\) of an ordered set \(S\), the standardization of \(A\) is the set partition of \(\{1, 2, \ldots, |S|\}\) obtained by replacing the elements of the parts of \(A\) by the integers \(1, 2, \ldots, |S|\) in such a way that their relative order is preserved (i. e., the smallest element in the whole set partition is replaced by \(1\), the next-smallest by \(2\), and so on).

    EXAMPLES:

    Sage

        sage: SetPartition([[4], [1, 3]]).standardization()
        {{1, 2}, {3}}
        sage: SetPartition([[4], [6, 3]]).standardization()
        {{1, 3}, {2}}
        sage: SetPartition([]).standardization()
        {}
        sage: SetPartition([('c','b'),('d','f'),('e','a')]).standardization()
        {{1, 5}, {2, 3}, {4, 6}}

    Python

        >>> from sage.all import *
        >>> SetPartition([[Integer(4)], [Integer(1), Integer(3)]]).standardization()
        {{1, 2}, {3}}
        >>> SetPartition([[Integer(4)], [Integer(6), Integer(3)]]).standardization()
        {{1, 3}, {2}}
        >>> SetPartition([]).standardization()
        {}
        >>> SetPartition([('c','b'),('d','f'),('e','a')]).standardization()
        {{1, 5}, {2, 3}, {4, 6}}

  strict_coarsenings()

    Return all strict coarsenings of `self`.

    Strict coarsening is the binary relation on set partitions defined as the transitive-and-reflexive closure of the relation \(\prec\) defined as follows: For two set partitions \(A\) and \(B\), we have \(A \prec B\) if there exist parts \(A_i, A_j\) of \(A\) such that \(\max(A_i) < \min(A_j)\) and \(B = A \setminus \{A_i, A_j\} \cup \{ A_i \cup A_j \}\).

    EXAMPLES:

    Sage

        sage: A = SetPartition([[1],[2,3],[4]])
        sage: A.strict_coarsenings()
        [{{1}, {2, 3}, {4}}, {{1, 2, 3}, {4}}, {{1, 4}, {2, 3}},
         {{1}, {2, 3, 4}}, {{1, 2, 3, 4}}]
        sage: SetPartition([[1],[2,4],[3]]).strict_coarsenings()
        [{{1}, {2, 4}, {3}}, {{1, 2, 4}, {3}}, {{1, 3}, {2, 4}}]
        sage: SetPartition([]).strict_coarsenings()
        [{}]

    Python

        >>> from sage.all import *
        >>> A = SetPartition([[Integer(1)],[Integer(2),Integer(3)],[Integer(4)]])
        >>> A.strict_coarsenings()
        [{{1}, {2, 3}, {4}}, {{1, 2, 3}, {4}}, {{1, 4}, {2, 3}},
         {{1}, {2, 3, 4}}, {{1, 2, 3, 4}}]
        >>> SetPartition([[Integer(1)],[Integer(2),Integer(4)],[Integer(3)]]).strict_coarsenings()
        [{{1}, {2, 4}, {3}}, {{1, 2, 4}, {3}}, {{1, 3}, {2, 4}}]
        >>> SetPartition([]).strict_coarsenings()
        [{}]

  to_partition()

    alias of `shape()`.

  to_permutation()

    Convert a set partition of \(\{1,...,n\}\) to a permutation by considering the blocks of the partition as cycles.

    The cycles are such that the number of excedences is maximised, that is, each cycle is of the form \((a_1,a_2, ...,a_k)\) with \(a_1<a_2<...<a_k\).

    EXAMPLES:

    Sage

        sage: s = SetPartition([[1,3],[2,4]])
        sage: s.to_permutation()
        [3, 4, 1, 2]

    Python

        >>> from sage.all import *
        >>> s = SetPartition([[Integer(1),Integer(3)],[Integer(2),Integer(4)]])
        >>> s.to_permutation()
        [3, 4, 1, 2]

  to_restricted_growth_word(bijection='blocks')

    Convert a set partition of \(\{1,...,n\}\) to a word of length \(n\) with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before.

    INPUT:

    - `bijection` – (default: `blocks`) defines the map from set partitions to restricted growth functions. These are currently:

      - `blocks`: `to_restricted_growth_word_blocks()`.

      - `intertwining`: `to_restricted_growth_word_intertwining()`.

    OUTPUT: a restricted growth word

    See also

    `SetPartitions.from_restricted_growth_word()`

    EXAMPLES:

    Sage

        sage: P = SetPartition([[1,4],[2,8],[3,5,6,9],[7]])
        sage: P.to_restricted_growth_word()
        [0, 1, 2, 0, 2, 2, 3, 1, 2]

        sage: P.to_restricted_growth_word("intertwining")
        [0, 1, 2, 2, 1, 0, 3, 3, 2]

        sage: P = SetPartition([[1,2,4,7],[3,9],[5,6,10,11,13],[8],[12]])
        sage: P.to_restricted_growth_word()
        [0, 0, 1, 0, 2, 2, 0, 3, 1, 2, 2, 4, 2]

        sage: P.to_restricted_growth_word("intertwining")
        [0, 0, 1, 1, 2, 0, 1, 3, 3, 3, 0, 4, 1]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(8)],[Integer(3),Integer(5),Integer(6),Integer(9)],[Integer(7)]])
        >>> P.to_restricted_growth_word()
        [0, 1, 2, 0, 2, 2, 3, 1, 2]

        >>> P.to_restricted_growth_word("intertwining")
        [0, 1, 2, 2, 1, 0, 3, 3, 2]

        >>> P = SetPartition([[Integer(1),Integer(2),Integer(4),Integer(7)],[Integer(3),Integer(9)],[Integer(5),Integer(6),Integer(10),Integer(11),Integer(13)],[Integer(8)],[Integer(12)]])
        >>> P.to_restricted_growth_word()
        [0, 0, 1, 0, 2, 2, 0, 3, 1, 2, 2, 4, 2]

        >>> P.to_restricted_growth_word("intertwining")
        [0, 0, 1, 1, 2, 0, 1, 3, 3, 3, 0, 4, 1]

  to_restricted_growth_word_blocks()

    Convert a set partition of \(\{1,...,n\}\) to a word of length \(n\) with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before.

    The word is obtained by sorting the blocks by their minimal element and setting the letters at the positions of the elements in the \(i\)-th block to \(i\).

    OUTPUT: a restricted growth word

    See also

    `to_restricted_growth_word()` `SetPartitions.from_restricted_growth_word()`

    EXAMPLES:

    Sage

        sage: P = SetPartition([[1,4],[2,8],[3,5,6,9],[7]])
        sage: P.to_restricted_growth_word_blocks()
        [0, 1, 2, 0, 2, 2, 3, 1, 2]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(8)],[Integer(3),Integer(5),Integer(6),Integer(9)],[Integer(7)]])
        >>> P.to_restricted_growth_word_blocks()
        [0, 1, 2, 0, 2, 2, 3, 1, 2]

  to_restricted_growth_word_intertwining()

    Convert a set partition of \(\{1,...,n\}\) to a word of length \(n\) with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before.

    The \(i\)-th letter of the word is the numbers of crossings of the arc (or half-arc) in the extended arc diagram ending at \(i\), with arcs (or half-arcs) beginning at a smaller element and ending at a larger element.

    OUTPUT: a restricted growth word

    See also

    `to_restricted_growth_word()` `SetPartitions.from_restricted_growth_word()`

    EXAMPLES:

    Sage

        sage: P = SetPartition([[1,4],[2,8],[3,5,6,9],[7]])
        sage: P.to_restricted_growth_word_intertwining()
        [0, 1, 2, 2, 1, 0, 3, 3, 2]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(8)],[Integer(3),Integer(5),Integer(6),Integer(9)],[Integer(7)]])
        >>> P.to_restricted_growth_word_intertwining()
        [0, 1, 2, 2, 1, 0, 3, 3, 2]

  to_rook_placement(bijection='arcs')

    Return a set of pairs defining a placement of non-attacking rooks on a triangular board.

    The cells of the board corresponding to a set partition of \(\{1,...,n\}\) are the pairs \((i,j)\) with \(0 < i < j < n+1\).

    INPUT:

    - `bijection` – (default: `arcs`) defines the bijection from set partitions to rook placements. These are currently:

      - `arcs`: `arcs()`

      - `gamma`: `to_rook_placement_gamma()`

      - `rho`: `to_rook_placement_rho()`

      - `psi`: `to_rook_placement_psi()`

    See also

    `SetPartitions.from_rook_placement()`

    EXAMPLES:

    Sage

        sage: P = SetPartition([[1,2,4,7],[3,9],[5,6,10,11,13],[8],[12]])
        sage: P.to_rook_placement()
        [(1, 2), (2, 4), (4, 7), (3, 9), (5, 6), (6, 10), (10, 11), (11, 13)]
        sage: P.to_rook_placement("gamma")
        [(1, 4), (3, 5), (4, 6), (5, 8), (7, 11), (8, 9), (10, 12), (12, 13)]
        sage: P.to_rook_placement("rho")
        [(1, 2), (2, 6), (3, 4), (4, 10), (5, 9), (6, 7), (10, 11), (11, 13)]
        sage: P.to_rook_placement("psi")
        [(1, 2), (2, 6), (3, 4), (5, 9), (6, 7), (7, 10), (9, 11), (11, 13)]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(2),Integer(4),Integer(7)],[Integer(3),Integer(9)],[Integer(5),Integer(6),Integer(10),Integer(11),Integer(13)],[Integer(8)],[Integer(12)]])
        >>> P.to_rook_placement()
        [(1, 2), (2, 4), (4, 7), (3, 9), (5, 6), (6, 10), (10, 11), (11, 13)]
        >>> P.to_rook_placement("gamma")
        [(1, 4), (3, 5), (4, 6), (5, 8), (7, 11), (8, 9), (10, 12), (12, 13)]
        >>> P.to_rook_placement("rho")
        [(1, 2), (2, 6), (3, 4), (4, 10), (5, 9), (6, 7), (10, 11), (11, 13)]
        >>> P.to_rook_placement("psi")
        [(1, 2), (2, 6), (3, 4), (5, 9), (6, 7), (7, 10), (9, 11), (11, 13)]

  to_rook_placement_gamma()

    Return the rook diagram obtained by placing rooks according to Wachs and White’s bijection gamma.

    Note that our index convention differs from the convention in [WW1991]: regarding the rook board as a lower-right triangular grid, we refer with \((i,j)\) to the cell in the \(i\)-th column from the right and the \(j\)-th row from the top.

    The algorithm proceeds as follows: non-attacking rooks are placed beginning at the left column. If \(n+1-i\) is an opener, column \(i\) remains empty. Otherwise, we place a rook into column \(i\), such that the number of cells below the rook, which are not yet attacked by another rook, equals the index of the block to which \(n+1-i\) belongs.

    OUTPUT: list of coordinates

    See also

    - `to_rook_placement()`

    - `SetPartitions.from_rook_placement()`

    - `SetPartitions.from_rook_placement_gamma()`

    EXAMPLES:

    Sage

        sage: P = SetPartition([[1,4],[2,8],[3,5,6,9],[7]])
        sage: P.to_rook_placement_gamma()
        [(1, 3), (2, 7), (4, 5), (5, 6), (6, 9)]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(8)],[Integer(3),Integer(5),Integer(6),Integer(9)],[Integer(7)]])
        >>> P.to_rook_placement_gamma()
        [(1, 3), (2, 7), (4, 5), (5, 6), (6, 9)]

    Figure 5 in [WW1991]:

    Sage

        sage: P = SetPartition([[1,2,4,7],[3,9],[5,6,10,11,13],[8],[12]])
        sage: r = P.to_rook_placement_gamma(); r
        [(1, 4), (3, 5), (4, 6), (5, 8), (7, 11), (8, 9), (10, 12), (12, 13)]

    [Python]

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(2),Integer(4),Integer(7)],[Integer(3),Integer(9)],[Integer(5),Integer(6),Integer(10),Integer(11),Integer(13)],[Integer(8)],[Integer(12)]])
        >>> r = P.to_rook_placement_gamma(); r
        [(1, 4), (3, 5), (4, 6), (5, 8), (7, 11), (8, 9), (10, 12), (12, 13)]

  to_rook_placement_psi()

    Return the rook diagram obtained by placing rooks according to Yip’s bijection psi.

    OUTPUT: list of coordinates

    See also

    - `to_rook_placement()`

    - `SetPartitions.from_rook_placement()`

    - `SetPartitions.from_rook_placement_psi()`

    EXAMPLES:

    Example 36 (arXiv version: Example 4.5) in [Yip2018]:

    Sage

        sage: P = SetPartition([[1, 5], [2], [3, 8, 9], [4], [6, 7]])
        sage: P.to_rook_placement_psi()
        [(1, 7), (3, 8), (4, 5), (7, 9)]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1), Integer(5)], [Integer(2)], [Integer(3), Integer(8), Integer(9)], [Integer(4)], [Integer(6), Integer(7)]])
        >>> P.to_rook_placement_psi()
        [(1, 7), (3, 8), (4, 5), (7, 9)]

    Note that the columns corresponding to the minimal elements of the blocks remain empty.

  to_rook_placement_rho()

    Return the rook diagram obtained by placing rooks according to Wachs and White’s bijection rho.

    Note that our index convention differs from the convention in [WW1991]: regarding the rook board as a lower-right triangular grid, we refer with \((i,j)\) to the cell in the \(i\)-th column from the right and the \(j\)-th row from the top.

    The algorithm proceeds as follows: non-attacking rooks are placed beginning at the top row. The columns corresponding to the closers of the set partition remain empty. Let \(rs_j\) be the number of closers which are larger than \(j\) and whose block is before the block of \(j\).

    We then place a rook into row \(j\), such that the number of cells to the left of the rook, which are not yet attacked by another rook and are not in a column corresponding to a closer, equals \(rs_j\), unless there are not enough cells in this row available, in which case the row remains empty.

    One can show that the precisely those rows which correspond to openers of the set partition remain empty.

    OUTPUT: list of coordinates

    See also

    - `to_rook_placement()`

    - `SetPartitions.from_rook_placement()`

    - `SetPartitions.from_rook_placement_rho()`

    EXAMPLES:

    Sage

        sage: P = SetPartition([[1,4],[2,8],[3,5,6,9],[7]])
        sage: P.to_rook_placement_rho()
        [(1, 5), (2, 6), (3, 4), (5, 9), (6, 8)]

    Python

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(4)],[Integer(2),Integer(8)],[Integer(3),Integer(5),Integer(6),Integer(9)],[Integer(7)]])
        >>> P.to_rook_placement_rho()
        [(1, 5), (2, 6), (3, 4), (5, 9), (6, 8)]

    Figure 6 in [WW1991]:

    Sage

        sage: P = SetPartition([[1,2,4,7],[3,9],[5,6,10,11,13],[8],[12]])
        sage: r = P.to_rook_placement_rho(); r
        [(1, 2), (2, 6), (3, 4), (4, 10), (5, 9), (6, 7), (10, 11), (11, 13)]

        sage: sorted(P.closers() + [i for i, _ in r]) == list(range(1,14))
        True
        sage: sorted(P.openers() + [j for _, j in r]) == list(range(1,14))
        True

    [Python]

        >>> from sage.all import *
        >>> P = SetPartition([[Integer(1),Integer(2),Integer(4),Integer(7)],[Integer(3),Integer(9)],[Integer(5),Integer(6),Integer(10),Integer(11),Integer(13)],[Integer(8)],[Integer(12)]])
        >>> r = P.to_rook_placement_rho(); r
        [(1, 2), (2, 6), (3, 4), (4, 10), (5, 9), (6, 7), (10, 11), (11, 13)]

        >>> sorted(P.closers() + [i for i, _ in r]) == list(range(Integer(1),Integer(14)))
        True
        >>> sorted(P.openers() + [j for _, j in r]) == list(range(Integer(1),Integer(14)))
        True

class sage.combinat.set_partition.SetPartitions

  Bases: `UniqueRepresentation`, `Parent`

  An (unordered) partition of a set \(S\) is a set of pairwise disjoint nonempty subsets with union \(S\), and is represented by a sorted list of such subsets.

  `SetPartitions(s)` returns the class of all set partitions of the set `s`, which can be given as a set or a string; if a string, each character is considered an element.

  `SetPartitions(n)`, where `n` is an integer, returns the class of all set partitions of the set \(\{1, 2, \ldots, n\}\).

  You may specify a second argument \(k\). If \(k\) is an integer, `SetPartitions` returns the class of set partitions into \(k\) parts; if it is an integer partition, `SetPartitions` returns the class of set partitions whose block sizes correspond to that integer partition.

  The Bell number \(B_n\), named in honor of Eric Temple Bell, is the number of different partitions of a set with \(n\) elements.

  EXAMPLES:

  Sage

      sage: S = [1,2,3,4]
      sage: SetPartitions(S, 2)
      Set partitions of {1, 2, 3, 4} with 2 parts
      sage: SetPartitions([1,2,3,4], [3,1]).list()                                    # needs sage.graphs sage.rings.finite_rings
      [{{1}, {2, 3, 4}}, {{1, 2, 3}, {4}}, {{1, 2, 4}, {3}}, {{1, 3, 4}, {2}}]
      sage: SetPartitions(7, [3,3,1]).cardinality()                                   # needs sage.libs.flint
      70

  Python

      >>> from sage.all import *
      >>> S = [Integer(1),Integer(2),Integer(3),Integer(4)]
      >>> SetPartitions(S, Integer(2))
      Set partitions of {1, 2, 3, 4} with 2 parts
      >>> SetPartitions([Integer(1),Integer(2),Integer(3),Integer(4)], [Integer(3),Integer(1)]).list()                                    # needs sage.graphs sage.rings.finite_rings
      [{{1}, {2, 3, 4}}, {{1, 2, 3}, {4}}, {{1, 2, 4}, {3}}, {{1, 3, 4}, {2}}]
      >>> SetPartitions(Integer(7), [Integer(3),Integer(3),Integer(1)]).cardinality()                                   # needs sage.libs.flint
      70

  In strings, repeated letters are not considered distinct as of Issue #14140:

  Sage

      sage: SetPartitions('abcde').cardinality()                                      # needs sage.libs.flint
      52
      sage: SetPartitions('aabcd').cardinality()                                      # needs sage.libs.flint
      15

  [Python]

      >>> from sage.all import *
      >>> SetPartitions('abcde').cardinality()                                      # needs sage.libs.flint
      52
      >>> SetPartitions('aabcd').cardinality()                                      # needs sage.libs.flint
      15

  If the number of parts exceeds the length of the set, an empty iterator is returned (Issue #37643):

  Sage

      sage: SetPartitions(range(3), 4).list()
      []
      sage: SetPartitions('abcd', 6).list()
      []

  Python

      >>> from sage.all import *
      >>> SetPartitions(range(Integer(3)), Integer(4)).list()
      []
      >>> SetPartitions('abcd', Integer(6)).list()
      []

  REFERENCES:

  - Wikipedia article Partition_of_a_set

  Element

    alias of `SetPartition`

  from_arcs(arcs, n)

    Return the coarsest set partition of \(\{1,...,n\}\) such that any two elements connected by an arc are in the same block.

    INPUT:

    - `n` – integer specifying the size of the set partition to be produced

    - `arcs` – list of pairs specifying which elements are in the same block

    See also

    - `from_rook_placement()`

    - `SetPartition.to_rook_placement()`

    - `SetPartition.arcs()`

    EXAMPLES:

    Sage

        sage: SetPartitions().from_arcs([(2,3)], 5)
        {{1}, {2, 3}, {4}, {5}}

    Python

        >>> from sage.all import *
        >>> SetPartitions().from_arcs([(Integer(2),Integer(3))], Integer(5))
        {{1}, {2, 3}, {4}, {5}}

  from_restricted_growth_word(w, bijection='blocks')

    Convert a word of length \(n\) with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before to a set partition of \(\{1,...,n\}\).

    INPUT:

    - `w` – a restricted growth word

    - `bijection` – (default: `blocks`) defines the map from restricted growth functions to set partitions. These are currently:

      - `blocks`: .

      - `intertwining`: `from_restricted_growth_word_intertwining()`.

    OUTPUT: a set partition

    See also

    `SetPartition.to_restricted_growth_word()`

    EXAMPLES:

    Sage

        sage: SetPartitions().from_restricted_growth_word([0, 1, 2, 0, 2, 2, 3, 1, 2])
        {{1, 4}, {2, 8}, {3, 5, 6, 9}, {7}}

        sage: SetPartitions().from_restricted_growth_word([0, 0, 1, 0, 2, 2, 0, 3, 1, 2, 2, 4, 2])
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

        sage: SetPartitions().from_restricted_growth_word([0, 0, 1, 0, 2, 2, 0, 3, 1, 2, 2, 4, 2], "intertwining")
        {{1, 2, 6, 7, 9}, {3, 4}, {5, 10, 13}, {8, 11}, {12}}

    Python

        >>> from sage.all import *
        >>> SetPartitions().from_restricted_growth_word([Integer(0), Integer(1), Integer(2), Integer(0), Integer(2), Integer(2), Integer(3), Integer(1), Integer(2)])
        {{1, 4}, {2, 8}, {3, 5, 6, 9}, {7}}

        >>> SetPartitions().from_restricted_growth_word([Integer(0), Integer(0), Integer(1), Integer(0), Integer(2), Integer(2), Integer(0), Integer(3), Integer(1), Integer(2), Integer(2), Integer(4), Integer(2)])
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

        >>> SetPartitions().from_restricted_growth_word([Integer(0), Integer(0), Integer(1), Integer(0), Integer(2), Integer(2), Integer(0), Integer(3), Integer(1), Integer(2), Integer(2), Integer(4), Integer(2)], "intertwining")
        {{1, 2, 6, 7, 9}, {3, 4}, {5, 10, 13}, {8, 11}, {12}}

  from_restricted_growth_word_blocks(w)

    Convert a word of length \(n\) with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before to a set partition of \(\{1,...,n\}\).

    `w[i]` is the index of the block containing `i+1` when sorting the blocks by their minimal element.

    INPUT:

    - `w` – a restricted growth word

    OUTPUT: a set partition

    See also

    `from_restricted_growth_word()` `SetPartition.to_restricted_growth_word()`

    EXAMPLES:

    Sage

        sage: SetPartitions().from_restricted_growth_word_blocks([0, 0, 1, 0, 2, 2, 0, 3, 1, 2, 2, 4, 2])
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

    Python

        >>> from sage.all import *
        >>> SetPartitions().from_restricted_growth_word_blocks([Integer(0), Integer(0), Integer(1), Integer(0), Integer(2), Integer(2), Integer(0), Integer(3), Integer(1), Integer(2), Integer(2), Integer(4), Integer(2)])
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

  from_restricted_growth_word_intertwining(w)

    Convert a word of length \(n\) with letters in the nonnegative integers such that each letter is at most 1 larger than all the letters before to a set partition of \(\{1,...,n\}\).

    The \(i\)-th letter of the word is the numbers of crossings of the arc (or half-arc) in the extended arc diagram ending at \(i\), with arcs (or half-arcs) beginning at a smaller element and ending at a larger element.

    INPUT:

    - `w` – a restricted growth word

    OUTPUT: a set partition

    See also

    `from_restricted_growth_word()` `SetPartition.to_restricted_growth_word()`

    EXAMPLES:

    Sage

        sage: SetPartitions().from_restricted_growth_word_intertwining([0, 0, 1, 0, 2, 2, 0, 3, 1, 2, 2, 4, 2])
        {{1, 2, 6, 7, 9}, {3, 4}, {5, 10, 13}, {8, 11}, {12}}

    Python

        >>> from sage.all import *
        >>> SetPartitions().from_restricted_growth_word_intertwining([Integer(0), Integer(0), Integer(1), Integer(0), Integer(2), Integer(2), Integer(0), Integer(3), Integer(1), Integer(2), Integer(2), Integer(4), Integer(2)])
        {{1, 2, 6, 7, 9}, {3, 4}, {5, 10, 13}, {8, 11}, {12}}

  from_rook_placement(rooks, bijection='arcs', n=None)

    Convert a rook placement of the triangular grid to a set partition of \(\{1,...,n\}\).

    If `n` is not given, it is first checked whether it can be determined from the parent, otherwise it is the maximal occurring integer in the set of rooks.

    INPUT:

    - `rooks` – list of pairs \((i,j)\) satisfying \(0 < i < j < n+1\)

    - `bijection` – (default: `arcs`) defines the map from rook placements to set partitions. These are currently:

      - `arcs`: `from_arcs()`.

      - `gamma`: `from_rook_placement_gamma()`.

      - `rho`: `from_rook_placement_rho()`.

      - `psi`: `from_rook_placement_psi()`.

    - `n` – (optional) the size of the ground set

    See also

    `SetPartition.to_rook_placement()`

    EXAMPLES:

    Sage

        sage: SetPartitions(9).from_rook_placement([[1,4],[2,8],[3,5],[5,6],[6,9]])
        {{1, 4}, {2, 8}, {3, 5, 6, 9}, {7}}

        sage: SetPartitions(13).from_rook_placement([[12,13],[10,12],[8,9],[7,11],[5,8],[4,6],[3,5],[1,4]], "gamma")
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

    Python

        >>> from sage.all import *
        >>> SetPartitions(Integer(9)).from_rook_placement([[Integer(1),Integer(4)],[Integer(2),Integer(8)],[Integer(3),Integer(5)],[Integer(5),Integer(6)],[Integer(6),Integer(9)]])
        {{1, 4}, {2, 8}, {3, 5, 6, 9}, {7}}

        >>> SetPartitions(Integer(13)).from_rook_placement([[Integer(12),Integer(13)],[Integer(10),Integer(12)],[Integer(8),Integer(9)],[Integer(7),Integer(11)],[Integer(5),Integer(8)],[Integer(4),Integer(6)],[Integer(3),Integer(5)],[Integer(1),Integer(4)]], "gamma")
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

  from_rook_placement_gamma(rooks, n)

    Return the set partition of \(\{1,...,n\}\) corresponding to the given rook placement by applying Wachs and White’s bijection gamma.

    Note that our index convention differs from the convention in [WW1991]: regarding the rook board as a lower-right triangular grid, we refer with \((i,j)\) to the cell in the \(i\)-th column from the right and the \(j\)-th row from the top.

    INPUT:

    - `n` – integer specifying the size of the set partition to be produced

    - `rooks` – list of pairs \((i,j)\) such that \(0 < i < j < n+1\)

    OUTPUT: a set partition

    See also

    - `from_rook_placement()`

    - `SetPartition.to_rook_placement()`

    - `SetPartition.to_rook_placement_gamma()`

    EXAMPLES:

    Figure 5 in [WW1991] concerns the following rook placement:

    Sage

        sage: r = [(1, 4), (3, 5), (4, 6), (5, 8), (7, 11), (8, 9), (10, 12), (12, 13)]

    Python

        >>> from sage.all import *
        >>> r = [(Integer(1), Integer(4)), (Integer(3), Integer(5)), (Integer(4), Integer(6)), (Integer(5), Integer(8)), (Integer(7), Integer(11)), (Integer(8), Integer(9)), (Integer(10), Integer(12)), (Integer(12), Integer(13))]

    Note that the rook \((1, 4)\), translated into Wachs and White’s convention, is a rook in row 4 from the top and column 13 from the left. The corresponding set partition is:

    Sage

        sage: SetPartitions().from_rook_placement_gamma(r, 13)
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

    [Python]

        >>> from sage.all import *
        >>> SetPartitions().from_rook_placement_gamma(r, Integer(13))
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

  from_rook_placement_psi(rooks, n)

    Return the set partition of \(\{1,...,n\}\) corresponding to the given rook placement by applying Yip’s bijection psi.

    INPUT:

    - `n` – integer specifying the size of the set partition to be produced

    - `rooks` – list of pairs \((i,j)\) such that \(0 < i < j < n+1\)

    OUTPUT: a set partition

    See also

    - `from_rook_placement()`

    - `SetPartition.to_rook_placement()`

    - `SetPartition.to_rook_placement_psi()`

    EXAMPLES:

    Example 36 (arXiv version: Example 4.5) in [Yip2018] concerns the following rook placement:

    Sage

        sage: r = [(4,5), (1,7), (3, 8), (7,9)]
        sage: SetPartitions().from_rook_placement_psi(r, 9)
        {{1, 5}, {2}, {3, 8, 9}, {4}, {6, 7}}

    Python

        >>> from sage.all import *
        >>> r = [(Integer(4),Integer(5)), (Integer(1),Integer(7)), (Integer(3), Integer(8)), (Integer(7),Integer(9))]
        >>> SetPartitions().from_rook_placement_psi(r, Integer(9))
        {{1, 5}, {2}, {3, 8, 9}, {4}, {6, 7}}

  from_rook_placement_rho(rooks, n)

    Return the set partition of \(\{1,...,n\}\) corresponding to the given rook placement by applying Wachs and White’s bijection rho.

    Note that our index convention differs from the convention in [WW1991]: regarding the rook board as a lower-right triangular grid, we refer with \((i,j)\) to the cell in the \(i\)-th column from the right and the \(j\)-th row from the top.

    INPUT:

    - `n` – integer specifying the size of the set partition to be produced

    - `rooks` – list of pairs \((i,j)\) such that \(0 < i < j < n+1\)

    OUTPUT: a set partition

    See also

    - `from_rook_placement()`

    - `SetPartition.to_rook_placement()`

    - `SetPartition.to_rook_placement_rho()`

    EXAMPLES:

    Figure 5 in [WW1991] concerns the following rook placement:

    Sage

        sage: r = [(1, 2), (2, 6), (3, 4), (4, 10), (5, 9), (6, 7), (10, 11), (11, 13)]

    Python

        >>> from sage.all import *
        >>> r = [(Integer(1), Integer(2)), (Integer(2), Integer(6)), (Integer(3), Integer(4)), (Integer(4), Integer(10)), (Integer(5), Integer(9)), (Integer(6), Integer(7)), (Integer(10), Integer(11)), (Integer(11), Integer(13))]

    Note that the rook \((1, 2)\), translated into Wachs and White’s convention, is a rook in row 2 from the top and column 13 from the left. The corresponding set partition is:

    Sage

        sage: SetPartitions().from_rook_placement_rho(r, 13)
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

    [Python]

        >>> from sage.all import *
        >>> SetPartitions().from_rook_placement_rho(r, Integer(13))
        {{1, 2, 4, 7}, {3, 9}, {5, 6, 10, 11, 13}, {8}, {12}}

  is_less_than(s, t)

    Check if \(s < t\) in the refinement ordering on set partitions.

    This means that \(s\) is a refinement of \(t\) and satisfies \(s \neq t\).

    A set partition \(s\) is said to be a refinement of a set partition \(t\) of the same set if and only if each part of \(s\) is a subset of a part of \(t\).

    EXAMPLES:

    Sage

        sage: S = SetPartitions(4)
        sage: s = S([[1,3],[2,4]])
        sage: t = S([[1],[2],[3],[4]])
        sage: S.is_less_than(t, s)
        True
        sage: S.is_less_than(s, t)
        False
        sage: S.is_less_than(s, s)
        False

    Python

        >>> from sage.all import *
        >>> S = SetPartitions(Integer(4))
        >>> s = S([[Integer(1),Integer(3)],[Integer(2),Integer(4)]])
        >>> t = S([[Integer(1)],[Integer(2)],[Integer(3)],[Integer(4)]])
        >>> S.is_less_than(t, s)
        True
        >>> S.is_less_than(s, t)
        False
        >>> S.is_less_than(s, s)
        False

  is_strict_refinement(s, t)

    Return `True` if `s` is a strict refinement of `t` and satisfies \(s \neq t\).

    A set partition \(s\) is said to be a strict refinement of a set partition \(t\) of the same set if and only if one can obtain \(t\) from \(s\) by repeatedly combining pairs of parts whose convex hulls don’t intersect (i. e., whenever we are combining two parts, the maximum of each of them should be smaller than the minimum of the other).

    EXAMPLES:

    Sage

        sage: S = SetPartitions(4)
        sage: s = S([[1],[2],[3],[4]])
        sage: t = S([[1,3],[2,4]])
        sage: u = S([[1,2,3,4]])
        sage: S.is_strict_refinement(s, t)
        True
        sage: S.is_strict_refinement(t, u)
        False
        sage: A = SetPartition([[1,3],[2,4]])
        sage: B = SetPartition([[1,2,3,4]])
        sage: S.is_strict_refinement(s, A)
        True
        sage: S.is_strict_refinement(t, B)
        False

    Python

        >>> from sage.all import *
        >>> S = SetPartitions(Integer(4))
        >>> s = S([[Integer(1)],[Integer(2)],[Integer(3)],[Integer(4)]])
        >>> t = S([[Integer(1),Integer(3)],[Integer(2),Integer(4)]])
        >>> u = S([[Integer(1),Integer(2),Integer(3),Integer(4)]])
        >>> S.is_strict_refinement(s, t)
        True
        >>> S.is_strict_refinement(t, u)
        False
        >>> A = SetPartition([[Integer(1),Integer(3)],[Integer(2),Integer(4)]])
        >>> B = SetPartition([[Integer(1),Integer(2),Integer(3),Integer(4)]])
        >>> S.is_strict_refinement(s, A)
        True
        >>> S.is_strict_refinement(t, B)
        False

  lt(s, t)

    alias of `is_less_than()`.

class sage.combinat.set_partition.SetPartitions_all

  Bases: `SetPartitions`

  All set partitions.

  subset(size=None, **kwargs)

    Return the subset of set partitions of a given size and additional keyword arguments.

    EXAMPLES:

    Sage

        sage: P = SetPartitions()
        sage: P.subset(4)
        Set partitions of {1, 2, 3, 4}

    Python

        >>> from sage.all import *
        >>> P = SetPartitions()
        >>> P.subset(Integer(4))
        Set partitions of {1, 2, 3, 4}

class sage.combinat.set_partition.SetPartitions_set(s)

  Bases: `SetPartitions`

  Set partitions of a fixed set \(S\).

  base_set()

    Return the base set of `self`.

    EXAMPLES:

    Sage

        sage: SetPartitions(3).base_set()
        {1, 2, 3}

        sage: sorted(SetPartitions(["a", "b", "c"]).base_set())
        ['a', 'b', 'c']

    Python

        >>> from sage.all import *
        >>> SetPartitions(Integer(3)).base_set()
        {1, 2, 3}

        >>> sorted(SetPartitions(["a", "b", "c"]).base_set())
        ['a', 'b', 'c']

  base_set_cardinality()

    Return the cardinality of the base set of `self`.

    EXAMPLES:

    Sage

        sage: SetPartitions(3).base_set_cardinality()
        3

    Python

        >>> from sage.all import *
        >>> SetPartitions(Integer(3)).base_set_cardinality()
        3

  cardinality()

    Return the number of set partitions of the set \(S\).

    The cardinality is given by the \(n\)-th Bell number where \(n\) is the number of elements in the set \(S\).

    EXAMPLES:

    Sage

        sage: # needs sage.libs.flint
        sage: SetPartitions([1,2,3,4]).cardinality()
        15
        sage: SetPartitions(3).cardinality()
        5
        sage: SetPartitions(3,2).cardinality()
        3
        sage: SetPartitions([]).cardinality()
        1

    Python

        >>> from sage.all import *
        >>> # needs sage.libs.flint
        >>> SetPartitions([Integer(1),Integer(2),Integer(3),Integer(4)]).cardinality()
        15
        >>> SetPartitions(Integer(3)).cardinality()
        5
        >>> SetPartitions(Integer(3),Integer(2)).cardinality()
        3
        >>> SetPartitions([]).cardinality()
        1

  random_element()

    Return a random set partition.

    This is a very naive implementation of Knuths outline in F3B, 7.2.1.5.

    EXAMPLES:

    Sage

        sage: S = SetPartitions(10)
        sage: s = S.random_element()                                                # needs sage.symbolic
        sage: s.parent() is S                                                       # needs sage.symbolic
        True
        sage: assert s in S, s                                                      # needs sage.symbolic

        sage: S = SetPartitions(["a", "b", "c"])
        sage: s = S.random_element()                                                # needs sage.symbolic
        sage: s.parent() is S                                                       # needs sage.symbolic
        True
        sage: assert s in S, s                                                      # needs sage.symbolic

    Python

        >>> from sage.all import *
        >>> S = SetPartitions(Integer(10))
        >>> s = S.random_element()                                                # needs sage.symbolic
        >>> s.parent() is S                                                       # needs sage.symbolic
        True
        >>> assert s in S, s                                                      # needs sage.symbolic

        >>> S = SetPartitions(["a", "b", "c"])
        >>> s = S.random_element()                                                # needs sage.symbolic
        >>> s.parent() is S                                                       # needs sage.symbolic
        True
        >>> assert s in S, s                                                      # needs sage.symbolic

class sage.combinat.set_partition.SetPartitions_setn(s, k)

  Bases: `SetPartitions_set`

  Set partitions with a given number of blocks.

  cardinality()

    The Stirling number of the second kind is the number of partitions of a set of size \(n\) into \(k\) blocks.

    EXAMPLES:

    Sage

        sage: SetPartitions(5, 3).cardinality()
        25
        sage: stirling_number2(5,3)
        25

    Python

        >>> from sage.all import *
        >>> SetPartitions(Integer(5), Integer(3)).cardinality()
        25
        >>> stirling_number2(Integer(5),Integer(3))
        25

  number_of_blocks()

    Return the number of blocks of the set partitions in `self`.

    EXAMPLES:

    Sage

        sage: SetPartitions(5, 3).number_of_blocks()
        3

    Python

        >>> from sage.all import *
        >>> SetPartitions(Integer(5), Integer(3)).number_of_blocks()
        3

  random_element()

    Return a random set partition of `self`.

    See https://mathoverflow.net/questions/141999.

    EXAMPLES:

    Sage

        sage: S = SetPartitions(10, 4)
        sage: s = S.random_element()
        sage: s.parent() is S
        True
        sage: assert s in S, s

        sage: S = SetPartitions(["a", "b", "c"], 2)
        sage: s = S.random_element()
        sage: s.parent() is S
        True
        sage: assert s in S, s

    Python

        >>> from sage.all import *
        >>> S = SetPartitions(Integer(10), Integer(4))
        >>> s = S.random_element()
        >>> s.parent() is S
        True
        >>> assert s in S, s

        >>> S = SetPartitions(["a", "b", "c"], Integer(2))
        >>> s = S.random_element()
        >>> s.parent() is S
        True
        >>> assert s in S, s

class sage.combinat.set_partition.SetPartitions_setparts(s, parts)

  Bases: `SetPartitions_set`

  Set partitions with fixed partition sizes corresponding to an integer partition \(\lambda\).

  cardinality()

    Return the cardinality of `self`.

    This algorithm counts for each block of the partition the number of ways to fill it using values from the set. Then, for each distinct value \(v\) of block size, we divide the result by the number of ways to arrange the blocks of size \(v\) in the set partition.

    For example, if we want to count the number of set partitions of size 13 having [3,3,3,2,2] as underlying partition we compute the number of ways to fill each block of the partition, which is \(\binom{13}{3} \binom{10}{3} \binom{7}{3} \binom{4}{2}\binom{2}{2}\) and as we have three blocks of size \(3\) and two blocks of size \(2\), we divide the result by \(3!2!\) which gives us \(600600\).

    EXAMPLES:

    Sage

        sage: SetPartitions(3, [2,1]).cardinality()
        3
        sage: SetPartitions(13, Partition([3,3,3,2,2])).cardinality()
        600600

    Python

        >>> from sage.all import *
        >>> SetPartitions(Integer(3), [Integer(2),Integer(1)]).cardinality()
        3
        >>> SetPartitions(Integer(13), Partition([Integer(3),Integer(3),Integer(3),Integer(2),Integer(2)])).cardinality()
        600600

  random_element()

    Return a random set partition of `self`.

    ALGORITHM:

    Based on the cardinality method. For each block size \(k_i\), we choose a uniformly random subset \(X_i \subseteq S_i\) of size \(k_i\) of the elements \(S_i\) that have not yet been selected. Thus, we define \(S_{i+1} = S_i \setminus X_i\) with \(S_i = S\) being the defining set. This is not yet proven to be uniformly distributed, but numerical tests show this is likely uniform.

    EXAMPLES:

    Sage

        sage: S = SetPartitions(10, [4,3,2,1])
        sage: s = S.random_element()
        sage: s.parent() is S
        True
        sage: assert s in S, s

        sage: S = SetPartitions(["a", "b", "c", "d"], [2,2])
        sage: s = S.random_element()
        sage: s.parent() is S
        True
        sage: assert s in S, s

    Python

        >>> from sage.all import *
        >>> S = SetPartitions(Integer(10), [Integer(4),Integer(3),Integer(2),Integer(1)])
        >>> s = S.random_element()
        >>> s.parent() is S
        True
        >>> assert s in S, s

        >>> S = SetPartitions(["a", "b", "c", "d"], [Integer(2),Integer(2)])
        >>> s = S.random_element()
        >>> s.parent() is S
        True
        >>> assert s in S, s

  shape()

    Return the partition of block sizes of the set partitions in `self`.

    EXAMPLES:

    Sage

        sage: SetPartitions(5, [2,2,1]).shape()
        [2, 2, 1]

    Python

        >>> from sage.all import *
        >>> SetPartitions(Integer(5), [Integer(2),Integer(2),Integer(1)]).shape()
        [2, 2, 1]

sage.combinat.set_partition.cyclic_permutations_of_set_partition(set_part)

  Return all combinations of cyclic permutations of each cell of the set partition.

  AUTHORS:

  - Robert L. Miller

  EXAMPLES:

  Sage

      sage: from sage.combinat.set_partition import cyclic_permutations_of_set_partition
      sage: cyclic_permutations_of_set_partition([[1,2,3,4],[5,6,7]])
      [[(1, 2, 3, 4), (5, 6, 7)],
       [(1, 2, 4, 3), (5, 6, 7)],
       [(1, 3, 2, 4), (5, 6, 7)],
       [(1, 3, 4, 2), (5, 6, 7)],
       [(1, 4, 2, 3), (5, 6, 7)],
       [(1, 4, 3, 2), (5, 6, 7)],
       [(1, 2, 3, 4), (5, 7, 6)],
       [(1, 2, 4, 3), (5, 7, 6)],
       [(1, 3, 2, 4), (5, 7, 6)],
       [(1, 3, 4, 2), (5, 7, 6)],
       [(1, 4, 2, 3), (5, 7, 6)],
       [(1, 4, 3, 2), (5, 7, 6)]]

  Python

      >>> from sage.all import *
      >>> from sage.combinat.set_partition import cyclic_permutations_of_set_partition
      >>> cyclic_permutations_of_set_partition([[Integer(1),Integer(2),Integer(3),Integer(4)],[Integer(5),Integer(6),Integer(7)]])
      [[(1, 2, 3, 4), (5, 6, 7)],
       [(1, 2, 4, 3), (5, 6, 7)],
       [(1, 3, 2, 4), (5, 6, 7)],
       [(1, 3, 4, 2), (5, 6, 7)],
       [(1, 4, 2, 3), (5, 6, 7)],
       [(1, 4, 3, 2), (5, 6, 7)],
       [(1, 2, 3, 4), (5, 7, 6)],
       [(1, 2, 4, 3), (5, 7, 6)],
       [(1, 3, 2, 4), (5, 7, 6)],
       [(1, 3, 4, 2), (5, 7, 6)],
       [(1, 4, 2, 3), (5, 7, 6)],
       [(1, 4, 3, 2), (5, 7, 6)]]

sage.combinat.set_partition.cyclic_permutations_of_set_partition_iterator(set_part)

  Iterate over all combinations of cyclic permutations of each cell of the set partition.

  AUTHORS:

  - Robert L. Miller

  EXAMPLES:

  Sage

      sage: from sage.combinat.set_partition import cyclic_permutations_of_set_partition_iterator
      sage: list(cyclic_permutations_of_set_partition_iterator([[1,2,3,4],[5,6,7]]))
      [[(1, 2, 3, 4), (5, 6, 7)],
       [(1, 2, 4, 3), (5, 6, 7)],
       [(1, 3, 2, 4), (5, 6, 7)],
       [(1, 3, 4, 2), (5, 6, 7)],
       [(1, 4, 2, 3), (5, 6, 7)],
       [(1, 4, 3, 2), (5, 6, 7)],
       [(1, 2, 3, 4), (5, 7, 6)],
       [(1, 2, 4, 3), (5, 7, 6)],
       [(1, 3, 2, 4), (5, 7, 6)],
       [(1, 3, 4, 2), (5, 7, 6)],
       [(1, 4, 2, 3), (5, 7, 6)],
       [(1, 4, 3, 2), (5, 7, 6)]]

  Python

      >>> from sage.all import *
      >>> from sage.combinat.set_partition import cyclic_permutations_of_set_partition_iterator
      >>> list(cyclic_permutations_of_set_partition_iterator([[Integer(1),Integer(2),Integer(3),Integer(4)],[Integer(5),Integer(6),Integer(7)]]))
      [[(1, 2, 3, 4), (5, 6, 7)],
       [(1, 2, 4, 3), (5, 6, 7)],
       [(1, 3, 2, 4), (5, 6, 7)],
       [(1, 3, 4, 2), (5, 6, 7)],
       [(1, 4, 2, 3), (5, 6, 7)],
       [(1, 4, 3, 2), (5, 6, 7)],
       [(1, 2, 3, 4), (5, 7, 6)],
       [(1, 2, 4, 3), (5, 7, 6)],
       [(1, 3, 2, 4), (5, 7, 6)],
       [(1, 3, 4, 2), (5, 7, 6)],
       [(1, 4, 2, 3), (5, 7, 6)],
       [(1, 4, 3, 2), (5, 7, 6)]]