Skip to content

Commit 394200a

Browse files
author
Release Manager
committed
gh-40245: moving linear_intervals_count to hasse as iterator to make them still faster ; also changed the moved method into an iterator as this could be convenient follow-up of previous effort in #40171 Timings : poset of size 4800 : 18s before ; 13 after poset of size 5300 : 24.4 s before and17.4 s after ### 📝 Checklist - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [x] I have updated the documentation and checked the documentation preview. URL: #40245 Reported by: Frédéric Chapoton Reviewer(s): Travis Scrimshaw
2 parents 2cc817d + 224b915 commit 394200a

File tree

2 files changed

+44
-25
lines changed

2 files changed

+44
-25
lines changed

src/sage/combinat/posets/hasse_diagram.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,13 +2427,56 @@ def chain_polynomial(self):
24272427
"""
24282428
return chain_poly(self._leq_storage)._sage_('q') # noqa: F821
24292429

2430+
def linear_intervals_count(self):
2431+
"""
2432+
Return the enumeration of linear intervals w.r.t. their cardinality.
2433+
2434+
An interval is linear if it is a total order.
2435+
2436+
OUTPUT: an iterator of integers
2437+
2438+
.. SEEALSO:: :meth:`is_linear_interval`
2439+
2440+
EXAMPLES::
2441+
2442+
sage: P = posets.BubblePoset(3,3)
2443+
sage: H = P._hasse_diagram
2444+
sage: list(H.linear_intervals_count())
2445+
[245, 735, 438, 144, 24]
2446+
"""
2447+
if not self:
2448+
return
2449+
# precomputation helps for speed:
2450+
_ = self._leq_storage
2451+
2452+
stock = [(x, x, x) for x in self]
2453+
yield len(stock)
2454+
exposant = 0
2455+
while True:
2456+
exposant += 1
2457+
next_stock = []
2458+
short_stock = [(ch[0], ch[2]) for ch in stock]
2459+
for xmin, cov_xmin, xmax in stock:
2460+
for y in self.neighbor_out_iterator(xmax):
2461+
if exposant == 1:
2462+
next_stock.append((xmin, y, y))
2463+
elif (cov_xmin, y) in short_stock:
2464+
if self.is_linear_interval(xmin, y):
2465+
next_stock.append((xmin, cov_xmin, y))
2466+
if next_stock:
2467+
yield len(next_stock)
2468+
stock = next_stock
2469+
else:
2470+
break
2471+
24302472
def is_linear_interval(self, t_min, t_max) -> bool:
24312473
"""
24322474
Return whether the interval ``[t_min, t_max]`` is linear.
24332475
24342476
This means that this interval is a total order.
24352477
24362478
EXAMPLES::
2479+
24372480
sage: # needs sage.modules
24382481
sage: P = posets.PentagonPoset()
24392482
sage: H = P._hasse_diagram

src/sage/combinat/posets/posets.py

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2771,31 +2771,7 @@ def linear_intervals_count(self) -> list[int]:
27712771
"""
27722772
if not self.cardinality():
27732773
return []
2774-
# precomputation helps for speed:
2775-
if self.cardinality() > 60:
2776-
self.lequal_matrix()
2777-
2778-
H = self._hasse_diagram
2779-
stock = [(x, x, x) for x in H]
2780-
poly = [len(stock)]
2781-
exposant = 0
2782-
while True:
2783-
exposant += 1
2784-
next_stock = []
2785-
short_stock = [(ch[0], ch[2]) for ch in stock]
2786-
for xmin, cov_xmin, xmax in stock:
2787-
for y in H.neighbor_out_iterator(xmax):
2788-
if exposant == 1:
2789-
next_stock.append((xmin, y, y))
2790-
elif (cov_xmin, y) in short_stock:
2791-
if H.is_linear_interval(xmin, y):
2792-
next_stock.append((xmin, cov_xmin, y))
2793-
if next_stock:
2794-
poly.append(len(next_stock))
2795-
stock = next_stock
2796-
else:
2797-
break
2798-
return poly
2774+
return list(self._hasse_diagram.linear_intervals_count())
27992775

28002776
def is_linear_interval(self, x, y) -> bool:
28012777
"""

0 commit comments

Comments
 (0)