def lfun_elliptic_curve(E): """ Create the L-function of an elliptic curve. OUTPUT: one :pari:`lfun` object EXAMPLES:: sage: from sage.lfunctions.pari import lfun_elliptic_curve, LFunction sage: E = EllipticCurve('11a1') sage: L = LFunction(lfun_elliptic_curve(E)) sage: L(3) 0.752723147389051 sage: L(1) 0.253841860855911 Over number fields:: sage: K.<a> = QuadraticField(2) sage: E = EllipticCurve([1,a]) sage: L = LFunction(lfun_elliptic_curve(E)) sage: L(3) 1.00412346717019 """ return pari.lfuncreate(E)
def lfun_character(chi): """ Create the L-function of a primitive Dirichlet character. If the given character is not primitive, it is replaced by its associated primitive character. OUTPUT: one :pari:`lfun` object EXAMPLES:: sage: from sage.lfunctions.pari import lfun_character, LFunction sage: chi = DirichletGroup(6).gen().primitive_character() sage: L = LFunction(lfun_character(chi)) sage: L(3) 0.884023811750080 TESTS: A non-primitive one:: sage: L = LFunction(lfun_character(DirichletGroup(6).gen())) sage: L(4) 0.940025680877124 With complex arguments:: sage: from sage.lfunctions.pari import lfun_character, LFunction sage: chi = DirichletGroup(6, CC).gen().primitive_character() sage: L = LFunction(lfun_character(chi)) sage: L(3) 0.884023811750080 Check the values:: sage: chi = DirichletGroup(24)([1,-1,-1]); chi Dirichlet character modulo 24 of conductor 24 mapping 7 |--> 1, 13 |--> -1, 17 |--> -1 sage: Lchi = lfun_character(chi) sage: v = [0] + Lchi.lfunan(30).sage() sage: all(v[i] == chi(i) for i in (7,13,17)) True """ if not chi.is_primitive(): chi = chi.primitive_character() G, v = chi._pari_conversion() return pari.lfuncreate([G, v])
def __init__(self, lfun, prec=None): """ Initialization of the L-function from a PARI L-function. INPUT: - lfun -- a PARI :pari:`lfun` object or an instance of :class:`lfun_generic` - prec -- integer (default: 53) number of *bits* of precision EXAMPLES:: sage: from sage.lfunctions.pari import lfun_generic, LFunction sage: lf = lfun_generic(conductor=1, gammaV=[0], weight=1, eps=1, poles=[1], residues=[-1], v=pari('k->vector(k,n,1)')) sage: L = LFunction(lf) sage: L.num_coeffs() 4 """ if isinstance(lfun, lfun_generic): # preparation using motivic data self._L = lfun.__pari__() if prec is None: prec = lfun.prec elif isinstance(lfun, Gen): # already some PARI lfun self._L = lfun else: # create a PARI lfunction from other input data self._L = pari.lfuncreate(lfun) self._conductor = ZZ(self._L[4]) # needs check self._weight = ZZ(self._L[3]) # needs check if prec is None: self.prec = 53 else: self.prec = PyNumber_Index(prec) self._RR = RealField(self.prec) self._CC = ComplexField(self.prec) # Complex field used for inputs, which ensures exact 1-to-1 # conversion to/from PARI. Since PARI objects have a precision # in machine words (not bits), this is typically higher. For # example, the default of 53 bits of precision would become 64. self._CCin = ComplexField(pari.bitprecision(self._RR(1)))
def lfun_number_field(K): """ Create the Dedekind zeta function of a number field. OUTPUT: one :pari:`lfun` object EXAMPLES:: sage: from sage.lfunctions.pari import lfun_number_field, LFunction sage: L = LFunction(lfun_number_field(QQ)) sage: L(3) 1.20205690315959 sage: K = NumberField(x**2-2, 'a') sage: L = LFunction(lfun_number_field(K)) sage: L(3) 1.15202784126080 sage: L(0) 0.000000000000000 """ return pari.lfuncreate(K)
def lfun_character(chi): """ Create the L-function of a primitive Dirichlet character. If the given character is not primitive, it is replaced by its associated primitive character. OUTPUT: one :pari:`lfun` object EXAMPLES:: sage: from sage.lfunctions.pari import lfun_character, LFunction sage: chi = DirichletGroup(6).gen().primitive_character() sage: L = LFunction(lfun_character(chi)) sage: L(3) 1.20205690315959 TESTS: A non-primitive one:: sage: L = LFunction(lfun_character(DirichletGroup(6).gen())) sage: L(4) 1.08232323371114 With complex arguments:: sage: from sage.lfunctions.pari import lfun_character, LFunction sage: chi = DirichletGroup(6, CC).gen().primitive_character() sage: L = LFunction(lfun_character(chi)) sage: L(3) 1.20205690315959 """ if not chi.is_primitive(): chi = chi.primitive_character() conductor = chi.conductor() G = pari.znstar(conductor, 1) pari_orders = [pari(o) for o in G[2][1]] pari_gens = IntegerModRing(conductor).unit_gens(algorithm="pari") # should coincide with G[2][2] values_on_gens = (chi(x) for x in pari_gens) # now compute the input for pari (list of exponents) P = chi.parent() if is_ComplexField(P.base_ring()): zeta = P.zeta() zeta_argument = zeta.argument() v = [int(x.argument() / zeta_argument) for x in values_on_gens] else: dlog = P._zeta_dlog v = [dlog[x] for x in values_on_gens] m = P.zeta_order() v = [(vi * oi) // m for vi, oi in zip(v, pari_orders)] return pari.lfuncreate([G, v])
def init_coeffs(self, v, cutoff=None, w=1, *args, **kwds): """ Set the coefficients `a_n` of the `L`-series. If `L(s)` is not equal to its dual, pass the coefficients of the dual as the second optional argument. INPUT: - ``v`` -- list of complex numbers or unary function - ``cutoff`` -- unused - ``w`` -- list of complex numbers or unary function EXAMPLES:: sage: from sage.lfunctions.pari import lfun_generic, LFunction sage: lf = lfun_generic(conductor=1, gammaV=[0,1], weight=12, eps=1) sage: pari_coeffs = pari('k->vector(k,n,(5*sigma(n,3)+7*sigma(n,5))*n/12 - 35*sum(k=1,n-1,(6*k-4*(n-k))*sigma(k,3)*sigma(n-k,5)))') sage: lf.init_coeffs(pari_coeffs) Evaluate the resulting L-function at a point, and compare with the answer that one gets "by definition" (of L-function attached to a modular form):: sage: L = LFunction(lf) sage: L(14) 0.998583063162746 sage: a = delta_qexp(1000) sage: sum(a[n]/float(n)^14 for n in range(1,1000)) 0.9985830631627459 Illustrate that one can give a list of complex numbers for v (see :trac:`10937`):: sage: l2 = lfun_generic(conductor=1, gammaV=[0,1], weight=12, eps=1) sage: l2.init_coeffs(list(delta_qexp(1000))[1:]) sage: L2 = LFunction(l2) sage: L2(14) 0.998583063162746 TESTS: Verify that setting the `w` parameter does not raise an error (see :trac:`10937`):: sage: L2 = lfun_generic(conductor=1, gammaV=[0,1], weight=12, eps=1) sage: L2.init_coeffs(list(delta_qexp(1000))[1:], w=[1..1000]) Additional arguments are ignored for compatibility with the old Dokchitser script:: sage: L2.init_coeffs(list(delta_qexp(1000))[1:], foo="bar") doctest:...: DeprecationWarning: additional arguments for initializing an lfun_generic are ignored See https://trac.sagemath.org/26098 for details. """ if args or kwds: from sage.misc.superseded import deprecation deprecation( 26098, "additional arguments for initializing an lfun_generic are ignored" ) v = pari(v) if v.type() not in ('t_CLOSURE', 't_VEC'): raise TypeError("v (coefficients) must be a list or a function") # w = 0 means a*_n = a_n # w = 1 means a*_n = complex conjugate of a_n # otherwise w must be a list of coefficients w = pari(w) if w.type() not in ('t_INT', 't_CLOSURE', 't_VEC'): raise TypeError( "w (dual coefficients) must be a list or a function or the special value 0 or 1" ) if not self.poles: self._L = pari.lfuncreate( [v, w, self.gammaV, self.weight, self.conductor, self.eps]) else: # TODO # poles = list(zip(poles, residues)) self._L = pari.lfuncreate([ v, w, self.gammaV, self.weight, self.conductor, self.eps, self.poles[0] ])