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


Quelle  subgeometries.gi   Sprache: unbekannt

 
Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

##############################################################################
##
##  subgeometries.gi        FinInG package
##                                                              John Bamberg
##                                                              Anton Betten
##                                                              Jan De Beule
##                                                             Philippe Cara
##                                                            Michel Lavrauw
##                                                           Max Neunhoeffer
##
##  Copyright 2020 Colorado State University, Fort Collins
##     Università degli Studi di Padova
##     University of St. Andrews
##     University of Western Australia, Perth
##                  Vrije Universiteit Brussel
##
##
##  Implementation stuff for subgeometries of projective spaces.
##
#############################################################################

#############################################################################
# already some general comments.
# SubgeometryOfProjectiveSpaceByFrame: creates the user defined sub geometry
# starting from a frame. sub!.projectivity: projectivity mapping the canonical
# sub geometry onto the user defined one.
# sub!.sigma: collineation fixing all elements of the sub geometry.
#
#############################################################################

## View methods
#############################################################################
#O  ViewObj( <pg> )
##
InstallMethod( ViewObj,
    "for a subgeometry of a projective space",
    [ IsSubgeometryOfProjectiveSpace and IsSubgeometryOfProjectiveSpaceRep ],
    function(pg)
        Print("Subgeometry PG(",pg!.dimension,", ",Size(pg!.subfield),") of ",ViewString(pg!.ambientspace));
end );

#############################################################################
#O  ViewString( <pg> )
##
InstallMethod( ViewString,
    "for a subgeometry of projective space",
    [ IsSubgeometryOfProjectiveSpace and IsSubgeometryOfProjectiveSpaceRep ],
    function( pg )
    return Concatenation("Subgeometry PG(",String(pg!.dimension),", ",String(Size(pg!.subfield)),") of ",ViewString(pg!.ambientspace));
end );

## operation to check whether a list of points is a frame of the ambient geometry
# of the points.
#############################################################################
#O  IsFrameOfProjectiveSpace( <list> )
##  change 22/6: IsSomething should return true or false!
InstallMethod( IsFrameOfProjectiveSpace,
    "for a list of points",
    [ IsList ],
    function(list)
    local pg, coll, base, n, i;
    coll:=DuplicateFreeList(List(list,x->AmbientGeometry(x)));
#    coll := Collected(List(list,x->AmbientGeometry(x))); #changed AmbientSpace into AmbientGeometry.
    if Length(coll) > 1 then
        #Error("all elements in <list> lie in the same projective space");
        return false;
    else
#       pg := coll[1][1];
        pg:= coll[1];
    fi;
    coll := Collected(List(list,x->Type(x)));
    if Length(coll) > 1 then
        #Error("all elements in <list> must be points");
        return false;
    elif coll[1][1] <> 1 then
        #Error("all elements in <list> must be points");
        return false;
    fi;
    n := Length(list);
    if n <> ProjectiveDimension(pg) + 2 then
        #Error("<list> does not contain the correct number of points");
        return false;
    fi;
    for i in [1..n] do
        base := list{Difference([1..n],[i])};
        if not Span(base) = pg then
            #Error("<list> is not a frame");
            return false;
        fi;
    od;
    return true;
    end );

#############################################################################
#O  RandomFrameOfProjectiveSpace( <pg> )
#   This method returns a random frame of a projective space
##
InstallMethod( RandomFrameOfProjectiveSpace,
    "for a projective space, and a prime power",
    [ IsProjectiveSpace ],
    function(pg)
    local pts,mat,final,gauge,d,field;
    d := ProjectiveDimension(pg)+1;
    field := BaseField(pg);
    mat := RandomInvertibleMat(d,field);
    pts := List(mat,x->VectorSpaceToElement(pg,x));
    # TODO: start with the standard frame and choose a random projectivity (#ml 18 May 2020)
    gauge := Random(Points(pg));
    while not IsFrameOfProjectiveSpace(Union(pts,[gauge])) do
        gauge := Random(Points(pg));
    od;
    pts := Union(pts,[gauge]);
    return Set(pts);
    end );

## Constructor methods for subgeometries of projective spaces.
# note for the next two methods: it may look strange to put a vectorspace over
# the big field as vectorspace. But this makes sure that incidence can be
# tested between elements of the subgeometry and the ambient geometry.

#############################################################################
#O  CanonicalSubgeometryOfProjectiveSpace( <pg>, <subfield> )
#   This method requires a projective space and a subfield.
# small change on 12/9/16: we added eventually a field .projectivity in the
# returned geometry. From time to time this is useful, e.g. when comparing
# a canonical subgeometry with an arbitrary one, see e.g. code for \=
##
InstallMethod( CanonicalSubgeometryOfProjectiveSpace,
    "for a projective space, and a prime power",
    [ IsProjectiveSpace, IsField and IsFinite],
    function(pg,subfield)
    local geo, subpg, d, frame, ty, em, sigma, h, t, frob, proj;
    if IsSubgeometryOfProjectiveSpace(pg) then
        Error("recursive construction of subgeometries not (yet) possible");
    fi;
    d := ProjectiveDimension(pg);
    h := DegreeOverPrimeField(subfield);
    t := DegreeOverPrimeField(BaseField(pg));
    if not t mod h = 0 then
        Error(" <subfield> is not a subfield of the base field of <pg>");
    elif t = h then #We may consider to return an error here.
        return pg;
    fi;
    subpg := ProjectiveSpace(d,subfield);
    frame := StandardFrame(pg);
    em := NaturalEmbeddingBySubfield(subpg,pg);
    frob := FrobeniusAutomorphism(BaseField(pg))^h;
    sigma := CollineationOfProjectiveSpace(pg,frob);
    proj := CollineationOfProjectiveSpace(IdentityMat(d+1,pg!.basefield),pg!.basefield);
    geo := rec(dimension := d, basefield := pg!.basefield, subfield := subfield, ambientspace := pg, isomorphicsubgeometry := subpg, frame := frame,
        embedding := em, vectorspace := FullRowSpace(pg!.basefield, d+1), sigma := sigma, projectivity := proj );
    ty := NewType( SubgeometriesFamily,
                  IsSubgeometryOfProjectiveSpace and IsSubgeometryOfProjectiveSpaceRep );
    Objectify( ty, geo );
    SetIsCanonicalSubgeometryOfProjectiveSpace(geo, true);
    SetAmbientSpace(geo, pg);
    SetDefiningFrameOfSubgeometry(geo,frame);
    #SetRankAttr(geo,d);
    return geo;
    end );

#############################################################################
#O  SubgeometryOfProjectiveSpaceByFrame( <pg>, <frame>, <subfield> )
#   It is checked whether <frame> is a frame. This operation requires
#   a projective space, a frame of this space, and a subfield.
##
InstallMethod( SubgeometryOfProjectiveSpaceByFrame,
    "for a projective space, and a prime power",
    [ IsProjectiveSpace, IsList, IsField and IsFinite],
    function(pg,frame,subfield)
    local geo, subpg, d, ty, matrix, proj, n, i, vecs, basis, coefs, em, sigma, h, t, frob, can;
    if not IsFrameOfProjectiveSpace(frame) then
        Error(" <frame> must be a frame of <pg>");
    fi;
     if IsSubgeometryOfProjectiveSpace(pg) then
        Error("recursive construction of subgeometries not (yet) possible");
    fi;
    d := ProjectiveDimension(pg);
    h := DegreeOverPrimeField(subfield);
    t := DegreeOverPrimeField(BaseField(pg));
    if not t mod h = 0 then
        Error(" <subfield> is not a subfield of the base field of <pg>");
    elif t = h then #We may consider to return an error here.
        return pg;
    fi;
    subpg := ProjectiveSpace(d,subfield);
    frob := FrobeniusAutomorphism(BaseField(pg))^h;
    if ForAll(frame,y->ForAll(Flat(y!.obj),x->x in subfield)=true) then
        can := true;
        proj := CollineationOfProjectiveSpace(IdentityMat(d+1 ,pg!.basefield),pg!.basefield);
        sigma := CollineationOfProjectiveSpace(pg,frob);
    else
        can := false;
        n:=Size(frame)-1;
        vecs:=List(frame,x->Coordinates(x));
        basis:=Basis(UnderlyingVectorSpace(Span(frame)),vecs{[1..n]});
        coefs:=Coefficients(basis,vecs[n+1]);
        matrix := List([1..n],i->coefs[i]*vecs[i]);
        proj := CollineationOfProjectiveSpace(matrix,BaseField(pg));
        sigma := proj^(-1)*CollineationOfProjectiveSpace(pg,frob)*proj;
    fi;
    em := NaturalEmbeddingBySubfield(subpg,pg);
    geo := rec(dimension := d, basefield := pg!.basefield, subfield := subfield, ambientspace := pg, isomorphicsubgeometry := subpg,
        frame := ShallowCopy(frame), embedding := em, vectorspace := FullRowSpace(pg!.basefield, d+1), sigma := sigma,
        projectivity := proj );
    ty := NewType( SubgeometriesFamily,
                  IsSubgeometryOfProjectiveSpace and IsSubgeometryOfProjectiveSpaceRep );
    Objectify( ty, geo );
    SetAmbientSpace(geo, pg);
    SetIsCanonicalSubgeometryOfProjectiveSpace(geo, can);
    SetDefiningFrameOfSubgeometry(geo,frame);
    #SetRankAttr(geo,d);
    return geo;
    end );

#############################################################################
#O  CanonicalSubgeometryOfProjectiveSpace( <pg>, <q> )
#   shortcut to CanonicalSubgeometryOfProjectiveSpace( <pg>, <GF(<q>))
##
InstallMethod( CanonicalSubgeometryOfProjectiveSpace,
    "for a projective space, and a prime power",
    [ IsProjectiveSpace, IsPosInt],
    function(pg,q)
        return CanonicalSubgeometryOfProjectiveSpace(pg,GF(q));
    end );

#############################################################################
#O  SubgeometryOfProjectiveSpaceByFrame( <pg>, <frame>, <q> )
#   shortcut to SubgeometryOfProjectiveSpaceByFrame( <pg>, <frame>, <GF(<q>))
##
InstallMethod( SubgeometryOfProjectiveSpaceByFrame,
    "for a projective space, and a prime power",
    [ IsProjectiveSpace, IsList, IsPosInt],
    function(pg,frame,q)
        return SubgeometryOfProjectiveSpaceByFrame(pg,frame,GF(q));
    end );

# Basic methods for subgeometries.
#############################################################################

#############################################################################
#O  \=( <sub1>, <sub2> )
# test equality of subgeometries.
# To test equality of two subgeometries, we check whether
# (0) if there ambient space equals, if not, return false
# (1) if (0)=true, then, test equality of their subfields, if not, return false
# (2) if (1)=true, test if one of them is not canonical, if so, check whether they
#      are equal if p*q^1, p, s their respective projectivities,
#      is a collineation over the subfield,
#      note 12/9/16: checking whether all elements of mat belong to the subfield, is
#      too restrictive: we must now first divded mat by the first non-zero element!
# (3) if (2)=false, then both are canonical, and return true.
##
InstallMethod( \=,
    "for two subgeometries of a projective space",
 [ IsSubgeometryOfProjectiveSpace, IsSubgeometryOfProjectiveSpaceRep ],
    function(sub1,sub2)
    local proj1, proj2, res, mat, nz;
    if not AmbientSpace(sub1) = AmbientSpace(sub2) then
        return false;
    elif not sub1!.subfield = sub2!.subfield then
        return false;
    elif IsCanonicalSubgeometryOfProjectiveSpace(sub1) = false or IsCanonicalSubgeometryOfProjectiveSpace(sub2) = false then
        proj1 := sub1!.projectivity;
        proj2 := sub2!.projectivity;
        res := proj1 * proj2^(-1);
        mat := MatrixOfCollineation(res);
        #return ForAll(Flat(mat), x->x in sub1!.subfield); # too restrictive!
        nz := First(Flat(mat),x->x <> Zero(sub1!.basefield));
        return ForAll(Flat(mat), x->x/nz in sub1!.subfield);
    else
        return true;
    fi;
    end );

# The next two methods are necessary, since a subgeometry of a projective space
# is also a projective space. Not installing these methods, would invoke the
# method for \= for two projective spaces if one of the arguments is a subgeometry
# and the other one a projective space not a subgeometry, with an incorrect answer.
#############################################################################
#O  \=( <pg1>, <pg2> )
##
InstallMethod( \=,
 "for two projective spaces",
 [IsSubgeometryOfProjectiveSpace, IsProjectiveSpace],
 function(pg1,pg2);
  return false;
 end );

#############################################################################
#O  \=( <pg1>, <pg2> )
##
InstallMethod( \=,
 "for two projective spaces",
 [IsProjectiveSpace, IsSubgeometryOfProjectiveSpace],
 function(pg1,pg2);
  return false;
 end );

#############################################################################
#O  Rank( <ps> )
# Rank of a subgeometry
##
InstallMethod( Rank,
 "for a projective space",
 [ IsSubgeometryOfProjectiveSpace and IsSubgeometryOfProjectiveSpaceRep ],
 ps -> ps!.dimension
 );

# Note that UnderlyingVectorSpace and BaseField are installed for projective
# spaces and hence, are applicable to subgeometries. See introductory comments
# at top of file, for the "definition" of underlying vectorspace and base field.
#############################################################################
#O  SubfieldOfSubgeometry( <sub> )
# Subfield of subgeometry.
##
InstallMethod( SubfieldOfSubgeometry,
 "for a subgeometry of a projective space",
 [ IsSubgeometryOfProjectiveSpace ],
 sub -> sub!.subfield );

# NEW 31/5/2020 jdb
#############################################################################
#A  StandardFrame( <sub> )
# if the dimension of subgeometry <sub> is n and <sub> is the canonical subgeometry,
# then StandardFrame returns a list of points of <sub> with coordinates
# (1,0,...0), (0,1,0,...,0), ..., (0,...,0,1) and (1,1,...,1). In case <sub> is not the
# canonical subgeometry, the image of these points under sub!.projectivity is returned.
# note that, due to the way we construct subgeometries of projective space,
# this is nothing else than the meet of the points of the defining frame with sub
##
InstallMethod( StandardFrame, 
 "for a subgeometry of a projective space",
 [ IsSubgeometryOfProjectiveSpace ],
 function( sub )
        return List(sub!.frame,x->Meet(sub,x));
 end );

#############################################################################
#A CollineationFixingSubgeometry
# For a subgeometry PG(n,q) in PG(n,q^2), we would call this the Baer involution.
# This is the collineation of PGammaL(n+1,q^t) fixing the subgeometry point wise.
# Its order is t.
##
InstallMethod( CollineationFixingSubgeometry,
 "for a subgeometry of a projective space",
 [ IsSubgeometryOfProjectiveSpace ],
    function(pg)
        return pg!.sigma;
    end );

# Constructor operations for elements and basic operations for elements.
#############################################################################

#############################################################################
#O  Wrap( <geo>, <type>, <o> )
# An almost classical method for Wrap, with <geo> a subgeometry. Note that
# Wrap is not a user operation.
##
InstallMethod( Wrap,
 "for a projective space and an object",
 [ IsSubgeometryOfProjectiveSpace, IsPosInt, IsObject],
 function( geo, type, o )
  local w;
  w := rec( geo := geo, type := type, obj := o );
  Objectify( NewType( SoSoPSFamily, IsElementOfIncidenceStructure and
   IsElementOfIncidenceStructureRep and IsSubspaceOfSubgeometryOfProjectiveSpace ), w );
  return w;
 end );

#############################################################################
#O  VectorSpaceToElementForSubgeometries( <sub>, <obj> )
# Note that a VectorSpaceToElement method must be created for every Lie geometry
# This is a helper operation to simplify the different VectorSpaceToElement
# methods for particular objects.
# It is checked whether the projectivity maps the element of the ambient projective
# space based on <obj> back to and element of the canonical subgeometry. If so,
# the element of the subgeometry based on <obj> is returned.
##
InstallMethod( VectorSpaceToElementForSubgeometries,
 "for a sub geometry of a projective space and an object",
 [ IsSubgeometryOfProjectiveSpace, IsObject],
 function( sub, obj )
        local ambient, element, newelement, proj, subfield, newobj, elements;
     if IsZero(obj) then
        return EmptySubspace(sub);
      fi;
      ambient := sub!.ambientspace;
      element := VectorSpaceToElement(ambient,obj);
      if element = ambient then
          # newobj := Filtered(obj,x->not IsZero(x));
          # elements := List(newobj,x->VectorSpaceToElement(sub,x));
          return sub;
      # else
      #     elements := [element];
      fi;
      if not IsCanonicalSubgeometryOfProjectiveSpace(sub) then
          proj := sub!.projectivity;
          newelement := element^(proj^(-1));
      else
          newelement := element;
      fi;
      subfield := sub!.subfield;
      if not ForAll(Flat(newelement!.obj),a->a in subfield) then
      #if not ForAll( Flat( List(newelements,x->x!.obj ) ), i -> i in subfield) then
          Error( "<obj> does not determine an element in <sub>");
      # elif element = ambient then
      #     return sub;
      else
          return Wrap(sub,element!.type,UnderlyingObject(element));
      fi;
    end);

# Now follow the different methods for VectorSpaceToElement for objects
# of particular type.
#############################################################################
#O  VectorSpaceToElement( <sub>, <v> )
##
InstallMethod( VectorSpaceToElement,
 "for a subgeometry of a projective space and a matrix as plist",
 [IsSubgeometryOfProjectiveSpace, IsPlistRep and IsMatrix],
 function( geom, v )
    return VectorSpaceToElementForSubgeometries(geom,v);
    end );

#############################################################################
#O  VectorSpaceToElement( <sub>, <v> )
##
InstallMethod( VectorSpaceToElement,
 "for a subgeometry of a projective space and a CMatRep",
 [ IsSubgeometryOfProjectiveSpace, IsCMatRep],
 function( geom, v )
 return VectorSpaceToElementForSubgeometries(geom, Unpack(v));
 end );

#############################################################################
#O  VectorSpaceToElement( <sub>, <v> )
##
InstallMethod( VectorSpaceToElement,
 "for a subgeometry of a projective space and a compressed GF(2)-matrix",
 [IsSubgeometryOfProjectiveSpace, IsGF2MatrixRep],
 function( geom, v )
 return VectorSpaceToElementForSubgeometries(geom, Unpack(v));
 end );

#############################################################################
#O  VectorSpaceToElement( <sub>, <v> )
##
InstallMethod( VectorSpaceToElement,
 "for a subgeometry of a projective space and a compressed basis of a vector subspace",
 [IsSubgeometryOfProjectiveSpace, Is8BitMatrixRep],
 function( geom, v )
   return VectorSpaceToElementForSubgeometries(geom, Unpack(v));
    end );

#############################################################################
#O  VectorSpaceToElement( <sub>, <v> )
##
InstallMethod( VectorSpaceToElement,
 "for a subgeometry of a projective space and a row vector as cvec",
 [IsSubgeometryOfProjectiveSpace, IsCVecRep],
 function( geom, v )
   return VectorSpaceToElementForSubgeometries(geom, Unpack(v));
    end );

#############################################################################
#O  VectorSpaceToElement( <sub>, <v> )
##
InstallMethod( VectorSpaceToElement,
 "for a subgeometry of a projective space and a row vector",
 [IsSubgeometryOfProjectiveSpace, IsRowVector],
 function( geom, v )
   return VectorSpaceToElementForSubgeometries(geom, v);
    end );

#############################################################################
#O  VectorSpaceToElement( <sub>, <v> )
##
InstallMethod( VectorSpaceToElement,
 "for a subgeometry of a projective space and an 8-bit vector",
 [IsSubgeometryOfProjectiveSpace, Is8BitVectorRep],
 function( geom, v )
   return VectorSpaceToElementForSubgeometries(geom, Unpack(v));
    end );

#############################################################################
#O \=
# Equality of two subspaces of a subgeometry
# Note that this is a test of mathematical equality: the ambient geometry
# must be equal (so not IsIdenticalObj), and
# the underlying object must be equal. Recall that due to norming the underlying
# object, this is garantueed for two equal subspaces.
##
InstallMethod( \=,
 "for two subspace of subgeometry a projective space",
 [IsSubspaceOfSubgeometryOfProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace],
 function(p1,p2);
  return (p1!.obj = p2!.obj) and (p1!.geo = p2!.geo);
 end );

#############################################################################
#O \=
# Equality of a subspace of a subgeometry and a subspace of a projective space
# returns always false.
##
InstallMethod( \=,
 "for a subspace of subgeometry a projective space and a subspace of a projective space",
 [IsSubspaceOfSubgeometryOfProjectiveSpace, IsSubspaceOfProjectiveSpace],
 function(p1,p2);
  return false;
 end );

#############################################################################
#O \=
# Equality of a subspace of a subgeometry and a subspace of a projective space
# returns always false.
##
InstallMethod( \=,
 "for a subspace of subgeometry a projective space and a subspace of a projective space",
 [IsSubspaceOfProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace],
 function(p1,p2);
  return false;
 end );

#############################################################################
#O UnderlyingVectorSpace
# This operation is defined for subspaces of a projective space. However,
# for subspaces of a subgeometry, which are also subspaces of projective
# spaces, this is mathematically senseless. We have to think about this,
# but currently, we return an error.
##
InstallMethod( UnderlyingVectorSpace,
 "for a subspace of subgeometry of a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace ],
    function(el)
        Error(" <el> is a subspace of a subgeometry of a projective space");
    end );

#InstallMethod( BaseField,
# "for an element of a projective space",
# [IsSubspaceOfProjectiveSpace],
# sub -> sub!.basefield );

#############################################################################
#O ElementsOfIncidenceStructure
# Classical operation for Lie geometries, here for subgeometries of projective
# spaces. Note that for this method, we rely on the isomorphic subgeometry.
##
InstallMethod( ElementsOfIncidenceStructure,
 "for a projective space and an integer",
 [IsSubgeometryOfProjectiveSpace, IsPosInt],
 function( ps, j )
  local r;
  r := Rank(ps);
  if j > r then
   Error("<ps> has no elements of type <j>");
  else
   return Objectify(
   NewType( ElementsCollFamily, IsSubspacesOfSubgeometryOfProjectiveSpace and IsSubspacesOfSubgeometryOfProjectiveSpaceRep ),
    rec( geometry := ps,
     type := j,
     size := Size(Subspaces(ps!.isomorphicsubgeometry!.vectorspace, j))
     )
     );
  fi;
 end);

#############################################################################
#O ExtendElementOfSubgeometry
# Particular method for subspaces of subgeometries: extend a subspace of a
# subgeometry to a subspace of the ambient projective space.
##
InstallMethod( ExtendElementOfSubgeometry,
 "for an element of a subgeometry of a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace ],
 element -> VectorSpaceToElement(AmbientSpace(element),Unpack(UnderlyingObject(element))));


# For elements of Lie geometries, incidence is based on set theoretic containment.
# therefore, a method of \in must be present. Note that we define several
# methods that return Errors if the (sub)geometries are different.
# For Lie geometries, \in is also applicable on subspaces of subgeometries
# and projective spaces.
#############################################################################
#O \in We use ExtendElementOfSubgeometry. Clearly, if the extension of an element
# is contained in the extension of another element, the first element is contained
# in the second in the subgeometry.
##
InstallMethod( \in,
 "for two subspaces of a subgeometry",
 [IsSubspaceOfSubgeometryOfProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace],
    function(x,y)
    if x!.geo = y!.geo then
        return ExtendElementOfSubgeometry(x) in ExtendElementOfSubgeometry(y);
    else
        Error("<x> and <y> do not belong to the same geometry");
    fi;
    end );

#############################################################################
#O \in for a subspace of a subgeometry and a subspace of a projective space.
##
InstallMethod( \in,
 "for a subspace of a subgeometry and a subspace of a projective space",
 [IsSubspaceOfSubgeometryOfProjectiveSpace, IsSubspaceOfProjectiveSpace],
    function(x,y)
        Error("<x> and <y> do not belong to the same geometry");
    end );

#############################################################################
#O \in for a subspace of a projective space and a subspace of a subgeometry.
##
InstallMethod( \in,
 "for a subspace of a projective space and a subspace of a subgeometry",
 [IsSubspaceOfProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace],
    function(x,y)
        Error("<x> and <y> do not belong to the same geometry");
    end );

#############################################################################
#O \in for a subspace of a subgeometry of a projective space and a projective
# space. This is somehow tricky: subgeometries also belong to IsProjectiveSpace
# so the element!.geo = can really occur. The consequence is also that
# an element of a subgeometry is not in the ambient projective space. This
# complies with the basic philosophy of subgeometries.
##
InstallMethod( \in,
 "for an element of a subgeometry of a projective space and a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace, IsProjectiveSpace],
 function( element, ps )
        if element!.geo = ps then
            return true;
        else
            Error(" <element> is not an element of <ps>");
        fi;
    end );

#############################################################################
#O \in( <element>, <ps> )
# for a subspace of a projective space and a subgeometry.
# This is tricky as well: subspaces of subgeometries also belong to
# IsSubspaceOfProjectiveSpace so the element!.geo = ps can occur if the
# element is really a subspace of a subgeometry.
##
InstallMethod( \in,
 "for an element of a subgeometry of a projective space and a projective space",
 [ IsSubspaceOfProjectiveSpace, IsSubgeometryOfProjectiveSpace],
 function( element, ps )
       return element!.geo = ps;
    end );

#############################################################################
#O  Random( <subs> )
# returns a random subspace out of the collection of subspaces of given dimension
# of a subgeometry of a projective space. Note that Random has its own method
# for a collection of subspaces of a given dimension of a projective space.
# We use the isomorphic subgeometry for the method here.
##
InstallMethod( Random,
 "for a collection of subspaces of a subgeometry of a projective space",
 [ IsSubspacesOfSubgeometryOfProjectiveSpace ],
    # chooses a random element out of the collection of subspaces of given
    # dimension of a subgeometry of a projective space
 function( subs )
  local d, pg, w, isom, em, el;
  ## the underlying projective space
  pg := subs!.geometry;
        isom := pg!.isomorphicsubgeometry;
        em := pg!.embedding;
  if not IsInt(subs!.type) then
   Error("The subspaces of the collection need to have the same dimension");
        fi;
  ## the common type of elements of subs
  d := subs!.type;
        el := Random(ElementsOfIncidenceStructure(isom,d))^em;
        if not IsCanonicalSubgeometryOfProjectiveSpace(pg) then
            el := el^pg!.projectivity;
        fi;
        return Wrap(pg,d,UnderlyingObject(el));
        end );

# Span/Meet operations. Note the basic philosophy. We allow a span of two
# subspaces of a subgeometry only if their ambient geometry is the same. So
# having the same ambient space is not sufficient. This is slightly different
# than for e.g. polar spaces.

#############################################################################
#O Span( <x>, <y> )
# for two elements of a subgeometry. We use Embed, then compute the
# span in the ambient space, and then rewrap the result as a subspace of
# the subgeometry. We are sure that if the ambient geometries of
# both subspaces are the same, the result is correct. It is checked whether
# this is true for the input.
##
InstallMethod( Span,
 "for two elements of a subgeometry of a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace,  IsSubspaceOfSubgeometryOfProjectiveSpace],
    function(x,y)
    local z,w,pg,span;
    if x!.geo = y!.geo then
        pg := AmbientSpace(x);
        z := Embed(pg,x);
        w := Embed(pg,y);
        span := Span(z,w);
        if (ProjectiveDimension(span) = ProjectiveDimension(x!.geo)) then
            return x!.geo;
        else
            return Wrap(x!.geo,span!.type,UnderlyingObject(span));
        fi;
    else
        Error( "<x> and <y> do not belong to the same geometry" );
    fi;
    end );

#############################################################################
#O Span( <l> )
# for a homogeneous lis of subspaces of a subgeometry. Note that the necessary
# checks are built in. We rely again on the Span in the ambient space.
# Compare this method with the method for Span for a homogeneous list of
# subspaces of a projective space.
##
InstallMethod( Span,
    "for a homogeneous list of subspaces of a subgeometry of a projective space",
 [ IsHomogeneousList and IsSubspaceOfSubgeometryOfProjectiveSpaceCollection ],
 function( l )
  local list, span, pg, same;
  # first we check that all items in the list belong to the same ambient geometry
  if Length(l)=0 then
   return [];
  elif not Size(AsDuplicateFreeList(List(l,x->AmbientGeometry(x))))=1 then
   Error("The elements in the list do not belong to the same ambient geometry");
  else
            pg := AmbientSpace(l[1]);
            list := List(l,x->Embed(pg,x));
            span := Span(list);
            same := Size(AsDuplicateFreeList(List(l,x->AmbientGeometry(x))))=1;
            if (ProjectiveDimension(span) = ProjectiveDimension(l[1]!.geo)) then
                return l[1]!.geo;
            else
                return Wrap(l[1]!.geo,span!.type,UnderlyingObject(span));
            fi;
        fi;
    end );

#############################################################################
#O Span( <x>, <y> )
# for a subspace of subgeometry and a subspace of a projective space. Simply
# produces an error. But we need to install this method, if not, the method
# for Span for two subspaces of a projective space would return a result which
# makes, in our philosophy of subgeometries, no sense.
##
InstallMethod( Span,
 "for a subspace of a projective space and a subspace of a subgeometry",
 [IsSubspaceOfProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace],
    function(x,y)
        Error("<x> and <y> do not belong to the same geometry");
    end );

#############################################################################
#O Span( <x>, <y> )
# see comment on previous Span method
##
InstallMethod( Span,
 "for a subspace of a subgeometry and a subspace of a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace, IsSubspaceOfProjectiveSpace],
    function(x,y)
        Error("<x> and <y> do not belong to the same geometry");
    end );

#############################################################################
#O Span( <element>, <ps> )
# returns <ps> if it is the ambient geometry of element.
##
InstallMethod( Span,
 "for an element of a subgeometry of a projective space and a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace, IsProjectiveSpace],
 function( element, ps )
        if element!.geo = ps then
            return ps;
        else
            Error( "<element> does not belong to <ps>");
        fi;
    end );

#############################################################################
#O Span( <ps>, <element> )
# returns <ps> if it is the ambient geometry of element.
##
InstallMethod( Span,
 "for a projective space and an element of a subgeometry of a projective space",
 [ IsProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace],
 function( ps, element )
        if element!.geo = ps then
            return ps;
        else
            Error( "<element> does not belong to <ps>");
        fi;
    end );

#############################################################################
#O Meet( <x>, <y> )
# for two elements of a subgeometry. We use Embed, then compute the
# meet in the ambient space, and then rewrap the result as a subspace of
# the subgeometry. We are sure that if the ambient geometries of
# both subspaces are the same, the result is correct. It is checked whether
# this is true for the input.
##
InstallMethod( Meet,
 "for two elements of a subgeometry of a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace,  IsSubspaceOfSubgeometryOfProjectiveSpace],
    function(x,y)
    local z,w,pg,meet;
    if x!.geo = y!.geo then
        pg := AmbientSpace(x);
        z := Embed(pg,x);
        w := Embed(pg,y);
        meet := Meet(z,w);
        if IsEmptySubspace(meet) then
            return EmptySubspace(x!.geo);
        else
            return Wrap(x!.geo,meet!.type,UnderlyingObject(meet));
        fi;
    else
        Error( "<x> and <y> do not belong to the same geometry" );
    fi;
    end );

#############################################################################
#O Meet( <l> )
# for a homogeneous lis of subspaces of a subgeometry. Note that the necessary
# checks are built in. We rely again on the Meet in the ambient space.
# Compare this method with the method for Meet for a homogeneous list of
# subspaces of a projective space.
##
InstallMethod( Meet,
    "for a homogeneous list of subspaces of a subgeometry of a projective space",
 [ IsHomogeneousList and IsSubspaceOfSubgeometryOfProjectiveSpaceCollection ],
 function( l )
  local list, meet, pg, same;
  # first we check that all items in the list belong to the same ambient geometry
  if Length(l)=0 then
   return [];
  elif not Size(AsDuplicateFreeList(List(l,x->AmbientGeometry(x))))=1 then
   Error("The elements in the list do not belong to the same ambient geometry");
  else
            pg := AmbientSpace(l[1]);
            list := List(l,x->Embed(pg,x));
            meet := Meet(list);
            # same := Size(AsDuplicateFreeList(List(l,x->AmbientGeometry(x))))=1;
            if IsEmptySubspace(meet) then
                return EmptySubspace(l[1]!.geo);
            else
                return Wrap(l[1]!.geo,meet!.type,UnderlyingObject(meet));
            fi;
        fi;
    end );

# we might consider to allow slightly more here: e.g. meet of a subspace of
# of subgeometry with a subspace of the ambient space.
#############################################################################
#O Meet( <x>, <y> )
# for a subspace of subgeometry and a subspace of a projective space. Simply
# produces an error. But we need to install this method, if not, the method
# for Meet for two subspaces of a projective space would return a result which
# makes, in our philosophy of subgeometries, no sense.
##
InstallMethod( Meet,
 "for a subspace of a projective space and a subspace of a subgeometry",
 [IsSubspaceOfProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace],
    function(x,y)
        Error("<x> and <y> do not belong to the same geometry");
    end );

InstallMethod( Meet,
 "for a subspace of a subgeometry and a subspace of a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace, IsSubspaceOfProjectiveSpace],
    function(x,y)
        Error("<x> and <y> do not belong to the same geometry");
    end );

#############################################################################
#O Meet( <element>, <ps> )
# returns <element> if <ps> is the ambient geometry of element.
##
InstallMethod( Meet,
 "for an element of a subgeometry of a projective space and a projective space",
 [ IsSubspaceOfSubgeometryOfProjectiveSpace, IsProjectiveSpace],
 function( element, ps )
        if element!.geo = ps then
            return element;
        else
            Error( "<element> does not belong to <ps>");
        fi;
    end );

#############################################################################
#O Meet( <ps>, <element> )
# returns <element> if <ps> is the ambient geometry of element.
##
InstallMethod( Meet,
 "for a projective space and an element of a subgeometry of a projective space",
 [ IsProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace],
 function( ps, element )
        if element!.geo = ps then
            return element;
        else
            Error( "<element> does not belong to <ps>");
        fi;
    end );

#############################################################################
#O Meet( <sub>, <el> )
# for a subgeometry and a subspace of a projective space.
##
#use sigma to compute the intersection of an element of the ambient space
InstallMethod( Meet,
    "for a subgeometry of a projectice space and a subspace of the ambient space",
    [ IsSubgeometryOfProjectiveSpace, IsSubspaceOfProjectiveSpace],
    function( sub, el)
        local sigma,meet;
        if not AmbientSpace(sub) = AmbientGeometry(el) then
            Error( "the ambient space of <sub> is not the ambient geometry of <el>");
        else
            sigma := sub!.sigma;
            meet := Meet(el,el^sigma);
            if not IsEmptySubspace(meet) then
                return Wrap(sub,meet!.type,meet!.obj);
            else
                return EmptySubspace(sub);
            fi;
        fi;
    end );

#############################################################################
#O Meet( <sub>, <el> )
# for a subspace of a projective space and a subgeometry
##
InstallMethod( Meet,
 "for a projective space and an element of a subgeometry of a projective space",
 [ IsSubspaceOfProjectiveSpace, IsSubgeometryOfProjectiveSpace],
 function( el, sub )
        return Meet(sub,el);
    end );

#  flags and shadows

#############################################################################
#O FlagOfIncidenceStructure( <ps>, <els> )
# returns the flag of the subgeometry <ps> with elements in <els>.
# It is checked first whether the elements in <els> belong to the
# same ambient geometry. The method checks whether the input really determines a flag.
# Note that the filter for the first argument is IsProjectiveSpace. So this method
# is applicable for a projective space that is not a subgeometry and a list
# of elements of a subgeometry, but will give an appropriate error.
# Using IsSubgeometryOfProjectiveSpace would force us to install another method
# just producing an error saying that the elements do not belong to <ps>
# if called with the first argument a projective space that is not a subgeometry.
# Installing no such method in that case would result in a no method found error.
##
InstallMethod( FlagOfIncidenceStructure,
 "for a projective space and list of subspaces of the projective space",
 [ IsProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpaceCollection ],
 function(ps,els)
  local list,i,test,type,flag;
  list := Set(ShallowCopy(els));
  if Length(list) > Rank(ps) then
    Error("A flag can contain at most Rank(<ps>) elements");
  fi;
        test := List(list,x->AmbientGeometry(x));
        if not ForAll(test,x->x=ps) then
            Error("not all elements have <ps> as ambient geometry");
        fi;
        test := Set(List([1..Length(list)-1],i -> IsIncident(list[i],list[i+1])));
  if (test <> [ true ] and test <> []) then
    Error("<els> do not determine a flag");
  fi;
  flag := rec(geo := ps, types := List(list,x->x!.type), els := list, vectorspace := ps!.vectorspace );
  ObjectifyWithAttributes(flag, IsFlagsOfSgOPSType, IsEmptyFlag, false, RankAttr, Size(list) );
  return flag;
 end);

#############################################################################
#O ShadowOfElement( <ps>, <v>, <j> )
# returns the shadow of an element v as a record containing the subgeometry <ps>,
# the type j of the elements (type), the element v (parentflag), and
# some extra information useful to compute with the shadows, e.g. iterator
# This method relies on the isomorphic subgeometry of <ps>
# Note: we use IsProjectiveSpace, see also note at FlagOfIncidenceStructure
##
InstallMethod( ShadowOfElement,
 "for a projective space, an element of a subgeometry, and an integer",
 [IsProjectiveSpace, IsSubspaceOfSubgeometryOfProjectiveSpace, IsPosInt],
 # returns the shadow of an element v as a record containing the projective space (geometry),
 # the type j of the elements (type), the element v (parentflag), and some extra information
 # useful to compute with the shadows, e.g. iterator
 function( ps, v, j )
  local localinner, localouter, localfactorspace, tocanonical, vs, vcanonical;
        if not AmbientGeometry(v) = ps then
            Error("<ps> is not the ambient geometry of <v>");
        fi;
        if j > ps!.dimension then
            Error("<ps> has no elements of type <j>");
        fi;
        if not IsCanonicalSubgeometryOfProjectiveSpace(ps) then
            tocanonical := (ps!.projectivity)^(-1);
            vcanonical := v^tocanonical;
        else
            vcanonical := v;
        fi;
        vs := ps!.isomorphicsubgeometry!.vectorspace;
        if j < v!.type then
   localinner := [];
   localouter := Unpack(vcanonical!.obj);
  elif j = v!.type then
            tocanonical := (ps!.proj)^(-1);
   localinner := Unpack(vcanonical!.obj);
   localouter := localinner;
  else
   localinner := Unpack(vcanonical!.obj);
   localouter := BasisVectors(Basis(vs));
  fi;
     if IsVector(localinner) and not IsMatrix(localinner) then
   localinner := [localinner];
  fi;
  if IsVector(localouter) and not IsMatrix(localouter) then
   localouter := [localouter];
  fi;
  localfactorspace := Subspace(vs,
  BaseSteinitzVectors(localouter, localinner).factorspace);
  return Objectify( NewType( ElementsCollFamily, IsElementsOfIncidenceStructure and
       IsShadowSubspacesOfSubgeometryOfProjectiveSpace and
       IsShadowSubspacesOfSubgeometryOfProjectiveSpaceRep),
       rec( geometry := ps,
         type := j,
         inner := localinner,
         outer := localouter,
         factorspace := localfactorspace,
         parentflag := FlagOfIncidenceStructure(ps,[v]),
         size := Size(Subspaces(localfactorspace))
        )
      );
 end);

#############################################################################
#O  ShadowOfFlag( <ps>, <flag>, <j> )
# returns the shadow elements of <flag>, i.e. the elements of <ps> of type <j>
# incident with all elements of <flag>.
# returns the shadow of a flag as a record containing the geometry,
# the type j of the elements (type), the flag (parentflag), and some extra information
# useful to compute with the shadows, e.g. iterator
# This method relies on the isomorphic subgeometry of <ps>
# Note: we use IsProjectiveSpace, see also note at FlagOfIncidenceStructure
##
InstallMethod( ShadowOfFlag,
 "for a a projective space, a flag of a subgeometry of a projective space, and an integer",
 [IsProjectiveSpace, IsFlagOfSubgeometryOfProjectiveSpace, IsPosInt],
 function( ps, flag, j )
    local localinner, localouter, localfactorspace, v, smallertypes, biggertypes, ceiling, floor, canels, vs;
    if not flag!.geo = ps then
        Error("<flag> is not a flag of <ps>");
    fi;
    if j > ps!.dimension then
        Error("<ps> has no elements of type <j>");
    fi;
    #empty flag - return all subspaces of the right type
    if IsEmptyFlag(flag) then
      return ElementsOfIncidenceStructure(ps, j);
    fi;

    # find the element in the flag of highest type less than j, and the subspace
    # in the flag of lowest type more than j.

 #listoftypes:=List(flag,x->x!.type);
 smallertypes:=Filtered(flag!.types,t->t <= j);
 biggertypes:=Filtered(flag!.types,t->t >= j);
    vs := ps!.isomorphicsubgeometry!.vectorspace;
    if not IsCanonicalSubgeometryOfProjectiveSpace(ps) then
           canels := List(flag!.els,x->x^(ps!.projectivity^(-1)));
        else
           canels := List(flag!.els);
    fi;

 if smallertypes=[] then
  localinner := [];
  ceiling:=Minimum(biggertypes);
  localouter:= canels[Position(flag!.types,ceiling)];
 elif biggertypes=[] then
  localouter:=BasisVectors(Basis(vs));
  floor:=Maximum(smallertypes);
  localinner:= canels[Position(flag!.types,floor)];
 else
  floor:=Maximum(smallertypes);
  ceiling:=Minimum(biggertypes);
  localinner:= canels[Position(flag!.types,floor)];
  localouter:= canels[Position(flag!.types,ceiling)];
 fi;
 if not smallertypes = [] then
  if localinner!.type = 1 then
   localinner:=[Unpack(localinner!.obj)]; #here is the cmat change
  else
   localinner:=Unpack(localinner!.obj);
  fi;
 fi;
    if not biggertypes = [] then
  if localouter!.type = 1 then
   localouter := [Unpack(localouter!.obj)];
        else
   localouter := Unpack(localouter!.obj);
        fi;
 fi;
    localfactorspace := Subspace(vs,
  BaseSteinitzVectors(localouter, localinner).factorspace);
    return Objectify(
  NewType( ElementsCollFamily, IsElementsOfIncidenceStructure and
       IsShadowSubspacesOfSubgeometryOfProjectiveSpace and
       IsShadowSubspacesOfSubgeometryOfProjectiveSpaceRep),
        rec(
          geometry := ps,
          type := j,
          inner := localinner,
          outer := localouter,
          factorspace := localfactorspace,
    parentflag := flag,
          size := Size(Subspaces(localfactorspace)) #this causes a problem when localfactorspace consists of cvec/cmat.
        )
      );
 end);

#############################################################################
#O Iterator: the classical iterator, relying completely on the isomorphic
# subgeometry and using the projectivity.
##
InstallMethod(Iterator,
 "for subspaces of a projective space",
 [ IsSubspacesOfSubgeometryOfProjectiveSpace ],
 function( vs )
  local sub, isomorphicsubgeometry, canonicalelements, j, em, proj, map;
  sub := vs!.geometry;
        j := vs!.type;
        isomorphicsubgeometry := sub!.isomorphicsubgeometry;
        canonicalelements := ElementsOfIncidenceStructure(isomorphicsubgeometry,j);
        em := sub!.embedding;
        if IsCanonicalSubgeometryOfProjectiveSpace(sub) then
            map := x->Wrap(sub,j,UnderlyingObject(x^em));
        else
            proj := sub!.projectivity;
            map := x->Wrap(sub,j,UnderlyingObject((x^em)^proj));
        fi;
        return IteratorByFunctions(
            rec(
   NextIterator := function(iter)
                local element;
                element := NextIterator(iter!.S);
                return map(element);
                end,

            IsDoneIterator := function(iter)
              return IsDoneIterator(iter!.S);
            end,

            ShallowCopy := function(iter)
              return rec(
                S := ShallowCopy(iter!.S)
                );
            end,
            S := Iterator(canonicalelements)
          ));
 end);


#############################################################################
#O Iterator: the classical iterator for shadows, relying completely on
# the isomorphic subgeometry and using the projectivity.
##
InstallMethod( Iterator,
 "for shadow subspaces of a projective space",
 [IsShadowSubspacesOfSubgeometryOfProjectiveSpace and IsShadowSubspacesOfSubgeometryOfProjectiveSpaceRep ],
    function( vs )
        local j, d, F, act, sub, proj;
        sub := vs!.geometry;
        j := vs!.type;
        d := sub!.dimension;
        F := sub!.basefield;
        if IsCanonicalSubgeometryOfProjectiveSpace(sub) then
            act := x->x;
        else
            proj := sub!.projectivity;
        #this should be just the action of the projectivity on x, see OnProjSubspacesNoFrob, we will take over
        #the code from there, OnProjSubspacesNoFrob expect that both arguments are cvec/cmat. Also note that
        #x is always a matrix.
            act := function(x)
                local mat;
                    mat := OnSubspacesByCanonicalBasis(x,Unpack(proj!.mat));
                        TriangulizeMat(mat);
                        return mat;
            end;
        fi;
        return IteratorByFunctions( rec(
        NextIterator := function(iter)
            local mat;
            mat := NextIterator(iter!.S);
            mat := MutableCopyMat(Concatenation(
                BasisVectors(Basis(mat)),
                    iter!.innermat
                ));
            return VectorSpaceToElement(sub,act(mat));
            end,
            IsDoneIterator := function(iter)
            return IsDoneIterator(iter!.S);
            end,
            ShallowCopy := function(iter)
            return rec(
                innermat := iter!.innermat,
                S := ShallowCopy(iter!.S)
            );
            end,
            innermat := vs!.inner,
            S := Iterator(Subspaces(vs!.factorspace,j-Size(vs!.inner)))
        ));
    end);

## groups and actions.

InstallMethod( CollineationGroup,
 "for a subgeometry of a projective space",
 [ IsSubgeometryOfProjectiveSpace and IsSubgeometryOfProjectiveSpaceRep ],
 function( sub )
  local coll,d,f,frob,g,newgens,q,s,pow,h,baer;
  f := sub!.subfield;
  q := Size(f);
  d := ProjectiveDimension(sub);
  if d <= -1 then
   Error("The dimension of the projective spaces needs to be at least 0");
  fi;
  g := GL(d+1,f);
  frob := FrobeniusAutomorphism(sub!.basefield); #frobenius automorphism of big field
        h := DegreeOverPrimeField(BaseField(sub));
        newgens := List(GeneratorsOfGroup(g),x->[x,frob^0]);
        #baer := frob^Length(FactorsInt(q)); #this is precisely the Baer collineation for the canonical subgeometry.
        #Add(newgens,[One(g),baer]);
        # new paradigm: CollineationGroup(sub) will not consider the embedding,
        # if q is not prime, the frobenius automorphism of GF(q) is also a collineation.
        # note that we add the frobenius automorphism of the basefield (not the subfield).
  #if not IsPrime(q) then #if q is not prime, there is a frobenius automorphism.
  # Add(newgens,[One(g),frob]);
        #    s := q^(d*(d+1)/2)*Product(List([2..d+1], i->q^i-1)) * Order(frob);
  #else
        #    Add(newgens,[One(g),baer]);
        #    s := q^(d*(d+1)/2)*Product(List([2..d+1], i->q^i-1)) * Order(baer);
        #fi;
        Add(newgens,[One(g),frob]);
  s := Size(CollineationGroup(PG(d,q)))*h;
        newgens := ProjElsWithFrob(newgens,sub!.basefield); #using sub!.basefield as second argument makes sure that
        # ProjElsWithFrob returns elements in the collineation group of the ambient projective space.
        if not IsCanonicalSubgeometryOfProjectiveSpace(sub) then
            newgens := List(newgens,x->sub!.projectivity^(-1)*x*sub!.projectivity);
        fi;
  coll := GroupWithGenerators(newgens);
  #pow := LogInt(q, Characteristic(f)); #order of frobenius of subfield!
  #s := pow * q^(d*(d+1)/2)*Product(List([2..d+1], i->q^i-1))*Order(baer); #hard coded order!
  if not IsPrime(q) then
   SetName( coll, Concatenation("The FinInG collineation group PGammaL(",String(d+1),",",String(q),") of ",ViewString(sub)) );
  else
   SetName( coll, Concatenation("The FinInG collineation group PGL(",String(d+1),",",String(q),") of ",ViewString(sub)) );
   # Remark that in the prime case, PGL is returned as a FinInG collineation group with associated automorphism F^0.
  fi;
  SetSize( coll, s );
        # only for making generalised polygons section more generic:
        if d = 2 then
            SetCollineationAction(coll,OnProjSubspacesOfSubgeometryNC);
        fi;
        SetDefaultGeometry(coll,sub);
        SetParent(coll,CollineationGroup(AmbientSpace(sub)));
  return coll;
 end );


##
InstallMethod( ProjectivityGroup,
 "for a subgeometry of a projective space",
 [ IsSubgeometryOfProjectiveSpace and IsSubgeometryOfProjectiveSpaceRep ],
 function( sub )
  local d,f,frob,g,newgens,q,s,baer,coll;
  f := sub!.subfield;
  q := Size(f);
  d := ProjectiveDimension(sub);
  if d <= -1 then
   Error("The dimension of the projective spaces needs to be at least 0");
  fi;
  g := GL(d+1,f);
  frob := FrobeniusAutomorphism(sub!.basefield); #frobenius automorphism of big field
  newgens := List(GeneratorsOfGroup(g),x->[x,frob^0]);
        #baer := frob^Length(FactorsInt(q)); #this is precisely the Baer collineation for the canonical subgeometry.
        #Add(newgens,[One(g),baer]);
  newgens := ProjElsWithFrob(newgens,sub!.basefield); #using sub!.basefield as second argument makes sure that
        # ProjElsWithFrob returns elements in the collineation group of the ambient projective space.
        if not IsCanonicalSubgeometryOfProjectiveSpace(sub) then
            newgens := List(newgens,x->sub!.projectivity^(-1)*x*sub!.projectivity);
        fi;
  coll := GroupWithGenerators(newgens);
        SetName( coll, Concatenation("The FinInG projectivity group PGL(",String(d+1),",",String(q),") of ",ViewString(sub)) );
        #s := q^(d*(d+1)/2)*Product(List([2..d+1], i->q^i-1)) * Order(baer);
  s := Size(ProjectivityGroup(PG(d,f)));
        SetSize( coll, s );
        # only for making generalised polygons section more generic:
        if d = 2 then
            SetCollineationAction(coll,OnProjSubspacesOfSubgeometryNC);
        fi;
        SetDefaultGeometry(coll,sub);
  return coll;
 end );


InstallMethod( NiceMonomorphism,
 "for a projective group of a subgeometry",
 [IsProjectiveGroupWithFrob and HasDefaultGeometry],
 50,
 function( pg )
 local hom, dom,bf, geom;
 Info(InfoFinInG,4,"Using NiceMonomorphism for proj. group (feasible)");
    geom := DefaultGeometry(pg);
 bf := SubfieldOfSubgeometry(geom);
    #dom := List(MakeAllProjectivePoints( bf, Dimension(pg) - 1),x->OnProjPointsWithFrob(x,geom!.projectivity));
    dom := AsList(Points(geom));
    #The use of FINING.Fast seems deprecated 25/5/2020.
    #if FINING.Fast then
    hom := NiceMonomorphismByDomain( pg, dom, OnProjSubspacesOfSubgeometryNC );
    #else
    #   hom := ActionHomomorphism(pg, dom, OnProjSubspacesOfSubgeometriesNC, "surjective");
    #   SetIsBijective(hom, true);
    #fi;
    return hom;
 end );


InstallGlobalFunction( OnProjSubspacesOfSubgeometryNC,
  function( var, el )
    local amb,geo,newvar;
    geo := var!.geo;
    if var!.type = 1 then
        newvar := OnProjPointsWithFrob(var!.obj,el);
    else
        newvar := OnProjSubspacesWithFrob(var!.obj,el);
    fi;
    return Wrap(geo,var!.type,newvar);
  end );

InstallGlobalFunction( OnProjSubspacesOfSubgeometry,
  function( var, el )
    local amb,geo,newvar,newel,baer;
    geo := var!.geo;
    if var!.type = 1 then
        newvar := OnProjPointsWithFrob(var!.obj,el);
    else
        newvar := OnProjSubspacesWithFrob(var!.obj,el);
    fi;
    newel := Wrap(AmbientSpace(geo),var!.type,newvar);
    baer := geo!.sigma;
    if newel^baer = newel then
        return Wrap(geo,var!.type,newvar);
    else
        return newel;
    fi;
  end );

InstallOtherMethod( \^,
 "for an element of an incidence structure and a projective semilinear element",
 [IsSubspaceOfSubgeometryOfProjectiveSpace, IsProjGrpElWithFrob],
 function(x, em)
  return OnProjSubspacesOfSubgeometry(x,em);
 end );

InstallGlobalFunction( OnSubgeometryOfProjectiveSpace,
  function( sub, el )
    local frame;
    frame := List(sub!.frame,x->x^el);
    return SubgeometryOfProjectiveSpaceByFrame(AmbientSpace(sub),frame,SubfieldOfSubgeometry(sub));
end );

[ Dauer der Verarbeitung: 0.56 Sekunden  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


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