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
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
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
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
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"')