Recog An/Sn unknown degree: conder, holt#265
Recog An/Sn unknown degree: conder, holt#265ssiccha wants to merge 34 commits intogap-packages:masterfrom
Conversation
5ae5367 to
d40a988
Compare
|
Rebased the last commit onto the current version of #176. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #265 +/- ##
==========================================
+ Coverage 69.12% 70.48% +1.35%
==========================================
Files 43 43
Lines 18321 18637 +316
==========================================
+ Hits 12665 13136 +471
+ Misses 5656 5501 -155
🚀 New features to boost your workflow:
|
d40a988 to
dc4a895
Compare
dc4a895 to
f162f36
Compare
cca25fd to
35a39de
Compare
|
Link to our Hackmd |
96f9a25 to
705504c
Compare
e63f4a8 to
956884d
Compare
|
We should be almost done. We think there are two TODOs left: clean up the tests and figure out what to do with small classical groups like: And get the tests to pass again. :) And in Make CallMethods directly write into the RecogNode update the docs of And, @FriedrichRober is writing a short text, how all the parts fit together, that is how our implementation differs from a "vanilla" implementation of the JLNP algorithm according to the paper. |
3b12114 to
daceec3
Compare
|
Awesome, thank you! |
|
@FriedrichRober do you think you can finish this on your own, now that @ssiccha is gone? Perhaps I can help a bit? |
|
Yes, I think I can finish this on my own. The code is finished (except for handling small classical groups). What is missing now is to finish the documentation (comments) and looking at the runtime of the test suite. |
d45adbb to
7ba5ec6
Compare
85ca56f to
deb2974
Compare
|
@fingolfin, ich habe nun die Änderungen implementiert, wie wir es besprochen haben. Wir geben früher auf, und speichern uns die Iteratoren im recog node ab, um sie später weiter zu verwenden. Trotzdem dauert die Test-Suite auf meinem Rechner 3-4 Minuten länger als auf dem master. Meiner Meinung nach ist dieser Zustand inakzeptabel, um das einfach so zu mergen :( Ich muss dann nochmal genau schauen, an welchen Stellen wir zu viel Zeit verschwenden, und ob sich da was machen lässt. |
| # We make a small improvement to the version described in | ||
| # <Cite Key="JLNP13"/>. The order of r ^ M is a 2-power. | ||
| # It can be at most 2 ^ logInt2N. Thus, if we find an r such that | ||
| # (r ^ M) ^ (2 ^ logInt2N) is non-trivial, then we can return | ||
| # NeverApplicable. |
There was a problem hiding this comment.
| # We make a small improvement to the version described in | |
| # <Cite Key="JLNP13"/>. The order of r ^ M is a 2-power. | |
| # It can be at most 2 ^ logInt2N. Thus, if we find an r such that | |
| # (r ^ M) ^ (2 ^ logInt2N) is non-trivial, then we can return | |
| # NeverApplicable. | |
| # We make a small improvement to the version described in | |
| # <Cite Key="JLNP13"/>. The order of r ^ M is a 2-power. | |
| # It can be at most 2 ^ logInt2N. Thus, if we find an r such that | |
| # (r ^ M) ^ (2 ^ logInt2N) is non-trivial, then we can return | |
| # NeverApplicable. I.e. we need one iteration less than in [JLNP13], | |
| # which also computes (r ^ M) ^ (2 ^ (longInt2N + 1)) |
Make the difference between the code and JLNP13 more explicit (hoping that I understood this correctly, I am not sure).
| Li := L; | ||
| Li := Minimum(Li, B); | ||
| Ki := Ki + K; | ||
| Ki := Minimum(Ki, C); | ||
| curInvolutionPos := 1; | ||
| return SnAnTryLater; | ||
| elif curInvolutionPos = Li then | ||
| Li := Li + L; | ||
| Li := Minimum(Li, B); |
There was a problem hiding this comment.
| Li := L; | |
| Li := Minimum(Li, B); | |
| Ki := Ki + K; | |
| Ki := Minimum(Ki, C); | |
| curInvolutionPos := 1; | |
| return SnAnTryLater; | |
| elif curInvolutionPos = Li then | |
| Li := Li + L; | |
| Li := Minimum(Li, B); | |
| # Last involution reached. Restart with next batch of conjugates later. | |
| Li := Minimum(L, B); # Reset Li to initial value | |
| Ki := Minimum(Ki+K, C); # Try up to K more conjugates later | |
| curInvolutionPos := 1; # Restart from first involution | |
| return SnAnTryLater; | |
| elif curInvolutionPos = Li then | |
| # End of batch of involutions reached. Try next batch later. | |
| Li := Minimum(Li+L, B); |
The new Minimum statements should be equivalent to the old ones. Also added some comments.
|
@FriedrichRober I went through |
| # correctness see Theorem 3.5.2. | ||
| # Returns the image of g under the monomorphism Grp(ri) -> S_n given by s and | ||
| # t, for n >= 5. | ||
| # Under that monomorphism s is mapped to a long cycle, t to a three cycle, |
There was a problem hiding this comment.
This comment explaining/defining the monomorphism Grp(ri) -> S_n given by s and t also applies to the previous function RECOG.FindAnElementMappingIToJ, so I suggest to move it to the general comments that apply to both functions (currently lines 825-828). We could also add a reference to Definition 3.2.2 in Conder's thesis where this notion of "alternating n-generators" is defined.
|
The implementation of |
| stdGensAn := StripMemory(stdGensAnWithMemory); | ||
| xis := RECOG.ConstructXiAn(n, stdGensAn[1], stdGensAn[2]); | ||
| # Construct filter. In <Cite Key="C12"/> filter is called E. | ||
| # In <Cite Key="JLNP13"/> filter is called `xi`. |
There was a problem hiding this comment.
| # In <Cite Key="JLNP13"/> filter is called `xi`. | |
| # In <Cite Key="JLNP13"/> filter is called `X_i`. |
Is this correct? I initially thought the comment referred to the Greek letter \xi.
| return [g, 2 * mDash + 2 * m + 3]; | ||
| end; | ||
|
|
||
| # ri : recognition node with group G |
There was a problem hiding this comment.
| # Algorithm 4.13 ConstructLongCycle in [JLNP13] | |
| # ri : recognition node with group G |
Add reference. (This function was not changed in this PR, but this seems like a useful addition.)
| # - g: element of G, | ||
| # should be a k-cycle matching c | ||
| # - k: integer, | ||
| # should be length of cycle g. |
There was a problem hiding this comment.
| # - g: element of G. | |
| # - k: integer. | |
| # If G \in [S_n, A_n] and c is a 3-cycle, then with probability at least 1-eps, | |
| # g is a k-cycle matching c (and also k >= max(3n/4, 9)). |
Make statement a bit more precise (again, was not touched in this PR). I think we do not need the lower bound on k, but it is also mentioned in [JLNP].
| od; | ||
| return tmp; | ||
| end; | ||
|
|
There was a problem hiding this comment.
| # Returns an integer m such that if the group represented by ri is isomorphic to S_n, | |
| # then necessarily m <= n |
| G := Grp(ri); | ||
| if (IsPermGroup(G) and NrMovedPoints(G) <= 6) | ||
| or (IsMatrixGroup(G) and DimensionOfMatrixGroup(G) < 3) then | ||
| Print("GuessAltsymDegree works only for degree > 6\n"); |
There was a problem hiding this comment.
| Print("GuessAltsymDegree works only for degree > 6\n"); | |
| Print("GuessSnAnDegree works only for permutation degree > 6 or matrix dimension > 2\n"); |
| ct := 0; | ||
| # vprintf IsAltsym: "New E, E = %o, O = %o, elt order = %o, Randoms = %o\n", mindege, mindego, o_fact, cte+cto; |
There was a problem hiding this comment.
| ct := 0; | |
| # vprintf IsAltsym: "New E, E = %o, O = %o, elt order = %o, Randoms = %o\n", mindege, mindego, o_fact, cte+cto; | |
| ct := 0; | |
| # vprintf IsAltsym: "New E, E = %o, O = %o, elt order = %o, Randoms = %o\n", mindege, mindego, o_fact, cte+cto; |
Indentation.
| # mindego and mindege will be respectively the smallest possible | ||
| # degrees of symmetric groups that contain the elements of odd and | ||
| # even orders, in the random sample. | ||
| # If mindego > mindege we assume the group is alternating, otherwise |
There was a problem hiding this comment.
| # If mindego > mindege we assume the group is alternating, otherwise | |
| # If mindego > mindege we guess that the group is alternating, otherwise |
I think "guess" is more precise here than "assume".
| if ct > maxtries then | ||
| # vprintf IsAltsym: "maxtries exceeded - giving up!"; | ||
| return fail; | ||
| fi; |
There was a problem hiding this comment.
I find this part confusing. We only exit the preceding loop if mindeg, mindege and mindego did not change for many iterations, and after the loop, ct is the smallest positive integer for which the loop condition
(ct < Maximum(mintries, fac * mindeg * Int(Ceil(Log(Float(mindeg+1))))) or mindego = mindege+1) and ct <= maxtries
fails. Hence I think this if statement is equivalent to the following:
- If
mindego = mindege+1, we always returnfail(because the loop can only end withct > maxtries. - If
mindego <> mindege+1, we returnfailat this point if and only iffac * mindeg * Int(Ceil(Log(Float(mindeg+1)))) > maxtries. (Here I use the reasonable assumption thatmintries < maxtries.)
Is this the desired behaviour? A previous comment says that the function returns fail if "maxtries elements are sampled with no decision made", but this does not seem to match what is happening.
| cto := 0; | ||
| cte := 0; |
There was a problem hiding this comment.
These counters are increased later on, but their values are never used for anything. I think they can be removed.
|
The guessing strategy of |
Co-authored-by: Torben Wiedemann <7226617+TWiedemann@users.noreply.github.com>
| if not IsInt(N) then | ||
| return; | ||
| fi; |
There was a problem hiding this comment.
| if not IsInt(N) then | |
| return; | |
| fi; | |
| # if not IsInt(N) then | |
| # return; | |
| # fi; |
If the code after these three lines is commented out, then they should also be commented out because they no longer do anything.
| if N = TemporaryFailure then | ||
| RECOG.SnAnResetCache(ri); | ||
| fi; | ||
| if not IsInt(N) then |
There was a problem hiding this comment.
| if not IsInt(N) then | |
| # If N is TemporaryFailure or NeverApplicable, pass it on | |
| if not IsInt(N) then |
|
I am finished with my review. Everything looks good, so I think we can merge as seen as all comments above are resolved. I think this PR will resolve #348, but correct me if I am wrong. |
A PR based on #176.
We are going to implement the extensions by Conder and Derek Holt's
GuessAltSymDegree.