diff --git a/lib/classic.gi b/lib/classic.gi index 859bd86..7bcfc71 100644 --- a/lib/classic.gi +++ b/lib/classic.gi @@ -43,18 +43,39 @@ BindGlobal( "_IsEqualModScalars", return IsZero( mat2 ); end ); +# The following helper function provides compatibility +# with older GAP versions. +# Before gap-system/gap/pull/6203, 'FieldOfMatrixGroup( G )' was interpreted +# as the field of definition of the invariant forms stored in 'G'. +# This was not always correct, hence we decided to add a component +# 'baseDomain' to the records that describe the invariant forms created with +# 'InvariantBilinearForm' etc. +BindGlobal("Forms_FieldOfDefinition", function( form_record, G ) + if IsBound( form_record.baseDomain ) then + return form_record.baseDomain; + else + return FieldOfMatrixGroup( G ); + fi; +end ); + BindGlobal("Forms_OrthogonalGroup", function( g, form ) local stored, gf, d, wanted, mat1, mat2, mat, matinv, gens, gg; - stored:= InvariantQuadraticForm( g ).matrix; + stored:= InvariantQuadraticForm( g ); + gf:= Forms_FieldOfDefinition( stored, g ); + stored:= stored.matrix; + + # Check that 'form' lives over the intended field. + if not IsSubset( gf, form!.basefield ) then + Error( "the defining field of
does not fit to " ); + fi; # If the prescribed form fits then just return. if stored = form!.matrix then return g; fi; - gf:= FieldOfMatrixGroup( g ); d:= DimensionOfMatrixGroup( g ); # Compute a base change matrix. @@ -80,7 +101,8 @@ BindGlobal("Forms_OrthogonalGroup", SetName( gg, Name( g ) ); fi; - SetInvariantQuadraticForm( gg, rec( matrix:= form!.matrix ) ); + SetInvariantQuadraticForm( gg, rec( matrix:= form!.matrix, + baseDomain:= gf ) ); if HasIsFullSubgroupGLorSLRespectingQuadraticForm( g ) then SetIsFullSubgroupGLorSLRespectingQuadraticForm( gg, IsFullSubgroupGLorSLRespectingQuadraticForm( g ) ); @@ -138,7 +160,7 @@ InstallMethod( GeneralOrthogonalGroupCons, { filt, G } -> GeneralOrthogonalGroupCons( filt, QuadraticFormByMatrix( InvariantQuadraticForm( G ).matrix, - FieldOfMatrixGroup( G ) ) ) ); + Forms_FieldOfDefinition( InvariantQuadraticForm( G ), G ) ) ) ); InstallMethod( GeneralOrthogonalGroupCons, "matrix group for form", @@ -278,7 +300,7 @@ InstallMethod( SpecialOrthogonalGroupCons, { filt, G } -> SpecialOrthogonalGroupCons( filt, QuadraticFormByMatrix( InvariantQuadraticForm( G ).matrix, - FieldOfMatrixGroup( G ) ) ) ); + Forms_FieldOfDefinition( InvariantQuadraticForm( G ), G ) ) ) ); InstallMethod( SpecialOrthogonalGroupCons, "matrix group for form", @@ -455,7 +477,7 @@ InstallMethod( OmegaCons, { filt, G } -> OmegaCons( filt, QuadraticFormByMatrix( InvariantQuadraticForm( G ).matrix, - FieldOfMatrixGroup( G ) ) ) ); + Forms_FieldOfDefinition( InvariantQuadraticForm( G ), G ) ) ) ); InstallMethod( OmegaCons, "matrix group for form", @@ -563,7 +585,7 @@ InstallMethod( GeneralUnitaryGroupCons, { filt, G } -> GeneralUnitaryGroupCons( filt, HermitianFormByMatrix( InvariantSesquilinearForm( G ).matrix, - FieldOfMatrixGroup( G ) ) ) ); + Forms_FieldOfDefinition( InvariantSesquilinearForm( G ), G ) ) ) ); InstallMethod( GeneralUnitaryGroupCons, "matrix group for form", @@ -619,12 +641,18 @@ InstallMethod( GeneralUnitaryGroupCons, IsPosInt, IsHermitianForm ], function( filt, d, q, form ) - local g, stored, wanted, mat1, mat2, mat, matinv, gens, gg; + local g, stored, F, wanted, mat1, mat2, mat, matinv, gens, gg; # Create the default generators and form. g:= GeneralUnitaryGroupCons( filt, d, q ); stored:= InvariantSesquilinearForm( g ).matrix; + # Check that 'form' lives over the intended field. + F:= GF(q^2); + if not IsSubset( F, form!.basefield ) then + Error( "the defining field of does not fit to " ); + fi; + # If the prescribed form fits then just return. if stored = form!.matrix then return g; @@ -632,7 +660,7 @@ InstallMethod( GeneralUnitaryGroupCons, # Compute a base change matrix. # (Check that the canonical forms are equal.) - wanted:= HermitianFormByMatrix( stored, GF(q^2) ); + wanted:= HermitianFormByMatrix( stored, F ); mat1:= BaseChangeToCanonical( form ); mat2:= BaseChangeToCanonical( wanted ); if mat1 * form!.matrix * TransposedFrobeniusMat( mat1, q ) <> @@ -652,7 +680,9 @@ InstallMethod( GeneralUnitaryGroupCons, SetName( gg, Name( g ) ); fi; - SetInvariantSesquilinearForm( gg, rec( matrix:= form!.matrix ) ); + SetInvariantSesquilinearForm( gg, rec( matrix:= form!.matrix, + baseDomain:= F ) ); + if HasIsFullSubgroupGLorSLRespectingSesquilinearForm( g ) then SetIsFullSubgroupGLorSLRespectingSesquilinearForm( gg, IsFullSubgroupGLorSLRespectingSesquilinearForm( g ) ); @@ -708,7 +738,7 @@ InstallMethod( SpecialUnitaryGroupCons, { filt, G } -> SpecialUnitaryGroupCons( filt, HermitianFormByMatrix( InvariantSesquilinearForm( G ).matrix, - FieldOfMatrixGroup( G ) ) ) ); + Forms_FieldOfDefinition( InvariantSesquilinearForm( G ), G ) ) ) ); InstallMethod( SpecialUnitaryGroupCons, "matrix group for form", @@ -748,7 +778,7 @@ InstallMethod( SpecialUnitaryGroupCons, IsPosInt, IsHermitianForm ], function( filt, d, q, form ) - local g, stored, wanted, mat1, mat2, mat, matinv, gens, gg; + local g, stored, F, wanted, mat1, mat2, mat, matinv, gens, gg; # Create the default generators and form. g:= SpecialUnitaryGroupCons( filt, d, q ); @@ -759,9 +789,15 @@ InstallMethod( SpecialUnitaryGroupCons, return g; fi; + # Check that 'form' lives over the intended field. + F:= GF(q^2); + if not IsSubset( F, form!.basefield ) then + Error( "the defining field of does not fit to " ); + fi; + # Compute a base change matrix. # (Check that the canonical forms are equal.) - wanted:= HermitianFormByMatrix( stored, GF(q^2) ); + wanted:= HermitianFormByMatrix( stored, F ); mat1:= BaseChangeToCanonical( form ); mat2:= BaseChangeToCanonical( wanted ); if mat1 * form!.matrix * TransposedFrobeniusMat( mat1, q ) <> @@ -781,7 +817,9 @@ InstallMethod( SpecialUnitaryGroupCons, SetName( gg, Name( g ) ); fi; - SetInvariantSesquilinearForm( gg, rec( matrix:= form!.matrix ) ); + SetInvariantSesquilinearForm( gg, rec( matrix:= form!.matrix, + baseDomain:= F ) ); + if HasIsFullSubgroupGLorSLRespectingSesquilinearForm( g ) then SetIsFullSubgroupGLorSLRespectingSesquilinearForm( gg, IsFullSubgroupGLorSLRespectingSesquilinearForm( g ) ); @@ -830,7 +868,7 @@ InstallMethod( SymplecticGroupCons, { filt, G } -> SymplecticGroupCons( filt, BilinearFormByMatrix( InvariantBilinearForm( G ).matrix, - FieldOfMatrixGroup( G ) ) ) ); + Forms_FieldOfDefinition( InvariantBilinearForm( G ), G ) ) ) ); InstallMethod( SymplecticGroupCons, "matrix group for form", @@ -870,7 +908,7 @@ InstallMethod( SymplecticGroupCons, IsPosInt, IsBilinearForm ], function( filt, d, q, form ) - local g, stored, wanted, mat1, mat2, mat, matinv, gens, gg; + local g, stored, F, wanted, mat1, mat2, mat, matinv, gens, gg; # Create the default generators and form. g:= SymplecticGroupCons( filt, d, q ); @@ -881,9 +919,15 @@ InstallMethod( SymplecticGroupCons, return g; fi; + # Check that 'form' lives over the intended field. + F:= GF(q); + if not IsSubset( F, form!.basefield ) then + Error( "the defining field of does not fit to " ); + fi; + # Compute a base change matrix. # (Check that the canonical forms are equal.) - wanted:= BilinearFormByMatrix( stored, GF(q) ); + wanted:= BilinearFormByMatrix( stored, F ); mat1:= BaseChangeToCanonical( form ); mat2:= BaseChangeToCanonical( wanted ); if mat1 * form!.matrix * TransposedMat( mat1 ) <> @@ -903,7 +947,8 @@ InstallMethod( SymplecticGroupCons, SetName( gg, Name( g ) ); fi; - SetInvariantBilinearForm( gg, rec( matrix:= form!.matrix ) ); + SetInvariantBilinearForm( gg, rec( matrix:= form!.matrix, + baseDomain:= F ) ); if HasIsFullSubgroupGLorSLRespectingBilinearForm( g ) then SetIsFullSubgroupGLorSLRespectingBilinearForm( gg, IsFullSubgroupGLorSLRespectingBilinearForm( g ) ); diff --git a/tst/adv/classic.tst b/tst/adv/classic.tst index 70ff479..0ade472 100644 --- a/tst/adv/classic.tst +++ b/tst/adv/classic.tst @@ -201,6 +201,23 @@ gap> g:= GO( 3, 257, mat );; gap> InvariantQuadraticForm( g ).matrix = mat; true +# Test inconsistent fields of definition. +gap> g:= GeneralOrthogonalGroup( 5, GF(3) );; +gap> mat:= InvariantQuadraticForm( g ).matrix;; +gap> form:= QuadraticFormByMatrix( mat, GF(9) );; +gap> GeneralOrthogonalGroup( 5, GF(3), form );; +Error, the defining field of does not fit to +gap> g:= GeneralUnitaryGroup( 4, 2 );; +gap> mat:= InvariantSesquilinearForm( g ).matrix;; +gap> form:= HermitianFormByMatrix( mat, GF(16) );; +gap> GeneralUnitaryGroup( 4, 2, form ); +Error, the defining field of does not fit to +gap> g:= SymplecticGroup( 4, GF(2) );; +gap> mat:= InvariantBilinearForm( g ).matrix;; +gap> form:= BilinearFormByMatrix( mat, GF(4) );; +gap> SymplecticGroup( 4, GF(2), form ); +Error, the defining field of does not fit to + # Increase the code coverage. gap> mat:= IdentityMat( 3, GF(5) );; gap> _IsEqualModScalars( mat, Z(5) * mat );