Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  classic.gd   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Frank Celler.
##
##  Copyright of GAP belongs to its developers, whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-2.0-or-later
##
##  This file contains the operations for the construction of the classical
##  group types.
##


#############################################################################
##
##  <#GAPDoc Label="[1]{classic}">
##  The following functions return classical groups.
##  <P/>
##  For the linear, symplectic, and unitary groups (the latter in dimension
##  at least <M>3</M>),
##  the generators are taken from <Cite Key="Tay87"/>.
##  For the unitary groups in dimension <M>2</M>, the isomorphism of
##  SU<M>(2,q)</M> and SL<M>(2,q)</M> is used,
##  see for example <Cite Key="Hup67"/>.
##  <P/>
##  The generators of the general and special orthogonal groups are taken
##  from <Cite Key="IshibashiEarnest94"/> and
##  <Cite Key="KleidmanLiebeck90"/>,
##  except that the generators of the groups in odd dimension in even
##  characteristic are constructed via the isomorphism to a symplectic group,
##  see for example <Cite Key="Car72a"/>.
##  <P/>
##  The generators of the groups <M>\Omega^\epsilon(d, q)</M> are taken
##  from <Cite Key="RylandsTalor98"/>,
##  except that in odd dimension and even characteristic,
##  the generators of SO<M>(d, q)</M> are taken for <M>\Omega(d, q)</M>.
##  Note that the generators claimed
##  in <Cite Key="RylandsTalor98" Where="Section 4.5 and 4.6"/>
##  do not describe orthogonal groups, one would have to transpose these
##  matrices in order to get groups that respect the required forms.
##  The matrices from <Cite Key="RylandsTalor98"/> generate groups
##  of the right isomorphism types but not orthogonal groups,
##  except in the case <M>(d,q) = (5,2)</M>,
##  where the matrices from <Cite Key="RylandsTalor98"/> generate
##  the simple group <M>S_4(2)'</M> and not the group <M>S_4(2)</M>.
##  <P/>
##  The generators for the semilinear groups are constructed from the
##  generators of the corresponding linear groups plus one additional
##  generator that describes the action of the group of field automorphisms;
##  for prime integers <M>p</M> and positive integers <M>f</M>,
##  this yields the matrix groups <M>Gamma</M>L<M>(d, p^f)</M> and
##  <M>Sigma</M>L<M>(d, p^f)</M> as groups of <M>d f \times df</M> matrices
##  over the field with <M>p</M> elements.
##  <P/>
##  For symplectic and orthogonal matrix groups returned by the functions
##  described below, the invariant bilinear form is stored as the value of
##  the attribute <Ref Attr="InvariantBilinearForm"/>.
##  Analogously, the invariant sesquilinear form defining the unitary groups
##  is stored as the value of the attribute
##  <Ref Attr="InvariantSesquilinearForm"/>).
##  The defining quadratic form of orthogonal groups is stored as the value
##  of the attribute <Ref Attr="InvariantQuadraticForm"/>.
##  <P/>
##  Note that due to the different sources for the generators,
##  the invariant forms for the groups <M>\Omega(e,d,q)</M> are in general
##  different from the forms for SO<M>(e,d,q)</M> and GO<M>(e,d,q)</M>.
##  If version at least 1.2.6 of the <Package>Forms</Package> package is
##  loaded then compatible groups can be created by specifying the desired
##  form, see the sections below.
##  <#/GAPDoc>
##


#############################################################################
##
#O  GeneralLinearGroupCons( <filter>, <d>, <R> )
##
##  <ManSection>
##  <Oper Name="GeneralLinearGroupCons" Arg='filter, d, R'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "GeneralLinearGroupCons", [ IsGroup, IsPosInt, IsRing ] );


#############################################################################
##
#F  GeneralLinearGroup( [<filt>, ]<d>, <R> )  . . . . .  general linear group
#F  GL( [<filt>, ]<d>, <R> )
#F  GeneralLinearGroup( [<filt>, ]<d>, <q> )
#F  GL( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="GeneralLinearGroup">
##  <ManSection>
##  <Heading>GeneralLinearGroup</Heading>
##  <Func Name="GeneralLinearGroup" Arg='[filt, ]d, R'
##   Label="for dimension and a ring"/>
##  <Func Name="GL" Arg='[filt, ]d, R'
##   Label="for dimension and a ring"/>
##  <Func Name="GeneralLinearGroup" Arg='[filt, ]d, q'
##   Label="for dimension and field size"/>
##  <Func Name="GL" Arg='[filt, ]d, q'
##   Label="for dimension and field size"/>
##
##  <Description>
##  The first two forms construct a group isomorphic to the general linear
##  group GL( <A>d</A>, <A>R</A> ) of all <M><A>d</A> \times <A>d</A></M>
##  matrices that are invertible over the ring <A>R</A>,
##  in the category given by the filter <A>filt</A>.
##  <P/>
##  The third and the fourth form construct the general linear group over the
##  finite field with <A>q</A> elements.
##  <P/>
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group is the general linear group as a matrix group in
##  its natural action (see also <Ref Prop="IsNaturalGL"/>,
##  <Ref Prop="IsNaturalGLnZ"/>).
##  <P/>
##  Currently supported rings <A>R</A> are finite fields,
##  the ring <Ref Var="Integers" Label="global variable"/>,
##  and residue class rings <C>Integers mod <A>m</A></C>,
##  see <Ref Sect="Residue Class Rings"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> GL(4,3);
##  GL(4,3)
##  gap> GL(2,Integers);
##  GL(2,Integers)
##  gap> GL(3,Integers mod 12);
##  GL(3,Z/12Z)
##  ]]></Example>
##  <P/>
##  <Index Key="OnLines" Subkey="example"><C>OnLines</C></Index>
##  Using the <Ref Func="OnLines"/> operation it is possible to obtain the
##  corresponding projective groups in a permutation action:
##  <P/>
##  <Example><![CDATA[
##  gap> g:=GL(4,3);;Size(g);
##  24261120
##  gap> pgl:=Action(g,Orbit(g,Z(3)^0*[1,0,0,0],OnLines),OnLines);;
##  gap> Size(pgl);
##  12130560
##  ]]></Example>
##  <P/>
##  If you are interested only in the projective group as a permutation group
##  and not in the correspondence between its moved points and the points in
##  the projective space, you can also use <Ref Func="PGL"/>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "GeneralLinearGroup", function ( arg )
  if Length( arg ) = 2 then
    if IsRing( arg[2] ) then
      return GeneralLinearGroupCons( IsMatrixGroup, arg[1], arg[2] );
    elif IsPrimePowerInt( arg[2] ) then
      return GeneralLinearGroupCons( IsMatrixGroup, arg[1], GF( arg[2] ) );
    fi;
  elif Length( arg ) = 3 and IsOperation( arg[1] ) then
    if IsRing( arg[3] ) then
      return GeneralLinearGroupCons( arg[1], arg[2], arg[3] );
    elif IsPrimePowerInt( arg[3] ) then
      return GeneralLinearGroupCons( arg[1], arg[2], GF( arg[3] ) );
    fi;
  fi;
  Error( "usage: GeneralLinearGroup( [<filter>, ]<d>, <R> )" );
end );

DeclareSynonym( "GL", GeneralLinearGroup );


#############################################################################
##
#O  GeneralOrthogonalGroupCons( <filter>, <e>, <d>, <q> )
##
##  <ManSection>
##  <Oper Name="GeneralOrthogonalGroupCons" Arg='filter, e, d, q'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "GeneralOrthogonalGroupCons",
    [ IsGroup, IsInt, IsPosInt, IsPosInt ] );
DeclareConstructor( "GeneralOrthogonalGroupCons",
    [ IsGroup, IsInt, IsPosInt, IsRing ] );


#############################################################################
##
#F  GeneralOrthogonalGroup( [<filt>, ][<e>, ]<d>, <q>[, <form>] )
#F  GeneralOrthogonalGroup( [<filt>, ]<form> )
#F  GO( [<filt>, ][<e>, ]<d>, <q>[, <form>] )
#F  GO( [<filt>, ]<form> )
##
##  <#GAPDoc Label="GeneralOrthogonalGroup">
##  <ManSection>
##  <Func Name="GeneralOrthogonalGroup" Arg='[filt, ][e, ]d, q[, form]'/>
##  <Func Name="GeneralOrthogonalGroup" Arg='[filt, ]form' Label="for a form"/>
##  <Func Name="GO" Arg='[filt, ][e, ]d, q[, form]'/>
##  <Func Name="GO" Arg='[filt, ]form' Label="for a form"/>
##
##  <Description>
##  constructs a group isomorphic to the
##  general orthogonal group GO( <A>e</A>, <A>d</A>, <A>q</A> ) of those
##  <M><A>d</A> \times <A>d</A></M> matrices over the field with <A>q</A>
##  elements that respect a non-singular quadratic form
##  (see <Ref Attr="InvariantQuadraticForm"/>) specified by <A>e</A>,
##  in the category given by the filter <A>filt</A>.
##  <P/>
##  The value of <A>e</A> must be <M>0</M> for odd <A>d</A> (and can
##  optionally be  omitted in this case), respectively one of <M>1</M> or
##  <M>-1</M> for even <A>d</A>.
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group is the general orthogonal group itself.
##  <P/>
##  If version at least 1.2.6 of the <Package>Forms</Package> package is
##  loaded then the desired quadratic form can be specified via <A>form</A>,
##  which can be either a matrix
##  or a form object in <Ref Filt="IsQuadraticForm" BookName="Forms"/>
##  or a group with stored <Ref Attr="InvariantQuadraticForm"/> value
##  (and then this form is taken).
##  <P/>
##  A given <A>form</A> determines <A>e</A> and <A>d</A>, and also <A>q</A>
##  except if <A>form</A> is a matrix that does not store its
##  <Ref Attr="BaseDomain" Label="for a matrix object"/> value.
##  These parameters can be entered, and an error is signalled if they do
##  not fit to the given <A>form</A>.
##  <P/>
##  If <A>form</A> is not given then a default is chosen as described in the
##  introduction to Section <Ref Sect="Classical Groups"/>.
##  <P/>
##  Note that in <Cite Key="KleidmanLiebeck90"/>,
##  GO is defined as the stabilizer
##  <M>\Delta(V, F, \kappa)</M> of the quadratic form, up to scalars,
##  whereas our GO is called <M>I(V, F, \kappa)</M> there.
##  <P/>
##  <Example><![CDATA[
##  gap> GeneralOrthogonalGroup( 5, 3 );
##  GO(0,5,3)
##  gap> GeneralOrthogonalGroup( -1, 8, 2 );
##  GO(-1,8,2)
##  gap> GeneralOrthogonalGroup( IsPermGroup, -1, 8, 2 );
##  Perm_GO(-1,8,2)
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "DescribesInvariantQuadraticForm",
    obj -> IsMatrixOrMatrixObj( obj ) or
           ( IsBoundGlobal( "IsQuadraticForm" ) and
             ValueGlobal( "IsQuadraticForm" )( obj ) ) or
           ( IsGroup( obj ) and HasInvariantQuadraticForm( obj ) ) );

BindGlobal( "GeneralOrthogonalGroup", function ( arg )
  local filt, form;

  if IsFilter( First( arg ) ) then
    filt:= Remove( arg, 1 );
  else
    filt:= IsMatrixGroup;
  fi;
  if DescribesInvariantQuadraticForm( Last( arg ) ) then
    form:= Remove( arg );
    if Length( arg ) = 0 then
      # ( [<filt>, ]<form> )
      return GeneralOrthogonalGroupCons( filt, form );
    elif Length( arg ) = 2 and IsPosInt( arg[1] )
                           and ( IsPosInt( arg[2] ) or IsRing( arg[2] ) ) then
      # ( [<filt>, ]<d>, <q>, form ) or ( [<filt>, ]<d>, <R>, form )
      return GeneralOrthogonalGroupCons( filt, 0, arg[1], arg[2], form );
    elif Length( arg ) = 3 and IsInt( arg[1] ) and IsPosInt( arg[2] )
                           and ( IsPosInt( arg[3] ) or IsRing( arg[3] ) ) then
      # ( [<filt>, ]<e>, <d>, <q>, form ) or ( [<filt>, ]<e>, <d>, <R>, form )
      return GeneralOrthogonalGroupCons( filt, arg[1], arg[2], arg[3], form );
    fi;
  elif Length( arg ) = 2 and IsPosInt( arg[1] )
                         and ( IsPosInt( arg[2] ) or IsRing( arg[2] ) ) then
    # ( [<filt>, ]<d>, <q> ) or ( [<filt>, ]<d>, <R> )
    return GeneralOrthogonalGroupCons( filt, 0, arg[1], arg[2] );
  elif Length( arg ) = 3 and IsInt( arg[1] ) and IsPosInt( arg[2] )
                         and ( IsPosInt( arg[3] ) or IsRing( arg[3] ) ) then
    # ( [<filt>, ]<e>, <d>, <q> ) or ( [<filt>, ]<e>, <d>, <R> )
    return GeneralOrthogonalGroupCons( filt, arg[1], arg[2], arg[3] );
  fi;
  Error( "usage: GeneralOrthogonalGroup( [<filt>, ][<e>, ]<d>, <q>[, <form>] )\n",
         "or GeneralOrthogonalGroup( [<filt>, ][<e>, ]<d>, <q>[, <form>] )\n",
         "or GeneralOrthogonalGroup( [<filt>, ]<form> )" );
end );

DeclareSynonym( "GO", GeneralOrthogonalGroup );


#############################################################################
##
#O  GeneralUnitaryGroupCons( <filter>, <d>, <q> )
##
##  <ManSection>
##  <Oper Name="GeneralUnitaryGroupCons" Arg='filter, d, q'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "GeneralUnitaryGroupCons",
    [ IsGroup, IsPosInt, IsPosInt ] );


#############################################################################
##
#F  GeneralUnitaryGroup( [<filt>, ]<d>, <q>[, <form>] )
#F  GeneralUnitaryGroup( [<filt>, ]<form> )
#F  GU( [<filt>, ]<d>, <q>[, <form>] )
#F  GU( [<filt>, ]<form> )
##
##  <#GAPDoc Label="GeneralUnitaryGroup">
##  <ManSection>
##  <Func Name="GeneralUnitaryGroup" Arg='[filt, ]d, q[, form]'/>
##  <Func Name="GeneralUnitaryGroup" Arg='[filt, ]form' Label="for a form"/>
##  <Func Name="GU" Arg='[filt, ]d, q[, form]'/>
##  <Func Name="GU" Arg='[filt, ]form' Label="for a form"/>
##
##  <Description>
##  constructs a group isomorphic to the general unitary group
##  GU( <A>d</A>, <A>q</A> ) of those <M><A>d</A> \times <A>d</A></M>
##  matrices over the field with <M><A>q</A>^2</M> elements
##  that respect a fixed nondegenerate sesquilinear form,
##  in the category given by the filter <A>filt</A>.
##  <P/>
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group is the general unitary group itself.
##  <P/>
##  If version at least 1.2.6 of the <Package>Forms</Package> package is
##  loaded then the desired sesquilinear form can be specified via
##  <A>form</A>, which can be either a matrix
##  or a form object in <Ref Filt="IsHermitianForm" BookName="Forms"/>
##  or a group with stored <Ref Attr="InvariantSesquilinearForm"/> value
##  (and then this form is taken).
##  <P/>
##  A given <A>form</A> determines <A>d</A>, and also <A>q</A>
##  except if <A>form</A> is a matrix that does not store its
##  <Ref Attr="BaseDomain" Label="for a matrix object"/> value.
##  These parameters can be entered, and an error is signalled if they do
##  not fit to the given <A>form</A>.
##  <P/>
##  If <A>form</A> is not given then a default is chosen as described in the
##  introduction to Section <Ref Sect="Classical Groups"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> GeneralUnitaryGroup( 3, 5 );
##  GU(3,5)
##  gap> GeneralUnitaryGroup( IsPermGroup, 3, 5 );
##  Perm_GU(3,5)
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "DescribesInvariantHermitianForm",
    obj -> IsMatrixOrMatrixObj( obj ) or
           ( IsBoundGlobal( "IsHermitianForm" ) and
             ValueGlobal( "IsHermitianForm" )( obj ) ) or
           ( IsGroup( obj ) and HasInvariantSesquilinearForm( obj ) ) );

BindGlobal( "GeneralUnitaryGroup", function ( arg )
  local filt, form;

  if IsFilter( First( arg ) ) then
    filt:= Remove( arg, 1 );
  else
    filt:= IsMatrixGroup;
  fi;
  if DescribesInvariantHermitianForm( Last( arg ) ) then
    form:= Remove( arg );
    if Length( arg ) = 0 then
      # ( [<filt>, ]<form> )
      return GeneralUnitaryGroupCons( filt, form );
    elif Length( arg ) = 2 and IsPosInt( arg[1] ) and IsPosInt( arg[2] ) then
      # ( [<filt>, ]<d>, <q>, <form> )
      return GeneralUnitaryGroupCons( filt, arg[1], arg[2], form );
    fi;
  elif Length( arg ) = 2 and IsPosInt( arg[1] ) and IsPosInt( arg[2] ) then
    # ( [<filt>, ]<d>, <q> )
    return GeneralUnitaryGroupCons( filt, arg[1], arg[2] );
  fi;
  Error( "usage: GeneralUnitaryGroup( [<filt>, ]<d>, <q>[, <form>] )\n",
         "or GeneralUnitaryGroup( [<filt>, ]<form> )" );
end );

DeclareSynonym( "GU", GeneralUnitaryGroup );


#############################################################################
##
#O  SpecialLinearGroupCons( <filter>, <d>, <R> )
##
##  <ManSection>
##  <Oper Name="SpecialLinearGroupCons" Arg='filter, d, R'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "SpecialLinearGroupCons", [ IsGroup, IsInt, IsRing ] );


#############################################################################
##
#F  SpecialLinearGroup( [<filt>, ]<d>, <R> )  . . . . .  special linear group
#F  SL( [<filt>, ]<d>, <R> )
#F  SpecialLinearGroup( [<filt>, ]<d>, <q> )
#F  SL( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="SpecialLinearGroup">
##  <ManSection>
##  <Heading>SpecialLinearGroup</Heading>
##  <Func Name="SpecialLinearGroup" Arg='[filt, ]d, R'
##   Label="for dimension and a ring"/>
##  <Func Name="SL" Arg='[filt, ]d, R'
##   Label="for dimension and a ring"/>
##  <Func Name="SpecialLinearGroup" Arg='[filt, ]d, q'
##   Label="for dimension and a field size"/>
##  <Func Name="SL" Arg='[filt, ]d, q'
##   Label="for dimension and a field size"/>
##
##  <Description>
##  The first two forms construct a group isomorphic to the special linear
##  group SL( <A>d</A>, <A>R</A> ) of all those
##  <M><A>d</A> \times <A>d</A></M> matrices over the ring <A>R</A> whose
##  determinant is the identity of <A>R</A>,
##  in the category given by the filter <A>filt</A>.
##  <P/>
##  The third and the fourth form construct the special linear group over the
##  finite field with <A>q</A> elements.
##  <P/>
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group is the special linear group as a matrix group in
##  its natural action (see also <Ref Prop="IsNaturalSL"/>,
##  <Ref Prop="IsNaturalSLnZ"/>).
##  <P/>
##  Currently supported rings <A>R</A> are finite fields,
##  the ring <Ref Var="Integers"/>,
##  and residue class rings <C>Integers mod <A>m</A></C>,
##  see <Ref Sect="Residue Class Rings"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> SpecialLinearGroup(2,2);
##  SL(2,2)
##  gap> SL(3,Integers);
##  SL(3,Integers)
##  gap> SL(4,Integers mod 4);
##  SL(4,Z/4Z)
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "SpecialLinearGroup", function ( arg )
  if Length( arg ) = 2  then
    if IsRing( arg[2] ) then
      return SpecialLinearGroupCons( IsMatrixGroup, arg[1], arg[2] );
    elif IsPrimePowerInt( arg[2] ) then
      return SpecialLinearGroupCons( IsMatrixGroup, arg[1], GF( arg[2] ) );
    fi;
  elif Length( arg ) = 3 and IsOperation( arg[1] ) then
    if IsRing( arg[3] ) then
      return SpecialLinearGroupCons( arg[1], arg[2], arg[3] );
    elif IsPrimePowerInt( arg[3] ) then
      return SpecialLinearGroupCons( arg[1], arg[2], GF( arg[3] ) );
    fi;
  fi;
  Error( "usage: SpecialLinearGroup( [<filter>, ]<d>, <R> )" );

end );

DeclareSynonym( "SL", SpecialLinearGroup );


#############################################################################
##
#O  SpecialOrthogonalGroupCons( <filter>, <e>, <d>, <q> )
##
##  <ManSection>
##  <Oper Name="SpecialOrthogonalGroupCons" Arg='filter, e, d, q'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "SpecialOrthogonalGroupCons",
    [ IsGroup, IsInt, IsPosInt, IsPosInt ] );
DeclareConstructor( "SpecialOrthogonalGroupCons",
    [ IsGroup, IsInt, IsPosInt, IsRing ] );


#############################################################################
##
#F  SpecialOrthogonalGroup( [<filt>, ][<e>, ]<d>, <q>[, <form>] )
#F  SpecialOrthogonalGroup( [<filt>, ]<form> )
#F  SO( [<filt>, ][<e>, ]<d>, <q>[, <form>] )
#F  SO( [<filt>, ]<form> )
##
##  <#GAPDoc Label="SpecialOrthogonalGroup">
##  <ManSection>
##  <Func Name="SpecialOrthogonalGroup" Arg='[filt, ][e, ]d, q[, form]'/>
##  <Func Name="SpecialOrthogonalGroup" Arg='[filt, ]form' Label="for a form"/>
##  <Func Name="SO" Arg='[filt, ][e, ]d, q[, form]'/>
##  <Func Name="SO" Arg='[filt, ]form' Label="for a form"/>
##
##  <Description>
##  constructs a group isomorphic to the
##  special orthogonal group SO( <A>e</A>, <A>d</A>, <A>q</A> ),
##  which is the subgroup of all those matrices in the general orthogonal
##  group (see <Ref Func="GeneralOrthogonalGroup"/>) that have
##  determinant one, in the category given by the filter <A>filt</A>.
##  (The index of SO( <A>e</A>, <A>d</A>, <A>q</A> ) in
##  GO( <A>e</A>, <A>d</A>, <A>q</A> ) is <M>2</M> if <A>q</A> is
##  odd, and <M>1</M> if <A>q</A> is even.)
##  Also interesting is the group Omega( <A>e</A>, <A>d</A>, <A>q</A> ),
##  see <Ref Oper="Omega" Label="construct an orthogonal group"/>,
##  which is of index <M>2</M> in SO( <A>e</A>, <A>d</A>, <A>q</A> ),
##  except in the case <M><A>d</A> = 1</M>.
##  <P/>
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group is the special orthogonal group itself.
##  <P/>
##  If version at least 1.2.6 of the <Package>Forms</Package> package is
##  loaded then the desired quadratic form can be specified via <A>form</A>,
##  which can be either a matrix
##  or a form object in <Ref Filt="IsQuadraticForm" BookName="Forms"/>
##  or a group with stored <Ref Attr="InvariantQuadraticForm"/> value
##  (and then this form is taken).
##  <P/>
##  A given <A>form</A> determines <A>e</A> and <A>d</A>, and also <A>q</A>
##  except if <A>form</A> is a matrix that does not store its
##  <Ref Attr="BaseDomain" Label="for a matrix object"/> value.
##  These parameters can be entered, and an error is signalled if they do
##  not fit to the given <A>form</A>.
##  <P/>
##  If <A>form</A> is not given then a default is chosen as described in the
##  introduction to Section <Ref Sect="Classical Groups"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> SpecialOrthogonalGroup( 5, 3 );
##  SO(0,5,3)
##  gap> SpecialOrthogonalGroup( -1, 8, 2 );  # here SO and GO coincide
##  GO(-1,8,2)
##  gap> SpecialOrthogonalGroup( IsPermGroup, 5, 3 );
##  Perm_SO(0,5,3)
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "SpecialOrthogonalGroup", function ( arg )
  local filt, form;

  if IsFilter( First( arg ) ) then
    filt:= Remove( arg, 1 );
  else
    filt:= IsMatrixGroup;
  fi;
  if DescribesInvariantQuadraticForm( Last( arg ) ) then
    form:= Remove( arg );
    if Length( arg ) = 0 then
      # ( [<filt>, ]<form> )
      return SpecialOrthogonalGroupCons( filt, form );
    elif Length( arg ) = 2 and IsPosInt( arg[1] )
                           and ( IsPosInt( arg[2] ) or IsRing( arg[2] ) ) then
      # ( [<filt>, ]<d>, <q>, form ) or ( [<filt>, ]<d>, <R>, form )
      return SpecialOrthogonalGroupCons( filt, 0, arg[1], arg[2], form );
    elif Length( arg ) = 3 and IsInt( arg[1] ) and IsPosInt( arg[2] )
                           and ( IsPosInt( arg[3] ) or IsRing( arg[3] ) ) then
      # ( [<filt>, ]<e>, <d>, <q>, form ) or ( [<filt>, ]<e>, <d>, <R>, form )
      return SpecialOrthogonalGroupCons( filt, arg[1], arg[2], arg[3], form );
    fi;
  elif Length( arg ) = 2 and IsPosInt( arg[1] )
                         and ( IsPosInt( arg[2] ) or IsRing( arg[2] ) ) then
    # ( [<filt>, ]<d>, <q> ) or ( [<filt>, ]<d>, <R> )
    return SpecialOrthogonalGroupCons( filt, 0, arg[1], arg[2] );
  elif Length( arg ) = 3 and IsInt( arg[1] ) and IsPosInt( arg[2] )
                         and ( IsPosInt( arg[3] ) or IsRing( arg[3] ) ) then
    # ( [<filt>, ]<e>, <d>, <q> ) or ( [<filt>, ]<e>, <d>, <R> )
    return SpecialOrthogonalGroupCons( filt, arg[1], arg[2], arg[3] );
  fi;
  Error( "usage: SpecialOrthogonalGroup( [<filt>, ][<e>, ]<d>, <q>[, <form>] )\n",
         "or SpecialOrthogonalGroup( [<filt>, ]<form> )" );
end );

DeclareSynonym( "SO", SpecialOrthogonalGroup );


#############################################################################
##
#O  SpecialUnitaryGroupCons( <filter>, <d>, <q> )
##
##  <ManSection>
##  <Oper Name="SpecialUnitaryGroupCons" Arg='filter, d, q'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "SpecialUnitaryGroupCons",
    [ IsGroup, IsPosInt, IsPosInt ] );


#############################################################################
##
#F  SpecialUnitaryGroup( [<filt>, ]<d>, <q>[, <form>] )
#F  SpecialUnitaryGroup( [<filt>, ]<form> )
#F  SU( [<filt>, ]<d>, <q>[, <form>] )
#F  SU( [<filt>, ]<form> )
##
##  <#GAPDoc Label="SpecialUnitaryGroup">
##  <ManSection>
##  <Func Name="SpecialUnitaryGroup" Arg='[filt, ]d, q[, form]'/>
##  <Func Name="SpecialUnitaryGroup" Arg='[filt, ]form' Label="for a form"/>
##  <Func Name="SU" Arg='[filt, ]d, q[, form]'/>
##  <Func Name="SU" Arg='[filt, ]form' Label="for a form"/>
##
##  <Description>
##  constructs a group isomorphic to the special unitary group
##  SU( <A>d</A>, <A>q</A> ) of those <M><A>d</A> \times <A>d</A></M>
##  matrices over the field with <M><A>q</A>^2</M> elements
##  whose determinant is the identity of the field and that respect a fixed
##  nondegenerate sesquilinear form,
##  in the category given by the filter <A>filt</A>.
##  <P/>
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group is the special unitary group itself.
##  <P/>
##  If version at least 1.2.6 of the <Package>Forms</Package> package is
##  loaded then the desired sesquilinear form can be specified via
##  <A>form</A>, which can be either a matrix
##  or a form object in <Ref Filt="IsHermitianForm" BookName="Forms"/>
##  or a group with stored <Ref Attr="InvariantSesquilinearForm"/> value
##  (and then this form is taken).
##  <P/>
##  A given <A>form</A> determines <A>d</A>, and also <A>q</A>
##  except if <A>form</A> is a matrix that does not store its
##  <Ref Attr="BaseDomain" Label="for a matrix object"/> value.
##  These parameters can be entered, and an error is signalled if they do
##  not fit to the given <A>form</A>.
##  <P/>
##  If <A>form</A> is not given then a default is chosen as described in the
##  introduction to Section <Ref Sect="Classical Groups"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> SpecialUnitaryGroup( 3, 5 );
##  SU(3,5)
##  gap> SpecialUnitaryGroup( IsPermGroup, 3, 5 );
##  Perm_SU(3,5)
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "SpecialUnitaryGroup", function ( arg )
  local filt, form;

  if IsFilter( First( arg ) ) then
    filt:= Remove( arg, 1 );
  else
    filt:= IsMatrixGroup;
  fi;
  if DescribesInvariantHermitianForm( Last( arg ) ) then
    form:= Remove( arg );
    if Length( arg ) = 0 then
      # ( [<filt>, ]<form> )
      return SpecialUnitaryGroupCons( filt, form );
    elif Length( arg ) = 2 and IsPosInt( arg[1] ) and IsPosInt( arg[2] ) then
      # ( [<filt>, ]<d>, <q>, form)
      return SpecialUnitaryGroupCons( filt, arg[1], arg[2], form );
    fi;

  elif Length( arg ) = 2 and IsPosInt( arg[1] ) and IsPosInt( arg[2] ) then
    # ( [<filt>, ]<d>, <q> )
    return SpecialUnitaryGroupCons( filt, arg[1], arg[2] );
  fi;
  Error( "usage: SpecialUnitaryGroup( [<filt>, ]<d>, <q>[, <form>] )\n",
         "or SpecialUnitaryGroup( [<filt>, ]<form> )" );
end );

DeclareSynonym( "SU", SpecialUnitaryGroup );


#############################################################################
##
#O  SymplecticGroupCons( <filter>, <d>, <q> )
##
##  <ManSection>
##  <Oper Name="SymplecticGroupCons" Arg='filter, d, q'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "SymplecticGroupCons", [ IsGroup, IsPosInt, IsPosInt ] );
DeclareConstructor( "SymplecticGroupCons", [ IsGroup, IsPosInt, IsRing ] );


#############################################################################
##
#F  SymplecticGroup( [<filt>, ]<d>, <q>[, <form>] ) . . . .  symplectic group
#F  SymplecticGroup( [<filt>, ]<form> ) . . . . . . . . . .  symplectic group
#F  Sp( [<filt>, ]<d>, <q>[, <form>] )
#F  Sp( [<filt>, ]<form> )
#F  SP( [<filt>, ]<d>, <q>[, <form>] )
#F  SP( [<filt>, ]<form> )
##
##  <#GAPDoc Label="SymplecticGroup">
##  <ManSection>
##  <Heading>SymplecticGroup</Heading>
##  <Func Name="SymplecticGroup" Arg='[filt, ]d, q[, form]'
##   Label="for dimension and field size"/>
##  <Func Name="SymplecticGroup" Arg='[filt, ]d, ring[, form]'
##   Label="for dimension and a ring"/>
##  <Func Name="SymplecticGroup" Arg='[filt, ]form'
##   Label="for form"/>
##  <Func Name="Sp" Arg='[filt, ]d, q[, form]'
##   Label="for dimension and field size"/>
##  <Func Name="Sp" Arg='[filt, ]d, ring[, form]'
##   Label="for dimension and a ring"/>
##  <Func Name="Sp" Arg='[filt, ]form'
##   Label="for form"/>
##  <Func Name="SP" Arg='[filt, ]d, q[, form]'
##   Label="for dimension and field size"/>
##  <Func Name="SP" Arg='[filt, ]d, ring[, form]'
##   Label="for dimension and a ring"/>
##  <Func Name="SP" Arg='[filt, ]form'
##   Label="for form"/>
##
##  <Description>
##  constructs a group isomorphic to the symplectic group
##  Sp( <A>d</A>, <A>q</A> ) of those <M><A>d</A> \times <A>d</A></M>
##  matrices over the field with <A>q</A> elements (respectively the ring
##  <A>ring</A>)
##  that respect a fixed nondegenerate symplectic form,
##  in the category given by the filter <A>filt</A>.
##  <P/>
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group is the symplectic group itself.
##  <P/>
##  At the moment finite fields or residue class rings
##  <C>Integers mod <A>q</A></C>, with <A>q</A> an odd prime power, are
##  supported.
##  <P/>
##  If version at least 1.2.6 of the <Package>Forms</Package> package is
##  loaded and the arguments describe a matrix group over a finite field then
##  the desired bilinear form can be specified via <A>form</A>,
##  which can be either a matrix
##  or a form object in <Ref Filt="IsBilinearForm" BookName="Forms"/>
##  or a group with stored <Ref Attr="InvariantBilinearForm"/> value
##  (and then this form is taken).
##  <P/>
##  A given <A>form</A> determines and <A>d</A>, and also <A>q</A>
##  except if <A>form</A> is a matrix that does not store its
##  <Ref Attr="BaseDomain" Label="for a matrix object"/> value.
##  These parameters can be entered, and an error is signalled if they do
##  not fit to the given <A>form</A>.
##  <P/>
##  If <A>form</A> is not given then a default is chosen as described in the
##  introduction to Section <Ref Sect="Classical Groups"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> SymplecticGroup( 4, 2 );
##  Sp(4,2)
##  gap> g:=SymplecticGroup(6,Integers mod 9);
##  Sp(6,Z/9Z)
##  gap> Size(g);
##  95928796265538862080
##  gap> SymplecticGroup( IsPermGroup, 4, 2 );
##  Perm_Sp(4,2)
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "DescribesInvariantBilinearForm",
    obj -> IsMatrixOrMatrixObj( obj ) or
           ( IsBoundGlobal( "IsBilinearForm" ) and
             ValueGlobal( "IsBilinearForm" )( obj ) ) or
           ( IsGroup( obj ) and HasInvariantBilinearForm( obj ) ) );

BindGlobal( "SymplecticGroup", function ( arg )
  local filt, form;

  if IsFilter( First( arg ) ) then
    filt:= Remove( arg, 1 );
  else
    filt:= IsMatrixGroup;
  fi;
  if DescribesInvariantBilinearForm( Last( arg ) ) then
    form:= Remove( arg );
    if Length( arg ) = 0 then
      # ( [<filt>, ]<form> )
      return SymplecticGroupCons( filt, form );
    elif Length( arg ) = 2 and IsPosInt( arg[1] )
                           and ( IsPosInt( arg[2] ) or IsRing( arg[2] ) ) then
      # ( [<filt>, ]<d>, <q>, <form> ) or ( [<filt>, ]<d>, <R>, <form> )
      return SymplecticGroupCons( filt, arg[1], arg[2], form );
    fi;
  elif Length( arg ) = 2 and IsPosInt( arg[1] )
                         and ( IsPosInt( arg[2] ) or IsRing( arg[2] ) ) then
    # ( [<filt>, ]<d>, <q> ) or ( [<filt>, ]<d>, <R> )
    return SymplecticGroupCons( filt, arg[1], arg[2] );
  fi;
  Error( "usage: SymplecticGroup( [<filt>, ]<d>, <q>[, <form>] )\n",
         "or SymplecticGroup( [<filt>, ]<d>, <R>[, <form>] )\n",
         "or SymplecticGroup( [<filt>, ]<form> )" );
end );

DeclareSynonym( "Sp", SymplecticGroup );
DeclareSynonym( "SP", SymplecticGroup );


#############################################################################
##
#O  OmegaCons( <filter>, <e>, <d>, <q> )  . . . . . . . . .  orthogonal group
##
##  <ManSection>
##  <Oper Name="OmegaCons" Arg='filter, d, e, q'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "OmegaCons", [ IsGroup, IsInt, IsPosInt, IsPosInt ] );


#############################################################################
##
#O  Omega( [<filt>, ][<e>, ]<d>, <q>[, <form>] )
#O  Omega( [<filt>, ]<form> )
##
##  <#GAPDoc Label="Omega_orthogonal_groups">
##  <ManSection>
##  <Oper Name="Omega" Arg='[filt, ][e, ]d, q[, form]'
##   Label="construct an orthogonal group"/>
##  <Oper Name="Omega" Arg='[filt, ]form'
##   Label="construct an orthogonal group for a given quadratic form"/>
##
##  <Description>
##  constructs a group isomorphic to the
##  group <M>\Omega</M>( <A>e</A>, <A>d</A>, <A>q</A> ) of those
##  <M><A>d</A> \times <A>d</A></M> matrices over the field with <A>q</A>
##  elements that respect a non-singular quadratic form
##  (see <Ref Attr="InvariantQuadraticForm"/>) specified by <A>e</A>,
##  and that have square spinor norm in odd characteristic
##  or Dickson invariant <M>0</M> in even characteristic, respectively,
##  in the category given by the filter <A>filt</A>.
##  <P/>
##  For odd <A>q</A> and <M><A>d</A> \geq 2</M>, this group has always
##  index two in the corresponding special orthogonal group,
##  which will be conjugate in <M>GL(d,q)</M> to the group returned by
##  SO( <A>e</A>, <A>d</A>, <A>q</A> ),
##  see <Ref Func="SpecialOrthogonalGroup"/>,
##  but may fix a different form (see <Ref Sect="Classical Groups"/>).
##  <P/>
##  The value of <A>e</A> must be <M>0</M> for odd <A>d</A> (and can
##  optionally be omitted in this case), respectively one of <M>1</M> or
##  <M>-1</M> for even <A>d</A>.
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group is the group
##  <M>\Omega</M>( <A>e</A>, <A>d</A>, <A>q</A> ) itself.
##  <P/>
##  If version at least 1.2.6 of the <Package>Forms</Package> package is
##  loaded then the desired quadratic form can be specified via <A>form</A>,
##  which can be either a matrix
##  or a form object in <Ref Filt="IsQuadraticForm" BookName="Forms"/>
##  or a group with stored <Ref Attr="InvariantQuadraticForm"/> value
##  (and then this form is taken).
##  <P/>
##  A given <A>form</A> determines <A>e</A> and <A>d</A>, and also <A>q</A>
##  except if <A>form</A> is a matrix that does not store its
##  <Ref Attr="BaseDomain" Label="for a matrix object"/> value.
##  These parameters can be entered, and an error is signalled if they do
##  not fit to the given <A>form</A>.
##  <P/>
##  If <A>form</A> is not given then a default is chosen as described in the
##  introduction to Section <Ref Sect="Classical Groups"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> g:= Omega( 3, 5 );  StructureDescription( g );
##  Omega(0,3,5)
##  "A5"
##  gap> g:= Omega( 1, 4, 4 );  StructureDescription( g );
##  Omega(+1,4,4)
##  "A5 x A5"
##  gap> g:= Omega( -1, 4, 3 );  StructureDescription( g );
##  Omega(-1,4,3)
##  "A6"
##  gap> g:= Omega( IsPermGroup, 1, 6, 2 );  StructureDescription( g );
##  Perm_Omega(+1,6,2)
##  "A8"
##  gap> IsSubset( GO( 3, 5 ), Omega( 3, 5 ) );  # different forms!
##  false
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "Omega", [ IsPosInt, IsPosInt ] );
DeclareOperation( "Omega", [ IsInt, IsPosInt, IsPosInt ] );
DeclareOperation( "Omega", [ IsFunction, IsPosInt, IsPosInt ] );
DeclareOperation( "Omega", [ IsFunction, IsInt, IsPosInt, IsPosInt ] );

DeclareOperation( "Omega", [ IsPosInt, IsRing ] );
DeclareOperation( "Omega", [ IsInt, IsPosInt, IsRing ] );
DeclareOperation( "Omega", [ IsFunction, IsPosInt, IsRing ] );
DeclareOperation( "Omega", [ IsFunction, IsInt, IsPosInt, IsRing ] );


#############################################################################
##
#O  GeneralSemilinearGroupCons( <filter>, <d>, <q> )
##
##  <ManSection>
##  <Oper Name="GeneralSemilinearGroupCons" Arg='filter, d, q'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "GeneralSemilinearGroupCons",
    [ IsGroup, IsPosInt, IsPosInt ] );


#############################################################################
##
#F  GeneralSemilinearGroup( [<filt>, ]<d>, <q> )  .  general semilinear group
#F  GammaL( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="GeneralSemilinearGroup">
##  <ManSection>
##  <Func Name="GeneralSemilinearGroup" Arg='[filt, ]d, q'/>
##  <Func Name="GammaL" Arg='[filt, ]d, q'/>
##
##  <Description>
##  <Ref Func="GeneralSemilinearGroup"/> returns a group isomorphic to the
##  general semilinear group <M>\Gamma</M>L( <A>d</A>, <A>q</A> ) of
##  semilinear mappings of the vector space
##  <C>GF( </C><A>q</A><C> )^</C><A>d</A>.
##  <P/>
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group consists of matrices of dimension
##  <A>d</A> <M>f</M> over the field with <M>p</M> elements,
##  where <A>q</A> <M>= p^f</M>, for a prime integer <M>p</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "GeneralSemilinearGroup", function( arg )
  if Length( arg ) = 2 then
    return GeneralSemilinearGroupCons( IsMatrixGroup, arg[1], arg[2] );
  elif Length( arg ) = 3 and IsOperation( arg[1] ) then
    return GeneralSemilinearGroupCons( arg[1], arg[2], arg[3] );
  fi;
  Error( "usage: GeneralSemilinearGroup( [<filter>, ]<d>, <q> )" );
end );

DeclareSynonym( "GammaL", GeneralSemilinearGroup );


#############################################################################
##
#O  SpecialSemilinearGroupCons( <filter>, <d>, <q> )
##
##  <ManSection>
##  <Oper Name="SpecialSemilinearGroupCons" Arg='filter, d, q'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareConstructor( "SpecialSemilinearGroupCons",
    [ IsGroup, IsPosInt, IsPosInt ] );


#############################################################################
##
#F  SpecialSemilinearGroup( [<filt>, ]<d>, <q> )  .  special semilinear group
#F  SigmaL( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="SpecialSemilinearGroup">
##  <ManSection>
##  <Func Name="SpecialSemilinearGroup" Arg='[filt, ]d, q'/>
##  <Func Name="SigmaL" Arg='[filt, ]d, q'/>
##
##  <Description>
##  <Ref Func="SpecialSemilinearGroup"/> returns a group isomorphic to the
##  special semilinear group <M>\Sigma</M>L( <A>d</A>, <A>q</A> ) of those
##  semilinear mappings of the vector space
##  <C>GF( </C><A>q</A><C> )^</C><A>d</A>
##  (see <Ref Func="GeneralSemilinearGroup"/>)
##  whose linear part has determinant one.
##  <P/>
##  If <A>filt</A> is not given it defaults to <Ref Filt="IsMatrixGroup"/>,
##  and the returned group consists of matrices of dimension
##  <A>d</A> <M>f</M> over the field with <M>p</M> elements,
##  where <A>q</A> <M>= p^f</M>, for a prime integer <M>p</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "SpecialSemilinearGroup", function( arg )
  if Length( arg ) = 2 then
    return SpecialSemilinearGroupCons( IsMatrixGroup, arg[1], arg[2] );
  elif Length( arg ) = 3 and IsOperation( arg[1] ) then
    return SpecialSemilinearGroupCons( arg[1], arg[2], arg[3] );
  fi;
  Error( "usage: SpecialSemilinearGroup( [<filter>, ]<d>, <q> )" );
end );

DeclareSynonym( "SigmaL", SpecialSemilinearGroup );


#############################################################################
##
#F  DECLARE_PROJECTIVE_GROUPS_OPERATION( ... )
##
BindGlobal("DECLARE_PROJECTIVE_GROUPS_OPERATION",
  # (<name>,<abbreviation>,<fieldextdeg>,<sizefunc-or-fail>)
  function(nam,abbr,extdeg,szf)
local pnam,cons,opr;
  opr:=VALUE_GLOBAL(nam);
  pnam:=Concatenation("Projective",nam);
  cons:=NewConstructor(Concatenation(pnam,"Cons"),[IsGroup,IsInt,IsInt]);
  BindGlobal(Concatenation(pnam,"Cons"),cons);
  BindGlobal(pnam,function(arg)
    if Length(arg) = 2  then
      return cons( IsPermGroup, arg[1], arg[2] );
    elif IsOperation(arg[1]) then
      if Length(arg) = 3  then
        return cons( arg[1], arg[2], arg[3] );
      fi;
    fi;
    Error( "usage: ",pnam,"( [<filter>, ]<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, IsPosInt,IsPosInt ],
  function(fil,n,q)
  local g,f,p;
    g:=opr(IsMatrixGroup,n,q);
    f:=GF(q^extdeg);
    p:=ProjectiveActionOnFullSpace(g,f,n);
    if szf<>fail then
      SetSize(p,szf(n,q,g));
    fi;
    return p;
  end);

end);


#############################################################################
##
#F  ProjectiveGeneralLinearGroup( [<filt>, ]<d>, <q> )
#F  PGL( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="ProjectiveGeneralLinearGroup">
##  <ManSection>
##  <Func Name="ProjectiveGeneralLinearGroup" Arg='[filt, ]d, q'/>
##  <Func Name="PGL" Arg='[filt, ]d, q'/>
##
##  <Description>
##  constructs a group isomorphic to the projective general linear group
##  PGL( <A>d</A>, <A>q</A> ) of those <M><A>d</A> \times <A>d</A></M>
##  matrices over the field with <A>q</A> elements, modulo the
##  centre, 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.
##  <P/>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DECLARE_PROJECTIVE_GROUPS_OPERATION("GeneralLinearGroup","GL",1,
  # size function
  function(n,q,g)
    return Size(g)/(q-1);
  end);


#############################################################################
##
#F  ProjectiveSpecialLinearGroup( [<filt>, ]<d>, <q> )
#F  PSL( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="ProjectiveSpecialLinearGroup">
##  <ManSection>
##  <Func Name="ProjectiveSpecialLinearGroup" Arg='[filt, ]d, q'/>
##  <Func Name="PSL" Arg='[filt, ]d, q'/>
##
##  <Description>
##  constructs a group isomorphic to the projective special linear group
##  PSL( <A>d</A>, <A>q</A> ) of those <M><A>d</A> \times <A>d</A></M>
##  matrices over the field with <A>q</A> elements whose determinant is the
##  identity of the field, modulo the centre,
##  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_GROUPS_OPERATION("SpecialLinearGroup","SL",1,
  # size function
  function(n,q,g)
    return Size(g)/Gcd(n,q-1);
  end);


#############################################################################
##
#F  ProjectiveGeneralUnitaryGroup( [<filt>, ]<d>, <q> )
#F  PGU( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="ProjectiveGeneralUnitaryGroup">
##  <ManSection>
##  <Func Name="ProjectiveGeneralUnitaryGroup" Arg='[filt, ]d, q'/>
##  <Func Name="PGU" Arg='[filt, ]d, q'/>
##
##  <Description>
##  constructs a group isomorphic to the projective general unitary group
##  PGU( <A>d</A>, <A>q</A> ) of those <M><A>d</A> \times <A>d</A></M>
##  matrices over the field with <M><A>q</A>^2</M> elements that respect
##  a fixed nondegenerate sesquilinear form,
##  modulo the centre, 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_GROUPS_OPERATION("GeneralUnitaryGroup","GU",2,
  # size function
  function(n,q,g)
    return Size(g)/(q+1);
  end);


#############################################################################
##
#F  ProjectiveSpecialUnitaryGroup( [<filt>, ]<d>, <q> )
#F  PSU( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="ProjectiveSpecialUnitaryGroup">
##  <ManSection>
##  <Func Name="ProjectiveSpecialUnitaryGroup" Arg='[filt, ]d, q'/>
##  <Func Name="PSU" Arg='[filt, ]d, q'/>
##
##  <Description>
##  constructs a group isomorphic to the projective special unitary group
##  PSU( <A>d</A>, <A>q</A> ) of those <M><A>d</A> \times <A>d</A></M>
##  matrices over the field with <M><A>q</A>^2</M> elements that respect
##  a fixed nondegenerate sesquilinear form and have determinant 1,
##  modulo the centre, 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_GROUPS_OPERATION("SpecialUnitaryGroup","SU",2,
  # size function
  function(n,q,g)
    return Size(g)/Gcd(n,q+1);
  end);


#############################################################################
##
#F  ProjectiveSymplecticGroup( [<filt>, ]<d>, <q> )
#F  PSP( [<filt>, ]<d>, <q> )
#F  PSp( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="ProjectiveSymplecticGroup">
##  <ManSection>
##  <Func Name="ProjectiveSymplecticGroup" Arg='[filt, ]d, q'/>
##  <Func Name="PSP" Arg='[filt, ]d, q'/>
##  <Func Name="PSp" Arg='[filt, ]d, q'/>
##
##  <Description>
##  constructs a group isomorphic to the projective symplectic group
##  PSp(<A>d</A>,<A>q</A>) of those <M><A>d</A> \times <A>d</A></M> matrices
##  over the field with <A>q</A> elements that respect a fixed nondegenerate
##  symplectic form, modulo the centre,
##  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_GROUPS_OPERATION("SymplecticGroup","SP",1,
  # size function
  function(n,q,g)
    return Size(g)/Gcd(2,q-1);
  end);
DeclareSynonym( "PSp", PSP );


#############################################################################
##
#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
##  (see <Ref Func="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 Func="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> )
##
##  <#GAPDoc Label="ProjectiveOmega">
##  <ManSection>
##  <Func Name="ProjectiveOmega" Arg='[filt, ][e, ]d, q'/>
##  <Func Name="POmega" Arg='[filt, ][e, ]d, q'/>
##
##  <Description>
##  constructs a group isomorphic to the projective group
##  P<M>\Omega</M>( <A>e</A>, <A>d</A>, <A>q</A> )
##  of <M>\Omega</M>( <A>e</A>, <A>d</A>, <A>q</A> ),
##  modulo the centre
##  (see <Ref Oper="Omega" Label="construct an orthogonal group"/>),
##  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( "Omega", "Omega",
  function( e, n, q, g )
    if n mod 2 = 0 and ( q^(n/2) - e ) mod 4 = 0 then
      return Size( g ) / 2;
    else
      return Size( g );
    fi;
  end );


#############################################################################
##
#F  DECLARE_PROJECTIVE_SEMILINEAR_GROUPS_OPERATION( ... )
##
BindGlobal( "DECLARE_PROJECTIVE_SEMILINEAR_GROUPS_OPERATION",
  function( name, abbrname, lineargroup, sizefun )
  local opr, pname, consname, cons;

  opr:= VALUE_GLOBAL( name );
  pname:= Concatenation( "Projective", name );
  consname:= Concatenation( pname, "Cons" );
  DeclareConstructor( consname, [ IsGroup, IsInt, IsInt ] );
  cons:= ValueGlobal( consname );

  BindGlobal( pname, function( arg )
    if Length( arg ) = 2 then
      return cons( IsPermGroup, arg[1], arg[2] );
    elif IsOperation( arg[1] ) then
      if Length( arg ) = 3 then
        return cons( arg[1], arg[2], arg[3] );
      fi;
    fi;
    Error( "usage: ", pname, "( [<filter>, ]<d>, <q> )" );
  end );

  DeclareSynonym( Concatenation( "P", abbrname ), VALUE_GLOBAL( pname ) );

  # Install a method to get the permutation action on lines.
  InstallMethod( cons,
      "action on lines",
      [ IsPermGroup, IsPosInt, IsPosInt ],
      function( filt, n, q )
      local lin, facts, d, p, F, points, gens, indices, g;

      lin:= lineargroup( IsMatrixGroup, n, q );
      facts:= Factors( Integers, q );
      d:= Length( facts );
      p:= facts[1];

      if n = 1 then
        return CyclicGroup( filt, d );
      fi;

      F:= GF( q );
      points:= Set( NormedRowVectors( F^n ), v -> ImmutableVector( F, v ) );
      gens:= List( GeneratorsOfGroup( lin ),
                   mat -> Permutation( mat, points, OnLines ) );

      # Apply the field automorphism to the normed vectors.
      if d > 1 then
        Apply( points, v -> ImmutableVector( F, List( v, x -> x^p ) ) );
        indices:= [ 1 .. Length( points ) ];
        SortParallel( points, indices );
        Add( gens, PermList( indices ) );
      fi;

      g:= GroupWithGenerators( gens );
      SetSize( g, sizefun( n, q, d, lin ) );

      return g;
  end );
end );


#############################################################################
##
#F  ProjectiveGeneralSemilinearGroup( [<filt>, ]<d>, <q> )
#F  PGammaL( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="ProjectiveGeneralSemilinearGroup">
##  <ManSection>
##  <Func Name="ProjectiveGeneralSemilinearGroup" Arg='[filt, ]d, q'/>
##  <Func Name="PGammaL" Arg='[filt, ]d, q'/>
##
##  <Description>
##  <Ref Func="ProjectiveGeneralSemilinearGroup"/> returns a group
##  isomorphic to the factor group of the general semilinear group
##  <C>GammaL(</C> <A>d</A>, <A>q</A> <C>)</C> modulo the center of its
##  normal subgroup <C>GL(</C> <A>d</A>, <A>q</A> <C>)</C>.
##  <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 <C>GF(</C><A>q</A><C>)^</C><A>d</A>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DECLARE_PROJECTIVE_SEMILINEAR_GROUPS_OPERATION( "GeneralSemilinearGroup",
    "GammaL", GL, { n, q, d, lin } -> d * Size( lin ) / (q-1) );


#############################################################################
##
#F  ProjectiveSpecialSemilinearGroup( [<filt>, ]<d>, <q> )
#F  PSigmaL( [<filt>, ]<d>, <q> )
##
##  <#GAPDoc Label="ProjectiveSpecialSemilinearGroup">
##  <ManSection>
##  <Func Name="ProjectiveSpecialSemilinearGroup" Arg='[filt, ]d, q'/>
##  <Func Name="PSigmaL" Arg='[filt, ]d, q'/>
##
##  <Description>
##  <Ref Func="ProjectiveSpecialSemilinearGroup"/> returns a group
##  isomorphic to the factor group of the special semilinear group
##  <C>SigmaL(</C> <A>d</A>, <A>q</A> <C>)</C> modulo the center of its
##  normal subgroup <C>SL(</C> <A>d</A>, <A>q</A> <C>)</C>.
##  <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 <C>GF(</C><A>q</A><C>)^</C><A>d</A>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DECLARE_PROJECTIVE_SEMILINEAR_GROUPS_OPERATION( "SpecialSemilinearGroup",
    "SigmaL", SL, { n, q, d, lin } -> d * Size( lin ) / Gcd( n, q-1 ) );

[ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge