def get_shift_and_width_for_coset(self, n): r""" Compute the shift and width of coset nr. n. """ if self._shift.has_key(n) and self._width.has_key(n): return self._shift[n], self._width[n] if not is_squarefree(self._level): raise NotImplementedError, "Only square-free levels implemented" G = Gamma0(self._level) A = self.coset_rep(n) a = A[0, 0] c = A[1, 0] width = G.cusp_width(Cusp(a, c)) if self._verbose > 0: print "width=", width Amat = Matrix(ZZ, 2, 2, A.matrix().list()) h = -1 for j in range(width): Th = Matrix(ZZ, 2, 2, [width, -j, 0, 1]) W = Amat * Th if self._verbose > 1: print "W=", W if self.is_involution(W): h = j break if h < 0: raise ArithmeticError, "Could not find shift!" self._shift[n] = h self._width[n] = width return h, width
def create_counts_table(levels, address, verbose=0): """ QUESTION: What proportion of curves in the database have squarefree conductor, as a function of the conductor? To answer, make another table ellcurves.counts with documents: {'_id':N, 'c':number_of_isogeny_classes_of_curves_of_conductor_N, 'ss':True} where 'ss':True is set only if N is squarefree. Once we have this table, the rest should be relatively easy. """ db_counts = get_ellcurves(address).counts from sage.all import is_squarefree i = 0 for N in levels: N = int(N) c = ellcurves.find({'level': N, 'number': 1}).count() doc = {'_id': N, 'c': c} if is_squarefree(N): doc['ss'] = True try: db_counts.insert(doc, safe=True) except DuplicateKeyError: if verbose and i % verbose == 0: print('[{0}]'.format(N)) else: if verbose and i % verbose == 0: print(N) i += 1 import sys sys.stdout.flush()
def get_shift_and_width_for_coset(self,n): r""" Compute the shift and width of coset nr. n. """ if self._shift.has_key(n) and self._width.has_key(n): return self._shift[n],self._width[n] if not is_squarefree(self._level): raise NotImplementedError,"Only square-free levels implemented" G = Gamma0(self._level) A = self.coset_rep(n) a = A[0,0]; c=A[1,0] width = G.cusp_width(Cusp(a,c)) if self._verbose>0: print "width=",width Amat = Matrix(ZZ,2,2,A.matrix().list()) h = -1 for j in range(width): Th = Matrix(ZZ,2,2,[width,-j,0,1]) W = Amat*Th if self._verbose>1: print "W=",W if self.is_involution(W): h = j break if h<0: raise ArithmeticError,"Could not find shift!" self._shift[n]=h self._width[n]=width return h,width
def create_counts_table(levels, address, verbose=0): """ QUESTION: What proportion of curves in the database have squarefree conductor, as a function of the conductor? To answer, make another table ellcurves.counts with documents: {'_id':N, 'c':number_of_isogeny_classes_of_curves_of_conductor_N, 'ss':True} where 'ss':True is set only if N is squarefree. Once we have this table, the rest should be relatively easy. """ db_counts = get_ellcurves(address).counts from sage.all import is_squarefree i = 0 for N in levels: N = int(N) c = ellcurves.find({'level':N, 'number':1}).count() doc = {'_id':N, 'c':c} if is_squarefree(N): doc['ss'] = True try: db_counts.insert(doc, safe=True) except DuplicateKeyError: if verbose and i%verbose == 0: print '[%s]'%N, else: if verbose and i%verbose == 0: print N, i += 1 import sys; sys.stdout.flush()
def weight_one_half_dim(FQM, use_reduction=True, proof=False, debug=0, local=True): N = Integer(FQM.level()) if not N % 4 == 0: return 0 m = Integer(N / Integer(4)) d = 0 for l in m.divisors(): if is_squarefree(m / l): if debug > 1: print "l = {0}".format(l) TM = FiniteQuadraticModule([2 * l], [-1 / Integer(4 * l)]) if local: dd = [0, 0] # eigenvalue 1, -1 multiplicity for p, n in lcm(FQM.level(), 4 * l).factor(): N = None TN = None J = FQM.jordan_decomposition() L = TM.jordan_decomposition() for j in xrange(1, n + 1): C = J.constituent(p**j)[0] D = L.constituent(p**j)[0] if debug > 1: print "C = {0}, D = {1}".format(C, D) if N == None and C.level() != 1: N = C elif C.level() != 1: N = N + C if TN == None and D.level() != 1: TN = D elif D.level() != 1: TN = TN + D dd1 = invariants_eps(N, TN, use_reduction, proof, debug) if debug > 1: print "dd1 = {}".format(dd1) if dd1 == [0, 0]: # the result is multiplicative # a single [0,0] as a local result # yields [0,0] in the end # and we're done here dd = [0, 0] break if dd == [0, 0]: # this is the first prime dd = dd1 else: # some basic arithmetic ;-) # 1 = 1*1 = (-1)(-1) # -1 = 1*(-1) = (-1)*1 ddtmp = copy(dd) ddtmp[0] = dd[0] * dd1[0] + dd[1] * dd1[1] ddtmp[1] = dd[0] * dd1[1] + dd[1] * dd1[0] dd = ddtmp if debug > 1: print "dd = {0}".format(dd) d += dd[0] else: d += invariants_eps(FQM, TM, use_reduction, proof, debug)[0] return d
def weight_one_half_dim(FQM, use_reduction = True, proof = False, debug = 0, local=True): N = Integer(FQM.level()) if not N % 4 == 0: return 0 m = Integer(N/Integer(4)) d = 0 for l in m.divisors(): if is_squarefree(m/l): if debug > 1: print "l = {0}".format(l) TM = FiniteQuadraticModule([2*l],[-1/Integer(4*l)]) if local: dd = [0,0] # eigenvalue 1, -1 multiplicity for p,n in lcm(FQM.level(),4*l).factor(): N = None TN = None J = FQM.jordan_decomposition() L = TM.jordan_decomposition() for j in xrange(1,n+1): C = J.constituent(p**j)[0] D = L.constituent(p**j)[0] if debug > 1: print "C = {0}, D = {1}".format(C,D) if N == None and C.level() != 1: N = C elif C.level() != 1: N = N + C if TN == None and D.level() != 1: TN = D elif D.level() != 1: TN = TN + D dd1 = invariants_eps(N, TN, use_reduction, proof, debug) if debug > 1: print "dd1 = {}".format(dd1) if dd1 == [0,0]: # the result is multiplicative # a single [0,0] as a local result # yields [0,0] in the end # and we're done here dd = [0,0] break if dd == [0,0]: # this is the first prime dd = dd1 else: # some basic arithmetic ;-) # 1 = 1*1 = (-1)(-1) # -1 = 1*(-1) = (-1)*1 ddtmp = copy(dd) ddtmp[0] = dd[0]*dd1[0] + dd[1]*dd1[1] ddtmp[1] = dd[0]*dd1[1] + dd[1]*dd1[0] dd = ddtmp if debug > 1: print "dd = {0}".format(dd) d += dd[0] else: d += invariants_eps(FQM, TM, use_reduction, proof, debug)[0] return d
def compute(self, p=None, cut_nonsimple_aniso=True, fast=1): args = list() for N in range(1, self._level_limit): v2 = Integer(N).valuation(2) N2 = 2 ** v2 if v2 in [0, 1, 2, 3] and is_squarefree(Integer(N) / N2): s = anisotropic_symbols(N, self._signature) if len(s) == 0: continue args = args + s logger.debug('args = {0}'.format(args)) logger.info('starting with {} anisotropic modules'.format(len(args))) self.compute_from_startpoints(args, p, cut_nonsimple_aniso, fast) return self._simple
def compute(self, p=None, cut_nonsimple_aniso=True, fast=1): args = list() for N in range(1, self._level_limit): v2 = Integer(N).valuation(2) N2 = 2**v2 if v2 in [0, 1, 2, 3] and is_squarefree(Integer(N) / N2): s = anisotropic_symbols(N, self._signature) if len(s) == 0: continue args = args + s logger.debug('args = {0}'.format(args)) logger.info('starting with {} anisotropic modules'.format(len(args))) self.compute_from_startpoints(args, p, cut_nonsimple_aniso, fast) return self._simple
def find_inverse_images_of_twists(k, N=1, chi=0, fi=0, prec=10, verbose=0): r""" Checks if f is minimal and if not, returns the associated minimal form to precision prec. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] - ''prec'' -- integer (the number of coefficients to get) - ''verbose'' -- integer OUTPUT: -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form. The actual minimal one is the first element of this list. EXAMPLES:: """ (t, f) = _get_newform(k, N, chi, fi) if (not t): return f if (is_squarefree(ZZ(N))): return [True, f] # We need to check all square factors of N logger.debug("investigating: %s" % f) N_sqfree = squarefree_part(ZZ(N)) Nsq = ZZ(N / N_sqfree) twist_candidates = list() KF = f.base_ring() # check how many Hecke eigenvalues we need to check max_nump = number_of_hecke_to_check(f) maxp = max(primes_first_n(max_nump)) for d in divisors(N): # we look at all d such that d^2 divdes N if (not ZZ(d**2).divides(ZZ(N))): continue D = DirichletGroup(d) # check possible candidates to twist into f # g in S_k(M,chi) wit M=N/d^2 M = ZZ(N / d**2) logger.debug("Checking level %s" % M) for xig in range(euler_phi(M)): (t, glist) = _get_newform(k, M, xig) if (not t): return glist for g in glist: logger.debug("Comparing to function %s" % g) KG = g.base_ring() # we now see if twisting of g by xi in D gives us f for xi in D: try: for p in primes_first_n(max_nump): if (ZZ(p).divides(ZZ(N))): continue bf = f.q_expansion(maxp + 1)[p] bg = g.q_expansion(maxp + 1)[p] if (bf == 0 and bg == 0): continue elif (bf == 0 and bg != 0 or bg == 0 and bf != 0): raise StopIteration() if (ZZ(p).divides(xi.conductor())): raise ArithmeticError("") xip = xi(p) # make a preliminary check that the base rings match with respect to being # real or not try: QQ(xip) XF = QQ if (KF != QQ or KG != QQ): raise StopIteration except TypeError: # we have a non-rational (i.e. complex) value of the character XF = xip.parent() if ((KF == QQ or KF.is_totally_real()) and (KG == QQ or KG.is_totally_real())): raise StopIteration ## it is diffcult to compare elements from diferent rings in general but we make some checcks # is it possible to see if there is a larger ring which everything can be # coerced into? ok = False try: a = KF(bg / xip) b = KF(bf) ok = True if (a != b): raise StopIteration() except TypeError: pass try: a = KG(bg) b = KG(xip * bf) ok = True if (a != b): raise StopIteration() except TypeError: pass if ( not ok ): # we could coerce and the coefficients were equal return "Could not compare against possible candidates!" # otherwise if we are here we are ok and found a candidate twist_candidates.append([dd, g.q_expansion(prec), xi]) except StopIteration: # they are not equal pass # logger.debug("Candidates=%s" % twist_candidates) if (len(twist_candidates) == 0): return (True, None) else: return (False, twist_candidates)
def find_inverse_images_of_twists(k, N=1, chi=0, fi=0, prec=10, verbose=0): r""" Checks if f is minimal and if not, returns the associated minimal form to precision prec. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] - ''prec'' -- integer (the number of coefficients to get) - ''verbose'' -- integer OUTPUT: -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form. The actual minimal one is the first element of this list. EXAMPLES:: """ (t, f) = _get_newform(k, N, chi, fi) if(not t): return f if(is_squarefree(ZZ(N))): return [True, f] # We need to check all square factors of N logger.debug("investigating: %s" % f) N_sqfree = squarefree_part(ZZ(N)) Nsq = ZZ(N / N_sqfree) twist_candidates = list() KF = f.base_ring() # check how many Hecke eigenvalues we need to check max_nump = number_of_hecke_to_check(f) maxp = max(primes_first_n(max_nump)) for d in divisors(N): # we look at all d such that d^2 divdes N if(not ZZ(d ** 2).divides(ZZ(N))): continue D = DirichletGroup(d) # check possible candidates to twist into f # g in S_k(M,chi) wit M=N/d^2 M = ZZ(N / d ** 2) logger.debug("Checking level %s" % M) for xig in range(euler_phi(M)): (t, glist) = _get_newform(k, M, xig) if(not t): return glist for g in glist: logger.debug("Comparing to function %s" % g) KG = g.base_ring() # we now see if twisting of g by xi in D gives us f for xi in D: try: for p in primes_first_n(max_nump): if(ZZ(p).divides(ZZ(N))): continue bf = f.q_expansion(maxp + 1)[p] bg = g.q_expansion(maxp + 1)[p] if(bf == 0 and bg == 0): continue elif(bf == 0 and bg != 0 or bg == 0 and bf != 0): raise StopIteration() if(ZZ(p).divides(xi.conductor())): raise ArithmeticError("") xip = xi(p) # make a preliminary check that the base rings match with respect to being # real or not try: QQ(xip) XF = QQ if(KF != QQ or KG != QQ): raise StopIteration except TypeError: # we have a non-rational (i.e. complex) value of the character XF = xip.parent() if((KF == QQ or KF.is_totally_real()) and (KG == QQ or KG.is_totally_real())): raise StopIteration ## it is diffcult to compare elements from diferent rings in general but we make some checcks # is it possible to see if there is a larger ring which everything can be # coerced into? ok = False try: a = KF(bg / xip) b = KF(bf) ok = True if(a != b): raise StopIteration() except TypeError: pass try: a = KG(bg) b = KG(xip * bf) ok = True if(a != b): raise StopIteration() except TypeError: pass if(not ok): # we could coerce and the coefficients were equal return "Could not compare against possible candidates!" # otherwise if we are here we are ok and found a candidate twist_candidates.append([dd, g.q_expansion(prec), xi]) except StopIteration: # they are not equal pass # logger.debug("Candidates=%s" % twist_candidates) if(len(twist_candidates) == 0): return (True, None) else: return (False, twist_candidates)
def set_twist_info(self, prec=10,insert_in_db=True): r""" Try to find forms of lower level which get twisted into self. OUTPUT: -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form. The actual minimal one is the first element of this list. t is set to True if self is minimal and False otherwise EXAMPLES:: """ if(len(self._twist_info) > 0): return self._twist_info N = self.level() k = self.weight() if(is_squarefree(ZZ(N))): self._twist_info = [True, None ] return [True, None] # We need to check all square factors of N twist_candidates = list() KF = self.base_ring() # check how many Hecke eigenvalues we need to check max_nump = self._number_of_hecke_eigenvalues_to_check() maxp = max(primes_first_n(max_nump)) for d in divisors(N): if(d == 1): continue # we look at all d such that d^2 divdes N if(not ZZ(d ** 2).divides(ZZ(N))): continue D = DirichletGroup(d) # check possible candidates to twist into f # g in S_k(M,chi) wit M=N/d^2 M = ZZ(N / d ** 2) if(self._verbose > 0): wmf_logger.debug("Checking level {0}".format(M)) for xig in range(euler_phi(M)): (t, glist) = _get_newform(M,k, xig) if(not t): return glist for g in glist: if(self._verbose > 1): wmf_logger.debug("Comparing to function {0}".format(g)) KG = g.base_ring() # we now see if twisting of g by xi in D gives us f for xi in D: try: for p in primes_first_n(max_nump): if(ZZ(p).divides(ZZ(N))): continue bf = self.as_factor().q_eigenform(maxp + 1, names='x')[p] bg = g.q_expansion(maxp + 1)[p] if(bf == 0 and bg == 0): continue elif(bf == 0 and bg != 0 or bg == 0 and bf != 0): raise StopIteration() if(ZZ(p).divides(xi.conductor())): raise ArithmeticError("") xip = xi(p) # make a preliminary check that the base rings match with respect to being # real or not try: QQ(xip) XF = QQ if(KF != QQ or KG != QQ): raise StopIteration except TypeError: # we have a non-rational (i.e. complex) value of the character XF = xip.parent() if((KF.absolute_degree() == 1 or KF.is_totally_real()) and (KG.absolute_degre() == 1 or KG.is_totally_real())): raise StopIteration ## it is diffcult to compare elements from diferent rings in general but we make some checcks # is it possible to see if there is a larger ring which everything can be # coerced into? ok = False try: a = KF(bg / xip) b = KF(bf) ok = True if(a != b): raise StopIteration() except TypeError: pass try: a = KG(bg) b = KG(xip * bf) ok = True if(a != b): raise StopIteration() except TypeError: pass if(not ok): # we could coerce and the coefficients were equal return "Could not compare against possible candidates!" # otherwise if we are here we are ok and found a candidate twist_candidates.append([M, g.q_expansion(prec), xi]) except StopIteration: # they are not equal pass wmf_logger.debug("Candidates=v{0}".format(twist_candidates)) self._twist_info = (False, twist_candidates) if(len(twist_candidates) == 0): self._twist_info = [True, None] else: self._twist_info = [False, twist_candidates] return self._twist_info
def __init__(self, f, prec=53, verbose=0, data={}): r""" Initialize the period polynomial of f. INPUT: - `f` -- Newform - `` EXAMPLES: # First elliptic curve sage: f=Newforms(11,2)[0] sage: pp=PeriodPolynomial(f,prec=103) sage: L=f.cuspform_lseries() sage: pp.petersson_norm() 0.00390834565612459898524738548154 - 5.53300833748482053164300189100e-35*I sage: pp.special_value(1) 0.253841860855910684337758923267 sage: L(1) 0.253841860855911 # We can also study rationality of the coefficients of the sage: pp.test_rationality() P(f 0)^+/omega_+=1.00000000000000000000000000000 P(f 0)^-/omega_-=0 P(f 1)^+/omega_+=-1.00000000000000000000000000000 P(f 1)^-/omega_-=0 P(f 2)^+/omega_+=0 P(f 2)^-/omega_-=1.27412157006452456511355616309e-31 + 1.01489446868406102099789763444e-28*I P(f 3)^+/omega_+=-5.00000000000000000000000000133 P(f 3)^-/omega_-=-1.16793587723237638257725820700e-60 + 8.24993716616779655911027615609e-29*I P(f 4)^+/omega_+=-2.50000000000000000000000000073 P(f 4)^-/omega_-=-3.39765752017206550696948310188e-32 + 2.39999999999999999999999999940*I P(f 5)^+/omega_+=2.50000000000000000000000000073 P(f 5)^-/omega_-=-3.39765752017206550696948310188e-32 + 2.39999999999999999999999999940*I P(f 6)^+/omega_+=5.00000000000000000000000000133 P(f 6)^-/omega_-=1.16793587723237638257725820700e-60 - 8.24993716616779655911027615609e-29*I P(f 7)^+/omega_+=5.00000000000000000000000000133 P(f 7)^-/omega_-=-1.16793587723237638257725820700e-60 + 8.24993716616779655911027615609e-29*I P(f 8)^+/omega_+=2.50000000000000000000000000073 P(f 8)^-/omega_-=3.39765752017206550696948310188e-32 - 2.39999999999999999999999999940*I P(f 9)^+/omega_+=-2.50000000000000000000000000073 P(f 9)^-/omega_-=3.39765752017206550696948310188e-32 - 2.39999999999999999999999999940*I P(f10)^+/omega_+=-5.00000000000000000000000000133 P(f10)^-/omega_-=1.16793587723237638257725820700e-60 - 8.24993716616779655911027615609e-29*I P(f11)^+/omega_+=0 P(f11)^-/omega_-=-1.27412157006452456511355616309e-31 - 1.01489446868406102099789763444e-28*I o1= 0.0404001869188632792144191985239*I o2= -1.36955018267536771772869542629e-33 - 0.0967407815209822856536332369020*I sage: f=Newforms(5,8,names='a')[0];f q - 14*q^2 - 48*q^3 + 68*q^4 + 125*q^5 + O(q^6) sage: L=f.cuspform_lseries() sage: pp=PeriodPolynomial(f,prec=103) sage: pp.special_value(4) -3.34183629241748201816194829811e-29 + 8.45531852674217908762910051272e-60*I sage: pp.special_value(3) -0.729970592499451187790964533256 + 2.56020879251697431818575640846e-31*I sage: L(3) -0.729970592499451 sage: L(4) 0.000000000000000 """ self._f = f self._level = None if data <> {}: self.init_from_dict(data) if self._level == None: self._level = f.level() self._k = f.weight() self._w = self._k - 2 self._verbose = verbose self._polynomials = {} self._prec = prec self._rks = {} self._coset_reps = {} self._dim = Gamma0(self._level).index() self._coefficients_at_coset = {} self._base_coeffs = [] self._base_coeffs_embedding = [] self._M = {} self._M0 = 0 self._width = {} self._shift = {} self._atkin_lehner = {} self._integrals = {} self._pplus = {} self._pminus = {} self._peterson_norm = 0 self._canonical_periods = [] # Check assert is_squarefree(self._level) ## Some numerical definitions self._RF = RealField(prec) self._eps = self._RF(2)**-self._RF(prec) self._pi = self._RF.pi()
def __init__(self,f,prec=53,verbose=0,data={}): r""" Initialize the period polynomial of f. INPUT: - `f` -- Newform - `` EXAMPLES: # First elliptic curve sage: f=Newforms(11,2)[0] sage: pp=PeriodPolynomial(f,prec=103) sage: L=f.cuspform_lseries() sage: pp.petersson_norm() 0.00390834565612459898524738548154 - 5.53300833748482053164300189100e-35*I sage: pp.special_value(1) 0.253841860855910684337758923267 sage: L(1) 0.253841860855911 # We can also study rationality of the coefficients of the sage: pp.test_rationality() P(f 0)^+/omega_+=1.00000000000000000000000000000 P(f 0)^-/omega_-=0 P(f 1)^+/omega_+=-1.00000000000000000000000000000 P(f 1)^-/omega_-=0 P(f 2)^+/omega_+=0 P(f 2)^-/omega_-=1.27412157006452456511355616309e-31 + 1.01489446868406102099789763444e-28*I P(f 3)^+/omega_+=-5.00000000000000000000000000133 P(f 3)^-/omega_-=-1.16793587723237638257725820700e-60 + 8.24993716616779655911027615609e-29*I P(f 4)^+/omega_+=-2.50000000000000000000000000073 P(f 4)^-/omega_-=-3.39765752017206550696948310188e-32 + 2.39999999999999999999999999940*I P(f 5)^+/omega_+=2.50000000000000000000000000073 P(f 5)^-/omega_-=-3.39765752017206550696948310188e-32 + 2.39999999999999999999999999940*I P(f 6)^+/omega_+=5.00000000000000000000000000133 P(f 6)^-/omega_-=1.16793587723237638257725820700e-60 - 8.24993716616779655911027615609e-29*I P(f 7)^+/omega_+=5.00000000000000000000000000133 P(f 7)^-/omega_-=-1.16793587723237638257725820700e-60 + 8.24993716616779655911027615609e-29*I P(f 8)^+/omega_+=2.50000000000000000000000000073 P(f 8)^-/omega_-=3.39765752017206550696948310188e-32 - 2.39999999999999999999999999940*I P(f 9)^+/omega_+=-2.50000000000000000000000000073 P(f 9)^-/omega_-=3.39765752017206550696948310188e-32 - 2.39999999999999999999999999940*I P(f10)^+/omega_+=-5.00000000000000000000000000133 P(f10)^-/omega_-=1.16793587723237638257725820700e-60 - 8.24993716616779655911027615609e-29*I P(f11)^+/omega_+=0 P(f11)^-/omega_-=-1.27412157006452456511355616309e-31 - 1.01489446868406102099789763444e-28*I o1= 0.0404001869188632792144191985239*I o2= -1.36955018267536771772869542629e-33 - 0.0967407815209822856536332369020*I sage: f=Newforms(5,8,names='a')[0];f q - 14*q^2 - 48*q^3 + 68*q^4 + 125*q^5 + O(q^6) sage: L=f.cuspform_lseries() sage: pp=PeriodPolynomial(f,prec=103) sage: pp.special_value(4) -3.34183629241748201816194829811e-29 + 8.45531852674217908762910051272e-60*I sage: pp.special_value(3) -0.729970592499451187790964533256 + 2.56020879251697431818575640846e-31*I sage: L(3) -0.729970592499451 sage: L(4) 0.000000000000000 """ self._f = f self._level = None if data<>{}: self.init_from_dict(data) if self._level==None: self._level = f.level() self._k = f.weight() self._w = self._k - 2 self._verbose = verbose self._polynomials = {} self._prec = prec self._rks = {} self._coset_reps={} self._dim = Gamma0(self._level).index() self._coefficients_at_coset = {} self._base_coeffs=[] self._base_coeffs_embedding=[] self._M = {} self._M0 = 0 self._width={} self._shift={} self._atkin_lehner={} self._integrals={} self._pplus = {} self._pminus={} self._peterson_norm=0 self._canonical_periods=[] # Check assert is_squarefree(self._level) ## Some numerical definitions self._RF = RealField(prec) self._eps = self._RF(2)**-self._RF(prec) self._pi = self._RF.pi()