Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/fining/lib/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 27.6.2023 mit Größe 101 kB image not shown  

Quelle  group.gi   Sprache: unbekannt

 
##########################################################################
##
##  group.gi              FinInG package
##                                                              John Bamberg
##                                                              Anton Betten
##                                                              Jan De Beule
##                                                             Philippe Cara
##                                                            Michel Lavrauw
##                                                           Max Neunhoeffer
##
##  Copyright 2018 Colorado State University
##                  Sabancı Üniversitesi
##     Università degli Studi di Padova
##     Universiteit Gent
##     University of St. Andrews
##     University of Western Australia
##                  Vrije Universiteit Brussel
##
##
##  Implementation stuff for our "projective groups"
##
############################################################################

## helping function. came from projectivespace.gi

# CHECKED 5/09/11 jdb
# We are currently CVec'ing everything. I decide to keep this function as is, and
# convert its output where appriopriate to a list of cvecs
# This makes that converting the vectors here to a dirty GAP vector is useless, so I
# uncommented the if q <= 256 statement.
#############################################################################
#F  MakeAllProjectivePoints( f,d )
# Global function to compute all points of a projective space. Not for users.
# <f>: field; <d>: *projective* dimension.
##
InstallGlobalFunction( MakeAllProjectivePoints, 
function(f,d)

  # f is a finite field
  # d an integer >= 1
  # This function is used for computing the permutation representation (NiceMonomorphism)
  # quickly and with the least memory used as possible, for a projective group.
  # Later, we will convert everything here to CVec's, which should give us an
  # improved permutation representation. For example:
  #   gap> pg:=PG(5,5);
  #   ProjectiveSpace(5, 5)
  #   gap> g:=ProjectivityGroup(pg);
  #   PGL(6,5)
  #   gap> hom := NiceMonomorphism(g);
  #   <action isomorphism>
  #   gap> omega:=UnderlyingExternalSet(hom);;
  #   gap> Random(omega);
  #   ## returns a compressed vector


  local els,i,j,l,q,sp,v,vs,w,ww,x;
  els := Elements(f);
  q := Length(els);
  v := CVec([1..d+1]*Zero(f),f); # using cvecs (ml 31/03/13) 
  #v := ListWithIdenticalEntries(d+1,Zero(f));
  #if q <= 256 then ConvertToVectorRep(v,q); fi;
  vs := EmptyPlist(q^d);
  sp := EmptyPlist((q^(d+1)-1)/(q-1));
  for x in els do
    w := ShallowCopy(v);
    w[d+1] := x;
    Add(vs,w);
  od;
  w := ShallowCopy(v);
  w[d+1] := One(f);
  Add(sp,w);
  for i in [d,d-1..1] do
    l := Length(vs);
    for j in [1..l] do
      ww := ShallowCopy(vs[j]);
      ww[i] := One(f);
      Add(sp,ww);
      Add(vs,ww);
    od;
    if i > 1 then
        for x in els do
          if not(IsZero(x)) and not(IsOne(x)) then
            for j in [1..l] do
              ww := ShallowCopy(vs[j]);
              ww[i] := x;
              Add(vs,ww);
            od;
          fi;
        od;
    fi;
  od;
  return Set(sp);
end);


## make this a global function? Definitely (jdb, 6/9/11).

# CHECKED 6/09/11 jdb
#############################################################################
#F  IsFiningScalarMatrix( a)
#returns true if <a> is a scalar matrix.
##
InstallGlobalFunction(IsFiningScalarMatrix,
 function( a )
 local n;
 n := a[1,1];
 if IsZero(n) then 
  return false;
 else
  return IsOne(a/n);
 fi;
 end );


###################################################################
# Construction of "projective elements", that is matrices modulo scalars:
###################################################################

## A lot of the following is now obselete. We should consider
## deleting some of it.

# CHECKED 5/09/11 jdb
# We are in the very big cvec operation and will skip all methods for non frob groups right now. 19/3/2014.
# I am not completely happy with the behaviour of this method, since there might
# be some issue with the field.
# On the other hand, it is not intended for the user and might even be obselete
#############################################################################
#O  ProjEl( <mat> )
# method to construct an object in the category IsProjGrpEl, i.e. projectivities, 
# aka "matrices modulo scalars". This method is not intended for the users. 
# it has no checks built in. It relies on DefaultFieldOfMatrix to determine the 
# field to be used.
##
InstallMethod( ProjEl, 
 "for a ffe matrix",
 [IsMatrix and IsFFECollColl],
 function( m )
  local el, m2, f;
     m2 := ShallowCopy( m );
  f := DefaultFieldOfMatrix(m);
  ConvertToMatrixRepNC( m2, f );
  el := rec( mat := m2, fld := f );
  Objectify( NewType( ProjElsFamily,
       IsProjGrpEl and
       IsProjGrpElRep ), el );
  return el;
 end );

# CHECKED 5/09/11 jdb
#############################################################################
#O  ProjEls( <mat> )
# method to construct objects in the category IsProjGrpEl, i.e. projectivities, 
# aka "matrices modulo scalars". This method is not intended for the users.
# it has no checks built in, and is almost liek ProjEl.
## 
InstallMethod( ProjEls, "for a list of ffe matrices",
  [IsList],
  function( l )
    local el,fld,ll,m,ty,m2;
    fld := FieldOfMatrixList(l);
    ll := [];
    ty := NewType( ProjElsFamily,
                   IsProjGrpEl and
                   IsProjGrpElRep );
    for m in l do
        m2 := ShallowCopy(m);
  ConvertToMatrixRepNC( m2, fld );
        el := rec( mat := m2, fld := fld );
        Objectify( ty, el );
        Add(ll,el);
    od;
    return ll;
  end );

# CHECKED 5/09/11 jdb # changed ml 8/11/12
# changed 19/3/2014 to cmat.
#############################################################################
#O  Projectivity( <mat>, <gf> )
# method to construct an object in the category IsProjGrpElWithFrob, but with
# field automorphism equal to the identity, i.e. a projectivity, 
# This method is intended for the user, and contains
# a check whether the matrix is non-singular.
## 
InstallMethod( Projectivity, [ IsMatrix and IsFFECollColl, IsField],
    ## A bug was found here, during a nice August afternoon involving pigeons,
    ## where the variable m2 was assigned to the size of the field.
    ## jdb 13/12/08, Giessen, cold saturday afternoon. I still remember the
    ## pigeons, so does my computer. I add some lines now to check whether the
    ## matrix is non singular. 
   function( mat, gf )
  local el, m2, fld, frob, cmat;
  m2 := ShallowCopy(mat);
  #if NrCols(m2) <> NrRows(m2) then
  # Error("<mat> must be a square matrix");
  #fi;
  if Rank(m2) <> Size(m2) then
   Error("<mat> must not be singular");
  fi;
  #ConvertToMatrixRep( m2, gf );
  cmat := NewMatrix( IsCMatRep, gf, Size(m2) , m2);
  el := rec( mat := cmat, fld := gf, frob := FrobeniusAutomorphism(gf)^0 );
  Objectify( ProjElsWithFrobType, el );
  return el;
 end );

# added 19/3/2014 (cmat).
#############################################################################
#O  Projectivity( <mat>, <gf> )
# method to construct an object in the category IsProjGrpElWithFrob,
# as above, with input a cmat and field
## 
InstallMethod( Projectivity, [ IsCMatRep and IsFFECollColl, IsField],
   function( mat, gf )
  local el, m2, fld, frob, cmat;
  m2 := ShallowCopy(mat);
  #if NrCols(m2) <> NrRows(m2) then
  # Error("<mat> must be a square matrix");
  #fi;
  if Rank(m2) <> NrRows(m2) then
   Error("<mat> must not be singular");
  fi;
  #ConvertToMatrixRep( m2, gf );
  el := rec( mat := m2, fld := gf, frob := FrobeniusAutomorphism(gf)^0 );
  Objectify( ProjElsWithFrobType, el );
  return el;
 end );


# Added ml 8/11/2012
#############################################################################
#O  Projectivity( <pg>, <mat> )
# method to construct an object in the category IsProjGrpEl, i.e. a projectivity, 
# This method is intended for the user, and contains
# a check whether the matrix is non-singular.
## 
InstallMethod( Projectivity, [ IsProjectiveSpace, IsMatrix],
#
   function( pg, mat )
  local d,gf,m2;
  d:=Dimension(pg);
  gf:=pg!.basefield;
  if d <> NrRows(mat)-1 then
   Error("The arguments <mat> and <pg> are incompatible");
  fi;
  m2 := ShallowCopy(mat);
  #if NrCols(m2) <> NrRows(m2) then
  # Error("<mat> must be a square matrix");
  #fi;
  if Rank(m2) <> NrRows(m2) then
   Error("<mat> must not be singular");
  fi;
  return Projectivity(mat,gf);
 end );

# Added ml cmat version 19/3/14.
#############################################################################
#O  Projectivity( <pg>, <mat> )
# method to construct an object in the category IsProjGrpEl, i.e. a projectivity, 
# This method is intended for the user, and contains
# a check whether the matrix is non-singular.
## 
InstallMethod( Projectivity, [ IsProjectiveSpace, IsCMatRep],
#
   function( pg, mat )
  local d,gf,m2;
  d:=Dimension(pg);
  gf:=pg!.basefield;
  if d <> NrRows(mat)-1 then
   Error("The arguments <mat> and <pg> are incompatible");
  fi;
  m2 := ShallowCopy(mat);
  #if NrCols(m2) <> NrRows(m2) then
  # Error("<mat> must be a square matrix");
  #fi;
  if Rank(m2) <> NrRows(m2) then
   Error("<mat> must not be singular");
  fi;
  return Projectivity(mat,gf);
 end );


###################################################################
# Tests whether collineation is a projectivity and so on ...
###################################################################

# Added ml 7/11/2012
#############################################################################
#O  IsProjectivity( <g> )
## 
InstallMethod( IsProjectivity, [ IsProjGrpEl ],
  function( g )
 return true;
  end );

# Added ml 7/11/2012
#############################################################################
#O  IsProjectivity( <g> )
# method to check if a given collineation of a projective space is a projectivity, 
# i.e. if the corresponding frobenius automorphism is the identity
## 
InstallMethod( IsProjectivity, [ IsProjGrpElWithFrob ],
  function( g )
    local F,sigma;
  F:=g!.fld;
  sigma:=g!.frob;
  if sigma = FrobeniusAutomorphism(F)^0
  then return true;
  else return false;
  fi;
  end );

# Added ml 8/11/2012 # changed ml 28/11/2012
#############################################################################
#O  IsStrictlySemilinear( <g> )
## 
InstallMethod( IsStrictlySemilinear, [ IsProjGrpEl],
  function( g )
 return false;
  end );

# Added ml 8/11/2012 # changed ml 28/11/2012
#############################################################################
#O  IsStrictlySemilinear( <g> )
# method to check if a given collineation of a projective space is semilinear, 
# i.e. if the corresponding frobenius automorphism is NOT the identity
## 
InstallMethod( IsStrictlySemilinear, [ IsProjGrpElWithFrob],
  function( g )
    local F,sigma;
  F:=g!.fld;
  sigma:=g!.frob;
  if sigma = FrobeniusAutomorphism(F)^0
  then return false;
  else return true;
  fi;
  end );

  
  
# Added ml 8/11/2012
#############################################################################
#O  IsCollineation( <g> )
## 
InstallMethod( IsCollineation, [ IsProjGrpEl],
  function( g )
 return true;
  end );

# Added ml 8/11/2012
#############################################################################
#O  IsCollineation( <g> )
## 
InstallMethod( IsCollineation, [ IsProjGrpElWithFrob],
  function( g )
    return true;
end );


# Added ml 7/11/2012
#############################################################################
#O  IsProjectivityGroup( <G> )
# method to check if a given projective collineation group G is a projectivity group, 
# i.e. if the corresponding frobenius automorphisms of the generators are the identity
## 
InstallMethod( IsProjectivityGroup, [ IsProjectiveGroupWithFrob],
  function( G )
    local gens, F, set, g;
  gens:=GeneratorsOfMagmaWithInverses(G);
  F:=gens[1]!.fld;
  set:=AsSet(List(gens,g->g!.frob));
  if set = AsSet([FrobeniusAutomorphism(F)^0])
  then return true;
  else return false;
  fi;
  end );


# Added ml 8/11/2012
#############################################################################
#O  IsCollineationGroup( <G> )
##
InstallMethod( IsCollineationGroup, [ IsProjectiveGroupWithFrob],
  function( G )
 return true;
  end );

###################################################################
# Construction of "projective collineation maps", that is matrices 
# modulo scalars with frobenius automorphism
###################################################################

# CHECKED 5/09/11 jdb
# cmat changed 19/3/14
#############################################################################
#O  ProjElWithFrob( <mat>, <frob>, <f> )
# method to construct an object in the category IsProjGrpElWithFrob, i.e. projective 
# semilinear maps aka "matrices modulo scalars with frob". This method is not 
# intended for the users, it has no checks built in.
##
InstallMethod( ProjElWithFrob, 
 "for a cmat/ffe matrix and a Frobenius automorphism, and a field",
 [IsCMatRep and IsFFECollColl, #changed 19/3/14 to cmat.
 IsRingHomomorphism and IsMultiplicativeElementWithInverse,
 IsField],
 function( m, frob, f )
  local el, m2;
  m2 := ShallowCopy(m);
  #ConvertToMatrixRep( m2, f );
  el := rec( mat := m2, fld := f, frob := frob );
  Objectify( ProjElsWithFrobType, el );
  return el;
 end );
 
# added 19/03/14
#############################################################################
#O  ProjElWithFrob( <mat>, <frob>, <f> )
# method to construct an object in the category IsProjGrpElWithFrob, i.e. projective 
# semilinear maps aka "matrices modulo scalars with frob". This method is not 
# intended for the users, it has no checks built in.
##
InstallMethod( ProjElWithFrob, 
 "for a ffe matrix and a Frobenius automorphism, and a field",
 [IsMatrix and IsFFECollColl, 
 IsRingHomomorphism and IsMultiplicativeElementWithInverse,
 IsField],
 function( m, frob, f )
  local el, m2, cmat;
  m2 := ShallowCopy(m);
  #ConvertToMatrixRep( m2, f );
  cmat := NewMatrix(IsCMatRep,f,NrCols(m2),m2);
  el := rec( mat := cmat, fld := f, frob := frob );
  Objectify( ProjElsWithFrobType, el );
  return el;
 end );
 

# CHECKED 5/09/11 jdb
# cmat changed 19/3/14
#############################################################################
#O  ProjElWithFrob( <mat>, <frob> )
# method to construct an object in the category IsProjGrpElWithFrob, i.e. projective 
# semilinear maps aka "matrices modulo scalars with frob". This method is not 
# intended for the users, although there are some checks built in. 
# This method relies on DefaultFieldOfMatrix and Range(<frbo>) to determine the field to be used
##
InstallMethod( ProjElWithFrob, 
 "for a cmat/ffe matrix and a Frobenius automorphism",
 [IsCMatRep and IsFFECollColl, #changed 19/3/14. 
 IsRingHomomorphism and IsMultiplicativeElementWithInverse], 
 1, #to set higher priority than the next method.
 function ( m, frob )
  local matrixfield, frobfield, mchar, fchar, dim;
  if IsOne(frob) then
    TryNextMethod();
  fi;
  matrixfield := DefaultFieldOfMatrix(m);
  mchar := Characteristic(matrixfield);
  frobfield := Range(frob);
  fchar := Characteristic(frobfield);
  if mchar <> fchar then
    Error("the matrix and automorphism do not agree on the characteristic");
  fi;
  
  # figure out a field which contains the matrices and admits the
  # automorphisms (nontrivially)
  dim := Lcm(
    LogInt(Size(matrixfield),mchar),
   LogInt(Size(frobfield),fchar)
   );
 return ProjElWithFrob( m, frob, GF(mchar^dim) );
 end);
 
# CHECKED 5/09/11 jdb
# cmat changed 19/3/14
#############################################################################
#O  ProjElWithFrob( <mat>, <frob> )
# method to construct an object in the category IsProjGrpElWithFrob, i.e. projective 
# semilinear maps aka "matrices modulo scalars with frob". This method is not 
# intended for the users; in fact this method is almost the same as the first version.
# This method relies on DefaultFieldOfMatrix to determine the field to be used
# This method should only be called from the above one, if IsOne(frob) is true,
# but we built in a little check to abvoid disasters.
##
InstallMethod( ProjElWithFrob, 
 "for a cmat/ffe matrix and a trivial Frobenius automorphism",
 [IsCMatRep and IsFFECollColl,
 IsRingHomomorphism and IsMultiplicativeElementWithInverse], 
 0, #to set lower priority than the previous method.
 function( m, frob )
  local el, m2;
  if not IsOne(frob) then
    Error("<frob> is not trivial. Something went wrong when calling this method");
  fi;
  m2 := ShallowCopy(m); 
  #ConvertToMatrixRepNC( m2 );
  el := rec( mat := m2, fld := DefaultFieldOfMatrix(m), frob := frob );
  Objectify( ProjElsWithFrobType, el );
  return el;
 end );

# CHECKED 5/09/11 jdb
#############################################################################
#O  ProjElsWithFrob( <l>, <f> )
# method to construct a list of objects in the category IsProjGrpElWithFrob,
# using a list of pairs of matrix/frobenius automorphism, and a field.
# This method relies of ProjElWithFrob, and is not inteded for the user.
# no checks are built in. This could result in e.g. the use of a field that is 
# not compatible with (some of) the matrices, and result in a non user friendly 
# error
##
InstallMethod( ProjElsWithFrob,
 "for a list of pairs of ffe matrices and frobenius automorphisms, and a field",
 [IsList, IsField],
 function( l, f )
 local objectlist, m;
  objectlist := [];
  for m in l do
   Add(objectlist, ProjElWithFrob(m[1],m[2],f));
  od;
  return objectlist;
 end );

# CHECKED 5/09/11 jdb
#############################################################################
#O  ProjElsWithFrob( <l> )
# method to construct a list of objects in the category IsProjGrpElWithFrob,
# using a list of pairs of matrix/frobenius automorphism. It is checked if 
# the given matrices/automorphism pairs can be considered over a common field.
# This method relies eventually also on ProjElWithFrob, and is not inteded for the user,
# although the mechanism of fining the suitable field will display an error 
# if this is not possible.
##
InstallMethod( ProjElsWithFrob, 
 "for a list of pairs of cmat/ffe matrices and Frobenius automorphisms",
 [IsList],
 function( l )
    local matrixfield, frobfield, mchar, fchar, oldchar, f, dim, m, objectlist;
    if(IsEmpty(l)) then
  return [];
  fi;
  dim := 1;

  # get the characteristic of the field that we want to work in.
  # it should be the same for every matrix and every automorphism --
  # if not we will raise an error.
  oldchar := Characteristic(l[1][1]);
  for m in l do
    matrixfield := DefaultFieldOfMatrix(m[1]);
    mchar := Characteristic(matrixfield);
    frobfield := Range(m[2]);
    fchar := Characteristic(frobfield);
    if mchar <> fchar or mchar <> oldchar then
      Error("matrices and automorphisms do not agree on the characteristic");
    fi;
  
    # at each step we increase the dimension of the desired field
  # so that it contains all the matrices and admits all the automorphisms
  # (nontrivially.)
  
    dim := Lcm( dim, LogInt(Size(matrixfield),mchar),
     LogInt(Size(frobfield),fchar));
  od;

  f := GF(oldchar ^ dim);
  objectlist := [];
  for m in l do
   Add(objectlist, ProjElWithFrob(m[1],m[2],f));
  od;
  return objectlist;
 end );


# CHECKED 5/09/11 jdb # changed ml 8/11/12
#############################################################################
#O  CollineationOfProjectiveSpace( <mat>, <gf> )
# method to construct an object in the category IsProjGrpElWithFrob, i.e. a 
# collineation of a projective space. 
# This method is intended for the user, and contains
# a check whether the matrix is non-singular. The method relies on ProjElWithFrob,
# which will produce an error if the entries of <mat> do not all belong to <gf>
# the automorphism will be trivial. Mathematically this is a projectivity.
## 
InstallMethod( CollineationOfProjectiveSpace, 
 [ IsMatrix and IsFFECollColl, IsField],
 function( mat, gf )
    if Rank(mat) <> NrRows(mat) then
  Error("<mat> must not be singular");
    fi;
    return ProjElWithFrob( mat, IdentityMapping(gf), gf);
 end );

# Added ml 8/11/2012
#############################################################################
#O  CollineationOfProjectiveSpace( <pg>, <mat> )
# method to construct an collineation of a projective space.
## 
InstallMethod( CollineationOfProjectiveSpace, [ IsProjectiveSpace, IsMatrix],
#
   function( pg, mat )
  local d,gf;
  d:=Dimension(pg);
  gf:=pg!.basefield;
  if d <> NrRows(mat)-1 then
   Error("The arguments <mat> and <pg> are incompatible");
  fi;
  return ProjElWithFrob( mat, IdentityMapping(gf), gf);
 end );

# Added jdb 26/05/2016
# not documented yet
#############################################################################
#O  CollineationOfProjectiveSpace( <pg>, <mat> )
# method to construct an collineation of a projective space with identitymatrix,
# but with user defined field automorphism.
## 
InstallMethod( CollineationOfProjectiveSpace, [ IsProjectiveSpace, IsMapping],
   function( pg, frob )
  local d,gf,mat;
  d:=Dimension(pg);
  gf:=Range(frob);
        if not gf = pg!.basefield then
            Error("basefield of <pg> does not match with range of <frob>");
        fi;
        mat := IdentityMat(d+1,gf);
  return ProjElWithFrob( mat, frob, gf);
 end );


# Added ml 8/11/2012
#############################################################################
#O  CollineationOfProjectiveSpace( <pg>, <mat>, <frob>)
# method to construct an collineation of a projective space.
## 
InstallMethod( CollineationOfProjectiveSpace, [ IsProjectiveSpace, IsMatrix, IsMapping],
#
   function( pg, mat, frob )
  local d,gf;
  d:=Dimension(pg);
  gf:=pg!.basefield;
  if d <> NrRows(mat)-1 then
   Error("The arguments <mat> and <pg> are incompatible");
  fi;
  return ProjElWithFrob( mat, frob, gf);
 end );


# Added ml 8/11/2012
#############################################################################
#O  Collineation( <pg>, <mat> )
# shorter version of the previous method to construct an collineation of a projective space.
## 
InstallMethod( Collineation, [ IsProjectiveSpace, IsMatrix],
#
   function( pg, mat )
  return CollineationOfProjectiveSpace(pg,mat);
 end );


# Added ml 8/11/2012
#############################################################################
#O  Collineation( <pg>, <mat>, <frob> )
# shorter version of the previous method to construct an collineation of a projective space.
## 
InstallMethod( Collineation, [ IsProjectiveSpace, IsMatrix, IsMapping],
#
   function( pg, mat, frob )
  return CollineationOfProjectiveSpace(pg,mat,frob);
 end );


# CHECKED 5/09/11 jdb # changed ml 8/11/12
# 5/09/11 jdb: added a check to see if frob has <gf> as source
#############################################################################
#O  CollineationOfProjectiveSpace( <mat>, <frob>, <gf> )
# method to construct an object in the category IsProjGrpElWithFrob, i.e. a 
# collineation of a projective space, aka a projective collineation map. 
# This method is intended for the user, and contains
# a check whether the matrix is non-singular. The method relies on ProjElWithFrob,
# which will produce an error if the entries of <mat> do not all belong to <gf>
## 
InstallMethod( CollineationOfProjectiveSpace,  
 [ IsMatrix and IsFFECollColl, IsRingHomomorphism and
    IsMultiplicativeElementWithInverse, IsField], 
 function( mat, frob, gf )
    if Rank(mat) <> NrRows(mat) then
  Error("<mat> must not be singular");
    fi;
    if Source(frob) <> gf then
  Error("<frob> must be defined as an automorphis of <gf>");
 fi;
 return ProjElWithFrob( mat, frob, gf);
 end );


# CHECKED 5/09/11 jdb # changed ml 8/11/12
# 5/09/11 jdb: added a check to see if frob has <gf> as source
#############################################################################
#O  ProjectiveSemilinearMap( <mat>, <frob>, <gf> )
# method to construct an object in the category IsProjGrpElWithFrob, i.e. a 
# collineation of a projective space, aka a projective collineation map. 
# This method is intended for the user, and contains
# a check whether the matrix is non-singular. The method relies on ProjElWithFrob,
# which will produce an error if the entries of <mat> do not all belong to <gf>
## 
InstallMethod( ProjectiveSemilinearMap,  
 [ IsMatrix and IsFFECollColl, IsRingHomomorphism and
    IsMultiplicativeElementWithInverse, IsField], 
 function( mat, frob, gf )
  return CollineationOfProjectiveSpace(mat,frob,gf);
 end );


# CHECKED 5/09/11 jdb
#############################################################################
#O  ProjectivityByImageOfStandardFrameNC( <pg>, <image> )
# method to construct a projectivity if the image of a standard frame is given.
# THERE IS NO CHECK TO SEE IF THE GIVEN IMAGE CONSISTS OF N+2 POINTS NO N+1 L.D.
# for this reason, this function is not documented (yet).
# despite its name (projectivity), this function returns a projective semlinear map.
## 
InstallMethod( ProjectivityByImageOfStandardFrameNC, [ IsProjectiveSpace, IsList ],
 function(pg,image)
 # If the dimension of the projective space is n, then
 # given a frame, there is a 
 # unique projectivity mapping the standard frame to this set of points
 # THERE IS NO CHECK TO SEE IF THE GIVEN IMAGE CONSISTS OF N+2 POINTS NO N+1 L.D.
 local d,i,x,vlist,mat,coeffs,mat2;
 if not Length(image)=Dimension(pg)+2 then 
 Error("The argument does not have the required length to be the image of a frame");
 fi;
 d:=Dimension(pg);
 vlist:=List(image,x->x!.obj);
 mat:=List([1..d+1],i->vlist[i]);
 coeffs:=vlist[d+2]*(mat^-1);
 mat2:=List([1..d+1],i->coeffs[i]*mat[i]);
 return CollineationOfProjectiveSpace(mat2,pg!.basefield);
end );

###################################################################
# Some operations for elements (without and with frobenius automorphism
###################################################################

# CHECKED 5/09/11 jdb
#############################################################################
#O  MatrixOfCollineation( <c> )
# returns the underlying matrix of <c> 
##
InstallMethod( MatrixOfCollineation, [ IsProjGrpEl and IsProjGrpElRep],
 c -> c!.mat );

# CHECKED 5/09/11 jdb
#############################################################################
#O  MatrixOfCollineation( <c> )
# returns the underlying matrix of <c> 
##  
InstallMethod( MatrixOfCollineation, [ IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
 c -> c!.mat );
  
# CHECKED 5/09/11 jdb
#############################################################################
#O  FieldAutomorphism( <c> )
# returns the underlying field automorphism of <c> 
##  
InstallMethod( FieldAutomorphism, [ IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
 c -> c!.frob );

# CHECKED 5/09/11 jdb
#############################################################################
#O  Representative( <el> )
# returns the underlying matrix of the projectivity <el> 
##  
InstallOtherMethod( Representative, 
 "for a projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
  return el!.mat;
 end );

# CHECKED 5/09/11 jdb
#############################################################################
#O  BaseField( <el> )
# returns the underlying field of <el> 
##  
InstallMethod( BaseField, 
 "for a projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
  return el!.fld;
 end );

# CHECKED 5/09/11 jdb
#############################################################################
#O  Representative( <el> )
# returns the underlying matrix and frobenius automorphism of the projective 
# semilinear element <el> 
## 
InstallOtherMethod( Representative, 
 "for a projective group element with Frobenius",
 [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
 function( el )
  return [el!.mat,el!.frob];
 end );

# CHECKED 5/09/11 jdb
#############################################################################
#O  BaseField( <el> )
# returns the underlying field of <el> 
##  
InstallMethod( BaseField, 
 "for a projective group element with Frobenius",
 [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
 function( el )
  return el!.fld;
 end );

# CHECKED 5/09/11 jdb
###################################################################
# View, print and display methods for elements (without and with Frobenius)
###################################################################

InstallMethod( ViewObj, "for a projective group element",
  [IsProjGrpEl and IsProjGrpElRep],
  function(el)
    Print("<projective element ");
    ViewObj(el!.mat);
    Print(">");
  end);

InstallMethod( Display, "for a projective group element",
  [IsProjGrpEl and IsProjGrpElRep],
  function(el)
    Print("<projective element, underlying matrix:\n");
    Display(el!.mat);
    Print(">\n");
  end );

InstallMethod( PrintObj, "for a projective group element",
  [IsProjGrpEl and IsProjGrpElRep],
  function(el)
    Print("ProjEl(");
    PrintObj(el!.mat);
    Print(")");
  end );
  
InstallMethod( ViewObj, "for a projective group element with Frobenius",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function(el)
    Print("< a collineation: ");
    ViewObj(el!.mat);
    if IsOne(el!.frob) then
        Print(", F^0>");
    else
        Print(", F^",el!.frob!.power,">");
    fi;
  end);

InstallMethod( Display, "for a projective group element with Frobenius",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function(el)
    Print("<a collineation , underlying matrix:\n");
    Display(el!.mat);
    if IsOne(el!.frob) then
        Print(", F^0>\n");
    else
        Print(", F^",el!.frob!.power,">\n");
    fi;
  end );

InstallMethod( PrintObj, "for a projective group element with Frobenius",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function(el)
    Print("ProjElWithFrob(");
    PrintObj(el!.mat);
    Print(",");
    PrintObj(el!.frob);
    Print(")");
  end );

# CHECKED 5/09/11 jdb
###################################################################
# comparing elements (without and with Frobenius automorphism)
###################################################################

InstallMethod( \=, "for two projective group elements",
  [IsProjGrpEl and IsProjGrpElRep, IsProjGrpEl and IsProjGrpElRep],
  function( a, b )
    local aa,bb,p,s,i;
    if a!.fld <> b!.fld then Error("different base fields"); fi;
    aa := a!.mat;
    bb := b!.mat;
    p := PositionNonZero(aa[1]);
    s := bb[1,p] / aa[1,p];
    for i in [1..Length(aa)] do
        if s*aa[i] <> bb[i] then return false; fi;
    od;
    return true;
  end );

InstallMethod(\<,
  [IsProjGrpEl, IsProjGrpEl],
  function(a,b)
    local aa,bb,pa,pb,sa,sb,i,va,vb;
    if a!.fld <> b!.fld then Error("different base fields"); fi;
    aa := a!.mat;
    bb := b!.mat;
    pa := PositionNonZero(aa[1]);
    pb := PositionNonZero(bb[1]);
    if pa > pb then 
        return true;
    elif pa < pb then
        return false;
    fi;
    sa := aa[1,pa]^-1;
    sb := bb[1,pb]^-1;
    for i in [1..Length(aa)] do
        va := sa*aa[i];
        vb := sb*bb[i];
        if va < vb then return true; fi;
        if vb < va then return false; fi;
    od;
    return false;
  end);

InstallMethod( \=, "for two projective group elements with Frobenius",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep,
   IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function( a, b )
    local aa,bb,p,s,i;
    if a!.fld <> b!.fld then Error("different base fields"); fi;
    if a!.frob <> b!.frob then return false; fi;
    aa := a!.mat;
    bb := b!.mat;
    p := PositionNonZero(aa[1]);
    s := bb[1,p] / aa[1,p];
    if s*aa <> bb then return false; fi;
 #for i in [1..Length(aa)] do
        #if s*aa[i] <> bb[i] then return false; fi;
    #od;
    return true;
  end );

InstallMethod(\<,
  [IsProjGrpElWithFrob, IsProjGrpElWithFrob],
  function(a,b)
    local aa,bb,pa,pb,sa,sb,i,va,vb;
    if a!.fld <> b!.fld then Error("different base fields"); fi;
    if a!.frob < b!.frob then
        return true;
    elif b!.frob < a!.frob then
        return false;
    fi;
    aa := a!.mat;
    bb := b!.mat;
    pa := PositionNonZero(aa[1]);
    pb := PositionNonZero(bb[1]);
    if pa > pb then 
        return true;
    elif pa < pb then
        return false;
    fi;
    sa := aa[1,pa]^-1;
    sb := bb[1,pb]^-1;
    for i in [1..Length(aa)] do
        va := sa*aa[i];
        vb := sb*bb[i];
        if va < vb then return true; fi;
        if vb < va then return false; fi;
    od;
    return false; 
  end);

###################################################################
# More operations for elements (without and with frobenius automorphism)
###################################################################

# CHECKED 5/09/11 jdb
#############################################################################
#O  Order( <a> )
# returns the order of <a>. This function relies on ProjectiveOrder.
##  
InstallMethod( Order, 
 "for a projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( a )
  return ProjectiveOrder(a!.mat)[1];
 end );

# CHECKED 5/09/11 jdb
# 22/04/12 jb: There was a bug here. I added "and i mod ofrob = 0;"
# 3/6/2015: bug fixed by jb.
#############################################################################
#O  Order( <a> )
# returns the order of <a>.
## 
InstallMethod( Order, 
 "for a projective group element with Frobenius",
 [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],

# This algorithm could be improved by using the ideas of
# Celler and Leedham-Green.

 function( a )
   local b, frob, bfrob, i, ofrob;
 b := a!.mat;
 frob := a!.frob;
 if IsOne(frob) then 
  return ProjectiveOrder(b)[1];
 fi;
 if not IsOne(b) then
  bfrob := b; i := 1;
  ofrob := Order(frob);
  repeat
   bfrob := bfrob^(frob^-1);  ## JB 3/6/2015: Found bug here
   b := b * bfrob;
   i := i + 1;
  until IsFiningScalarMatrix( b ) and i mod ofrob = 0;
  return i;
 else
  return Order(frob);
 fi;
 return 1;
 end );

# CHECKED 5/09/11 jdb
#############################################################################
#O  IsOne( <a> )
# returns true if <a> is the identity.
## 
InstallMethod( IsOne, 
 "for a projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
    local s;
    s := el!.mat[1,1];
    if IsZero(s) then 
  return false; 
 fi;
    s := s^-1;
    return IsOne( s*el!.mat );
 end );

# CHECKED 5/09/11 jdb
#############################################################################
#O  IsOne( <a> )
# returns true if <a> is the identity
## 
InstallMethod( IsOne, 
 "for a projective group element with Frobenius",
 [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
 function( el )
    local s;
    if not(IsOne(el!.frob)) then 
  return false; 
 fi;
    s := el!.mat[1,1];
    if IsZero(s) then return false; fi;
    s := s^-1;
    return IsOne( s*el!.mat );
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  DegreeFFE( <el> )
# for projectivities. returns the degree of the underlying field over its 
# prime field.
## 
InstallOtherMethod( DegreeFFE, 
 "for projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
  return DegreeOverPrimeField( el!.fld );
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  DegreeFFE( <el> )
# for projective collineation maps. returns the degree of the underlying 
# field over its prime field.
## 
InstallOtherMethod( DegreeFFE, 
 "for projective group element with Frobenius",
 [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
 function( el )
  return DegreeOverPrimeField( el!.fld );
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  Characteristic( <el> )
# for projectivities. returns the characteristic of the underlying field.
## 
InstallMethod( Characteristic, 
 "for projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
  return Characteristic( el!.fld );
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  Characteristic( <el> )
# for projective collineation maps. returns the characteristic of the underlying field.
## 
InstallMethod( Characteristic, 
 "for projective group element with Frobenius",
 [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
 function( el )
  return Characteristic( el!.fld );
 end );

###################################################################
# The things that make it a group :-) (without Frobenius)
###################################################################

# CHECKED 5/09/11 jdb
#############################################################################
#O  \*( <a>, <b> )
# returns a*b, for IsProjGrpEl
## 
InstallMethod( \*, 
 "for two projective group elements",
 [IsProjGrpEl and IsProjGrpElRep, IsProjGrpEl and IsProjGrpElRep],
 function( a, b )
  local el;
  el := rec( mat := a!.mat * b!.mat, fld := a!.fld );
  Objectify( ProjElsType, el );
  return el;
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  InverseSameMutability( <el> )
# returns el^-1, for IsProjGrpEl, keeps mutability.
## 
InstallMethod( InverseSameMutability, 
 "for a projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
  local m;
  m := rec( mat := InverseSameMutability(el!.mat), fld := el!.fld );
  Objectify( ProjElsType, m );
  return m;
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  InverseMutable( <el> )
# returns el^-1 (mutable) for IsProjGrpEl
## 
InstallMethod( InverseMutable, 
 "for a projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
  local m;
  m := rec( mat := InverseMutable(el!.mat), fld := el!.fld );
  Objectify( ProjElsType, m );
  return m;
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  OneImmutable( <el> )
# returns immutable one of the group of <el>
## 
InstallMethod( OneImmutable, 
 "for a projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
  local o;
  o := rec( mat := OneImmutable( el!.mat ), fld := el!.fld );
  Objectify( NewType(FamilyObj(el), IsProjGrpElRep), o );
  return o;
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  OneSameMutability( <el> )
# returns one of the group of <el> with same mutability of <el>.
## 
InstallMethod( OneSameMutability, 
 "for a projective group element",
 [IsProjGrpEl and IsProjGrpElRep],
 function( el )
  local o;
  o := rec( mat := OneImmutable( el!.mat ), fld := el!.fld );
  Objectify( NewType(FamilyObj(el), IsProjGrpElRep), o );
  return o;
 end );

###################################################################
# The things that make it a group :-) (with Frobenius)
###################################################################
# we first need: 
#################################################
# Frobenius automorphisms and groups using them:
#################################################
#12 CHECKED 6/09/11 jdb

InstallOtherMethod( \^, "for a FFE vector and a Frobenius automorphism",
  [ IsVector and IsFFECollection and IsMutable, IsFrobeniusAutomorphism ],
  function( v, f )
    return List(v,x->x^f);
  end );

#cvec version
InstallOtherMethod( \^, "for a cvec/FFE vector and a Frobenius automorphism",
  [ IsCVecRep and IsFFECollection and IsMutable, IsFrobeniusAutomorphism ],
  function( v, f )
    return CVec(List(v,x->x^f),BaseField(v));
  end );

InstallOtherMethod( \^, "for a FFE vector and a Frobenius automorphism",
  [ IsVector and IsFFECollection, IsFrobeniusAutomorphism ],
  function( v, f )
    return MakeImmutable(List(v,x->x^f));
  end );

#cvec version
InstallOtherMethod( \^, "for a cvec/FFE vector and a Frobenius automorphism",
  [ IsCVecRep and IsFFECollection, IsFrobeniusAutomorphism ],
  function( v, f )
    return MakeImmutable(CVec(List(v,x->x^f),BaseField(v)));
  end );

#we think that this method is not needed, worse, should not be used.
#InstallOtherMethod( \^, 
#  "for a mutable FFE vector and a trivial Frobenius automorphism",
#  [ IsVector and IsFFECollection and IsMutable, IsMapping and IsOne ],
#  function( v, f )
#    return v;
#  end );

#cvec version
#InstallOtherMethod( \^, 
#  "for a mutable cvec/FFE vector and a trivial Frobenius automorphism",
#  [ IsCVecRep and IsFFECollection and IsMutable, IsMapping and IsOne ],
#  function( v, f )
#    return v;
#  end );
  
InstallOtherMethod( \^, 
  "for a mutable FFE vector and a trivial Frobenius automorphism",
  [ IsVector and IsFFECollection and IsMutable, IsMapping and IsOne ],
  function( v, f )
    return ShallowCopy(v);
  end );
  
#cvec version
InstallOtherMethod( \^, 
  "for a mutable cvec/FFE vector and a trivial Frobenius automorphism",
  [ IsCVecRep and IsFFECollection and IsMutable, IsMapping and IsOne ],
  function( v, f )
    return ShallowCopy(v);
  end );

#the next operations until the matrix section, the methods will become obsolete as soon as fining is cvec'ed.
  
InstallOtherMethod( \^, 
  "for a compressed GF2 vector and a Frobenius automorphism",
  [ IsVector and IsFFECollection and IsGF2VectorRep, IsFrobeniusAutomorphism ],
  function( v, f )
    local w;
    w := List(v,x->x^f);
    ConvertToVectorRepNC(w,2);
    return MakeImmutable(w);
  end );

InstallOtherMethod( \^, 
  "for a mutable compressed GF2 vector and a Frobenius automorphism",
  [ IsVector and IsFFECollection and IsGF2VectorRep and IsMutable, 
    IsFrobeniusAutomorphism ],
  function( v, f )
    local w;
    w := List(v,x->x^f);
    ConvertToVectorRepNC(w,2);
    return w;
  end );

InstallOtherMethod( \^, 
  "for a compressed GF2 vector and a trivial Frobenius automorphism",
  [ IsVector and IsFFECollection and IsGF2VectorRep, IsMapping and IsOne ],
  function( v, f )
    return v;
  end );

InstallOtherMethod( \^, 
  "for a mutable compressed GF2 vector and a trivial Frobenius automorphism",
  [ IsVector and IsFFECollection and IsGF2VectorRep and IsMutable, 
    IsMapping and IsOne ],
  function( v, f )
    return ShallowCopy(v);
  end );

InstallOtherMethod( \^, 
  "for a compressed 8bit vector and a Frobenius automorphism",
  [ IsVector and IsFFECollection and Is8BitVectorRep, IsFrobeniusAutomorphism ],
  function( v, f )
    local w;
    w := List(v,x->x^f);
    ConvertToVectorRepNC(w,Q_VEC8BIT(v));
    return MakeImmutable(w);
  end );

InstallOtherMethod( \^, 
  "for a mutable compressed 8bit vector and a Frobenius automorphism",
  [ IsVector and IsFFECollection and Is8BitVectorRep and IsMutable, 
    IsFrobeniusAutomorphism ],
  function( v, f )
    local w;
    w := List(v,x->x^f);
    ConvertToVectorRepNC(w,Q_VEC8BIT(v));
    return w;
  end );

InstallOtherMethod( \^, 
  "for a compressed 8bit vector and a trivial Frobenius automorphism",
  [ IsVector and IsFFECollection and Is8BitVectorRep, IsMapping and IsOne ],
  function( v, f )
    return v;
  end );

InstallOtherMethod( \^, 
  "for a mutable compressed 8bit vector and a trivial Frobenius automorphism",
  [ IsVector and IsFFECollection and Is8BitVectorRep and IsMutable, 
    IsMapping and IsOne ],
  function( v, f )
    return ShallowCopy(v);
  end );

#### matrix methods

InstallOtherMethod( \^, "for a FFE matrix and a Frobenius automorphism",
  [ IsMatrix and IsFFECollColl, IsFrobeniusAutomorphism ],
  function( m, f )
    return MakeImmutable(List(m,v->List(v,x->x^f)));
  end );

#cmat
InstallOtherMethod( \^, "for a FFE matrix and a Frobenius automorphism",
  [ IsCMatRep and IsFFECollColl, IsFrobeniusAutomorphism ],
  function( m, f )
    return MakeImmutable(CMat(List(m,v->v^f)));
  end );  
  
#InstallOtherMethod( \^, "for a FFE matrix and a Frobenius automorphism",
#  [ IsMatrix and IsFFECollColl, IsFrobeniusAutomorphism ],
#  function( m, f )
#    return MakeImmutable(List(m,v->List(v,x->x^f)));
#  end );
  
InstallOtherMethod( \^, "for a mutable FFE matrix and a Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and IsMutable, IsFrobeniusAutomorphism ],
  function( m, f )
    return List(m,v->List(v,x->x^f));
  end );

#cmat
InstallOtherMethod( \^, "for a mutable FFE matrix and a Frobenius automorphism",
  [ IsCMatRep and IsFFECollColl and IsMutable, IsFrobeniusAutomorphism ],
  function( m, f )
    return CMat(List(m,v->v^f));
  end );

InstallOtherMethod( \^, "for a FFE matrix and a trivial Frobenius automorphism",
  [ IsMatrix and IsFFECollColl, IsMapping and IsOne ],
  function( m, f )
    return m;
  end );

#cmat
InstallOtherMethod( \^, "for a FFE matrix and a trivial Frobenius automorphism",
  [ IsCMatRep and IsFFECollColl and IsMutable, IsMapping and IsOne ],
  function( m, f )
    return ShallowCopy(m);
  end );

InstallOtherMethod( \^, 
  "for a mutable FFE matrix and a trivial Frobenius automorphism",
  [ IsMatrix and IsFFECollColl, IsMapping and IsOne ],
  function( m, f )
    return MutableCopyMat(m);
  end );

#cmat  
InstallOtherMethod( \^, "for a FFE matrix and a trivial Frobenius automorphism",
  [ IsCMatRep and IsFFECollColl , IsMapping and IsOne ],
  function( m, f )
    return MakeImmutable(ShallowCopy(m));
  end );

#the next matrix methods will become obsolete.

InstallOtherMethod( \^, 
  "for a compressed GF2 matrix and a Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and IsGF2MatrixRep, IsFrobeniusAutomorphism ],
  function( m, f )
    local w,l,i;
    l := [];
    for i in [1..NrRows(m)] do
        w := List(m[i],x->x^f);
        ConvertToVectorRepNC(w,2);
        Add(l,w);
    od;
    ConvertToMatrixRepNC(l,2);
    return MakeImmutable(l);
  end );

InstallOtherMethod( \^, 
  "for a mutable compressed GF2 matrix and a Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and IsGF2MatrixRep and IsMutable, 
    IsFrobeniusAutomorphism ],
  function( m, f )
    local w,l,i;
    l := [];
    for i in [1..NrRows(m)] do
        w := List(m[i],x->x^f);
        ConvertToVectorRepNC(w,2);
        Add(l,w);
    od;
    ConvertToMatrixRepNC(l,2);
    return l;
  end );

InstallOtherMethod( \^, 
  "for a compressed GF2 matrix and a trivial Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and IsGF2MatrixRep, IsMapping and IsOne ],
  function( m, f )
    return m;
  end );

InstallOtherMethod( \^, 
  "for a mutable compressed GF2 matrix and a trivial Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and IsGF2MatrixRep and IsMutable, 
    IsMapping and IsOne ],
  function( m, f )
    return MutableCopyMat(m);
  end );

InstallOtherMethod( \^, 
  "for a compressed 8bit matrix and a Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and Is8BitMatrixRep, IsFrobeniusAutomorphism ],
  function( m, f )
    local w,l,i,q;
    l := [];
    q := Q_VEC8BIT(m[1]);
    for i in [1..NrRows(m)] do
        w := List(m[i],x->x^f);
        ConvertToVectorRepNC(w,q);
        Add(l,w);
    od;
    ConvertToMatrixRepNC(l,q);
    return MakeImmutable(l);
  end );

InstallOtherMethod( \^, 
  "for a mutable compressed 8bit matrix and a Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and Is8BitMatrixRep and IsMutable, 
    IsFrobeniusAutomorphism ],
  function( m, f )
    local w,l,i,q;
    l := [];
    q := Q_VEC8BIT(m[1]);
    for i in [1..NrRows(m)] do
        w := List(m[i],x->x^f);
        ConvertToVectorRepNC(w,q);
        Add(l,w);
    od;
    ConvertToMatrixRepNC(l,q);
    return MakeImmutable(l);
  end );

InstallOtherMethod( \^, 
  "for a compressed 8bit matrix and a trivial Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and Is8BitMatrixRep, IsMapping and IsOne ],
  function( m, f )
    return m;
  end );

InstallOtherMethod( \^, 
  "for a mutable compressed 8bit matrix and a trivial Frobenius automorphism",
  [ IsMatrix and IsFFECollColl and Is8BitMatrixRep and IsMutable, 
    IsMapping and IsOne ],
  function( m, f )
    return MutableCopyMat(m);
  end );


# CHECKED 6/09/11 jdb
#############################################################################
#O  \*( <a>, <b> )
# returns a*b, for IsProjGrpElWithFrob
## 
#made a change, added ^-1 on march 8 2007, J&J
InstallMethod( \*, "for two projective group element with Frobenious",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep,
   IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function( a, b )
    local el;
    el := rec( mat := a!.mat * (b!.mat^(a!.frob^-1)), fld := a!.fld, 
               frob := a!.frob * b!.frob );
    Objectify( ProjElsWithFrobType, el);
    return el;
  end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  InverseSameMutability( <el> )
# returns el^-1, for IsProjGrpElWithFrob, keeps mutability.
## 
#found a bug 23/09/08 in st. andrews.
#J&J feel a great relief.
#C&P too.
#all after Max concluded that there was a big bug.
InstallMethod( InverseSameMutability, 
  "for a projective group element with Frobenius",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function( el )
    local m,f;
    f := el!.frob;
    m := rec( mat := (InverseSameMutability(el!.mat))^f, fld := el!.fld,
              frob := f^-1 );
    Objectify( ProjElsWithFrobType, m );
    return m;
  end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  InverseMutable( <el> )
# returns mutable el^-1, for IsProjGrpElWithFrob
## 
InstallMethod( InverseMutable, 
  "for a projective group element with Frobenius",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function( el )
    local m,f;
    f := el!.frob;
    m := rec( mat := (InverseMutable(el!.mat))^f, fld := el!.fld,
              frob := f^-1 );
    Objectify( ProjElsWithFrobType, m );
    return m;
  end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  OneImmutable( <el> )
# returns immutable one of the group of <el>
## 
InstallMethod( OneImmutable, "for a projective group element with Frobenius",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function( el )
    local o;
    o := rec( mat := OneImmutable( el!.mat ), fld := el!.fld,
              frob := el!.frob^0 );
    Objectify( ProjElsWithFrobType, o);
    return o;
  end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  OneSameMutability( <el> )
# returns one of the group of <el> with same mutability
## 
InstallMethod( OneSameMutability, 
  "for a projective group element with Frobenius",
  [IsProjGrpElWithFrob and IsProjGrpElWithFrobRep],
  function( el )
    local o;
    o := rec( mat := OneImmutable( el!.mat ), fld := el!.fld,
              frob := el!.frob^0 );
    Objectify( ProjElsWithFrobType, o);
    return o;
  end );

###################################################################
# General methods to deal with projective groups.
# Construction of (projective) groups is done in the appropriate files
# that deal with geometries.
###################################################################

# 10 CHECKED 6/09/11 jdb
###################################################################
# View, print and display methods for projective groups 
# (without and with Frobenius)
###################################################################


#InstallMethod( ViewObj, 
# "for a projective group",
# [IsProjectivityGroup],
# function( g )
#  Print("<projective group>");
# end );
#
#InstallMethod( ViewObj, 
# "for a trivial projective group",
# [IsProjectivityGroup and IsTrivial],
# function( g )
#  Print("<trivial projective group>");
# end );
#
#InstallMethod( ViewObj, 
# "for a projective group with gens",
# [IsProjectivityGroup and HasGeneratorsOfGroup],
# function( g )
#  local gens;
#  gens := GeneratorsOfGroup(g);
#  if Length(gens) = 0 then
#   Print("<trivial projective group>");
#  else
#   Print("<projective group with ",Length(gens),
 #             " generators>");
#  fi;
# end );
#
#InstallMethod( ViewObj, 
# "for a projective group with size",
# [IsProjectivityGroup and HasSize],
# function( g )
#  if Size(g) = 1 then
#   Print("<trivial projective group>");
#  else
#   Print("<projective group of size ",Size(g),">");
#  fi;
# end );
#
#InstallMethod( ViewObj, 
# "for a projective group with gens and size",
# [IsProjectivityGroup and HasGeneratorsOfGroup and HasSize],
# function( g )
#  local gens;
#  gens := GeneratorsOfGroup(g);
#  if Length(gens) = 0 then
#   Print("<trivial projective group>");
#  else
#   Print("<projective group of size ",Size(g)," with ",
 #             Length(gens)," generators>");
#  fi;
# end );
 
InstallMethod( ViewObj, 
 "for a projective collineation group",
 [IsProjectiveGroupWithFrob],
 function( g )
  Print("<projective collineation group>");
 end );

InstallMethod( ViewObj, 
 "for a trivial projective collineation group",
 [IsProjectiveGroupWithFrob and IsTrivial],
 function( g )
  Print("<trivial projective collineation group>");
 end );

InstallMethod( ViewObj, 
 "for a projective collineation group with gens",
 [IsProjectiveGroupWithFrob and HasGeneratorsOfGroup],
 function( g )
  local gens;
  gens := GeneratorsOfGroup(g);
  if Length(gens) = 0 then
   Print("<trivial projective collineation group>");
  else
   Print("<projective collineation group with ",Length(gens),
              " generators>");
  fi;
 end );

InstallMethod( ViewObj, 
 "for a projective collineation group with size",
 [IsProjectiveGroupWithFrob and HasSize],
 function( g )
  if Size(g) = 1 then
   Print("<trivial projective collineation group>");
  else
   Print("<projective collineation group of size ",Size(g),">");
  fi;
 end );

InstallMethod( ViewObj, 
 "for a projective collineation group with gens and size",
 [IsProjectiveGroupWithFrob and HasGeneratorsOfGroup and HasSize],
 function( g )
  local gens;
  gens := GeneratorsOfGroup(g);
  if Length(gens) = 0 then
   Print("<trivial projective collineation group>");
  else
   Print("<projective collineation group of size ",Size(g)," with ",
              Length(gens)," generators>");
  fi;
 end );


###################################################################
# Some operations for projective groups (without and with frobenius automorphism)
###################################################################

# CHECKED 6/09/11 jdb
#############################################################################
#O  BaseField( <g> )
# returns the base field of the projective group <g>
## 


# ml 07/11/2012: I have taken out the view, print and display methods
# for projectivity groups, since these are also collineation groups in FinInG
#InstallMethod( BaseField, 
# "for a projective group",
# [IsProjectivityGroup],
# function( g )
#  local f,gens;
#  if IsBound(g!.basefield) then
#   return g!.basefield;
#  fi;
#  if HasParent(g) then
#   f := BaseField(Parent(g));
#   g!.basefield := f;
#   return f;
#  fi;
 #   # Now start to investigate:
#  gens := GeneratorsOfGroup(g);
#  if Length(gens) > 0 then
#   g!.basefield := gens[1]!.fld;
#   return g!.basefield;
#  fi;
 #   # Now we have to give up:
#  Error("base field could not be determined");
# end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  BaseField( <g> )
# returns the base field of the projective collineation group <g>
## 
InstallMethod( BaseField, 
 "for a projective collineation group",
 [IsProjectiveGroupWithFrob],
 function( g )
  local f,gens,P;
  if IsBound(g!.basefield) then
   return g!.basefield;
  fi;
  # This if statement can cause an infinite loop!
  if HasParent(g) then  # JB 22/03/2014
   P := Parent(g);
   if IsBound(P!.basefield) then
    f := P!.basefield;
    g!.basefield := f;
    return f;
   fi;
  fi;
    # Now start to investigate:
  gens := GeneratorsOfGroup(g);
  if Length(gens) > 0 then
   g!.basefield := gens[1]!.fld;
   return g!.basefield;
  elif IsTrivial(g) then    #JB: 22/03/2014: The trivial group with no generators slipped through.
   g!.basefield := One(g)!.fld;
   return g!.basefield;
  fi;
    
    # Now we have to give up:
  Error("base field could not be determined");
 end );
 
# TO DO (22/03/2014): We ought to set the basefield on creating collineation groups.

# CHECKED 6/09/11 jdb
#############################################################################
#O  Dimension( <g> )
# returns the dimension of the projective group <g>. The dimension of this 
# group is defined as the vector space dimension of the projective space  
# of which <g> was defined as a projective group, or, in other words, as the 
# size of the matrices.
## 

# ml 07/11/2012: I have taken out the view, print and display methods
# for projectivity groups, since these are also collineation groups in FinInG

#InstallMethod( Dimension, 
# "for a projective group",
# [IsProjectivityGroup],
# function( g )
#  local gens;
#  if HasParent(g) then
#   return Dimension(Parent(g));
#  fi;
 #   # Now start to investigate:
#  gens := GeneratorsOfGroup(g);
#  if Length(gens) > 0 then
#   return NrRows(gens[1]!.mat);
#  fi;
#  Error("dimension could not be determined");
# end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  Dimension( <g> )
# returns the dimension of the projective collineation group <g>. The dimension of this 
# group is defined as the vector space dimension of the projective space  
# of which <g> was defined as a projective group, or, in other words, as the 
# size of the matrices.
## 
InstallMethod( Dimension, 
 "for a projective collineation group",
 [IsProjectiveGroupWithFrob],
 function( g )
  local gens;
  if HasParent(g) and HasDimension(Parent(g)) then #JB: 22/03/2014: Made sure the parent had a dimension first
   return Dimension(Parent(g));
  fi;
    # Now start to investigate:
  gens := GeneratorsOfGroup(g);
  if Length(gens) > 0 then
   return NrRows(gens[1]!.mat);
  elif IsTrivial(g) then    #JB: 22/03/2014: The trivial group with no generators slipped through.
    return NrRows(One(g)!.mat);
  fi;
  Error("dimension could not be determined");
 end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  OneImmutable( <g> )
# returns an immutable one of the projectivity group <g>
## 
# ml 07/11/2012: I have taken out the view, print and display methods
# for projectivity groups, since these are also collineation groups in FinInG

#InstallMethod( OneImmutable, 
# "for a projective group",
# # was: [IsGroup and IsProjectivityGroup], I think might be
# [IsProjectivityGroup],
# function( g )
#  local gens, o;
#  gens := GeneratorsOfGroup(g);
#  if Length(gens) = 0 then
#   if HasParent(g) then
#    gens := GeneratorsOfGroup(Parent(g));
#   else
#    Error("sorry, no generators, no one");
#   fi;
#  fi;
#  o := rec( mat := OneImmutable( gens[1]!.mat ), fld := gens[1]!.fld );
#  Objectify( NewType(FamilyObj(gens[1]), IsProjGrpElRep), o );
#  return o;
# end );

# CHECKED 6/09/11 jdb
#############################################################################
#O  OneImmutable( <g> )
# returns immutable one of the projective collineation group <g>
## 
InstallMethod( OneImmutable, 
 "for a projective collineation group",
 # was [IsGroup and IsProjectiveGroupWithFrob], I think might be
 [IsProjectiveGroupWithFrob],
 function( g )
  local gens, o;
  gens := GeneratorsOfGroup(g);
  if Length(gens) = 0 then
   if HasParent(g) and HasOneImmutable(Parent(g)) then # JB 22/03/2014
    gens := GeneratorsOfGroup(Parent(g));
   else
    Error("sorry, no generators, no one");
   fi;
  fi;
  o := rec( mat := OneImmutable( gens[1]!.mat ), fld := BaseField(g),
    frob := gens[1]!.frob^0 );
  Objectify( ProjElsWithFrobType, o);
  return o;
 end );

###################################################################
# All about actions. But low level stuff. In each appropriate files
# for particular geometries, user-friendly action functions must be
# provided.
###################################################################

# CHECKED 6/09/11 jdb
#############################################################################
#P  CanComputeActionOnPoints( <g> )
# is set true if we consider the computation of the action feasible.
# for projective groups.
##
# ml 07/11/2012: I have taken out the view, print and display methods
# for projectivity groups, since these are also collineation groups in FinInG
 
#InstallMethod( CanComputeActionOnPoints, 
# "for a projective group",
# [IsProjectivityGroup],
# function( g )
#  local d,q;
#  d := Dimension( g );
#  q := Size( BaseField( g ) );
#  if (q^d - 1)/(q-1) > FINING.LimitForCanComputeActionOnPoints then
#   return false;
#  else
#   return true;
#  fi;
# end );
  
# CHECKED 6/09/11 jdb
#############################################################################
#P  CanComputeActionOnPoints( <g> )
# is set true if we consider the computation of the action feasible.
# for projective collineation groups.
## 
InstallMethod( CanComputeActionOnPoints, 
 "for a projective group with frob",
 [IsProjectiveGroupWithFrob],
 function( g )
  local d,q;
  d := Dimension( g );
  q := Size( BaseField( g ) );
  if (q^d - 1)/(q-1) > FINING.LimitForCanComputeActionOnPoints then
   return false;
  else
   return true;
  fi;
 end );
  
###################################################################
# Action functions for projective groups and projective collineation
# groups. The four action functions here are low level and not 
# intended for the user.
###################################################################

# CHECKED 6/09/11 jdb
#############################################################################
#F  OnProjPoints( <line>, <el> )
# computes <line>^<el> where this action is the "natural" one, and <line> represents
# a projective point. We called it line, since this functions relies on the Gap action
# function OnLines, which is the "natural" actions of a matrix on a vector line.
# Important: despite its natural name, this function is *not* intended for the user.
# <line>: just a row vector, representing a vector line
# <el>: a projective group element (so a projectivity, *not* a projective collineation element.
# normalizing the result is handled by the Gap function OnLines. This function assumes that 
# the input vector is also normalized (says the GAP manual). This became reality on september 19, 2011 :-)
## 
InstallGlobalFunction( OnProjPoints,
 function( line, el )
  return OnLines(line,el!.mat);
 end );

# CHECKED 6/09/11 jdb
# CHANGED 19/09/2011 jdb + ml
# can be shortened if you use that OnLines normalizes the result.
#############################################################################
#F  OnProjPointsWithFrob( <line>, <el> )
# computes <line>^<el> where this action is the "natural" one, and <line> represents
# a projective point. This function relies on the GAP function OnLines (see above),
# the result is hence normalized
# Important: despite its natural name, this function is *not* intended for the user.
# <line>: just a row vector, representing a projective point.
# <el>: a projective collineation element 
## 
InstallGlobalFunction( OnProjPointsWithFrob,
  function( line, el )
    local vec,c;
#    vec := OnPoints(line,el!.mat)^el!.frob;
    vec := OnLines(line,el!.mat)^el!.frob;
    #c := PositionNonZero(vec);
    #if c <= Length( vec )  then
#        if not(IsMutable(vec)) then
#   vec := ShallowCopy(vec);
#        fi;
#        MultVector(vec,Inverse( vec[c] ));
#    fi;
    return vec;
 end );

# CHECKED 6/09/11 jdb
# CHANGED 19/09/2011 jdb + ml
# CHANGED 20/09/2011 jdb + ml (SemiEchelonMat -> EchelonMat).
#############################################################################
#F  OnProjSubspacesNoFrob( <subspace>, <el> )
# computes <subspace>^<el> where this action is the "natural" one, and <subspace> represents
# a projective subspace. This function relies on the GAP action function
# OnSubspacesByCanonicalBasis. This function assumes as arguments a list (mat) of linearly 
# independent row vectors, in Hermite normal form (triangulied), and return the 
# mat*<el> in Hermite normal form. To be used in user action functions, we EchelonMat it, so that
# the output can be used directly in a Wrap.
# Important: despite its natural name, this function is *not* intended for the user.
# <el>: a projective group element (so a projectivity, *not* a projective collineation element.
## 
InstallGlobalFunction( OnProjSubspacesNoFrob,
 function( matrix, el )
  # matrix is a matrix containing the basis vectors of some subspace.
  local mat;
  mat := TriangulizeMat(OnSubspacesByCanonicalBasis(matrix,el!.mat));
  return mat;
  #return EchelonMat(OnSubspacesByCanonicalBasis(matrix,el!.mat)).vectors;
 end );

# CHECKED 6/09/11 jdb
# CHANGED 19/09/2011 jdb + ml
# CHANGED 20/09/2011 jdb + ml (SemiEchelonMat -> EchelonMat).
#############################################################################
#F  OnProjSubspacesWithFrob( <subspace>, <el> )
# computes <subspace>^<el> where this action is the "natural" one, and <subspace> represents
# a projective subspace. This function relies on the GAP action function
# OnRight, which computs the action of a matrix on a sub vector space. Here we have to rely on 
# OnRight, and so we have to EchelonMat afterwards.
--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet)  ]