diff --git a/doc/manualbib.xml b/doc/manualbib.xml index 99cc0a62a0..90eea8a038 100644 --- a/doc/manualbib.xml +++ b/doc/manualbib.xml @@ -5558,4 +5558,20 @@ 10.1017/CBO9781139192576 + + + Donald E.Taylor + + The geometry of the classical groups + Heldermann Verlag, Berlin + 1992 + 9 + Sigma Series in Pure Mathematics + 3-88538-009-9 + 1189139 + 20E32 (20E34 20E42 20G40 51E24) + Gernot Stroth + xii+229 + + diff --git a/grp/classic.gi b/grp/classic.gi index 885f863d80..b827860610 100644 --- a/grp/classic.gi +++ b/grp/classic.gi @@ -1917,6 +1917,111 @@ InstallMethod( Omega, { filt, e, d, R } -> OmegaCons( filt, e, d, Size( R ) ) ); +############################################################################# +## +#F WallForm(
, ) . . . compute Wall form of wrt +## +## Return the Wall form of , where is a matrix which is orthogonal +## with respect to the bilinear 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 is a square in +## +## For an finite field element of this function returns +## true if is a square element in and otherwise false. +BindGlobal( "IsSquareFFE", function( fld, e ) + local char, q; + + if IsZero(e) then + return true; + else + 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( , , ) . . . . . compute the spinor norm of +## +## +## For a matrix over the finite field of odd characteristic which +## is orthogonal with respect to the bilinear form , also given as a +## matrix, this function returns One(fld) if the discriminant of the +## Wall form of is (F^*)^2 and otherwise -1 * One(fld). +## For the definition of Wall forms, see [Tay92, page 163]. +BindGlobal( "SpinorNorm", function( form, fld, m ) + local one; + + if Characteristic(fld) = 2 then + Error("The characteristic of 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( ,

) . . . . . . . . . wreath product diff --git a/tst/testinstall/grp/classic-G.tst b/tst/testinstall/grp/classic-G.tst index 098b062aee..7861935b31 100644 --- a/tst/testinstall/grp/classic-G.tst +++ b/tst/testinstall/grp/classic-G.tst @@ -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"); @@ -196,6 +196,35 @@ Error, no 1st choice method found for `Omega' on 3 arguments gap> Omega(2,2); Error, sign = 0 but dimension 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