#############################################################################
##
#W plane_isomorphisms.gd 			 RDS Package		 Marc Roeder
##
##  Methods for calculations with projective planes
##
#H @(#)$Id: plane_isomorphisms.gd, v 0.9beta21 15/11/2006 19:33:30 gap Exp $
##
#Y	 Copyright (C) 2006 Marc Roeder 
#Y 
#Y This program is free software; you can redistribute it and/or 
#Y modify it under the terms of the GNU General Public License 
#Y as published by the Free Software Foundation; either version 2 
#Y of the License, or (at your option) any later version. 
#Y 
#Y This program is distributed in the hope that it will be useful, 
#Y but WITHOUT ANY WARRANTY; without even the implied warranty of 
#Y MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
#Y GNU General Public License for more details. 
#Y 
#Y You should have received a copy of the GNU General Public License 
#Y along with this program; if not, write to the Free Software 
#Y Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
##
Revision.("rds/lib/plane_isomorphisms_gd"):=
	"@(#)$Id: plane_isomorphisms.gd, v 0.9beta21 15/11/2006   19:33:30  gap Exp $";
#############################################################################
##
#O  DualPlane( <blocks> )  generate dual plane
##
##  For a projective plane given by <blocks>, `DualPlane( <blocks> )' returns
##  a record containing a set of blocks defining the dual plane and a List 
##  <image> containing the same blocks such that <image[p]> is the image of the
##  point <p> under duality.
##  It is not tested, if the design defined by <blocks> is actually
##  a projective plane.
##
DeclareOperation("DualPlane",[IsDenseList]);

#############################################################################
##
#O ProjectiveClosureOfPointSet(<points>,<maxsize>,<data>)
##
##  Let $P$ be a projective plane given by the record <data> as returned by
##  `ElationPrecalcSmall'. Let <points> be a set of points (integers). Then
##  `ProjectiveClosureOfPointSet' returns the projective colsure of <points>
##  in $P$ (the smallest subplane of $P$ containing the points <points>). 
##  The closure is returned as a list of points. 
##  If $<maxsize>\neq 0$, calculations are stopped if the closure is known to
##  have at least <maxsize> points and <data.points> is returned.
##  Observe that this is a ``small'' function, in the sense that it does not 
##  need the data from `ElationPrecalc' but merely the data generated by
##  `ElationPrecalcSmall'.
##
DeclareOperation("ProjectiveClosureOfPointSet",[IsDenseList,IsInt,IsRecord]);


#############################################################################
##
#O  IsIsomorphismOfProjectivePlanes( <perm>,<blocks1>,<blocks2> )  test for isomorphism of projective planes on the same points
##
##  Let <blocks1>, <blocks2> be two sets of blocks of projective planes 
##  on the same points. 
##  `IsIsomorphismOfProjectivePlanes( <perm>,<blocks1>,<blocks2> )' test if the permutation
##  <perm> on points defines an isomorphism of the projective planes defined
##  by <blocks1> and <blocks2>.
##
DeclareOperation("IsIsomorphismOfProjectivePlanes",[IsPerm,IsDenseList,IsDenseList]);

#############################################################################
##
#O  IsCollineationOfProjectivePlane( <perm>,<blocks> )  test if a permutation is a collineation of a projective plane
#O  IsCollineationOfProjectivePlane( <perm>,<data> )  test if a permutation is a collineation of a projective plane
##
##  Let <blocks> be the blocks of a projective plane and <perm> a permutation
##  on the points of this plane. `IsCollineationOfProjectivePlane(<perm>,<blocks>)' returns 
##  `true', if <perm> induces a collineation of the projective plane.
##
##  If <data> as returned by `ElationPrecalc' is given instead of <blocks>,
##  the calculation should be faster.
##
DeclareOperation("IsCollineationOfProjectivePlane",[IsPerm,IsDenseList]);
DeclareOperation("IsCollineationOfProjectivePlane",[IsPerm,IsRecord]);


#############################################################################
##
#F  ElationPrecalc( <blocks> )  generate data for calculating elations
#F  ElationPrecalcSmall( <blocks> )  generate data for calculating elations
##
##  Given the blocks <blocks> of a projective plane, 
##  `ElationPrecalc( <blocks> )' returns a record conatining 
##  \beginlist
##   \item{.points} the points of the projective plane (immutable)
##   \item{.blocks} the blocks as passed to the function (immutable)
##   \item{.jpoint} a matrix with $ij$-th entry the point meeting the 
##      $i$-th and the $j$-th block.
##   \item{.jblock} a matrix with $ij$-th entry the position of the block 
#       connecting the point $i$ to the point $j$ in <blocks>.
##  \endlist
## 
##  `ElationPrecalcSmall( <blocks> )' returns a record which 
##  does only contain <.points>, <.blocks> and <.jblock>. Hence the name.
##
DeclareGlobalFunction("ElationPrecalc");
DeclareGlobalFunction("ElationPrecalcSmall");

#############################################################################
##
#O  ElationsByPairs( <centre>,<axis>,<pairs>,<data>)  calculate elations of projective planes.
#O  ElationsByPairs( <centre>,<axis>,<pairs>,<blocks>)  calculate elations of projective planes.
#O  ElationsByPairsSmall( <centre>,<axis>,<pairs>,<data>)  calculate elations of projective planes.
##
##  Let <centre> be a point and  <axis> a block of a projective plane defined 
##  by <blocks> (or by <data> as returned by `ElationPrecalc').
##  The list <pairs> must contain pairs of points outside <axis>. 
##  `ElationsByPairs' returns a collineation fixing <axis> pointwise and
##  <centre> blockwise (an elation) such that for each pair <p> of <pairs> 
##  <p[1]> is mapped on <p[2]>. If no such elation exists, `fail' is returned.
##  
##  `ElationsByPairsSmall' uses <data> as returned by `ElationPrecalcSmall'
##
DeclareOperation("ElationsByPairs",[IsInt,IsDenseList,IsDenseList,IsRecord]);
DeclareOperation("ElationsByPairs",[IsInt,IsDenseList,IsDenseList,IsDenseList]);
DeclareOperation("ElationsByPairsSmall",[IsInt,IsDenseList,IsDenseList,IsRecord]);


#############################################################################
##
#O  AllElationsCentAx( <centre>,<axis>,<data>[,"generators"])  calculate elations of projective planes.
#O  AllElationsCentAx( <centre>,<axis>,<blocks>[,"generators"])  calculate elations of projective planes
#O  AllElationsCentAxSmall( <centre>,<axis>,<data>[,"generators"])  calculate elations of projective planes.
##
##  Let <centre> be a point and  <axis> a block of a projective plane defined 
##  by <blocks> (or by <data> as returned by `ElationPrecalc').
##  `AllElationsCentAx' returns a list of all non-trivial elations with centre
##  <centre> and axis <axis>.
##  If ``generators'' is set, a list of generators of the translation
##  group is returned.
##  
DeclareOperation("AllElationsCentAx",[IsInt,IsDenseList,IsRecord]);
DeclareOperation("AllElationsCentAx",[IsInt,IsDenseList,IsDenseList]);
DeclareOperation("AllElationsCentAx",[IsInt,IsDenseList,IsRecord,IsString]);
DeclareOperation("AllElationsCentAx",[IsInt,IsDenseList,IsDenseList,IsString]);
DeclareOperation("AllElationsCentAxSmall",[IsInt,IsDenseList,IsRecord]);
DeclareOperation("AllElationsCentAxSmall",[IsInt,IsDenseList,IsRecord,IsString]);

#############################################################################
##
#O  AllElationsAx(<axis>,<data>[,"generators"])  calcualte all elations with given axis.
#O  AllElationsAx(<axis>,<blocks>)  calcualte all elations with given axis.
#O  AllElationsAxSmall(<axis>,<data>[,"generators"])  calcualte all elations with given axis.
##
##  Let <axis> be a block of a projective plane defined 
##  by <blocks> (or by <data> as returned by `ElationPrecalc').
##  `AllElationsAx' returns a list of all non-trivial elations with axis 
##  <axis>.
DeclareOperation("AllElationsAx",[IsDenseList,IsRecord]);
DeclareOperation("AllElationsAx",[IsDenseList,IsRecord,IsString]);
DeclareOperation("AllElationsAx",[IsDenseList,IsDenseList]);
DeclareOperation("AllElationsAx",[IsDenseList,IsDenseList,IsString]);
DeclareOperation("AllElationsAxSmall",[IsDenseList,IsRecord]);
DeclareOperation("AllElationsAxSmall",[IsDenseList,IsRecord,IsString]);

#############################################################################
##
#O IsTranslationPlane(<infline>,<planedata>)
#O IsTranslationPlaneSmall(<infline>,<planedata>)
##
##  If the group of elations with axis <infline> is (sharply) transitive on 
##  the affine points (the points outside <infline>), `IsTranslationPlane' 
##  returns `true', otherwise it returns `false'. This is faster than 
##  calculating the full translation group if the projective plane is not a 
##  translation plane.
##
DeclareOperation("IsTranslationPlane",[IsDenseList,IsRecord]);
DeclareOperation("IsTranslationPlaneSmall",[IsDenseList,IsRecord]);

#############################################################################
##
#O GroupOfHomologiesSmall(<centre>,<axis>,<data>)
##
##  returns the group of homologies with centre <centre> and axis 
##  <axis>.
##
DeclareOperation("GroupOfHomologiesSmall",[IsInt,IsDenseList,IsRecord]);

#############################################################################
##
#O HomologyByPairSmall(<centre>,<axis>,<pair>,<data>)
##
##  `HomologyByPairSmall' returns the homology defined by the pair
##  <pair> fixing <centre> blockwise and <axis> pointwise. 
##  The returned permutation fixes <axis> pointwise and <centre> linewise and
##  takes <pair[1]> to <pair[2]>.
##

DeclareOperation("HomologyByPairSmall",[IsInt,IsDenseList,IsDenseList,IsRecord]);

#############################################################################
##
#O InducedCollineation(<baerdata>,<baercoll>,<point>,<image>,<planedata>,<liftingperm>)
##
##  If a projective plane contains a Baer subplane, collineations of the 
##  subplane may be lifted to the full plane. Here <baercoll> is a collineation
##  of the subplane given by <baerdata> (as returned by `ElationPrecalc'. 
##  Be careful, as the enumeration for the subplane is not the same as for the
##  whole plane). <liftingperm> is a permutation on the points of the full pane
##  which converts the enumeration of the subplane to that of the full plane. 
##  This means that the image of <baerdata.points> under <liftingperm> is a 
##  subset of <planedata.points>. Namely the one representing the Baer plane
##  in the enumeration used for the whole plane.
##  <point> and <image> are points outside the Baer plane.
##
##  `InducedCollineation' returns a collineation of the full plane (as a  
##  permutation on <planedata.points>) which takes <point> to <image> and acts
##  on the Baer plane as <baercoll> does.
##
##  Just to make this clear again, <baerdata> has points $[1,\dots,n^2+n+1]$
##  and <planedata> has points $[1,\dots,n^4+n^2+1]$. <baercoll> lives on 
##  <baerdata.points> (and hence on $n^2+n+1$ points) and <point> and <image> 
##  live on <planedata.points>. Anything can happen if you mix something up 
##  here.
DeclareOperation("InducedCollineation",[IsRecord,IsPerm,IsInt,IsInt,IsRecord,IsPerm]);

#############################################################################
##
#O  NrFanoPlanesAtPoints(<points>,<data>)  invariant for projective planes
##
##  For a projective plane defined by the blocks  <data> as returned 
##  by `ElationPrecalc', `NrFanoPlanesAtPoints(<points>,<data>)' 
##  calculates the so-called Fano invariant. That is, for each point 
##  in <points>, the number of subplanes of order 2 (so-called Fano planes)
##  containing this point is calculated.
##  The method returns a list of pairs of the form $[<point>,<number>]$
##  where <number> is the number of Fano sub-planes in <point>.
DeclareOperation("NrFanoPlanesAtPoints",[IsDenseList,IsRecord]);
DeclareOperation("NrFanoPlanesAtPoints",[IsDenseList,IsDenseList]);

#############################################################################
#O  NrFanoPlanesAtPointsSmall(<pointlist>,<data>)  invariant for projective planes

##
##  Uses <data> as returned by `ElationPrecalcSmall'. Only use this, if you
##  want to do a quick experiment in a plane of *small* order and don't like
##  to generate a new set of data with `ElationPrecalc'. The difference
##  between `NrFanoPlanesAtPoints' and `NrFanoPlanesAtPointsSmall' is that
##  the ``small'' version does some operations for lists (like `Intersection')
##  whereas the ``large'' version does only read matrix entries. This makes
##  quite a difference as for a plane of order $n$, there are 
##  ${n+1 \choose 3}{n\choose 2}n$ quadrangles to be tested per point.
##
DeclareOperation("NrFanoPlanesAtPointsSmall",[IsDenseList,IsRecord]);

#############################################################################
##
#O IncidenceMatrix(<points>,<blocks>)
#O IncidenceMatrix(<data>)
##
##  returns a matrix <I>, where the columns are numbered by the blocks and
##  the rows are numbered by points. And <I[i][j]=1> if and only if 
##  <points[i]> is incident (contained in) <blocks[j]>.
##
DeclareOperation("IncidenceMatrix",[IsDenseList,IsDenseList]);
DeclareOperation("IncidenceMatrix",[IsRecord]);

#############################################################################
##
#O pRank(<blocklist>,<p>)
#O pRank(<data>,<p>)
##
##  Let <I> be the incidence matrix of the projective plane given by  the list
##  of blocks <blocklist> or the record <data> as returned by 
##  `ElationPrecalc'. The rank of $I.I^t$ as a matrix over
##  $GF(p)$ is called  <p>-rank of the projective plane. Here $I^t$ denotes
##  the transposed matrix.
##
##  As `pRank' calls `IncidenceMatrix', the list <blocklist> has to be a list 
##  of lists of integers.
##
DeclareOperation("pRank",[IsDenseList,IsInt]);
DeclareOperation("pRank",[IsRecord,IsInt]);

#############################################################################
##
#O FingerprintAntiFlag(<point>,<linenr>,<data>)
##
##  Let $m_1,\dots,m_{n+1}$ be the lines containing <point> and 
##  $E_1,\dots,E_{n+1}$ the points on the line given by <linenr> such that
##  $E_i$ is incident with $m_i$. Now label the points of $m_i$ as 
##  $<point>=P_{i,1},\dots,P_{i,n+1}=E_i$ and the lines of $E_i$ as
##  $<line>=l_1,\dots,l_{i,n+1}=m_i$. 
##  For $i\not = j$, each $P_{j,k}$ lies on exactly one line 
##  $l_{i,k\sigma_{i,j}}$ containing $E_i$ for some permutation $\sigma_{i,j}$
##
##  Define a matrix $A$, where $A_{i,j}$ is the sign of $\sigma_{i,j}$ if 
##  $i\neq j$ and $A_{i,i}=0$ for all $i$.
##  The partial fingerprint is the multiset of entries of $|AA^t|$ where $A^t$ 
##  denotes the transposed matrix of $A$.
##
##  this is a ``small'' function.
##
DeclareOperation("FingerprintAntiFlag",[IsInt,IsInt,IsRecord]);

#############################################################################
##
#O FingerprintProjPlane(<blocks>)
#O FingerprintProjPlane(<data>)
##
##  For each anti-flag $(p,l)$ of a projective plane of order $n$, 
##  define an arbitrary but fixed enumeration of the lines through $p$ and 
##  the points on $l$. Say $l_1,\dots,l_{n+1}$ and $p_1,\dots,p_{n+1}$
##  The incidence relation defines a canonical bijection between the $l_i$ and
##  the $p_i$ and hence a permutation on the indices $1,\dots,n+1$. 
##  Let $\sigma_{(p,l)}$ be this permutation.
##
##  Denote the points and lines of the plane by $q_1,\dots q_{n^2+n+1}$ 
##  and $e_1,\dots,e_{n^2+n+1}$. 
##  Define the sign matrix as $A_{ij}=sgn(\sigma_{(q_i,e_j)})$ if $(q_i,e_j)$ 
##  is an anti-flag and $=0$ if it is a flag.
##  Then the fingerprint is defnied as the multiset of the entries of $|AA^t|$.
##  Here <data> is a record as returned by `ElationPrecalcSmall'.
##
DeclareOperation("FingerprintProjPlane",[IsDenseList]);
DeclareOperation("FingerprintProjPlane",[IsRecord]);


#############################################################################
##
#O IsomorphismProjPlanesByGenerators(<gens1>,<data1>,<gens2>,<data2>)
#O IsomorphismProjPlanesByGeneratorsNC(<gens1>,<data1>,<gens2>,<data2>)
##
##  Let <gens1> be a list of points generating the projective plane defined 
##  by <data1> and <gens2> a list of generating points for <data2>. Then a 
##  permutation is returned representing a mapping from the <data1.points> 
##  to <data2.points> and mapping the list <gens1> to the list <gens2>.
##  If there is no such mapping which defines an isomorphism of projective
##  planes, `fail' is returned.
##  Note that this is a ``small'' function, in the sense that <data1> and 
##  <data2> are as returned by `ElationPrecalcSmall' rather than by
##  `ElationPrecalc'.
##
##  `IsomorphismProjPlanesByGeneratorsNC' does *not* checked whether <gens1> 
##  and <gens2> really generate the planes given by <data1> and <data2>. 
##
DeclareOperation("IsomorphismProjPlanesByGenerators",[IsDenseList,IsRecord,IsDenseList,IsRecord]);
DeclareOperation("IsomorphismProjPlanesByGeneratorsNC",[IsDenseList,IsRecord,IsDenseList,IsRecord]);

#############################################################################
#E