
E := EllipticCurve(CremonaDatabase(), "2006E1");
time TwoSelmerGroup(E);
//

AnalyticRank(E);
//

E := EllipticCurve(CremonaDatabase(), "2331C1");
E;
AnalyticRank(E);
ConjecturalRegulator(E);  //  = Regulator * #Sha,  actually
//
#TwoSelmerGroup(E);
curves := TwoDescent(E);
curves;
C2 := curves[1];
C2;
//
time Points(E : Bound := 10^5);
time Points(C2 : Bound := 10^5);

// TRY FOUR DESCENT ...
FourDescent(C2);
C4 := $1[1];
PointsQI(C4, 10^5);   // Search for rational points on C4
ptC4 := C4! $1[1];
_, C4toE := AssociatedEllipticCurve(C4 : E:=E );
// 
ptE := C4toE(ptC4);
ptE;
// How did we miss it?
Ilog(10, Numerator(ptE[1]));  // Should be about 8 times as many digits as ptC4
// Let's look at the image on C2 
//  ... it's in the middle of C4 --> C2 --> E
//  ... and should have about twice as many digits as ptC4
_, C4toC2 := AssociatedHyperellipticCurve(C4 : C2:=C2 );
C4toC2(ptC4);

//
// THE FIRST CURVE WITH NONTRIVIAL SHA (Conductor = 390)
E := EllipticCurve(CremonaDatabase(), "390B5");
E;
RankBounds(E);
TwoTorsionSubgroup(E);
C2s := TwoDescent(E); 
C2s;
for C2 in C2s do FourDescent(C2); end for;
//
// This proves that Rank(E) = 0, and Sha(E) contains (Z/2Z)^2.
// Also, the nontrivial C4 will have very small points. 
C4s :=  FourDescent(C2s[4]);
for C4 in C4s do PointsQI(C4, 5); end for;


// TRY A HEEGNER POINT ...
E := EllipticCurve(CremonaDatabase(), "2331C1");
time HeegnerPoint(E);
// What is a "HeegnerPoint"?
SetVerbose("Heegner",1);
bool, HPt := HeegnerPoint(E);
//
Saturation([HPt],1000);
//
TorsionSubgroup(E);
DivisionPoints(HPt, 2);
DivisionPoints(HPt, 3);
//
// MORE ABOUT THE HEEGNER POINTS ...
ClassNumber(QuadraticField(-83));
// So there should be 3 conjugate points on X_0(N).
// In the upper half plane, they are given as the roots of quadratic polynomials:
HeegnerForms(E, -83);
//
K<sqrt> := QuadraticField(-83);
for tup in $1 do Roots(Polynomial(Reverse(Eltseq(tup[1]))),K)[1,1]; end for;
HeegnerPointsOverClassField(E, -83);   // points in E(H_K)
// Too big! (Can't get enough precision to recognise rationals)
// A simple example : the first curve of rank 1 ...
E := EllipticCurve(CremonaDatabase(), "37A1");
E;
Generators(E);
RankBounds(E);
HeegnerPoint(E);
HeegnerDiscriminants(E, -200 ,0);
HeegnerPointsOverClassField(E, -83);   // points in E(H_K)
//


// COULD ALSO TRY THREE DESCENT ...
E := EllipticCurve(CremonaDatabase(), "2331C1");
// Needs class group of a degree 8 field ...
//  ... don't try to do it unconditionally
SetClassGroupBounds("GRH");
curves3, mapstoE := ThreeDescent(E);
curves3;
PointSearch(curves3[1], 10^5);
//
Hpt := HeegnerPoints(E);
pullbackscheme := Hpt @@ mapstoE[1];
Points(pullbackscheme);
pullbackscheme := -Hpt @@ mapstoE[1];
Points(pullbackscheme);

//
// A CURVE WITH 3-SHA
Pr2<X,Y,Z> := ProjectiveSpace(Rationals(),2);
E := EllipticCurve(Curve(Pr2, X^3+Y^3+73*Z^3));
E;
ThreeTorsionType(E);
C3s, _, dualC3s, _, Isog := ThreeIsogenyDescent(E);
C3s;
dualC3s;
 EE := Codomain(Isog);
ThreeSelmerGroup(E);
 C3sOverEE := ThreeDescent(EE);
 C3sOverEE;
//
[CC : CC in  C3sOverEE | IsEquivalent(Equation(CC), Equation(dualC3s[1])) ];

//
// THREE-ISOGENY DESCENT FOR LARGE CURVES
SetVerbose( "Reduce", 2 );
for p := 1000000000 to 1000000004 do E := EllipticCurve([0,p]); E;
time C3s, _, dualC3s := ThreeIsogenyDescent(E); C3s; dualC3s; end for;
 


// 2-DESCENT FOR E DEFINED OVER F_p(t)
// This is the first step in a new direction for Magma

SetVerbose("Selmer",3);
F<t> := FunctionField(GF(3));
E := EllipticCurve([t^3-t+1,t^5+t-1]); E;
//
TwoSelmerGroup(E);
//
// AnalyticInformation computes conjectural values for the
// rank, the geometric rank, and the regulator*sha
AnalyticInformation(E);
//
// The actual regulator of this curve:
Determinant(HeightPairingMatrix(Basis(Generators(E))));

E := EllipticCurve([t^6-t+1,t^5+t-1]); E;
//
TwoSelmerGroup(E);
//
AnalyticInformation(E);
//
Determinant(HeightPairingMatrix(Basis(Generators(E))));


