Пример #1
0
def lseries_dokchitser(E, prec=53):
    """
    Return the Dokchitser L-series object associated to the elliptic
    curve E, which may be defined over the rational numbers or a
    number field.  Also prec is the number of bits of precision to
    which evaluation of the L-series occurs.
    
    INPUT:
        - E -- elliptic curve over a number field (or QQ)
        - prec -- integer (default: 53) precision in *bits*

    OUTPUT:
        - Dokchitser L-function object
    
    EXAMPLES::

    A curve over Q(sqrt(5)), for which we have an optimized implementation::
    
        sage: from psage.ellcurve.lseries.lseries_nf import lseries_dokchitser
        sage: K.<a> = NumberField(x^2-x-1); E = EllipticCurve([0,-a,a,0,0])
        sage: L = lseries_dokchitser(E); L
        Dokchitser L-function of Elliptic Curve defined by y^2 + a*y = x^3 + (-a)*x^2 over Number Field in a with defining polynomial x^2 - x - 1
        sage: L(1)
        0.422214159001667
        sage: L.taylor_series(1,5)
        0.422214159001667 + 0.575883864741340*z - 0.102163426876721*z^2 - 0.158119743123727*z^3 + 0.120350687595265*z^4 + O(z^5)

    Higher precision::
    
        sage: L = lseries_dokchitser(E, 200)
        sage: L(1)
        0.42221415900166715092967967717023093014455137669360598558872

    A curve over Q(i)::

        sage: K.<i> = NumberField(x^2 + 1)
        sage: E = EllipticCurve(K, [1,0])
        sage: E.conductor().norm()
        256
        sage: L = lseries_dokchitser(E, 10)
        sage: L.taylor_series(1,5)
        0.86 + 0.58*z - 0.62*z^2 + 0.19*z^3 + 0.18*z^4 + O(z^5)

    More examples::

        sage: lseries_dokchitser(EllipticCurve([0,-1,1,0,0]), 10)(1)
        0.25
        sage: K.<i> = NumberField(x^2+1)
        sage: lseries_dokchitser(EllipticCurve(K, [0,-1,1,0,0]), 10)(1)
        0.37
        sage: K.<a> = NumberField(x^2-x-1)
        sage: lseries_dokchitser(EllipticCurve(K, [0,-1,1,0,0]), 10)(1)
        0.72

        sage: E = EllipticCurve([0,-1,1,0,0])
        sage: E.quadratic_twist(2).rank()
        1
        sage: K.<d> = NumberField(x^2-2)
        sage: L = lseries_dokchitser(EllipticCurve(K, [0,-1,1,0,0]), 10)
        sage: L(1)
        0
        sage: L.taylor_series(1, 5)
        0.58*z + 0.20*z^2 - 0.50*z^3 + 0.28*z^4 + O(z^5)

    You can use this function as an algorithm to compute the sign of the functional
    equation (global root number)::

        sage: E = EllipticCurve([1..5])
        sage: E.root_number()
        -1
        sage: L = lseries_dokchitser(E,32); L
        Dokchitser L-function of Elliptic Curve defined by y^2 + x*y = x^3 - x^2 + 4*x + 3 over Rational Field
        sage: L.eps
        -1

    Over QQ, this isn't so useful (since Sage has a root_number
    method), but over number fields it is very useful::

        sage: K.<a> = NumberField(x^2 - x - 1)
        sage: E1=EllipticCurve([0,-a-1,1,a,0]); E0 = EllipticCurve([0,-a,a,0,0])
        sage: lseries_dokchitser(E1, 16).eps
        -1
        sage: E1.rank()
        1
        sage: lseries_dokchitser(E0, 16).eps
        1
        sage: E0.rank()
        0
    """
    # The code assumes in various places that we have a global minimal model,
    # for example, in anlist_sqrt5 above.
    E = E.global_minimal_model()

    # Check that we're over a number field.
    K = E.base_field()
    if not is_NumberField(K):
        raise TypeError("base field must be a number field")

    # Compute norm of the conductor -- awkward because QQ elements have no norm method (they should).
    N = E.conductor()
    if K != QQ:
        N = N.norm()

    # We guess the sign epsilon in the functional equation to be +1
    # first.  If our guess is wrong then we just choose the other
    # possibility.
    epsilon = 1

    # Define the Dokchitser L-function object with all parameters set:
    L = Dokchitser(conductor=N * K.discriminant()**2,
                   gammaV=[0] * K.degree() + [1] * K.degree(),
                   weight=2,
                   eps=epsilon,
                   poles=[],
                   prec=prec)

    # Find out how many coefficients of the Dirichlet series are needed
    # to compute to the requested precision.
    n = L.num_coeffs()
    # print "num coeffs = %s"%n

    # Compute the Dirichlet series coefficients
    coeffs = anlist(E, n)[1:]

    # Define a string that when evaluated in PARI defines a function
    # a(k), which returns the Dirichlet coefficient a_k.
    s = 'v=%s; a(k)=v[k];' % coeffs

    # Actually tell the L-series / PARI about the coefficients.
    L.init_coeffs('a(k)', pari_precode=s)

    # Test that the functional equation is satisfied.  This will very,
    # very, very likely if we chose the sign of the functional
    # equation incorrectly, or made any mistake in computing the
    # Dirichlet series coefficients.
    tiny = max(1e-8, old_div(1.0, 2**(prec - 1)))
    if abs(L.check_functional_equation()) > tiny:
        # The test failed, so we try the other choice of functional equation.
        epsilon *= -1
        L.eps = epsilon

        # It is not necessary to recreate L -- just tell PARI the different sign.
        L._gp_eval('sgn = %s' % epsilon)

        # Once again, verify that the functional equation is
        # satisfied.  If it is, then we've got it.  If it isn't, then
        # there is definitely some other subtle bug, probably in computed
        # the Dirichlet series coefficients.
        if abs(L.check_functional_equation()) > tiny:
            raise RuntimeError(
                "Functional equation not numerically satisfied for either choice of sign"
            )

    L.rename('Dokchitser L-function of %s' % E)
    return L
Пример #2
0
def lseries_dokchitser(E, prec=53):
    """
    Return the Dokchitser L-series object associated to the elliptic
    curve E, which may be defined over the rational numbers or a
    number field.  Also prec is the number of bits of precision to
    which evaluation of the L-series occurs.
    
    INPUT:
        - E -- elliptic curve over a number field (or QQ)
        - prec -- integer (default: 53) precision in *bits*

    OUTPUT:
        - Dokchitser L-function object
    
    EXAMPLES::

    A curve over Q(sqrt(5)), for which we have an optimized implementation::
    
        sage: from psage.ellcurve.lseries.lseries_nf import lseries_dokchitser
        sage: K.<a> = NumberField(x^2-x-1); E = EllipticCurve([0,-a,a,0,0])
        sage: L = lseries_dokchitser(E); L
        Dokchitser L-function of Elliptic Curve defined by y^2 + a*y = x^3 + (-a)*x^2 over Number Field in a with defining polynomial x^2 - x - 1
        sage: L(1)
        0.422214159001667
        sage: L.taylor_series(1,5)
        0.422214159001667 + 0.575883864741340*z - 0.102163426876721*z^2 - 0.158119743123727*z^3 + 0.120350687595265*z^4 + O(z^5)

    Higher precision::
    
        sage: L = lseries_dokchitser(E, 200)
        sage: L(1)
        0.42221415900166715092967967717023093014455137669360598558872

    A curve over Q(i)::

        sage: K.<i> = NumberField(x^2 + 1)
        sage: E = EllipticCurve(K, [1,0])
        sage: E.conductor().norm()
        256
        sage: L = lseries_dokchitser(E, 10)
        sage: L.taylor_series(1,5)
        0.86 + 0.58*z - 0.62*z^2 + 0.19*z^3 + 0.18*z^4 + O(z^5)

    More examples::

        sage: lseries_dokchitser(EllipticCurve([0,-1,1,0,0]), 10)(1)
        0.25
        sage: K.<i> = NumberField(x^2+1)
        sage: lseries_dokchitser(EllipticCurve(K, [0,-1,1,0,0]), 10)(1)
        0.37
        sage: K.<a> = NumberField(x^2-x-1)
        sage: lseries_dokchitser(EllipticCurve(K, [0,-1,1,0,0]), 10)(1)
        0.72

        sage: E = EllipticCurve([0,-1,1,0,0])
        sage: E.quadratic_twist(2).rank()
        1
        sage: K.<d> = NumberField(x^2-2)
        sage: L = lseries_dokchitser(EllipticCurve(K, [0,-1,1,0,0]), 10)
        sage: L(1)
        0
        sage: L.taylor_series(1, 5)
        0.58*z + 0.20*z^2 - 0.50*z^3 + 0.28*z^4 + O(z^5)

    You can use this function as an algorithm to compute the sign of the functional
    equation (global root number)::

        sage: E = EllipticCurve([1..5])
        sage: E.root_number()
        -1
        sage: L = lseries_dokchitser(E,32); L
        Dokchitser L-function of Elliptic Curve defined by y^2 + x*y = x^3 - x^2 + 4*x + 3 over Rational Field
        sage: L.eps
        -1

    Over QQ, this isn't so useful (since Sage has a root_number
    method), but over number fields it is very useful::

        sage: K.<a> = NumberField(x^2 - x - 1)
        sage: E1=EllipticCurve([0,-a-1,1,a,0]); E0 = EllipticCurve([0,-a,a,0,0])
        sage: lseries_dokchitser(E1, 16).eps
        -1
        sage: E1.rank()
        1
        sage: lseries_dokchitser(E0, 16).eps
        1
        sage: E0.rank()
        0
    """
    # The code asssumes in various places that we have a global minimal model,
    # for example, in anlist_sqrt5 above.
    E = E.global_minimal_model() 

    # Check that we're over a number field.
    K = E.base_field()
    if not is_NumberField(K):
        raise TypeError, "base field must be a number field"

    # Compute norm of the conductor -- awkward because QQ elements have no norm method (they should).
    N = E.conductor()
    if K != QQ:
        N = N.norm()

    # We guess the sign epsilon in the functional equation to be +1
    # first.  If our guess is wrong then we just choose the other
    # possibility.
    epsilon = 1

    # Define the Dokchitser L-function object with all parameters set:
    L = Dokchitser(conductor = N * K.discriminant()**2,
                   gammaV = [0]*K.degree() + [1]*K.degree(),
                   weight = 2, eps = epsilon, poles = [], prec = prec)

    # Find out how many coefficients of the Dirichlet series are needed
    # to compute to the requested precision.
    n = L.num_coeffs()
    # print "num coeffs = %s"%n


    # Compute the Dirichlet series coefficients
    coeffs = anlist(E, n)[1:]

    # Define a string that when evaluated in PARI defines a function
    # a(k), which returns the Dirichlet coefficient a_k.
    s = 'v=%s; a(k)=v[k];'%coeffs

    # Actually tell the L-series / PARI about the coefficients.
    L.init_coeffs('a(k)', pari_precode = s)      

    # Test that the functional equation is satisfied.  This will very,
    # very, very likely if we chose the sign of the functional
    # equation incorrectly, or made any mistake in computing the
    # Dirichlet series coefficients. 
    tiny = max(1e-8, 1.0/2**(prec-1))
    if abs(L.check_functional_equation()) > tiny:
        # The test failed, so we try the other choice of functional equation.
        epsilon *= -1
        L.eps = epsilon

        # It is not necessary to recreate L -- just tell PARI the different sign.
        L._gp_eval('sgn = %s'%epsilon)

        # Once again, verify that the functional equation is
        # satisfied.  If it is, then we've got it.  If it isn't, then
        # there is definitely some other subtle bug, probably in computed
        # the Dirichlet series coefficients.  
        if abs(L.check_functional_equation()) > tiny: 
            raise RuntimeError, "Functional equation not numerically satisfied for either choice of sign"
        
    L.rename('Dokchitser L-function of %s'%E)
    return L