//Names od all of the lists and arrays that we will be using.
SetClassGroupBounds("GRH");
TwoClassGroupRank := AssociativeArray();
TrueCurveRank :=  AssociativeArray();
FalseCurveRankLowerBound :=  AssociativeArray();
FalseCurveRankUpperBound :=  AssociativeArray();
WashingtonsBound := AssociativeArray();
MsChecked := [];
FalseCurveRankList := [];
TrueCurveRankList := [];





//Function to add the data gathered from searching through N
Set := [1..20000];
for m in Set do
if IsSquarefree(m^2+3*m+9) and m^2+3*m+9 mod 3 ne 0 then
Append(~MsChecked,m);
f := Polynomial([1,-(m+3),m,1]);m;
E := EllipticCurve(f);
Lm := NumberField(f);
G := ClassGroup(Lm);
mult2 := hom<G -> G | g :-> 2*g>;
TwoRank := Integers()!(Log(#Kernel(mult2))/Log(2));
rlower , rupper := RankBounds(E);
//Keeps track of the rank of the two class group of L_m
if IsDefined(TwoClassGroupRank,TwoRank) then
TwoClassGroupRank[TwoRank]:=Append(TwoClassGroupRank[TwoRank],m);
else
TwoClassGroupRank[TwoRank]:=[m];
end if;
//Keeps track of the rank of Washington's bound for E_m
if IsDefined(WashingtonsBound,TwoRank+1) then
WashingtonsBound[TwoRank+1]:=Append(WashingtonsBound[TwoRank+1],m);
else
WashingtonsBound[TwoRank+1]:=[m];
end if;
//Keeps track of the m that we can provably compute the rank of E_m and what the rank is
if rlower eq rupper then
Append(~TrueCurveRankList,m);
r := rlower;
if IsDefined(TrueCurveRank,r) then
TrueCurveRank[r]:=Append(TrueCurveRank[r],m);
else
TrueCurveRank[r]:=[m];
end if;
end if;
//Keeps track of the m that we can't provably compute the rank of E_m and what the lower bound of the rank is
if rupper ne rlower then
Append(~FalseCurveRankList,m);
if IsDefined(FalseCurveRankLowerBound,rlower) then
FalseCurveRankLowerBound[rlower]:=Append(FalseCurveRankLowerBound[rlower],m);
else
FalseCurveRankLowerBound[rlower]:=[m];
end if;
//Keeps track of the m that we can't provably compute the rank of E_m and what the upper bound of the rank is
if IsDefined(FalseCurveRankUpperBound,rupper) then
FalseCurveRankUpperBound[rupper]:=Append(FalseCurveRankUpperBound[rupper],m);
else
FalseCurveRankUpperBound[rupper]:=[m];
end if;
end if;
end if;
end for;


//Procedure to write the data gathered above as a loadable magma file.
//The input is the directory where you would like it to be written.
procedure WriteGenus1SearchData(Dir)
ArrayList := [TwoClassGroupRank, TrueCurveRank, FalseCurveRankLowerBound, FalseCurveRankUpperBound, WashingtonsBound];
ArrayNames := ["TwoClassGroupRank", "TrueCurveRank", "FalseCurveRankLowerBound", "FalseCurveRankUpperBound", "WashingtonsBound"];
for i in [1..#ArrayList] do
Name := ArrayNames[i];
fprintf Dir, "%o := %o;\n",Name,"AssociativeArray()";
end for;
for i in [1..#ArrayList] do
A := ArrayList[i];
Name := ArrayNames[i];
for key in Keys(A) do
fprintf Dir, "%o[%o] := %o;\n",Name,key,A[key];
end for;
end for;
fprintf Dir, "MsChecked := %o;\n", MsChecked;
fprintf Dir, "FalseCurveRankList:= %o;", FalseCurveRankList;
fprintf Dir, "TrueCurveRankList:= %o;", TrueCurveRankList;
end procedure;
