Skip to content

Conversation

mantepse
Copy link
Contributor

@mantepse mantepse commented Nov 1, 2024

We provide a new class, PartitionsSmallestGE to handle subsets of the constraints length, min_length, max_length and min_part, to make cardinality computations with such constraints reasonable.

Fixes #38897, #39107

Copy link

github-actions bot commented Nov 1, 2024

Documentation preview for this PR (built with commit a20587a; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@fchapoton fchapoton self-assigned this Nov 5, 2024
@mantepse
Copy link
Contributor Author

@fchapoton, could you please have a look so it doesn't rot away?

Copy link
Contributor

@fchapoton fchapoton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. Please avoid doing a lot of cleanup work in this kind of ticket.

@mantepse
Copy link
Contributor Author

mantepse commented Nov 17, 2024

Thank you! Sorry, I couldn't resist.

@mantepse
Copy link
Contributor Author

mantepse commented Nov 18, 2024

Dear @fchapoton, I would like to put this back to "needs work", because it doesn't quite solve Max' issue, and it's not hard to do that, but I'd like to avoid deprecation of something I just introduced.

Is this OK with you or would you prefer if I open a new pull request?

Ideally, I think there should be a single class for partitions of n with parts in a given set or interval and length in a given interval, which computes the cardinality efficiently using a few case distinctions and a recurrence if necessary.

and generalize it to handle also max_part
@mantepse
Copy link
Contributor Author

This is now much better. Almost all the time is now spent in IntegerListsLex.__init__, which is a pity, but can probably not be fixed in this pull request.

I'm open for a better name for the class Partitions_parts_length_restricted. I'm also open for deprecating PartitionsGreatestLE.

@mantepse
Copy link
Contributor Author

I find it a bit frustrating that we do not need the IntegerListsLex.__init__ at all to compute the cardinality. It would be nice to have a pattern where such an expensive initialisation is postponed until it's needed.

Failing that, it seems that most of the time is spent in Envelope.__init__. Maybe this can be optimized.

@mantepse
Copy link
Contributor Author

The solution was very simple, so I implemented it.

Max' problem is still much better solved without using Partitions (it seems to take roughly twice as long), because Partitions has UniqueRepresentation, which is expensive if we call it with very many different arguments - we are creating an entry in the cache not only for each size, but for each restriction.

@mantepse
Copy link
Contributor Author

@tscrim, there seems to be a problem with FockSpace. In FockSpaceTruncated.F.__init__, the index set is set to be partitions of F._n, but that doesn't seem to be quite true. Could you please check?

def __init__(self, F):
r"""
Initialize ``self``.
EXAMPLES::
sage: F = FockSpace(2, truncated=3).natural()
sage: TestSuite(F).run() # long time
"""
self._basis_name = "natural"
# If the cell x is above the cell y
if len(F._multicharge) == 1: # For partitions
self._above = lambda x,y: x[0] < y[0]
else: # For partition tuples
self._above = lambda x,y: x[0] < y[0] or (x[0] == y[0] and x[1] < y[1])
self._addable = lambda la,i: [x for x in la.outside_corners()
if la.content(*x, multicharge=F._multicharge) == i]
self._removable = lambda la,i: [x for x in la.corners()
if la.content(*x, multicharge=F._multicharge) == i]
indices = Partitions(F._n, max_length=F._k)
CombinatorialFreeModule.__init__(self, F.base_ring(), indices,
prefix='', bracket=['|', '>'],
latex_bracket=['\\lvert', '\\rangle'],
sorting_reverse=True,
category=FockSpaceBases(F))

@tscrim
Copy link
Collaborator

tscrim commented Nov 22, 2024

@tscrim, there seems to be a problem with FockSpace. In FockSpaceTruncated.F.__init__, the index set is set to be partitions of F._n, but that doesn't seem to be quite true. Could you please check?

Yes, that is not correct. It should be over all partitions of length \leq k (as per the doc of FockSpaceTruncated).

@mantepse mantepse marked this pull request as draft December 21, 2024 12:33
@mantepse
Copy link
Contributor Author

mantepse commented Dec 21, 2024

I checked the other containment checks, and many of them fail to treat trailing zeros correctly. So, there is more work to do. I also did a performance check:

sage: n=15; P = Partitions(n); P1 = Partitions_length_and_parts_constrained(n, 3, 6, 2, 8)
sage: l = [P.random_element() for _ in range(100000)]
sage: l2 = [list(x) for x in l]
sage: %time sum(1 for mu in l if P1.__contains__(mu))
CPU times: user 126 ms, sys: 0 ns, total: 126 ms
Wall time: 126 ms
15841
sage: %time sum(1 for mu in l if P1._contains2(mu))
CPU times: user 204 ms, sys: 0 ns, total: 204 ms
Wall time: 204 ms
15841
sage: %time sum(1 for mu in l2 if P1.__contains__(mu))
CPU times: user 596 ms, sys: 0 ns, total: 596 ms
Wall time: 596 ms
15841
sage: %time sum(1 for mu in l2 if P1._contains2(mu))
CPU times: user 830 ms, sys: 0 ns, total: 830 ms
Wall time: 830 ms
15841

where

    def __contains__(self, x):
...
        if x not in _Partitions:
            return False
        if not self._n:
            return not x
        return (sum(x) == self._n
                and x[-1] >= self._min_part
                and x[0] <= self._max_part
                and self._min_length <= len(x) <= self._max_length)

    def _contains2(self, x):
        try:
            mu = Partition(x)
        except ValueError:
            return False
        return (mu.size() == self._n
                and (not mu
                     or (min(mu) >= self._min_part
                         and max(mu) <= self._max_part
                         and self._min_length <= len(mu) <= self._max_length)))

I'm not sure whether it's worth the effort to do something super intelligent here. Note that __contains__ above does not deal with trailing zeros, and that we would have the complication - whatever the more intelligent check might be - in most of the __contains__ methods.

@mantepse mantepse marked this pull request as ready for review December 21, 2024 23:44
@mantepse
Copy link
Contributor Author

An awful lot of time is spent in line 6464 of the _element_constructor_, i.e., the last (!) line of

        try:
            lst = list(map(ZZ, lst))
        except TypeError:
            raise ValueError(f'all parts of {lst} should be nonnegative integers')

Removing {lst} would probably make a big difference.

Also, list(map(ZZ, lst)) seems a bit slower than [ZZ(e) for e in lst].

@mantepse
Copy link
Contributor Author

mantepse commented Dec 22, 2024

If tests pass, I hope that this is good enough.

@mantepse
Copy link
Contributor Author

The two failing tests are #39183 and most likely #38737 - in any case I cannot reproduce them locally.

@mantepse
Copy link
Contributor Author

mantepse commented Jan 5, 2025

ping?

Copy link
Contributor

@fchapoton fchapoton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's move forward and keep further changes for later

vbraun pushed a commit to vbraun/sage that referenced this pull request Jan 9, 2025
sagemathgh-38904: provide a class for partitions with bounded length and minimal part
    
We provide a new class, `PartitionsSmallestGE` to handle subsets of the
constraints `length`, `min_length`, `max_length` and `min_part`, to make
cardinality computations with such constraints reasonable.

Fixes sagemath#38897, sagemath#39107
    
URL: sagemath#38904
Reported by: Martin Rubey
Reviewer(s): Frédéric Chapoton, Martin Rubey, Travis Scrimshaw
vbraun pushed a commit to vbraun/sage that referenced this pull request Jan 10, 2025
sagemathgh-38904: provide a class for partitions with bounded length and minimal part
    
We provide a new class, `PartitionsSmallestGE` to handle subsets of the
constraints `length`, `min_length`, `max_length` and `min_part`, to make
cardinality computations with such constraints reasonable.

Fixes sagemath#38897, sagemath#39107
    
URL: sagemath#38904
Reported by: Martin Rubey
Reviewer(s): Frédéric Chapoton, Martin Rubey, Travis Scrimshaw
vbraun pushed a commit to vbraun/sage that referenced this pull request Jan 12, 2025
sagemathgh-38904: provide a class for partitions with bounded length and minimal part
    
We provide a new class, `PartitionsSmallestGE` to handle subsets of the
constraints `length`, `min_length`, `max_length` and `min_part`, to make
cardinality computations with such constraints reasonable.

Fixes sagemath#38897, sagemath#39107
    
URL: sagemath#38904
Reported by: Martin Rubey
Reviewer(s): Frédéric Chapoton, Martin Rubey, Travis Scrimshaw
vbraun pushed a commit to vbraun/sage that referenced this pull request Jan 16, 2025
sagemathgh-38904: provide a class for partitions with bounded length and minimal part
    
We provide a new class, `PartitionsSmallestGE` to handle subsets of the
constraints `length`, `min_length`, `max_length` and `min_part`, to make
cardinality computations with such constraints reasonable.

Fixes sagemath#38897, sagemath#39107
    
URL: sagemath#38904
Reported by: Martin Rubey
Reviewer(s): Frédéric Chapoton, Martin Rubey, Travis Scrimshaw
@vbraun vbraun merged commit 15f25d9 into sagemath:develop Jan 18, 2025
21 of 23 checks passed
@mantepse mantepse deleted the partitions/cardinality branch January 20, 2025 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Computing Partitions(...).cardinality() with set min_length= can be significantly improved by complementation and using max_length= instead
4 participants