Repository navigation
Add EnumeratorOfCombinations( mset, k ) and speed up orbits of permutation groups on sets and tuples - #6756
Add EnumeratorOfCombinations( mset, k ) and speed up orbits of permutation groups on sets and tuples#6756fingolfin wants to merge 2 commits into
EnumeratorOfCombinations( mset, k ) and speed up orbits of permutation groups on sets and tuples#6756Conversation
EnumeratorOfCombinations takes an optional k, like
IteratorOfCombinations. With k it lists the combinations in
lexicographic order; for a set it ranks a combination with k binomial
coefficients.
DomainForAction for permutations on lists of integers returned the
placeholder ["BoundedTuples", [1..m], k] for OnSets, which SparseIntKey
recognised by comparing strings. It now returns
EnumeratorOfCombinations([1..m], k) for OnSets and
EnumeratorOfTuples([1..m], k) for OnTuples and OnPairs, which had no
domain and fell back to a sort dictionary. Dictionaries index these
enumerators by position, or above blistlimit hash them with HashKeyBag.
The old hash read the length word and dropped the last entry, so k-sets
that differed only in their largest point collided. EnumeratorOfTuples
no longer allocates a list in NumberElement.
A position dictionary keeps its values in a list indexed by domain
position, which grows to the largest position used, so a small orbit in
a domain of up to 2^25 points would allocate hundreds of MB. The orbit
has at most Size(G) points, so OrbitStabilizer now hashes domains with
more than 8*Size(G) points, including vector spaces for matrix groups.
Before:
gap> G:=SymmetricGroup(100);;
gap> Orbit(G,[1,2,3],OnSets);; time;
3461
gap> Orbit(G,[1,2,3],OnTuples);; time;
40960
gap> OrbitStabilizer(G,[1,2,3],OnTuples);; time;
45121
After:
gap> G:=SymmetricGroup(100);;
gap> Orbit(G,[1,2,3],OnSets);; time;
257
gap> Orbit(G,[1,2,3],OnTuples);; time;
1281
gap> OrbitStabilizer(G,[1,2,3],OnTuples);; time;
4294
Assisted-by: Generative AI
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6756 +/- ##
==========================================
+ Coverage 79.67% 79.70% +0.02%
==========================================
Files 684 684
Lines 295460 295609 +149
Branches 8656 8656
==========================================
+ Hits 235419 235605 +186
+ Misses 58215 58176 -39
- Partials 1826 1828 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
|
||
| ## default for the option blistlimit of NewDictionary: the largest domain | ||
| ## that gets a position dictionary | ||
| BindGlobal("DICT_BLISTLIMIT", 2^25); |
There was a problem hiding this comment.
Maybe indicate how this number arose? Is it 2^17 bytes, i.e. 130kB?
EnumeratorOfCombinations( mset, k ) and speed up orbits of permutation groups on sets and tuples
james-d-mitchell
left a comment
There was a problem hiding this comment.
I also think this is really good but should probably have a bit more robust checks on the additional arguments as indicated.
| return enum; | ||
| end); | ||
|
|
||
| InstallGlobalFunction(EnumeratorOfCombinations, function(mset, arg...) |
There was a problem hiding this comment.
Shouldn't we give an error or something if arg is of length >1?
There was a problem hiding this comment.
Also shouldn't there be some checks that if arg[1] is present then it is a non-negative integer? At the moment I can do stupid things like:
gap> EnumeratorOfCombinations([1 .. 3], infinity);
[ ]
gap> EnumeratorOfCombinations([1 .. 3], -infinity);
Error, Binomial: <k> must be an integer (not a positional object)
Stack trace:
*[1] Binomial( Length( els ), k )
@ /Users/jdm3/gap/lib/combinat.gi:329
[2] EnumeratorOfCombinations_k( mset, arg[1] )
@ /Users/jdm3/gap/lib/combinat.gi:366
<function "EnumeratorOfCombinations">( <arguments> )
called from read-eval loop at *stdin*:2
you can enter 'quit;' to quit to outer loop
brk>
gap> EnumeratorOfCombinations([1 .. 3], "a");
[ ]
gap> EnumeratorOfCombinations([1 .. 3], "a", "b");
[ ]
| BindGlobal("ElementNumber_Combinations_set", function(enum, num) | ||
| local set, n, r, comb, c, i, lo, hi, mid; | ||
| if num > enum!.size then | ||
| Error("Index ", num, " not bound."); |
There was a problem hiding this comment.
| Error("Index ", num, " not bound."); | |
| Error("Index ", num, " not bound, expected at most ", enum!.size); |
Might be a bit more helpful.
A k that was not a non-negative integer, such as infinity or a string, gave an empty list or an error from Binomial, and extra arguments were ignored. Both now raise an error. An index out of range now reports the length, and DICT_BLISTLIMIT says how much memory it allows. Assisted-by: Generative AI
EnumeratorOfCombinationstakes an optional k, likeIteratorOfCombinations. With k it lists the combinations in lexicographic order; for a set it ranks a combination with k binomial coefficients.DomainForActionfor permutations on lists of integers returned the placeholder["BoundedTuples", [1..m], k]forOnSets, whichSparseIntKeyrecognised by comparing strings. It now returnsEnumeratorOfCombinations([1..m], k)forOnSetsandEnumeratorOfTuples([1..m], k)forOnTuplesandOnPairs, which had no domain and fell back to a sort dictionary. Dictionaries index these enumerators by position, or above blistlimit hash them withHashKeyBag. The old hash read the length word and dropped the last entry, so k-sets that differed only in their largest point collided.EnumeratorOfTuplesno longer allocates a list inNumberElement.A position dictionary keeps its values in a list indexed by domain position, which grows to the largest position used, so a small orbit in a domain of up to 2^25 points would allocate hundreds of MB. The orbit has at most
Size(G)points, soOrbitStabilizernow hashes domains with more than8*Size(G)points, including vector spaces for matrix groups.Before:
After:
Assisted-by: Generative AI