Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- r""" Plane Partitions
AUTHORS:
- Jang Soo Kim (2016): Initial implementation - Jessica Striker (2016): Added additional methods """ #***************************************************************************** # Copyright (C) 2016 Jang Soo Kim <jangsookim@skku.edu>, # 2016 Jessica Striker <jessicapalencia@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function, absolute_import from six.moves import range from six import add_metaclass
from sage.structure.list_clone import ClonableArray from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.structure.unique_representation import UniqueRepresentation from sage.structure.parent import Parent from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.combinat.posets.posets import Poset from sage.rings.integer import Integer from sage.misc.all import prod from sage.combinat.tableau import Tableau
@add_metaclass(InheritComparisonClasscallMetaclass) class PlanePartition(ClonableArray): r""" A plane partition.
A *plane partition* is a stack of cubes in the positive orthant.
INPUT:
- ``PP`` -- a list of lists which represents a tableau
- ``box_size`` -- (optional) a list ``[A, B, C]`` of 3 positive integers, where ``A``, ``B``, ``C`` are the lengths of the box in the `x`-axis, `y`-axis, `z`-axis, respectively; if this is not given, it is determined by the smallest box bounding ``PP``
OUTPUT:
The plane partition whose tableau representation is ``PP``.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP Plane partition [[4, 3, 3, 1], [2, 1, 1], [1, 1]]
TESTS::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: TestSuite(PP).run() """ @staticmethod def __classcall_private__(cls, PP, box_size=None): """ Construct a plane partition with the appropriate parent.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1], [2,1,1], [1,1]]) sage: PP.parent() is PlanePartitions((3,4,4)) True """ else: box_size = (0, 0, 0)
def __init__(self, parent, PP, check=True): """ Initialize ``self``.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: TestSuite(PP).run() """
def check(self): """ Check to see that ``self`` is a valid plane partition.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.check() """ return raise ValueError("too big in z direction") raise ValueError("too big in y direction") raise ValueError("too big in x direction")
def _repr_(self): """ Return a string representation of ``self``.
EXAMPLES::
sage: PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) Plane partition [[4, 3, 3, 1], [2, 1, 1], [1, 1]] """
def to_tableau(self): r""" Return the tableau class of ``self``.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.to_tableau() [[4, 3, 3, 1], [2, 1, 1], [1, 1]] """
def z_tableau(self): r""" Return the projection of ``self`` in the `z` direction.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.z_tableau() [[4, 3, 3, 1], [2, 1, 1, 0], [1, 1, 0, 0]] """
def y_tableau(self): r""" Return the projection of ``self`` in the `y` direction.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.y_tableau() [[4, 3, 2], [3, 1, 0], [3, 0, 0], [1, 0, 0]] """
def x_tableau(self): r""" Return the projection of ``self`` in the `x` direction.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.x_tableau() [[3, 2, 1, 1], [3, 1, 1, 0], [2, 1, 1, 0], [1, 0, 0, 0]] """
def cells(self): r""" Return the list of cells inside ``self``.
EXAMPLES::
sage: PP = PlanePartition([[3,1],[2]]) sage: PP.cells() [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [1, 0, 0], [1, 0, 1]] """
def _repr_diagram(self, show_box=False, use_unicode=False): r""" Return a string of the 3D diagram of ``self``.
INPUT:
- ``show_box`` -- boolean (default: ``False``); if ``True``, also shows the visible tiles on the `xy`-, `yz`-, `zx`-planes - ``use_unicode`` -- boolean (default: ``False``); use unicode
OUTPUT:
A string of the 3D diagram of the plane partition.
EXAMPLES::
sage: print(PlanePartition([[4,3,3,1],[2,1,1],[1,1]])._repr_diagram()) __ /\_\ __/\/_/ __/\_\/\_\ /\_\/_/\/\_\ \/\_\_\/\/_/ \/_/\_\/_/ \/_/\_\ \/_/ sage: print(PlanePartition([[4,3,3,1],[2,1,1],[1,1]])._repr_diagram(True)) ______ /_/_/\_\ /_/_/\/_/\ /_/\_\/\_\/\ /\_\/_/\/\_\/\ \/\_\_\/\/_/\/ \/_/\_\/_/\/ \_\/_/\_\/ \_\_\/_/ """
for j in range(y + z + 1)]
# add the given letter at line l and column c
drawing.pop() else:
return u"∅" if use_unicode else ""
def _ascii_art_(self): r""" Return an ascii art representation of ``self``.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: ascii_art(PP) __ /\_\ __/\/_/ __/\_\/\_\ /\_\/_/\/\_\ \/\_\_\/\/_/ \/_/\_\/_/ \/_/\_\ \/_/ """
def _unicode_art_(self): r""" Return a unicode representation of ``self``.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: unicode_art(PP) __ ╱╲_╲ __╱╲╱_╱ __╱╲_╲╱╲_╲ ╱╲_╲╱_╱╲╱╲_╲ ╲╱╲_╲_╲╱╲╱_╱ ╲╱_╱╲_╲╱_╱ ╲╱_╱╲_╲ ╲╱_╱ """
def pp(self, show_box=False): r""" Return a pretty print of the plane partition.
INPUT:
- ``show_box`` -- boolean (default: ``False``); if ``True``, also shows the visible tiles on the `xy`-, `yz`-, `zx`-planes
OUTPUT:
A pretty print of the plane partition.
EXAMPLES::
sage: PlanePartition([[4,3,3,1],[2,1,1],[1,1]]).pp() __ /\_\ __/\/_/ __/\_\/\_\ /\_\/_/\/\_\ \/\_\_\/\/_/ \/_/\_\/_/ \/_/\_\ \/_/ sage: PlanePartition([[4,3,3,1],[2,1,1],[1,1]]).pp(True) ______ /_/_/\_\ /_/_/\/_/\ /_/\_\/\_\/\ /\_\/_/\/\_\/\ \/\_\_\/\/_/\/ \/_/\_\/_/\/ \_\/_/\_\/ \_\_\/_/ """
def _latex_(self, show_box=False, colors=["white","lightgray","darkgray"]): r""" Return latex code for ``self``, which uses TikZ package to draw the plane partition.
INPUT:
- ``show_box`` -- boolean (default: ``False``); if ``True``, also shows the visible tiles on the `xy`-, `yz`-, `zx`-planes
- ``colors`` -- (default: ``["white", "lightgray", "darkgray"]``) list ``[A, B, C]`` of 3 strings representing colors
OUTPUT:
Latex code for drawing the plane partition.
EXAMPLES::
sage: PP = PlanePartition([[1]]) sage: latex(PP) \begin{tikzpicture} \draw[fill=white,shift={(210:0)},shift={(-30:0)},shift={(90:1)}] (0,0)--(-30:1)--(0,-1)--(210:1)--(0,0); \draw[fill=darkgray,shift={(210:0)},shift={(-30:1)},shift={(90:0)}] (0,0)--(210:1)--(150:1)--(0,1)--(0,0); \draw[fill=lightgray,shift={(210:1)},shift={(-30:0)},shift={(90:0)}] (0,0)--(0,1)--(30:1)--(-30:1)--(0,0); \end{tikzpicture} """
def plot(self, show_box=False, colors=["white","lightgray","darkgray"]): r""" Return a plot of ``self``.
INPUT:
- ``show_box`` -- boolean (default: ``False``); if ``True``, also shows the visible tiles on the `xy`-, `yz`-, `zx`-planes
- ``colors`` -- (default: ``["white", "lightgray", "darkgray"]``) list ``[A, B, C]`` of 3 strings representing colors
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.plot() Graphics object consisting of 27 graphics primitives """ P[1]+i*Xdir[1]+j*Ydir[1]+k*Zdir[1]] for P in side]
def complement(self, tableau_only=False): r""" Return the complement of ``self``.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.complement() Plane partition [[4, 4, 3, 3], [4, 3, 3, 2], [3, 1, 1, 0]] sage: PP.complement(True) [[4, 4, 3, 3], [4, 3, 3, 2], [3, 1, 1, 0]] """ else:
def transpose(self, tableau_only=False): r""" Return the transpose of ``self``.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.transpose() Plane partition [[4, 2, 1], [3, 1, 1], [3, 1, 0], [1, 0, 0]] sage: PP.transpose(True) [[4, 2, 1], [3, 1, 1], [3, 1, 0], [1, 0, 0]] """ else:
def is_SPP(self): r""" Return whether ``self`` is a symmetric plane partition.
A plane partition is symmetric if the corresponding tableau is symmetric about the diagonal.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_SPP() False sage: PP = PlanePartition([[3,3,2],[3,3,2],[2,2,2]]) sage: PP.is_SPP() True """ for r in range(len(z_tab)) for c in range(r, len(z_tab[r])))
def is_CSPP(self): r""" Return whether ``self`` is a cyclically symmetric plane partition.
A plane partition is cyclically symmetric if its `x`, `y`, and `z` tableaux are all equal.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_CSPP() False sage: PP = PlanePartition([[3,2,2],[3,1,0],[1,1,0]]) sage: PP.is_CSPP() True """
def is_TSPP(self): r""" Return whether ``self`` is a totally symmetric plane partition.
A plane partition is totally symmetric if it is both symmetric and cyclically symmetric.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_TSPP() False sage: PP = PlanePartition([[3,3,3],[3,3,2],[3,2,1]]) sage: PP.is_TSPP() True """
def is_SCPP(self): r""" Return whether ``self`` is a self-complementary plane partition.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_SCPP() False sage: PP = PlanePartition([[4,4,4,4],[4,4,2,0],[4,2,0,0],[0,0,0,0]]) sage: PP.is_SCPP() True """
def is_TCPP(self): r""" Return whether ``self`` is a transpose-complementary plane partition.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_TCPP() False sage: PP = PlanePartition([[4,4,3,2],[4,4,2,1],[4,2,0,0],[2,0,0,0]]) sage: PP.is_TCPP() True """
def is_SSCPP(self): r""" Return whether ``self`` is a symmetric, self-complementary plane partition.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_SSCPP() False sage: PP = PlanePartition([[4,3,3,2],[3,2,2,1],[3,2,2,1],[2,1,1,0]]) sage: PP.is_SSCPP() True """
def is_CSTCPP(self): r""" Return whether ``self`` is a cyclically symmetric and transpose-complementary plane partition.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_CSTCPP() False sage: PP = PlanePartition([[4,4,3,2],[4,3,2,1],[3,2,1,0],[2,1,0,0]]) sage: PP.is_CSTCPP() True """
def is_CSSCPP(self): r""" Return whether ``self`` is a cyclically symmetric and self-complementary plane partition.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_CSSCPP() False sage: PP = PlanePartition([[4,4,4,1],[3,3,2,1],[3,2,1,1],[3,0,0,0]]) sage: PP.is_CSSCPP() True """
def is_TSSCPP(self): r""" Return whether ``self`` is a totally symmetric self-complementary plane partition.
EXAMPLES::
sage: PP = PlanePartition([[4,3,3,1],[2,1,1],[1,1]]) sage: PP.is_TSSCPP() False sage: PP = PlanePartition([[4,4,3,2],[4,3,2,1],[3,2,1,0],[2,1,0,0]]) sage: PP.is_TSSCPP() True """
class PlanePartitions(UniqueRepresentation, Parent): r""" All plane partitions inside a rectangular box of given side lengths.
INPUT:
- ``box_size`` -- a triple of positive integers indicating the size of the box containing the plane partition
EXAMPLES:
This will create an instance to manipulate the plane partitions in a `4 \times 3 \times 2` box::
sage: P = PlanePartitions((4,3,2)) sage: P Plane partitions inside a 4 x 3 x 2 box sage: P.cardinality() 490
.. SEEALSO::
:class:`PlanePartition` """ @staticmethod def __classcall_private__(cls, box_size): """ Normalize input to ensure a unique representation.
EXAMPLES::
sage: P1 = PlanePartitions((4,3,2)) sage: P2 = PlanePartitions([4,3,2]) sage: P1 is P2 True """
def __init__(self, box_size): r""" Initialize ``self``
EXAMPLES::
sage: PP = PlanePartitions((4,3,2)) sage: TestSuite(PP).run() """ raise ValueError("invalid box size")
def _repr_(self): """ Return a string representation of ``self``.
EXAMPLES::
sage: PlanePartitions((4,3,2)) Plane partitions inside a 4 x 3 x 2 box """ self._box[0], self._box[1], self._box[2])
def __iter__(self): """ Iterate over ``self``.
EXAMPLES::
sage: list(PlanePartitions((1,2,1))) [Plane partition [[0, 0]], Plane partition [[1, 0]], Plane partition [[1, 1]]] """
def cardinality(self): r""" Return the cardinality of ``self``.
The number of plane partitions inside an `a \times b \times c` box is equal to
.. MATH::
\prod_{i=1}^{a} \prod_{j=1}^{b} \prod_{k=1}^{c} \frac{i+j+k-1}{i+j+k-2}.
EXAMPLES::
sage: P = PlanePartitions((4,3,5)) sage: P.cardinality() 116424 """ for i in range(1, A+1) for j in range(1, B+1) for k in range(1, C+1) ))
def box(self): """ Return the sizes of the box of the plane partitions of ``self`` are contained in.
EXAMPLES::
sage: P = PlanePartitions((4,3,5)) sage: P.box() (4, 3, 5) """
def random_element(self): r""" Return a uniformly random element of ``self``.
ALGORITHM:
This uses the :meth:`~sage.combinat.posets.posets.FinitePoset.random_order_ideal` method and the natural bijection with plane partitions.
EXAMPLES::
sage: P = PlanePartitions((4,3,5)) sage: P.random_element() Plane partition [[4, 3, 3], [4, 0, 0], [2, 0, 0], [0, 0, 0]] """ for k in range(self._box[2])]
Element = PlanePartition |