Curves over the Rationals

Contents

Local Invariants

Conductor(E) : CrvEll -> RngIntElt
The conductor of the elliptic curve E defined over Q.
BadPrimes(E) : CrvEll -> [ RngIntElt ]
Given an elliptic curve E defined over Q, return the sequence of primes dividing the minimal discriminant of E. These are the primes at which the minimal model for E has bad reduction; note that there may be other primes dividing the discriminant of the given model of E.
TamagawaNumber(E, p) : CrvEll, RngIntElt -> RngIntElt
Given an elliptic curve E defined over Q and a prime number p, this function returns the local Tamagawa number of E at p, which is the index in E(Qp) of the subgroup E0(Qp) of points with nonsingular reduction modulo p. For any prime p that is of good reduction for E, this function returns 1.
TamagawaNumbers(E) : CrvEll -> [ RngIntElt ]
Given an elliptic curve E defined over Q, this function returns the sequence of Tamagawa numbers at each of the bad primes of E, as defined above.
LocalInformation(E, p) : CrvEll, RngIntElt -> <RngIntElt, RngIntElt, RngIntElt, RngIntElt, SymKod, BoolElt>, CrvEll
Given an elliptic curve E defined over Q and a prime number p, this function returns the local information at the prime p as a tuple of the form <P, vpd, fp, cp, K, split>, consisting of p, its multiplicity in the discriminant, its multiplicity in the conductor, the Tamagawa number at p, the Kodaira symbol, and finally a boolean which is false iff the curve has nonsplit multiplicative reduction. The second object returned is a local minimal model for E at p.
LocalInformation(E) : CrvEll -> [ Tup ]
Given an elliptic curve E this function returns a sequence of tuples of the kind described above, for the primes dividing the discriminant of E.
ReductionType(E, p) : CrvEll, RngIntElt -> MonStgElt
Returns a string describing the reduction type of E at p; the possibilities are "Good", "Additive", "Split multiplicative" or "Nonsplit multiplicative". These correspond to the type of singularity (if any) on the reduced curve. This function is necessary as the Kodaira symbols (see below) do not distinguish between split and unsplit multiplicative reduction.
TraceOfFrobeniusDirect(E, p) : CrvEll, RngIntElt -> RngIntElt
This function provides an efficient way to obtain the trace of Frobenius of a rational elliptic curve E at a prime p. The argument p is not checked to be prime.
TracesOfFrobenius(E, B) : CrvEll, RngIntElt -> SeqEnum
This function provides an efficient way to obtain the traces of Frobenius ap(E) of the reduction mod p of E, for all primes p up to B.

Example CrvEllQNF_frobenius-traces (H130E1)

> E := EllipticCurve([ 0, 1, 1, 3, 5 ]);
> T := TracesOfFrobenius(E, 100); T;
[ 0, 1, -3, -2, -5, 1, -3, -1, 5, 6, 8, -1, -6, 7, -2, 1, 14, -1, -12,
16, -16, -7, 6, 12, 2 ]
> time T := TracesOfFrobenius(E, 10^6);
Time: 5.600

Kodaira Symbols

Kodaira symbols have their own type SymKod. Apart from the two functions that determine symbols for elliptic curves, there is a special creation function and a comparison operator to test Kodaira symbols.

KodairaSymbol(E, p) : CrvEll, RngIntElt -> SymKod
Given an elliptic curve E defined over Q and a prime number p, this function returns the reduction type of E modulo p in the form of a Kodaira symbol.
KodairaSymbols(E) : CrvEll -> [ SymKod ]
Given an elliptic curve E defined over Q, this function returns the reduction types of E modulo the bad primes in the form of a sequence of Kodaira symbols.
KodairaSymbol(s) : MonStgElt -> SymKod
Given a string s, return the Kodaira symbol it represents. The values of s that are allowed are: "I0", "I1", "I2", ..., "In", "II", "III", "IV", and "I0*", "I1*", "I2*", ..., "In*", "II*", "III*", "IV*". The dots stand for "Ik" with k a positive integer. The `generic' type "In" allows the matching of types "In" for any integer n>0 (and similarly for "In*").
h eq k : SymKod, SymKod -> BoolElt
Given two Kodaira symbols h and k, this function returns true if and only if either both are identical, or one is generic (of the form "In", or "In*") and the other is specific of the same type: "In" will compare equal with any of "I1", "I2", "I3", etc., and "In*" will compare equal with any of "I1*", "I2*", "I3*", etc. Note however that "In" and "I3" are different from the point of view of set creation.
h ne k : SymKod, SymKod -> BoolElt
The logical negation of eq.

Example CrvEllQNF_Kodaira (H130E2)

We search for curves with a particular reduction type `I0*' in a family of curves.
> S := [ ];
> for n := 2 to 100 do
>    E := EllipticCurve([n, 0]);
>    for p in BadPrimes(E) do
>       if KodairaSymbol(E, p) eq KodairaSymbol("I0*") then
>          Append(~S, <p, n>);
>       end if;
>    end for;
> end for;
> S;
[ <3, 9>, <3, 18>, <5, 25>, <3, 36>, <3, 45>, <7, 49>, <5, 50>,
<3, 63>, <3, 72>, <5, 75>, <3, 90>, <7, 98>, <3, 99>, <5, 100> ]

Complex Multiplication

HasComplexMultiplication(E) : CrvEll -> BoolElt, RngIntElt
Given an elliptic curve E over the rationals (or a number field), the function determines whether the curve has complex multiplication or not and, if so, also returns the discriminant of the CM quadratic order. The algorithm uses fairly straightforward analytic methods, which are not suited to very high degree j-invariants with CM by orders with discriminants more than a few thousand.

Isogenous Curves

IsogenousCurves(E) : CrvEll[FldRat] -> SeqEnum, RngIntElt
The set of curves Q-isogenous to a rational elliptic curve E. The method used is to proceed prime-by-prime. Mazur's Theorem restricts the possibilities to a short list, and j-invariant considerations leave only p-isogenies for p = 2, 3, 5, 7, 13 to be considered. For p = 2 or 3, the method proceeds by finding the rational roots of the p-th division polynomial for the curve E. From these roots, one can then recover the isogenous curves. The question as to whether or not there is a p-isogeny is entirely a function of the j-invariant of the curve, and this idea is used for p = 5, 7, 13. In these cases the algorithm first takes a minimal twist of the elliptic curve, and then finds rational roots of the polynomial of degree (p + 1) that comes from a fibre of X0(p). The isogenous curves of the minimal twist corresponding to these roots are then computed, and then these curves are twisted back to get the isogenous curves of E. In all cases, if the conductor is squarefree, some small values of the Frobenius traces are checked mod p to ensure the feasibility of a p-isogeny. Other similar ideas involving checking congruences are also used to try to eliminate the possibility of a p-isogeny without finding roots. Tree-based methods are used to extend the isogeny tree from (say) 2-isogenies to 4-isogenies to 8-isogenies, etc. The integer returned as a second argument corresponds to the largest degree of a cyclic isogeny between two curves in the isogeny class. The ordering of the list of curves returned is well-defined; the first curve is always the curve of minimal Faltings height, and the heights generically increase upon going down the list. However, when there are isogenies of two different prime degrees, a different ordering is used. In the case where there is a 4-isogeny (or a certain type of 9-isogeny), there is an arbitrary choice made on the bottom tree leaves in order to make the ordering consistent.
FaltingsHeight(E) : CrvEll[FldRat] -> FldReElt
    Precision: RngIntElt                Default: 
Computes the unstable Faltings height of an elliptic curve over the rationals. This is defined as -logSqrt(Ω) where Ω is the fundamental volume. Note that FaltingsHeight for an elliptic curve over a number fields uses a different normalization.
StableFaltingsHeight(E) : CrvEll[FldRat] -> FldReElt
    Precision: RngIntElt                Default: 
Computes the stable Faltings height of an elliptic curve over the rationals. This is defined as (log (denom)(jE)/12) - (log|ΔE|/12) - logSqrt(Ω) where jE is the j-invariant, ΔE is the (minimal) discriminant, and Ω is the fundamental volume.

Example CrvEllQNF_isog-curves (H130E3)

First we compute isogenous curves using DivisionPolynomial; in this special case we obtain the entire isogeny class by considering only 3-isogenies directly from E.
> E:=EllipticCurve([1,-1,1,1,-1]);
> F:=Factorization(DivisionPolynomial(E,3));
> I:=IsogenyFromKernel(E,F[1][1]); I;
Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 29*x - 53 over Rational
Field
> I:=IsogenyFromKernel(E,F[2][1]); I;
Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 14*x + 29 over Rational
Field
Alternatively, we can get the IsogenousCurves directly. Note that IsogenyFromKernel also returns the map between the isogenous curves as a second argument.
> IsogenousCurves(E);
[
    Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 + x - 1 over Rational
    Field,
    Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 29*x - 53 over
    Rational Field,
    Elliptic Curve defined by y^2 + x*y + y = x^3 - x^2 - 14*x + 29 over
    Rational Field
]
9

Heights and Height Pairing

These functions require that the corresponding elliptic curve has integral coefficients.

NaiveHeight(P) : PtEll -> FldPrElt
WeilHeight(P) : PtEll -> FldPrElt
Given a point P=(a/b, c/d, 1) on an elliptic curve E defined over Q with integral coefficients, this function returns the naive (or Weil) height h(P) whose definition is h(P) = log max {|a|, |b|}.
Height(P: parameters) : PtEll -> NFldComElt
CanonicalHeight(P: parameters) : PtEll -> NFldComElt
    Precision: RngIntElt                Default: 
Given a point P on an elliptic curve E defined over Q with integral coefficients, this function returns the canonical height of P.

One definition of

the canonical height is the limit as n goes to infinity of h(2^n*P) / 4^n,
although this is of limited computational use. A more useful computational definition is as the sum of local heights:
the canonical height of P = sum(h_p(P)),
where the sum ranges over each prime p and the so-called `infinite prime'. Each of these local heights can be evaluated fairly simply, and in fact most of them are 0. The function always uses a minimal model for the elliptic curve internally, as otherwise the local height computation could fail. The computation at the infinite prime uses a slight improvement over the σ-function methods given in Cohen, with the implementation being based on an AGM-trick due to Mestre.
LocalHeight(P, p) : PtEll, RngIntElt -> FldComElt
    Precision: RngIntElt                Default: 
    Check: BoolElt                      Default: false
    Renormalization: BoolElt            Default: false
Given a point P on an elliptic curve E defined over Q with integral coefficients, this function returns the local height of P at p as described in Height above. The integer p must be either a prime number or 0; in the latter case the height at the infinite prime is returned. The Check parameter determines whether to check if the second argument is prime. The Renormalization parameter changes what definition of heights is used. Without this flag, a factor of (1/6)log Δv is added at every place.
HeightPairing(P, Q: parameters) : PtEll, PtEll -> FldComElt
    Precision: RngIntElt                Default: 
Given two points P, Q on the same elliptic curve defined over Q with integral coefficients, this function returns the height pairing of P and Q, which is defined by h(P, Q) = (h(P + Q) - h(P) - h(Q))/2, where h denotes the canonical height.
HeightPairingMatrix(S: parameters) : [PtEll] -> AlgMat
HeightPairingMatrix(E: parameters) : CrvEll -> AlgMat
    Precision: RngIntElt                Default: 
Given a sequence of points on an elliptic curve defined over Q with integral coefficients, this function returns the height pairing matrix. If an elliptic curve is passed to it, the corresponding matrix for the Mordell--Weil generators is returned.
Regulator(S) : [ PtEll ] -> FldComElt
    Precision: RngIntElt                Default: 
Given a sequence of points S on an elliptic curve E over Q, this function returns the determinant of the Néron-Tate height pairing matrix of the sequence.
Regulator(E) : CrvEll -> FldComElt
    Precision: RngIntElt                Default: 
Given an elliptic curve E this function returns the regulator of E; i.e., the determinant of the Néron-Tate height pairing matrix of a basis of the free quotient of the Mordell--Weil group.

Example CrvEllQNF_FunWithHeights (H130E4)

> E := EllipticCurve([0,0,1,-7,6]);
> P1, P2, P3 := Explode(Generators(E));
> Height(P1);
0.6682051656519279350331420509
> IsZero(Abs(Height(2*P1) - 4*Height(P1)));
true
> BadPrimes(E);
[ 5077 ]
The local height of a point P at a prime is 0 except possibly at the bad primes of E, the `infinite' prime, and those primes dividing the denominator of the x-coordinate of P. Since these generators have denominator 1 we see that only two local heights need to be computed to find the canonical heights of these points.
> P2;
(2 : 0 : 1)
> LocalHeight(P2, 0);
-0.655035947159686182497278069814
> LocalHeight(P2, 5077); // 0 + Log(5077)/6
1.42207930249123238829272871637
> LocalHeight(P2, 0 : Renormalization);
0.767043355331546205795450646552
> LocalHeight(P2, 5077 : Renormalization);
0.000000000000000000000000000000
> Height(P2);
0.7670433553315462057954506466
The above shows that the local height at a bad prime may still be zero, at least in the renormalised value.
SilvermanBound(H) : SetPtEll -> FldPrElt
SilvermanBound(E) : CrvEll -> FldPrElt
Given an elliptic curve E over Q with integral coefficients, this function returns the Silverman bound B of E. For any point P on E we will have NaiveHeight(P) - Height(P) ≤B.
SiksekBound(H: parameters) : SetPtEll -> FldPrElt
SiksekBound(E: parameters) : CrvEll -> FldPrElt
    Torsion: BoolElt                    Default: false
Given an elliptic curve E over Q which is a minimal model, this function returns a real number B such that for any point P on E NaiveHeight(P) - Height(P) ≤B. In many cases, the Siksek bound is much better than the Silverman bound.

If the parameter Torsion is true then a potentially better bound BTor is computed, such that for any point P on E there exists a torsion point T so that NaiveHeight(P + T) - Height(P) ≤BTor. Note that Height(P + T) = Height(P).

Example CrvEllQNF_Bounds (H130E5)

We demonstrate the improvement of the Siksek bound over the Silverman bound for the three example curves from Siksek's paper [Sik95].
> E := EllipticCurve([0, 0, 0, -73705, -7526231]);
> SilvermanBound(E);
13.00022113685530200655193
> SiksekBound(E);
0.82150471924479497959096194911
> E := EllipticCurve([0, 0, 1, -6349808647, 193146346911036]);
> SilvermanBound(E);
21.75416864448061105008
> SiksekBound(E);
0.617777290687848386342334921728509577480
> E := EllipticCurve([1, 0, 0, -5818216808130, 5401285759982786436]);
> SilvermanBound(E);
27.56255914401769757660
> SiksekBound(E);
15.70818965430290161142481294545
This last curve has a torsion point, so we can further improve the bound:
> T := E![ 1402932, -701466 ];
> Order(T);
2
> SiksekBound(E : Torsion := true);
11.0309876231179839831829512652688
Here is a point which demonstrates the applicability of the modified bound.
> P := E![ 14267166114 * 109, -495898392903126, 109^3 ];
> NaiveHeight(P) - Height(P);
12.193000709615680011116868901084
> NaiveHeight(P + T) - Height(P);
2.60218831527724007036
IsLinearlyIndependent(P, Q) : PtEll, PtEll -> BoolElt, ModTupElt
Given points P and Q on an elliptic curve E, this function returns true if and only if P and Q are independent free elements of the group of rational points of an elliptic curve (modulo torsion points). If false, the function returns a vector v = (r, s) as a second value such that rP + sQ is a torsion point.
IsLinearlyIndependent(S) : [ PtEll ] -> BoolElt, ModTupElt
Given a sequence of points S belonging to an elliptic curve E, this function returns true if and only if the points in S are linearly independent (modulo torsion). If false, the function returns a vector v in the kernel of the height pairing matrix, i.e. giving a torsion point as a linear combination of the points in S.
ReducedBasis(S) : [ PtEll ] -> [ PtEll ]
Given a sequence of points S belonging to an elliptic curve E over the rationals, the function returns a sequence of points that are independent modulo the torsion subgroup (equivalently, they have non-degenerate height pairing), and which generate the same subgroup of E(Q)/Etors(Q) as points of S.

Example CrvEllQNF_LinearIndependence (H130E6)

We demonstrate the linear independence test on an example curve with an 8-torsion point and four independent points. The torsion point is easily recognized and we establish the independence of the remaining points using the height function.
> E := EllipticCurve([0,1,0,-95549172512866864, 11690998742798553808334900]);
> P0 := E![ 39860582, 2818809365988 ];
> P1 := E![ 144658748, -946639447182 ];
> P2 := E![ 180065822, 569437198932 ];
> P3 := E![ -339374593, 2242867099638 ];
> P4 := E![ -3492442669/25, 590454479818404/125 ];
> S0 := [P0, P1, P2, P3, P4];
> IsLinearlyIndependent(S0);
false (1 0 0 0 0)
> Order(P0);
8
> S1 := [P1, P2, P3, P4];
> IsLinearlyIndependent(S1);
true

We now demonstrate the process of solving for a nontrivial linear dependence among points on an elliptic curve by constructing a singular matrix, forming the corresponding linear combination of points, and establishing that the dependence is in the matrix kernel.

> M := Matrix(4, 4, [-3,-1,2,-1,3,3,3,-2,3,0,-1,-1,0,2,1,1]);
> Determinant(M);
0
> S2 := [ &+[ M[i, j]*S1[j] : j in [1..4] ] : i in [1..4] ];
> IsLinearlyIndependent(S2);
false ( 5 -3  8  7)
> Kernel(M);
RSpace of degree 4, dimension 1 over Integer Ring
Echelonized basis:
( 5 -3  8  7)

Despite the moderate size of the numbers which appear in the matrix M, we note that height is a quadratic function in the matrix coefficients. Since height is a logarithmic function of the coefficient size of the points, we see that the sizes of the points in this example are very large:

> [ RealField(16) | Height(P) : P in S2 ];
[ 137.376951049198, 446.51954933694, 52.724183282292, 59.091649046171 ]
> Q := S2[2];
> Log(Abs(Numerator(Q[1])));
467.6598587040659411808117253
> Log(Abs(Denominator(Q[1])));
449.2554587727840583949442765
pAdicHeight(P, p) : PtEll, RngIntElt -> FldPadElt
    Precision: RngIntElt                Default: 0
    E2: FldPadElt                       Default: 0
Given a point P on an elliptic curve defined on the rationals and a prime p≥5 of good ordinary reduction, this function computes the p-adic height of P to the desired precision. The value of the EisensteinTwo function for the curve can be passed as a parameter. The algorithm dates back to [MT91] with improvements due to [MST06] and [Har08]. The normalization is that of the last-named paper and is 2p (or -2p in some cases) as large as in other papers.
pAdicRegulator(S, p) : [PtEll], RngIntElt -> FldPadElt
    Precision: RngIntElt                Default: 0
    E2: FldPadElt                       Default: 0
Given a set of points S on an elliptic curve defined over the rationals and a prime p≥5 of good ordinary reduction, this function computes the p-adic height regulator of S to the desired precision. Here the normalization divides out a power of p from the individual heights.
EisensteinTwo(E, p) : CrvEll, RngIntElt -> FldPadElt
    Precision: RngIntElt                Default: 0
Given an elliptic curve over the rationals and a prime p≥5 of good ordinary reduction, this function computes the value of the Eisenstein series E2 using the Monsky-Washnitzer techniques via Kedlaya's algorithm. See pAdicHeight above for references.
FrobeniusMatrix(E, p) : CrvEll, RngIntElt -> Mtrx
    Precision: RngIntElt                Default: 10
Given an elliptic curve over the rationals and a prime p≥5 of good reduction, this function computes the matrix corresponding to the action of Frobenius, to the given precision. The basis used is {dx/y, x(dx/y)}.

Example CrvEllQNF_padic-height (H130E7)

We give examples for computing p-adic heights.
> E := EllipticCurve("5077a");
> P1 := E ! [2, 0];
> P2 := E ! [1, 0];
> P3 := E ! [-3, 0];
> assert P1+P2+P3 eq E!0; // the three points sum to zero
> for p in PrimesInInterval(5,30) do pAdicHeight(P1, p); end for;
4834874647277 + O(5^20)
5495832406058373*7 + O(7^20)
-12403985313704524674*11 + O(11^20)
616727731594753360389*13 + O(13^20)
53144975867434108754867*17 + O(17^20)
651478754033733420744924*19 + O(19^20)
1382894029404692415656094*23^2 + O(23^20)
-2615503441214747688800993518*29 + O(29^20)
> pAdicHeight(P1, 37); // 37 is not ordinary for this curve
>> pAdicHeight(P1, 37); // 37 is not ordinary for this curve
Runtime error in 'pAdicHeight': p cannot be supersingular
> for p in PrimesInInterval(5,30) do pAdicRegulator([P1, P2], p); end for;
-263182161797834*5^-2 + O(5^20)
-35022392779944725 + O(7^20)
-331747503271490921584 + O(11^20)
246446095809126124462 + O(13^20)
-1528527915797227515067270 + O(17^20)
333884275695653846729970*19 + O(19^20)
412978398356115570280760602 + O(23^20)
-45973362301048046561945193743 + O(29^20)
> pAdicRegulator([P1, P2, P3], 23); // dependent points
O(23^20)
> eisen_two := EisensteinTwo(E, 13 : Precision:=40); eisen_two;
25360291252705414983472710631099471724343012 + O(13^40)
> pAdicRegulator([P1, P2], 13 : Precision:=40, E2:=eisen_two);
85894629213918025547455609490608727790695215 + O(13^40)

Heegner Points

For an elliptic curve of rank 1, it is possible to compute a generator by an analytic process; the elliptic logarithm of some multiple nP of the generator is the sum of the values of the modular parameterization at a series of points in the upper half-plane corresponding to a full set of class representatives for an appropriately-chosen quadratic field. There is no such thing as a free lunch, sadly; the calculation requires computing O(hN) terms to a precision of O(h) digits, so in practice it works best for curves contrived to have small conductors.

The calculation proceeds in three stages: choosing the quadratic field Q(Sqrt( - d)), evaluating the modular parameterization, and recovering the generator from the elliptic logarithm value. Essentially, this is an implementation of the method of Gross and Zagier [GZ86]; Elkies performed some substantial computations using this method in 1994, and much of the work required to produce this implementation was done by Cremona and Womack. An array of tricks have been added, and are described to some extent in some notes of Watkins.

HeegnerPoint(E : parameters) : CrvEll -> BoolElt, PtEll
    NaiveSearch: RngIntElt              Default: 1000
    Discriminant: RngIntElt             Default: 
    Cover: Crv                          Default: 
    DescentPossible: BoolElt            Default: true
    IsogenyPossible: BoolElt            Default: true
    Traces: SeqEnum                     Default: []
    SetVerbose("Heegner", n):           Maximum: 1
Attempts to find a point on a rank 1 rational elliptic curve E using the method of Heegner points, returning true and the point if it finds one, otherwise false. The parameter NaiveSearch indicates to what height the algorithm does a preliminary search for points on E (using Points). The Discriminant parameter allows the user to specify an auxiliary discriminant; this must satisfy the Heegner hypothesis, and the corresponding quadratic twist must have rank 0. The Cover option allows the user to specify a 2-cover or 4-cover (perhaps obtained from TwoDescent or FourDescent) to speed the calculation. This should be either a hyperelliptic curve or a quadric intersection, and there must be a map from the cover to the given elliptic curve. If the DescentPossible option is true, then the algorithm might perform such a descent in any case. If the IsogenyPossible option is true, then the algorithm will first try to guess the best isogenous curve on which to do the calculation --- if a Cover is passed to the algorithm, it will be ignored if E is not the best isogenous curve. The Traces option takes an array of integers which correspond to the first however-many traces of Frobenius for the elliptic curve, thus saving having to recompute them.

The algorithm assumes that the Manin constant of the given elliptic curve is 1 (which is conjectured in this case), and does not return a generator for the Mordell--Weil group, but a point whose height is that given by a conjectural extension of the Gross--Zagier formula. This should be Sqrt(Sha) times a generator.

HeegnerPoint(C : parameters) : CrvHyp -> BoolElt, PtHyp
HeegnerPoint(f : parameters) : RngUPolElt -> BoolElt, PtHyp
HeegnerPoint(C : parameters) : Crv -> BoolElt, Pt
    NaiveSearch: RngIntElt              Default: 10000
    Discriminant: RngIntElt             Default: 
    Traces: SeqEnum                     Default: []
    SetVerbose("Heegner", n):           Maximum: 3
These are utility functions for the above. The input is either a hyperelliptic curve given by a polynomial of degree 4, or this quartic polynomial --- in both cases the quartic should have no rational roots --- or a nonsingular intersection of two quadrics in P3. These functions call HeegnerPoint on the underlying elliptic curve. They then map the computed point back to the given covering curve. The rational reconstruction step of the HeegnerPoint algorithm can be quite time-consuming for some coverings, especially if the index is large. Also, if a cover corresponds to an element of the Tate--Shafarevich group, the algorithm will likely enter an infinite loop. These functions have not been as extensively tested as the ordinary HeegnerPoint function, and thus occasionally might fail due to unforeseen problems.
ModularParametrization(E, z, B : parameters) : CrvEll[FldRat], FldComElt, RngIntElt -> FldComElt
ModularParametrisation(E, z, B : parameters) : CrvEll[FldRat], FldComElt, RngIntElt -> FldComElt
ModularParametrization(E, z : parameters) : CrvEll[FldRat], FldComElt -> FldComElt
ModularParametrisation(E, z : parameters) : CrvEll[FldRat], FldComElt -> FldComElt
ModularParametrization(E, Z, B : parameters) : CrvEll[FldRat], [FldComElt], RngIntElt -> [FldComElt]
ModularParametrisation(E, Z, B : parameters) : CrvEll[FldRat], [FldComElt], RngIntElt -> [FldComElt]
ModularParametrization(E, Z : parameters) : CrvEll[FldRat], [FldComElt] -> [FldComElt]
ModularParametrisation(E, Z : parameters) : CrvEll[FldRat], [FldComElt] -> [FldComElt]
    Traces: SeqEnum                     Default: []
ModularParametrization(E, f, B : parameters) : CrvEll[FldRat], QuadBinElt, RngIntElt -> FldComElt
ModularParametrisation(E, f, B : parameters) : CrvEll[FldRat], QuadBinElt, RngIntElt -> FldComElt
ModularParametrization(E, f : parameters) : CrvEll[FldRat], QuadBinElt -> FldComElt
ModularParametrisation(E, f : parameters) : CrvEll[FldRat], QuadBinElt -> FldComElt
ModularParametrization(E, F, B : parameters) : CrvEll[FldRat], [QuadBinElt], RngIntElt -> [FldComElt]
ModularParametrisation(E, F, B : parameters) : CrvEll[FldRat], [QuadBinElt], RngIntElt -> [FldComElt]
ModularParametrization(E, F : parameters) : CrvEll[FldRat], [QuadBinElt] -> [FldComElt]
ModularParametrisation(E, F : parameters) : CrvEll[FldRat], [QuadBinElt] -> [FldComElt]
    Traces: SeqEnum                     Default: []
    Precision: RngIntElt                Default: 
Given a rational elliptic curve E and a point z in the upper-half-plane, compute the modular parametrization intz^∞fE(τ) dτ where fE is the modular form associated to E. The version with a bound B uses the first B terms of the q-expansion, while the other version determines how many terms are needed. The optional parameter Traces allows the user to pass the first however-many traces of Frobenius. There are also versions which take an array Z of complex points, and versions which take positive definite binary quadratic forms f (or an array F) rather than points in the upper-half-plane (a Precision can be specified with the latter).
HeegnerDiscriminants(E,lo,hi) : CrvEll[FldRat], RngIntElt, RngIntElt -> SeqEnum
    Fundamental: BoolElt                Default: false
    Strong: BoolElt                     Default: false
Given a rational elliptic curve and a range from lo to hi, compute the negative fundamental discriminant in this range that satisfies the Heegner hypothesis for the curve. The Fundamental option restricts to fundamental discriminants. The Strong option restricts to discriminants that satisfy a stronger Heegner hypothesis, namely that ap= - 1 for all primes p that divide gcd(D, N).
HeegnerForms(E,D : parameters) : CrvEll[FldRat], RngIntElt -> SeqEnum
    UsePairing: BoolElt                 Default: false
    UseAtkinLehner: BoolElt             Default: true
    Use_wQ: BoolElt                     Default: true
    IgnoreTorsion: BoolElt              Default: false
Given a rational elliptic curve of conductor N and a negative discriminant that meets the Heegner hypothesis for N, the function computes representatives for the complex multiplication points on X0(N).

In general the return value is a sequence of 3-tuples (Q, m, T) where Q is a quadratic form, m is a multiplicity, and T is a torsion point on E. Letting φ be the modular parametrization map, the sum on E of the values m(φ(Q) + T) is a Heegner point in E(Q). When the number of these values equals the class number h=h(D) (and the multiplicities are all 1 or -1) then they are actually the images on E of the CM points on X0(N). (They all correspond to a single choice of square root of D modulo 4N.)

If UsePairing is added, then CM points that give conjugate values under the modular parametrisation map are combined. If UseAtkinLehner is added, then more than one square root of D modulo 4N can be used. If Use_wQ is added, then forms can appear with extra multiplicity, due to primes that divide the GCD of the conductor and the fundamental discriminant. If IgnoreTorsion is added, then the fact that Atkin-Lehner can change the result by a torsion point will be ignored. The UsePairing option requires that IgnoreTorsion be true.

This function requires (so as not to confuse the user) that the ManinConstant of the curve be equal to 1.

HeegnerForms(N,D : parameters) : RngIntElt, RngIntElt -> SeqEnum
    AtkinLehner: [RngIntElt]            Default: []
Given a level N and a discriminant that meets the Heegner hypothesis for the level, the function returns a sequence of binary quadratic forms which correspond to the Heegner points. The Atkin-Lehner option takes a sequence of q with gcd(q, N/q)=1 and has the effect of allowing more than one square root of D modulo 4N to be used.
ManinConstant(E) : CrvEll[FldRat] -> RngIntElt
Compute the Manin constant of a rational elliptic curve. This is in most cases simply a conjectural value (and most often just 1).
HeegnerTorsionElement(E, Q) : CrvEll[FldRat], RngIntElt -> PtEll
Given a rational elliptic curve and an integer Q corresponding to an Atkin-Lehner involution (so that gcd(Q, N/Q)=1), this function computes the torsion point on the curve corresponding to the period given by the integral from i∞ to wQ(i∞).
HeegnerPoints(E, D : parameters) : CrvEll[FldRat], RngIntElt -> Tup, PtEll
    ReturnPoint: BoolElt                Default: false
    Precision: RngIntElt                Default: 100
    SetVerbose("Heegner", n):           Maximum: 1
Given an elliptic curve E over Q, and a suitable discriminant D (of a quadratic field) this function computes the images on E under the modular parametrization of the CM points on X0(N) associated to D. It returns a tuple < pD, m >, where pD is an irreducible polynomial whose roots are the x-coordinates of these images, and where m is the multiplicity of each of these images (the number of CM points on X0(N) mapping to a given point on E). These x-coordinates lie in the ring class field of Q(Sqrt(D)), and the class number h(D) must equal either m deg(pD) or 2m deg(pD).

The conductor of the order Q(Sqrt(D)) is required to be coprime to the conductor of E.

The second object returned by the function is one of the conjugate points, as an element of the point set E(H) where H is the field defined by pD, or a quadratic extension of it. This step can be time consuming; if ReturnPoint is set to false, the point is not computed.

Warning: The computation is not rigorous, as it involves computing over the complex numbers, and then recognising the coefficients of the polynomial as rationals. However, the program performs a heuristic check: it checks that the polynomial has the correct splitting at some small primes (sufficiently many to be sure that wrong answers will not occur in practice).

Example CrvEllQNF_Heegner (H130E8)

> time HeegnerPoint(EllipticCurve([1,0,0,312,-3008])); //uses search
true (12 : -56 : 1)
Time: 0.240
> time HeegnerPoint(EllipticCurve([0,0,1,-22787553,-41873464535]));
true (11003637829478432203592984661004129/1048524607168660222036584535396 :
-1004181871409718654255966342764883958203316448270339/10736628855783147946
99393270058310986889998056 : 1)
Time: 1.380

Example CrvEllQNF_Heegner2 (H130E9)

Here are some more complicated examples. In the first one, the curve has a 163-isogenous curve, which the algorithm uses to speed the computation. This occurs automatically, with most of the time taken being in computing the isogeny map.

> E := EllipticCurve([0,0,1,-57772164980,-5344733777551611]);
> b, pt:= HeegnerPoint(E);
> Height(pt);
373.478661569142379884077480412

Example CrvEllQNF_Heegner3 (H130E10)

In this next example, we first use descent to get a covering on which the desired point will have smaller height.
> E := EllipticCurve([0,-1,0,-71582788120,-7371563751267600]);
> T := TwoDescent(E : RemoveTorsion)[1];
> T;
Hyperelliptic Curve defined by y^2 = -2896*x^4 - 57928*x^3 - 202741*x^2
 + 868870*x - 651725 over Rational Field
> S := FourDescent(T : RemoveTorsion)[1];
> b, pt := HeegnerPoint(S);
> pt;
(-34940281640330765977951793/72963317481453011430052232 :
46087465795237503244048957/72963317481453011430052232 :
82501230298438806677528297/72963317481453011430052232 : 1)

We obtain a point on S, not on the original curve. We map it to E using the descent machinery.

> _, m := AssociatedEllipticCurve(S);
> PT := m(pt);
> PT;
(26935643239674824824611869793601774003477303945223677741244455058753
924460587724041316046901475913814274843012625394997597714766923750555
669810857471061235926971161094484197799515212721830555528087646969545
65/837619099331786545303500955405701693904657590793269053332825491870
645799230089011267382251975387071464373622714525213870033427638236014
2288012504288439077587496501436920044109243898570190931925860244164 :
410189886613094359515065087530226951251222017120181558101276037601794
678635473792334597914052557787798899390943937170051840037860568689664
871351793404398352109768736545284569745952273382778021947446766526118
621612003004627401344216069791103330332004546699363266079516476593864
98538303998567379869974143259174395/766601839981278884919411893932635
388671474045058772153268571977045787439290021029065740244648077391646
579430077900352635000328805236464794479797855430820809227462762666048
009219642700664370632930446228302292313415544188481623273194456758440
446505454248062292834244615276350323795396202280072306278575288 : 1)
> Height(PT);
476.811182818720336949724781780
> ConjecturalRegulator(E : Precision := 5);
476.81 1

Example CrvEllQNF_Heegner4 (H130E11)

Finally, we do some Heegner point calculation with the curve 43A and the discriminant -327. Note that the obtained trace down to the rationals is 3-divisible, but the point over the Hilbert class field is not.
> E := EllipticCurve([0,1,1,0,0]);
> HeegnerDiscriminants(E,-350,-300);
[ -347, -344, -340, -335, -331, -328, -327, -323, -319, -308, -303 ]
> HF := HeegnerForms(E,-327); HF;
[ <<43,19,4>, 1, (0 : 1 : 0)>, <<43,67,28>, 1, (0 : 1 : 0)>,
<<86,105,33>, 1, (0 : 1 : 0)>, <<86,153,69>, 1, (0 : 1 : 0)>,
<<129,105,22>, 1, (0 : 1 : 0)>, <<129,153,46>, 1, (0 : 1 : 0)>,
<<172,67,7>, 1, (0 : 1 : 0)>, <<258,363,128>, 1, (0 : 1 : 0)>,
<<258,411,164>, 1, (0 : 1 : 0)>, <<301,67,4>, 1, (0 : 1 : 0)>,
<<473,621,204>, 1, (0 : 1 : 0)>, <<473,841,374>, 1, (0 : 1 : 0)> ]
> H := [x[1] : x in HF]; mul := [x[2] : x in HF];
> params := ModularParametrization(E,H : Precision := 10);
> wparams := [ mul[i]*params[i] : i in [1..#H]];
> hgpt := EllipticExponential(E,&+wparams);
> hgpt;
[ 1.000000002 - 1.098466121E-9*I, 1.000000003 - 1.830776870E-9*I ]
> HeegnerPt := E![1,1];
> DivisionPoints(HeegnerPt, 3);
[ (0 : -1 : 1) ]
So the Heegner point is 3 times (0, - 1) in E(Q). We now find algebraically one of the points (of which we took the trace to get HeegnerPt). This point will be defined over a subfield of the class field of Q(Sqrt( - 327)), and will have degree dividing the class number. The poly below is the minimal polynomial of the x-coordinate.
> ClassNumber(QuadraticField(-327));
12
> poly, pt := HeegnerPoints(E, -327 : ReturnPoint);
> poly;
<t^12 + 10*t^11 + 76*t^10 - 1150*t^9 + 475*t^8 - 4823*t^7 +
 997*t^6 - 5049*t^5 - 2418*t^4 - 468*t^3 - 3006*t^2 + 405*t - 675, 1>
> pt;
(u : 1/16976844562625*(58475062076*u^11 + 568781661961*u^10 +
 4238812569862*u^9 - 68932294336288*u^8 + 42534102728187*u^7 -
 238141610215111*u^6 + 134503848441911*u^5 - 122884262733563*u^4 -
 58148031982456*u^3 + 129014145075851*u^2 -
 68190988248855*u + 40320643901175) : 1)
> DivisionPoints(pt,3);
[]

Here is another example of Heegner points over class fields.

Example CrvEllQNF_Heegner5 (H130E12)

> E := EllipticCurve([0,-1,0,-116,-520]);
> Conductor(E);
1460
> ConjecturalRegulator(E);
4.48887474770666173576726806264 1
> HeegnerDiscriminants(E,-200,-100);
[ -119, -111 ]
> P := HeegnerPoints(E,-119);
> P;
<1227609449333996689*t^10 - 106261506377143984603*t^9 +
    2459826667693945203684*t^8 - 12539974356047058417320*t^7 -
    298524708823654411408343*t^6 + 4440876684434597926161175*t^5 +
    7573549099120618979833241*t^4 - 393938048860406386108113130*t^3 -
    215318107135691628298668863*t^2 + 13958289016298162706904004974*t
    + 38624559371249968900024945369, 1>
The function automatically performs a heuristic check that the polynomial has the right properties, using reduction mod small primes. A more expensive check is the following.
> G := GaloisGroup( P[1] );
> IsIsomorphic(G,DihedralGroup(10));
true
The extension of Q( - 119) defined by the polynomial is the class field. We now obtain a nice representation of it, and use this to compute the height of the point (which is a bit quicker than computing the height directly).
> K<u> := NumberField(P[1]);
> L<v>, m := OptimizedRepresentation(K);
> _<y> := PolynomialRing(Rationals());  // use 'y' for printing
> DefiningPolynomial(L);
y^10 + 2*y^9 - y^8 - 7*y^7 - 7*y^6 + 10*y^5 + 13*y^4 - 9*y^3 - 5*y^2 +
    5*y - 1
> PT := Points(ChangeRing(E,L),m(u))[1];  // y-coord is defined over L
> Height(PT);
6.97911761109714376876370533

Analytic Information

Periods(E: parameters) : CrvEll -> [ FldComElt ]
    Precision: RngIntElt                Default: 
Returns the sequence of periods of the Weierstrass wp-function associated to the (rational) elliptic curve E, to Precision digits. The first element of the sequence is the real period. The function accepts a non-minimal model, and returns the periods corresponding to that model. As with many algorithms involving analytic information on elliptic curves, the implementation exploits an AGM-trick due to Mestre. There is some functionality for elliptic curves over number fields (package level code), though the exact normalisation is not always given.
Periods(E, k) : CrvEll, RngIntElt -> [ FldComElt ]
    Precision: RngIntElt                Default: 
Given an elliptic curve over a number field an integer denoting the kth real embedding, calculate the periods. This uses the C implementation after turning the coefficients of the defining equation into real numbers. Again the first period in the returned array should be real.
EllipticCurveFromPeriods(om: parameters) : [ FldComElt ] -> CrvEll
    Epsilon: FldReElt                   Default: 0.001
Given two complex numbers ω1, ω2 such that ω21 is in the upper half-plane that correspond to an integral model of an elliptic curve over (Q), return such a minimal model of such a curve. This uses the classical Eisenstein series, with the parameter Epsilon indicating how close to integers the computed -27c4 and -54c6 need to be.
RealPeriod(E: parameters) : CrvEll -> FldReElt
    Precision: RngIntElt                Default: 
Returns the real period of the Weierstrass wp-function associated to the elliptic curve E to Precision digits.
EllipticExponential(E, z) : CrvEll, FldComElt -> [ FldComElt ]
Given a rational elliptic curve E and a complex number z, the function computes the pair [wp(z), wp'(z)] where wp(s) is the Weierstrass wp-function. A nonminimal model may be given, though it should be integral. The algorithm used is taken from [Coh93] for small precision, and Newton iteration on EllipticLogarithm is used for high precision. The function returns a sequence rather than a point on the curve.
EllipticExponential(E, k, z) : CrvEll, RngIntElt, FldComElt -> [ FldComElt ]
Given an elliptic curve E over a number field, an integer denoting the kth real embedding, and a complex number z, the function computes the pair [wp(z), wp'(z)] where wp(s) is the Weierstrass wp-function. As with Periods, the function proceeds by using the C implementation over the reals. There is no restriction that the curve equation be integral. The function returns a sequence rather than a point on the curve.
EllipticExponential(E, S) : CrvEll, [ FldRat ] -> [ FldComElt ]
Given a rational elliptic curve E and a sequence S = [p, q], where p and q are rational numbers, this function computes the elliptic exponential of p times the RealPeriod and q times the imaginary period.
EllipticLogarithm(P): PtEll[FldRat] -> FldComElt
    Precision: RngIntElt                Default: 
Denote by ω1, ω2 the periods of the Weierstrass wp-function related to E. This function returns the elliptic logarithm φ(P) of the point P, such that -ω1/2≤((Re))(φ(P)) < ω1/2 and -ω2/2≤((Im))(φ(P)) < ω2/2. The value is returned to Precision digits. As with Periods, a non-minimal model can be given (though the model must be integral), and the EllipticLogarithm will be computed with respect to it. The algorithm is again an AGM-trick due to Mestre.
EllipticLogarithm(P, k): PtEll[FldNum], RngIntElt -> FldComElt
    Precision: RngIntElt                Default: 
Given an elliptic curve over a number field and a point on it, return the elliptic logarithm associated to the kth real embedding. There is no restriction that the model be integral.
EllipticLogarithm(E, S): CrvEll, [ FldComElt ] -> FldComElt
    Precision: RngIntElt                Default: 
    Check: BoolElt                      Default: true
Given an elliptic curve E and a sequence S = [z1, z2], where z1 and z2 are complex numbers approximating a point P on E, this function returns the elliptic logarithm φ(P). For details see the previous intrinsic. When Check is false, z1 and z2 need not have any relation to a point on the curve, in which case only the x-coordinate matters up to (essentially) a choice of sign in the resulting logarithm.
pAdicEllipticLogarithm(P, p: parameters): PtEll, RngIntElt -> FldLocElt
    Precision: RngIntElt                Default: 50
For a point P on an elliptic curve E which is a minimal model and a prime p, returns the p-adic elliptic logarithm of P to Precision digits. The order of P must not be a power of p.

Example CrvEllQNF_ell-exp (H130E13)

Verify that EllipticExponential and EllipticLogarithm are inverses.
> C<I>:=ComplexField(96);
> E:=EllipticCurve([0,1,1,0,0]);
> P:=EllipticExponential(E,0.571+0.221*I); P;
[ 1.656947605210186238868298175 + -1.785440180067681418618695947*I,
-2.417077284700315330385200257 + 3.894153792661208360153853530*I ]
> EllipticLogarithm(E,P);
0.5710000000000000000000000000 + 0.2210000000000000000000000000*I

Add points on a curve via Napier's method.

> E:=EllipticCurve([0,0,1,-7,6]);
> P1:=E![0,2]; P2:=E![2,0]; P3:=E![1,0];
> L:=EllipticLogarithm(E!P1)+EllipticLogarithm(E!P2)+EllipticLogarithm(E!P3);
> L;
0.521748219757790769853120197937 + 1.48054826824141499330733111064*i
> P:=EllipticExponential(E,L);
> [Round(Real(x)) : x in P];
[ 4, -7 ]
> P1+P2+P3;
(4 : -7 : 1)

Example CrvEllQNF_ellexp-nf (H130E14)

Verify that the use of real embeddings works with Periods.
> Q := RationalsAsNumberField();
> E := EllipticCurve([0,1,1,0,0]);
> Periods (E : Precision:=15);
[ 5.46868952996758, 2.73434476498379 + 1.36318241817043*$.1 ]
> EQ := BaseChange (E, Q);
> Periods (EQ,1 : Precision:=15);
[ 5.46868952996758, 2.73434476498379 + 1.36318241817043*$.1 ]
> _<s> := QuadraticField(5);
> E := EllipticCurve([s+1,1,-1,-s,2]);
> Periods (E,1 : Precision:=15);
[ 3.87725004777908, 1.93862502388954 + 0.697984279657861*$.1 ]
> Periods (E,2 : Precision:=15);
[ 3.20379220349709, 1.60189610174854 + 1.31468730940820*$.1 ]
And go back-and-forth with exponentials and logarithms.
> K<s> := QuadraticField(5);
> E := EllipticCurve([s+1,1,-1,-s,2]);
> P := Points(E,1)[1];
> Q := Points(E,1/2*(-9*s+11))[1];
> R := Points(E,1/2*(25*s + 55))[1];
> lP1 := EllipticLogarithm(P,1); lP1;
0.786501754500788971333154830602
> P1 := EllipticExponential(E,1,lP1); P1;
 0.999999999999999999999999999998 - 8.09833458701901575572176176187E-40*i,
-2.85410196624968454461376050309 - 5.80398551230662251457732924835E-40*i ]
> Abs(Conjugates(P[2])[1]-P1[2]); // y-coord diff is close to 0
3.15544362088404722170029225148E-30
> lQ2 := EllipticLogarithm(Q,2);
> lR2 := EllipticLogarithm(R,2);
> QR2 := EllipticExponential(E,2,lQ2+lR2);
[ 0.236067977499789696409173668732 - 9.28794630103153670720620051679E-40*i,
-1.09016994374947424102293417183 - 2.95168486889455241068806426790E-39*i ]
> Abs(Conjugates((Q+R)[1])[2]-QR2[1]);  // compare x-coords
1.18329135783151770848210977742E-30
RootNumber(E) : CrvEll -> RngIntElt
Calculates the global root number of an elliptic curve E defined over Q. This is equal to the sign in the functional equation of the L-series associated to the curve. The method used is to take a product of local root numbers over the primes of bad reduction.
RootNumber(E, p) : CrvEll, RngIntElt -> RngIntElt
Calculates the local root number at a prime p of an elliptic curve E. The method used is due to Halberstadt; for p > 3 it is a straightforward calculation involving the valuation of the discriminant, while for p = 2, 3 it involves a more careful analysis of the reduction type.
AnalyticRank(E) : CrvEll -> RngIntElt, FldReElt
    SetVerbose("AnalyticRank", n):      Maximum: 1
    Precision: RngIntElt                Default: 5
Determine the analytic rank of the rational elliptic curve E. The algorithm used is heuristic, computing derivatives of the L-function L(E, s) at s=1 until one appears to be nonzero. Local power series methods are used to compute the special functions used for higher derivatives. The function returns the first nonzero derivative L(r)(1)/r! as a second argument. The precision is optional, and is taken to be 17 bits if omitted; the time taken can increase dramatically if this is increased much beyond 50 digits as the time to compute the special functions then starts to dominate the running time.
ConjecturalRegulator(E) : CrvEll -> FldReElt, RngIntElt
    Precision: RngIntElt                Default: 
Using the AnalyticRank function, this function calculates an approximation, assuming that the Birch--Swinnerton-Dyer conjecture holds, to the product of the regulator of the elliptic curve E and the order of the Tate--Shafarevich group. The (assumed) analytic rank is returned as a second value.
ConjecturalRegulator(E, v) : CrvEll, FldReElt -> FldReElt
Given an elliptic curve E with L-function L(E, s) and the value v of the first nonzero derivative L(r)(1)/r!, this function calculates an approximation, assuming that the Birch--Swinnerton-Dyer conjecture holds, to the product of the regulator of the elliptic curve E and the order of its Tate--Shafarevich group.

Example CrvEllQNF_analytic-rank (H130E15)

> E:=EllipticCurve([1,1,0,-2582,48720]);
> time r, Lvalue := AnalyticRank(E : Precision:=9); r,Lvalue;
Time: 17.930
6 320.781164
> ConjecturalRegulator(E,Lvalue);
68.2713770
> time G, map := MordellWeilGroup(E : HeightBound := 8); G;
Time: 21.540
Abelian Group isomorphic to Z (6 copies)
Defined on 6 generators (free)
> Regulator([map(g): g in OrderedGenerators(G)]);
68.2713769

Example CrvEllQNF_conjectural-regulator (H130E16)

> ConjecturalRegulator(EllipticCurve([0,-1,1,0,0]) : Precision := 8);
1.0000000 0
> ConjecturalRegulator(EllipticCurve([0,-1,1,0,0]) : Precision := 21);
1.00000000000000000000 0
> ConjecturalRegulator(EllipticCurve([0,-1,1,0,0]) : Precision := 35);
1.0000000000000000000000000000000000 0
> ConjecturalRegulator(EllipticCurve([0,-1,1,0,0]) : Precision := 50);
1.0000000000000000000000000000000000000000000000000 0
ModularDegree(E) : CrvEll -> RngIntElt
    SetVerbose("ModularDegree", n):     Maximum: 1
Determine the modular degree of a rational elliptic curve E. The algorithm used is described in [Wat02]. One computes the special value L(Sym2 E, 2) of the motivic symmetric-square L-function of the elliptic curve, and uses the formula deg(φ)=L(Sym2 E, 2)/(2 * Π * Ω) * (Nc2) * Ep(2) where Ω is the area of the fundamental parallelogram of the curve, N is the conductor, c is the Manin constant, and Ep(2) is a product over primes whose square divides the conductor. The Manin constant is assumed to be 1 except in the cases described in [SW02], where it is conjectured that the optimal curves for parameterizations from X1(N) and X0(N) are different. A warning is given in these cases. The optimal curve for parameterizations from X1(N) is assumed to be the curve in the isogeny class of E that has minimal Faltings height (maximal Ω). The algorithm is based upon a sequence of real-number approximations converging to an integer --- the use of verbose printing for ModularDegree allows the user to see the sequence of approximations.

Example CrvEllQNF_mod-deg (H130E17)

First we define a space of ModularForms.
> M:=ModularForms(Gamma0(389),2);
The first of the newforms associated to M corresponds to an elliptic curve.
> f := Newform(M,1); f;
q - 2*q^2 - 2*q^3 + 2*q^4 - 3*q^5 + 4*q^6 - 5*q^7 + q^9 + 6*q^10 - 4*q^11 +
O(q^12)
> E := EllipticCurve(f); E;
Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field
We can compute the modular degree of this using modular symbols.
> time ModularDegree(ModularSymbols(f));
40
Time: 0.200
Or via the algorithm based on elliptic curves.
> time ModularDegree(E);
40
Time: 0.000
The elliptic curve algorithm is capable of handling examples of high level, particularly when bad primes have multiplicative reduction.
> E := EllipticCurve([0,0,0,0,-(10^4+9)]);
> Conductor(E);
14425931664
> time ModularDegree(E);
6035544576
Time: 3.100

Integral and S-integral Points

Let E be an elliptic curve defined over the rational numbers Q and denote by S={p1, ..., ps - 1, ∞} a finite set of primes containing the prime at infinity. There are only finitely many S-integral points on E. (That is, points where the denominators of the coordinates are only supported by primes in S.) Note that the point at infinity on E is never returned, since it is supported at every prime.

The following algorithms use the technique of linear forms in complex and p-adic elliptic logarithms. They were initially implemented by Emmanuel Hermann in the late 90s, and then Steve Donnelly made various improvements. The main theoretical reference is Stroeker and Tzanakis [ST94], and Tzanakis [ST96] for the case of a quartic equation.

The main routine here is (S)IntegralPoints for an elliptic curves. The functions listed afterwards, for determining integral points on various other kinds of genus one curves, are applications of the main routine.

IntegralPoints(E) : CrvEll[FldRat] -> [ PtEll ]
    FBasis: [ PtEll ]                   Default: 
    SafetyFactor: RngIntElt             Default: 1
Given an elliptic curve E over Q, having integral coefficients, this returns a sequence containing all the integral points on E, up to sign (only one of P and -P is listed).

The algorithm involves first computing generators of the Mordell-Weil group, using the tools available in Magma for this. Alternatively, the user may precompute generators and pass them to IntegralPoints as the optional parameter FBasis. This should be a sequence of points on E that are independent modulo torsion (for instance, as returned by ReducedBasis). IntegralPoints will then find all integral points on E that are in the group generated by FBasis and torsion.

If the optional argument SafetyFactor is specified, the search phase at the final step is extended as a safety check. (The number of points checked is increased by approximately this factor, which must be at least 1.)

SIntegralPoints(E, S) : CrvEll, SeqEnum -> [ PtEll ]
    FBasis: [ PtEll ]                   Default: 
    SafetyFactor: RngIntElt             Default: 1
Given an elliptic curve E over the rationals and a set S of finite primes, returns the sequence of all S-integral points, up to sign (only one of P and -P is listed).

The optional parameters FBasis and SafetyFactor have the same meaning as in IntegralPoints.

Example CrvEllQNF_IntegralPoints (H130E18)

We find all integral points on a certain elliptic curve:
> E := EllipticCurve([0, 17]);
> Q, reps := IntegralPoints(E);
> Q;
[ (-2 : -3 : 1), (8 : 23 : 1), (43 : -282 : 1), (4 : 9 : 1),
(2 : -5 : 1), (-1 : 4 : 1), (52 : -375 : 1), (5234 : 378661 : 1) ]
> reps;
[
    [ <(-2 : -3 : 1), 1> ],
    [ <(-2 : -3 : 1), 2> ],
    [ <(-2 : -3 : 1), 1>, <(4 : -9 : 1), -2> ],
    [ <(4 : -9 : 1), -1> ],
    [ <(-2 : -3 : 1), 1>, <(4 : -9 : 1), -1> ],
    [ <(-2 : -3 : 1), 1>, <(4 : -9 : 1), 1> ],
    [ <(-2 : -3 : 1), 2>, <(4 : -9 : 1), 1> ],
    [ <(-2 : -3 : 1), 1>, <(4 : -9 : 1), 3> ]
]
We see here that the chosen basis consists of the points ( - 2 : - 3 : 1) and (4 : - 9 : 1), and that coefficients which are zero are omitted.

Example CrvEllQNF_SIntegralPoints (H130E19)

We find all S-integral points on an elliptic curve of rank 2, for the set of primes S = {2, 3, 5, 7}.
> E := EllipticCurve([-228, 848]);
> Q := SIntegralPoints(E, [2, 3, 5, 7]);
> for P in Q do P; end for;    // Print one per line
(4 : 0 : 1)
(-11 : 45 : 1)
(16 : 36 : 1)
(97/4 : -783/8 : 1)
(-44/9 : -1160/27 : 1)
(857/4 : -25027/8 : 1)
(6361/400 : -282141/8000 : 1)
(534256 : -390502764 : 1)
(946/49 : -20700/343 : 1)
(-194/25 : -5796/125 : 1)
(34/9 : 172/27 : 1)
(814 : 23220 : 1)
(13 : 9 : 1)
(-16 : 20 : 1)
(1/4 : -225/8 : 1)
(52 : -360 : 1)
(53 : 371 : 1)
(16/49 : 9540/343 : 1)
(-16439/1024 : -631035/32768 : 1)
(34 : 180 : 1)
(-2 : 36 : 1)
(-14 : -36 : 1)
(14 : -20 : 1)
(754 : -20700 : 1)
(94/25 : -828/125 : 1)
(2 : 20 : 1)
(94 : 900 : 1)
(-818/49 : 468/343 : 1)
(49/16 : -855/64 : 1)
(196 : -2736 : 1)
(629/25 : 13133/125 : 1)
(1534/81 : -42020/729 : 1)
(8516/117649 : -1163623840/40353607 : 1)
IntegralQuarticPoints(Q) : [ RngIntElt ] -> [ SeqEnum ]
If Q is a sequence of five integers [a, b, c, d, e] where e is a square, this function returns all integral points (modulo negation) on the curve y2=ax4 + bx3 + cx2 + dx + e.
IntegralQuarticPoints(Q, P) : [ RngIntElt ], [ RngIntElt ] -> [ SeqEnum ]
If Q is a list of five integers [a, b, c, d, e] defining the hyperelliptic quartic y2=ax4 + bx3 + cx2 + dx + e and P is a sequence representing a rational point [x, y], this function returns all integral points on Q.
SIntegralQuarticPoints(Q, S) : [ RngIntElt ], [ RngIntElt ] -> [ SeqEnum ]
Given a sequence of integers Q = [a, b, c, d, e] where a is a square, this function returns all S-integral points on the quartic curve y2 = ax4 + bx3 + cx2 + dx + e for the set S of finite primes.

Example CrvEllQNF_IntegralPointsSequence (H130E20)

We find all integral points (modulo negation) on the curve y2 = x4 - 8x2 + 8x + 1. Since the constant term is a square we can use the first form and do not have to provide a point as well.
> IntegralQuarticPoints([1, 0, -8, 8, 1]);
[
    [ 2, -1 ],
    [ -6, 31 ],
    [ 0, 1 ]
]
SIntegralLjunggrenPoints(Q, S) : [ RngIntElt ], [ RngIntElt ] -> [ SeqEnum ]
Given a sequence of integers Q = [a, b, c, d], this function returns all S-integral points on the curve C: ay2 = bx4 + cx2 + d for the set S of finite primes, provided that C is nonsingular.
SIntegralDesbovesPoints(Q, S) : [ RngIntElt ], [ RngIntElt ] -> [ SeqEnum ]
Given a sequence of integers Q = [a, b, c, d], this function returns all S-integral points on C: ay3 + bx3 + cxy + d=0 for the set S of finite primes, provided that C is nonsingular.

Example CrvEllQNF_Desboves (H130E21)

We find the points supported by [2, 3, 5, 7] on the curve 9y3 + 2x3 + xy + 8 = 0.
> S := [2, 3, 5, 7];
> SIntegralDesbovesPoints([9, 2, 1, 8], S);
[
    [ 1, -1 ],
    [ -94/7, 172/21 ],
    [ -11/7, 2/7 ],
    [ 5, -3 ],
    [ 2, -4/3 ],
    [ 2/7, -20/21 ],
    [ -8/5, -2/15 ]
]

Elliptic Curve Database

Magma includes John Cremona's database of all elliptic curves over Q of small conductor (up to 499 999 as of September 2019). This section defines the interface to that database.

For each conductor in the range stored in the database the curves with that conductor are stored in a number of isogeny classes. Each curve in an isogeny class is isogenous (but not isomorphic) to the other curves in that class. Isogeny classes are referred to by number rather than the alphabetic form given in the Cremona tables.

All of the stored curves are global minimal models.

EllipticCurveDatabase(: parameters) : -> DB
CremonaDatabase(: parameters) : -> DB
    BufferSize: RngIntElt               Default: 10000
This function returns a database object which contains information about the elliptic curve database and is used in the functions which access it. The optional parameter BufferSize controls the size of an internal buffer --- see the description of SetBufferSize for more information.
SetBufferSize(D, n) : DB, RngIntElt ->
The elliptic curve database D uses an internal buffer to cache disk reads; if the buffer is large enough then the entire file can be cached and will not need to be read from the disk more than once. On the other hand, if only a few curves will be accessed then a large buffer is not especially useful. SetBufferSize can be used to set the size n (in bytes) of this buffer. There are well defined useful minimum and maximum sizes for this buffer, and values outside this range will be treated as the nearest useful value.
LargestConductor(D) : DB -> RngIntElt
Returns the largest conductor of any elliptic curve stored in the database. It is an error to attempt to refer to larger conductors in the database.
ConductorRange(D) : DB -> RngIntElt, RngIntElt
Returns the smallest and largest conductors stored in the database. It is an error to attempt to refer to conductors outside of this range.
# D : DB -> RngIntElt
NumberOfCurves(D) : DB -> RngIntElt
Returns the number of elliptic curves stored in the database.
NumberOfCurves(D, N) : DB, RngIntElt -> RngIntElt
Returns the number of elliptic curves stored in the database for conductor N.
NumberOfCurves(D, N, i) : DB, RngIntElt, RngIntElt -> RngIntElt
Returns the number of elliptic curves stored in the database in the i-th isogeny class for conductor N.
NumberOfIsogenyClasses(D, N) : DB, RngIntElt -> RngIntElt
Returns the number of isogeny classes stored in the database for conductor N.
EllipticCurve(D, N, I, J): DB, RngIntElt, RngIntElt, RngIntElt -> CrvEll
EllipticCurve(D, N, S, J): DB, RngIntElt, MonStgElt, RngIntElt -> CrvEll
Returns the J-th elliptic curve of the I-th isogeny class of conductor N from the database. I may be specified either as an integer (first form) or as a label like "A" (second form).
EllipticCurve(D, S): DB, MonStgElt -> CrvEll
EllipticCurve(S): MonStgElt -> CrvEll
Returns a representative elliptic curve with label S (e.g., "101a" or "101a1") from the specified database (or if not specified, from the Cremona database).
Random(D) : DB -> CrvEll
Returns a random curve from the database.
CremonaReference(D, E) : DB, CrvEll -> MonStgElt
CremonaReference(E) : CrvEll -> MonStgElt
Returns the database reference to the minimal model for E (e.g., "101a1"). E must be defined over Q and its conductor must lie within the range of the database. The second form of this function must open the database for each call, so if it is being used many times the database should be created once and the first form used instead.

Example CrvEllQNF_ecdb1 (H130E22)

> D := CremonaDatabase();
> #D;
3064705
> minC, maxC := ConductorRange(D);
> minC, maxC;
1 499999
> &+[ NumberOfCurves(D, C) : C in [ minC .. maxC ] ];
3064705
The conductor in that range with the most curves is 369600.
> S := [ NumberOfCurves(D, C) : C in [ minC .. maxC ] ];
> cond := maxval + minC - 1 where _,maxval := Max(S);
> cond;
369600
> NumberOfCurves(D, cond);
1386
> NumberOfIsogenyClasses(D, cond);
612
The unique curve of conductor 5077 has rank 3.
> NumberOfCurves(D, 5077);
1
> E := EllipticCurve(D, 5077, 1, 1);
> E;
Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field
> CremonaReference(D, E);
5077a1
> Rank(E);
3
EllipticCurves(D, N, I) : DB, RngIntElt, RngIntElt -> [ CrvEll ]
EllipticCurves(D, N, S) : DB, RngIntElt, MonStgElt -> [ CrvEll ]
Returns the sequence of elliptic curves in the I-th isogeny class for conductor N from the database. I may be specified either as an integer (first form) or as a label like "A" (second form).
EllipticCurves(D, N) : DB, RngIntElt -> [ CrvEll ]
The sequence of elliptic curves for conductor N from the database.
EllipticCurves(D, S) : DB, MonStgElt -> [ CrvEll ]
The sequence of elliptic curves with label S from the database. S may specify just a conductor (like "101"), or both a conductor and an isogeny class (like "101A").
EllipticCurves(D) : DB -> [ CrvEll ]
The sequence of elliptic curves stored in the database. Note: this function is extremely slow due to the number of curves involved. Where possible it would be much better to iterate through the database instead (see example).

Example CrvEllQNF_ecdb2 (H130E23)

Here are two ways to iterate through the database:
> D := CremonaDatabase();
> &+[ Discriminant(E) : E in D ];
-794859469677543528151728699560961881672278939536
> sum := 0;
> for E in D do sum +:= Discriminant(E); end for;
> sum;
-794859469677543528151728699560961881672278939536
Now we choose a random curve from the database, and look up the other curves in the same isogeny class. (Note: when this input is entered, the random curve will probably be different to the example shown here!)
> E := Random(D);
> E;
Elliptic Curve defined by y^2 = x^3 - 225*x over Rational Field
> r := CremonaReference(E);
> r;
7200bg1
// remove the numeric characters from the end of the string r
> while r[#r] in "0123456789" do Prune(~r); end while;
> r;
7200bg
> EllipticCurves(D, r);
[
    Elliptic Curve defined by y^2 = x^3 - 225*x over Rational Field,
    Elliptic Curve defined by y^2 = x^3 - 2475*x - 47250 over Rational Field,
    Elliptic Curve defined by y^2 = x^3 - 2475*x + 47250 over Rational Field,
    Elliptic Curve defined by y^2 = x^3 + 900*x over Rational Field
]
> E in $1;
true
V2.28, 13 July 2023