def _lfunction(self, W, prec=53, threshold=1e-10):
     from sage.lfunctions.all import Dokchitser
     G = self.domain()
     LG = G.splitting_field()
     deg = self.degree()
     
     #Determine the Gamma factors
     if LG.is_totally_real():
         gammaV = [0] * deg
     else:
         H = G.subgroup([G.complex_conjugation(LG.places()[0])])
         deg_plus = ZZ(self.restrict(H).scalar_product(H.trivial_character()))
         gammaV = [0] * deg_plus + [1] * (deg - deg_plus)
     
     if self.scalar_product(G.trivial_character()) > 0:
         raise NotImplementedError
     L = Dokchitser(conductor=self.conductor(), gammaV=gammaV, weight=1, eps=W, prec=prec)
     coeffs = 'coeff = %s'%(self.dirichlet_coefficients(L.num_coeffs(1.2)))
     L.init_coeffs('coeff[k]', pari_precode=coeffs)
     if L.check_functional_equation().abs() > threshold:
         return None
     self._root_number = W
     return True
     #self._lfunction = L
     pass
Exemple #2
0
def eisenstein_series_lseries(weight, prec=53,
               max_imaginary_part=0,
               max_asymp_coeffs=40):
    r"""
    Return the L-series of the weight `2k` Eisenstein series
    on `\mathrm{SL}_2(\ZZ)`.

    This actually returns an interface to Tim Dokchitser's program
    for computing with the L-series of the Eisenstein series

    INPUT:

    - ``weight`` - even integer

    - ``prec`` - integer (bits precision)

    - ``max_imaginary_part`` - real number

    - ``max_asymp_coeffs`` - integer

    OUTPUT:

    The L-series of the Eisenstein series.

    EXAMPLES:

    We compute with the L-series of `E_{16}` and then `E_{20}`::

       sage: L = eisenstein_series_lseries(16)
       sage: L(1)
       -0.291657724743874
       sage: L = eisenstein_series_lseries(20)
       sage: L(2)
       -5.02355351645998

    Now with higher precision::

        sage: L = eisenstein_series_lseries(20, prec=200)
        sage: L(2)
        -5.0235535164599797471968418348135050804419155747868718371029
    """
    f = eisenstein_series_qexp(weight,prec)
    from sage.lfunctions.all import Dokchitser
    from sage.symbolic.constants import pi
    key = (prec, max_imaginary_part, max_asymp_coeffs)
    j = weight
    L = Dokchitser(conductor = 1,
                   gammaV = [0,1],
                   weight = j,
                   eps = (-1)**Integer(j/2),
                   poles = [j],
                   # Using a string for residues is a hack but it works well
                   # since this will make PARI/GP compute sqrt(pi) with the
                   # right precision.
                   residues = '[sqrt(Pi)*(%s)]'%((-1)**Integer(j/2)*bernoulli(j)/j),
                   prec = prec)

    s = 'coeff = %s;'%f.list()
    L.init_coeffs('coeff[k+1]',pari_precode = s,
                  max_imaginary_part=max_imaginary_part,
                  max_asymp_coeffs=max_asymp_coeffs)
    L.check_functional_equation()
    L.rename('L-series associated to the weight %s Eisenstein series %s on SL_2(Z)'%(j,f))
    return L
Exemple #3
0
def eisenstein_series_lseries(weight, prec=53,
               max_imaginary_part=0,
               max_asymp_coeffs=40):
    r"""
    Return the L-series of the weight `2k` Eisenstein series
    on `\mathrm{SL}_2(\ZZ)`.

    This actually returns an interface to Tim Dokchitser's program
    for computing with the L-series of the Eisenstein series

    INPUT:

    - ``weight`` - even integer

    - ``prec`` - integer (bits precision)

    - ``max_imaginary_part`` - real number

    - ``max_asymp_coeffs`` - integer

    OUTPUT:

    The L-series of the Eisenstein series.

    EXAMPLES:

    We compute with the L-series of `E_{16}` and then `E_{20}`::

       sage: L = eisenstein_series_lseries(16)
       sage: L(1)
       -0.291657724743874
       sage: L = eisenstein_series_lseries(20)
       sage: L(2)
       -5.02355351645998

    Now with higher precision::

        sage: L = eisenstein_series_lseries(20, prec=200)
        sage: L(2)
        -5.0235535164599797471968418348135050804419155747868718371029
    """
    f = eisenstein_series_qexp(weight,prec)
    from sage.lfunctions.all import Dokchitser
    from sage.symbolic.constants import pi
    key = (prec, max_imaginary_part, max_asymp_coeffs)
    j = weight
    L = Dokchitser(conductor = 1,
                   gammaV = [0,1],
                   weight = j,
                   eps = (-1)**Integer(j/2),
                   poles = [j],
                   # Using a string for residues is a hack but it works well
                   # since this will make PARI/GP compute sqrt(pi) with the
                   # right precision.
                   residues = '[sqrt(Pi)*(%s)]'%((-1)**Integer(j/2)*bernoulli(j)/j),
                   prec = prec)

    s = 'coeff = %s;'%f.list()
    L.init_coeffs('coeff[k+1]',pari_precode = s,
                  max_imaginary_part=max_imaginary_part,
                  max_asymp_coeffs=max_asymp_coeffs)
    L.check_functional_equation()
    L.rename('L-series associated to the weight %s Eisenstein series %s on SL_2(Z)'%(j,f))
    return L
Exemple #4
0
    def dokchitser(self,
                   prec=53,
                   max_imaginary_part=0,
                   max_asymp_coeffs=40,
                   algorithm='gp'):
        r"""
        Return interface to Tim Dokchitser's program for computing
        with the `L`-series of this elliptic curve; this provides a way
        to compute Taylor expansions and higher derivatives of
        `L`-series.

        INPUT:

        - ``prec`` -- integer (bits precision)

        - ``max_imaginary_part`` -- real number

        - ``max_asymp_coeffs`` -- integer

        - ``algorithm`` -- string: 'gp' or 'magma'

        .. note::

           If algorithm='magma', then the precision is in digits rather
           than bits and the object returned is a Magma L-series, which has
           different functionality from the Sage L-series.

        EXAMPLES::

            sage: E = EllipticCurve('37a')
            sage: L = E.lseries().dokchitser()
            sage: L(2)
            0.381575408260711
            sage: L = E.lseries().dokchitser(algorithm='magma')         # optional - magma
            sage: L.Evaluate(2)                                         # optional - magma
            0.38157540826071121129371040958008663667709753398892116

        If the curve has too large a conductor, it isn't possible to
        compute with the `L`-series using this command.  Instead a
        ``RuntimeError`` is raised::

            sage: e = EllipticCurve([1,1,0,-63900,-1964465932632])
            sage: L = e.lseries().dokchitser(15)
            Traceback (most recent call last):
            ...
            RuntimeError: Unable to create L-series, due to precision or other limits in PARI.
        """
        if algorithm == 'magma':
            from sage.interfaces.all import magma
            return magma(self.__E).LSeries(Precision=prec)

        from sage.lfunctions.all import Dokchitser
        key = (prec, max_imaginary_part, max_asymp_coeffs)
        try:
            return self.__dokchitser[key]
        except KeyError:
            pass
        except AttributeError:
            self.__dokchitser = {}
        L = Dokchitser(conductor=self.__E.conductor(),
                       gammaV=[0, 1],
                       weight=2,
                       eps=self.__E.root_number(),
                       poles=[],
                       prec=prec)
        gp = L.gp()
        s = 'e = ellinit(%s);' % list(self.__E.minimal_model().a_invariants())
        s += 'a(k) = ellak(e, k);'
        L.init_coeffs('a(k)',
                      1,
                      pari_precode=s,
                      max_imaginary_part=max_imaginary_part,
                      max_asymp_coeffs=max_asymp_coeffs)
        L.rename('Dokchitser L-function associated to %s' % self.__E)
        self.__dokchitser[key] = L
        return L
Exemple #5
0
    def dokchitser(self, prec=53,
                   max_imaginary_part=0,
                   max_asymp_coeffs=40,
                   algorithm='gp'):
        r"""
        Return interface to Tim Dokchitser's program for computing
        with the L-series of this elliptic curve; this provides a way
        to compute Taylor expansions and higher derivatives of
        $L$-series.

        INPUT:
            prec -- integer (bits precision)
            max_imaginary_part -- real number
            max_asymp_coeffs -- integer
            algorithm -- string: 'gp' or 'magma'

        \note{If algorithm='magma', then the precision is in digits rather
        than bits and the object returned is a Magma L-series, which has
        different functionality from the Sage L-series.}

        EXAMPLES::

            sage: E = EllipticCurve('37a')
            sage: L = E.lseries().dokchitser()
            sage: L(2)
            0.381575408260711
            sage: L = E.lseries().dokchitser(algorithm='magma')         # optional - magma
            sage: L.Evaluate(2)                                         # optional - magma
            0.38157540826071121129371040958008663667709753398892116

        If the curve has too large a conductor, it isn't possible to
        compute with the L-series using this command.  Instead a
        RuntimeError is raised::

            sage: e = EllipticCurve([1,1,0,-63900,-1964465932632])
            sage: L = e.lseries().dokchitser(15)
            Traceback (most recent call last):
            ...
            RuntimeError: Unable to create L-series, due to precision or other limits in PARI.
        """
        if algorithm == 'magma':
            from sage.interfaces.all import magma
            return magma(self.__E).LSeries(Precision = prec)

        from sage.lfunctions.all import Dokchitser
        key = (prec, max_imaginary_part, max_asymp_coeffs)
        try:
            return self.__dokchitser[key]
        except KeyError:
            pass
        except AttributeError:
            self.__dokchitser = {}
        L = Dokchitser(conductor = self.__E.conductor(),
                       gammaV = [0,1],
                       weight = 2,
                       eps = self.__E.root_number(),
                       poles = [],
                       prec = prec)
        gp = L.gp()
        s = 'e = ellinit(%s);'%list(self.__E.minimal_model().a_invariants())
        s += 'a(k) = ellak(e, k);'
        L.init_coeffs('a(k)', 1, pari_precode = s,
                      max_imaginary_part=max_imaginary_part,
                      max_asymp_coeffs=max_asymp_coeffs)
        L.rename('Dokchitser L-function associated to %s'%self.__E)
        self.__dokchitser[key] = L
        return L
Exemple #6
0
        def zeta_function(self,
                          prec=53,
                          max_imaginary_part=0,
                          max_asymp_coeffs=40,
                          algorithm='pari'):
            r"""
            Return the Dedekind zeta function of this number field.

            Actually, this returns an interface for computing with the
            Dedekind zeta function `\zeta_F(s)` of the number field `F`.

            INPUT:

            - ``prec`` -- optional integer (default 53) bits precision

            - ``max_imaginary_part`` -- optional real number (default 0)

            - ``max_asymp_coeffs`` -- optional integer (default 40)

            - ``algorithm`` -- optional (default "pari") either "gp" or "pari"

            OUTPUT: The zeta function of this number field.

            If algorithm is "gp", this returns an interface to Tim
            Dokchitser's gp script for computing with L-functions.

            If algorithm is "pari", this returns instead an interface to Pari's
            own general implementation of L-functions.

            EXAMPLES::

                sage: K.<a> = NumberField(ZZ['x'].0^2+ZZ['x'].0-1)
                sage: Z = K.zeta_function(); Z
                PARI zeta function associated to Number Field in a with defining polynomial x^2 + x - 1
                sage: Z(-1)
                0.0333333333333333
                sage: L.<a, b, c> = NumberField([x^2 - 5, x^2 + 3, x^2 + 1])
                sage: Z = L.zeta_function()
                sage: Z(5)
                1.00199015670185

            Using the algorithm "pari"::

                sage: K.<a> = NumberField(ZZ['x'].0^2+ZZ['x'].0-1)
                sage: Z = K.zeta_function(algorithm="pari")
                sage: Z(-1)
                0.0333333333333333
                sage: L.<a, b, c> = NumberField([x^2 - 5, x^2 + 3, x^2 + 1])
                sage: Z = L.zeta_function(algorithm="pari")
                sage: Z(5)
                1.00199015670185

            TESTS::

                sage: QQ.zeta_function()
                PARI zeta function associated to Rational Field
            """
            if algorithm == 'gp':
                from sage.lfunctions.all import Dokchitser
                r1, r2 = self.signature()
                zero = [0]
                one = [1]
                Z = Dokchitser(conductor=abs(self.absolute_discriminant()),
                               gammaV=(r1 + r2) * zero + r2 * one,
                               weight=1,
                               eps=1,
                               poles=[1],
                               prec=prec)
                s = 'nf = nfinit(%s);' % self.absolute_polynomial()
                s += 'dzk = dirzetak(nf,cflength());'
                Z.init_coeffs('dzk[k]',
                              pari_precode=s,
                              max_imaginary_part=max_imaginary_part,
                              max_asymp_coeffs=max_asymp_coeffs)
                Z.check_functional_equation()
                Z.rename('Dokchitser Zeta function associated to %s' % self)
                return Z

            if algorithm == 'pari':
                from sage.lfunctions.pari import lfun_number_field, LFunction
                Z = LFunction(lfun_number_field(self), prec=prec)
                Z.rename('PARI zeta function associated to %s' % self)
                return Z

            raise ValueError('algorithm must be "gp" or "pari"')