diff --git a/init.g b/init.g index 6f21851..d01ab28 100644 --- a/init.g +++ b/init.g @@ -14,3 +14,4 @@ ReadPackage("forms","lib/forms.gd"); ReadPackage("forms","lib/recognition.gd"); +ReadPackage("forms","lib/conformal.gd"); diff --git a/lib/conformal.gd b/lib/conformal.gd new file mode 100644 index 0000000..1151306 --- /dev/null +++ b/lib/conformal.gd @@ -0,0 +1,152 @@ +############################################################################# +## +#A InvariantBilinearFormUpToScalars( ) +## +## <#GAPDoc Label="InvariantBilinearFormUpToScalars"> +## +## +## +## +## This attribute describes a bilinear form that is invariant up to scalars +## under the matrix group matgrp. +## The form is given by a record with the component matrix +## which is a matrix J such that for every generator g of +## matgrp the equation g \cdot J \cdot g^{tr} = \lambda(g) J +## holds, for \lambda(g) in the +## value of matgrp. +## +## +## <#/GAPDoc> +## +DeclareAttribute( "InvariantBilinearFormUpToScalars", IsMatrixGroup ); + + +############################################################################# +## +#P IsFullSubgroupGLRespectingBilinearFormUpToScalars( ) +## +## <#GAPDoc Label="IsFullSubgroupGLRespectingBilinearFormUpToScalars"> +## +## +## +## +## This property tests whether the matrix group matgrp is the full +## subgroup of GL respecting, up to scalars, the form stored as the value of +## for matgrp. +## +## +## <#/GAPDoc> +## +DeclareProperty( "IsFullSubgroupGLRespectingBilinearFormUpToScalars", + IsMatrixGroup ); + +InstallTrueMethod( IsGroup, + IsFullSubgroupGLRespectingBilinearFormUpToScalars ); + + +############################################################################# +## +#O ConformalSymplecticGroupCons( ,
) +#O ConformalSymplecticGroupCons( , ) +#O ConformalSymplecticGroupCons( , ) +#O ConformalSymplecticGroupCons( , , ) +#O ConformalSymplecticGroupCons( , , , ) +#O ConformalSymplecticGroupCons( , , , ) +#O ConformalSymplecticGroupCons( , , , ) +#O ConformalSymplecticGroupCons( , , ) +#O ConformalSymplecticGroupCons( , , , ) +#O ConformalSymplecticGroupCons( , , , ) +#O ConformalSymplecticGroupCons( , , , ) +## +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsBilinearForm ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsMatrixOrMatrixObj ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsGroup ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsPosInt, IsRing ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsPosInt, IsRing, IsBilinearForm ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsPosInt, IsRing, IsMatrixOrMatrixObj ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsPosInt, IsRing, IsGroup ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsPosInt, IsPosInt ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsPosInt, IsPosInt, IsBilinearForm ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsPosInt, IsPosInt, IsMatrixOrMatrixObj ] ); +DeclareConstructor( "ConformalSymplecticGroupCons", [ IsGroup, IsPosInt, IsPosInt, IsGroup ] ); + + +############################################################################# +## +#F ConformalSymplecticGroup( [, ], [, ] ) conf. sympl. gp. +#F ConformalSymplecticGroup( [, ], [, ] ) conf. sympl. gp. +#F ConformalSymplecticGroup( [, ] ) conformal symplectic group +#F CSp( [, ], [, ] ) conformal symplectic group +#F CSp( [, ], [, ] ) conformal symplectic group +#F CSp( [, ] ) conformal symplectic group +## +## <#GAPDoc Label="ConformalSymplecticGroup"> +## +## ConformalSymplecticGroup +## +## +## +## +## +## +## +## +## constructs a group isomorphic to the conformal symplectic group +## CSp( d, R ) of those d \times d +## matrices over the ring R or the field with q elements, +## respectively, +## that respect a fixed nondegenerate symplectic form up to scalars, +## in the category given by the filter filt. +##

+## Currently only finite fields R are supported. +##

+## If filt is not given it defaults to +## , +## and the returned group is the conformal symplectic group itself. +## Another supported value for filt is +## ; +## in this case, the argument form is not supported. +##

+## If the arguments describe a matrix group over a finite field then +## the desired bilinear form can be specified via form, +## which can be either a matrix +## or a form object in +## or a group with stored +## or +## value +## (and then this form is taken). +##

+## A given form determines and d, and also R +## except if form is a matrix that does not store its +## value. +## These parameters can be entered, and an error is signalled if they do +## not fit to the given form. +##

+## If form is not given then a default is chosen as described in the +## introduction to Section . +##

+## g:= ConformalSymplecticGroup( 4, 2 ); +## CSp(4,2) +## gap> Size( g ); +## 720 +## gap> StructureDescription( g ); +## "S6" +## gap> ConformalSymplecticGroup( IsPermGroup, 4, 2 ); +## Perm_CSp(4,2) +## ]]> +## +## +## <#/GAPDoc> +## +DeclareGlobalFunction( "ConformalSymplecticGroup" ); + +DeclareSynonym( "CSp", ConformalSymplecticGroup ); + diff --git a/lib/conformal.gi b/lib/conformal.gi new file mode 100644 index 0000000..4792ee3 --- /dev/null +++ b/lib/conformal.gi @@ -0,0 +1,412 @@ + +# auxiliary function analogous to `DescribesInvariantBilinearForm` +BindGlobal( "DescribesInvariantBilinearFormUpToScalars", + obj -> IsMatrixOrMatrixObj( obj ) or + IsBilinearForm( obj ) or + ( IsGroup( obj ) and HasInvariantBilinearForm( obj ) ) or + ( IsGroup( obj ) and HasInvariantBilinearFormUpToScalars( obj ) ) ); + + +############################################################################# +## +#F ConformalSymplecticGroup( [, ], [, ] ) conf. sympl. gp. +#F ConformalSymplecticGroup( [, ], [, ] ) conf. sympl. gp. +#F ConformalSymplecticGroup( [, ] ) conformal symplectic group +#F CSp( [, ], [, ] ) conformal symplectic group +#F CSp( [, ], [, ] ) conformal symplectic group +#F CSp( [, ] ) conformal symplectic group +## +InstallGlobalFunction( ConformalSymplecticGroup, function ( arg ) + local filt, form; + + if IsFilter( First( arg ) ) then + filt:= Remove( arg, 1 ); + else + filt:= IsMatrixGroup; + fi; + if DescribesInvariantBilinearFormUpToScalars( Last( arg ) ) then + # interpret this argument (matrix or form or group with stored form) + # as "up to scalars" + form:= Remove( arg ); + if Length( arg ) = 0 then + # ( [, ] ) + return ConformalSymplecticGroupCons( filt, form ); + elif Length( arg ) = 2 and IsPosInt( arg[1] ) + and ( IsRing( arg[2] ) or IsPosInt( arg[2] ) ) then + # ( [, ], , ) or ( [, ], , ) + return ConformalSymplecticGroupCons( filt, arg[1], arg[2], form ); + fi; + elif Length( arg ) = 2 and IsPosInt( arg[1] ) + and ( IsRing( arg[2] ) or IsPosInt( arg[2] ) ) then + # ( [, ], ) or ( [, ], ) + return ConformalSymplecticGroupCons( filt, arg[1], arg[2] ); + fi; + Error( "usage: ConformalSymplecticGroup( [, ], [, ] )\n", + "or ConformalSymplecticGroup( [, ], [, ] )\n", + "or ConformalSymplecticGroup( [, ] )" ); +end ); + + +############################################################################# +## +#M ConformalSymplecticGroupCons( , , ) +## +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension and finite field", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsField and IsFinite" ], + function( filter, d, F ) + local q, z, o, filt, g, mat1, mat2, i, mat3, size, qi, c; + + # the dimension must be even + if d mod 2 = 1 then + Error( "the dimension must be even" ); + fi; + q:= Size( F ); + z:= PrimitiveRoot( F ); + o:= One( F ); + + # Decide about the internal representation of group generators. + filt:= ValueOption( "ConstructingFilter" ); + if filt = fail then + filt:= IsPlistRep; + fi; + + # if the dimension is two it is a general linear group + if d = 2 then + g:= GL( 2, F ); +#T TODO/Note: +#T Currently `filt` is ignored here. +#T This will be fixed automatically as soon as +#T `GL` also supports the global option. + c:= List( GeneratorsOfGroup( g ), x -> Matrix( filt, F, x ) ); + c:= GroupWithGenerators( c ); + SetDimensionOfMatrixGroup( c, d ); + SetFieldOfMatrixGroup( c, F ); + SetName( c, Name( g ) ); + SetSize( c, Size( g ) ); + g:= c; + else + # CSp(4,2) + if d = 4 and q = 2 then + mat1:= Matrix( filt, F, [1,0,1,1,1,0,0,1,0,1,0,1,1,1,1,1] * o, 4 ); + mat2:= Matrix( filt, F, [0,0,1,0,1,0,0,0,0,0,0,1,0,1,0,0] * o, 4 ); + + # CSp(d,q) + else + mat1 := IdentityMatrix( filt, F, d ); + mat2 := ZeroMatrix( filt, F, d, d ); + for i in [ 2 .. d/2 ] do mat2[i,i-1]:= o; od; + for i in [ d/2+1 .. d-1 ] do mat2[i,i+1]:= o; od; + + if q mod 2 = 1 then + mat1[ 1, 1] := z; + mat1[ d, d] := z^-1; + mat2[ 1, 1] := o; + mat2[ 1,d/2+1] := o; + mat2[d-1, d/2] := o; + mat2[ d, d/2] := -o; + + elif q <> 2 then + mat1[ 1, 1] := z; + mat1[ d/2, d/2] := z; + mat1[d/2+1,d/2+1] := z^-1; + mat1[ d, d] := z^-1; + mat2[ 1,d/2-1] := o; + mat2[ 1, d/2] := o; + mat2[ 1,d/2+1] := o; + mat2[d/2+1, d/2] := o; + mat2[ d, d/2] := o; + + else + mat1[ 1, d/2] := o; + mat1[ 1, d] := o; + mat1[d/2+1, d] := o; + mat2[ 1,d/2+1] := o; + mat2[ d, d/2] := o; + fi; + fi; + + mat3:= IdentityMatrix( filt, F, d ); + for i in [ 1 .. d/2 ] do + mat3[i, i]:= z; + od; + + mat1:= ImmutableMatrix( F, mat1, true ); + mat2:= ImmutableMatrix( F, mat2, true ); + mat3:= ImmutableMatrix( F, mat3, true ); + + # avoid to call 'Group' because this would check invertibility ... + g:= GroupWithGenerators( [ mat1, mat2, mat3 ] ); + SetName( g, Concatenation( "CSp(", String(d), ",", String(q), ")" ) ); + SetDimensionOfMatrixGroup( g, d ); + SetFieldOfMatrixGroup( g, F ); + + # add the size + size := 1; + qi := 1; + for i in [ 1 .. d/2 ] do + qi := qi * q^2; + size := size * (qi-1); + od; + SetSize( g, q^((d/2)^2) * size * (q-1) ); + fi; + + # construct the form + c:= ZeroMatrix( filt, F, d, d ); + for i in [ 1 .. d/2 ] do + c[i,d-i+1]:= o; + c[d/2+i,d/2-i+1]:= -o; + od; + SetInvariantBilinearFormUpToScalars( g, + rec( matrix:= ImmutableMatrix( F, c, true ) ) ); + + SetIsFullSubgroupGLRespectingBilinearFormUpToScalars( g, true ); + + # and return + return g; +end ); + + +############################################################################# +## +#M ConformalSymplecticGroupCons( , , ) +## +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension and finite field size", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsPosInt" ], + { filt, n, q } -> ConformalSymplecticGroupCons( filt, n, GF(q) ) ); + + +############################################################################# +## +#M ConformalSymplecticGroupCons( , ) +## +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for matrix of form", + [ "IsMatrixGroup and IsFinite", "IsMatrixOrMatrixObj" ], + { filt, mat } -> ConformalSymplecticGroupCons( filt, + BilinearFormByMatrix( mat, BaseDomain( mat ) ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for group with form", + [ "IsMatrixGroup and IsFinite", "IsGroup and HasInvariantBilinearForm" ], + { filt, G } -> ConformalSymplecticGroupCons( filt, + BilinearFormByMatrix( + InvariantBilinearForm( G ).matrix, + FieldOfMatrixGroup( G ) ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for group with form", + [ "IsMatrixGroup and IsFinite", + "IsGroup and HasInvariantBilinearFormUpToScalars" ], + { filt, G } -> ConformalSymplecticGroupCons( filt, + BilinearFormByMatrix( + InvariantBilinearFormUpToScalars( G ).matrix, + FieldOfMatrixGroup( G ) ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for form", + [ "IsMatrixGroup and IsFinite", "IsBilinearForm" ], + { filt, form } -> ConformalSymplecticGroupCons( filt, + NumberRows( form!.matrix ), + form!.basefield, form ) ); + + +############################################################################# +## +#M ConformalSymplecticGroupCons( , , , ) +## +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension, finite field size, matrix of form", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsPosInt", + "IsMatrixOrMatrixObj" ], + { filt, d, q, mat } -> ConformalSymplecticGroupCons( filt, d, GF(q), + BilinearFormByMatrix( mat, GF(q) ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension, finite field size, group with form", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsPosInt", + "IsGroup and HasInvariantBilinearForm" ], + { filt, d, q, G } -> ConformalSymplecticGroupCons( filt, d, GF(q), + BilinearFormByMatrix( + InvariantBilinearForm( G ).matrix, GF(q) ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension, finite field size, group with form", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsPosInt", + "IsGroup and HasInvariantBilinearFormUpToScalars" ], + { filt, d, q, G } -> ConformalSymplecticGroupCons( filt, d, GF(q), + BilinearFormByMatrix( + InvariantBilinearFormUpToScalars( G ).matrix, GF(q) ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension, finite field size, form", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsPosInt", + "IsBilinearForm" ], + { filt, d, q, form } -> ConformalSymplecticGroupCons( filt, d, GF(q), form ) ); + + +############################################################################# +## +#M ConformalSymplecticGroupCons( , , , ) +## +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension, finite field, matrix of form", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsField and IsFinite", + "IsMatrixOrMatrixObj" ], + { filt, d, F, form } -> ConformalSymplecticGroupCons( filt, d, F, + BilinearFormByMatrix( form, F ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension, finite field, group with form", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsField and IsFinite", + "IsGroup and HasInvariantBilinearForm" ], + { filt, d, F, G } -> ConformalSymplecticGroupCons( filt, d, F, + BilinearFormByMatrix( + InvariantBilinearForm( G ).matrix, F ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension, finite field, group with form", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsField and IsFinite", + "IsGroup and HasInvariantBilinearFormUpToScalars" ], + { filt, d, F, G } -> ConformalSymplecticGroupCons( filt, d, F, + BilinearFormByMatrix( + InvariantBilinearFormUpToScalars( G ).matrix, F ) ) ); + +InstallMethod( ConformalSymplecticGroupCons, + "matrix group for dimension, finite field, form", + [ "IsMatrixGroup and IsFinite", + "IsPosInt", + "IsField and IsFinite", + "IsBilinearForm" ], + function( filt, d, F, form ) + local g, stored, wanted, mat1, mat2, mat, matinv, gens, gg; + + # Create the default generators and form. + g:= ConformalSymplecticGroupCons( filt, d, F ); + stored:= InvariantBilinearFormUpToScalars( g ).matrix; + + # If the prescribed form fits then just return. + if stored = form!.matrix then + return g; + fi; + + # Compute a base change matrix. + # (Check that the canonical forms are equal.) + wanted:= BilinearFormByMatrix( stored, F ); + mat1:= BaseChangeToCanonical( form ); + mat2:= BaseChangeToCanonical( wanted ); + if mat1 * form!.matrix * TransposedMat( mat1 ) <> + mat2 * stored * TransposedMat( mat2 ) then + Error( "canonical forms of and differ" ); + fi; + mat:= mat2^-1 * mat1; + matinv:= mat^-1; + + # Create the group w.r.t. the prescribed form. + gens:= List( GeneratorsOfGroup( g ), + x -> Matrix( matinv * x * mat, stored ) ); + gg:= GroupWithGenerators( gens ); + + UseIsomorphismRelation( g, gg ); + + if HasName( g ) then + SetName( gg, Name( g ) ); + fi; + + SetInvariantBilinearFormUpToScalars( gg, + rec( matrix:= Matrix( form!.matrix, stored ) ) ); + + if HasIsFullSubgroupGLRespectingBilinearFormUpToScalars( g ) then + SetIsFullSubgroupGLRespectingBilinearFormUpToScalars( gg, + IsFullSubgroupGLRespectingBilinearFormUpToScalars( g ) ); + fi; + + return gg; +end ); + + +############################################################################# +## +## Support `IsPermGroup` as first argument in `ConformalSymplecticGroup`. +## +PermConstructor( ConformalSymplecticGroupCons, + [ IsPermGroup, IsInt, IsObject ], + IsMatrixGroup and IsFinite); + + +############################################################################# +## +#M \in( , ) . . . . . . . . membership test method based on form +## +InstallMethod( \in, "respecting bilinear form", IsElmsColls, + [ "IsMatrixOrMatrixObj", + "IsFullSubgroupGLRespectingBilinearFormUpToScalars" ], + {} -> RankFilter( IsHandledByNiceMonomorphism ), # override nice mon. method + function( mat, G ) + local inv; + + if not IsSubset( FieldOfMatrixGroup( G ), + FieldOfMatrixList( [ mat ] ) ) then + return false; + fi; + inv:= InvariantBilinearFormUpToScalars( G ).matrix; + return _IsEqualModScalars( inv, mat * inv * TransposedMat( mat ) ); +end ); + + +############################################################################# +## +## The following methods are currently needed to make the code work +## in case one creates groups whose elements are in `IsMatrixObj`. +## Eventually we want to get rid of them (or or to add something similar +## to the GAP library). +## + +# Strictly speaking, the following is not correct, +# according to the definition of `DegreeFFE`. +# Eventually we should fix the use of `FieldOfMatrixList` +# and `FieldOfMatrixGroup`, then `DegreeFFE` will not be important anymore. +InstallOtherMethod( DegreeFFE, + [ "IsMatrixObj and IsFFECollColl" ], + mat -> DegreeOverPrimeField( BaseDomain( mat ) ) ); + +# This is a really ugly hack. +# Without this method, multiplying a matrix object with a matrix +# is possible but yields the matrix product of with the *transposed* +# of . +# (This is because GAP regards as a scalar and computes the list of +# products of with the rows of .) +InstallOtherMethod( \*, + [ "IsMatrixObj", "IsMatrix" ], + { matobj, mat } -> Unpack( matobj ) * mat ); + + +InstallOtherMethod( BilinearFormByMatrix, + "for a ffe matrix object and a field", + [ "IsMatrixObj and IsFFECollColl", "IsField and IsFinite" ], + { m, F } -> BilinearFormByMatrix( Unpack( m ), F ) ); + +InstallOtherMethod( BilinearFormByMatrix, + "for a ffe matrix object", + [ "IsMatrixObj and IsFFECollColl" ], + m -> BilinearFormByMatrix( Unpack( m ) ) ); + diff --git a/read.g b/read.g index abe27b6..08fb100 100644 --- a/read.g +++ b/read.g @@ -16,3 +16,4 @@ ReadPackage("forms", "lib/forms.gi"); ReadPackage("forms", "lib/recognition.gi"); ReadPackage("forms", "lib/classic.gi"); ReadPackage("forms", "lib/recognition_new.gi"); +ReadPackage("forms", "lib/conformal.gi"); diff --git a/tst/adv/conformal.tst b/tst/adv/conformal.tst new file mode 100644 index 0000000..0d913ba --- /dev/null +++ b/tst/adv/conformal.tst @@ -0,0 +1,63 @@ +#@local is_equal, q, F, d, filt, g, stored, pi, permmat, form, gg, pg + +gap> START_TEST( "Forms: conformal.tst" ); + +# Provide an auxiliary function (until GAP's '=' gets fast). +gap> is_equal:= function( G1, G2 ) +> return IsSubset( G1, GeneratorsOfGroup( G2 ) ) and +> IsSubset( G2, GeneratorsOfGroup( G1 ) ); +> end;; + +# Test the creation of conformal symplectic groups. +gap> for q in [ 2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19, 23, 25 ] do +> F:= GF(q); +> for d in [ 2, 4 .. 8 ] do +> for filt in [ IsPlistRep, IsPlistMatrixRep ] do +> PushOptions( rec( ConstructingFilter:= filt ) ); +> +> g:= ConformalSymplecticGroup( d, q ); +> stored:= InvariantBilinearFormUpToScalars( g ).matrix; +> pi:= Matrix( PermutationMat( (1,2), d, F ), stored ); +> permmat:= pi * stored * TransposedMat( pi ); +> form:= BilinearFormByMatrix( stored, F ); +> gg:= ConformalSymplecticGroup( d, q, permmat ); +> if not ( is_equal( g, ConformalSymplecticGroup( g ) ) and +> ( is_equal( g, ConformalSymplecticGroup( stored ) ) or +> BaseDomain( stored ) <> F ) and +> is_equal( g, ConformalSymplecticGroup( d, F ) ) and +> is_equal( g, ConformalSymplecticGroup( form ) ) and +> is_equal( g, ConformalSymplecticGroup( d, q, g ) ) and +> is_equal( g, ConformalSymplecticGroup( d, q, stored ) ) and +> is_equal( g, ConformalSymplecticGroup( d, q, form ) ) and +> is_equal( g, ConformalSymplecticGroup( d, F, g ) ) and +> is_equal( g, ConformalSymplecticGroup( d, F, stored ) ) and +> is_equal( g, ConformalSymplecticGroup( d, F, form ) ) and +> IsSubset( gg, GeneratorsOfGroup( gg ) ) and +> IsSubset( g, List( GeneratorsOfGroup( gg ), x -> x^pi ) ) ) then +> Error( "problem with CSp(", d, ",", q, ")" ); +> fi; +> +> if Size( g ) < 10^7 and filt = IsPlistRep then +> #TODO: Make this work for `IsPlistMatrixRep` +> pg:= ConformalSymplecticGroup( IsPermGroup, d, q ); +> if Size( g ) <> Size( pg ) then +> Error( "problem with CSp(IsPermGroup, ", d, ",", q, ")" ); +> fi; +> fi; +> +> #TODO: Once `SymplecticGroup` supports matrix objects, +> # the following will work. +> # sp:= SymplecticGroup( d, q, permmat ); +> # g:= ConformalSymplecticGroup( sp ); +> # if not IsSubset( g, sp ) then +> # Error( "problem with CSp(", d, ",", q, ")" ); +> # fi; +> +> PushOptions( rec( ConstructingFilter:= fail ) ); +> od; +> od; +> od; + +## +gap> STOP_TEST( "conformal.tst" ); +