Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SpinorNorm #4668

Merged
merged 14 commits into from
Oct 12, 2021
16 changes: 16 additions & 0 deletions doc/manualbib.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5558,4 +5558,20 @@
<other type="doi">10.1017/CBO9781139192576</other>
</book></entry>

<entry id="Tay92"><book>
<author>
<name><first>Donald E.</first><last>Taylor</last></name>
</author>
<title>The geometry of the classical groups</title>
<publisher>Heldermann Verlag, Berlin</publisher>
<year>1992</year>
<volume>9</volume>
<series>Sigma Series in Pure Mathematics</series>
<isbn>3-88538-009-9</isbn>
<mrnumber>1189139</mrnumber>
<mrclass>20E32 (20E34 20E42 20G40 51E24)</mrclass>
<mrreviewer>Gernot Stroth</mrreviewer>
<other type="pages">xii+229</other>
</book></entry>

</file>
105 changes: 105 additions & 0 deletions grp/classic.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1917,6 +1917,111 @@ InstallMethod( Omega,
{ filt, e, d, R } -> OmegaCons( filt, e, d, Size( R ) ) );


#############################################################################
##
#F WallForm( <form>, <m> ) . . . compute Wall form of <m> wrt <form>
##
## Return the Wall form of <m>, where <m> is a matrix which is orthogonal
## with respect to the bilinear form <form>, also given as a matrix.
## For the definition of Wall forms, see [Tay92, page 163].
BindGlobal( "WallForm", function( form, m )
local id, w, b, p, i, x, j, d, rank;

id := One( m );

# compute a base for Image(id-m) which is a subset of the rows of (id - m)
# We also store the index of the rows (corresponding to w) in p
w := id - m;
b := [];
p := [];
rank := 0;
for i in [ 1 .. Length(w) ] do
# add a new row and see if that increases the rank
Add( b, w[i] );
if RankMat(b) > rank then
Add( p, i );
rank := rank + 1;
else
Remove( b ); # rank was not increased, so remove the added row again
fi;
od;

# compute the form
d := Length(b);
x := NullMat(d,d,DefaultFieldOfMatrix(m));
for i in [ 1 .. d ] do
for j in [ 1 .. d ] do
x[i,j] := form[p[i]] * b[j];
od;
od;

# and return
return rec( base := b, pos := p, form := x );

end );


#############################################################################
##
#F IsSquareFFE( fld, e) . . . . . . . Tests whether <e> is a square in <fld>
##
## For an finite field element <e> of <fld> this function returns
## true if <e> is a square element in <fld> and otherwise false.
BindGlobal( "IsSquareFFE", function( fld, e )
local char, q;

danielrademacher marked this conversation as resolved.
Show resolved Hide resolved
if IsZero(e) then
return true;
else
danielrademacher marked this conversation as resolved.
Show resolved Hide resolved
char := Characteristic(fld);
# If the characteristic of fld is equal to 2, we know that every element is a
# square. Hence, we can return true.
if char = 2 then
return true;
fi;
q := Size(fld);

# If the characteristic of fld is not 2, we know that there are exactly
# (q+1)/2 elements which are a square (Huppert LA, Theorem 2.5.4). Now observe
# that for a square element e we have that e^((q-1)/2) = 1. And, thus, the
# polynomial X^((q-1)/2) - 1 has already (q-1)/2 different roots (every square
# except 0). Hence, for a non-square element e' we have that (e')^((q-1)/2) <> 1
# which proves the line below.
return IsOne(e^((q-1)/2));
fi;

end );


#############################################################################
##
#F SpinorNorm( <form>, <fld>, <m> ) . . . . . compute the spinor norm of <m>
##
##
## For a matrix <m> over the finite field <fld> of odd characteristic which
## is orthogonal with respect to the bilinear form <form>, also given as a
## matrix, this function returns One(fld) if the discriminant of the
## Wall form of <m> is (F^*)^2 and otherwise -1 * One(fld).
## For the definition of Wall forms, see [Tay92, page 163].
Copy link
Member

Choose a reason for hiding this comment

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

Actually it should be made clear (and perhaps also checked) that this function only applies to odd characteristic. Right now it always returns +1 in even characteristic; which is of course consistent with the notion of Spinor norm; but if one is interested in even characteristic, then one uses a different definition (but I need to look up the details, it's been too long). Anyway, if you don't need even char, it's fine to not cover it; but it simply should be made clear what his here and what not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In Taylors book "The geometry of the classical groups" there is no difference in the characteristic. But if there is an other definition, I change this.

Copy link
Member

Choose a reason for hiding this comment

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

You are right, in Taylor's book there is no special case here. Instead, Taylor gives a definition of SO(V) that differs from that used in GAP: in even characteristic, in GAP we have that SO and GO return the same group. But for Taylor, SO is always an index 2 subgroup of GO, namely the kernel of the Dickson invariant D:O(V) -> C_2. This then renders Theorem 11.51 true, where he shows that \Omega(V) is the intersection of SO(V) with the kernel of the Spinor norm. Unfortunately, this is false in GAP.

However, other authors handle this differently from Taylor, by using the "usual" definition for SO(V) (kernel of the determinant map on O(V)) and then defining the Spinor norm differently (sorry got no good reference right now, but see e.g. https://groupprops.subwiki.org/wiki/Spinor_norm). And Magma simply returns the Dickson invariant in char 2.

I am not saying this is better, just that it is a potential point of confusion. So it'd be good to document explicitly what happens in char 2.

So I see the following options:

  1. document that this function always returns 1 in char 2
  • correct and consistent with Taylor
  • useless for testing whether a matrix is contained in Omega in char 2 (but we can add a function DicksonInvariant for that)
  • changing this behavior in the future could be problematic
  1. change the function to produce an error in char 2, and document that
  • useless in the same sense as option 1
  • defers the decision on what to do in char 2, allowing us to go either way in the future
  1. change the function to return the Dickson invariant in char 2
  • this way the "theorem" Omega(V) = SO(V) \cap ker(SpinorNorm) becomes true within GAP
  • useful for testing membership in Omega in char 2
  • not consistent with Definition used by Taylor
  • consistent with that used elsewhere, e.g. in Magma

Right now you went with option 2, which is fine by me. It means we can decide on whether to go to option 1 or 3 at a later point in the future.

BindGlobal( "SpinorNorm", function( form, fld, m )
local one;

if Characteristic(fld) = 2 then
Error("The characteristic of <fld> needs to be odd.");
fi;

one := OneOfBaseDomain(m);
if IsOne(m) then return one; fi;

if IsSquareFFE(fld, DeterminantMat( WallForm(form,m).form )) then
return one;
else
return -1 * one;
fi;
end );



#############################################################################
##
#F WreathProductOfMatrixGroup( <M>, <P> ) . . . . . . . . . wreath product
Expand Down
31 changes: 30 additions & 1 deletion tst/testinstall/grp/classic-G.tst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# Tests for the "general" group constructors: GL, GO, GU, GammaL
#
#@local G, H, d, q, S, grps
#@local G, H, d, q, S, grps, gens, w, form, g, fld

gap> START_TEST("classic-G.tst");

Expand Down Expand Up @@ -196,6 +196,35 @@ Error, no 1st choice method found for `Omega' on 3 arguments
gap> Omega(2,2);
Error, sign <e> = 0 but dimension <d> is even

# Tests for IsSquare
gap> fld := GF(3^2);;
gap> IsSquareFFE(fld,Zero(fld));
true
gap> IsSquareFFE(fld,Z(3^2)^6);
true
gap> IsSquareFFE(fld,Z(3^2)^7);
false
gap> fld := GF(2^2);;
gap> IsSquareFFE(fld,PseudoRandom(fld));
true

# Tests for SpinorNorm
gap> G := Omega(1,4,3);;
gap> gens := GeneratorsOfGroup(G);;
gap> form := G!.InvariantBilinearForm.matrix;;
gap> SpinorNorm(form,GF(3),gens[1]);
Z(3)^0
gap> SpinorNorm(form,GF(3),gens[2]);
Z(3)^0
gap> w := PrimitiveElement(GF(3));;
gap> g := IdentityMat(4,GF(3));;
gap> SpinorNorm(form,GF(3),g);
Z(3)^0
gap> g[1,1] := w^3;;
gap> g[4,4] := w^(-3);;
gap> SpinorNorm(form,GF(3),g);
Z(3)

# Membership tests in GL, SL, GO, SO, GU, SU, Sp can be delegated
# to the tests of the stored respected forms and therefore are cheap.
gap> for d in [ 1 .. 10 ] do
Expand Down