Skip to content

Add constructive recognition for SL_n, take 2#371

Open
fingolfin wants to merge 41 commits into
masterfrom
Include_ConstructiveRecognition_SL
Open

Add constructive recognition for SL_n, take 2#371
fingolfin wants to merge 41 commits into
masterfrom
Include_ConstructiveRecognition_SL

Conversation

@fingolfin
Copy link
Copy Markdown
Member

@fingolfin fingolfin commented Feb 3, 2026

This is a successor for PR #330. The only difference for now is that the branch is now hosted in this repo, not in @danielrademacher's branch. This will make it easier for us here to work on it together.

The plan is to further reduce diffs between this and master, and then get it merged.

There will also soon be another PR / branch with the rest of Daniel's code.

TODOs for merging this:

  • no merge conflicts
  • all tests must pass
  • understand the change in gap/projective/classicalnatural.gi‎ and possibly remove or adjust it (see also PR Make RECOG.IsThisSL2Natural more precise #487)
  • ensure the code added here has good code coverage (i.e., is actually used)
    • we can keep some "dead" code if there is a good reason, but then it should be commented accordingly, otherwise it'll lead to a lot of confusion
    • if there are no immediate plans to use the dead code, we should consider instead putting it into a contrib subdir (as part of this PR)
  • generally perform a code review and make sure we understand everything
  • look out for bottlenecks and potential optimizations (but: correctness over performance, always)

Daniel Rademacher and others added 30 commits June 13, 2024 14:59
Make sure that the correct path of `regen_doc.g` is used
when PackageManager builds the documentation.
preliminary fix in `makedoc.g`
If one wants to build the documentation with version 1.4.3 of
PackageManager then also the calls of `OutputTextFile` require paths
relative to `DirectoryCurrent()`.
... and add some comments (pointing out this needs documentation, and
also an obvious bug in the code that would lead to an unexpected
error if the code it is in was ever run)
... which made it depend on the characteristic. This corresponds
to a change in our manuscript where it turned out we don't need this,
and experiments validate this.
The GAP kernel already does that and this is way faster.
@fingolfin fingolfin changed the title Add constructive recognition for $SL_n$, take 2 Add constructive recognition for SL_n, take 2 Feb 3, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 3, 2026

Codecov Report

❌ Patch coverage is 32.00908% with 1797 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.55%. Comparing base (67ae22b) to head (2c1fb00).

Files with missing lines Patch % Lines
...projective/constructive_recognition/utils/utils.gi 24.53% 846 Missing ⚠️
...ective/constructive_recognition/SL/sl2_BlackBox.gi 8.91% 327 Missing ⚠️
...rojective/constructive_recognition/SL/GoingDown.gi 33.33% 312 Missing ⚠️
...projective/constructive_recognition/SL/BaseCase.gi 4.72% 242 Missing ⚠️
gap/projective/constructive_recognition/SL/main.gi 52.81% 67 Missing ⚠️
.../projective/constructive_recognition/SL/GoingUp.gi 98.98% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #371      +/-   ##
==========================================
- Coverage   88.13%   81.55%   -6.58%     
==========================================
  Files          45       50       +5     
  Lines       19023    21097    +2074     
==========================================
+ Hits        16765    17205     +440     
- Misses       2258     3892    +1634     
Files with missing lines Coverage Δ
gap/base/kernel.gi 88.33% <100.00%> (+0.19%) ⬆️
.../projective/constructive_recognition/SL/GoingUp.gi 98.98% <98.98%> (ø)
gap/projective/constructive_recognition/SL/main.gi 52.81% <52.81%> (ø)
...projective/constructive_recognition/SL/BaseCase.gi 4.72% <4.72%> (ø)
...rojective/constructive_recognition/SL/GoingDown.gi 33.33% <33.33%> (ø)
...ective/constructive_recognition/SL/sl2_BlackBox.gi 8.91% <8.91%> (ø)
...projective/constructive_recognition/utils/utils.gi 24.53% <24.53%> (ø)

... and 4 files with indirect coverage changes

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

@fingolfin fingolfin force-pushed the Include_ConstructiveRecognition_SL branch from c4ddfcb to a41b2dc Compare March 17, 2026 11:48
No offense intended, but Daniel didn't make substantial change here other than deleting or moving code
@fingolfin
Copy link
Copy Markdown
Member Author

Good: tests pass, merge conflicts remove, future merging easier
Bad: test coverage on the new code is less than 27%. Quite a bit will be due to dead code. Should clean that up, and for the user code, increase code coverage.
Ugly: the diff to PR #372 keeps growing :-/

@Till-Eisen
Copy link
Copy Markdown
Collaborator

I'd like to help move this forward - what would be most useful to work on next?

Comment thread gap/projective/classicalnatural.gi Outdated
Info(InfoRecog,4,"SL2: size is ",Size(S));
return Size(S) mod (q*(q-1)*(q+1)) = 0;
# return Size(S) mod (q*(q-1)*(q+1)) = 0;
return Size(S) = (q*(q-1)*(q+1));
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This change is fishy. See also #487

I wonder why we need it. But if we do need it, then certainly there must be more; e.g. the code comment a few lines above references this code and thus must be adjusted.

Comment thread gap/projective/classicalnatural.gi Outdated
Co-authored-by: Max Horn <max@quendi.de>
@fingolfin
Copy link
Copy Markdown
Member Author

@Till-Eisen I've outlined a couple of things in the PR description that we ought to take care before merging this. I'll add some review comments soon. Happy to talk about this more next Tuesday.


factors := PrimeDivisors(q-1);
counter := 1;
F := GF(q);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

For this (and all other future code) we should strive to pass around the field, not the size.

This is key first step towards supporting alternative field implementations (such as those from the StandardFF package).

Though in this case, really the field should be derived from G (i.e. the group G is generated by matrices which have a certain BaseDomain...). On the GAP side we are discussing adding a BaseDomain for matrix groups.

G := GroupWithMemory(G);
fi;

one := One(G);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Better to use IsOne (it used to be that IsOne was super slow for matrices, but this was fixed some years ago)

Suggested change
one := One(G);

Comment on lines +46 to +70
# Step 1: Find random element of order q-1
# foundEle := false;
# while not(foundEle) do
# A := PseudoRandom(G);
# if A^(q-1) = one then
# passed := true;
# for factor in factors do
# if A^((q-1)/factor) = one then
# passed := false;
# break;
# fi;
# od;
# if passed then
# foundEle := true;
# else
# counter := counter + 1;
# fi;
# else
# counter := counter +1;
# fi;
# if counter >= max then
# return fail;
# fi;
#od;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Any reason to keep this? Otherwise I'd rather delete this.

Suggested change
# Step 1: Find random element of order q-1
# foundEle := false;
# while not(foundEle) do
# A := PseudoRandom(G);
# if A^(q-1) = one then
# passed := true;
# for factor in factors do
# if A^((q-1)/factor) = one then
# passed := false;
# break;
# fi;
# od;
# if passed then
# foundEle := true;
# else
# counter := counter + 1;
# fi;
# else
# counter := counter +1;
# fi;
# if counter >= max then
# return fail;
# fi;
#od;

# fi;
#od;

# Step 1: Find random element of order q-1 (first improvement based on magma code)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Suggested change
# Step 1: Find random element of order q-1 (first improvement based on magma code)
# Step 1: Find random element of order q-1

I don't mind crediting Magma, but this comment is super vague. If anyone knows what improvements this refers to...?

Comment on lines +72 to +85
foundEle := false;
while not(foundEle) do
A := PseudoRandom(G);
o := Order (A);
if (o mod (q - 1) = 0) then
A := A^(o/(q - 1));
foundEle := true;
else
counter := counter +1;
fi;
if counter >= max then
return fail;
fi;
od;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

can be simplified

Suggested change
foundEle := false;
while not(foundEle) do
A := PseudoRandom(G);
o := Order (A);
if (o mod (q - 1) = 0) then
A := A^(o/(q - 1));
foundEle := true;
else
counter := counter +1;
fi;
if counter >= max then
return fail;
fi;
od;
while true do
A := PseudoRandom(G);
o := Order (A);
if (o mod (q - 1) = 0) then
A := A^(o/(q - 1));
break;
fi;
counter := counter +1;
if counter >= max then
return fail;
fi;
od;

Perhaps we should also use RandomElmOrd or so (see also #237, #462)

repeat
s:=r^PseudoRandom(g);
nulls:=RECOG.FixspaceMat(s);
nullspaces:=VectorSpace(GF(q),nulls);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Same questions/suggestions as above

Comment on lines +69 to +70
shortr:=newr{[dim-3..dim]}{[dim-3..dim]};
shorts:=news{[dim-3..dim]}{[dim-3..dim]};
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I assume this means we are looking at stingray matrices with the "head/body" at the bottom right (instead of top left)?

A comment should stat that, I guess.

Comment on lines +73 to +88
readydim4:=false;
readydim3:=false;
repeat
u:=PseudoRandom(h);
orderu:=Order(u);
if orderu mod ((q^4-1)/(q-1)) = 0 then
readydim4:=true;
elif Gcd(orderu,(q^2+q+1)/Gcd(3,q-1))>1 then
readydim3:=true;
fi;
if readydim4 = true and readydim3 = true then
ready:=true;
break;
fi;
count:=count+1;
until count=30;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What's the idea here? Is this meant to be a test ("naming") to verify we have $SL_4$ ? Why is that correct, though?

I also wonder if it is better / cheaper / faster than `RecogniseClassical(h,rec(case:="linear"));



# Find random element s = r^PseudRandom(g) such that <r,s> is isomorphic to SL(4,q)
# and check whether they are isomorphic
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What is meant by "they"? The group <r,s>, and... what?


#g=SL(d,q), given as a subgroup of SL(dim,q)
#output: [SL(2,q), and a basis for the 2-dimensional subspace where it acts
RECOG.SLn_godownfromd:=function(g,q,d,dim)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It seems this is only ever called with d=4?

Is dim really necessary as an argument, can't we get that from DimensionOfMatrixGroup(g)?

Likewise for q, as Size(FieldOfMatrixGroup(g))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants