Skip to content

Add constructive recognition for SL_n, take 2#371

Open
fingolfin wants to merge 46 commits into
masterfrom
Include_ConstructiveRecognition_SL
Open

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

Conversation

@fingolfin

@fingolfin fingolfin commented Feb 3, 2026

Copy link
Copy Markdown
Member

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

Comment thread gap/projective/constructive_recognition/SL/BaseCase.gi Outdated
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))

@fingolfin

Copy link
Copy Markdown
Member Author

Another TODO: in Daniel's thesis, the algorithm 26 ComputeHorizontalTransvections currently differs from what @aniemeyer and me manage to prove. It would be good to check if the algorithm as written in the thesis matches the implemented version precisely, or not...

The difference is that in the thesis, in five places entries of the matrix $c^{-1}$ are used. But in our write-up, we instead use entries of $c$ in what corresponds to line 11 of the written algorithm.


# Now cleanup row n left of column n:
for j in [1..w.n-1] do
tf := DoRowOp_n(tf,w.n,j,-c[i,j],w);

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 matches the paper draft @aniemeyer are working on, and disagrees with line 11 of Algorithm 26 in the thesis. Phew!

Comment thread makedoc.g Outdated
Comment thread regen_doc.g Outdated
@fingolfin fingolfin force-pushed the Include_ConstructiveRecognition_SL branch from e660caa to 2c1fb00 Compare June 2, 2026 09:15
@fingolfin

Copy link
Copy Markdown
Member Author

I am realizing more and more that there is very little new code here, mostly existing code was modified.

My plan is now this: first, re-arrange and split the content of sl.gi to match the structure in this PR. Then merge / rebase on that -- then we can better see the actual changes.

Depending on the findings, we may then directly go over to PR #372 and treat it similarly (there, I expect a lot more genuinely new code)

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