Elliptic Curve LRatio table

William Stein

April 2005

This is a table that gives the ratio L(E,1)/OmegaE for every elliptic curve of conductor <= 40000. The L-ratios are provably correct in that care was taken to bound all errors in the computation so as to obtain a provably correct rational number, rather than just an approximation for the ratio. Of course it's still possible that there is a bug somewhere in the programs used to compute these ratios.


    lratio.1-40000       (11MB)    

    lratio.1-40000.bz2   (1.5MB)   


For each optimal curve of conductor <= 40000, there is one row in the table:
   conductor  letter  number(=1)  rank     L(E,1)/Omega_E   [a1,a2,a3,a4,a6]    
Thus the table begins as follows:
    11    A 1 0             1/5               [0,-1,1,-10,-20]
    14    A 1 0             1/6                   [1,0,1,4,-6]
    15    A 1 0             1/8                [1,1,1,-10,-10]
    .. .. ..
    35    A 1 0             1/3                    [0,1,1,9,1]
    36    A 1 0             1/6                    [0,0,0,0,1]
    37    A 1 1               0                   [0,0,1,-1,0]
    37    B 1 0             1/3                [0,1,1,-23,-50]

I created this table using the following program, which requires that SAGE and the SAGE elliptic curves database be installed:

       lratio.tar.bz2
With the above program installed (and SAGE), I typed go 1 40000 and waited a few minutes. The underlying calculation makes uses of Cremona's tables, PARI, and SAGE.

Source Code

The following excerpt from sage/ellcurve/ellcurve.py is the source code for the L_ratio function. The comments mostly explain the theory that goes into computing the L-ratios provably correctly. A key input is knowledge that the Manin constant is 1 for the curve, which follows for curves of conductor up to 40000 by Cremona's calculations.
    def L_ratio(self):
        """
        Returns the ratio L(E,1)/Omega as an exact rational
        number. The result is *provably* correct if the Manin constant
        of the associated optimal quotient is <= 2.  This hypothesis
        on the Manin constant is true for all curves of conductor <=
        40000 (by Cremona) and all semistable curves (i.e., squarefree
        conductor).

        EXAMPLES:
            >>> E = EllipticCurve([0, -1, 1, -10, -20])   # 11A  = X_0(11)
            >>> E.L_ratio()
            1/5
            >>> E = EllipticCurve([0, -1, 1, 0, 0])       # X_1(11)
            >>> E.L_ratio()
            1/25
            >>> E = EllipticCurve([0, 0, 1, -1, 0])       # 37A  (rank 1)
            >>> E.L_ratio()
            0
            >>> E = EllipticCurve([0, 1, 1, -2, 0])       # 389A (rank 2)
            >>> E.L_ratio()
            0
            >>> E = EllipticCurve([0, 0, 1, -38, 90])     # 361A (CM curve))
            >>> E.L_ratio()
            0
            >>> E = EllipticCurve([0,-1,1,-2,-1])         # 141C (13-isogeny)
            >>> E.L_ratio()
            1

        WARNING: It's conceivable that machine floats are not large
        enough precision for the computation; if this could be the
        case a RuntimeError is raised.  The curve's real period would
        have to be very small for this to occur.

        ALGORITHM: Compute the root number.  If it is -1 then L(E,s)
        vanishes to odd order at 1, hence vanishes.  If it is +1, use
        a result about modular symbols and Mazur's "Rational Isogenies"
        paper to determine a provably correct bound (assuming Manin
        constant is <= 2) so that we can determine whether L(E,1) = 0.

        AUTHOR: William Stein, 2005-04-20.
        """
        
        if self.root_number() == -1:
            return 0

        # Even root number.  Decide if L(E,1) = 0.  If E is a modular
        # optimal quotient of J_0(N) elliptic curve, we know that T *
        # L(E,1)/omega is an integer n, where T is the order of the
        # image of the rational torsion point (0)-(oo) in E(Q), and
        # omega is the least real Neron period.  (This is proved in my
        # Ph.D. thesis, but is probably well known.)  We can easily
        # compute omega to very high precision using AGM.  So to prove
        # that L(E,1) = 0 we compute T/omega * L(E,1) to sufficient
        # precision to determine it as an integer.  If eps is the
        # error in computation of L(E,1), then the error in computing
        # the product is (2T/Omega_E) * eps, and we need this to be
        # less than 0.5, i.e.,
        #          (2T/Omega_E) * eps < 0.5,
        # so
        #          eps < 0.5 * Omega_E / (2T) = Omega_E / (4*T).
        #
        # Since in general E need not be optimal, we have to choose
        # eps = Omega_E/(8*t*B), where t is the exponent of E(Q)_tor,
        # and B is a bound on the degree of any isogeny.   A liberal
        # bound on the degrees of cyclic N-isogenies is 200, by Mazur's
        # "Rational Isogenies of Prime Degree" paper, so we take B=200.
        #
        # NOTES: We *do* have to worry about the Manin constant, since
        # we are using the Neron model to compute omega, not the
        # newform.  My theorem replaces the omega above by omega/c,
        # where c is the Manin constant, and the bound must be
        # correspondingly smaller.  If the level is square free, then
        # the Manin constant is 1 or 2, so there's no problem (since
        # we took 8 instead of 4 in the denominator).  If the level
        # is divisible by a square, then the Manin constant could
        # be a divisible by an arbitrary power of that prime, except
        # that Edixhoven claims the primes that appear are <= 7.
        
        t = self.torsion_subgroup().exponent()
        omega = self.period_lattice()[0]
        C = 8*200*t
        eps = omega / C
        if eps < 10**(-15):  # liberal bound on precision of float
            raise RuntimeError, "Insufficient machine precision for computation."
        sqrtN = 2*int(sqrt(self.conductor()))
        k = sqrtN + 10
        while True:
            L1, error_bound = self.Lseries_at1(k)
            if error_bound < eps:
                n = int(round(L1*C/omega))
                quo = Q(n) / Q(C)
                return quo / self.real_components()
            k += sqrtN
            misc.verbose("Increasing precision to %s terms."%k)