Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/doc/en/reference/combinat/module_list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ Comprehensive module list
sage/combinat/posets/linear_extensions
sage/combinat/posets/mobile
sage/combinat/posets/moebius_algebra
sage/combinat/posets/sashes
sage/combinat/posets/all
sage/combinat/posets/hasse_cython
sage/combinat/posets/hasse_cython_flint
Expand Down
9 changes: 8 additions & 1 deletion src/doc/en/reference/references/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ REFERENCES:
Ann. Math. (2) 192, No. 3, 821-891 (2020).
:arxiv:`1902.03719`, :doi:`10.4007/annals.2020.192.3.4`.

.. [Bru2014] Erwan Brugalle and Kristin Shaw. *A bit of tropical geometry*.
.. [Bru2014] Erwan Brugallé and Kristin Shaw. *A bit of tropical geometry*.
Amer. Math. Monthly, 121(7):563-589, 2014.

.. [BHNR2004] \S. Brlek, S. Hamel, M. Nivat, C. Reutenauer, On the
Expand Down Expand Up @@ -1428,6 +1428,10 @@ REFERENCES:
The Open Book Series, Vol. 2 (2019), No. 1, pp. 155-171,
https://msp.org/obs/2019/2-1/p10.xhtml

.. [BTTM2024] \L. Bossinger, M. L. Telek, H. Tillmann-Morris,
*Binary Geometries From Pellytopes*,
:arxiv:`2410.08002`

.. [BUVO2007] Johannes Buchmann, Ullrich Vollmer: Binary Quadratic Forms,
An Algorithmic Approach, Algorithms and Computation in Mathematics,
Volume 20, Springer (2007)
Expand Down Expand Up @@ -4427,6 +4431,9 @@ REFERENCES:
modular forms*, LMS J. of Comput. Math. 14 (2011),
214-231.

.. [Law2014] Shirley Law, *Combinatorial realization of the Hopf algebra
of sashes*, Proceedings of FPSAC 2014, DMTCS, :arxiv:`1407.4073`

.. [Laz1992] Daniel Lazard, *Solving Zero-dimensional Algebraic
Systems*, in Journal of Symbolic Computation (1992)
vol\. 13, pp\. 117-131
Expand Down
1 change: 1 addition & 0 deletions src/sage/combinat/posets/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ py.install_sources(
'moebius_algebra.py',
'poset_examples.py',
'posets.py',
'sashes.py',
subdir: 'sage/combinat/posets',
)

Expand Down
5 changes: 4 additions & 1 deletion src/sage/combinat/posets/poset_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
:meth:`~Posets.RandomPoset` | Return a random poset on `n` elements.
:meth:`~Posets.RibbonPoset` | Return a ribbon on `n` elements with descents at `descents`.
:meth:`~Posets.RestrictedIntegerPartitions` | Return the poset of integer partitions of `n`, ordered by restricted refinement.
:meth:`~Posets.Sashes` | Return the lattice of sashes of `n`.
:meth:`~Posets.SetPartitions` | Return the poset of set partitions of the set `\{1,\dots,n\}`.
:meth:`~Posets.ShardPoset` | Return the shard intersection order.
:meth:`~Posets.ShufflePoset` | Return the Shuffle lattice for `(m,n)`.
Expand Down Expand Up @@ -102,7 +103,7 @@
import sage.categories.posets
from sage.combinat.permutation import Permutations, Permutation, to_standard
from sage.combinat.posets.posets import Poset, FinitePoset, FinitePosets_n
from sage.combinat.posets import bubble_shuffle, hochschild_lattice
from sage.combinat.posets import bubble_shuffle, hochschild_lattice, sashes
from sage.combinat.posets.d_complete import DCompletePoset
from sage.combinat.posets.mobile import MobilePoset as Mobile
from sage.combinat.posets.lattices import (LatticePoset, MeetSemilattice,
Expand Down Expand Up @@ -290,6 +291,8 @@ def BooleanLattice(n, facade=None, use_subsets=False):

HochschildLattice = staticmethod(hochschild_lattice.hochschild_lattice)

Sashes = staticmethod(sashes.lattice_of_sashes)

@staticmethod
def ChainPoset(n, facade=None):
r"""
Expand Down
219 changes: 219 additions & 0 deletions src/sage/combinat/posets/sashes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
r"""
Lattices of sashes

These lattices were introduced by S. Law in [Law2014]_. They are
lattice quotients of the weak order on the symmetric groups. This
implies that they are congruence-uniform.

There is a lattice of sashes `\Sigma_n` for every integer `n \geq 1`.
The underlying set of `\Sigma_n` is the set of words of length `n`
in the letters ``□``, ``▨`` and ``■■`` of respective lengths `1,1` and `2`.

The cardinalities of the lattices $\Sigma_n$ are therefore given by
the Pell numbers (:oeis:`A000129`).

The implementation describes sashes as tuples of strings.

REFERENCES:

- [Law2014]_

"""
from itertools import pairwise
from typing import Iterator

from sage.categories.finite_lattice_posets import FiniteLatticePosets
from sage.combinat.posets.lattices import LatticePoset
from sage.geometry.cone import Cone
from sage.geometry.fan import Fan
from sage.geometry.polyhedron.constructor import Polyhedron
from sage.misc.cachefunc import cached_function
from sage.modules.free_module_element import vector

B, N, BB = "□", "▨", "■■"


def sashes(n: int) -> Iterator[tuple[str, ...]]:
"""
Iterate over the sashes of length `n`.

INPUT:

- ``n`` -- nonnegative integer

EXAMPLES::

sage: from sage.combinat.posets.sashes import sashes
sage: [''.join(s) for s in sashes(2)]
['□□', '□▨', '▨□', '▨▨', '■■']

TESTS::

sage: [''.join(s) for s in sashes(0)]
['']
sage: [''.join(s) for s in sashes(1)]
['□', '▨']
sage: list(sashes(-1))
Traceback (most recent call last):
...
ValueError: n must be nonnegative
"""
if n < 0:
raise ValueError("n must be nonnegative")
if n == 0:
yield ()
return
if n == 1:
yield (B,)
yield (N,)
return
for s in sashes(n - 1):
yield s + (B,)
yield s + (N,)
for s in sashes(n - 2):
yield s + (BB,)


def cover_relations(s: tuple[str, ...]) -> Iterator[tuple[str, ...]]:
"""
Iterate over the cover relations of the given sash.

INPUT:

- ``s`` -- a sash, as a tuple of strings

EXAMPLES::

sage: from sage.combinat.posets.sashes import cover_relations
sage: s = ('□', '▨', '▨')
sage: [''.join(t) for t in cover_relations(s)]
['□□▨', '□▨□']
sage: s = ('□', '■■', '▨')
sage: [''.join(t) for t in cover_relations(s)]
['□□□▨', '□■■□']
"""
for i, letter in enumerate(s):
if letter == BB:
yield s[:i] + (B, B) + s[i + 1:]
for i, (l1, l2) in enumerate(pairwise(s)):
if l1 == N:
if l2 == B:
yield s[:i] + (BB,) + s[i + 2:]
else:
yield s[:i] + (B,) + s[i + 1:]
if s[-1] == N:
yield s[:-1] + (B,)


def lattice_of_sashes(n: int) -> LatticePoset:
"""
Return the lattice of sashes of length `n`.

INPUT:

- ``n`` -- positive integer

EXAMPLES::

sage: L = posets.Sashes(4); L
Finite lattice containing 29 elements
sage: L.hasse_diagram().to_undirected().is_regular(4)
True

TESTS::

sage: posets.Sashes(0)
Traceback (most recent call last):
...
ValueError: n must be positive
"""
if n <= 0:
raise ValueError("n must be positive")
cat = FiniteLatticePosets().CongruenceUniform()
return LatticePoset({s: list(cover_relations(s)) for s in sashes(n)},
cover_relations=True, check=False,
category=cat)


@cached_function
def pellytope_fan(n: int) -> Fan:
"""
Return the fan of the pellytope of dimension `n`.

This is defined by induction.

INPUT:

- ``n`` -- integer

EXAMPLES::

sage: from sage.combinat.posets.sashes import pellytope_fan
sage: pellytope_fan(3).f_vector()
(1, 8, 18, 12)

TESTS::

sage: pellytope_fan(1)
Rational polyhedral fan in 1-d lattice N
sage: pellytope_fan(0)
Traceback (most recent call last):
...
ValueError: n must be positive

REFERENCES:

- [BTTM2024]_
"""
if n <= 0:
raise ValueError("n must be positive")
dim_one = Fan([Cone([[-1]]), Cone([[1]])])
if n == 1:
return dim_one
G = pellytope_fan(n - 1).cartesian_product(dim_one)
v = vector([0] * (n - 2) + [-1, 1])
return G.subdivide(new_rays=[v])


def pellytope(n: int) -> Polyhedron:
"""
Return the pellytope of dimension `n`.

This is defined as a Minkowski sum.

INPUT:

- ``n`` -- integer

EXAMPLES::

sage: from sage.combinat.posets.sashes import pellytope
sage: P3 = pellytope(3); P3
A 3-dimensional polyhedron in ZZ^3 defined as
the convex hull of 12 vertices
sage: P3.f_vector()
(1, 12, 18, 8, 1)

TESTS::

sage: pellytope(0)
Traceback (most recent call last):
...
ValueError: n must be positive

REFERENCES:

- [BTTM2024]_
"""
if n <= 0:
raise ValueError("n must be positive")
v = [vector([1 if i == j else 0 for i in range(n)])
for j in range(n)]
zero = [0] * n

resu = [Polyhedron(vertices=[zero, v[i]]) for i in range(n)]

resu.extend(Polyhedron(vertices=[zero, v[j], v[j] + v[j + 1]])
for j in range(n - 1))

return sum(resu)
Loading