From 81bbadfe494a786a03abe219a0658063827757b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 10 Oct 2024 09:21:33 +0200 Subject: [PATCH 1/6] switch to nauty for generating posets --- src/sage/combinat/posets/posets.py | 10 +++++----- src/sage/combinat/tutorial.py | 8 ++++---- src/sage/databases/findstat.py | 9 +++++---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 6471163fe00..5822d6af366 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -8884,11 +8884,11 @@ class FinitePosets_n(UniqueRepresentation, Parent): sage: P.cardinality() 5 sage: for p in P: print(p.cover_relations()) - [] - [[1, 2]] + [[1, 2], [0, 2]] [[0, 1], [0, 2]] + [[0, 2]] [[0, 1], [1, 2]] - [[1, 2], [0, 2]] + [] """ def __init__(self, n) -> None: @@ -8945,8 +8945,8 @@ def __iter__(self): sage: list(P) [Finite poset containing 2 elements, Finite poset containing 2 elements] """ - from sage.graphs.digraph_generators import DiGraphGenerators - for dig in DiGraphGenerators()(self._n, is_poset): + from sage.graphs.digraph_generators import DiGraphGenerators as DG + for dig in DG().nauty_posetg(f"{self._n} o"): # We need to relabel the digraph since range(self._n) must be a linear # extension. Too bad we need to compute this again. TODO: Fix this. label_dict = dict(zip(dig.topological_sort(), range(dig.order()))) diff --git a/src/sage/combinat/tutorial.py b/src/sage/combinat/tutorial.py index 1b8555f4565..ef77bf66d4e 100644 --- a/src/sage/combinat/tutorial.py +++ b/src/sage/combinat/tutorial.py @@ -844,15 +844,15 @@ Partial orders on a set of `8` elements, up to isomorphism:: - sage: C = Posets(8); C - Posets containing 8 elements + sage: C = Posets(7); C + Posets containing 7 elements sage: C.cardinality() - 16999 + 2045 :: sage: C.unrank(20).plot() - Graphics object consisting of 20 graphics primitives + Graphics object consisting of ... graphics primitives .. image:: ../../media/a_poset.png diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index 89cd74f457e..852c258a4ac 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -4002,16 +4002,17 @@ def _finite_lattices(n): TESTS:: sage: from sage.databases.findstat import _finite_lattices - sage: [L.cover_relations() for L in _finite_lattices(4)] - [[['bottom', 0], ['bottom', 1], [0, 'top'], [1, 'top']], - [['bottom', 0], [0, 1], [1, 'top']]] + sage: sorted((L.cover_relations() for L in _finite_lattices(4)), + ....: key=len) + [[['bottom', 0], [0, 1], [1, 'top']], + [['bottom', 0], ['bottom', 1], [0, 'top'], [1, 'top']]] """ if n <= 2: for P in Posets(n): if P.is_lattice(): yield LatticePoset(P) else: - for P in Posets(n-2): + for P in Posets(n - 2): Q = P.with_bounds() if Q.is_lattice(): yield LatticePoset(Q) From c66f999722c4307dc42f042920ebe9ce952a3908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 10 Oct 2024 10:15:16 +0200 Subject: [PATCH 2/6] fix for linter --- src/sage/databases/findstat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index 852c258a4ac..c3a886645ac 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -4005,7 +4005,7 @@ def _finite_lattices(n): sage: sorted((L.cover_relations() for L in _finite_lattices(4)), ....: key=len) [[['bottom', 0], [0, 1], [1, 'top']], - [['bottom', 0], ['bottom', 1], [0, 'top'], [1, 'top']]] + [['bottom', 0], ['bottom', 1], [0, 'top'], [1, 'top']]] """ if n <= 2: for P in Posets(n): From 1e9209ace2e7aff49e6fa5ac416922e5196e7234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 10 Oct 2024 13:17:09 +0200 Subject: [PATCH 3/6] details --- src/sage/combinat/posets/posets.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 5822d6af366..aa0ee7f249f 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -8936,7 +8936,7 @@ def __iter__(self): .. NOTE:: - This uses the DiGraph iterator as a backend to construct + This uses an iterator from ``nauty`` as a backend to construct transitively-reduced, acyclic digraphs. EXAMPLES:: @@ -8945,8 +8945,8 @@ def __iter__(self): sage: list(P) [Finite poset containing 2 elements, Finite poset containing 2 elements] """ - from sage.graphs.digraph_generators import DiGraphGenerators as DG - for dig in DG().nauty_posetg(f"{self._n} o"): + from sage.graphs.digraph_generators import DiGraphGenerators + for dig in DiGraphGenerators().nauty_posetg(f"{self._n} o"): # We need to relabel the digraph since range(self._n) must be a linear # extension. Too bad we need to compute this again. TODO: Fix this. label_dict = dict(zip(dig.topological_sort(), range(dig.order()))) From 8b55fc3f8dc08ea09261024bd4531df68176149d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 10 Oct 2024 13:18:56 +0200 Subject: [PATCH 4/6] move import --- src/sage/combinat/posets/posets.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index aa0ee7f249f..9e2e1250e76 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -8945,8 +8945,7 @@ def __iter__(self): sage: list(P) [Finite poset containing 2 elements, Finite poset containing 2 elements] """ - from sage.graphs.digraph_generators import DiGraphGenerators - for dig in DiGraphGenerators().nauty_posetg(f"{self._n} o"): + for dig in digraphs.nauty_posetg(f"{self._n} o"): # We need to relabel the digraph since range(self._n) must be a linear # extension. Too bad we need to compute this again. TODO: Fix this. label_dict = dict(zip(dig.topological_sort(), range(dig.order()))) From 93c0c8b3b39b993508ab2283f597331580dc27ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 10 Oct 2024 15:37:02 +0200 Subject: [PATCH 5/6] add switch for n > 16 --- src/sage/combinat/posets/posets.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 9e2e1250e76..8a85febf4c8 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -8930,22 +8930,35 @@ def __contains__(self, P) -> bool: return P in FinitePosets() and P.cardinality() == self._n def __iter__(self): - """ + r""" Return an iterator of representatives of the isomorphism classes of finite posets of a given size. .. NOTE:: - This uses an iterator from ``nauty`` as a backend to construct - transitively-reduced, acyclic digraphs. + If the size `n\leq 16`, this uses an iterator from + ``nauty`` as a backend to construct only transitively-reduced, + acyclic digraphs. Otherwise it uses a slow naive iterator, + as the ``nauty`` iterator is not available. EXAMPLES:: sage: P = Posets(2) sage: list(P) [Finite poset containing 2 elements, Finite poset containing 2 elements] + + TESTS:: + + sage: it = iter(Posets(17)) + sage: next(it) + Finite poset containing 17 elements """ - for dig in digraphs.nauty_posetg(f"{self._n} o"): + if self._n <= 16: + it = digraphs.nauty_posetg(f"{self._n} o") + else: + it = digraphs(self._n, is_poset) + + for dig in it: # We need to relabel the digraph since range(self._n) must be a linear # extension. Too bad we need to compute this again. TODO: Fix this. label_dict = dict(zip(dig.topological_sort(), range(dig.order()))) From 17f72fa4080c60a8a2d772ec4c21fd928c7471ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 10 Oct 2024 17:43:44 +0200 Subject: [PATCH 6/6] avoid copy of graph --- src/sage/combinat/posets/posets.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 8a85febf4c8..e565eb3d2ee 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -8961,8 +8961,9 @@ def __iter__(self): for dig in it: # We need to relabel the digraph since range(self._n) must be a linear # extension. Too bad we need to compute this again. TODO: Fix this. - label_dict = dict(zip(dig.topological_sort(), range(dig.order()))) - yield FinitePoset(dig.relabel(label_dict, inplace=False)) + label_dict = dict(zip(dig.topological_sort(), range(self._n))) + dig.relabel(label_dict, inplace=True) + yield FinitePoset(dig) def cardinality(self, from_iterator=False): r"""