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