The following code searches for incidence structures in the nonAbelian groups \(\mathbb{F}_{p^{2}}\times H\) where \(H\) is the integers modulo \(p+1\). We first define several functions.
Bin_op:=function(p,x,y) //defines a binary operation on a cartesian product
return <x[1]+y[1]^(p^(Integers() ! y[2])),x[2]+y[2]>;
end function;
Op_inv:=function(p,x) //defines the inverse wrt above binary operation
return <(-x[1])^(p^(Integers() ! -x[2])),-x[2]>;
end function;
nPow:=function(a,n,p) //defines nth power wrt above binary operation
i:=0;
x:=a;
while i lt n+1 do
x:=Bin_op(p,x,a);
i:=i+1;
end while;
return x;
end function;
Trans_bin:=function(A,p,x) //creates translation by x of set of elements wrt above binary op
X:={};
for a in A do
Include(~X,Bin_op(p,x,a));
end for;
return X;
end function;
Build_S:=function(G,p,s) //builds set of elements of form <h,0> where h is in GF(p,s)
H:=Set(GF(p,s));
X:={G|};
for h in H do
Include(~X,<h,0>);
end for;
return X;
end function;
Build_splint:=function(p,W) //builds set of 1-dim subgroups of W
X:={@ @};
for w in W diff {<0,0>} do
Y:={w};
for i in {0..p-1} do
Include(~Y,nPow(w,i,p));
end for;
Include(~X,Y);
end for;
return X;
end function;
Build_flesh:=function(p,A) //collects members of form x*y where x,y are in A and puts them in a set
X:=A;
for x,y in X do
Include(~X,Bin_op(p,x,y));
end for;
return X;
end function;
fleshPow:=function(p,A,n) //builds subgroup generated by members of A
i:=0;
X:=A;
while i lt n+1 do
X:=Build_flesh(p,X);
i:=i+1;
end while;
return X;
end function;
Build_splint0:=function(p,W,k) //builds set of subgroups of W of order p^k
X:={@ @};
for A in Subsets(W diff {<0,0<},k) do
Y:=A;
while # Y lt # Build_flesh(p,Y) do
Y:=Build_flesh(p,Y);
end while;
if # Y eq p^k then
Include(~X,Y);
end if;
end for;
return X;
end function;
Build_cos_reps:=function(G,Subgrp,p) //builds set of coset reps of a subgroup of G
X:={};
Y:={};
for g in G do
W:={};
for g1 in Subgrp do
Include(~W,Bin_op(p,g,g1));
end for;
if W notin X then
Include(~X,W);
Include(~Y,g);
end if;
end for;
return SetToIndexedSet(Y);
end function;
Build_diff:=function(G,p,s) //builds incidence structure which is union of differences of subgroups of G
S:=Build_S(G,p,s);
Spl:=Build_splint0(p,S,s-1);
X:=Build_cos_reps(G,S,p);
Y:={};
for i in {1..# X} do
Y:=Y join Trans_bin(S diff Spl[i],p,X[i]);
end for;
return Y;
end function;
Build_diff0:=function(G,p,s,W,m) //variation of above union
S:=Build_S(G,p,s);
Spl:=W;
X:=Build_cos_reps(G,S,p);
Y:={};
for i in {1..m} do
Y:=Y join Trans_bin(S diff Spl[i],p,X[i]);
end for;
for i in {m+1..# X} do
Y:=Y join Trans_bin(Spl[i],p,X[i]);
end for;
return Y;
end function;
Multi:=function(p,G,U) //builds multiset {u1-u2 | u1,u2 are in U and u1 not equal to u2}
X:={* *};
for u1,u2 in U do
if u1 ne u2 then
Include(~X,Bin_op(p,u1,Op_inv(p,u2)));
end if;
end for;
return X;
end function;
Check_multi:=function(p,G,U) //checks multiplicites of members of multiset and puts them into a set
X:={};
for g in G diff {G ! <0,0<} do
Include(~X,Multiplicity(Multi(p,G,U),g));
end for;
return X;
end function;
Check_multi0:=function(p,G,U) //variation of above function that keeps track of whether the cayley graph is an srg
X:={};
Y:={};
for u in U do
Include(~X,Multiplicity(Multi(p,G,U),u));
end for;
for u in Set(G) diff (U join {<0,0<}) do
Include(~Y,Multiplicity(Multi(p,G,U),u));
end for;
return [* X, Y *];
end function;
Here we check whether the set union obtained with \(p=7\) and \(s=2\) is a difference set.
p:=7; //finds almost differecne set in the nonabelian group G=GF(p,s)xC where C is integers modulo p+1
s:=2;
H1:=Set(GF(p,s));
r:=(p^s-1)/(p-1);
r:=Integers() ! r;
H2:=Set(Integers(r));
G:=Set(CartesianProduct(H1,H2));
S:=Build_S(G,p,s);
Spl:=Build_splint0(p,S,s-1);
X:=Build_cos_reps(G,S,p);
for m in {5..# X} do
U:=Build_diff0(G,p,s,Spl,m);
print "m=",m;
Check_multi(p,G,U);
end for;