Skip to content

Commit

Permalink
Symplectic C3 (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
maxhauck authored Nov 17, 2021
1 parent 9632197 commit 15f217a
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 1 deletion.
22 changes: 22 additions & 0 deletions gap/ClassicalMaximals.gi
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,28 @@ function(n, q)
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);

BindGlobal("C4SubgroupsSymplecticGeneric",
function(n, q)
local result, l, halfOfEvenFactorsOfn, n_1, n_2;
Expand Down
82 changes: 82 additions & 0 deletions gap/SemilinearMatrixGroups.gi
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,85 @@ 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("<s> must be prime and a divisor of <d> but <s> = ", s,
" and <d> = ", d);
fi;
if not IsEvenInt(QuoInt(d, s)) then
ErrorNoReturn("The quotient <d> / <s> must be even but <d> = ", d,
" and <s> = ", 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("<d> must be divisible by 2 but <d> = ", d);
fi;
if q mod 2 = 0 then
ErrorNoReturn("<q> must be odd but <q> = ", q);
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);
29 changes: 29 additions & 0 deletions tst/standard/SemilinearMatrixGroups.tst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,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], [6, 5]];;
gap> ForAll(testsUnitarySemilinearSp, TestUnitarySemilinearSp);
true
gap> TestMatricesInducingGaloisGroupOfGFQToSOverGFQ := function(args)
> local q, s, gens;
> q := args[1];
Expand Down
2 changes: 1 addition & 1 deletion tst/standard/SubfieldMatrixGroups.tst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,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
Expand Down
4 changes: 4 additions & 0 deletions tst/standard/TensorInducedMatrixGroups.tst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ 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

Expand Down

0 comments on commit 15f217a

Please sign in to comment.