
(*  HughesPlanes.m  *)

(*  Vedran Krcadinac, April, 1996.  *)


(* Load a Hughes nearfield and all necessary objects *)

LoadFF[name_] :=
 ( Clear[FFPlus,FFTimes,FFInverse,A,L]; Get[name];  L[t_] := L[t] =
   Cases[Points[FFOrder] , {x_,y_,z_} /; FFPlus[x,FFTimes[y,t],z] == 0 ]
 )


(* The points in a Hughes plane *)

Points[x_ /; x == FFOrder] := Points[x] =  
  Join[{{0,0,1}},Table[{0,1,i},{i,0,FFOrder-1}],
       Flatten[Table[{1,i,j},{i,0,FFOrder-1},{j,0,FFOrder-1}],1]]


(* L(t) is the set of all points (x,y,z) that satisfy the equation
   x + yt + z = 0                                                   *)

L[t_] := L[t] =
  Cases[Points[FFOrder] , {x_,y_,z_} /; FFPlus[x,FFTimes[y,t],z] == 0 ]


(* Matrix-vector product over the loaded Hughes nearfield  *)

FFDot[M_, v_] :=
  Table[Inner[FFTimes, M[[i]], v, FFPlus], {i, 1, First[Dimensions[M]]}]


(* The construction of Hughes planes  *)

Norm[{0, 0, x_}] := {0, 0, 1}

Norm[{0, x_, y_}] := {0, 1, FFTimes[FFInverse[x], y]}

Norm[{x_, y_, z_}] :=
  {1, FFTimes[FFInverse[x], y], FFTimes[FFInverse[x], z]}

HughesPlane := Map[Norm,
 Join[ Table[ Map[FFDot[A[m],#] &, L[1]], {m,0,FFOrder+Sqrt[FFOrder]}],
       Flatten[ Table[ Map[FFDot[A[m],#] &, L[t]], {m,0,FFOrder+Sqrt[FFOrder]},
              {t,Sqrt[FFOrder],FFOrder-1} ] , 1]
     ],
             {2}]


(* A normalization rule that transforms ordered triplets to integers *)

Normalize := {x_Integer,y_Integer,z_Integer} :> 
         Position[Points[FFOrder],{x,y,z}][[1,1]] 


(* Transformation of Hughes projective planes to affine planes *)

ProjectiveToAffine[pp_,pos_] :=
  Module[ {plane,line} ,
          plane = pp /. Normalize;
          line = plane[[pos]];
          DeleteCases[Delete[plane,pos] , x_Integer /;
                      MemberQ[line,x] , -1          ]
        ]              


(* Compute the incidence matrix of a plane *)
 
IncidenceMatrix[plane_] :=
  Module[{po, i, j}, po = Union[Flatten[plane, 1]];
    Table[If[MemberQ[plane[[i]], po[[j]]], 1, 0], {j, 1, Length[po]},
     {i, 1, Length[plane]}]]

(* The incidence matrix M of a projective plane should satisfy
   M . Transpose[M] == TestMatrix                                *)

TestMatrix := FFOrder*IdentityMatrix[FFOrder^2 + FFOrder + 1] + 
   Table[1, {FFOrder^2 + FFOrder + 1}, {FFOrder^2 + FFOrder + 1}]


(* Joining points and intersecting lines *)

Vee[plane_,A_,B_] := 
  If[A==B, Message[Vee::samearg]; $Failed,
           Position[plane, x_ /; MemberQ[x,A] && MemberQ[x,B],{1}][[1,1]] ]

Vee::samearg =
  "Attempt to join point with itself.";

Wedge[plane_,a_,b_] :=
  If[a==b, Message[Wedge::samearg]; $Failed,
           Intersection[plane[[a]],plane[[b]]][[1]] ]

Wedge::samearg =
  "Attempt to intersect line with itself.";
