예제 #1
0
 def _basic_integral(self, a, j, twist=None):
     r"""
     Computes the integral
     
         .. MATH::
            
            \int_{a+p\ZZ_p}(z-\omega(a))^jd\mu_\chi.
     
     If ``twist`` is ``None``, `\\chi` is the trivial character. Otherwise, ``twist`` can be a primitive quadratic character of conductor prime to `p`.
     """
     #is this the negative of what we want?
     #if Phis is fixed for this p-adic L-function, we should make this method cached
     p = self._Phis.parent().prime()
     if twist is None:
         pass
     elif twist in ZZ:
         twist = kronecker_character(twist)
         if twist.is_trivial():
             twist = None
         else:
             D = twist.level()
             assert(D.gcd(p) == 1)
     else:
         if twist.is_trivial():
             twist = None
         else:
             assert((twist**2).is_trivial())
             twist = twist.primitive_character()
             D = twist.level()
             assert(D.gcd(p) == 1)
     
     onDa = self._on_Da(a, twist)#self._Phis(Da)
     aminusat = a - self._Phis.parent().base_ring().base_ring().teichmuller(a)
     #aminusat = a - self._coefficient_ring.base_ring().teichmuller(a)
     try:
         ap = self._ap
     except AttributeError:
         self._ap = self._Phis.Tq_eigenvalue(p) #catch exception if not eigensymbol
         ap = self._ap
     if not twist is None:
         ap *= twist(p)
     if j == 0:
         return (~ap) * onDa.moment(0)
     if a == 1:
         #aminusat is 0, so only the j=r term is non-zero
         return (~ap) * (p ** j) * onDa.moment(j)
     #print "j =", j, "a = ", a
     ans = onDa.moment(0) * (aminusat ** j)
     #ans = onDa.moment(0)
     #print "\tr =", 0, " ans =", ans
     for r in range(1, j+1):
         if r == j:
             ans += binomial(j, r) * (p ** r) * onDa.moment(r)
         else:
             ans += binomial(j, r) * (aminusat ** (j - r)) * (p ** r) * onDa.moment(r)
         #print "\tr =", r, " ans =", ans
     #print " "
     return (~ap) * ans
예제 #2
0
    def __init__(self, E, A, prec=53):
        r"""
        Class for the Gross-Zagier L-series.

        This is attached to a pair `(E,A)` where `E` is an elliptic curve over
        `\QQ` and `A` is an ideal class in an imaginary quadratic number field.

        For the exact definition, in the more general setting of modular forms
        instead of elliptic curves, see section IV of [GrossZagier]_.

        INPUT:

        - ``E`` -- an elliptic curve over `\QQ`

        - ``A`` -- an ideal class in an imaginary quadratic number field

        - ``prec`` -- an integer (default 53) giving the required precision

        EXAMPLES::

            sage: e = EllipticCurve('37a')
            sage: K.<a> = QuadraticField(-40)
            sage: A = K.class_group().gen(0)
            sage: from sage.modular.modform.l_series_gross_zagier import GrossZagierLseries
            sage: G = GrossZagierLseries(e, A)

        TESTS::

            sage: K.<b> = QuadraticField(131)
            sage: A = K.class_group().one()
            sage: G = GrossZagierLseries(e, A)
            Traceback (most recent call last):
            ...
            ValueError: A is not an ideal class in an imaginary quadratic field
        """
        self._E = E
        self._N = N = E.conductor()
        self._A = A
        ideal = A.ideal()
        K = A.gens()[0].parent()
        D = K.disc()
        if not (K.degree() == 2 and D < 0):
            raise ValueError("A is not an ideal class in an"
                             " imaginary quadratic field")
        Q = ideal.quadratic_form().reduced_form()
        epsilon = -kronecker_character(D)(N)
        self._dokchister = Dokchitser(N**2 * D**2, [0, 0, 1, 1],
                                      weight=2,
                                      eps=epsilon,
                                      prec=prec)
        self._nterms = nterms = Integer(self._dokchister.gp()('cflength()'))
        if nterms > 1e6:
            # just takes way to long
            raise ValueError("Too many terms: {}".format(nterms))
        zeta_ord = ideal.number_field().zeta_order()
        an_list = gross_zagier_L_series(E.anlist(nterms + 1), Q, N, zeta_ord)
        self._dokchister.gp().set('a', an_list[1:])
        self._dokchister.init_coeffs('a[k]', 1)
예제 #3
0
    def __init__(self, E, A, prec=53):
        r"""
        Class for the Gross-Zagier L-series.

        This is attached to a pair `(E,A)` where `E` is an elliptic curve over
        `\QQ` and `A` is an ideal class in an imaginary quadratic number field.

        For the exact definition, in the more general setting of modular forms
        instead of elliptic curves, see section IV of [GrossZagier]_.

        INPUT:

        - ``E`` -- an elliptic curve over `\QQ`

        - ``A`` -- an ideal class in an imaginary quadratic number field

        - ``prec`` -- an integer (default 53) giving the required precision

        EXAMPLES::

            sage: e = EllipticCurve('37a')
            sage: K.<a> = QuadraticField(-40)
            sage: A = K.class_group().gen(0)
            sage: from sage.modular.modform.l_series_gross_zagier import GrossZagierLseries
            sage: G = GrossZagierLseries(e, A)

        TESTS::

            sage: K.<b> = QuadraticField(131)
            sage: A = K.class_group().one()
            sage: G = GrossZagierLseries(e, A)
            Traceback (most recent call last):
            ...
            ValueError: A is not an ideal class in an imaginary quadratic field
        """
        self._E = E
        self._N = N = E.conductor()
        self._A = A
        ideal = A.ideal()
        K = A.gens()[0].parent()
        D = K.disc()
        if not(K.degree() == 2 and D < 0):
            raise ValueError("A is not an ideal class in an"
                             " imaginary quadratic field")
        Q = ideal.quadratic_form().reduced_form()
        epsilon = - kronecker_character(D)(N)
        self._dokchister = Dokchitser(N ** 2 * D ** 2,
                                      [0, 0, 1, 1],
                                      weight=2, eps=epsilon, prec=prec)
        self._nterms = nterms = Integer(self._dokchister.num_coeffs())
        if nterms > 1e6:
            # just takes way to long
            raise ValueError("Too many terms: {}".format(nterms))
        zeta_ord = ideal.number_field().zeta_order()
        an_list = gross_zagier_L_series(E.anlist(nterms + 1), Q, N, zeta_ord)
        self._dokchister.gp().set('a', an_list[1:])
        self._dokchister.init_coeffs('a[k]', 1)
예제 #4
0
 def _evalf_(self, x, D, **kwargs):  #numerical value
     D = Integer(D)
     if D % 4 > 1:
         raise ValueError('Not a discriminant')
     s = kronecker_character(D).lfunction(algorithm='lcalc').value(x).real()
     f = D.squarefree_part()
     if f % 4 > 1 and not D % 4:
         f *= 4
     m = D // f
     if m != 1:
         return prod(1 - p**(-x) * kronecker(f, p)
                     for p in prime_divisors(m)) * s
     return s
예제 #5
0
    def _basic_integral(self, a, j, twist=None):
        r"""
        Computes the integral
        
            .. MATH::
               
               \int_{a+p\ZZ_p}(z-\omega(a))^jd\mu_\chi.
        
        If ``twist`` is ``None``, `\\chi` is the trivial character. Otherwise, ``twist`` can be a primitive quadratic character of conductor prime to `p`.
        """
        #is this the negative of what we want?
        #if Phis is fixed for this p-adic L-function, we should make this method cached
        p = self._Phis.parent().prime()
        if twist is None:
            pass
        elif twist in ZZ:
            twist = kronecker_character(twist)
            if twist.is_trivial():
                twist = None
            else:
                D = twist.level()
                assert (D.gcd(p) == 1)
        else:
            if twist.is_trivial():
                twist = None
            else:
                assert ((twist**2).is_trivial())
                twist = twist.primitive_character()
                D = twist.level()
                assert (D.gcd(p) == 1)

        onDa = self._on_Da(a, twist)  #self._Phis(Da)
        aminusat = a - self._Phis.parent().base_ring().base_ring().teichmuller(
            a)
        #aminusat = a - self._coefficient_ring.base_ring().teichmuller(a)
        try:
            ap = self._ap
        except AttributeError:
            self._ap = self._Phis.Tq_eigenvalue(
                p)  #catch exception if not eigensymbol
            ap = self._ap
        if not twist is None:
            ap *= twist(p)
        if j == 0:
            return (~ap) * onDa.moment(0)
        if a == 1:
            #aminusat is 0, so only the j=r term is non-zero
            return (~ap) * (p**j) * onDa.moment(j)
        #print "j =", j, "a = ", a
        ans = onDa.moment(0) * (aminusat**j)
        #ans = onDa.moment(0)
        #print "\tr =", 0, " ans =", ans
        for r in range(1, j + 1):
            if r == j:
                ans += binomial(j, r) * (p**r) * onDa.moment(r)
            else:
                ans += binomial(j, r) * (aminusat
                                         **(j - r)) * (p**r) * onDa.moment(r)
            #print "\tr =", r, " ans =", ans
        #print " "
        return (~ap) * ans