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 group constructors PGO and PSO #4334

Merged
merged 1 commit into from
Mar 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/ref/grplib.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ gap> AsSSortedList(DihedralGroup(12:generatorNames:=["a","b","c"]));
<#Include Label="ProjectiveGeneralUnitaryGroup">
<#Include Label="ProjectiveSpecialUnitaryGroup">
<#Include Label="ProjectiveSymplecticGroup">
<#Include Label="ProjectiveGeneralOrthogonalGroup">
<#Include Label="ProjectiveSpecialOrthogonalGroup">
<#Include Label="ProjectiveOmega">
<#Include Label="ProjectiveGeneralSemilinearGroup">
<#Include Label="ProjectiveSpecialSemilinearGroup">
Expand Down
155 changes: 124 additions & 31 deletions grp/classic.gd
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,125 @@ DeclareSynonym( "PSp", PSP );

#############################################################################
##
#O ProjectiveOmegaCons( <filt>, <e>, <d>, <q> )
#F DECLARE_PROJECTIVE_ORTHOGONAL_GROUPS_OPERATION( ... )
##
BindGlobal("DECLARE_PROJECTIVE_ORTHOGONAL_GROUPS_OPERATION",
# ( <name>, <abbreviation>, <sizefunc-or-fail> )
function( nam, abbr, szf )
local pnam,cons,opr;

opr:= VALUE_GLOBAL( nam );
pnam:= Concatenation( "Projective", nam );
cons:= NewConstructor( Concatenation( pnam, "Cons" ),
[ IsGroup, IsInt, IsInt, IsInt ] );
BindGlobal( Concatenation( pnam, "Cons" ), cons );
BindGlobal( pnam, function( arg )
if Length( arg ) = 2 then
return cons( IsPermGroup, 0, arg[1], arg[2] );
elif Length( arg ) = 3 and ForAll( arg, IsInt ) then
return cons( IsPermGroup, arg[1], arg[2], arg[3] );
elif IsOperation( arg[1] ) then
if Length( arg ) = 3 then
return cons( arg[1], 0, arg[2], arg[3] );
elif Length( arg ) = 4 then
return cons( arg[1], arg[2], arg[3], arg[4] );
fi;
fi;
Error( "usage: ", pnam, "( [<filter>, ][<e>, ]<d>, <q> )" );
end );

DeclareSynonym( Concatenation( "P", abbr ), VALUE_GLOBAL( pnam ) );

# Install a method to get the permutation action on lines.
InstallMethod( cons, "action on lines",
[ IsPermGroup, IsInt, IsPosInt, IsPosInt ],
function( filter, e, n, q )
local g, p;

g:= opr( IsMatrixGroup, e, n, q );
p:= ProjectiveActionOnFullSpace( g, GF( q ), n );
if szf <> fail then
SetSize( p, szf( e, n, q, g ) );
fi;

return p;
end );
end );


#############################################################################
##
#F ProjectiveGeneralOrthogonalGroup( [<filt>, ][<e>, ]<d>, <q> )
#F PGO( [<filt>, ][<e>, ]<d>, <q> )
##
## <#GAPDoc Label="ProjectiveGeneralOrthogonalGroup">
## <ManSection>
## <Func Name="ProjectiveGeneralOrthogonalGroup" Arg='[filt, ][e, ]d, q'/>
## <Func Name="PGO" Arg='[filt, ][e, ]d, q'/>
##
## <Description>
## constructs a group isomorphic to the projective group
## PGO( <A>e</A>, <A>d</A>, <A>q</A> )
## of GO( <A>e</A>, <A>d</A>, <A>q</A> ),
## modulo the centre
Copy link
Member

Choose a reason for hiding this comment

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

A nitpick (which really is about existing documentation, which you just covered, so I don't really expect it to be addressed here): Formally, the definition is not to take the quotient modulo the center, but rather modulo scalar matrices (achieved implicitly by using a projective action on the vector). The two are related by not completely trivial mathematics. I think for a user who is not yet very experienced, this can be confusing (source: myself, many years ago ;-) -- so maybe I am just projecting here (pun not intended) and nobody else ever got confused).

Anyway, I guess what I am saying is that it might be better if we described in a separate section / paragraph what we mean by projective group (modulo scalars, equiv: acting on lines) and that this means we take a central factor, and that for many important cases ("full" groups) this in fact means factoring out the whole center. And then we can just reference that.

Thoughts? If people are not adverse to this, I could give it a go some of these days (I'd probably for now just submit an issue to not forget it...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Such a section on projective actions would be useful. It could refer to the FinInG package. (I had expected that also the recog package contains something interesting in this respect, but I did not find this at first sight.) In the other direction, the functions NormedVectors, OnLines, ProjectiveActionOnFullSpace, ProjectiveOrder could refer to the new section.

## (see <Ref Oper="GeneralOrthogonalGroup"/>),
## in the category given by the filter <A>filt</A>.
## <P/>
## If <A>filt</A> is not given it defaults to <Ref Filt="IsPermGroup"/>,
## and the returned group is the action on lines of the underlying vector
## space.
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DECLARE_PROJECTIVE_ORTHOGONAL_GROUPS_OPERATION( "GeneralOrthogonalGroup", "GO",
function( e, n, q, g )
if ( n mod 2 = 0 and ( q^(n/2) - e ) mod 2 = 0 ) or
( n mod 2 = 1 and ( q - 1 ) mod 2 = 0 ) then
return Size( g ) / 2;
else
return Size( g );
fi;
end );


#############################################################################
##
#F ProjectiveSpecialOrthogonalGroup( [<filt>, ][<e>, ]<d>, <q> )
#F PSO( [<filt>, ][<e>, ]<d>, <q> )
##
## <#GAPDoc Label="ProjectiveSpecialOrthogonalGroup">
## <ManSection>
## <Func Name="ProjectiveSpecialOrthogonalGroup" Arg='[filt, ][e, ]d, q'/>
## <Func Name="PSO" Arg='[filt, ][e, ]d, q'/>
##
## <Description>
## constructs a group isomorphic to the projective group
## PSO( <A>e</A>, <A>d</A>, <A>q</A> )
## of SO( <A>e</A>, <A>d</A>, <A>q</A> ),
## modulo the centre
## (see <Ref Oper="SpecialOrthogonalGroup"/>),
## in the category given by the filter <A>filt</A>.
## <P/>
## If <A>filt</A> is not given it defaults to <Ref Filt="IsPermGroup"/>,
## and the returned group is the action on lines of the underlying vector
## space.
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DECLARE_PROJECTIVE_ORTHOGONAL_GROUPS_OPERATION( "SpecialOrthogonalGroup", "SO",
function( e, n, q, g )
if n mod 2 = 0 and ( q^(n/2) - e ) mod 2 = 0 then
return Size( g ) / 2;
else
return Size( g );
fi;
end );


#############################################################################
##
#F ProjectiveOmega( [<filt>, ][<e>, ]<d>, <q> )
#F POmega( [<filt>, ][<e>, ]<d>, <q> )
##
Expand All @@ -1017,39 +1135,14 @@ DeclareSynonym( "PSp", PSP );
## </ManSection>
## <#/GAPDoc>
##
DeclareConstructor( "ProjectiveOmegaCons", [ IsGroup, IsInt, IsInt, IsInt ] );

BindGlobal( "ProjectiveOmega", function( arg )
if Length( arg ) = 2 then
return ProjectiveOmegaCons( IsPermGroup, 0, arg[1], arg[2] );
elif Length( arg ) = 3 and IsInt( arg[1] ) then
return ProjectiveOmegaCons( IsPermGroup, arg[1], arg[2], arg[3] );
elif Length( arg ) = 3 and IsOperation( arg[1] ) then
return ProjectiveOmegaCons( arg[1], 0, arg[2], arg[3] );
elif IsOperation( arg[1] ) and Length( arg ) = 4 then
return ProjectiveOmegaCons( arg[1], arg[2], arg[3], arg[4] );
fi;
Error( "usage: ProjectiveOmega( [<filter>, ][<e>, ]<d>, <q> )" );
end );

DeclareSynonym( "POmega", ProjectiveOmega );

InstallMethod( ProjectiveOmegaCons,
"action on lines",
[ IsPermGroup, IsInt, IsPosInt, IsPosInt ],
function( filter, e, n, q )
local g, p;

g:= Omega( IsMatrixGroup, e, n, q );
p:= ProjectiveActionOnFullSpace( g, GF( q ), n );
DECLARE_PROJECTIVE_ORTHOGONAL_GROUPS_OPERATION( "Omega", "Omega",
function( e, n, q, g )
if n mod 2 = 0 and ( q^(n/2) - e ) mod 4 = 0 then
SetSize( p, Size( g ) / 2 );
return Size( g ) / 2;
else
SetSize( p, Size( g ) );
return Size( g );
fi;

return p;
end);
end );


#############################################################################
Expand Down
50 changes: 49 additions & 1 deletion tst/testinstall/grp/classic-PG.tst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#
# Tests for the "projective general" group constructors: PGL, POmega, PGU, PGammaL
# Tests for the "projective general" group constructors:
# PGL, PGO, POmega, PGU, PGammaL
#
gap> START_TEST("classic-PG.tst");

Expand All @@ -17,6 +18,24 @@ Error, usage: ProjectiveGeneralLinearGroup( [<filter>, ]<d>, <q> )
gap> PGL(3,6);
Error, usage: GeneralLinearGroup( [<filter>, ]<d>, <R> )

#
gap> G:= PGO( 3, 5 );; Size( G );
120
gap> G = PGO( 0, 3, 5 );
true
gap> G = PGO( IsPermGroup, 3, 5 );
true
gap> G = PGO( IsPermGroup, 0, 3, 5 );
true
gap> G:= PGO( 1, 4, 5 );; Size( G );
14400
gap> G = PGO( IsPermGroup, 1, 4, 5 );
true
gap> G:= PGO( -1, 4, 5 );; Size( G );
15600
gap> G = PGO( IsPermGroup, -1, 4, 5 );
true

#
gap> G := POmega(3,7);
<permutation group of size 168 with 2 generators>
Expand Down Expand Up @@ -58,6 +77,35 @@ Error, sign <e> = 0 but dimension <d> is even
gap> POmega(0,4,9);
Error, sign <e> = 0 but dimension <d> is even

#
gap> for d in [ 1, 3, 5, 7 ] do
> for q in [ 2, 3, 4, 5 ] do
> for cons in [ PGO, PSO, POmega ] do
> G:= cons( d, q );
> if Size( G ) <> Size( GroupByGenerators( GeneratorsOfGroup( G ),
> One( G ) ) ) then
> Error( "problem with group order for ", [ d, q ], "\n" );
> fi;
> od;
> od;
> od;
gap> for d in [ 2, 4, 6 ] do
> for q in [ 2, 3, 4, 5 ] do
> for cons in [ PGO, PSO, POmega ] do
> G:= cons( 1, d, q );
> if Size( G ) <> Size( GroupByGenerators( GeneratorsOfGroup( G ),
> One( G ) ) ) then
> Error( [ d, q ] );
> fi;
> G:= cons( -1, d, q );
> if Size( G ) <> Size( GroupByGenerators( GeneratorsOfGroup( G ),
> One( G ) ) ) then
> Error( [ d, q ] );
> fi;
> od;
> od;
> od;

#
gap> PGU(3,5);
<permutation group of size 378000 with 2 generators>
Expand Down
21 changes: 20 additions & 1 deletion tst/testinstall/grp/classic-PS.tst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#
# Tests for the "projective special" group constructors: PSL, PSU, PSp, PSigmaL
# Tests for the "projective special" group constructors:
# PSL, PSO, PSU, PSp, PSigmaL
#
gap> START_TEST("classic-PS.tst");

Expand All @@ -17,6 +18,24 @@ Error, usage: ProjectiveSpecialLinearGroup( [<filter>, ]<d>, <q> )
gap> PSL(3,6);
Error, usage: SpecialLinearGroup( [<filter>, ]<d>, <R> )

#
gap> G:= PSO( 3, 5 );; Size( G );
120
gap> G = PSO( 0, 3, 5 );
true
gap> G = PSO( IsPermGroup, 3, 5 );
true
gap> G = PSO( IsPermGroup, 0, 3, 5 );
true
gap> G:= PSO( 1, 4, 5 );; Size( G );
7200
gap> G = PSO( IsPermGroup, 1, 4, 5 );
true
gap> G:= PSO( -1, 4, 5 );; Size( G );
7800
gap> G = PSO( IsPermGroup, -1, 4, 5 );
true

#
gap> PSU(3,5);
<permutation group of size 126000 with 2 generators>
Expand Down