Skip to content

Recog An/Sn unknown degree: conder, holt#265

Open
ssiccha wants to merge 34 commits intogap-packages:masterfrom
ssiccha:frss/AnSnRecogUnknownDegree-2
Open

Recog An/Sn unknown degree: conder, holt#265
ssiccha wants to merge 34 commits intogap-packages:masterfrom
ssiccha:frss/AnSnRecogUnknownDegree-2

Conversation

@ssiccha
Copy link
Copy Markdown
Collaborator

@ssiccha ssiccha commented Apr 9, 2021

A PR based on #176.

We are going to implement the extensions by Conder and Derek Holt's
GuessAltSymDegree.

@ssiccha
Copy link
Copy Markdown
Collaborator Author

ssiccha commented Apr 12, 2021

Rebased the last commit onto the current version of #176.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 12, 2021

Codecov Report

❌ Patch coverage is 75.32468% with 95 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.48%. Comparing base (c309d8a) to head (16bace0).

Files with missing lines Patch % Lines
gap/generic/SnAnUnknownDegree.gi 75.13% 95 Missing ⚠️
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     
Files with missing lines Coverage Δ
gap/matrix.gi 92.97% <100.00%> (+0.01%) ⬆️
gap/perm.gi 79.76% <100.00%> (+0.07%) ⬆️
gap/projective.gi 83.17% <100.00%> (+0.08%) ⬆️
gap/generic/SnAnUnknownDegree.gi 85.07% <75.13%> (-5.02%) ⬇️

... and 12 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ssiccha ssiccha force-pushed the frss/AnSnRecogUnknownDegree-2 branch from d40a988 to dc4a895 Compare April 12, 2021 12:32
@FriedrichRober FriedrichRober force-pushed the frss/AnSnRecogUnknownDegree-2 branch from dc4a895 to f162f36 Compare June 23, 2021 14:20
@ssiccha ssiccha force-pushed the frss/AnSnRecogUnknownDegree-2 branch from cca25fd to 35a39de Compare June 23, 2021 16:37
@FriedrichRober
Copy link
Copy Markdown
Contributor

Link to our Hackmd

@ssiccha ssiccha force-pushed the frss/AnSnRecogUnknownDegree-2 branch from 96f9a25 to 705504c Compare March 28, 2022 22:01
@FriedrichRober FriedrichRober force-pushed the frss/AnSnRecogUnknownDegree-2 branch 3 times, most recently from e63f4a8 to 956884d Compare March 29, 2022 22:51
@ssiccha
Copy link
Copy Markdown
Collaborator Author

ssiccha commented Mar 29, 2022

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: Omega(-1,4,3). It has element orders <= 5, thus slips through our heuristics to weed out groups which are not isomorphic to An or Sn. Hence the SnAnUnknownDegree algorithm takes forever until it realizes, that the group in question is not an An or Sn. We think we should be able to alleviate this by simply saying that we're NeverApplicable if the vector space our group acts has less than e.g. 100 elements. And then we'll post a challenge on slack or the GAP forum whether somebody can find a small group, which makes the algorithm run slow.

And get the tests to pass again. :)

And in Make CallMethods directly write into the RecogNode update the docs of CallMethods.

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.

@ssiccha ssiccha force-pushed the frss/AnSnRecogUnknownDegree-2 branch 2 times, most recently from 3b12114 to daceec3 Compare March 29, 2022 23:52
@fingolfin
Copy link
Copy Markdown
Member

Awesome, thank you!

@fingolfin
Copy link
Copy Markdown
Member

@FriedrichRober do you think you can finish this on your own, now that @ssiccha is gone? Perhaps I can help a bit?

@FriedrichRober
Copy link
Copy Markdown
Contributor

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.

@FriedrichRober FriedrichRober force-pushed the frss/AnSnRecogUnknownDegree-2 branch 2 times, most recently from d45adbb to 7ba5ec6 Compare June 1, 2022 13:32
@FriedrichRober FriedrichRober force-pushed the frss/AnSnRecogUnknownDegree-2 branch 4 times, most recently from 85ca56f to deb2974 Compare November 7, 2022 03:36
@FriedrichRober
Copy link
Copy Markdown
Contributor

@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.

Comment on lines +252 to +256
# 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.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# 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).

Comment on lines +286 to +294
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);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
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.

@TWiedemann
Copy link
Copy Markdown
Collaborator

@FriedrichRober I went through ThreeCycleCandidatesIterator and it looks good to me! The only other comment I have is that I think whenever you write "commutating", you actually mean "non-commutating": The algorithm looks for conjugates of the involution t that do not commute with t, and counts how many it has found already. Hence I think nrCommutatingConjugates should be appropriately renamed, and some comments adapted.

Comment thread gap/generic/SnAnUnknownDegree.gi Outdated
Comment thread gap/generic/SnAnUnknownDegree.gi Outdated
Comment thread gap/generic/SnAnUnknownDegree.gi Outdated
# 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,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

@TWiedemann
Copy link
Copy Markdown
Collaborator

The implementation of RECOG.FindAnElementMappingIToJ and RECOG.FindImageSnAnSmallDegree looks flawless to me.

Comment thread gap/generic/SnAnUnknownDegree.gi Outdated
Comment thread gap/generic/SnAnUnknownDegree.gi Outdated
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`.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# 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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# 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.)

Comment on lines 740 to 743
# - g: element of G,
# should be a k-cycle matching c
# - k: integer,
# should be length of cycle g.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# - 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;

Copy link
Copy Markdown
Collaborator

@TWiedemann TWiedemann Mar 17, 2026

Choose a reason for hiding this comment

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

Suggested change
# Returns an integer m such that if the group represented by ri is isomorphic to S_n,
# then necessarily m <= n

Comment thread gap/generic/SnAnUnknownDegree.gi Outdated
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");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
Print("GuessAltsymDegree works only for degree > 6\n");
Print("GuessSnAnDegree works only for permutation degree > 6 or matrix dimension > 2\n");

Comment on lines +1210 to +1211
ct := 0;
# vprintf IsAltsym: "New E, E = %o, O = %o, elt order = %o, Randoms = %o\n", mindege, mindego, o_fact, cte+cto;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# 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".

Comment on lines +1226 to +1229
if ct > maxtries then
# vprintf IsAltsym: "maxtries exceeded - giving up!";
return fail;
fi;
Copy link
Copy Markdown
Collaborator

@TWiedemann TWiedemann Mar 17, 2026

Choose a reason for hiding this comment

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

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 return fail (because the loop can only end with ct > maxtries.
  • If mindego <> mindege+1, we return fail at this point if and only if fac * mindeg * Int(Ceil(Log(Float(mindeg+1)))) > maxtries. (Here I use the reasonable assumption that mintries < 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.

Comment on lines +1182 to +1183
cto := 0;
cte := 0;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These counters are increased later on, but their values are never used for anything. I think they can be removed.

@TWiedemann
Copy link
Copy Markdown
Collaborator

The guessing strategy of RECOG.GuessSnAnDegree seems reasonable to me. I.e. if it does not fail, the guess seems reasonable. I find it hard to estimate how likely it is to fail.

Co-authored-by: Torben Wiedemann <7226617+TWiedemann@users.noreply.github.com>
Comment on lines +1321 to +1323
if not IsInt(N) then
return;
fi;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
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
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if not IsInt(N) then
# If N is TemporaryFailure or NeverApplicable, pass it on
if not IsInt(N) then

@TWiedemann
Copy link
Copy Markdown
Collaborator

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.

@TWiedemann TWiedemann linked an issue Mar 24, 2026 that may be closed by this pull request
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.

SnAn naming algorithm

5 participants