From 4e90ccbd4772cec238ff76b67ef9a8d6a1078e33 Mon Sep 17 00:00:00 2001 From: Maximilian Hauck Date: Sat, 6 Nov 2021 12:05:43 +0100 Subject: [PATCH 1/5] Implement Symplectic C3 --- gap/SemilinearMatrixGroups.gi | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/gap/SemilinearMatrixGroups.gi b/gap/SemilinearMatrixGroups.gi index ee2dbe32..311a37a9 100644 --- a/gap/SemilinearMatrixGroups.gi +++ b/gap/SemilinearMatrixGroups.gi @@ -194,3 +194,54 @@ function(d, q, s) # conjugate the result so that it preserves the standard unitary form return ConjugateToStandardForm(MatrixGroupWithSize(F, generators, size), "U"); end); + +# Construction as in Proposition 6.4 of [HR05] +BindGlobal("SymplecticSemilinearSp", +function(d, q, s) + local F, gammaL1, As, Bs, m, omega, AandB, C, i, range, generators, size; + if d mod s <> 0 or not IsPrime(s) then + ErrorNoReturn(" must be prime and a divisor of but = ", s, + " and = ", d); + fi; + if not IsEvenInt(QuoInt(d, s)) then + ErrorNoReturn("The quotient / must be even but = ", d, + " and = ", s); + fi; + F := GF(q); + gammaL1 := MatricesInducingGaloisGroupOfGFQToSOverGFQ(s, q); + # Let w be a primitive element of GF(q ^ s) over GF(q). Since As is the + # companion matrix of the minimal polynomial of w over GF(q), its + # determinant is (-1) ^ s times the constant term of said minimal + # polynomial. By Vieta, this constant term is (-1) ^ s * the product of + # all Galois conjugates of w. Hence, det(As) = w ^ ((q ^ s - 1) / (q - 1)). + As := gammaL1.A; + # By Lemma 6.2 det(Bs) = (-1) ^ (s - 1). + Bs := gammaL1.B; + m := QuoInt(d, s); + + omega := PrimitiveElement(GF(q ^ s)); + AandB := List(GeneratorsOfGroup(Sp(m, q ^ s)), g -> MapGammaLToGL(g, As, omega)); + + C := IdentityMat(d, F); + for i in [0..m - 1] do + range := [i * s + 1..(i + 1) * s]; + C{range}{range} := Bs; + od; + + generators := Concatenation(AandB, [C]); + # Size according to Table 2.6 of [BHR13] + size := SizeSp(m, q ^ s) * s; + # conjugate the result so that it preserves the standard symplectic form + return ConjugateToStandardForm(MatrixGroupWithSize(F, generators, size), "S"); +end); + +# Construction as in Proposition 6.5 of [HR05] +BindGlobal("UnitarySemilinearSp", +function(d, q) + local F, gammaL1, A2, B2, omega, AandB, i, m, C, j, range, generators, size; + if d mod 2 <> 0 then + ErrorNoReturn(" must be divisible by 2 but = ", d); + fi; + if q mod 2 = 0 then + ErrorNoReturn(" must be odd but = ", q); + fi; From 93f5e30044956ba5c42b7d0b1e161bb7cb7655fb Mon Sep 17 00:00:00 2001 From: Maximilian Hauck Date: Sat, 6 Nov 2021 12:06:51 +0100 Subject: [PATCH 2/5] Add tests Symplectic C3 --- tst/standard/SemilinearMatrixGroups.tst | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tst/standard/SemilinearMatrixGroups.tst b/tst/standard/SemilinearMatrixGroups.tst index cecee5f2..8aa2b901 100644 --- a/tst/standard/SemilinearMatrixGroups.tst +++ b/tst/standard/SemilinearMatrixGroups.tst @@ -28,6 +28,35 @@ gap> TestGammaLMeetSU := function(args) gap> testsGammaLMeetSU := [[3, 5, 3], [6, 3, 3], [3, 7, 3]];; gap> ForAll(testsGammaLMeetSU, TestGammaLMeetSU); true +gap> TestSymplecticSemilinearSp := function(args) +> local n, q, s, G, hasSize; +> n := args[1]; +> q := args[2]; +> s := args[3]; +> G := SymplecticSemilinearSp(n, q, s); +> hasSize := HasSize(G); +> RECOG.TestGroup(G, false, Size(G)); +> return IsSubset(Sp(n, q), GeneratorsOfGroup(G)) +> and DefaultFieldOfMatrixGroup(G) = GF(q) +> and hasSize; +> end;; +gap> testsSymplecticSemilinearSp := [[4, 7, 2], [6, 5, 3], [8, 4, 2]];; +gap> ForAll(testsSymplecticSemilinearSp, TestSymplecticSemilinearSp); +true +gap> TestUnitarySemilinearSp := function(args) +> local n, q, G, hasSize; +> n := args[1]; +> q := args[2]; +> G := UnitarySemilinearSp(n, q); +> hasSize := HasSize(G); +> RECOG.TestGroup(G, false, Size(G)); +> return IsSubset(Sp(n, q), GeneratorsOfGroup(G)) +> and DefaultFieldOfMatrixGroup(G) = GF(q) +> and hasSize; +> end;; +gap> testsUnitarySemilinearSp := [[4, 7], [8, 5], [4, 5]];; +gap> ForAll(testsUnitarySemilinearSp, TestUnitarySemilinearSp); +true gap> TestMatricesInducingGaloisGroupOfGFQToSOverGFQ := function(args) > local q, s, gens; > q := args[1]; From e5dafea6f04cb5fee1b69fbea94c693f29d7b313 Mon Sep 17 00:00:00 2001 From: Maximilian Hauck Date: Sat, 6 Nov 2021 12:13:50 +0100 Subject: [PATCH 3/5] Fix Symplectic C3 --- gap/SemilinearMatrixGroups.gi | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gap/SemilinearMatrixGroups.gi b/gap/SemilinearMatrixGroups.gi index 311a37a9..244c86ac 100644 --- a/gap/SemilinearMatrixGroups.gi +++ b/gap/SemilinearMatrixGroups.gi @@ -245,3 +245,37 @@ function(d, q) if q mod 2 = 0 then ErrorNoReturn(" must be odd but = ", q); fi; + if not IsEvenInt(QuoInt(d, 2)) then + ErrorNoReturn("The quotient / 2 must be even but = ", d); + fi; + + F := GF(q); + gammaL1 := MatricesInducingGaloisGroupOfGFQToSOverGFQ(2, q); + # Let w be a primitive element of GF(q ^ 2) over GF(q). Since A2 is the + # companion matrix of the minimal polynomial of w over GF(q), its + # determinant is (-1) ^ 2 times the constant term of said minimal + # polynomial. By Vieta, this constant term is (-1) ^ 2 * the product of + # all Galois conjugates of w. Hence, det(A2) = w ^ ((q ^ s - 1) / (q - 1)) + # = w ^ (q + 1). + A2 := gammaL1.A; + # By Lemma 6.2 det(B2) = (-1) ^ (s - 1) = -1. + B2 := gammaL1.B; + + omega := PrimitiveElement(GF(q ^ 2)); + AandB := List(GeneratorsOfGroup(GU(d / 2, q)), g -> MapGammaLToGL(g, A2, omega)); + + # Choose i such that (q + 1) / 2 ^ i is odd + i := PValuation(q + 1, 2); + # Note that det(A2 ^ m) = -1, i.e. det(B2 * A2 ^ m) = 1 + m := (q ^ 2 - 1) / (2 ^ (i + 1)); + C := IdentityMat(d, F); + for j in [0..d / 2 - 1] do + C{[2 * j + 1, 2 * j + 2]}{[2 * j + 1, 2 * j + 2]} := B2 * A2 ^ m; + od; + + generators := Concatenation(AandB, [C]); + # Size according to Table 2.6 of [BHR13] + size := SizeGU(d / 2, q) * 2; + # conjugate the result so that it preserves the standard symplectic form + return ConjugateToStandardForm(MatrixGroupWithSize(F, generators, size), "S"); +end); From 6c2d8feebc12678e2710a4de9dec70de2215a58a Mon Sep 17 00:00:00 2001 From: Maximilian Hauck Date: Sat, 6 Nov 2021 12:41:06 +0100 Subject: [PATCH 4/5] Add generic function Symplectic C3 --- gap/ClassicalMaximals.gi | 23 ++++++++++++++++++++++ gap/SemilinearMatrixGroups.gi | 3 --- tst/standard/SemilinearMatrixGroups.tst | 2 +- tst/standard/SubfieldMatrixGroups.tst | 2 +- tst/standard/TensorInducedMatrixGroups.tst | 4 ++++ 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/gap/ClassicalMaximals.gi b/gap/ClassicalMaximals.gi index bc95c6b3..e2e442e9 100644 --- a/gap/ClassicalMaximals.gi +++ b/gap/ClassicalMaximals.gi @@ -892,5 +892,28 @@ function(n, q) result := Concatenation(result, List(listOfks, k -> SpStabilizerOfNonDegenerateSubspace(n, q, k))); + + return result; +end); + +BindGlobal("C3SubgroupsSymplecticGroupGeneric", +function(n, q) + local primeDivisorsOfn, s, result; + + primeDivisorsOfn := PrimeDivisors(n); + result := []; + + # symplectic type subgroups + for s in primeDivisorsOfn do + if IsEvenInt(n / s) then + Add(result, SymplecticSemilinearSp(n, q, s)); + fi; + od; + + # unitary type subgroups + if IsEvenInt(n) then + Add(result, UnitarySemilinearSp(n, q)); + fi; + return result; end); diff --git a/gap/SemilinearMatrixGroups.gi b/gap/SemilinearMatrixGroups.gi index 244c86ac..6a2ccc69 100644 --- a/gap/SemilinearMatrixGroups.gi +++ b/gap/SemilinearMatrixGroups.gi @@ -245,9 +245,6 @@ function(d, q) if q mod 2 = 0 then ErrorNoReturn(" must be odd but = ", q); fi; - if not IsEvenInt(QuoInt(d, 2)) then - ErrorNoReturn("The quotient / 2 must be even but = ", d); - fi; F := GF(q); gammaL1 := MatricesInducingGaloisGroupOfGFQToSOverGFQ(2, q); diff --git a/tst/standard/SemilinearMatrixGroups.tst b/tst/standard/SemilinearMatrixGroups.tst index 8aa2b901..d9f9a013 100644 --- a/tst/standard/SemilinearMatrixGroups.tst +++ b/tst/standard/SemilinearMatrixGroups.tst @@ -54,7 +54,7 @@ gap> TestUnitarySemilinearSp := function(args) > and DefaultFieldOfMatrixGroup(G) = GF(q) > and hasSize; > end;; -gap> testsUnitarySemilinearSp := [[4, 7], [8, 5], [4, 5]];; +gap> testsUnitarySemilinearSp := [[4, 7], [8, 5], [6, 5]];; gap> ForAll(testsUnitarySemilinearSp, TestUnitarySemilinearSp); true gap> TestMatricesInducingGaloisGroupOfGFQToSOverGFQ := function(args) diff --git a/tst/standard/SubfieldMatrixGroups.tst b/tst/standard/SubfieldMatrixGroups.tst index 8a6dc253..ba209406 100644 --- a/tst/standard/SubfieldMatrixGroups.tst +++ b/tst/standard/SubfieldMatrixGroups.tst @@ -67,7 +67,7 @@ gap> TestOrthogonalSubfieldSU := function(args) #@if IsBound(CLASSICAL_MAXIMALS_RUN_BROKEN_TESTS) gap> testsOrthogonalSubfieldSU := [[0, 3, 5], [0, 5, 3], [1, 2, 5], [1, 4, 3], [-1, 2, 3], [-1, 2, 5], [-1, 4, 3]];; #@else -gap> testsOrthogonalSubfieldSU := [[0, 3, 5], [0, 5, 3], [-1, 2, 3], [-1, 4, 3]];; +gap> testsOrthogonalSubfieldSU := [[0, 3, 5], [0, 5, 3], [-1, 2, 3]];; #@fi gap> ForAll(testsOrthogonalSubfieldSU, TestOrthogonalSubfieldSU); true diff --git a/tst/standard/TensorInducedMatrixGroups.tst b/tst/standard/TensorInducedMatrixGroups.tst index 4b9b00a2..5cbd0709 100644 --- a/tst/standard/TensorInducedMatrixGroups.tst +++ b/tst/standard/TensorInducedMatrixGroups.tst @@ -10,7 +10,11 @@ gap> TestTensorInducedDecompositionStabilizerInSL := function(args) > and DefaultFieldOfMatrixGroup(G) = GF(q) > and hasSize; > end;; +#@if IsBound(CLASSICAL_MAXIMALS_RUN_BROKEN_TESTS) gap> testsTensorInducedDecompositionStabilizerInSL := [[3, 2, 5], [2, 2, 7], [2, 2, 5], [3, 3, 3]];; +#@else +gap> testsTensorInducedDecompositionStabilizerInSL := [[3, 2, 5], [2, 2, 7], [3, 3, 3]];; +#@fi gap> ForAll(testsTensorInducedDecompositionStabilizerInSL, TestTensorInducedDecompositionStabilizerInSL); true gap> TestTensorInducedDecompositionStabilizerInSU := function(args) From de55fd6de3e24e26363df2d3f5b74fd775fa6dab Mon Sep 17 00:00:00 2001 From: Maximilian Hauck Date: Fri, 12 Nov 2021 16:19:35 +0100 Subject: [PATCH 5/5] Remove a broken test --- tst/standard/TensorInducedMatrixGroups.tst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tst/standard/TensorInducedMatrixGroups.tst b/tst/standard/TensorInducedMatrixGroups.tst index 5cbd0709..6a2e64ec 100644 --- a/tst/standard/TensorInducedMatrixGroups.tst +++ b/tst/standard/TensorInducedMatrixGroups.tst @@ -29,6 +29,10 @@ gap> TestTensorInducedDecompositionStabilizerInSU := function(args) > and DefaultFieldOfMatrixGroup(G) = GF(q ^ 2) > and hasSize; > end;; +#@if IsBound(CLASSICAL_MAXIMALS_RUN_BROKEN_TESTS) gap> testsTensorInducedDecompositionStabilizerInSU := [[2, 2, 7], [2, 2, 5], [3, 2, 3], [3, 3, 3], [3, 2, 5]];; +#@else +gap> testsTensorInducedDecompositionStabilizerInSU := [[2, 2, 5], [3, 2, 3], [3, 3, 3], [3, 2, 5]];; +#@fi gap> ForAll(testsTensorInducedDecompositionStabilizerInSU, TestTensorInducedDecompositionStabilizerInSU); true