From 251bafd13e034c5b58f1af2d21ad496cfe0fae71 Mon Sep 17 00:00:00 2001 From: Christian Seeger <78646626+chseeger@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:43:50 +0200 Subject: [PATCH 1/2] Fix scalars normalization in sesquilinear form detection In ClassicalForms_GeneratorsWithBetterScalarsSesquilinear, - use exponent q+1 instead of 2 - remove root-based normalization --- lib/recognition_new.gi | 9 ++-- tst/adv/test_pres_sesforms3.tst | 81 +++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 tst/adv/test_pres_sesforms3.tst diff --git a/lib/recognition_new.gi b/lib/recognition_new.gi index 5fb035e..e91f7c7 100644 --- a/lib/recognition_new.gi +++ b/lib/recognition_new.gi @@ -125,13 +125,10 @@ InstallGlobalFunction( ClassicalForms_GeneratorsWithBetterScalarsSesquilinear, if IsList(a1) then root := NthRoot(field,a1[2],a1[1]); if a1[1] = 1 then # the matrix m1 has scalar a1[2] - #if a1[2] has a square root, we can replace m1 with m1*sqrt{a1[2]}; - if LogFFE(a1[2],PrimitiveRoot(field)) mod 2 = 0 then - return [m1/NthRoot(field,a1[2],2),[One(field)]]; + if LogFFE(a1[2],PrimitiveRoot(field)) mod (q+1) = 0 then + return [m1/NthRoot(field,a1[2],q+1),[One(field)]]; fi; - return [m1,[a1[2]]]; #originally, the three lines above this return were not there. Those three lines make sure scalar becomes 1 if possible (basicaly if there is a sqrt). - elif LogFFE(root,PrimitiveRoot(field)) mod (q+1) = 0 then - return [m1/NthRoot(field,root,q+1),[One(field)]]; #either frob = id, then q+1 = 2, or frob is not trivial, then we take q+1-st root. In both cases, modify m1 to a matrix that has scalar one. + return [m1,[a1[2]]]; #originally, the three lines above this return were not there. Those three lines make sure scalar becomes 1 if possible (basically if there is a q+1-st root). else scalars := AsList(Group(NthRoot(field,a1[2],a1[1]))); # add all possible scalars for m1 if count = 0 then diff --git a/tst/adv/test_pres_sesforms3.tst b/tst/adv/test_pres_sesforms3.tst new file mode 100644 index 0000000..4509298 --- /dev/null +++ b/tst/adv/test_pres_sesforms3.tst @@ -0,0 +1,81 @@ +gap> START_TEST("Forms: test_pres_sesforms3.tst"); + +# Regression tests for issue #83: +# examples where sesquilinear forms preserved up to scalars +# were not detected due to scalar normalization issues. +gap> grp := Group([ +> [ [ Z(3^2)^3, Z(3^2)^6, Z(3^2)^7 ], +> [ Z(3^2)^7, Z(3^2)^2, Z(3)^0 ], +> [ Z(3^2)^7, Z(3^2)^7, 0*Z(3) ] ], +> [ [ 0*Z(3), 0*Z(3), Z(3) ], +> [ Z(3^2)^7, Z(3)^0, Z(3^2)^7 ], +> [ Z(3), Z(3^2), Z(3) ] ], +> [ [ Z(3^2), 0*Z(3), 0*Z(3) ], +> [ 0*Z(3), Z(3^2), 0*Z(3) ], +> [ 0*Z(3), 0*Z(3), Z(3^2) ] ] +> ]);; +gap> forms := PreservedSesquilinearForms(grp); +[ < hermitian form > ] +gap> TestPreservedSesquilinearForms(grp, forms); +true +gap> grp := Group(Z(3)^0*[ +> [ [ 0, 1, 2, 2, 0, 1, 1, 0 ], +> [ 0, 1, 0, 2, 0, 1, 0, 2 ], +> [ 1, 2, 2, 0, 0, 0, 2, 2 ], +> [ 0, 0, 0, 1, 0, 0, 0, 0 ], +> [ 0, 0, 0, 0, 1, 0, 1, 1 ], +> [ 0, 0, 0, 0, 0, 0, 0, 1 ], +> [ 0, 0, 0, 0, 0, 1, 1, 2 ], +> [ 0, 0, 0, 0, 0, 2, 0, 2 ] ], +> [ [ 2, 1, 0, 2, 2, 2, 0, 1 ], +> [ 0, 0, 0, 1, 0, 2, 2, 1 ], +> [ 1, 2, 0, 0, 1, 0, 2, 2 ], +> [ 0, 0, 0, 1, 0, 1, 2, 1 ], +> [ 1, 0, 2, 1, 1, 1, 0, 0 ], +> [ 0, 1, 0, 2, 1, 1, 1, 1 ], +> [ 1, 2, 1, 0, 0, 0, 2, 2 ], +> [ 0, 1, 0, 1, 1, 1, 2, 2 ] ], +> [ [ 0, 2, 0, 1, 1, 2, 1, 0 ], +> [ 2, 0, 1, 2, 2, 1, 0, 2 ], +> [ 2, 2, 0, 0, 0, 0, 2, 1 ], +> [ 1, 1, 1, 1, 0, 0, 1, 2 ], +> [ 1, 1, 2, 0, 2, 0, 1, 2 ], +> [ 0, 2, 0, 1, 2, 0, 2, 0 ], +> [ 1, 0, 1, 2, 2, 1, 0, 1 ], +> [ 0, 2, 0, 2, 2, 1, 1, 0 ] ] +> ]);; +gap> forms := PreservedSesquilinearForms(grp); +[ < bilinear form > ] +gap> TestPreservedSesquilinearForms(grp, forms); +true +gap> grp := Group(Z(5)^0*[ +> [ [ 0, 1, 0, 0, 0, 0, 0, 0 ], +> [ 0, 0, 0, 0, 1, 0, 0, 0 ], +> [ 0, 0, 0, 0, 0, 0, 0, 1 ], +> [ 2, 3, 4, 3, 1, 3, 2, 4 ], +> [ 1, 4, 0, 0, 1, 0, 0, 0 ], +> [ 0, 2, 2, 2, 4, 4, 2, 1 ], +> [ 2, 3, 4, 2, 1, 3, 3, 4 ], +> [ 2, 2, 3, 0, 1, 0, 0, 3 ] ], +> [ [ 0, 0, 1, 0, 0, 0, 0, 0 ], +> [ 0, 0, 0, 0, 0, 1, 0, 0 ], +> [ 2, 4, 0, 3, 2, 1, 2, 2 ], +> [ 2, 4, 0, 2, 4, 4, 4, 4 ], +> [ 4, 4, 1, 0, 1, 0, 3, 2 ], +> [ 1, 1, 2, 3, 2, 4, 1, 3 ], +> [ 3, 2, 0, 3, 1, 4, 1, 4 ], +> [ 3, 3, 1, 4, 0, 3, 4, 3 ] ], +> [ [ 0, 0, 0, 1, 0, 0, 0, 0 ], +> [ 0, 0, 0, 0, 0, 0, 1, 0 ], +> [ 2, 2, 3, 1, 3, 3, 2, 4 ], +> [ 3, 0, 0, 0, 0, 0, 0, 0 ], +> [ 1, 0, 2, 1, 0, 3, 2, 1 ], +> [ 1, 3, 2, 4, 3, 1, 2, 2 ], +> [ 0, 3, 0, 0, 0, 0, 0, 0 ], +> [ 0, 1, 3, 0, 3, 1, 0, 1 ] ] +> ]);; +gap> forms := PreservedSesquilinearForms(grp); +[ < bilinear form > ] +gap> TestPreservedSesquilinearForms(grp, forms); +true +gap> STOP_TEST("test_pres_sesforms3.tst", 10000 ); From c4f244dc5d922cb6ed0ff8cef1b213a1f1a99ee9 Mon Sep 17 00:00:00 2001 From: Christian Seeger <78646626+chseeger@users.noreply.github.com> Date: Wed, 6 May 2026 10:45:49 +0200 Subject: [PATCH 2/2] Remove unused variable 'root' --- lib/recognition_new.gi | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/recognition_new.gi b/lib/recognition_new.gi index e91f7c7..20fc6fa 100644 --- a/lib/recognition_new.gi +++ b/lib/recognition_new.gi @@ -90,7 +90,7 @@ InstallGlobalFunction( ClassicalForms_PossibleScalarsSesquilinear, ## InstallGlobalFunction( ClassicalForms_GeneratorsWithBetterScalarsSesquilinear, function( grp, frob ) - local tries, gens, field, m1, a1, new, i, scalars, root, improvegenerator, res, newgens, champion, len, qq, q; + local tries, gens, field, m1, a1, new, i, scalars, improvegenerator, res, newgens, champion, len, qq, q; # the aim of this function is to replace the matrix m1 by a # matrix that has as few solutions to the scalar equation @@ -114,7 +114,7 @@ InstallGlobalFunction( ClassicalForms_GeneratorsWithBetterScalarsSesquilinear, # if it is possible to change the matrix to multiple that preserves up to scalar one, this is achieved. improvegenerator := function(m1,i,count,len) - local a1, s, j, k, scalars, root; #I think root should be declare locally here! + local a1, s, j, k, scalars; a1 := ClassicalForms_PossibleScalarsSesquilinear(field,m1,frob); #Recall that the scalars satisfy the equation lambda^a[1] = a[2] @@ -123,7 +123,6 @@ InstallGlobalFunction( ClassicalForms_GeneratorsWithBetterScalarsSesquilinear, fi; if IsList(a1) then - root := NthRoot(field,a1[2],a1[1]); if a1[1] = 1 then # the matrix m1 has scalar a1[2] if LogFFE(a1[2],PrimitiveRoot(field)) mod (q+1) = 0 then return [m1/NthRoot(field,a1[2],q+1),[One(field)]];