Eine aufbereitete Darstellung der Quelle

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

Benutzer

Impressum morphisms.gi   Interaktion und
PortierbarkeitShell

 

#############################################################################
##
##  morphisms.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 incidence geometry morphisms
##
#############################################################################


########################################
# 20/3/14
# cmat notice: in many operations we will compute
# a matrix to initialize a form. Forms can not handle cmats, so
# Unpacking the cmats will sometimes be necessary.
########################################


############################################################
## Generic constructor operations, not intended for the user.
############################################################

## The three methods for GeometryMorphismByFunction are analogous
## with the MappingByFunction function. It behaves in exactly the same
eptwe.

# CHECKED 27/09/11 jdb
######  </tem>
#O  GeometryMorphismByFunction( <els1>, <els2>, <fun>, <bool>, <prefun> )
##
InstallMethod( GeometryMorphismByFunction, 
 "for two times a collection  
 [ IsAnyElementsOfIncidenceStructure, IsAnyElementsOfIncidenceStructure,
,IsBool, IsFunction ,
 function( els1, els2, fun, bool, prefun )
  java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
  morphism := MappingByFunction(els1, java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 69
  SetFilterObj( morphism, java.lang.StringIndexOutOfBoundsException: Range [4, 1) out of bounds for length 50
  return morphism;
 end );  
  
# CHECKED 27/09/11 jdb
######################################
#O  GeometryMorphismByFunction( <els1>, <els2>, <fun>, <prefun> )
##
InstallMethod( GeometryMorphismByFunction,
 "for two times a collection of Otherwise if <A>G</A> is class-wisepreserving   
 [ IsAnyElementsOfIncidenceStructure, of the permutation group induced on the stored respected partition.
    IsFunction, IsFunction ],
 function( els1, els2, fun, inv )
  local morphism;
  morphismIf<><A   - orderp,returnthesize
  SetFilterObj( morphism, IsGeometryMorphism ); 
  return morphism;
 end );  

#       permutation groupi   of thestored
##################################################  hich isobtained by splittingeachresidueclass
#O  GeometryMorphismByFunction( <els1>, <els2>, <fun> )
#
InstallMethod( GeometryMorphismByFunction,
 "for two times java.lang.StringIndexOutOfBoundsException: Range [0, 17) out of bounds for length 9
 [ java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 8
    IsFunction ],
 function( <C>Size(<A<A>)<C>(of  rcwa )
  local morphism;
  morphism := MappingByFunction(els1, els2, fun);
  SetFilterObj( morphism, IsGeometryMorphism ); 
  return morphism;
 end );  

###################################
# Display methods
##############################Ijava.lang.StringIndexOutOfBoundsException: Range [8, 9) out of bounds for length 8

InstallMethod( ViewObj, 
 "for a geometry morphism",
 [ IsGeometryMorphism ],
 function( f )
  Print("<geometry morphism from "); 
  ViewObj(Source(f));
  Print( " to " );
  ViewObj(Range(f));
  Print(">");
 end );

InstallMethod( PrintObj,
 "for a geometry morphism",
 [ IsGeometryMorphism ],
 function( f )
  Print("Geometry morphism:\n ", f, "\n");
 end );

InstallMethod( Display, 
 "for a geometry morphism",
 [ IsGeometryMorphism ],
 function( f )
  Print("Geometry morphism: ", Source(f), " -> ", Range(f), "\n");
 end );

InstallMethod( ViewObj,
 "for a geometry morphism",
 [ IsGeometryMorphism and IsMappingByFunctionWithInverseRep ],
 function( f )
  Print("<geometry morphism from "); 
  ViewObj(Source(f));
  Print( " to " );
  ViewObj(Range(f));
  Print(">");
 end );

InstallMethod( ViewObj, 
 "for a geometry morphism",
 [ IsGeometryMorphism and IsMappingByFunctionRep ],
 function( f )
  Print("<geometry morphism from "); 
  ViewObj(Source(f));
  Print( " to " );
  ViewObj(Range(f));
  Print(">");
 end );

InstallMethod( PrintObj, 
 "for a geometry morphism",
 [ IsGeometryMorphism and IsMappingByFunctionRep ],
 function( f )
  Print("Geometry morphism:\n ", f, "\n");
 end );

InstallMethod( Display,
 "for a geometry morphism",
 [ IsGeometryMorphism and IsMappingByFunctionRep ],
 function( f )
  Print("Geometry morphism: ", Source(f), " -> ", Range(f), "\n");
 end );

############################################################
## Generic methods for the Image* operations for IsGeometryMorphism. 
############################################################

# CHECKED 27/09/11 jdb
#############################################################################
#O  ImageElm( <em>, <x> )
##
InstallOtherMethod( ImageElm, 
 "for a geometry morphism and an element of an incidence structure",
 [IsGeometryMorphism, IsElementOfIncidenceStructure],
 function(em, x)
  return em!.fun(x); 
 end );

# CHECKED 27/09/11 jdb
#############################################################################
#O  \^( <x>, <em> )
##
InstallOtherMethod( \^, 
 "for an element of an incidence structure and a geometry morphism",
 [IsElementOfIncidenceStructure, IsGeometryMorphism],
 function(x, em)
  return ImageElm(em,x);
 end );


# CHECKED 27/09/11 jdb
#############################################################################
#O  ImagesSet( <em>, <x> )
##
InstallOtherMethod( ImagesSet,
 "for a geometry morphism and a collection of elements of an incidence structure",
 [IsGeometryMorphism, IsElementOfIncidenceStructureCollection],
 function(em, x)
  return List(x, t -> em!.fun(t));
 end );


# CHECKED 27/09/11 jdb
#############################################################################
#O  PreImageElm( <em>, <x> )
##
InstallOtherMethod( PreImageElm,
 "for a geometry morphism and an element of an incidence structure",
 [IsGeometryMorphism, IsElementOfIncidenceStructure],
 function(em, x)
  if IsInjective(em) then
   return em!.prefun(x); 
  else
   Error("Map is not injective");
  fi;
 end );
  
# CHECKED 27/09/11 jdb
#############################################################################
#O  PreImagesSet( <em>, <x> )
##
InstallOtherMethod( PreImagesSet,
 "for a geometry morphism and an element of an incidence structure",
 [IsGeometryMorphism, IsElementOfIncidenceStructureCollection],
 function(em, x)
  return List(x, t -> em!.prefun(t)); 
 end );

##########################################################
## User methods for the "natural geometry morphisms"
##########################################################

## The specialised operations...

# CHECKED 14/12/11 jdb + ml (and added a check that basefields of <ps1> and <ps2> are equal.)
# cmat changed 21/3/14.
#############################################################################
#O  NaturalEmbeddingBySubspace( <ps1>, <ps2>, <v> ) returns a geometry morphism
# from the projective space <ps1> into <v>, an element of the projective space
# <ps2>. <v> must be of the right type, i.e. same projective dimension as <ps1>
# and <ps1> and <ps2> must be projective spaces over the same field.
##
InstallMethod( NaturalEmbeddingBySubspace, 
 "for a projective space into another, via a specified subspace",  
 [ IsProjectiveSpace, IsProjectiveSpace, IsSubspaceOfProjectiveSpace ],
 function( geom1, geom2, v ) 
  local d1, d2, rk, f, invbasis, basis, func, pre, map, morphism, bs;
  rk := v!.type;
  basis := Unpack(v!.obj); #cmat change
  d1 := geom1!.dimension + 1;
  d2 := geom2!.dimension + 1;
  f := geom2!.basefield;
  if not v in geom2 then
   Error("Subspace is not an element of ", geom2);
  fi;
  if d2 < d1 or d1 <> rk then
   Error("Dimensions are incompatible");
  fi;
  if not f = geom1!.basefield then
   Error("Basefields must be the same");
  fi;
    ##    To find the preimage, we first find an invertible matrix C such that
    ##    [a1,..,ad]B = [a1,...,ad,0,...,0]C (where B is our d x e matrix "basis") 
    ##    is our embedding. We simply extend B to a basis for geom2.
  bs := BaseSteinitzVectors(Basis(geom2!.vectorspace), basis);
  invbasis := Inverse(Concatenation(bs!.subspace, bs!.factorspace));
  #ConvertToMatrixRep(invbasis, f); #useless now.
  func := x -> VectorSpaceToElement(geom2 , Unpack(x!.obj) * basis); #VectorSpaceToElement makes sure the 2nd arg becomes cmat.
  pre := function(y)
   local newy;
   if not y in v then
    Error("Applying preimage to an element which is not in the range");
   fi;
   newy:= Unpack(y!.obj) * invbasis; #cmat change.
   if not IsMatrix(newy) then 
    newy := newy{[1..d1]};
                #ConvertToVectorRepNC(newy, f); #useless now.
   else
    newy := newy{[1..Size(newy)]}{[1..d1]};
    #ConvertToMatrixRepNC(newy, f); #useless now.
   fi;
   return VectorSpaceToElement(geom1, newy); #VectorSpaceToElement etc.
  end;   
  morphism := GeometryMorphismByFunction(ElementsOfIncidenceStructure(geom1), 
                                           ElementsOfIncidenceStructure(geom2), 
                                           func, false, pre );
  SetIsInjective( morphism, true );  
  return morphism;
 end );

# CHECKED 27/09/11 jdb + ml
# cmat changed 21/3/14.
#############################################################################
#O  NaturalEmbeddingBySubspaceNC( <ps1>, <ps2>, <v> ) 
## This operation is just like its namesake except that it 
## has no checks
##
InstallMethod( NaturalEmbeddingBySubspaceNC, 
 "for a projective space into another, via a specified subspace",  
 [ IsProjectiveSpace, IsProjectiveSpace, IsSubspaceOfProjectiveSpace ],
 function( geom1, geom2, v ) 
  local d1, f, invbasis, basis, func, pre, map, morphism, bs;
  basis := Unpack(v!.obj); #cmat change
  d1 := geom1!.dimension + 1;
  f := geom2!.basefield;
  bs := BaseSteinitzVectors(Basis(geom2!.vectorspace), basis);
  invbasis := Inverse(Concatenation(bs!.subspace, bs!.factorspace));
  # ConvertToMatrixRep(invbasis, f); #useless now.
  func := x -> VectorSpaceToElement(geom2 , x!.obj * basis); #VectorSpaceToElement etc.
  pre := function(y)
   local newy;
   newy:= Unpack(y!.obj) * invbasis; #cmat change
   if not IsMatrix(newy) then 
    newy := newy{[1..d1]}; 
    #ConvertToVectorRepNC(newy, f); useless now.
   else
    newy := newy{[1..Size(newy)]}{[1..d1]};
    #ConvertToMatrixRepNC(newy, f); useless now.
   fi;
   return VectorSpaceToElement(geom1, newy); #cfr. supra.
  end;   
  morphism := GeometryMorphismByFunction(ElementsOfIncidenceStructure(geom1), 
                                           ElementsOfIncidenceStructure(geom2), 
                                           func, false, pre );
  SetIsInjective( morphism, true );  
  return morphism;
 end );

# CHECKED 27/09/11 jdb + ml
# cmat version 20/3/14.
#############################################################################
#O  NaturalEmbeddingBySubspace( <ps1>, <ps2>, <v> ) returns a geometry morphism
# from the polar space <ps1> into <ps2>, a polar space induced as a section of
# <ps1> and <v>, the latter a subspace of the ambient projective space of <ps1>
##
InstallMethod( NaturalEmbeddingBySubspace, 
 "for a polar space into another, via a specified subspace",  
 [ IsClassicalPolarSpace, IsClassicalPolarSpace, IsSubspaceOfProjectiveSpace ], 
 function( geom1, geom2, v ) 
 local map, d1, d2, rk, f, i, basis, invbasis, bs, c1, c2, orth, tyv, quad1, quad2,
  change, perp2, formonv, ses1, ses2, ty1, ty2, newmat, func, pre, invchange;
  rk := v!.type;
  ty1 := PolarSpaceType(geom1); 
  ty2 := PolarSpaceType(geom2); 
  f := geom1!.basefield; 
  d1 := geom1!.dimension;
  d2 := geom2!.dimension;
  tyv := TypeOfSubspace( geom2, v );
    ## Check that fields are the same and v is non-degenerate 
  if geom2!.basefield <> f then
   Error("fields of both spaces must be the same");
  fi;
    #27/9/2011. jdb was wondering on the next 7 lines. Is this not just tyv = "degenerate"?
 #if not (ty2 = "parabolic" and IsEvenInt(Size(f))) then
    #  perp2 := Polarity(geom2);
    #  if perp2(v) in geom2 then
    #     Error("subspace is degenerate"); 
    #     return;
    #  fi;
    #fi;
  if rk > d2 or d1 > d2 then
   Error("dimensions are incompatible"); 
  fi; 
  if tyv = "degenerate" then
   Error("subspace is degenerate");
  elif
   tyv <> ty1 then 
   Error("non
  fi;  
  orth := ["parabolic", "elliptic", "hyperbolic"];
  if ty1 = ty2 or (ty1 in orth and ty2 in orth) then 
          
          ## Let B be basis of v. Then the form BM(B^T)^sigma (n.b. sigma 
          ## is a field automorphism), where M is the form for geom2,
          ## will be equivalent to the form for geom1.

   basis := Unpack(v!.obj); #cmat unpack

          ## As usual we must consider two cases, the quadratic form case
          ## and the sesquilinear form case. We then obtain a base change matrix c1.

   if HasQuadraticForm( geom2 ) and HasQuadraticForm( geom1 ) then
    quad1 := QuadraticForm(geom1); #cmat notice: these are never cmats. So keep untouched.
    quad2 := QuadraticForm(geom2);
    newmat := basis * quad2!.matrix * TransposedMat(basis);
    formonv := QuadraticFormByMatrix(newmat, f);
    c1 := BaseChangeToCanonical( quad1 );
   else
    ses1 := SesquilinearForm(geom1);
    ses2 := SesquilinearForm(geom2);
    if ty1 = "hermitian" then 
     newmat := basis * ses2!.matrix * (TransposedMat(basis))^CompanionAutomorphism(geom1);
     formonv := HermitianFormByMatrix(newmat, f);
    else
     newmat := basis * ses2!.matrix * TransposedMat(basis);
     formonv := BilinearFormByMatrix(newmat, f);
    fi;
    c1 := BaseChangeToCanonical( ses1 );
   fi;

       ## Finding isometry from geom1 to polar space defined by formofv:

   c2 := BaseChangeToCanonical( formonv );
   change := c1^-1 * c2;        
   # ConvertToMatrixRep(change, f); #became useless.
   invchange := change^-1;
   bs := BaseSteinitzVectors(Basis(geom2!.vectorspace), basis);
   invbasis := Inverse(Concatenation(bs!.subspace, bs!.factorspace));
   # ConvertToMatrixRep(invbasis, f); #same here.
   func := x -> VectorSpaceToElement( geom2, Unpack(x!.obj) * change * basis);
   pre := function(y)
    local newy;
    if not y in v then
     Error("Applying preimage to an element which is not in the range");
    fi;
    newy:= Unpack(y!.obj) * invbasis;
    if IsMatrix(newy) then 
     newy := newy{[1..Size(newy)]}{[1..rk]};
     ConvertToMatrixRepNC(newy, f);
    else
     newy := newy{[1..rk]}; 
     ConvertToVectorRepNC(newy, f);
    fi;
    return VectorSpaceToElement(geom1, newy * invchange);
   end; 
   map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(geom1), 
                                         ElementsOfIncidenceStructure(geom2), 
                                         func, false, pre );
   SetIsInjective( map, true );
  else 
   Error("Polar spaces are not compatible"); 
  fi;
  return map;
 end );
  
# CHECKED 28/09/11 jdb
# cmat comments: see NaturalEmbeddingBySubspace (above).
#############################################################################
#O  NaturalEmbeddingBySubspaceNC( <ps1>, <ps2>, <v> ) 
## This operation is just like its namesake except that it 
## has no checks
##  
InstallMethod( NaturalEmbeddingBySubspaceNC, 
 "for a geometry into another, via a specified subspace, no-check version",  
 [ IsClassicalPolarSpace, IsClassicalPolarSpace, IsSubspaceOfProjectiveSpace ],
 function( geom1, geom2, v ) 
  local map, rk, f, i, basis, invbasis, bs, c1, c2, orth, tyv, quad1, quad2,
          change, perp2, formonv, ses1, ses2, ty1, ty2, newmat, func, pre, invchange;
  rk := v!.type;
  ty1 := PolarSpaceType(geom1); 
  ty2 := PolarSpaceType(geom2); 
  f := geom1!.basefield;
  tyv := TypeOfSubspace( geom2, v );
  orth := ["parabolic", "elliptic", "hyperbolic"];
  if ty1 = ty2 or (ty1 in orth and ty2 in orth) then 
          
          ## Let B be basis of v. Then the form BM(B^T)^sigma (n.b. sigma 
          ## is a field automorphism), where M is the form for geom2,
          ## will be equivalent to the form for geom1.

  basis := Unpack(v!.obj);

          ## As usual we must consider two cases, the quadratic form case
          ## and the sesquilinear form case. We then obtain a base change matrix c1.

  if HasQuadraticForm( geom2 ) and HasQuadraticForm( geom1 ) then
   quad1 := QuadraticForm(geom1);
   quad2 := QuadraticForm(geom2);
   newmat := basis * quad2!.matrix * TransposedMat(basis);
   formonv := QuadraticFormByMatrix(newmat, f);
   c1 := BaseChangeToCanonical( quad1 );
  else
   ses1 := SesquilinearForm(geom1);
   ses2 := SesquilinearForm(geom2);
   if ty1 = "hermitian" then 
    newmat := basis * ses2!.matrix * (TransposedMat(basis))^CompanionAutomorphism(geom1);
    formonv := HermitianFormByMatrix(newmat, f);
   else
    newmat := basis * ses2!.matrix * TransposedMat(basis);
    formonv := BilinearFormByMatrix(newmat, f);
   fi;
   c1 := BaseChangeToCanonical( ses1 );
  fi;

       ## Finding isometry from geom1 to polar space defined by formofv:

  c2 := BaseChangeToCanonical( formonv );
  change := c1^-1 * c2;        
  #ConvertToMatrixRepNC(change, f);
  invchange := change^-1;
  bs := BaseSteinitzVectors(Basis(geom2!.vectorspace), basis);
  invbasis := Inverse(Concatenation(bs!.subspace, bs!.factorspace));
  #ConvertToMatrixRepNC(invbasis, f);

  func := x -> VectorSpaceToElement( geom2, Unpack(x!.obj) * change * basis);
  pre := function(y)
   local newy;
   newy:= Unpack(y!.obj) * invbasis;
    if IsMatrix(newy) then 
     newy := newy{[1..Size(newy)]}{[1..rk]};
     ConvertToMatrixRepNC(newy, f);
    else
     newy := newy{[1..rk]}; 
     ConvertToVectorRepNC(newy, f);
    fi;
    return VectorSpaceToElement(geom1, newy * invchange);
   end; 
   map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(geom1), 
                                         ElementsOfIncidenceStructure(geom2), 
                                         func, false, pre );
  SetIsInjective( map, true );
  else 
   Error("Polar spaces are not compatible"); 
  fi;
  return map;
 end );
  
# CHECKED 28/09/11 jdb (and added a check that basefields of <ps1> and <ps2> are equal.)
#cmat changed 20/3/14.
#############################################################################
#O  java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 40
# returns ,d1basvecsjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
# polar spaces of the same typeifIsIntt
# computed.
##
( IsomorphismPolarSpaces 
    "for two similar polar spaces and a boolean",  
    [ IsClassicalPolarSpace, IsClassicalPolarSpace, IsBool ],
function , ps2 computeintertwiner )
  local form1, java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 4
          coll1, coll2, gens1, gens2, x, y, java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 0
 ty1=PolarSpaceType  )java.lang.StringIndexOutOfBoundsException: Range [31, 32) out of bounds for length 31
  ty2 := PolarSpaceType( ps2 );
   = "arabolic"andty2= symplectic" 
            
        fi;
        r1 := Rank(ps1);
        r2 := Rank(ps2);
        if ty1 <> ty2 or r1 <> r2 then
   Error("Polar spaces are of different type or of different rank");
  fi;
  f := ps1!.basefield;
  if f <> ps2!.basefield then
   Error( "<ps1> and <ps2> must be polar spaces over the same field");
  fi;
  if IsEvenInt(Size(f)) and ty1 in ["parabolic", "elliptic", "hyperbolic"] then
   form1 := QuadraticForm( ps1 );
   form2 := QuadraticForm( ps2 );
  else
   form1 := SesquilinearForm( ps1 );
   form2 := SesquilinearForm( ps2 );
  fi;
  c1 := BaseChangeToCanonical( form1 );
  c2 := BaseChangeToCanonical( form2 );
  change := NewMatrix(IsCMatRep, ps1!.basefield, ps1!.dimension+1,c1^-1 * c2);  #cmat change here
  #ConvertToMatrixRep(change, f);
  invchange := Inverse(change); 
  if ty1 = "hermitian" then
  change^ompanionAutomorphism)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
  invchange =invchange^ompanionAutomorphism(;
  fi; q,trpg2,at1,mat2;
  func := function(x)
   return VectorSpaceToElement(ps2, ShallowCopy(x!.obj) * change q:basis!.java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14

  inv := function(x  Error(The basisandtheprojectivearenotcompatible!");
   return VectorSpaceToElement(ps1, ShallowCopy(x!.obj) * invchange);
  end;
  map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(ps1), 
                                      ElementsOfIncidenceStructure(ps2),
                                      func, inv);               

    # map from gens2 to gens1
  twinerprefun := function( x )
   local y;
    y := MutableCopyMat( x!.mat );
                #return ProjElWithFrob( change * y * invchange^x!.frob, x!.frob, f );  
                return ProjElWithFrob( change * y * invchange^(x!.frob^-1), x!.frob, f );  

   end;  
       
    # map from gens1 to gens2
  twinerfunc := function( y )
   local x;
    x := MutableCopyMat( y!.mat );
                #return ProjElWithFrob( invchange * x * change^y!.frob, y!.frob,                 #return ProjElWithFrob( invchange * x * change^y!.frob, y!.frob, f
                return (invchange  x *^y!.frob^1, y!frob  ;
   end;
  if computeintertwiner then
   if (HasIsCanonicalPolarSpace( ps1 ) and IsCanonicalPolarSpace( ps1 )) or
    HasCollineationGroup( ps1 ) then
    coll1 := CollineationGroup(ps1);
    gens1 := GeneratorsOfGroup( coll1 );  
    gens2 := List(gens1, twinerfunc);  
    coll2 := GroupWithGenerators(gens2);  
    hom := GroupHomomorphismByFunction(coll1, coll2, twinerfunc, twinerprefun); 
    SetIntertwiner( map, hom );
   UseIsomorphismRelation(oll1coll2)                
  e(asIsCanonicalPolarSpaceps2 ) andIsCanonicalPolarSpace( ps2 )) or
    HasCollineationGroup( ps2 ) then                                 
   coll2 =CollineationGroup ps2 ); 
    gens2 := BlownUpProjectiveSpaceBySubfield( <subfield>, <pg> ) 
    gens1 := List(gens2, twinerprefun ); 
    coll1 := #   blows up a projective space  a  space field reduction wr.  basis
    hom := GroupHomomorphismByFunctionI( BlownUpProjectiveSpaceBySubfield,
   SetIntertwiner map  );      
    UseIsomorphismRelation(coll1,coll2);         
   else 
    Info(InfoFinInG, 1, "No intertwiner computed. One of the polar spaces must have a collineation group computed");
   fi;
  fi;
  return map;
 end );

# CHECKED 28/09/11 jdb
#############################################################################
#O  IsomorphismPolarSpaces( <ps1>, <ps2> ) 
# returns (<> <> true)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
##
InstallMethod( IsomorphismPolarSpaces, 
 "for two similar polar spaces",  
  , IsClassicalPolarSpace]
 function( ps1, ps2 )
  return return PG(r*t-1,Size)
 end )

# CHECKED 28/09/11 jdb
################################################################################
#O  BlownUpSubspaceOfProjectiveSpace( <B>, <subspace> ) 
# This operation is just like its namesake except that it 
# hasno checks
InstallMethod( IsomorphismPolarSpacesNC, 
     a boolean" java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
 [ IsClassicalPolarSpace, IsClassicalPolarSpace,[IsBasis  ],
 ( ,ps2 computeintertwiner)
  local form1, form2, f, map, c1, c2, change, invchange, hom, ty1, ty2, n,
          coll1, coll2, gens1, gens2          coll1, coll2, gens1, gens2,java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 33
  ty1 := if not pg1!.basefield(^) then 
  ty2 := PolarSpaceType( ps2 );
  f := ps1!.basefield;
   Error"     are  compatible!;
   form1 := QuadraticForm( ps1 );
   form2 := fi
  else
   form1 := SesquilinearForm( ps1 );
  form2 : SesquilinearForm(ps2 ;
  fi;
 1: ( )
  c2 := if subspacetype=then 
  java.lang.StringIndexOutOfBoundsException: Range [21, 8) out of bounds for length 97
  #ConvertToMatrixRepNC(change, f);
  invchange := Inverse  mat2:BlownUpMatb,;
 : functionxjava.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
   return VectorSpaceToElement(ps2, ShallowCopy This  wr.  thecanonicalbasisofthefieldover  subfield.
  end;
  inv := 
   return VectorSpaceToElement(ps1, ShallowCopy(InstallMethod(BlownUpSubspaceOfProjectiveSpaceBySubfield,
  end;
  map := IsField, IsSubspaceOfProjectiveSpace
                                      (subfieldsubspace)
                                      java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 53
     (The first is asubfieldof  basefieldof theprojective!);
#map fromgens2togens1
  twinerprefun  :BasisAsVectorSpacesubfield))
   local y;
   y:= MutableCopyMat( !mat )
                #return ProjElWithFrob( invchange * java.lang.StringIndexOutOfBoundsException: Range [0, 53) out of bounds for length 7
               return ProjElWithFrob(invchange*x *change^y!frob^1,y!  );
                java.lang.StringIndexOutOfBoundsException: Range [37, 22) out of bounds for length 89
  end;  
       
    # map from gens1 to gens2
  twinerfunc := function( y )
   localx;
            x := for a basis and a subspace  space,
        #ProjElWithFrob  *xy!frob, y.rob  );
                return java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
  end;
  if computeintertwiner then
  if (HasIsCanonicalPolarSpace )IsCanonicalPolarSpaceps1) or
    HasCollineationGroup( 
    coll1 :=  r=rt/;
    gens1 :=  pg1:PG(1qt;
    : Listg,twinerfunc;java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
    coll2 := GroupWithGenerators( v1:List(1.r,-v[i1)t1.i*t]*;
  hom :=GroupHomomorphismByFunctioncoll1,coll2,twinerfunc );
    SetIntertwinerflag: =VectorSpaceToElementp,;
    java.lang.StringIndexOutOfBoundsException: Range [0, 26) out of bounds for length 5
   end)
    HasCollineationGroup( ps2 ) then                                 
    coll2 := CollineationGroup( ps2 );  
    gens2:=GeneratorsOfGroup( coll2 );          
    gens1 := List(gens2, twinerprefun ); 
   coll1GroupWithGeneratorsgens1;
  hom: GroupHomomorphismByFunction(coll1,, , twinerprefun) 
 winer ,hom);     
    UseIsomorphismRelation(coll1,coll2);         
   elsejava.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
   (,1, " intertwiner .One   polarspaces must  a  group ";
   fi;
  fi;
  return map;
 end );
  
# CHECKED 28/09/11 jdb
################################
#O  IsomorphismPolarSpacesNC(#basis     the subspaceis blownup
#returnsIsomorphismPolarSpacesNC <ps1><,true )
##
smPolarSpacesNC 
 "for two similar flag:true;
 [ java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
 t=!.;
  return  K:=GF(q^t)
  ;

#############################
## Field reduction / subfield morphisms. Helper operations.
################################

 28/911jdb
#########################################
#O  flag=falsejava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
# returns the preimage of return flag;
##
InstallMethod( ShrinkMat, 
 "for a basis and a ##################################################
  ],
 function( B, ########################################
  
  ## THERE WAS A BUG IN   ## THERE WAS A BUG IN THIS
  ## NOT ALL#A reference    projectivespaces is
  #Here is theexplanation could go into thedocumentation:
  # TheresultofBlownUpMatB) is the matrix, each entry= isreplacedby
  ## the dxd matrix M_a, ########################################################
  #   Kseen  - vectorspace F.This means if 
  ## B={b_1,b_2#< is aprojective   a  K,geom1>is a projectivespace
y  we wanttoimplementShrinkMat we  to   the inputis 
  #that <geom1>and <geom2 have the  vectorspace K  this
   canbe done asfollows.  A  admx matrix   dxd block, say M, 
  ## #   K.
  ## (Since # Important note note: the intertwinerhas as  * group* only 
  
  ##  is basicallythe   java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
  ## "for two projec two projective spacesabasis"java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
  
  unction pg1,, )
 d:=Size(
 ecs=();
 m:=NrRows(mat);
 n:=rColsmat)
  # First f1 : pg1!.basefield; 
 if not (IsInt(m/d) and IsInt(/d)then 
  Error("The   =Size(1;
 fi;
 blocks:=List(Cartesian([0..m/d-1], 2: Sizef)java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 12
 iin[.m java.lang.StringIndexOutOfBoundsException: Range [21, 22) out of bounds for length 21
 row=] 
  for j  d2 := d1 : *tjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
   #submat:=blocks[(ifnot (sBasisbasis)andf1=GF((basis.)basis.d)and f2=F(asis!q  *(asis.d)=d2 
   submat=(-)(/d+;
   checklist:= i;
   if Size(
    Error fun :=function(subspace #Thismap  up a subspace  geom1 to  subspaceof geom2
  f;
   #BlownUpSubspaceOfProjectiveSpacex;
  od;
  Add(newmat,row);
 d;
 return newmat;
   DOWE NEED TOUSEConvertToMatrixRepNC java.lang.StringIndexOutOfBoundsException: Range [44, 45) out of bounds for length 44
 end); 
  
  
InstallMethod( ShrinkMat, 
 "for a field, a subfield and a matrix"return VectorSpaceToElement(pg2,mat2);
 [IsField,sField,IsMatrix ],
 function( f1,f2,mat )
   gives the sameresult asShrinkMatBmat   the natural basis returned by
 # Basis(AsVectorSpacelocalflagb,mat1,,,,v1,i,ecsjava.lang.StringIndexOutOfBoundsException: Range [55, 56) out of bounds for length 55
 local ;
 B:=Basis(AsVectorSpace(f2,Error(Theinputisnotintherangeofthe  map";
 return fi;
end)
 

###########################################
#Obasvecs:BasisVectorsbasis)
# f2 is a subfield of f1 vecs := Unpack(subspace)java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
   lengthd2t  d2=(2,andt[1f]
# using the natural basisspan =VectorSpaceToElement(g2,lownUpMat(basis,at1)
##
nstallMethod ShrinkVec,
 "for a field, a subfield and a vector",
 [ IsField, IsField, java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 19
  f2, )
 local         (Theinputisnotintherangeofthe field  map";
 t:=Dimension(AsVectorSpace(f2,f1));
 d1:=Length(vfijava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
 if IsInt(d1) then
  java.lang.StringIndexOutOfBoundsException: Range [0, 9) out of bounds for length 7
  return List([1..d1],i->v{[ElementsOfIncidenceStructure(pg2),
 else
  Error("The length of v is not divisible by                                             fun,,prefun);
 fi;
end );

###################Nowcreating intertwiner
#O       # /14 checktoseem  projectivity
# 
InstallMethod( ShrinkVec, 
 "for a field, a subfield and a vector",
 [ IsField, IsField, IsVector, IsBasis   localimage;
 function( f1,f2,v,basis )
 localt,,d2basvecs;
 t:=Dimensionreturn fail;
 d1:Info(InfoFinInG,1 "<l>is not aprojectivity)java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
 if IsInt(d1) then
  basvecs:BasisVectorsbasis);
  return List(image, f2;
 else
  Error("The length of v is not Error("The length of v is not 
 fi;
end );



#####################################
#O  ( <>,<pg1>) 
#   blows up a projective space returnC(preimage,)
#
InstallMethod
 "for a  g1 =ProjectivityGroup(  );
 [ IsBasis, IsProjectiveSpace ],
 functionbasis,java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
 local q,t,r,pg2, g2:= Group()
  q:=basis SetSize(g2,Size(1))
  t:basis!.;
sefield=GF(q^t) then 
   Error("The basis and the projective space are not compatible!");
  fi;
  r:=Dimension(pg1)+1;
  pg2:=PG(r*t-1,q);
  pg2java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
 end );

################################## <>isa field ,<eom1 a  space
#( subfield, <pg> )
#   blows up   projective space geom2 thathasthe  vectorspace K.This
#java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
InstallMethod( BlownUpProjectiveSpaceBySubfield,
 "( NaturalEmbeddingByFieldReduction,java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
 [ IsField, IsProjectiveSpace ],
 function(subfield,pg)
  t,,ield;
        field:=java.lang.StringIndexOutOfBoundsException: Range [0, 31) out of bounds for length 14
        if notreturn (,2,asis)
         Error("The first argumentend )
        fi;
        =((ubfieldfield));
        r:=Dimension(pg)  NaturalEmbeddingByFieldReductiongeom1> geom2><> ) 
        (subfield);
  end );   a field extension  vector  over K, yields 

# CHECKED 1/10/11 jdb
#######################################
#O  BlownUpSubspaceOfProjectiveSpace( <B>, <subspace> ) 
#  blows up a subspace of a projective space by field reduction
##
InstallMethod( "for two projective spaces and,
or a  anda subspace a projective space",
  IsBasis,IsSubspaceOfProjectiveSpacejava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
 function(basis,subspace)
 local pg1,q,t,r,pg2,java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 0
  pg1:=AmbientGeometry(subspace);
  q:basis!q;
  t:=basis!.d;#O  (<> <geom2>)
  if not# geom2>  aprojectivespaceovera field,< isa projectivespace
   Error("The basis and the subspace are not compatible!");
 ;
  r:=Dimension(pg1)+1;
  pg2:PG(*-,)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  mat1=!obj;
  if subspaceI(NaturalEmbeddingByFieldReduction
   or two projective spaces"
  fi; 
  mat2:=BlownUpMat(basis,mat1);
  return VectorSpaceToElement( return VectorSpaceToElement(pg2,mat2);
 end );

#######################################
#O  java.lang.StringIndexOutOfBoundsException: Range [48, 46) out of bounds for length 72
# blows up a subspace of projective space by
# This is w.r.t. to the canonical basis
##
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 0
 "for a field java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 [ java.lang.StringIndexOutOfBoundsException: Range [0, 10) out of bounds for length 0
 function(subfield#######################################
 local pg POLAR SPACES
  pg:=#################################################
  field:=LeftActingDomain(java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 0
    subfield inSubfieldsfield)then
   Error("#  [1] from g  point  :"    ofclassicalgroups byNickGill
  fi;
  basis:=#  [2] from fi geometry pointof :"ield    sets   geomety"byLavrauw
 BlownUpSubspaceOfProjectiveSpacesubspace)
 end );

######################################java.lang.StringIndexOutOfBoundsException: Range [77, 78) out of bounds for length 77
#
# checks
##
InstallMethod( IsDesarguesianSpreadElement,java.lang.StringIndexOutOfBoundsException: Range [0, 44) out of bounds for length 1
 "for a basis and a subspace of a projective space"java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
 [ IsBasis, IsSubspaceOfProjectiveSpace ],
 function(basis,subspace)
  ocal,,,pg1,pg2,basvecs,v1,m,rtrjava.lang.StringIndexOutOfBoundsException: Range [52, 53) out of bounds for length 52
  flag:=true;
 q:basis!q
  t:=basis!.d;
  =(subspace;
  rt:=Dimension(pg2)+1;
  if not (Dimension(subspace)+1 = t and IsInt(rt/t)) then 
   flag:=false;#withbasis <asis> This operationthen
  else
   r:=
   pg1:=PG(r-1,#REMARK ml 10/13)The  argumentisa basisofL .T justgives
   :BasisVectorsbasis)
   java.lang.StringIndexOutOfBoundsException: Range [17, 4) out of bounds for length 44
   v1=(1.],->{[i)*1.*]}basvecs;
  mat=(,v1];
   java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 0
  fi;
return flagjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
 end );
   
# To be done: check this method! (but java.lang.StringIndexOutOfBoundsException: Range [0, 40) out of bounds for length 30
####################
#O  IsBlownUpSubspaceOfProjectiveSpace( <Bl mat1f1d1t,V2,V1,hib2,,mat2,,row,,bil2
#   a subspace  blown upusingreduction w.t  basis
##
InstallMethod( IsBlownUpSubspaceOfProjectiveSpace, 
 "for a basis and a subspace of a projective  t:Dimension((,1)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
 [ IsBasis, IsSubspaceOfProjectiveSpace ],
 # It's important that we java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 15
 # since for java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 10
 # basis with respect to which the subspace is blown up.
 function(for j in [1. 
 flagqF,,,pg2,rtrpg1,,at1s,,,v1,;
  flag:=true;
  q:=basis!.q;
  F:=GF(q);
  t:=basis!.d;
 K=GF^t;
  pg2: bil2;
  rt:=Dimension(pg2)+1;
  if not (IsInt(rt/t) and IsInt((Dimension(subspace)+1)/t)) then 
   flag:=
  else
  :rt/;
   pg1:=PG(rO BilinearFormFieldReduction(<bil1>, <f2>, <alpha> )
   :(basis);
   mat1:=[];
   span:=[];
   repeat
 ; untilnot xin span;
     v:=Coordinates(x);
     v1:=List([1..r],i->v{[(i-1)*t+1..i*t]}[IsBilinearForm IsField, IsFFE ,
     Add(mat1,v1);
   span:VectorSpaceToElementpg2,lownUpMatbasis,)java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
    Dimensionspan)Dimension(subspace;
    if not span = end )
     flag:= false;
  fi;
  fi;
  returnflag;
 end );   
  
#############################################################################
#  PROJECTIVE SPACES
#############################################################################

#
#  A recent reference on field reduction of projective spaces is
#  "Field reduction and linear sets in finite geomety" by Lavrauw
 and   Voordepreprint 2013)

##############operation . 
#O  # There is also a version of this operation  does  use
# isa  spaceover   ,<eom1isaprojectivespace
# over a field extension L, and java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
# that <"for  quadratic   ",
#  returnsthe ,i.withrelation  the basis
# of L over K.
# Important note: the intertwiner has as source the *#f2  a ofbasefield thequadraticformq1
#thefullcollineationgroupjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
##
InstallMethod( NaturalEmbeddingByFieldReduction, 
 "for two projective spaces and a basis",
     [ IsProjectiveSpaceif .java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
,,  )
  
  # morphism a prefuncwith built-ncheck.
 
  local map, f1, d1, d2, t, fun, prefun, g1, gens, newgens, g2, twiner, homlocal flag,,,span,,,1i;
  f1 := pg1!.java.lang.StringIndexOutOfBoundsException: Range [8, 1) out of bounds for length 19
  q1 := Size(f1);
  q2 := Size(f2);
  t =LogInt(1,2;
  if not q2^t = q1 then
   Error( "<f2> is not a subfield of the base field of <pg1> ");
  fi;
  d1 := pg1!.dimension (subspace)+)t 
  d2 := d1*t;
  pg2 := ProjectiveSpace( pg2 := ProjectiveSpace(d2
  if not (IsBasis(basis) and f1=GF((basis!.q)^basis basvecs:BasisVectorsbasis;
   Error("The basis is not a basis or is not compatible with the basefields of the geometries"span=]
 f;

  :function    java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 92
            mat1mat2;
            #return BlownUpSubspaceOfProjectiveSpace(basis,x);
java.lang.StringIndexOutOfBoundsException: Range [16, 12) out of bounds for length 34
            if subspace!.type = 1 then
                mat1 := [subspace!.obj];
            fi;
            mat2java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 11
            return VectorSpaceToElement(            Error("The input is not in the the field!";
  end;

        prefun :return VectorSpaceToElement(ps1mat1)java.lang.StringIndexOutOfBoundsException: Range [46, 47) out of bounds for length 46
            local flag,basvecs,mat1,span,x,v,v1,i,vecs ap=GeometryMorphismByFunction((ps1),ElementsOfIncidenceStructure),
            true
            if not subspace in pg2 then
                Error("The input is not in the range of the field reduction map!");
            fi;
            ((Dimension()1/)then
                flag := false
            else
                basvecs:=BasisVectors(basis);
                vecs(subspace);
                mat1 := List(vecs,x->List([1..d1],i->x{[(i-1)*t+HasCollineationGroup ps1) then
                span := VectorSpaceToElementhom:=function(m)
                 not = then
                    flag := false;
                fi;
            fijava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
            if flag= false then
                Error("The input is not in the range of thelocal preimage;
            fi;
            preimage :=ShrinkMatbasis,Unpackm!);
        end;

        return(preimage )java.lang.StringIndexOutOfBoundsException: Range [67, 68) out of bounds for length 67
 torSpaceToElementpg1S(,x!objjava.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
  #end;
       
  map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(pg1),
                                         ElementsOfIncidenceStructure(pg2),
twiner: GroupHomomorphismByFunction(, hom,hominv;
  
  (map true )
        
        ## Now creating intertwiner
        ## 12/6/14: added check to see
  
        hom := function(m)
   local image;
            if not IsOne(m!.java.lang.StringIndexOutOfBoundsException: Range [0, 32) out of bounds for length 0
                returnfail;
                Info(InfoFinInG, 1, "<el> is not a projectivity");
            ;
   ONaturalEmbeddingByFieldReduction geom1,f2><alpha,basis java.lang.StringIndexOutOfBoundsException: Range [71, 72) out of bounds for length 71
   #ConvertToMatrixRepNC( image, f2 );
   return CollineationOfProjectiveSpace(image, f2);
  end;

  hominv := function( m )
  local preimagejava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
            if not IsOne(m!.frob) then
                return fail;
ty";
            fi;
   preimage :=end )java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
   #second particular version: user wants a particular alpha, and bool, agrees with basis.
  return CollineationOfProjectiveSpacepreimage );
  end;

  g1 := ProjectivityGroup( pg1 );
   :GeneratorsOfGroup g1 ;
  newgens := #where basis>is the canonical basis  BaseFieldg)overf2>
  g2 :#
  SetSize(g2, Size(g1));
  twiner := GroupHomomorphismByFunction(g1, g2, hom, hominv);
    twiner;
  return map;
 end );

################### function(s1f2,,)
#O  NaturalEmbeddingByFieldReduction NaturalEmbeddingByFieldReductionp,2,lphaBasisAsVectorSpace(2BaseFieldps1)),bool;
 field   field K,<geom1  java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 7
   L andconsideringLas a space ,yields
# that a java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 7
# operation returns the natural embedding, i.e. with relation to the standard basis of
# L over K.
##
NaturalEmbeddingByFieldReduction
 "for a projective space and ()then
 [ IsProjectiveSpace IsField,
 function( pg1, f2 )
  local basis;
 basis:=asis(sVectorSpace(pg1!);
  return NaturalEmbeddingByFieldReduction(pg1,f2,basis);
 end );

########################    
#O  NaturalEmbeddingByFieldReduction type1 hermitian andtype2="elliptic IsEvenInt()and IsOddInt()
# <geom2> is java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 24
  a extension and Lasaspaceover,
# that <geom1> and <geom2> have the same java.lang.StringIndexOutOfBoundsException: Range [0, 48) out of bounds for length 21
# operation returns the natural embedding, i.e. form2: (form1,f2,alpha,basis);
# of L  
##
InstallMethod( NaturalEmbeddingByFieldReduction, 
tive spaces and a "java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 51
is )
  return NaturalEmbeddingByFieldReduction #ap :=NaturalEmbeddingByFieldReduction,f2,alpha java.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 69
 end);

# CHECKED 28/09/11 jdb
############################################################################ fi;
#O  NaturalEmbeddingByFieldReduction( <else#form1isaquadraticform
# <geom2 iftype1="yperbolic"type2="yperbolic" then
# over a field extension L, and considering L as a vector space over  Info(InfoFinInG, 1, "These polar spaces are suitable for field redu 1,Thesespaces java.lang.StringIndexOutOfBoundsException: Range [56, 55) out of bounds for length 78
#that<geom1>and <geom2 have thesame ambient  vectorspace over K, then this
# operation returns the natural embedding, i.e. with relation to the standard basis of
# L over K.
##
InstallMethod , 
 "for two projective spaces",
 [ java.lang.StringIndexOutOfBoundsException: Range [39, 20) out of bounds for length 42
 function( pg1, pg2 )
 local basis
  basis:=Basis(AsVectorSpace(pg2!.basefield form2:=QuadraticFormFieldReduction(orm1,f2,alpha,asis);
  return NaturalEmbeddingByFieldReduction(pg1,pg2!.basefield,basis);
 end );










#########################  alpha  : One(1;
#  POLAR  #map : NaturalEmbeddingByFieldReduction( ps1, 2,alpha,basis )
################form2 :=,2alpha,basis;


#
#  Two references on field that  will use for the embedding
#   # dependson the  typeof . isometrytype is determined 
#  (New Zealand J. Math gamma being a  or,where  
#  [2] from  # (-1)^(r-1)/2 the determinant  the bilinearform   .
#   and Van de Voorde (preprint 2013)
#
#  We will use [2] as it is more convenient to us.


####
# #somewhat easier to work with than the conditions in Gill's paper.
# java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 0
#
#####


#############################################################################
#O   bil1=AssociatedBilinearForm(form1); # important to use this instead of 
 nonsquare
# <alpha> determines the linear map from f1 to <f2>, f1 the field extension of <f2>
#with basis basis>. This operation then
# returns the bilinear form L(bil1(.,.)), L(x) = T(alpha*x), T the trace from <f1> to <f2>.
##
# REMARK (ml 31/10/13) The fourth argument is a basis of L over K. This  alpha := First(f1, a >notIsZeroais_square *,f1) )java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
# extra functionality to the user, and it is used as third argument in java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 71
# 
# There is also  elif type1="arabolic"java.lang.StringIndexOutOfBoundsException: Index 101 out of bounds for length 101
# a basis as fourth argument. In this case the standardgamma=(-)(r1)2)  (!matrix/;

InstallMethod( BilinearFormFieldReduction,
 "for a bilinear form and a field",
 [ IsBilinearForm  IsFFE  ,
 function(bil1,f2,alpha,basis)
 # f2 is a subfield of the basefieldmap:NaturalEmbeddingByFieldReduction,f,alpha,basis ;
 localform2: QuadraticFormFieldReductionform1falpha,basis);
 mat1:=bil1!.matrix;
 f1
 d1:=NrRows(mat1);
 t:=Dimension(AsVectorSpace(f2,f1 Error(These polar nsuitablefield.;
 d2:=d1*t;
 V2:=f2^d2;
 V1:=f1^d1;
 b2:=Basis(V2);
 b2vecs:=BasisVectors(b2);
 mat2:=[];
 for i in [1..d2] do 
  row:=[];
  for j in [1..d2] do
   Add(row,Trace(f1,f2,alpha*(ShrinkVec(f1,f2,b2vecs[i],basis) : !.bj;
  od;
  Add(mat2,row);
 od;
 bil2:=BilinearFormByMatrix(mat2,f2)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
 return bil2;
end );

###################################################end;
#O  BilinearFormFieldReduction( <bil1>, <f2>, <alpha> ) 
# The same as above, #this version of prefun new(//.
#flag=;
InstallMethod( java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
 "for a bilinear form and a field",
 [ IsBilinearForm, IsField, IsFFE ],
 functionbil1,java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
 # f2 is a subfield of the basefield of the bilinear form bil1
 return BilinearFormFieldReduction(bil1,f2,alpha,Basis(AsVectorSpace(f2,bil1#                                  ps2),
nd);

java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#O  QuadraticFormFieldReduction( <qf1>, <f2>, <alpha>, <basis> ) 
# <bil1> is a bilinear form over <f1>, <f2> is a subfield of <f1>. This operation
# returns the  SetIsInjective( map, )
##
# REMARK (ml 31/10/13) The fourth argument is a    if H( ps1)andIsCanonicalPolarSpace ps1 )ps1 ) or
# extra functionality to the user, and it is used as third argument in the 
# operation ShrinkVec. 
# There is also a version of this field reduction operation, which does notlocal image;
# a basis as fourth argument. In this case the standard GAP basis is used.

InstallMethod,
 "for a quadraticreturn (cps2*image  cps2inv,f2)java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
 [ IsQuadraticForm, IsField, IsFFEhominv=function  )
 function(qf1,f2,alpha,basis)
 # f2 is a subfield of the basefield for the quadratic form q1
 local f1,basvecs,d1,t,d2,V2,V1,phi,b2,b2vecs,mat2,i,bil1,j,qf2;
 f1:=qf1!.basefield;
 basvecs:=BasisVectors(basis);
 :NrRows(qf1!.)java.lang.StringIndexOutOfBoundsException: Range [25, 26) out of bounds for length 25
 t:=Dimension(AsVectorSpace(f2,f1));
 d2:=d1*t;
 V2:=f2^d2;
 V1:=f1^d1;
 b2:=Basis(V2);
 b2vecs:=gens ( );
 mat2:=IdentityMat(d2,f2);
 for i in[..d2] java.lang.StringIndexOutOfBoundsException: Range [20, 21) out of bounds for length 20
  mat2[i,i]:=Trace(f1,f2,alpha*((ShrinkVec(f1,f2,b2vecs[i],basis))^qf1))SetSizeg2 (1)
 ;
 for i in [1..d2-1] do
  for j in [i+1..d2] do
   mat2[i,j]:=Trace(f1fi;
       -(ShrinkVec(f1,f2,b2vecs[i],basis))^qf1-(ShrinkVec(f1,f2,b2vecs[j],basis))^qf1));
   #mat2[j,SetIntertwinerm,hom)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
  od;
 od;
 :QuadraticFormByMatrixmat2,)
 return qf2;
end );

##################################################################java.lang.StringIndexOutOfBoundsException: Index 85 out of bounds for length 85
# #O  QuadraticFormFieldReduction( <qf1>, <f2>, <alpha> #This takestwopolar spacesand   embedding
# The obtained by field reduction if such  embedding exists,  it returnsanerrorjava.lang.StringIndexOutOfBoundsException: Index 89 out of bounds for length 89
##
InstallMethod( QuadraticFormFieldReduction,
 "for a quadratic form and a field",
 [ IsQuadraticForm, IsField, IsFFE ],
 function(qf1,f2,alpha)
 local basis,qf2;
 # f2        return NaturalEmbeddingByFieldReductionps1,s2t)
 :Basis(AsVectorSpace(2,!b);
 qf2:=QuadraticFormFieldReduction(qf1,f2,alpha,basis);
 return qf2;
end );


########################################################################
#O  HermitianFormFieldReduction( <hf1>, <f2>, <alpha>, <basis> ) 
# <hf1> is a java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
# returns the form T(alpha*bil1(.,.)). java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 1
# yieldseither abilinear or hermitian formjava.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
##
# REMARK (ml 31/10/13) The fourth argument is a basis of # CHECKED/0614
theuser andit is  as  inthe 
# operation ShrinkVec. 
# There is also#########################################
# a basis as fourth argument. In this case the <geom2>, two projective of

MethodHermitianFormFieldReductionjava.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
 ",
 [ IsHermitianForm, IsField, IsFFE, IsBasis ]" two projectivespaces",
 hf1,,,)
 # f2 is
sasquare
 local f1,d1,t,d2,V2,V1,phi,b2Error(Dimensionsandorfieldareincompatible) return;
 f1:=hf1!.basefield;
 d1:=NrRows(hf1!.matrix);
 t:=Dimension(AsVectorSpace(f2,f1));
 d2:=d1*t;
 java.lang.StringIndexOutOfBoundsException: Range [51, 3) out of bounds for length 51
 V1:=f1^d1;
 b2:=Basis(V2);
 b2vecs:=BasisVectors(b2);
 mat2:=[];
 for i in [1..d2] do 
r:;
  in1.2 java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
   Add(row,Trace(f1,f2,alpha* (,hom;
  od;
  Add(mat2, map, ,q1,q2  ,,g1 , ,gens2 ,
od
 # checking parity ,basis d , bmat ,, c1 c2,form2;
 if IsOddInt(t) then 
  hf2:=HermitianFormByMatrix(mat2,f2);
 else
  hf2#
 fi;
 return hf2;
end );


########################Allpossible cases:
# #O  HermitianFormFieldReduction(
# The #W-  (uadratic)
##

InstallMethod( HermitianFormFieldReduction,
 "for a hermitian form and a field",
 [,IsField,IsFFE ],
 function(hf1,f2,alpha)
 # f2 is a subfield of the basefield for theif geom1!. = geom2!.dimensionand IsSubsetf,)thenjava.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
  the basefieldis always a
 local basis;
 
 basis:=Basis(AsVectorSpace(f2,hf1!.basefield));
 return HermitianFormFieldReduction(hf1,f2,alpha,basis);
)



##########################################################
#
# Next the embeddings for polar spaces based on the field reduction of the forms above
# 
#############################################################################

# master version for the user: handle all parameters.
#############################################################################
#O  NaturalEmbeddingByFieldReduction( <ps1>, <f2>, <alpha>, <basis>, <bool> ) 
# returns a geometry morphism, described below. If <bool> is true, then an intertwiner
# is  form := QuadraticFormByMatrixgram f2)
#
InstallMethod (NaturalEmbeddingByFieldReduction,
 "for a polar space, a field, a basis, a finite field element, and a boolean",
 [IsClassicalPolarSpace, IsField, IsFFE, IsBasis, IsBool],
 function(ps1,f2,alpha,basis,computeintertwiner)
 # f2 must be a subfield of the basefield of the classical polar space
 local type1,qf1,qf2,ps2,bil1,bil2,hf1,hf2,fun,prefun,f1,
     map,hom,hominv,g1,gens,newgens,g2,twiner, t,q1,q2,d1,d2;
 type1 := PolarSpaceType(ps1);
 f1:=ps1!.basefield;
 q1 := Size(f1);
 q2 := Size(f2);
 t := LogInt(q1,q2);
d1 :ps1!dimension 
 d2 := d1*t;

 #1. the polar    
 if type1 in ["hyperbolic","elliptic","parabolic"] then
  qf1:=QuadraticForm(ps1);
 =,2alphabasis;
  
q) 
   Error("The field reduction does not yield a natural;
  else   ConvertToVectorRepNC(nvecf); #,also if appearantly vec is already  f1
  fi;
 # 2. the polar space is of symplectic : BlownUpMat(basis,vec)
   : SumIntersectionMatb,bmat[] #hard coded operation:)
  bil1:=SesquilinearForm(ps1);
  bil2:=nvec := List(list->(,,x);
  ps2:=
 # 3. the polar space is of hermitian type 
 elif type1 in ["hermitian"] then
  hf1:=SesquilinearForm(ps1);
  hf2:=HermitianFormFieldReduction(hf1,f2,alpha,basis);
  ps2:=PolarSpace(hf2);
 fi;
 
 #em:=NaturalEmbeddingByFieldReduction(AmbientSpace(ps1),AmbientSpace(ps2));
 # this is the field reduction for projective spaces PG(r-1,q^t) -> PG(rt-1,q)
 
 #fun:=function(x)
 # local projfun;
 #projfun:em!fun;
 # return VectorSpaceToElement(ps2,projfun(x)!.obj);
 #end;
 
    fun := function( subspace )
        ,java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
        java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 30
        if subspace!.type = 1 then
            mat1 := [subspace!.obj];
        fi;
         : (basism)
        return VectorSpaceToElement(ps2,mat2);
    end;


 #
 # local             ymat := *Unpackymat)* change here!
 # projprefun:=emymat = ymatFirsty[1]-notIsZero());
 # return  if not ForAll( Flat)  ->i


    # new version (2/7/14, much faster since we avoid the repeat loops and Random         ;
    prefun := function( subspace ) # This map is the inverse of func
        if ( geom1 )then
        flag:=true;
        if not subspace in ps2 then
            Error("The input is not in the range of the field reduction map!");
        fi;
        if not IsInt((Dimension(subspace)+1)/t) then
            flag:=false;
        
            basvecs:=BasisVectors(
            mat1:=[];
            span:=[];
            vecs :=# CHECKED 28/9/11jdb
            ######################################################java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
             =VectorSpaceToElement(),(asismat1);
                #the returns NaturalEmbeddingBySubfield( <geom1>, <geom2>, true )
            if not span=subspace then
                flag := false;
            fi;
        fi;
        if flag= false then
            Error("The input is not in the range of the field reduction  [IsClassicalPolarSpace  ]
        ;
        return VectorSpaceToElement(ps1return NaturalEmbeddingBySubfield(geom1,geom2,true)
    end;

 map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(ps1), ElementsOfIncidenceStructure(ps2),
                                           fun, false, prefun########################################
  
 SetIsInjective( map, true );
 
 ## Now creating java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 1
 
 if computeintertwiner then
        if (        if (HasIsCanonicalPolarSpace( 
            HasCollineationGroup( ps1 ) then
            
            hom := function( m )
                local image;
                image := BlownUpMat(basis, m!.mat);
                ConvertToMatrixRepNC( image, f2 );
                return CollineationOfProjectiveSpace(image, f2);
            end;
            java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 35
                local preimage;
                preimage := ShrinkMat(basis, Unpack(m!.mat));
                ConvertToMatrixRepNC( preimage, f1 );
                return CollineationOfProjectiveSpace(preimage, f1);
            
            g1 := IsometryGroup( ps1 );
            gens := GeneratorsOfGroup( g1 );
            newgens: (,hom;
            g2 := Group( newgens );
            SetSize(g2, Size(g1));
            twiner(g1, g2,hom )java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
            SetIntertwiner( map,Wvectors,mb,compl  , ,
        java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
 fi;

    return map;
 end );


first:userwantsparticular ,andbasis,  booltrue.
#############################################################################
#O  NaturalEmbeddingByFieldReduction( <geom1>, <f2>, <alpha>, <basis> )
# returns NaturalEmbeddingByFieldReduction( <geom1>, <f2>, <alpha>, <basis>, true )
#
InstallMethod (NaturalEmbeddingByFieldReduction,
 "for a polar space and a field, a finite field element, and a basis",
 [IsClassicalPolarSpace, IsField, IsFFE, IsBasis],
 function(ps1,f2,alpha,basis)
  return NaturalEmbeddingByFieldReduction(ps1,f2,alpha,basis,true);
 );

#second particular version: user wants a particular alpha, and bool, agrees with java.lang.StringIndexOutOfBoundsException: Index 83 out of bounds for length 52
### NaturalHomomorphismBySubspace code
#O  NaturalEmbeddingByFieldReduction( <geom1>, <f2>, <alpha>, java.lang.StringIndexOutOfBoundsException: Range [3, 4) out of bounds for length 3
# returns NaturalEmbeddingByFieldReduction( <geom1>, <f2>, <alphamb: MutableBasis( f )
#compl=[;
#
InstallMethod (NaturalEmbeddingByFieldReduction,
 "for a polar space and a field, a finite field element, and a boolean",
 [IsClassicalPolarSpace, IsField, IsFFE, IsBool],
 function(ps1,f2,alpha,bool)
  returnon(ps1,,,(AsVectorSpacefBaseField))bool;
 end );

#third particular version: user wants a particular alpha, agrees with basis and bool.
#######################################################################java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#O  NaturalEmbeddingByFieldReduction( <geom1>, <f2>, <alpha> )
 NaturalEmbeddingByFieldReductiongeom1>, f2,<alpha>, basis> true)
# where <basis> is the canonical basis of BaseField(geom1) over <f2#Matrixofthelinear we
#
 (NaturalEmbeddingByFieldReduction
 "for a polar space, a field, and a BasisVectors( canbas ));
 [IsClassicalPolarSpace, IsField, IsFFE],
 function(ps1,f2,alpha)
  return NaturalEmbeddingByFieldReduction(ps1,f2,alpha,Basis(AsVectorSpace(f2,BaseField(  local;java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  ;

# java.lang.StringIndexOutOfBoundsException: Range [31, 4) out of bounds for length 31
########################################## #          !
#O  NaturalEmbeddingByFieldReduction( <geom1>, <f2>, <bool> ) 
# returns NaturalEmbeddingByFieldReductionjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
# where <basis> is the canonical basis of BaseFieldy:= y[1]; 
# <one> is  #onvertToVectorRep(,f;
# want the java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 6
#
InstallMethod (NaturalEmbeddingByFieldReduction,
 "for a polar space, a field, and a  re =   java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
 [x :=(.)  c 
 functionif!. =  x:x;fi
  return NaturalEmbeddingByFieldReduction(ps1,f2,java.lang.StringIndexOutOfBoundsException: Range [0, 52) out of bounds for length 47
 end );

# fifth particular version: user agrees with everything
#####################################
#O  NaturalEmbeddingByFieldReduction( <geom1>, <f2ElementsOfIncidenceStructure(ps2), func, pre );
# returns NaturalEmbeddingByFieldReduction( <geom1>, <f2>, <alpha>, <basis>, true )
# where <basis> is the canonical basis of BaseField(geom1) over <f2>, and
# <alpha> is One(f2
#CHECKED 28// jdb
 "for a polar space and a field",
 I, IsField,
 function(ps1,f2)
  return NaturalEmbeddingByFieldReduction(ps1,f2,One(f2),Basis(AsVectorSpace(f2,BaseField(ps1))),true# Thisoperation just its namesake that itjava.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
 end );

# CHECKED 28/09/11 jdb
###############################################"for projective space and a singular subspace",
#O  NaturalEmbeddingByFieldReduction( <geom1>, <geom2> ) 
# returns NaturalEmbeddingByFieldReduction(<geom1>, <geom2> )
##
InstallMethod( NaturalEmbeddingByFieldReduction, 

 [ IsClassicalPolarSpace, IsClassicalPolarSpace ],
 function(geom1 geom2 )
  return NaturalEmbeddingByFieldReduction( geom1, geom2, true );
 end );

# ml 31/10/# ml 31/10/2013,mb ,gen,bas,img 
# newprefun2//jdb
################################# 
# O  NaturalEmbeddingByFieldReduction
# This NaturalEmbeddingByFieldReduction takes two polar spaces and returns an embedding
# obtained by field reduction if such an embedding existsb: !o;
##
InstallMethod (NaturalEmbeddingByFieldReduction,
 "for two classical polar spaces",
 [IsClassicalPolarSpace, IsClassicalPolarSpace, IsBool],
 function(ps1, ps2, computeintertwiner)

 #####################################################################
 #  List of possible embeddings of ps1 in# if vhas,   geometryjava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
 #
 #  Hermitian
 H- H (todd)
 #   H -> W (t even)
 #   H -> Q+ (t even, r even# This was adapted fromThomas Breuer's
 #   H -> Q- uralHomomorphismBySubspace code
 #
 #  Symplectic
 #   W -> W (always)
 #
 #  Orthogonal 
 # r even   
  + ->Q a)
 # Q- -> Q- (always)
 # r odd
 # Q -> Q (t odd, q odd)
 #   Q -> Q+ (t even, q odd)
 #   Q -> Q- (t even, q odd)
 #####################################################################

     type2form1 ,,newps,sigma map,
    gamma, bil1, q, n, alpha, basis, is_square, iso, form2, fun, prefun,
          c1, c2, cps2, cps2inv        #Compute  linearmapping by images.
     
 type1: (ps1;
 type2 := PolarSpaceType(ps2);
 if type1 in ["hyperbolic", "parabolic", "elliptic"] then 
    form1 := QuadraticForm(ps1);
 else
    form1 := SesquilinearForm(ps1);
 fi
    d1 :=              ( canbas))
 f1 := ps1!.basefield;
 f2 := ps2!.basefield;
 q := Size(f2);
 
 if not IsSubset(f1,              y := Lis : (.,->Coefficients,)*;  
    Error("Fields are y : SemiEchelonMat(y!vectors;java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
 fi;
 t := Log(Size(f1),q);
 r := ProjectiveDimension(ps1)+1;
 basis := ConvertToVectorRepy, f);
    is_square := function(x, f) return IsZero(x) or IsEvenInt(LogFFEelse
      
 if IsSesquilinearForm()then
        if type1 = "hermitian" and type2 = "hermitian" java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 17
   Info(InfoFinInG, 1, "These polar spaces are suitable for field reduction");
    # need alpha to be fixed by sigma:
   alpha := One(f1);
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
   form2 := HermitianFormFieldReduction(form1,f2,alpha,basis);
     elif type1 = "hermitian" and type2 = "symplectic" and
   Info(InfoFinInG, 1,  y)
   if IsEvenInt(q) then
    # need alpha to be fixed by sigma:
    alpha := One(f1);    
   else
    # need sigma(alpha)=-alpha
    sigma := Sqrt(Size(f1));
    alpha :ConvertToMatrixRepNC(x,);
   fi; 
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
            form2 := HermitianFormFieldReduction(form1,f2,alpha,basis);
  
     elif type1 = "hermitian" and type2 = "hyperbolic" and IsEvenInt(t) and IsEvenInt(r) 
    and IsOddInt(q) then
   Info(################################################
   alpha := One(f1)O  / <s> v )
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
             : HermitianFormFieldReduction(form1,f2,alpha,basis);
      
     elif type1 = "hermitiansubspace of <ps>
    and #
   Info(InfoFinInG, 1, "These polar spaces are suitable for field java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 22
   alpha := One(f1); 
  # : NaturalEmbeddingByFieldReduction(ps1,f2,alpha,basis )
            form2 := HermitianFormFieldReduction(form1,f2,alpha function(ps,v java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
   
     elifSubspacedoesnotbelongthe
   Info(InfoFinInG, 1, "These polar spaces are suitable  fi;
   alpha  (NaturalProjectionBySubspace ps,v  !geometryjava.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
            form2 := BilinearFormFieldReduction(form1,f2,alpha,basis);
        
    Error("These polar spaces are not java.lang.StringIndexOutOfBoundsException: Range [0, 46) out of bounds for length 20
  fi;
 #form1isa  form
  if type1 = "hyperbolic" and type2 = "hyperbolic" then
   Info(InfoFinInG, 1, "These polar spaces are suitable for field reduction");
   alpha := One(f1);
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
            form2 := QuadraticFormFieldReduction(form1,f2,alpha,basis);
  java.lang.StringIndexOutOfBoundsException: Range [24, 6) out of bounds for length 53
  Info(InfoFinInG, 1, "hesepolar spacesare suitable field reduction";
   alpha := One(f1);
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
            form2 :=   ## map from geometry of incidentwith v
  # tothe polar pace thesame  butoflesser  
   Info(InfoFinInG, 1, "These polar spaces are suitable for field java.lang.StringIndexOutOfBoundsException: Range [0, 75) out of bounds for length 48
   alpha := One(f1);
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
            form2 := QuadraticFormFieldReduction(form1,f2,alpha,basis);

  # If ps1 is  Error(v is ";
  # then the choice of alpha that we will use for the embedding
  # depends on the isometry type of ps1. The isometry type is determined by
  # gamma being a square or not, where gamma psdim =ps.;
  # (-1)^(r-1)/2 f: !basefield
  # b :Unpack(v!) cmat necessary infra
ion and linear sets  finite" preprint] they are
  # somewhat easier to work withif vdim =1 thenb=b;fi;

  elif type1 = "parabolic" and type2 = "hyperbolic" and IsEvenInt(t) and IsOddInt(q) then
   Info(InfoFinInG, 1, "These polar spaces are suitable for field reduction: Parabolic -> Hyperbolic");
   bil1:=; java.lang.StringIndexOutOfBoundsException: Range [52, 51) out of bounds for length 75
   # BilinearFormByQuadraticForm (see java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 0
   gamma:=(m:M java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 37
   if q^(t/2) mod 4 = 1 then # the product     for gen in BasisVectors( Basis( vs ) ) do
     : First(f1,a>not IsZero()andnotis_square( a*amma,f1 ))
   else # the product of alpha andAdd compl gen)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
    alpha := First(f1, a -> not IsZero(a) and is_square( a*gamma, f1 ) );
   fi;
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
            form2 := QuadraticFormFieldReduction(form1,f2,alpha,basis);

  liftype1 =""  ="lliptic" andIsEvenIntt IsOddIntq then
   Info(InfoFinInG, 1, "These polar spaces areimg= ( ,Length( compl  );
   bil1:=AssociatedBilinearForm(form1); # important to use this instead of 
   # BilinearFormByQuadraticForm (see documentation of the Forms package).
   gamma:=((-1)^((r-1)/2)) * Determinant(basimgs:= Concatenation( List( Wvectors- zero)
   if q^t/)mod  = 1then #the product of alpha andgamma must bea square
     alpha := First(f1, a -> not IsZero(a) and is_square( a*gamma, f1#onvertToMatrixRepbasimgs ) useles now.
  else#the productof andgammamustbe anonsquare
    alpha := First(f1, a -> not IsZero(a) java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 0
   fi;
   #map := NaturalEmbeddingByFieldReduction( ps1, f2, alpha, basis );
            : (form1f2,lpha,basis)

  else
  Error(  spacesarenotsuitable field .";
      fi; 
 fi;
 
 oCanonical )
    if not IsCanonicalPolarSpace(ps2(a*m* TransposedMat(CompanionAutomorphism(ps)), f);
        if type2 in ["parabolic", "hyperbolic", "elliptic"] then
            c2 := BaseChangeToCanonicalelse
        else
            c2 := BaseChangeToCanonicalSesquilinearForm(s2)java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
        fi;
        cps2 := c2^-1 * c1;
    else
        cps2 := c1;
    fi;
    cps2inv := cps2^-1;

     localy;         
        local mat1,mat2;
        mat1 := subspace!.obj;
        subspace!type =1then
            mat1 := [subspace!.obj];
        fi;
        java.lang.StringIndexOutOfBoundsException: Range [14, 1) out of bounds for length 33
                      (Subspaceisnot an ofpolar")
    end;

    #this version v =then return

    prefun := function( subspace ) # This map is the inverse of func and returns an error, or a subspace of geom1
        local                 : List(npack(!.)i Coefficients(as,)basimgs #matunpackhere
        flag:=true;
        if not subspace in ps2 then
            "he  is not  the  of field reduction !)java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
        ;
        if not IsInt((Dimension(subspace)+1)/t) then
            flag:=false;
        else
            basvecs:=BasisVectors(basis);
            vecs :                 fi;
            mat1 := List(vecs,x->List([1..d1],i->x{[(i-1)*t+1..i*t]}*basvecs));
            span := VectorSpaceToElement(AmbientSpace(ps2)fi;
            if not span = subspace then
                
            fi;
        fi;
        if flag = false then
           (is  map)
        fi;
        return VectorSpaceToElement(ps1,mat1);
    end;

    #iso := IsomorphismPolarSpacesNC(AmbientGeometry(Range(mapElementsOfIncidenceStructure(ps2), func, false, pre );
 #morphism := GeometryMorphismByFunction(ElementsOfIncidenceStructure(ps1),
    #                                   ElementsOfIncidenceStructure(ps2),
    #                                    x -> iso!.fun(map!.fun(x)), java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 8

 map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(ps1),
cturep)
                                            fun, false, prefun);
 SetIsInjective( map, true##Thisoperationis   its namesake except  itjava.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59

    if (HasIsCanonicalPolarSpace( ps1 ) and IsCanonicalPolarSpace( ps1 )) or
            ( ) then
        if computeintertwiner then
            hom := function( m )
                local image;
                image       [ IsClassicalPolarSpace, IsSubspaceOfClassicalPolarSpace ], 
                ConvertToMatrixRepNC( image, f2 );
                return CollineationOfProjectiveSpace(cps2 * image * cps2inv, f2);
            end;
            hominv := function( m )
                local preimage;
                preimage : ShrinkMat(basis,cps2inv *Unpack(!.at)* cps2)
                ConvertToMatrixRepNC( preimage, f1 );
                return CollineationOfProjectiveSpace pstype, psdim,b,vdim, vs,func,,
            end;
            g1 := IsometryGroup( ps1 );
             :=GeneratorsOfGroup g1)
            newgens := List(
            g2 : pstype :=PolarSpaceType) 
            SetSize(g2, java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
            twiner := GroupHomomorphismByFunction(g1, g2, hom, hominv);
            SetIntertwiner( map, twiner);
        fi;
    fi;

 SetIntertwiner(map, hom );
  
 return map;
end );

# added 2/7/14 jdb
#####################vs :VectorSpace(,perp(!obj)
# O  NaturalEmbeddingByFieldReduction
# This NaturalEmbeddingByFieldReduction takes two polar spaces and returns    ##ifvhas dimension j, then the new geometry 
# obtained by field reduction if such an embedding exists, otherwise it returns an error.
##
InstallMethod (java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 0
 "for two classical polar spaces",
 [IsClassicalPolarSpace, IsClassicalPolarSpace],
 function(ps1, ps2)
         NaturalEmbeddingByFieldReductionps1p,truejava.lang.StringIndexOutOfBoundsException: Range [62, 63) out of bounds for length 62
    end );


#################################################
#
#
# Embeddings by SUBFIELDS
#
#
#############################################################################


#y().ectors  
# found another cvec/cmat bug if!type  vdim =1then 
####java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
eddingBySubfieldgeom1,geom2 )
# returns the embedding of <geom1> in <geom2>, two projective spaces of the
# same dimension, over the fields K and L java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 0
# of K.
##
java.lang.StringIndexOutOfBoundsException: Range [14, 1) out of bounds for length 27
 "for two projective spaces",
eSpace]
 function( geom1, geom2 )
  local map, f1, f2, func, prefun, g1, g2,
          gens1, gens2, hom, twinerfunc, twinerprefun;
  f1 := geom1!.basefield; 
  f2 :=     map := Ge :=GeometryMorphismByFunction((ps,java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
  if geom1!.dimension  <> geom2!.dimension or not IsSubset(f2,f1) then  
   Error("Dimensions and/or field sizes are incompatible"); return;
  fi;
  
        func :=  x -> VectorSpaceToElement(geom2, Unpack(x!.obj)); #here an unpack is needed to avoid field incompatibilites.
  
        prefun := function( x )
            local xmat;
   if not ForAll( Flat(x!.obj), i -> i in f1 ) then
    Error("Element does not have all of its coordinates in ", f1);
   fi;
            =Unpackx.)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
            if x!.type = 1 then
                ConvertToVectorRep(xmat);
            
                ConvertToMatrixRep(xmat);
            fi;
 return (geom1 xmat ; # he same here.
  end;
  
        map: ( ElementsOfIncidenceStructure),
                                       ElementsOfIncidenceStructureifl. > orDimensionl. >3then
                                       func, false, prefun ); 
  SetIsInjective( map, true );

    ## Intertwiner...
    
  twinerfunc := function( x )
calxmat;
            if not IsOne(x!.frob) then
    Info(InfoFinInG, 1, "<el> is not in the source java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 16
                return fail;
            ;
            xmat := x!.mat;
            return CollineationOfProjectiveSpace( Unpack(x!.mat), f2 ); #here was an unpack needed!
        end;

  twinerprefun := function( y )
            local
            if not IsOne(y!.frob) then
    Info(InfoFinInG, 1, "#CHECKED 28// 
                return fail;
            fi;
           :Unpacky.) h too
            q :O  ( <>)
            if not q =# returns a  of vectorsspanning line  coordinates <java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
     (InfoFinInG,1,"el>is   the    intertwiner";
                return fail;
            fi;
            return cmat note: l will be an ordinary matrix
        end;
        
        g1 := ProjectivityGroup( geom1 );
  gens1 := GeneratorsOfGroup( g1 );
  gens2 := List(    [  ,
  g2 := Group(gens2);
  SetSize(g2, Size(g1));
  hom := GroupHomomorphismByFunction(g1, g2, twinerfunc, twinerprefun);    
  SetIntertwiner(map, hom);
   ;
 end );
  
# CHECKED 25/7/14 jdb. With new (and correct now) prefun. 
# cmat changes 21/3/14 and 24/3/2014, after a nice cultural weekend :-)
###################################################################   +5,  eachrow is uptoa.It  out
#O    needed factors arealways hesame:
# returns the embedding of <geom1> in <geom2>,  [1,1,1,1,1,-1]. This explains the '-' at newmat
  dimension    Kand respectively whereLisanextension
##   and latin  do  induce projectivity (,)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
# The prefun principle is taken from NaturalDualityHermitian.
##
InstallMethod( NaturalEmbeddingBySubfield, 
 "for two polar spaces and "for two polar spaces and /atins are   done  mapping  
 [ IsClassicalPolarSpace, IsClassicalPolarSpace, IsBool ],
 function(geom1,geom2, computeintertwiner 
  local map, f1, f2, q1   theimage    is      of Q+(5,q)
          r, type1, type2,#  swapsthegreeks/       of (,)
    change, invchange, basis, d, n, bmat, one, i, c1, c2,#
        
    #
    #  Check Kleidman and Liebeck Table 4.5.A
    #  There, the conditions on the polarity types can be found.
    #
          possible :
    #  W -> W
    #  W -> H (quadratic)
    #  O^eps -> H (q odd, quadratic)
    #  H -> H (odd degree)
     one := nef;
    #

  
  f2 := geom2!.basefield; q2 := Size(f2);       
  type1 := PolarSpaceType(geom1);
  type2 := PolarSpaceType(geom2);
  form2 := SesquilinearForm( geom2 ); #will be changed in last case only
  if geom1!.dimension = geom2!.dimension and IsSubset(f2, f1) then  
   r := LogInt(q2, q1);
   gram := GramMatrix( SesquilinearForm(geom1) );
   [ype1, type2]=[symplectic,h"  r=2then                   
    gamma := First( f2, t -> not IsZero(t) and IsZero(t^q1+ ps = (form)
    newgram pg :=ProjectiveSpace3f;
    form := HermitianFormByMatrix(newgram, f2);
   elif [type1, type2] = ["symplectic" plucker: 
    form  function(l java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
   elif [type1, type2] = ["hermitian", "hermitian"] and IsOddInt(r) then
    form := HermitianFormByMatrix(gram, f2);
   elif type1 in ["elliptic", "parabolic", "hyperbolic"] and 
    type2 = "hermitian" and r=2 and IsOddInt(q2) then
    form := HermitianFormByMatrix(gram, f2);
   elif (IsOddInt(r) and type2 in ["elliptic", "parabolic", "hyperbolic"] and 
    type1 = type2) or (java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 21
   [""",[parabolic","parabolic"]] 
    gram := GramMatrix( QuadraticForm(geom1) );return(pg )
    form := QuadraticFormByMatrix(gram, f2
    form2 := QuadraticForm(geom2);           
   else
  Error"ot  for these geometries\";
   fi;   
  else
   Error("Dimensions and/or field sizes are incompatible"); return;
  fi;
  
  :BaseChangeToCanonical ;
  if not IsCanonicalPolarSpace( geom2 ) then
   c2 := BaseChangeToCanonical( form2 );
   change := c2^-1 * c1;
  else
   change := c1;
  fi;
  invchange := change^-1;

  d := geom1!. newmat[4] := PluckerCoo(mat[3]mat[2]];
  basis := Basis(AsVectorSpace(f1,f2));
  n : Length(basis)
  bmat=[e,id1][i[]]y>());
  one := One(f1);
  for i in [1..d] do
   bmat[i,1+(java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
  od;

  func := function( el )
   return VectorSpaceToElement(geom2,Unpack(el!.obj) * invchange);
  end; 

  prefun := function( el )
   local vec,nvec,list,bgen;
   vec := 
   if el!.type = 1 then
    nvec := vec / First(vec,x->not IsZero(x));
    if not ForAll( nvec, i -> i in f1 ) then
  "isnot the   the geometry morphism");
    fi; 
    ConvertToVectorRepNC(nvec,f1); #necessary, also if appearantly vec is java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 36
   else
    bgen := BlownUpMat(basis,vec);
    list := SumIntersectionMat(bgen, bmat)[2]; #hard coded Meet operation :-)
    nvec := List(list,x->ShrinkVec(f2,f1,x));
    if not (IsMatrix(nvec) and Length(nvec) = el!.type) then
     #return fail;
     Error("Element is not in the range of the geometry morphism");
    fi;
    ConvertToMatrixRepNC(nvec,f1);
   fi;
   return VectorSpaceToElement(geom1,nvec);
  end;
  
  map := GeometryMorphismByFunction( ElementsOfIncidenceStructure(geom1), 
                                       ElementsOfIncidenceStructure(geom2),
                                       func, false, prefun ); 
  SetIsInjective( map, true );
 
     twinerfunc := function( x )
            local xmat;
            if not IsOne(x!.frob) then
    Info(InfoFinInG, 1, "<el> is not in the source of the intertwiner");
                return fail;
            fi;
            xmat := x!.mat;
            return CollineationOfProjectiveSpace( change * Unpack(x!.mat) * invchange, f2 ); #here was an unpack needed!
        end;

  twinerprefun := function( y )
            local ymat,q;
            if not IsOne(y!.frob) then
    Info(InfoFinInG, 1, "<el> is not in the range of the intertwiner");
                return fail;
            
            ymat := invchange * Unpack(y!.mat) * change; #here too!
            ymat := ymat/First(ymat[1],x->java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 2
   if ForAll(Flat(ymat)  ->   f1 )then
    Info(InfoFinInG, 1, "<el> is not in the range of the java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 58
   ,ie,cs, iept ;
   else
    ConvertToMatrixRepNC(ymat,f1);
                return CollineationOfProjectiveSpace(ymat,f1);
            fi;
        end
        
       if HasCollineationGroup(geom1 ) then
   g1 := SimilarityGroup( geom1 );
  =GeneratorsOfGroup(g1 )
   gens2 := List(gens1, twinerfunc );
   g2 := Group(gens2);
  ( Size();
   hom := GroupHomomorphismByFunction(g1, g2, twinerfunc, twinerprefun);    
   SetIntertwiner(map, hom);
  else
   Info ipts =List(ts,>mat;
  fi;
  
  return map;

 end );

# CHECKED 28/09/11 jdb
########################################## fi;
#O  NaturalEmbeddingBySubfield( <geom1>, <geom2> )
# returns NaturalEmbeddingBySubfield( <geom1>, <geom2>, true )
 =ieptxInversePluckerCoordinates));
InstallMethod( NaturalEmbeddingBySubfield, 
 "for two polar spaces",
 [IsClassicalPolarSpace,IsClassicalPolarSpace]
 function( geom1, geom2 )
  return NaturalEmbeddingBySubfield( geom1, geom2, true );
 end );


#############################################################################
#
# PROJECTIONS
#
#############################################################################

# CHECKED 28/09/11 jdb
#############################################################################
#O  NaturalProjectionBySubspace( <ps>, <v> )
#  themorphism theprojectivespace the  space of the 
# subspace <v>. It is checked if <v> is a moment I recycle the interwiner from the appropriate'java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
InstallMethod( NaturalProjectionBySubspace, 
 "for a projective  twinerprefun, coll1, g   ,;
 [ IsProjectiveSpace, IsSubspaceOfProjectiveSpace ], 
 function(ps, v)

  ## maphe formfor the resultingPluckercoordinatesis 
  ## to the projective space java.lang.StringIndexOutOfBoundsException: Range [0, 31) out of bounds for length 25

    local psdim,  mat := NullMat(6,6 f)
          Wvectors, for in 1.]do
          canbas, zero, basimgs, ps2 mat[,-]: ;
    if not v in ps then
       Error("<v> is not an element of <ps>");
    fi;
    psdim := ps!.dimension;
    f := ps!.basefield;
    b := Unpack(v!.obj)
    vdim := v!.type;  
    if vdim = 1 then b:=[b]; fi;
    vs := ps!.vectorspace;
    sub := Subspace(vs, b);  
   
    ## if v has dimension j, then the new geometry 
    ## has dimension psdim - vdim

    ps2 := ProjectiveSpace( psdim - vdim, ec[]) ([lvec,[]), ([,]];

      ## This code was adapted from Thomas Breuer's 
      ## "NaturalHomomorphismBySubspace" code
   
    Wvectors:= b;
    mb:= MutableBasis( f, Wvectors );
    compl=[];
    for gen in BasisVectors( Basis( vs ) ) do
        if not IsContainedInSpan( mb, gen ) then
          Add( compl, gen );
          CloseMutableBasis( mb, gen );
        fi;
    od;
    bas := BasisNC( vs, Concatenation( Wvectors, compl ) );

        # Compute the linear mapping by images.
    img:= FullRowModule( f, Length( compl  t : el.typejava.lang.StringIndexOutOfBoundsException: Range [17, 18) out of bounds for length 17
    canbas:= CanonicalBasis( img );
    zero:= Zero( img );
ixof the lineartransformationwant
    basimgs:= Concatenation( ListWithIdenticalEntries( Size(Wvectors), zero  return (pg,)
                             BasisVectors( java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 18

    func := function( x )
  local y;         
spac =Meetl)
   Error("Subspace is not incident with the subspace   (space) 
  fi;
        y := List(Unpack(Unwrap(x)),i-> Coefficients(bas,i))*basimgs;  #was x^_, now UnWrap(x), cmat unpack
        if not IsEmpty( return space
            fi;
           ##       rank, whereas SemiEchelonMat does!
       y := SemiEchelonMat(y)!.vectors;  ## JB: 3/11/2012. Moved this line from the "else" to here so it also applies to the first case.

   if x!.type - vdim = 1 then 
    y := y[1]; 
    #ConvertToVectorRep(y, f);
 fijava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
   #else
   # (y,f)
   #fi;
        fi;
  if not IsEmpty(y) then  
  #return Wrap(ps2,x!. -vdim ;
            return VectorSpaceToElement(ps2,y);
   else  
    return EmptySubspace(ps2);
   fi;
  end;
  ##########################################
   local x;          
            x := Unpack(y!.obj);  #cmat unpack
            if y!.type = 1 then x := [x]; fi;
            x :=  Concatenation(x * compl, b); 
            #ConvertToMatrixRepNC(x, f);
            return VectorSpaceToElement(ps, x);
 end;
  map := GeometryMorphismByFunctionq - KleinCorrespondenceExtendedG(q,
                                      java.lang.StringIndexOutOfBoundsException: Range [1, 66) out of bounds for length 3
  return map;
 end );

# CHECKED 28/09/11 jdb
#############################################################################
#O  NaturalProjectionBySubspaceNC( <ps>, <v> )
## This operation is just like its namesake except that it 
## has no checks
##
InstallMethod( NaturalProjectionBySubspaceNCfor  andaboolean,
 "for a projective space and a singular subspace",
 [ IsProjectiveSpace, IsSubspaceOfProjectiveSpace ], 
 function(ps, v)

  ## map from geometry of elements incident with v
  ## to the projective space of lesser dimension 

 local psdim,b vdim,  ,,
          Wvectors, mb, compl, gen, bas, img, 
          canbas, zero, basimgs, ps2, map, hom, f;
  
    psdim := ps!.dimension;
    f :# x1x6+2x5+3x4=0
    b := v!.obj;
    vdim := v!.type;  
    if vdim = 1 then b:=[b]; fi;
    s =ps!.ectorspace;
    sub := Subspace(vs, b);  
   
    ## if v has dimension j, then the new geometry 
    ## has dimension psdim - vdim

    ps2 := ProjectiveSpace( psdim - vdim, f );

      pg : ProjectiveSpace(3,f;
      ## "java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 11
   
    Wvectors:= b;
    mb:= MutableBasis( f, Wvectors );
    compl: []
    for gen in BasisVectors( Basis( vs ) ) do
        if not IsContainedInSpan( mb, gen ) then
          Add( compl, gen );
          CloseMutableBasis( mb, gen );
        fi;
    od;
   bas :BasisNC(vs (Wvectors );

        # Compute the linear mapping by images.
    img=FullRowModule( , ( ) )
    canbas:= CanonicalBasis( img );
    zero:= Zero( img );
        # Matrix of the linear transformation we want
    basimgs:= Concatenation( ListWithIdenticalEntries( Size(Wvectors), zero ),
                             BasisVectors( canbas ) );

    func := function( x )
              local y;         
              y := List(x!.obj,i-> Coefficients(bas,i))*basimgs;   
              y := SemiEchelonMat(y)!.vectors;     
              if x!.type - vdim = 1 then 
                 y := y[1]; 
                 ConvertToVectorRep(y, f);
              else
                 ConvertToMatrixRepNC(y, f);
              fi;
     if not IsEmpty(y) then  
    Wrap(s2,x. -,y)
           else  
        return EmptySubspace(ps2);
     fi;
   end;

    pre := function( y )
              local x;          
              x := y!.obj; 
              if y!.type = 1 then x := [x]; fi;
              x :=  Concatenation(x * compl, b); 
              ConvertToMatrixRepNC(x, f);
              return VectorSpaceToElement(ps, x);
           end;

    map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(ps), 
                                      
    map;
  end );

# CHECKED 28/09/11 jdb
##############################################java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
#O  \/( <ps>, <v> )
# returns the quotient space of the subspace <v> of the projective space <ps>
# 
##
nstallOtherMethod,
 "for a projective space and a subspace",
 [ IsProjectiveSpace and IsProjectiveSpaceRep, IsSubspaceOfProjectiveSpace],
 function( ps, v )
  if not v java.lang.StringIndexOutOfBoundsException: Range [0, 13) out of bounds for length 1
  ("  notbelong to theprojectivespace";
  fi;
  return Range( NaturalProjectionBySubspace( ps, v ) )!.geometry;
 end );

# CHECKED 28/09/11 jdb
#cmat change 21/3/14
#############################################################################
#O  NaturalProjectionBySubspace( <ps>, <v> )
# returns the morphism from the polar space to the quotient space of the 
# subspace <v>. It is checked if <v> is a subspace of <ps>.
##
InstallMethod( NaturalProjectionBySubspace, 
    "for a polar space and a subspace",
    [ IsClassicalPolarSpace, IsSubspaceOfClassicalPolarSpace ], 
 function(ps, v)

  ## map from geometry of elements incident with v
  ## to the polar space of the same type but of lesser dimension 
    local pstype, psdim, b, vdim, vs, func, pre,
          Wvectors, mb, compl, gen, bas, img, canbas, zero, basimgs,
          ps2, map, hom, a, m, newform, f, perp;
    if not v in ps then
  Error("<v> is not an element of <ps>");
    fi;
    pstype := PolarSpaceType(ps); 
    psdim := ps!.dimension;
    f := ps!.basefield;
    b := Unpack(v!.obj); #cmat unpack necessary for infra.
    vdim := v!.type;  
    if vdim = 1 then b:=[b]; fi; 
    perp := PolarMap(ps);
    vs := VectorSpace(f, Unpack(perp(v)!.obj)); #PolarMap maps to elements, containing a cmat.

    ## if v has dimension j, then the new geometry 
    ## has dimension psdim - 2*vardim

    Wvectors:= b;
    mb:= MutableBasis( f, Wvectors );
    compl:= [];
    for gen in BasisVectors( Basis( vs ) ) do
        if not IsContainedInSpan( mb, gen ) then
          Add( compl, gen );
          CloseMutableBasis( mb, gen );
        fi;
    od;
    bas := BasisNC( vs, Concatenation( Wvectors, compl ) );

    # Compute the linear mapping by images.
    img:= FullRowModule( f, Length( compl ) );
    canbas:= CanonicalBasis( img );
    zero:= Zero( img );
    # Matrix of the linear transformation we want
    basimgs:= Concatenation( List( Wvectors, v -> zero ),
                             BasisVectors( canbas ) );
    #ConvertToMatrixRep(basimgs, f); #useles now.
    a := compl;

    if HasQuadraticForm( ps ) then
       m := QuadraticForm(ps)!.matrix;   
       newform := QuadraticFormByMatrix(a * m * TransposedMat(a), f);
    else
       m := SesquilinearForm(ps)!.matrix; 
       if pstype = "hermitian" then   
          #newform := HermitianFormByMatrix(a^CompanionAutomorphism(ps) * m * TransposedMat(a), f); #finally found the bug, jdb gets thirrrrrrsty now.
    newform := HermitianFormByMatrix(a * m * TransposedMat(a^CompanionAutomorphism(ps)), f);

       else
          newform := BilinearFormByMatrix(a * m * TransposedMat(a), f);
       fi;
    fi;
    ps2 := PolarSpace( newform );  
  
  
    func := function( x )
              local y;         
              if not v in x then
                 Error("Subspace is not incident with the subspace of projection");
              fi;
              if not x in ps then
                 Error("Subspace is not an element of the polar space");
              fi;
              if v = x then return
                 EmptySubspace(ps2); 
              else
                 y := List(Unpack(x!.obj),i-> Coefficients(bas,i))*basimgs;  #cmat unpack here
                 y := SemiEchelonMat(y)!.vectors;   
                 if x!.type - vdim = 1 then 
                    y := y[1]; 
                    #ConvertToVectorRep(y, f);
                 #else
                 #   ConvertToMatrixRepNC(y, f);
                 fi;
                 return VectorSpaceToElement(ps2, y);
              fi;
           end;

    pre := function( y )
              local x;   
              if not y in ps2 then
                 Error("Subspace is not an element of the polar space");
              fi;
              x := Unpack(y!.obj); #cmat unpack here.
              if y!.type = 1 then x := [x]; fi;
              x := Concatenation(x * compl, StructuralCopy( b )); 
              #ConvertToMatrixRepNC(x, f); #useless now.
              return VectorSpaceToElement(ps, x);
            end;
    map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(ps), 
                                      ElementsOfIncidenceStructure(ps2), func, false, pre );
    return map;
  end );

# CHECKED 28/09/11 jdb
#############################################################################
#O  NaturalProjectionBySubspaceNC( <ps>, <v> )
## This operation is just like its namesake except that it 
## has no checks
##
InstallMethod( NaturalProjectionBySubspaceNC, 
      "for a polar space and a singular subspace",
      [ IsClassicalPolarSpace, IsSubspaceOfClassicalPolarSpace ], 
  function(ps, v)

  ## map from geometry of elements incident with v
  ## to the polar space of the same type but of lesser dimension 

    local pstype, psdim, b, vdim, vs, func, pre,
          Wvectors, mb, compl, gen, bas, img, canbas, zero, basimgs,
          ps2, map, hom, a, m, newform, f, perp;
  
    pstype := PolarSpaceType(ps); 
    psdim := ps!.dimension;
    f := ps!.basefield;
    b := v!.obj;
    vdim := v!.type;  
    if vdim = 1 then b:=[b]; fi; 
    perp := PolarMap(ps);
    vs := VectorSpace(f, perp(v)!.obj);

    ## if v has dimension j, then the new geometry 
    ## has dimension psdim - 2*vdim

    Wvectors:= b;
    mb:= MutableBasis( f, Wvectors );
    compl:= [];
    for gen in BasisVectors( Basis( vs ) ) do
        if not IsContainedInSpan( mb, gen ) then
          Add( compl, gen );
          CloseMutableBasis( mb, gen );
        fi;
    od;
    bas := BasisNC( vs, Concatenation( Wvectors, compl ) );

    # Compute the linear mapping by images.
    img:= FullRowModule( f, Length( compl ) );
    canbas:= CanonicalBasis( img );
    zero:= Zero( img );
    # Matrix of the linear transformation we want
    basimgs:= Concatenation( List( Wvectors, v -> zero ),
                             BasisVectors( canbas ) );
    ConvertToMatrixRep(basimgs, f);
    a := compl;

    if HasQuadraticForm( ps ) then
       m := QuadraticForm(ps)!.matrix;   
       newform := QuadraticFormByMatrix(a * m * TransposedMat(a), f);
    else
       m := SesquilinearForm(ps)!.matrix; 
       if pstype = "hermitian" then   
          newform := HermitianFormByMatrix(a * m * TransposedMat(a^CompanionAutomorphism(ps)), f);
       else
          newform := BilinearFormByMatrix(a * m * TransposedMat(a), f);
       fi;
    fi;
    ps2 := PolarSpace( newform );  
  
    func := function( x )
              local y;         
              y := List(x!.obj,i-> Coefficients(bas,i))*basimgs;
              y := SemiEchelonMat(y)!.vectors;  
              if x!.type - vdim = 1 then 
                 y := y[1]; 
                 ConvertToVectorRepNC(y, f);
              else
                 ConvertToMatrixRepNC(y, f);
              fi;
              return VectorSpaceToElement(ps2, y);
            end;

    pre := function( y )
              local x;          
              x := y!.obj; 
              if y!.type = 1 then x := [x]; fi;
              x := Concatenation(x * compl, StructuralCopy( b )); 
              ConvertToMatrixRepNC(x, f);
              return VectorSpaceToElement(ps, x);
            end;
    map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(ps), 
                                      ElementsOfIncidenceStructure(ps2), func, false, pre );
    return map;
  end );

#############################################################################
#
# Klein correspondence
#
#############################################################################

#############################################################################
# two helper operations. They can be used by the users, but on the other hand
# the form of the Klein quadric is fixed, so this is against the philiosphy of
# FinInG, at least for user functions. Also, there are no checks. So we will 
# describe these in the technical section of the documentation.
#############################################################################

# CHECKED 28/09/11 jdb
# changed 28/3/14 jdb
#############################################################################
#O  PluckerCoordinates( <lobj> )
# returns the Plucker coordinates of the line represented by <lobj>. We accept 
# a matrix representing the line. No check on whether this is a line of PG(3,q),`
# so use with care. cmat note: whether l is a cmat or not, coords will be a plain 
# list (so no cvec). This is the internal version accepting a matrix.
##
InstallMethod( PluckerCoordinates, 
 "for a matrix representing a line of PG(3,q)",
    [ IsMatrix ],
 function( lobj )
  local pij, u, v, coords;
  pij := function(u,v,i,j)
   return u[i]*v[j] - u[j] * v[i];
  end;
  u := lobj[1];
  v := lobj[2];
  coords := [pij(u,v,1,2),pij(u,v,1,3),pij(u,v,1,4),
   pij(u,v,2,3),pij(u,v,4,2),pij(u,v,3,4)];
  return coords;
 end );

# CHECKED 28/09/11 jdb
# changed 28/3/14 jdb
#############################################################################
#O  PluckerCoordinates( <line> )
# returns the Plucker coordinates of the line represented by <lobj>. We accept 
# a matrix representing the line. No check on whether this is a line of PG(3,q),`
# so use with care. cmat note: whether l is a cmat or not, coords will be a plain 
# list (so no cvec). This is the user version accepting a subspace of a projective
# space.
##
#InstallMethod( PluckerCoordinates,
# "for a matrix representing a line of PG(3,q)",
#    [ IsSubspaceOfProjectiveSpace ],
# function( l )
#  local pij, u, v, coords,lobj;
#  if l!.type <> 2 or Dimension(l!.geo) <> 3 then
#           Error(" <l> must be a line of a PG(3,q)");
#        fi;
#        lobj := l!.obj;
#        pij := function(u,v,i,j)
#   return u[i]*v[j] - u[j] * v[i];
#  end;
#  u := lobj[1];
#  v := lobj[2];
#  coords := [pij(u,v,1,2),pij(u,v,1,3),pij(u,v,1,4),
#   pij(u,v,2,3),pij(u,v,4,2),pij(u,v,3,4)];
#  return coords;
# end );


# CHECKED 28/09/11 jdb
# changed 28/3/14 jdb
#############################################################################
#O  InversePluckerCoordinates( <var> )
# returns a list of two vectors spanning the line with Plucker coordinates <var>
# no check on whether this is really a line of the particular Q+(5,q):X0X5+X1X4+X2X3
# caution: the list l is not Triangulized!
# cmat note: l will be an ordinary matrix.
##
InstallMethod( InversePluckerCoordinates, 
 "for a vector repr. a point of Q+(5,q): X0X5+X1X4+X2X3=0",
    [ IsVector ],

   ## The point must satisfy the Pluecker relation x1x6+x2x5+x3x4=0.
 function( x )
  local pairs, i, pair, l, f, zero;
  pairs := [[1,2],[1,3],[1,4],[2,3],[4,2],[3,4]];
  i := PositionNonZero(x);
  pair := pairs[i];
  zero := Zero(x[1]);
        l := [];
  if 1 in pair then
   Add(l, [ zero, x[1], x[2], x[3] ]);
  fi;
  if 2 in pair then
   Add(l, [ x[1], zero, -x[4], x[5] ]);
  fi;
  if 3 in pair then
   Add(l, [ x[2], x[4], zero, -x[6] ]);
  fi;
  if 4 in pair then
   Add(l, [ x[3], -x[5], x[6], zero ]);
  fi;
  return l;
 end );

#############################################################################
# Klein correspondence: the user operations.
#############################################################################

# added may 2014 jdb
#############################################################################
#O  PluckerCoordinates( <l> )
# returns the Plucker coordinates of the line <l>. The is the user variant
# of the operation. It accepts a line of PG(3,q), does some checking, and
# uses the helper operation.
##
InstallMethod( PluckerCoordinates, 
 "for a line of PG(3,q)",
    [ IsSubspaceOfProjectiveSpace ],
 function( l )
  if Dimension(AmbientSpace(l)) <> 3 then
   Error("<l> is not a line of a three dimensional projective space");
  elif l!.type <> 2 then
   Error("<l> is not a line");
  fi;
  return PluckerCoordinates(l!.obj);
 end );

# added may 2014 jdb
#############################################################################
#O  KleinCorrespondence( <f>, <computeintertwiner> )
# returns the well known morphism from the lines of PG(3,f), f a finite field
# to the points of Q+(5,q): x0x5+x1x4+x2x3 = 0. This is the bare essential 
# of some geometry morphisms that follow. For didactical reasons, it looks 
# useful to me to have this version that maps to a fixed hyperbolic quadric. 
# Of course a flexible verion of this operation is also present.
##
# The interwiner: - the frobenius automorphism commutes with taking PluckerCoordinates
#     so we only have to deal with the matrices in the twiner/pretwiner
#     funcs.
#      - A projectivity is known if its image of a frame is known. So:
#     going from PGL(4,q) -> PGO+(6,q): the standard basepoints of PG(5,q)
#     are points of the quadric, compute the lines (InversePlucker), their image,
#     , computer the point (Plucker), this gives the matrix of the element
#     of PGO+(5,q) where each row is determined up to a factor. It turns out
#     using order as in twinerfunc, the needed factors are always the same:
#     [1,1,1,1,1,-1]. This explains the '-' at newmat[6] line.
#     going from PGO+(5,q) -> PGL(4,q): cave canem: projectivities swapping
#     greek and latin planes do not induce a projectivity of PG(3,q)!
#     The principle is the same as above, just more work is needed to compute
#     the factors here (they seem not to be independant of the group element now).
#     Checking whether greek/latins are swapped is done by mapping a point
#     to a generator, computing the image, mapping back, and see whether
#     the three lines span PG(3,q). If so, we have the point, if not,
#     the image of the point is a plane and the projectivity of Q+(5,q)
#     swaps the greeks/latins and induces in fact a correlation of PG(3,q).
##
InstallMethod( KleinCorrespondence, 
 "for a finite field and a boolean",
    [ IsField, IsBool ],
 function( f, computeintertwiner )
  local i, form, map, pg, mat, pre, plucker, ps, inv, one, twinerfunc, 
  twinerprefun, coll1, gens1, coll2, gens2, hom, id;
  
  one := One(f);

    ## The form for the resulting Plucker coordinates is 
    ## x1x6+x2x5+x3x4 = 0
 
  mat := NullMat(6, 6, f);
  for i in [1..3] do
   mat[i,7-i] := one;
  od;
  form := QuadraticFormByMatrix(mat, f);
  ps := PolarSpace( form );
  pg := ProjectiveSpace(3,f);
  
  plucker := 
           function( l )
             local pt1;
             pt1 := PluckerCoordinates( l!.obj );
             return VectorSpaceToElement(ps, pt1);
           end;
  
  inv := 
           function( x )
             local l;
             l := InversePluckerCoordinates( x!.obj );
             return VectorSpaceToElement(pg, l);
           end;
  
  map := GeometryMorphismByFunction(Lines(pg), Points(ps), plucker, inv);
  SetIsBijective(map, true);
  
  twinerfunc := function(g)
   local mat,newmat;
   mat := Unpack(g!.mat);
   newmat := [];
   newmat[1] := PluckerCoordinates([mat[2],mat[1]]);
   newmat[2] := PluckerCoordinates([mat[3],mat[1]]);
   newmat[3] := PluckerCoordinates([mat[4],mat[1]]);
   newmat[4] := PluckerCoordinates([mat[3],mat[2]]);
   newmat[5] := PluckerCoordinates([mat[4],-mat[2]]);
   newmat[6] := -PluckerCoordinates([-mat[4],mat[3]]);
   return ProjElWithFrob(newmat,g!.frob,f);
  end;
  
  id := IdentityMat(4, f);
  
  twinerprefun := function( g )
   local mat, newmat, lines, pts, ipts, ilines, e, x, ept,
    ielines, ie, cs, iept;
   mat := Unpack(g!.mat);
   lines:= [];
   lines[1] := [[id[1],id[2]],[id[1],id[3]],[id[1],id[4]]];
   lines[2] := [[id[2],id[3]],[id[2],id[4]]];
   lines[3] := [[id[3],id[4]],[id[3],id[1]]];
   lines[4] := [[id[4],id[1]],[id[4],id[2]]];
   pts := List(lines,x->List(x,y->PluckerCoordinates(y)));
   ipts := List(pts,x->x*mat);
   ilines := List(ipts,x->List(x,y->InversePluckerCoordinates(y)));
   if Rank(Union(ilines[1])) = 3 then
    Info(InfoFinInG, 1, "<el> is not inducing a collineation of PG(3,q)");
    return fail;
   fi;
   ipts := List(ilines, x->SumIntersectionMat(x[1],x[2])[2]);
   newmat := List(ipts,x->x[1]);
   e := [1,1,1,1]*one;
   ept := List([[e,id[1]],[e,id[2]]],y->PluckerCoordinates(y));
   iept := List(ept,x->x*mat);
   ielines := List(iept,x->InversePluckerCoordinates(x));
   ie := SumIntersectionMat(ielines[1],ielines[2])[2];
   cs := SolutionMat(newmat,ie[1]);
   for i in [1..4] do
    newmat[i] := newmat[i]*cs[i];
   od;
   return ProjElWithFrob(newmat,g!.frob,f);
  end;

  if computeintertwiner then
   coll1 := CollineationGroup(PG(3,f));
   gens1 := GeneratorsOfGroup(coll1);
   gens2 := List(gens1, twinerfunc);
   coll2 := GroupWithGenerators(gens2);
   hom := GroupHomomorphismByFunction(coll1, coll2, twinerfunc, twinerprefun);
   SetIntertwiner( map, hom );
  fi;
  
  return map;
 end );

#############################################################################
#O  KleinCorrespondence( <q> )
# returns KleinCorrespondence( GF(q), true )
##
InstallMethod( KleinCorrespondence, 
 "for a prime power",
    [ IsPosInt ],
 q -> KleinCorrespondence(GF(q),true)
 );
 
#############################################################################
#O  KleinCorrespondence( <q> )
# returns KleinCorrespondence( GF(q), computeintertwiner )
##
InstallMethod( KleinCorrespondence, 
 "for a prime power and a boolean",
    [ IsPosInt, IsBool ],
 function(q, computeintertwiner )
  return KleinCorrespondence(GF(q),computeintertwiner);
 end );
    
#############################################################################
#O  KleinCorrespondence( <f> )
# returns KleinCorrespondence( GF(q), true )
##
InstallMethod( KleinCorrespondence, 
 "for a finite field",
    [ IsField ],
 f -> KleinCorrespondence(f,true)
 );

 
# CHECKED 28/09/11 jdb
#############################################################################
#O  KleinCorrespondence( <quadric>, <computeintertwiner> )
# returns the well known morphism from the lines of PG(3,q) to the points
# of Q+(5,q). Of course, the bilinear form determining the latter, can be chosen
# by the users. This method is exactly the same as the method for 
#  KleinCorrespondence( <f>, <computeintertwiner> ), but adds base changes.
##
InstallMethod( KleinCorrespondence, 
 "for a hyperbolic quadric and a boolean",
 [ IsClassicalPolarSpace, IsBool ],
 function( quadric, computeintertwiner )
  local f, i, form, map, pg, mat, twinerfunc, twinerprefun,
   pre, func, ps, iso, one, c, c1, c2, id, cinv, coll1, gens1,
   coll2, gens2, hom;
  if ProjectiveDimension(quadric) <> 5 then
   Error("<ps> is not Klein's quadric");
  fi;
  if not IsHyperbolicQuadric(quadric) then
      Error("<ps> is not Klein's quadric");
  fi;
  f := quadric!.basefield;
  one := One(f);

    ## The form for the resulting Plucker coordinates is 
    ## x1x6+x2x5+x3x4 = 0
 
  mat := NullMat(6, 6, f);
  for i in [1..3] do
   mat[i,7-i] := one;
  od;
  form := QuadraticFormByMatrix(mat, f);
  ps := PolarSpace( form );
  c1 := BaseChangeToCanonical( form );
  if not IsCanonicalPolarSpace(quadric) then
   c2 := BaseChangeToCanonical(QuadraticForm(quadric));
   c := c2^-1 * c1;
  else
   c := c1;
  fi;
  cinv := c^-1;
  pg := ProjectiveSpace(3,f);
  
  func := function( el )
   local pt1;
   if el!.type <> 2 then
    Error("<el> is not a line ");
   fi;
   pt1 := PluckerCoordinates( el!.obj );
   return VectorSpaceToElement(quadric, pt1 * cinv ); #base change is here
        end;
  
  pre := function( el )
   local l;
   if el!.type <> 1 then
    Error("<el> is not a point ");
   fi; 
   l := InversePluckerCoordinates( el!.obj * c ); #base change is here
   return VectorSpaceToElement(pg, l);
        end;
  
  map := GeometryMorphismByFunction(Lines(pg), Points(quadric), func, pre);
  SetIsBijective(map, true);
  
  twinerfunc := function(g)
   local mat,newmat,frob;
   mat := Unpack(g!.mat);
   frob := g!.frob;
   newmat := [];
   newmat[1] := PluckerCoordinates([mat[2],mat[1]]);
   newmat[2] := PluckerCoordinates([mat[3],mat[1]]);
   newmat[3] := PluckerCoordinates([mat[4],mat[1]]);
   newmat[4] := PluckerCoordinates([mat[3],mat[2]]);
   newmat[5] := PluckerCoordinates([mat[4],-mat[2]]);
   newmat[6] := -PluckerCoordinates([-mat[4],mat[3]]);
   return ProjElWithFrob(c * newmat * cinv^frob,frob,f); #base change is here.
  end;
  
  id := IdentityMat(4, f);
  
  twinerprefun := function( g )
   local mat, newmat, lines, pts, ipts, ilines, e, x, ept,
    ielines, ie, cs, iept, frob;
   frob := g!.frob;
   mat := cinv * Unpack(g!.mat) * c^frob;      #base change is here.
   lines:= [];
   lines[1] := [[id[1],id[2]],[id[1],id[3]],[id[1],id[4]]];
   lines[2] := [[id[2],id[3]],[id[2],id[4]]];
   lines[3] := [[id[3],id[4]],[id[3],id[1]]];
   lines[4] := [[id[4],id[1]],[id[4],id[2]]];
   pts := List(lines,x->List(x,y->PluckerCoordinates(y)));
   ipts := List(pts,x->x*mat);
   ilines := List(ipts,x->List(x,y->InversePluckerCoordinates(y)));
   if Rank(Union(ilines[1])) = 3 then
    Info(InfoFinInG, 1, "<el> is not inducing a collineation of PG(3,q)");
    return fail;
   fi;
   ipts := List(ilines, x->SumIntersectionMat(x[1],x[2])[2]);
   newmat := List(ipts,x->x[1]);
   e := [1,1,1,1]*one;
   ept := List([[e,id[1]],[e,id[2]]],y->PluckerCoordinates(y));
   iept := List(ept,x->x*mat);
   ielines := List(iept,x->InversePluckerCoordinates(x));
   ie := SumIntersectionMat(ielines[1],ielines[2])[2];
   cs := SolutionMat(newmat,ie[1]);
   for i in [1..4] do
    newmat[i] := newmat[i]*cs[i];
   od;
   return ProjElWithFrob(newmat,g!.frob,f);
  end;

  if computeintertwiner then
   coll1 := CollineationGroup(PG(3,f));
   gens1 := GeneratorsOfGroup(coll1);
   gens2 := List(gens1, twinerfunc);
   coll2 := GroupWithGenerators(gens2);
   hom := GroupHomomorphismByFunction(coll1, coll2, twinerfunc, twinerprefun);
   SetIntertwiner( map, hom );
  fi;

  return map;

 end );

#############################################################################
#O  KleinCorrespondence( <quadric> )
# returns KleinCorrespondence( <quadric>, true )
##
InstallMethod( KleinCorrespondence, 
 "for a hyperbolic quadric",
    [ IsClassicalPolarSpace ],
 quadric -> KleinCorrespondence(quadric, true)
 );

# added may 2014 jdb.
#############################################################################
#O  KleinCorrespondenceExtended( <f>, <computeintertwiner> )
# I had really a lot of fun with the above methods and the mathematics behind.
# Therefore I decided to include an "extension" which also computes the image
# of points and planes of PG(3,q) under the Klein correspondence. This morphism
# becomes an isomorphism from PG(3,q) as incidence geometry to the incidence
# geometry consisting of the points and the two systems of generators of Q+(5,q).
# All mathematics is explained in the KleinCorrespondence variants above. For the 
# moment I recycle the interwiner from the appropriate KleinCorrespondence's.
# When I will have more time, I'll maybe implement the interwiner from the
# CorrelationCollineationGroup(PG(3,q)) to PGO+(6,q). 
##
InstallMethod( KleinCorrespondenceExtended, 
 "for a field and a boolean",
    [ IsField, IsBool ],
 function( f, computeintertwiner )
  local i, form, map, pg, mat, pre, func, ps, one, twinerfunc, 
  twinerprefun, coll1, gens1, coll2, gens2, hom, em;
  
  one := One(f);

    ## The form for the resulting Plucker coordinates is 
    ## x1x6+x2x5+x3x4 = 0
 
  mat := NullMat(6, 6, f);
  for i in [1..3] do
   mat[i,7-i] := one;
  od;
  form := QuadraticFormByMatrix(mat, f);
  ps := PolarSpace( form );
  pg := ProjectiveSpace(3,f);
  
  func := function( el )
   local t, vec, newvec, ptvec, elvec;
   t := el!.type;
   elvec := Unpack(el!.obj);
   if t = 1 then
    vec := BasisVectors(Basis(Lines(el)!.factorspace));
    newvec := [PluckerCoordinates([elvec,vec[1]]), PluckerCoordinates([elvec,vec[2]]), PluckerCoordinates([elvec,vec[3]])];
    return VectorSpaceToElement(ps,newvec);
   elif t = 2 then
    return VectorSpaceToElement(ps,PluckerCoordinates(elvec));
   elif t = 3 then
    newvec := [PluckerCoordinates( elvec{[1,2]}), PluckerCoordinates( elvec{[2,3]} ), PluckerCoordinates( elvec{[1,3]} )];
    return VectorSpaceToElement(ps,newvec);
   fi;
  end;
  
  pre := function( el )
   local elvec,t,newvec,lines,space;
   t := el!.type;
   elvec := Unpack(el!.obj);
   if t = 1 then
    newvec := InversePluckerCoordinates( elvec );
    return VectorSpaceToElement(pg, newvec);
   elif t = 3 then
    newvec := List(elvec,x->InversePluckerCoordinates( x ));
    lines := List(newvec,x->VectorSpaceToElement(pg,x));
    space := Meet(lines);
    if IsEmptySubspace(space) then
     return Span(lines);
    else
     return space;
   
   elif t = 2 then
    Error("Lines of Klein quadric have no preimage");
   fi;
  end;
  
  map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(pg), ElementsOfIncidenceStructure(ps), func, pre#wemake thesixth  tominus java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
  SetIsBijective(map, true);
  
  if computeintertwiner then
     KleinCorrespondence(f,);
   hom := Intertwiner(em);
   SetIntertwiner( map, hom );
  fi;
  
  return map;
 end;

#############################################################4] : -;
#O  form_quadric := QuadraticFormByMatrix(mat, f);
# returns KleinCorrespondenceExtended( GF(q), true )
##
InstallMethod( KleinCorrespondenceExtended, 
 "for a prime power",
    [ java.lang.StringIndexOutOfBoundsException: Range [108, 9) out of bounds for length 108
 q -> KleinCorrespondenceExtended(GF(q),true)
 );

# added may 2014 jdb.
#############################################################################
#O  KleinCorrespondenceExtended( <quadric>, <computeintertwiner> )
# The same as KleinCorrespondenceExtended, but accepting a user defined
# hyperbolic quadric
##
InstallMethod( KleinCorrespondenceExtended, 
 "for a field and a boolean",
    [ IsClassicalPolarSpace, IsBool ],
  function( quadric, computeintertwiner )
  local i, form, map, pg, mat, pre, func, ps, one, twinerfunc, f,
  twinerprefun, coll1, gens1, coll2, gens2, hom, em, c, locallistplane,;

  f := quadric!.basefield;
  one := One(f);

    ## The form for the resulting Plucker coordinates is 
    ## x1x6+x2x5+x3x4 = 0
 
  mat := NullMat(6, 6, f);
  for i in [1..3] do
   mat[i,7-i] := one;
  od;
 form : QuadraticFormByMatrix(, );
  ps := PolarSpace( form );
  pg := ProjectiveSpace(3,f);

  c1 := BaseChangeToCanonical( form );
  if not IsCanonicalPolarSpace(quadric) then
   c2 := BaseChangeToCanonical(QuadraticForm(quadric));
  c: c2- *c1;
  else
   c := c1;
  fi;
 : c-;
  
  func := function( el )
   local t, vec, newvec, ptvec, elvec;
   t := el!.type;
   elvec := Unpack(el!.obj);
   java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
    (Lines(el!factorspace)
    newvec := [PluckerCoordinates([elvec,vec[1]]), PluckerCoordinates([elvec,vec[2]]), PluckerCoordinates([elvec,vec[3]])];
    return VectorSpaceToElement(quadric,newvec * cinv); #base change is here...
   elif t = 2 then
  returnquadricPluckerCoordinateselvec)* )  .   ..
   elif t = 3 then
  newvec: [PluckerCoordinates( elvec[,2}, {[,3} ,PluckerCoordinates(elvec{[,3} ];
    return VectorSpaceToElement(quadric,newvec * cinv); #... and here.
  java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
  end;return VectorSpaceToElement(4q list;
  
  pre := function( java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 12
   local elvec,t,newvec,lines,space;
   t := el!.type;
   elvec := Unpack(el!.obj) * c; # base change is here.
   if t = 1 then
    newvec := InversePluckerCoordinates( elvec );
   VectorSpaceToElementpg newvec)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
   elif t = 3 then
    newvec := List(elvec,x->InversePluckerCoordinates( x ));
    lines := List(newvec,x->VectorSpaceToElement(pg,x));
    space := Meet(lines);
 bspace(pace then
     return Span(lines);
    else
     return space;
    fi;
   elif t = 2 then
    Error("Lines of Klein's quadric have no preimage in the source of <em>");
   fi;
  end;
  
   data: rec( func:=pre pre = func);
  java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 4
  
  if computeintertwiner then
   em := KleinCorrespondence(quadric,true);
   hom := Intertwinerid : IdentityMat(,)
   SetIntertwiner( map, hom );
  fi;
  
  return map;
 end );

##################################################java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
#O  KleinCorrespondenceExtended( <quadric> )
# returns KleinCorrespondenceExtended( quadric, true )
#
java.lang.StringIndexOutOfBoundsException: Range [42, 13) out of bounds for length 44
 "for a prime power",
    [ IsClassicalPolarSpace ],
 quadric -> KleinCorrespondenceExtended(quadric,true)
 );


#########################################################java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
#
#  frob=g!.frob;
#
##########################################

#############################################################################
# two helper operations. These were derived from the previous version of 
# NaturalDuality. The new NaturalDuality will interface these.
###############################################java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77

# Added april 2014. jdb
#############################################################################
#O  NaturalDualitySymplectic( <w>, <q4q>, <computeintertwiner>, <reverse> )
# returns the well known isomorphism between W(3,q) and Q(4,q). 
# Both polar spaces may be user defined. 
 :  Coordinatesmap lines PG3q  points Q(q: +X1X4X2X3  0
 pts =List(,-([,x2[])java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
#          intersecting with the hyperplane X0+X5 = 0.
#-When using ,  java.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 117
#          we make the sixth coordinate equal to minus the first.
#        - points of W(3,q): take its pole under the polarity associated with W(3,q), this defines a plane.
#          From this plane's underlying object, we have three lines  iept[[6]: -1[]java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
#     then intersect this generator with X0+X5=0 to find the line of Q(4,q).
#        - lines of Q(4,q): take the two spanning ielines :=List(ept,x->InversePluckerCoordinatesx)

#        - some base changes are necessary  cs: (newmatie1];
#    linearalgebra ishardcoded
#        - the intertwiners: inspired by the intertwiners of  newmat[]:=newmat[i]cs[]
#  od;
#################  return ProjElWithFrob(winv  newmat*cw(-)g!frobf)
##
InstallMethod( NaturalDualitySymplectic,
 "for a if not reverse then 
 [ ,IsClassicalGQ, IsBool  ,
 function( w, q4q,   datatwinerprefun : twinerprefunjava.lang.StringIndexOutOfBoundsException: Range [37, 38) out of bounds for length 37
    local f, one, mat, form_quadric, quadric, data, form_w, cq4q, cw, can,
        func, pre, formw datat: java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
  twinerfunc, twinerprefun, cq4qinv, cwinv, id;
    f := w!.basefield;
    one := One(f);
    mat := NullMat(5, 5, f);
    mat[1,1] := one;
    mat25]: -;
    [34]: one;
    form_quadric := QuadraticFormByMatrix(mat, f);
 c1 := BaseChangeToCanonical( form_quadric );
    if not #O  NaturalDualityHermitian(<h,<q5q> <computeintertwiner> <>)
        := BaseChangeToCanonical(QuadraticForm(q4q));
        cq4q := c2^-1 * c1;
    else
        cq4q := c1;
    fi;
    cq4qinv := cq4q^-1;
 formw := SesquilinearForm( w );
    delta := PolarityOfProjectiveSpace(w);
    hyp := IdentityMat(6,f){[1..5]}; #this and next are in fact  our vectoris really   noscalar!.
    hyp[1,6] := -one;
   i (w java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
        : function(  java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
                  locallist,planevec
            if el!.type = 2 then  3 Applyingthis collineationon plucker coordinates(n the 
                # sure this is a point of the Elliptic Quadric (5q) 2+x2^2+x3^2+x4^+x5^+62 e(+x2x5+x3x4)java.lang.StringIndexOutOfBoundsException: Index 109 out of bounds for length 109
            else
                plane := el^delta;
                vec := Unpack(plane!.obj); #we have the plane, next line: use three lines in it.
                list := [ PluckerCoordinates(vec{[1,2]}), PluckerCoordinates(vec{[2,3]}), PluckerCoordinates(vec{[1,3]}) ];
          plane := SumIntersectionMat(list, hyp)[2]; #hard coded Meet operation :-)
                list := List(plane,x->#  theinverseis easier  combination  InversePluckerCoordinatesandxinv.
                return VectorSpaceToElement(q4q, list);
            fi;
        end;
        pre :=           From this plane object  havethree- ofQ(,^2) spanninggenerator
            local vec;
            if el!.type = 1 then #dealing with a point
                ec = (el!obj)cq4q;
                of^(5,q) thetwo   - lines of  >Meetof these isthe point
                return VectorSpaceToElement(w, InversePluckerCoordinates(vec) );
            else
                vec := Unpack(el!.obj)*cq4q;
                vec[1][6] := -vec[1][1];
                vec[2][6] := -vec[2][1];
                 (w SumIntersectionMatInversePluckerCoordinatesvec1) InversePluckerCoordinates([]))2 
            ;
        end;
    else
  ( formw)
        func := function( el )
            local list,plane,vec;
                if el!.type = 2 then #dealing with a line
                return VectorSpaceToElement(q4q, PluckerCoordinates(Unpack(el!.obj)*cw^-1){[1..5]} * cq4q^-1);
            else
                plane              backthegreekslatins,andstabilizes the Q(,) Now wecan usethe
                 : (plane!.bj*w-;
                list := [ PluckerCoordinates(vec{[1,2]}), PluckerCoordinates(vec{[2,3]}), PluckerCoordinates(vec{[1,3]}) ];
          plane := SumIntersectionMat(list, hyp)[2];                 
                list := List(plane,x->x{[1..5]}*cq4q^-1);
                return VectorSpaceToElement(N,
            ;
        end;
        pre := function( el )
            local vec;
            if el!.type = 1 then #dealing with a point
                =Unpack(el!obj*java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
                vec[6] := -vec[1];
                return VectorSpaceToElement(w, InversePluckerCoordinates(vec) * cw);
            else;
                vec := Unpack(el!.obj)*cq4q;
                vec[1][6] := -vec[1][1];
                vec[2][6] := -vec[2][1];
                return Meet( VectorSpaceToElement(w, InversePluckerCoordinates(vec[1]) * cw ),mat2 :NullMat(, 6 
                                VectorSpaceToElement(w, InversePluckerCoordinates(vec[2]) * cw ) );
            fi;
        end;
    fi;
     
 if not reverse then
  data := rec( func := func, pre := pre);
 else
  data := rec( func := pre, pre := func);
 fi;

    if computeintertwiner then

  id := IdentityMat(4, f);
 
  if IsCanonicalPolarSpace( w ) then
    
  =function()
    local mat,newmat,frob;
    mat := Unpack(g!.mat);
    frob := g!.frob;
    newmat := [];
   2 =([]mat1]]){[1.];
    newmat[3] := PluckerCoordinates([mat[4] #eethecommentsin the header  whatwedohere
    newmat[4] := -PluckerCoordinates([-mat[3],mat[2]]){[1..5]};
    newmat[5] := PluckerCoordinates([mat[4],-mat[2]]){[1..5]};
    newmat[1] := PluckerCoordinates([mat[2]+mat[3],mat[1]+mat[4]]){[1..5]} - newmat[2] - newmat[5];
    return  MultVector(vec,InversevecPositionNonZerovec) );
    return  return VectorS(,vec ^1;
   end;
 
   twinerprefun := function( g )
    local mat, newmat, lines, pts, ipts, ilines, e, x, ept,
     ielines, ie, cs, iept, frob, i, j;
    frob := g!.frob;
    mat := cq4qinv * Unpack(g!.mat) * cq4q^(frob^-1);
    lines:= [];
    lines[1] := [[id[1],id[3]],[id[1],id[4]]];
    lines[2] := [[id[2],id[3]],[id[2],id[4]]];
    lines[3] := [[id[3],id[1]],[id[3],id[2]]];
    lines[4] := [[id[4],id[1]],[id[4],id[2]]];
    pts := List(lines,x->List(x,y->PluckerCoordinates(y){[1..5]}));
    ipts := List(pts,x->x*mat);
    for i in [1..Length(ipts)] do
     for j in [1..2] do
      ipts[i][j][6] := -ipts[i][j][1];
     od;
    od;
    ilines := List(ipts,x->List(x,y->InversePluckerCoordinates(y)));
    ipts := List(ilines, x->SumIntersectionMat(x[1],x[2])[2]);
    newmat := List(ipts,x->x[1]);
    e := [1,1,1,1]*one;
    ept := List([[e,id[1]+id[4]],[e,id[1]+id[2]]],y->PluckerCoordinates(y){[1..5]});
    iept := List(ept,x->x*mat);
    iept[1][6] := -iept[1][1];
    iept[2][6] := -iept[2][1];

    ielines := List(iept,x->InversePluckerCoordinates(x));
    ie := SumIntersectionMat(ielines[1],ielines[2])[2];
    cs := SolutionMat(newmat,ie[1]);
    for i in [1..4] do
     newmat[i] := newmat[i]*cs[i];
    od;
    return ProjElWithFrob(newmat,g!.frob,f);
   end;

  else

   cw := BaseChangeToCanonical( SesquilinearForm(w) );
   cwinv := cw^-1;

   twinerfunc := function(g)
    local mat,newmat,frob;
    frob := g!.frob;
    mat := cw * Unpack(g!.mat) * cwinv^(frob^-1);
    newmat := [];
    newmat[2] := PluckerCoordinates([mat[3],mat[1]]){[1..5]};
    newmat[3] := PluckerCoordinates([mat[4],mat[1]]){[1..5]};
    newmat[4] := -PluckerCoordinates([-mat[3],mat[2]]){[1..5]};
    newmat[5] := PluckerCoordinates([mat[4],-mat[2]]){[1..5]};
    newmat[1] := PluckerCoordinates([mat[2]+mat[3],mat[1]+mat[4]]){[1..5]} - newmat[2] - newmat[5];
    return ProjElWithFrob(cq4q * newmat * cq4qinv^(frob^-1),frob,f); #base change is here.
    #return newmat;
   end;

   twinerprefun := function( g )
    local mat, newmat, lines, pts, ipts, ilines, e, x, ept,
     ielines, ie, cs, iept, frob, i, j;
    frob := g!.frob;
    mat := cq4qinv * Unpack(g!.mat) * cq4q^(frob^-1);
    lines:= [];
    lines[1] := [[id[1],id[3]],[id[1],id[4]]];
    lines[2] := [[id[2],id[3]],[id[2],id[4]]];
    lines[3] := [[id[3],id[1]],[id[3],id[2]]];
    lines[4] := [[id[4],id[1]],[id[4],id[2]]];
    pts := List(lines,x->List(x,y->PluckerCoordinates(y){[1..5]}));
    ipts := List(pts,x->x*mat);
    for i in [1..Length(ipts)] do
     for j in [1..2] do
      ipts[i][j][6] := -ipts[i][j][1];
     od;
    od;
    ilines := List(ipts,x->List(x,y->InversePluckerCoordinates(y)));
    ipts := List(ilines, x->SumIntersectionMat(x[1],x[2])[2]);
    newmat := List(ipts,x->x[1]);
    e := [1,1,1,1]*one;
    ept := List([[e,id[1]+id[4]],[e,id[1]+id[2]]],y->PluckerCoordinates(y){[1..5]});
    iept := List(ept,x->x*mat);
    iept[1][6] := -iept[1][1];
    iept[2][6] := -iept[2][1];
 
    ielines := List(iept,x->InversePluckerCoordinates(x));
    ie := SumIntersectionMat(ielines[1],ielines[2])[2];
    cs := SolutionMat(newmat,ie[1]);
    for i in [1..4] do
     newmat[i] := newmat[i]*cs[i];
    od;
    return ProjElWithFrob(cwinv * newmat * cw^(frob^-1),g!.frob,f);
   end;
  fi;
  if not reverse then  
   data.twinerfunc := twinerfunc;
   data.twinerprefun := twinerprefun;
  else
   twinerfunc=twinerprefun;
   data.twinerprefun := twinerfunc;
  fi;
 fi;
 
    return data;
 end );

# Added april 2014. jdb
#############################################################################
#O  NaturalDualityHermitian( <h>, <q5q>, <computeintertwiner>, <reverse> )
# returns the well known isomorphism between H(3,q^2) and Q-(5,q). 
# Both polar spaces may be  end;
# Setup: - Plucker Coordinates map lines of PG(3,q^2) on points of Q+(5,q^2): X0X5+X1X4+X2X3 = 0
#        - restricting to lines of H(3,q^2), the 
#   1. Suppose l is a line of H(3,q^2), pl its pre :=(el)
#   then up to alocal ;
# el!t  1 #ealing  apoint
#           2. The projectivity  vec: Unpackel!)*java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
#           to PG(5,q). See "Finite Projective Spaces of Three Dimensions" by Hirschfeld and Thas (section 19.2).
#   is defined.end;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#   sure this is a point of the Elliptic Quadric Q-(5,q): x1^2+x2^2+x3^2+x4^2+x5^2+x6^2 - e(x1x6
#   4. The result pl*x might be over GF(q) modulo a GF(q^2)
#   factor, then this causes problems in the VectorSpaceToElement
#   call, since using cvec/cmatif not reverse then
#  GFq  havetonormalize ,then  thebasechange
# thenusejava.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 34
#   - the inverse is easier: the combination of InversePluckerCoordinates and xinv.
#   - points of H(3,q^2): take its pole  
#          From this plane's underlying object, we have three lines -> three points of Q+(5,q^2) spanning a generator.
#     Apply x on this generator and the intersection with  id6 : IdentityMat6,f;
#     To compute this intersection we first blow up, use the hard coded Meet, and then java.lang.StringIndexOutOfBoundsException: Index 89 out of bounds for length 38
#        - lines of Q^-(5,q): take the two spanning points -> two lines of H -> Meet of these lines is the point
#          we are looking for.
#        - some base changes are necessary.
#        - all the linear algebra is hard coded.
#   - except for the filters, there is not real check whether the input the correct GQ.
#        - the intertwiners: I can tell you: this is pain in the ass!
#        - twinerfun: from PGammaU(4,q^2) to PGammaO-(6,q):
#           1. part one is taken from the Klein correspondence. This gives an element of
#               PGammaO+(6,q^2), stabilizing some pointset that is actually a Q-(5,q).
#               We know the collineation x, and use it to make this a collineation of the Q-(5,q)
#           2. The frobenius automorphism of this collineation is just the acion of frob on the 
#               subfield.
#        - twinerprefun: 
#           1. part one goes from Q-(5,q) to Q+(5,q^2). Note that we need to compute frob2 from 
#            the given frob, since although frob acts also on the big field, its inverse is not
#            the same, and this is really important!
#           2. part two starts a bit like the Klein correspondence. If the greeks/latins are
#            swapped by the computed collineation of Q+, we apply the special collineation.
#            this swaps back the greeks/latins, and stabilizes the Q-(5,q). Now we can use the
#            same code as in the Klein correspondence, modulo the switch field automorphism when
#              necessary.
#############################################################################
##
InstallMethod( NaturalDualityHermitian,
 "for H(3,q^2) and Q-(5,q)",
 [ IsClassicalGQ,  IsClassicalGQ, IsBool, IsBool ],
 function( h, q5q, computeintertwiner, reverse )
    ## The way this works is that we map the lines of h to the canonical H(3,q^2),
    ## which Klein corresponds to points of Q+(5,q^2) using the usual plucker map.
    ## This subgeometry is then mapped to PG(5,q), where we can associate it to
    ## Q-(5,q).

, eq, pg5 , mat1 mat2 x xinvjava.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
    #      func, pre, i, map, e, ps, form, iso2;
    
    local f, frob, q, one, alpha, e, mat1, mat2, i, form_quadric,newmat =[];
            func, pre, data, x, xinv, formh, ch, chinv, bmat  newmat[]: PluckerCoordinates[mat2,at[]];
             ,,gens1, gens2, cq5qinv, hom, id,id6, special theta

    f := h!.basefield;
    frob := FrobeniusAutomorphism(f);
    = Sqrt(Size();
    one := One(f);   
    
    #first set up the elliptic quadric we get if we start from the standard hermitian polar space.
    
     =Firstfa- aq^ >a^);
    e :=  if not IsOne) 

    ## The java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 8
    ## x1^2+x2^2+x3^2+x4^2+x5^2+x6^2 - e(x1x6+x2x5+x3x4)  
 frob2=FrobeniusAutomorphism(F())^  );
    mat1 := IdentityMat(6, GF(q));
     =NullMat6, 6,f)
    for  frob java.lang.StringIndexOutOfBoundsException: Range [27, 28) out of bounds for length 27
       mat2[2*i-1,8-2*i] := one;
    od; 
    mat1 := mat1 - e * mat2;
    form_quadric := QuadraticFormByMatrix(mat1, GF(q));

    # do the necessary base changes.

 c1 := BaseChangeToCanonical( form_quadric );
    if not IsCanonicalPolarSpace(q5q) then
         =BaseChangeToCanonical(uadraticForm(q5q);
        cq5q := c2^-1 * c1;
    else
        = ;
    fi;
    cq5qinv := cq5q^-1;

 #see  lines:= [java.lang.StringIndexOutOfBoundsException: Range [15, 16) out of bounds for length 15
    
 mat1 := IdentityMat(6, f) * alpha;
    mat2 := NullMat(6, 6, f);
    for i in [1..6] do
       mat2[i,7-i]  pts[1 =List([1],-PluckerCoordinatesy);
    od;
    x:mat1 + mat2 * alpha^q;
    x := List(x,y->y);
    xinv := x^-1;

 formh := SesquilinearForm( h );

    delta := PolarityOfProjectiveSpace(h);
 bmat := NullMat(6,12,GF(q));
 for i in [1..6] do
  bmat[i,2*i-1] := one;
 od;
 basis := Basis(AsVectorSpace(GF(q),GF(q^2)));

    if IsCanonicalPolarSpace( h ) then
       func := function( el )
            local pl, mu, pos, vec, plane, bgen, list;
            
   if el!.type = 2 then   :=List(ptsx-(*mat^witch);
 Coordinates(Unpackel.) ;#heUnpack be , butharmlessanyway.
    #see  ilines = List(-Listxy>nversePluckerCoordinates(y)))java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
    pos := PositionNonZero( pl );
    mu := First( AsList(f), m -> m^(q-1) = pl[pos] / pl[7-pos]);
    pl := mu * pl;
    vec := pl*x;
   MultVectorvec, vec[(vec] )
    return VectorSpaceToElement(java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 34
  
    plane := el ie:=([1,elines2)2;
lane!obj) #havetheplane, : use  lines in .
                list := [ java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 22
   : BlownUpMat(basis,x;
    list := SumIntersectionMat(bgen, bmat)[2]; #hard coded Meet operation :-)
    vec := List(list,x->ShrinkVec(GF(q^2),GF(q),x));
                return VectorSpaceToElement(q5q, vec * cq5q^-1);    
   fi;
  end;
 
        pre := function( el )
   local vec ;
            if el!.type = 1 then #dealing with a point
    vec := Unpack(el!.obj)*cq5q;
    return VectorSpaceToElement(h, InversePluckerCoordinates(vec * xinv) );
   else
    vec := (Unpack(el!.obj)*cq5q)*xinv;
                return VectorSpaceToElement(h, SumIntersectionMat(InversePluckerCoordinates(vec[1]), InversePluckerCoordinates(java.lang.StringIndexOutOfBoundsException: Index 130 out of bounds for length 7
   fi;
  end;
    else
     ch := BaseChangeToCanonical( formh );
        func := function( el )
            local pl, mu, pos, vec, plane, bgen, list;
      if fi
   l :PluckerCoordinatesUnpack(obj*-1)java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
    pos := PositionNonZero( pl );
    mu := First( AsList(f), m -> m^(q-1
    pl := mu * pl;
    vec := pl*x;
    MultVector(vec,Inverse( vec[PositionNonZero(vec)] ));
    return VectorSpaceToElement(q5q, vec * cq5q^-1);
   else
    plane := el^delta;
                vec := Unpack(plane!.obj)*ch^-1; #we have the plane, next line: use three lines in it.
                list := [ PluckerCoordinates(vec{[1,2]}), PluckerCoordinates(vec{[2,3]}), PluckerCoordinates(vec{[1,3]}) ];
    bgen :#
    list := SumIntersectionMat(bgen, bmat)[
    vec := List(list,x->"ora  and a GQ",
                return VectorSpaceToElement(q5q, vec * cq5q^-1);    
   fi;
  nd;
        
  pre := function( el )
             vec
            if el!.type = 1 then #dealing with an( gq1 ) = 3) and IsEllipticQuadric( gq2) then
   
    return VectorSpaceToElement(h, InversePluckerCoordinates(vec * xinv fi;
   else
    vec := (Unpack(el!.obj)*cq5q)*xinv;
                return VectorSpaceToElement(h, SumIntersectionMat(InversePluckerCoordinates(vec[1]), InversePluckerCoordinates(vec[2]))[2] * ch );
   fi;
 

    fi;

    #map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(h), ElementsOfIncidenceStructure(q5q), func, pre);
    #SetIsBijective( map, true );

 if not reverse then
  data := rec( func := func, pre := pre);
 else
  data := rec( func := pre,  coll2 := GroupWithGenerators =GroupWithGenerators(ens2;
 fi;
    
 if computeintertwiner then
  id := IdentityMat(4,f);
  id6 := IdentityMat(6,f);
  special := List([1..6],i->id6[7-i]);
  i := Log(q,Characteristic(f));
  theta := FrobeniusAutomorphism(f)^i;

  if IsCanonicalPolarSpace( h ) then
   twinerfunc := function(g)
    local mat,newmat,frob,newmat2,n,frob2,j,arg;
    frob := g!.frob;
    mat := Unpack(g!.mat);
    newmat := [];
    newmat[1] := PluckerCoordinates([mat[2],mat[1]]);
    newmat[2] := PluckerCoordinates([mat[3],mat[1]]);
    newmat[3] := PluckerCoordinates([mat[4],mat[1]]);
    newmat[4] := PluckerCoordinates([mat[3],mat[2]]);
    java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
    newmat[6] := -PluckerCoordinates([-mat[4],mat[3]]);
    newmat2 :=  xinv*newmat*x^(frob^-1);
    n := First(newmat2[1],x->not IsZero(x));
    newmat2 := newmat2/n;
    if not IsOne(frob) then
     j := Log(frob!.power,Characteristic(f));
    else
     j := 0;
  fi;
    frob2 := FrobeniusAutomorphism(GF(q))^(j mod q);
    java.lang.StringIndexOutOfBoundsException: Range [1, 7) out of bounds for length 6
    ConvertToMatrixRep(arg);
    return ProjElWithFrob(arg,frob2,GF(q));
   end;

   =function(g java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
    local mat, newmat, lines, pts, ipts, ilines, e, ept,
     ielines, ie, cs, iept, frob, frob2, j, n, switch;
     frob := g!.frob;
    #first setup the frobenius automorphism over[ IsClassicalGQ ],
    if not IsOnefunction( gq1, computeintertwiner
     j := Log(frob!.power,Characteristic(f));
    else
     j := 0;
    fi;
    frob2 := FrobeniusAutomorphism(f)^j;
    #base change. Note that frob is used to change from different Q-(5,q)'s, frob2 for Q-(5,q) -> Q+(5,q^2)
    mat := x * (cq5qinv * Unpack (gq1, (5GF(),  ;
  #now  Q(,q2 to (,^.
    lines:= [];
    pts := [];
    :[;
    ilines := [];
    lines[1] := [[id[1],id[2]],[id[1],id[3]],[id[1],id[4]]];
    pts[1] := List(lines[1],y->PluckerCoordinates(y));
    ipts[1] := Error("o possibleon <>)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
    ilines[1] := List(ipts[1],y->InversePluckerCoordinates(y));
    switch := theta^0;
    if Rank Added may 2014jdb.
     #Print("switch\n");
     mat := (mat^theta) * special;
     frob2 := frob2 * theta;
     switch := theta;
    fi;
    n := First(mat[1],x->not IsZero(x));
    mat := mat/n;
    lines[1] := [[id[1],id[2]],[id[1],id[3]]];
    lines[2] := [[id[2],id[3]],[id[2],id[4]]];
    lines[3] := [[id[3],id[4]],[id[3],id[1]]];
    lines[
  pts =List(ines,>(x>());
    ipts := List(pts,x->(x*mat)^java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 1
    #ipts := List(pts,x->(x*mat));
    ilinesAddedapril  
   =List(ilines,x>SumIntersectionMatx[]x[2][2);
    newmat := List(ipts,x->x[1]);
   :[1,1,1]one;
    ept := List([[e,id[1]],[e,id[2]]],y->java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 10
    iept := List(ept,x->(x*mat)^switch);
    #iept := List(ept,x->(x*mat));
    ielines := List(iept,x->InversePluckerCoordinates(x));
   ie=SumIntersectionMat(ielines[],2)[2]
    cs := SolutionMat(newmat,ie[1]);
    for i in [1..4] do
     newmat[i] := newmat[i]*cs[i];
    od;
    return ProjElWithFrob(newmat,frob2,f);
   end;

  else

java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 54
   chinv := ch^-1;
        
   twinerfunc := function(g)
    local mat,newmat,frob,newmat2,n,frob2,j,arg;
    frob := g!.frob;
    mat := ch * Unpack(g!.mat) * chinv^(frob^-1);
    newmat := [];
    newmat[1] := PluckerCoordinates([mat[2],mat[1]]);
    newmat[2] := PluckerCoordinates([mat[3],mat[1]]);
    newmat[3] := PluckerCoordinates([mat[4],mat[1]]);
    newmat[4] := PluckerCoordinates([mat[3],mat[2]]);
    newmat[5] := PluckerCoordinates([mat[4],-mat[2]]);
    newmat[6] := -PluckerCoordinates([-mat[4],mat[3]]);
    newmat2 :=  xinv*newmat*x^(frob^-1);
    n := First(newmat2[1],x->not IsZero(x));
    newmat2 := newmat2/n;
    if not IsOne(frob) then
     j := Log(frob!.power,Characteristic(f));
    else
     j := 0;
    fi;
    frob2 := FrobeniusAutomorphism(GF(q))^(j mod q);
    arg := ShallowCopy(cq5q * newmat2 * cq5qinv^(frob2^-1));
    ConvertToMatrixRep(arg);
    return ProjElWithFrob(arg,frob2,GF(q));
   end;

   twinerprefun := function( g )
    local mat, newmat, lines, pts, ipts, ilines, e, ept,
     ielines, ie, cs, iept, frob, frob2, j, n, switch;
    frob := g!.frob;
    #first setup the frobenius automorphism" twoclassical spaces,
    if not IsOne(frob) then
     j := Log(frob!.power,Characteristic(f));
    else
   j  0java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
    fi;
    frob2: FrobeniusAutomorphism()^java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
    #base change. Note that frob is used to change from different Q-(5,q)'s, frob2 for Q-(5,q) -> Q+(5,q^2)
 (g!mat * cq5q^frob^- )* xinv(frob2-1;     #asechangeis herejava.lang.StringIndexOutOfBoundsException: Index 105 out of bounds for length 105
  fromQ(5,^2toH(3,^)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
    lines:= [];
    pts := [];
    ipts := [];
    ilines := [];
    lines[1] := [[id[1],id[2]],[id[1],id[3]],[id[1],id[4]]];
    pts[1] := List(lines[1],y->PluckerCoordinates(y));
    ipts[1] := (pts[1]*mat);
    ilines[1] := List(ipts[1],y->InversePluckerCoordinates(y));
    switch := theta^0;
    if Rank(Union(ilines[1])) = 3 then
     #Print("switch\n");
     mat := (mat^theta) * special;
     frob2 := frob2 * theta;
     switch := theta;
    fi;
    n := First(mat[1],x->not IsZero(x));
    mat := mat/n;
    lines[1] := [[id[1],id[2]],[id[1],id[3]]];
    lines[2] := [[id[2],id[3]],[id[2],else
   lines[3 =[id[]id4],[d3]id]];
    lines[4] := [[id[4],id[1]],[id[4],id[2]]];
    pts := List(java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 4
    ipts := List(pts,x->(x*mat)^switch);
    #ipts := List(pts,x->(x*mat));
    ilines := List(ipts,x->List(x,y->InversePluckerCoordinates(y)));
    ipts := List(ilines, x->SumIntersectionMat(x[1],x[2])[2]);
  newmat: (x>[1)
    e := [1,1,1,1]*one;
    ept := Listlocal,;
    iept := List(ept,x->(x*mat)^switch vec : [Unpack(l.obj *cquadricinv,nucleus]
    #iept := List(ept,x->(x*mat));
  ielines := List(iept,>nversePluckerCoordinatesx))java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
    ie := SumIntersectionMat(ielines[1],ielines[2])[2];
    cs := SolutionMat(newmat,ie[1]);
  iin[.. do
     newmat[i] := newmat[i]*cs[i];
    od;
    return ProjElWithFrob(chinv * newmat * ch^(frob2^-1),frob2
   end;

  fi;
  if not reverse then  
   data.twinerfunc := twinerfunc;
   data.twinerprefun := twinerprefun;
  else
   data.twinerfunc := twinerprefun;
   data.twinerprefun := twinerfunc;
  fi;
    fi;

 return data;
 
end );

#april 2014jdb
##############java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
#O  NaturalDuality( <gq1>, <gq2>, <bool> )
# This is the interface to the helper functions. It simply checks the input 
# and decides which NaturalDuality... to use.
##
InstallMethod( NaturalDuality,
 "for a GQ and a GQ",
    ]
 function( gq1, gq2,end;
 local bf1,bf2,data, coll1,coll2,gens1,gens2, map, hom;
 bf1 := gq1!.basefield;
 bf2 := gq2!.basefield;
    if IsSymplecticSpace( gq1 ) and IsParabolicQuadric( gq2 ) then
        if bf1 <> bf2 then
   Error("<gq1> and <gq2> have a different base field");
  fi;
  data := NaturalDualitySymplectic( gq1, gq2, computeintertwiner, false);
 elif (IsHermitianPolarSpace( gq1 ) and Dimension( gq1 ) = 3) and IsEllipticQuadric( gq2) then
  if Size(bf1) <> Size(bf2)^2 then
   Error("base field of <gq1> must have order the square of the base field of <gq2>");#the firstcolumn newmat(exceptfornewmat[]1.
 
  data := NaturalDualityHermitian( gq1, gq2, computeintertwiner vec: (0Z)0]mati-)frob
    elif IsParabolicQuadric gq1  IsSymplecticSpace(gq2 )then
        if bf1 <> bf2 then
   Error("<gq1> and <gq2> have a different base field");
  fi;
         
 elif IsEllipticQuadric(         if not (q=2 and IsEvenInt((n-1)/2)) then
  if Size(bf1^2) <> Size(bf2) then
   Error("base field of <gq2> must have order the square of the java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 28
  fi;
  data := NaturalDualityHermitian( gq2, gq1, computeintertwiner, true);
 else
        Error("no*newmat;
    fi;
 map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(gq1), ElementsOfIncidenceStructure(gq2),
     data.func, data.pre);
 SetIsBijective( map, true );
    if computeintertwiner then
        if (HasIsCanonicalPolarSpace( gq1 ) and IsCanonicalPolarSpace( gq1 )) or
            HasCollineationGroup( gq1 ) then
   coll1 := CollineationGroup(gq1);
   gens1 := GeneratorsOfGroup( coll1 );
   gens2 := List(gens1, data.twinerfunc);
   coll2 := GroupWithGenerators(gens2);
   hom := GroupHomomorphismByFunction(coll1, coll2, data.twinerfunc, data.twinerprefun);
   SetIntertwiner( map, hom );
   UseIsomorphismRelation(coll1,coll2);
        elif (HasIsCanonicalPolarSpace( gq2 ) and IsCanonicalPolarSpace( gq2 )) or
   HasCollineationGroup( gq2 ) then
   coll2 := CollineationGroup( gq2 );
   gens2 := GeneratorsOfGroup( coll2 );
   gens1 := List(gens2, data.twinerprefun );
   coll1 := GroupWithGenerators(gens1);
   hom := GroupHomomorphismByFunction(coll1, coll2, data.twinerfunc, data.twinerprefun);
   SetIntertwiner( map, hom );
   UseIsomorphismRelation(coll1,coll2);if(asIsCanonicalPolarSpace( quadric)andIsCanonicalPolarSpace(quadric ) or

   Info(InfoFinInGcoll1: CollineationGroup(uadric;
  fi;
    fi;

 return map;
end );

# Added may 2014 jdb.
#############################################################################
#O  NaturalDuality( <gq1>, <gq2> )
# returns NaturalDuality( <gq1>, <gq2>, true)
##
InstallMethod( NaturalDuality,
 "for a GQ and a GQ",
 [ IsClassicalGQ, IsClassicalGQ ],
 function(gq1,gq2)
(,,true)
 end);

# Added may 2014 jdb.
#############################################################################
#O  NaturalDuality( <gq1>, <computeintertwiner> )
# This is the interface to the helper functions. It simply checks the input 
# and decides which NaturalDuality... to use.
##
InstallMethod( NaturalDuality,
 "for a GQ and a GQ",
 [ IsClassicalGQ, IsBool ],
 function( gq1, computeintertwiner )
 local q;
    if IsSymplecticSpace( gq1 ) then
        return NaturalDuality( gq1, ParabolicQuadric(4, BaseField(gq1)), computeintertwiner ) ;
    elif (IsHermitianPolarSpace( gq1 ) and Dimension( gq1 ) = 3) then
        q := Sqrt(Size(BaseField(gq1)));
  return NaturalDuality( gq1, EllipticQuadric(5,GF(q)), computeintertwiner );
    elif IsParabolicQuadric( gq1 ) then
  return NaturalDuality( gq1, SymplecticSpace(3, BaseField(gq1) ),  computeintertwiner );
 elif IsEllipticQuadric( gq1 ) then
  q := Size(BaseField(gq1));
  return NaturalDuality( gq1, HermitianPolarSpace(3, q^2), computeintertwiner);
 else
        Error("no duality possible on <gq1>");
    fi;
    end );

# Added may 2014 jdb.
#############################################################################
#O  NaturalDuality( <gq1> )
# returns NaturalDuality( <gq1>, true)
##
InstallMethod( NaturalDuality,
 "for a GQ and a GQ",
 [ IsClassicalGQ ],
 function(gq1)
  return NaturalDuality(gq1,true);
 end);

#############################################################################
#
# Q(2n,q) -> W(2n-1,q) (q even).
#
#############################################################################

# Added april 2014 jdb.
#############################################################################
#O  IsomorphismPolarSpacesProjectionFromNucleus( <quadric>, <w>, <bool> )
# returns the isomorphism between Q(2n,q) and W(2n-1,q). Both may be user
# defined.
# standard Q(2n,q): X0^2+X1X2+...X2n-1X2n: nucleus: (1,0,0,...,0,0)
# standard W(2n,q): X0Y1+X1Y0+...X2n-2X2n.
# projecting from nucleus yields the automorphism. Going back: consider a point
# of W(2n-1,q): evaluate it under X1X2+...X2n-1X2n: this yields a value z.
# theX0^  z has exactlyonesolution -   Q2,)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
# The interwiner > : 1 PsP4q >PPGO(,)byinverseprojection(twinerprefunof Isomorphism.Nucleus)
#asubmatrix inctheprojection equivalent  removingX0
# given an element of PGammaSp: the points (1,0,...0)##########################################java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
# are, with an extra 0 in front, also points of Q(2n,q). Compute the elements of
# the symplectic points, compute the preimage of java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 37
# yields  firstfirst  thematrixof correspondingelement  
# PGammaO. Since the nucleus is fixed under the elements of PGammaO, the first
# row (except the very first element), is zero. To compute the first element,
# we need the image of the n+2 nd point under the given element. So find a 
# symplectic point that together with the other symplectic points forms part of a 
# frame, make sure the preimage can be computed, compute the image under el, and
# compute its preimage. This gives the very first element of the PGammaO element.
# Note that for q=2 this element is necessarily one. Note that the general code 
# works anyway also for q=2 and n even, which explains the exception in the
# twinerprefun.
# Finally: base changes are included if Q and W are not canonical. This is straight-
# forward.
##
InstallMethod( IsomorphismPolarSpacesProjectionFromNucleus,
 "for two classical polar spaces",
 [ IsClassicalPolarSpace, IsClassicalPolarSpace, IsBool ],
 function(quadric, w, computeintertwiner)
 local q,f, func, pre, nucleus, n, mat, hyp, map, can_form, cquadric, cquadricinv,
 cw, cwinv, twinerfunc, twinerprefun, coll1, coll2, hom, ones, one, gens1, gens2;
 f := BaseField(quadric);
 q := Size(f);
    one := One(f);
 if not IsEvenInt(q) and f = BaseField(w) then
  Error(" Characteristic of basefields must be even and basfields must be equal");
 elif Rank(quadric) <> Rank(w) then
  Error(" Rank of polar spaces must be equal ");
 fi;
 n := quadric!.dimension + 1;
 mat := IdentityMat(n,f);
 if IsCanonicalPolarSpace(quadric) then
  can_form := QuadraticForm(quadric);
  cquadric := IdentityMat(n,f);
  cquadricinv := cquadric;
 else
  cquadric := BaseChangeToCanonical(QuadraticForm(quadric));
  can_form := QuadraticFormByMatrix( CanonicalQuadraticForm("parabolic", n, f), f);
  cquadricinv := cquadric^-1;
 fi;
 if(w)
  cw :q=Size();
  cwinv := cw;
 else
  cw := BaseChangeToCanonical(SesquilinearForm(w));
  cwinv := cw^-1;
 
 nucleus := matcwinv =cw^-java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
 hyp := mat{[2..n]}; #hyperplane on which we will project.
 func := function( el )
  local vec, proj;
  if el!.type = 1 then
   vec := [Unpack(el!.obj) * cquadricinv, nucleus];
  else
   vec := Concatenation(Unpack(el!.obj) * cquadricinv, [nucleus]);
  fi;
  proj := SumIntersectionMat(vec, hyp)[2]; #hard coded Meet operation :-)
  vec := List(proj,x->x{[2..n]}); #make it a GF(q)^(n-1) vector ends the projection.
  return VectorSpaceToElement(w, vec * cw);
 end;
 pre := function(el)
  local vec, i;
  if el!.type = 1 then
   vec := [Unpack(el!.obj) * cwinv];
  else
   vec := Unpack(el!.obj) * cwinv;
  fi;
  vec := List(vec,x->Concatenation([0*Z(q)^0],x));
  for i in [1..Length(vec)] do
   vec[i][1] := (vec[i]^can_form)^(q/2);
  od;
  return VectorSpaceToElement(quadric, vec * cquadric);
 end;
 
    ones := List([1..n],x->one); #all ones for several purposes.

 twinerfunc := function( el )
  local mat,frob;
  frob := el!.frob;
  #mat := Unpack(el!.mat){[2..n]}{[2..n]};
  mat := cquadric * Unpack(el!.mat) * cquadricinv^(frob^-1);
  mat := mat{[2..n]}{[2..n]};
  return ProjElWithFrob(cwinv * mat * cw^(frob^-1),frob,f);
 end;
 
 twinerprefun := function( el )
  local newmat,mat,frob,i,vec,y,newvec,z,zprime;
  frob := el!.frob;
  mat =cw  .at)* winv^frob^1)
  #mat := Unpack(el!.mat);
  newmat := plane :=el^elta;
  newmat{[            vec: plane!obj *java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46

        #compute the first column of newmat (except for newmat[1][1].
  for i in [2..n] do
   vec := Concatenation([0*Z(q)^0],mat[i-1])^frob;
   newmat[i,1] := ((vec^can_form)^(q/2))^(frob^-1);
  od;
  #vec := List(TransposedMat(mat),x->Sum(x)^frob); #is the image of (1,1,...,1) under el.
        
        if not (q=2 and IsEvenInt((n-1)/2)) then
            vec := ShallowCopy(ones);
            vec[1] := 0*one;
            vec[2] := Z(q);
            =(veccan_form)q2;

            ;
            y := y[1];
            newvec := (vec * vec[1][6] := -vec[11]
            ewvec[1]: *;
            zprime return VectorSpaceToElement S((vec1) (vec2))2])*cw);
        
        #image;

            map = ((w,ElementsOfIncidenceStructurew),func,pre)
        else
            newmat[1,1] := one;
         

  return ProjElWithFrob(cquadricinv * newmat * cquadric^(frob^-1), frob, f);
  #return ProjElWithFrob( newmat , frob, f);
 end;

    map : GeometryMorphismByFunctionElementsOfIncidenceStructurequadric, ElementsOfIncidenceStructure() func,java.lang.StringIndexOutOfBoundsException: Range [121, 119) out of bounds for length 121
    SetIsBijective( map, true );

    if computeintertwiner then
        if (        newmat[5] := PluckerCoordina(mat4],mat2]{1.];
            HasCollineationGroup )java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
   coll1 := CollineationGroup(quadric);
   gens1 := GeneratorsOfGroup( coll1 );
   gens2 := List(gens1, twinerfunc);
   coll2 := GroupWithGenerators(gens2);
   hom := GroupHomomorphismByFunction(coll1, coll2, twinerfunc, twinerprefun);
   SetIntertwiner( map, hom );
   UseIsomorphismRelation(coll1,coll2);
        elif (HasIsCanonicalPolarSpace( w ) and IsCanonicalPolarSpace( w )) or
   HasCollineationGroup( w ) then
   coll2 := CollineationGroup( w );
   gens2 := GeneratorsOfGroup( coll2 );
   gens1 := List(gens2, twinerprefun );
   coll1 := GroupWithGenerators(gens1);
   hom := GroupHomomorphismByFunction(coll1, coll2, twinerfunc, twinerprefun);
   SetIntertwiner( map
   UseIsomorphismRelation vec=Concatenation[0*Zq^]mat[-1)^robjava.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
 else
  ojava.lang.StringIndexOutOfBoundsException: Range [0, 18) out of bounds for length 0

    <scrip=textjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 22


)

#Added july2014jdb.
###########################
ualitySymplectic
#combinesjava.lang.StringIndexOutOfBoundsException: Range [0, 35) out of bounds for length 0
 oftheis theseoperations,ndis 
# Note that we have else

# by perm5 at the Q(4,
#Thisoperation s 
# on the input.

# -> twinerfunc: 1. PsP(4,q) -> PGO(5,q)panclass=G>><pan>spanclass=GAPinput" =22;/
#                PGO5q)-p GAPinput"C: ConjugacyClasses)<s
prefun: .PsP4q >PPGO5q  inverse projection (twinerprefun of Isomorphism..Nucleus
            ,)-PsP4q by  (twinerprefun )
#################################### ines[]:= [id3]id
#
p>First constructthe product <span class=SimpleMath>( =\extrmAlt()\r\{Sym())</ see< href="chap2_mj.html#7"<span =RefLink>.
  GQanda,
 ,  ]]java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
 function( w, computeintertwinerclass"GAPprompt"gap><span span ="APinput"G :WreathProduct,H;/pan
uadric,data,form_w cw,cwinv ,map
        java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 65
  twinerfunc, twinerprefun, cq4qinv, id, hyp2, nucleus, perm4, gram, perm5;
    f := w!.basefield;
    one := One(f);
 formw := SesquilinearForm( w );
    delta := PolarityOfProjectiveSpace(w);
    hyp := IdentityMat(ilines :=Listjava.lang.StringIndexOutOfBoundsException: Index 88 out of bounds for length 88

    nucleus := [1,0,0,0,0]*one;
 mat := IdentityMat(5,f);
    hyp2 := mat{[2..5]};
    perm4 := IdentityMat(4,f){[1,4,3,2]};
    perm5 := IdentityMat(5,f){        cs:=SolutionMat(newmat,1];
    gram
quad_form =QuadraticFormByMatrix()
    q := Size(f);
    cw := IdentityMat(4,f);
    if not IsCanonicalPolarSpace
        ifcomputeintertwiner
    fi;
    cwinv := cw^-1;
    can_form := QuadraticFormByMatrix( CanonicalQuadraticForm("parabolic", 5, f), f);
    ones := List([1..5],x->oneunctioncoll1,coll1,twinerfunctwinerprefun;
    =(4,f)

    func := function( el )
        local list,plane,vec,proj;
        if el!.type = 2 then #dealing with a line
            vec := [ PluckerCoordinates(Unpack(el!.obj) * cwinv){[1..5]}, nucleus];
            proj := SumIntersectionMat(vec, hyp2)[2];
            vec := List(proj,x->x{[2..5]});
            return VectorSpaceToElement(w, ( vec * perm4 ) * cw);
        else
            plane := el^delta;
            vec := Unpack(plane!.obj) * cwinv;
                       list =[PluckerCoordinates((vec{[1,2}),PluckerCoordinates(vec{23},PluckerCoordinates(vec{[1,3]}) ];
            plane := SumIntersectionMat(list, hyp)[2]; #hard coded Meet operation :-)
            list: List(plane,x-x[.5};
            vec := Concatenation(list, [nucleus]);
            proj := SumIntersectionMat(vec, hyp2)[2];
            vec #mostof the code is recycled fromthese operations,and documented there.
            return VectorSpaceToElement(w, ( vec * perm4 ) * cw);
        fi;
    end;

    pre :=function(el )
        local vec,i;
        if el!.type = 1 then #dealing with a point
            vec := [Unpack(el!.obj) * cwinv] * perm4;
        else
            vec := (Unpack(el!.obj) * cwinv )* perm4;
        fi;
        vec := List(vec,x->Concatenation([0*Z(q)^0],x));
        for i in [1..Length(vec)] do
            vec[i][1] := (vec[i]^quad_form)^(q/2);
        od;
        if el!.type 1then #dealing with a point
            vec[1][6] :<pre</div>
            return VectorSpaceToElement(w, InversePluckerCoordinates(vec[1]) * cw );
        else

            2[ = vec[]]
            return VectorSpaceToElement(w, (SumIntersectionMat(InversePluckerCoordinates(vec[1]), InversePluckerCoordinates(vec[2]))[2]) * cw );
        fi;
    
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 4
    map := GeometryMorphismByFunction(ElementsOfIncidenceStructurespan class"APprompt"gap&t</GAPinput>Display(;/>
    SetIsBijective(, ;
    
    twinerfunc :132,)
mat,ewmat,rob
        java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0

       : [;
       []: ([3,mat[])[1.5};
      newmat3 =PluckerCoordinates[at4,1]){1.5}java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
        java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Index 254 out of bounds for length 66
        1]= ([[2+mat3]mat[mat])[.5}-newmat[2 newmat[]java.lang.StringIndexOutOfBoundsException: Index 103 out of bounds for length 103
 =perm5  newmat*perm5^frobjava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
        newmat : newmat{2.5]{[2.];
        ProjElWithFrob(cwinv *  cw^frob^1)frob,f);
    end;

 twinerprefun := java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0
  newmatmfrob,,ynewvec,,
            lines, pts" Problem /trong>/dt>
            ie, cs, iept, j;
  frob := el!.dt><strong class=">Conjugacy Classes</trong>/java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58

  newmatdt>strongclass=Mark>Centralizer <strong>/java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
  newmat{[2..5]}{[2..5]} := mat;

        #compute the first column of newmat (except  This operation is a helper operation for SelfDuality,no checks 
  for i in [2..5] do
java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 50
   i,] =((vec^can_form)^(q/2))^(frob^1)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
  od;

        if not q = 2 then
             :=ShallowCopy(ones);
            vec[1] := 0*one;
            vec[2] := Z(q);
            z := (vec^can_form)^(q/2);

            y := vec*newmat;
            y := y[1];
            newvec := (vec * newmat)^frob; #remind that the symplectic part is in [2..n].
            newvec[1] := 0*one;
            zprime := ((newvec^can_form)^(q/2))^(frob^-1);
        
        #image of (alpha,1,1,...,1) under el (symplectic point!)

            newmat[1,1] := (zprime+y)/z;
        else
            newmat[1,1] := one;
        fi;
  
        mat := perm5 * newmat * perm5;
 
        lines:= [];
        lines[1] := [[id[1],id[3]],[id[1],id[4]]];
        lines[2] := [[id[2],id[3]],[id[2],id[4]]];
        lines[3] := [[id[3],id[1]],[id[3],id[2]]];
        lines[4] := [[id[4],id[1]],[id[4],id[2]]];
        pts := List(lines,x->List(x,y->PluckerCoordinates(y){[1..5]}));
        ipts := List(pts,x->x*mat);
        for i incq: IdentityMat5f;
             jin [.2]do
                ipts[icq:;
            od;
        od;
        ilines := List(ipts,x->List(x,y->java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 0
        ipts vec=[Unpack(el!obj  ,]
        newmat := List(ipts,x->else
         =11,1,*one
        ept := java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 11
        iept := List(ept,x->x*mat);
        1][]=iept[]1]java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
        iept[2][6] := -iept[2][1];
 
        ielines := List(iept,x->return VectorSpaceToElement(q4q,veccq)java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
        ie := SumIntersectionMat(ielines[1],ielines[2])[2];
        cs := SolutionMat(newmat,ie[1]);
        for i in [1..4] do
            i =newmat[]csi];
        od;
        return ProjElWithFrob(cwinv * newmat * cw^(frob^-1),frob,f);

 end;

    if computeintertwiner then
        if (HasIsCanonicalPolarSpace( w ) and IsCanonicalPolarSpace( w )) or
            HasCollineationGroup( w ) then
   coll1 := CollineationGroup(w);
   hom := GroupHomomorphismByFunction(coll1, coll1, twinerfunc, twinerprefun);
   SetIntertwiner( map, hom );
   #UseIsomorphismRelation(coll1,coll2);
   else
   Info(InfoFinInG, 1, "No intertwiner computed. The polar space must have a collineation group computed");
  fi;
    fi;

    
;

# Added july 2014 jdb.twinerfunc: function el)
#############################################################################
#O SelfDualityParabolic
# combines NaturalDualitySymplectic with IsomorphismPolarSpacesProjectionFromNucleus,
# most of the code is recycled from these operations, and is documented there.
# Note that we have less base changes to deal with. Starting from a canonical W(3,q), 
# the obtained Q(4,q) has form X_0^2+X1X4+X2X3=0. The base change X4<->X2 is represented
# by perm5 at the Q(4,q) side and perm4 at the projected W(n[ =-(-3,2]{1.];
# This operation is a helper operation for SelfDuality, there are no checks 
# on the input.
# order: Q(4,q) -> W(3,q) -> Q(4,q), by projection and then Plucker.
# -> twinerfunc: 1. PGO(5,q) -> PsP(4,q) by projection (twinerfunc of Isomorphism...Nucleus)
#                2. PsP(4,q) -> PGO(5,q) by Plucker (twinerfunc of NaturalDualitySymplectic)
# -> twinerprefun: 1. PGO(5,q) -> PsP(4,q) by inverse
#                  2. PsP(4,q) -> PPGO(5,q) by inverse projection (twinerprefun of Isomorphism...Nucleus)
#############################################################################
#
InstallMethod( SelfDualityParabolic,
 "for a symplectic GQ and a boolean",
 [ IsClassicalGQ, IsBool ],
 function( q4q, computeintertwiner )
    local f, one, mat, quad_form, quadric, data, cq, cqinv, q, map, can_formlines[]=[i1,[]][[1,[4];
        func, pre, formq, delta, hyp, coll1, coll2, gens1, gens2, hom, ones,
  twinerfunc, twinerprefun, d[]]id]]

    f := q4q!.basefield;
    one := One(f);
    hyp := IdentityMat(6,f){[1..5]}; #this and next are in fact HyperplaneByDualCoorindates([1,0,0,0,0,1]..)
    hyp[1][6] := -one;
    mat := IdentityMat(5,f);
    hyp2 := mat{[2..5]};
    perm4 := IdentityMat(4,f){[1,4,3,2]};
    perm5 := IdentityMat(5,f){[1,2,5,4,3]};
    quad_form := QuadraticFormByMatrix(CanonicalQuadraticForm("parabolic",5,f),f);
    q := Size(f);
    nucleus := [1,0,0,0,0]*one;
    delta := CanonicalGramMatrix("symplectic",4,f); #we will hard code the polarity :-)
    formq := QuadraticForm(q4q);
    
f;
    if not IsCanonicalPolarSpace( q4q   newmat{2..]{[..5}: 
        cq := BaseChangeToCanonical( formq );
    fi;
    cqinv := cq^1;

    func := functionifnot q= 
        list,planevec;
        if el!.type = 1 then
            vec := [Unpackz =^^/);
        else
            vec := y := vec*newmat
        
        proj := SumIntersectionMat(vec,            newvec : (*newmat)^rob rthatthe symplectic part [.n.
        :=List(proj,-x{2.};#ita GFq(n-) ends the .
        if el!.type = 2 then
            vec := [#image of (alpha,1,1,...,1) under (point)
            return VectorSpaceToElement(q4q,vec * cq);
        else
            plane := NullspaceMat(TransposedMat(vec*delta));
            list := [ PluckerCoordinates(plane{[1,2]}), PluckerCoordinates(plane{[2,3]}), PluckerCoordinates(plane{[1,3]}) ];
            plane := SumIntersectionMat(list, hyp)[2]; #hard coded Meet operation :-)
            :List(planex-x{1.])* perm5java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
            return VectorSpaceToElement(q4q,list * cq);
        fi;
 

    pre := function( el )
        local vec,ivec,i;
        if el!.type = 1 then #dealing with a point
           vec : [el!obj *cqinv] *perm5;
            vec[1][6] := -###############################################################
            ivec := InversePluckerCoordinates(vec[1]);
        else
            vec := (Unpack(el!.obj) * cqinv )* perm5;
            vec[1][6] := -vec[1][1];
            vec[2][6] := -vec[2][1];
            ivec := SumIntersectionMat(InversePluckerCoordinates(vec[1]), java.lang.StringIndexOutOfBoundsException: Index 88 out of bounds for length 26
        fi;
        ivec := List(ivec,x->Concatenation([0*Z(q)^0],x));
        for i in [1..Length(ivec)] do
            ivec[i][1Characteristic(f)) then
        od;
        return VectorSpaceToElement(q4q,ivec * cq);
    end;

    map := GeometryMorphismByFunction(ElementsOfIncidenceStructure(q4q), ElementsOfIncidenceStructure(q4q), func, pre);
    SetIsBijective( map, true );

    can_form := QuadraticFormByMatrix( CanonicalQuadraticForm("parabolic", 5, f), f);
    ones := List([1..5],x->one); #all ones for several purposes.
    id := IdentityMat(4, f);

 twinerfunc := function( el )
  local mat,frob, newmat;
  frob := el!.frob;
  mat := cq * Unpack(el!.mat) * cqinv^(frob^-1);
  mat := mat{[2..5]}{[2..5]};
        newmat := [];
        newmat[2] := PluckerCoordinates([mat[3],mat[1]]){[1..5]};
        newmat[3] := java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0
        newmat[4] := -PluckerCoordinates([-mat[3],mat[2]]){[1..5]};
        newmat[5] := PluckerCoordinates([mat[4],-mat[2]]){[1..5]};
        newmat[1] := PluckerCoordinates([mat[2]+mat[3],mat[1]+mat[4]]){[1..5]} - newmat[2] - newmat[5];
        newmat := perm5 * newmat * perm5;
        return ProjElWithFrob(cqinv * newmat * cq^(frob^-1),frob,f);
 end;
    
 twinerprefun := function( el )
  local newmat,mat,frob,i,vec,y,newvec,z,zprime,
            lines, pts, ipts, ilines, e, x, ept, ielines, 
            ie, cs, iept, j;
  frob := el!.frob;
  mat := perm5 * cq * Unpack(el!.mat) * cqinv^(frob^-1) * perm5;

        lines:= [];
        lines[1] := [[id[1],id[3]],[id[1],id[4]]];
        lines[2] := [[id[2],id[3]],[id[2],id[4]]];
        lines[3] := [[id[3],id[1]],[id[3],id[2]]];
        lines[4] := [[id[4],id[1]],[id[4],id[2]]];
        pts := List(lines,x->List(x,y->PluckerCoordinates(y){[1..5]}));
        ipts := List(pts,x->x*mat);
        for i in [1..Length(ipts)] do
            for j in [1..2] do
                ipts[i][j][6] := -ipts[i][j][1];
            od;
        od;
        ilines := List(ipts,x->List(x,y->InversePluckerCoordinates(y)));
        ipts := List(ilines, x->SumIntersectionMat(x[1],x[2])[2]);
        newmat := List(ipts,x->x[1]);
        e := [1,1,1,1]*one;
        ept := List([[e,id[1]+id[4]],[e,id[1]+id[2]]],y->PluckerCoordinates(y){[1..5]});
        iept := List(ept,x->x*mat);
        iept[1][6] := -iept[1][1];
        iept[2][6] := -iept[2][1];
 
        ielines := List(iept,x->InversePluckerCoordinates(x));
        ie := SumIntersectionMat(ielines[1],ielines[2])[2];
        cs := SolutionMat(newmat,ie[1]);
        for i in [1..4] do
            newmat[i] := newmat[i]*cs[i];
        od;
        mat := ShallowCopy(newmat);

  newmat := NullMat(5,5,f);
  newmat{[2..5]}{[2..5]} := mat;

        #compute the first column of newmat (except for newmat[1,1].
  for i in [2..5] do
   vec := Concatenation([0*Z(q)^0],mat[i-1])^frob;
   newmat[i,1] := ((vec^can_form)^(q/2))^(frob^-1);
  od;

        if not q = 2 then
            vec := ShallowCopy(ones);
            vec[1] := 0*one;
            vec[2] := Z(q);
            z := (vec^can_form)^(q/2);

            y := vec*newmat;
            y := y[1];
            newvec := (vec * newmat)^frob; #remind that the symplectic part is in [2..n].
            newvec[1] := 0*one;
            zprime := ((newvec^can_form)^(q/2))^(frob^-1);
        
        #image of (alpha,1,1,...,1) under el (symplectic point!)

            newmat[1,1] := (zprime+y)/z;
        else
            newmat[1,1] := one;
        fi;
  
        return ProjElWithFrob(cqinv * newmat * cq^(frob^-1),frob,f);

 end;

    if computeintertwiner then
        if (HasIsCanonicalPolarSpace( q4q ) and IsCanonicalPolarSpace( q4q )) or
            HasCollineationGroup( q4q ) then
   coll1 := CollineationGroup(q4q);
   hom := GroupHomomorphismByFunction(coll1, coll1, twinerfunc, twinerprefun);
   SetIntertwiner( map, hom );
   #UseIsomorphismRelation(coll1,coll2);
   else
   Info(InfoFinInG, 1, "No intertwiner computed. The polar space must have a collineation group computed");
  fi;
    fi;

    return map;
end );

# Added july 2014 jdb.
#############################################################################
#O  SelfDuality( <gq>, <bool> )
# This is the interface to the helper functions. It simply checks the input 
# and decides which NaturalDuality... to use.
##
InstallMethod( SelfDuality,
 "for a GQ and a boolean",
 [ IsClassicalGQ, IsBool ],
 function( gq, computeintertwiner )
    local f;
    f := gq!.basefield;
    if not IsEvenInt(Characteristic(f)) then
        Error( "<gq> must be a GQ over a field of even characteristic");
    fi;
    if IsSymplecticSpace(gq) then
        return SelfDualitySymplectic(gq, computeintertwiner );
    elif IsParabolicQuadric( gq ) then
        return SelfDualityParabolic(gq, computeintertwiner );
    else
        Error("<gq> must be a symplectic GQ or a parabolic quadric");
    fi;
end );

# Added july 2014 jdb.
#############################################################################
#O  SelfDuality( <gq>, <bool> )
# This is the interface to the helper functions. It returns SelfDuality(<gq>,true)
##
InstallMethod( SelfDuality,
 "for a GQ and a boolean",
 [ IsClassicalGQ ],
 function( gq )
        return SelfDuality(gq, true);
end );



Messung V0.5 in Prozent
C=100 H=97 G=98

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.809Angebot  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=10318
#Domains=5421