def signOfEmfLfunction(level, weight, coefs, tol=10**(-7), num=1.3): """ Computes the sign of a EMF with give level, weight and coefficients numerically by computing the value of the EMF at two points related by the Atkin-Lehner involution. If the absolute value of the result is more than tol from 1 then it returns "Not able to compute" which indicates to few (or wrong) coeffcients. The parameter num chooses the related points and shouldn't be 1. """ sum1 = 0 sum2 = 0 for i in range(1, len(coefs)): sum1 += coefs[i - 1] * math.exp( -2 * math.pi * i * num / math.sqrt(level)) logger.debug("Sum1: {0}".format(sum1)) sum2 += coefs[i - 1].conjugate() * math.exp(- 2 * math.pi * i / num / math.sqrt(level)) / \ num ** weight logger.debug("Sum2: {0}".format(sum2)) sign = sum1 / sum2 if abs(abs(sign) - 1) > tol: logger.critical( "Not enough coefficients to compute the sign of the L-function.") sign = "Not able to compute." sign = 1 # wrong, but we need some type of error handling here. return sign
def styleTheSign(sign): ''' Returns the string to display as sign ''' try: logger.debug(1 - sign) if sign == 0: return "unknown" return (seriescoeff(sign, 0, "literal", "", -6, 5)) # the remaining code in this function can probably be deleted. # It does not correctly format 1.23-4.56i, and the seriescoeff function should andle all cases if abs(1 - sign) < 1e-10: return '1' elif abs(1 + sign) < 1e-10: return '-1' elif abs(1 - sign.imag()) < 1e-10: return 'i' elif abs(1 + sign.imag()) < 1e-10: return '-i' elif sign.imag > 0: return "${0} + {1}i$".format(truncatenumber(sign.real(), 5), truncatenumber(sign.imag(), 5)) else: return "${0} {1}i$".format(truncatenumber(sign.real(), 5), truncatenumber(sign.imag(), 5)) except: logger.debug("no styling of sign") return str(sign)
def number_of_coefficients_needed(Q, kappa_fe, lambda_fe, max_t): # TODO: This doesn't work. Trouble when computing t0 # We completely mimic what lcalc does when it decides whether # to print a warning. DIGITS = 14 # These are names of lcalc parameters, and we are DIGITS2 = 2 # mimicking them. logger.debug("Start NOC") theta = sum(kappa_fe) c = DIGITS2 * log(10.0) a = len(kappa_fe) c1 = 0.0 for j in range(a): logger.debug("In loop NOC") t0 = kappa_fe[j] * max_t + complex(lambda_fe[j]).imag() logger.debug("In loop 2 NOC") if abs(t0) < 2 * c / (math.pi * a): logger.debug("In loop 3_1 NOC") c1 += kappa_fe[j] * pi / 2.0 else: c1 += kappa_fe[j] * abs(c / (t0 * a)) logger.debug("In loop 3_2 NOC") return int(round(Q * exp(log(2.3 * DIGITS * theta / c1) * theta) + 10))
def render_single_Lfunction(Lclass, args, request): temp_args = to_dict(request.args) logger.debug(args) logger.debug(temp_args) try: L = Lclass(**args) except Exception as ex: from flask import current_app if not current_app.debug: info = { 'content': 'Sorry, there has been a problem: %s.' % str(ex.args), 'title': 'Error' } return render_template('LfunctionSimple.html', info=info, **info), 500 else: raise ex try: if temp_args['download'] == 'lcalcfile': return render_lcalcfile(L, request.url) except KeyError as ex: pass # Do nothing info = initLfunction(L, temp_args, request) return render_template('Lfunction.html', **info)
def render_plotLfunction_from_db(db, dbTable, condition): data_location = os.path.expanduser( "~/data/lfunction_plots/{0}.db".format(db)) logger.debug(data_location) try: db = sqlite3.connect(data_location) with db: cur = db.cursor() query = "SELECT start,end,points FROM {0} WHERE {1} LIMIT 1".format( dbTable, condition) cur.execute(query) row = cur.fetchone() start, end, values = row values = numpy.frombuffer(values) step = (end - start) / values.size pairs = [(start + x * step, values[x]) for x in range(0, values.size, 1)] p = plot(spline(pairs), -30, 30, thickness=0.4) styleLfunctionPlot(p, 8) except: return flask.redirect(404) fn = tempfile.mktemp(suffix=".png") p.save(filename=fn, dpi=100) data = file(fn).read() os.remove(fn) response = make_response(data) response.headers['Content-type'] = 'image/png' return response
def render_plotLfunction_from_db(db, dbTable, condition): data_location = os.path.expanduser( "~/data/lfunction_plots/{0}.db".format(db)) logger.debug(data_location) try: db = sqlite3.connect(data_location) with db: cur = db.cursor() query = "SELECT start,end,points FROM {0} WHERE {1} LIMIT 1".format(dbTable, condition) cur.execute(query) row = cur.fetchone() start,end,values = row values = numpy.frombuffer(values) step = (end - start)/values.size pairs = [ (start + x * step, values[x] ) for x in range(0, values.size, 1)] p = plot(spline(pairs), -30, 30, thickness = 0.4) styleLfunctionPlot(p, 8) except: return flask.redirect(404) fn = tempfile.mktemp(suffix=".png") p.save(filename=fn, dpi = 100) data = file(fn).read() os.remove(fn) response = make_response(data) response.headers['Content-type'] = 'image/png' return response
def l_function_ec_page(label): logger.debug(label) m = lmfdb_label_regex.match(label) if m is not None: # Lmfdb label is given if m.groups()[2]: # strip off the curve number return flask.redirect( url_for('.l_function_ec_page', label=label[:-1]), 301) else: args = {'label': label} return render_single_Lfunction(Lfunction_EC_Q, args, request) m = cremona_label_regex.match(label) if m is not None: # Do a redirect if cremona label is given if m.groups()[2]: C = getDBConnection().elliptic_curves.curves.find_one( {'label': label}) else: C = getDBConnection().elliptic_curves.curves.find_one( {'iso': label}) return flask.redirect( url_for('.l_function_ec_page', label=(C['lmfdb_iso'])), 301)
def styleTheSign(sign): """ Returns the string to display as sign """ try: logger.debug(1 - sign) if sign == 0: return "unknown" return seriescoeff(sign, 0, "literal", "", -6, 5) # the remaining code in this function can probably be deleted. # It does not correctly format 1.23-4.56i, and the seriescoeff function should andle all cases if abs(1 - sign) < 1e-10: return "1" elif abs(1 + sign) < 1e-10: return "-1" elif abs(1 - sign.imag()) < 1e-10: return "i" elif abs(1 + sign.imag()) < 1e-10: return "-i" elif sign.imag > 0: return "${0} + {1}i$".format(truncatenumber(sign.real(), 5), truncatenumber(sign.imag(), 5)) else: return "${0} {1}i$".format(truncatenumber(sign.real(), 5), truncatenumber(sign.imag(), 5)) except: logger.debug("no styling of sign") return str(sign)
def l_function_hmf_redirect_2(field, label): logger.debug(field, label) return flask.redirect(url_for('.l_function_hmf_page', field=field, label=label, character='0', number='0'), code=301)
def l_function_emf_redirect_3(level, weight): logger.debug(level, weight) return flask.redirect(url_for('.l_function_emf_page', level=level, weight=weight, character='0', label='a', number='0'), code=301)
def processSymPowerEllipticCurveNavigation(startCond, endCond, power): """ Produces a table of all symmetric power L-functions of elliptic curves with conductors from startCond to endCond """ try: N = startCond if N < 11: N = 11 elif N > 100: N = 100 except: N = 11 try: if endCond > 500: end = 500 else: end = endCond except: end = 100 iso_list = isogenyclasstable(N, end) if power == 2: powerName = 'square' elif power == 3: powerName = 'cube' else: powerName = str(power) + '-th power' s = '<h5>Examples of symmetric ' + powerName + \ ' L-functions attached to isogeny classes of elliptic curves</h5>' s += '<table>' logger.debug(iso_list) counter = 0 nr_of_columns = 10 for label in iso_list: if counter == 0: s += '<tr>' counter += 1 s += '<td><a href="' + url_for('.l_function_ec_sym_page', power=str(power), label=label) + '">%s</a></td>\n' % label if counter == nr_of_columns: s += '</tr>\n' counter = 0 if counter > 0: s += '</tr>\n' s += '</table>\n' return s
def styleTheSign(sign): ''' Returns the string to display as sign ''' try: logger.debug(1 - sign) if sign == 0: return "unknown" return(seriescoeff(sign, 0, "literal", "", -6, 5)) except: logger.debug("no styling of sign") return str(sign)
def styleTheSign(sign): ''' Returns the string to display as sign ''' try: logger.debug(1 - sign) if sign == 0: return "unknown" return seriescoeff(sign, 0, "literal", "", 3) except: logger.debug("no styling of sign") return str(sign)
def compute_local_roots_SMF2_scalar_valued(ev_data, k, embedding): """ computes the dirichlet series for a Lfunction_SMF2_scalar_valued """ logger.debug("Start SMF2") K = ev_data[0].parent().fraction_field() # field of definition for the eigenvalues ev = ev_data[1] # dict of eigenvalues L = ev.keys() m = ZZ(max(L)).isqrt() + 1 ev2 = {} for p in primes(m): try: ev2[p] = (ev[p], ev[p * p]) except: break logger.debug(str(ev2)) ret = [] for p in ev2: R = PolynomialRing(K, "x") x = R.gens()[0] f = ( 1 - ev2[p][0] * x + (ev2[p][0] ** 2 - ev2[p][1] - p ** (2 * k - 4)) * x ** 2 - ev2[p][0] * p ** (2 * k - 3) * x ** 3 + p ** (4 * k - 6) * x ** 4 ) Rnum = PolynomialRing(CF, "y") x = Rnum.gens()[0] fnum = Rnum(0) if K != QQ: for i in range(int(f.degree()) + 1): fnum = fnum + f[i].complex_embeddings(NN)[embedding] * (x / p ** (k - 1.5)) ** i else: for i in range(int(f.degree()) + 1): fnum = fnum + f[i] * (x / CF(p ** (k - 1.5))) ** i r = fnum.roots(CF) r = [1 / a[0] for a in r] # a1 = r[1][0]/r[0][0] # a2 = r[2][0]/r[0][0] # a0 = 1/r[3][0] ret.append((p, r)) return ret
def compute_local_roots_SMF2_scalar_valued(ev_data, k, embedding): ''' computes the dirichlet series for a Lfunction_SMF2_scalar_valued ''' logger.debug("Start SMF2") K = ev_data[0].parent().fraction_field( ) # field of definition for the eigenvalues ev = ev_data[1] # dict of eigenvalues print "ev=--------->>>>>>>", ev L = ev.keys() m = ZZ(max(L)).isqrt() + 1 ev2 = {} for p in primes(m): try: ev2[p] = (ev[p], ev[p * p]) except: break logger.debug(str(ev2)) ret = [] for p in ev2: R = PolynomialRing(K, 'x') x = R.gens()[0] f = (1 - ev2[p][0] * x + (ev2[p][0]**2 - ev2[p][1] - p**(2 * k - 4)) * x**2 - ev2[p][0] * p**(2 * k - 3) * x**3 + p**(4 * k - 6) * x**4) Rnum = PolynomialRing(CF, 'y') x = Rnum.gens()[0] fnum = Rnum(0) if K != QQ: for i in range(int(f.degree()) + 1): fnum = fnum + f[i].complex_embeddings(NN)[embedding] * ( x / p**(k - 1.5))**i else: for i in range(int(f.degree()) + 1): fnum = fnum + f[i] * (x / CF(p**(k - 1.5)))**i r = fnum.roots(CF) r = [1 / a[0] for a in r] # a1 = r[1][0]/r[0][0] # a2 = r[2][0]/r[0][0] # a0 = 1/r[3][0] ret.append((p, r)) return ret
def processEllipticCurveNavigation(startCond, endCond): """ Produces a table of all L-functions of elliptic curves with conductors from startCond to endCond """ try: N = startCond if N < 11: N = 11 elif N > 100: N = 100 except: N = 11 try: if endCond > 500: end = 500 else: end = endCond except: end = 100 iso_list = isogenyclasstable(N, end) s = '<h5>Examples of L-functions attached to isogeny classes of elliptic curves</h5>' s += '<table>' logger.debug(iso_list) counter = 0 nr_of_columns = 10 for label in iso_list: if counter == 0: s += '<tr>' counter += 1 s += '<td><a href="' + url_for('.l_function_ec_page', label=label) + '">%s</a></td>\n' % label if counter == nr_of_columns: s += '</tr>\n' counter = 0 if counter > 0: s += '</tr>\n' s += '</table>\n' return s
def render_single_Lfunction(Lclass, args, request): temp_args = to_dict(request.args) logger.debug(args) logger.debug(temp_args) try: L = Lclass(**args) try: if temp_args['download'] == 'lcalcfile': return render_lcalcfile(L, request.url) except Exception as ex: pass # Do nothing except Exception as ex: info = {'content': 'Sorry, there has been a problem: %s.' % ex.args[0], 'title': 'Error'} return render_template('LfunctionSimple.html', info=info, **info), 500 info = initLfunction(L, temp_args, request) return render_template('Lfunction.html', **info)
def processGenus2CurveNavigation(startCond, endCond): """ Produces a table of all L-functions of genus 2 curves with conductors from startCond to endCond """ Nmin = startCond if Nmin < 169: Nmin = 169 Nmax = endCond if Nmax > 10000: Nmax = 10000 query = {'cond': {'$lte': Nmax, '$gte': Nmin}} # Get all the isogeny classes and sort them according to conductor cursor = base.getDBConnection().genus2_curves.isogeny_classes.find(query) iso_list = cursor.sort([('cond', ASCENDING), ('label', ASCENDING)]) s = '<h5>Examples of L-functions attached to isogeny classes of genus 2 curves</h5>' s += '<table>' logger.debug(iso_list) counter = 0 nr_of_columns = 10 for iso in iso_list: if counter == 0: s += '<tr>' counter += 1 condx = iso['label'].split('.') s += '<td><a href="' + url_for('.l_function_genus2_page',cond=condx[0], x=condx[1]) + '">%s</a></td>\n' % iso['label'] if counter == nr_of_columns: s += '</tr>\n' counter = 0 if counter > 0: s += '</tr>\n' s += '</table>\n' return s
def compute_local_roots_SMF2_scalar_valued(K, ev, k, embedding): ''' computes the dirichlet series for a Lfunction_SMF2_scalar_valued ''' L = ev.keys() m = ZZ(max(L)).isqrt() + 1 ev2 = {} for p in primes(m): try: ev2[p] = (ev[p], ev[p * p]) except: break logger.debug(str(ev2)) ret = [] for p in ev2: R = PolynomialRing(K, 'x') x = R.gens()[0] f = (1 - ev2[p][0] * x + (ev2[p][0] ** 2 - ev2[p][1] - p ** ( 2 * k - 4)) * x ** 2 - ev2[p][0] * p ** (2 * k - 3) * x ** 3 + p ** (4 * k - 6) * x ** 4) Rnum = PolynomialRing(CF, 'y') x = Rnum.gens()[0] fnum = Rnum(0) if K != QQ: for i in range(int(f.degree()) + 1): fnum = fnum + f[i].complex_embeddings(NN)[embedding] * (x / p ** (k - 1.5)) ** i else: for i in range(int(f.degree()) + 1): fnum = fnum + f[i] * (x / CF(p ** (k - 1.5))) ** i r = fnum.roots(CF) r = [1 / a[0] for a in r] # a1 = r[1][0]/r[0][0] # a2 = r[2][0]/r[0][0] # a0 = 1/r[3][0] ret.append((p, r)) return ret
def signOfEmfLfunction(level, weight, coefs, tol=10 ** (-7), num=1.3): """ Computes the sign of a EMF with give level, weight and coefficients numerically by computing the value of the EMF at two points related by the Atkin-Lehner involution. If the absolute value of the result is more than tol from 1 then it returns "Not able to compute" which indicates to few (or wrong) coeffcients. The parameter num chooses the related points and shouldn't be 1. """ sum1 = 0 sum2 = 0 for i in range(1, len(coefs)): sum1 += coefs[i - 1] * math.exp(-2 * math.pi * i * num / math.sqrt(level)) logger.debug("Sum1: {0}".format(sum1)) sum2 += coefs[i - 1].conjugate() * math.exp(-2 * math.pi * i / num / math.sqrt(level)) / num ** weight logger.debug("Sum2: {0}".format(sum2)) sign = sum1 / sum2 if abs(abs(sign) - 1) > tol: logger.critical("Not enough coefficients to compute the sign of the L-function.") sign = "Not able to compute." return sign
def render_single_Lfunction(Lclass, args, request): temp_args = to_dict(request.args) logger.debug(args) logger.debug(temp_args) try: L = Lclass(**args) except Exception as ex: from flask import current_app if not current_app.debug: info = {'content': 'Sorry, there has been a problem: %s.'%str(ex.args), 'title': 'Error'} return render_template('LfunctionSimple.html', info=info, **info), 500 else: raise ex try: if temp_args['download'] == 'lcalcfile': return render_lcalcfile(L, request.url) except KeyError as ex: pass # Do nothing info = initLfunction(L, temp_args, request) return render_template('Lfunction.html', **info)
def getOneGraphHtmlHolo(condmax): if condmax == 1: pic = (url_for('static', filename='images/browseGraphHoloNew_1.svg'), 2023, 610) elif condmax == 0.501: pic = (url_for('static', filename='images/browseGraphHoloNew_0.501.svg'), 1020, 550) else: logger.debug( "Warning: image is generated on the fly, not from static, this is slow!" ) pic = (url_for('.browseGraphHoloNew', **{'condmax': condmax}), 1010, 600) logger.debug(pic[0]) ans = ( "<embed src='%s' width='%s' height='%s' type='image/svg+xml' " % pic + "pluginspage='http://www.adobe.com/svg/viewer/install/'/>\n") ans += "<br/>\n" return (ans)
def l_function_ec_page(label): logger.debug(label) m = lmfdb_label_regex.match(label) if m is not None: # Lmfdb label is given if m.groups()[2]: # strip off the curve number return flask.redirect(url_for('.l_function_ec_page', label=label[:-1]), 301) else: args = {'label': label} return render_single_Lfunction(Lfunction_EC_Q, args, request) m = cremona_label_regex.match(label) if m is not None: # Do a redirect if cremona label is given if m.groups()[2]: C = getDBConnection().elliptic_curves.curves.find_one({'label': label}) else: C = getDBConnection().elliptic_curves.curves.find_one({'iso': label}) return flask.redirect(url_for('.l_function_ec_page', label=(C['lmfdb_iso'])), 301)
def getLmaassByDatabaseId(dbid): collList = [('Lfunction', 'LemurellMaassHighDegree'), ('Lfunction', 'FarmerMaass'), ('Lfunction', 'LemurellTest')] dbName = '' dbColl = '' dbEntry = None i = 0 # Go through all collections to find a Maass form with correct id while i < len(collList) and dbEntry is None: connection = base.getDBConnection() db = pymongo.database.Database(connection, collList[i][0]) collection = pymongo.collection.Collection(db, collList[i][1]) logger.debug(str(collection)) logger.debug(dbid) dbEntry = collection.find_one({'_id': dbid}) if dbEntry is None: i += 1 else: (dbName, dbColl) = collList[i] return [dbName, dbColl, dbEntry]
def styleTheSign(sign): ''' Returns the string to display as sign ''' try: logger.debug(1 - sign) if sign == 0: return "unknown" if abs(1 - sign) < 1e-10: return '1' elif abs(1 + sign) < 1e-10: return '-1' elif abs(1 - sign.imag()) < 1e-10: return 'i' elif abs(1 + sign.imag()) < 1e-10: return '-i' elif sign.imag > 0: return "${0} + {1}i$".format(truncatenumber(sign.real(), 5), truncatenumber(sign.imag(), 5)) else: return "${0} {1}i$".format(truncatenumber(sign.real(), 5), truncatenumber(sign.imag(), 5)) except: logger.debug("no styling of sign") return str(sign)
def getLmaassByDatabaseId(dbid): collList = [('Lfunction','LemurellMaassHighDegree'), ('Lfunction','FarmerMaass'), ('Lfunction','LemurellTest')] dbName = '' dbColl = '' dbEntry = None i = 0 # Go through all collections to find a Maass form with correct id while i < len(collList) and dbEntry is None: connection = base.getDBConnection() db = pymongo.database.Database(connection, collList[i][0]) collection = pymongo.collection.Collection(db, collList[i][1]) logger.debug(str(collection)) logger.debug(dbid) dbEntry = collection.find_one({'_id': dbid}) if dbEntry is None: i += 1 else: (dbName,dbColl) = collList[i] return [dbName, dbColl, dbEntry]
def __init__(self, **args): # Check for compulsory arguments if not ('label' in args.keys()): raise KeyError("You have to supply label for a Hilbert modular form L-function") logger.debug(str(args)) # Initialize default values if not args['number']: args['number'] = 0 # Default choice of embedding of the coefficients args['character'] = 0 # Only trivial character # Put the arguments into the object dictionary self.__dict__.update(args) logger.debug(str(self.character) + str(self.label) + str(self.number)) # Load form from database C = base.getDBConnection() f = C.hmfs.forms.find_one({'label': self.label}) if f is None: raise KeyError("There is no Hilbert modular form with that label") logger.debug(str(args)) F = WebNumberField(f['field_label']) F_hmf = C.hmfs.fields.find_one({'label': f['field_label']}) self.character = args['character'] if self.character > 0: raise KeyError("The L-function of a Hilbert modular form with non-trivial character has not been implemented yet.") self.number = int(args['number']) # It is a Sage int self.field_disc = F.disc() self.field_degree = int(F.degree()) try: self.weight = int(f['parallel_weight']) except KeyError: self.weight = int(f['weight'].split(', ')[0][1:]) self.level = f['level_norm'] * self.field_disc ** 2 # Extract the L-function information from the elliptic modular form self.automorphyexp = float(self.weight - 1) / float(2) self.Q_fe = float(sqrt(self.level)) / (2 * math.pi) ** (self.field_degree) R = QQ['x'] (x,) = R._first_ngens(1) K = NumberField(R(str(f['hecke_polynomial']).replace('^', '**')), 'e') e = K.gens()[0] iota = K.complex_embeddings()[self.number] if self.level == 1: # For level 1, the sign is always plus self.sign = 1 else: # for level not 1, calculate sign from Fricke involution and weight AL_signs = [iota(eval(al[1])) for al in f['AL_eigenvalues']] self.sign = prod(AL_signs) * (-1) ** (float(self.weight * self.field_degree / 2)) logger.debug("Sign: " + str(self.sign)) self.kappa_fe = [1 for i in range(self.field_degree)] self.lambda_fe = [self.automorphyexp for i in range(self.field_degree)] self.mu_fe = [] self.nu_fe = [self.automorphyexp for i in range(self.field_degree)] self.selfdual = True self.langlands = True self.primitive = True self.degree = 2 * self.field_degree self.poles = [] self.residues = [] # Compute Dirichlet coefficients hecke_eigenvalues = [iota(K(str(ae))) for ae in f['hecke_eigenvalues']] primes = [pp_str.split(', ') for pp_str in F_hmf['primes']] primes = [[int(pp[0][1:]), int(pp[1])] for pp in primes] primes = [[pp[0], pp[1], factor(pp[0])[0][1]] for pp in primes] PP = primes[-1][0] self.numcoeff = PP # The number of coefficients is given by the norm of the last prime ppmidNN = [c[0] for c in f['AL_eigenvalues']] ratl_primes = [p for p in range(primes[-1][0] + 1) if is_prime(p)] RCC = CC['T'] (T,) = RCC._first_ngens(1) heckepols = [RCC(1) for p in ratl_primes] for l in range(len(hecke_eigenvalues)): if F_hmf['primes'][l] in ppmidNN: heckepols[ratl_primes.index(primes[l][1])] *= 1 - hecke_eigenvalues[l] / \ float(sqrt(primes[l][0])) * (T ** primes[l][2]) else: heckepols[ratl_primes.index(primes[l][1])] *= 1 - hecke_eigenvalues[l] / float( sqrt(primes[l][0])) * (T ** primes[l][2]) + (T ** (2 * primes[l][2])) # Compute inverses up to given degree heckepolsinv = [heckepols[i].xgcd(T ** ceil(log(PP * 1.0) / log(ratl_primes[i] * 1.0)))[1] for i in range(len(heckepols))] dcoeffs = [0, 1] for n in range(2, ratl_primes[-1] + 1): nfact = factor(n) if len(nfact) == 1: # prime power p = nfact[0][0] k = nfact[0][1] S = [1] + [dcoeffs[p ** i] for i in range(1, k)] heckepol = heckepolsinv[ratl_primes.index(p)] dcoeffs.append(heckepol[k]) else: # composite ancoeff = prod([dcoeffs[pe[0] ** pe[1]] for pe in nfact]) dcoeffs.append(ancoeff) # ff = open('dcoeffs.txt', 'w') # ff.write(str(primes) + '\n') # ff.write(str(heckepols) + '\n') # ff.write(str(ratl_primes) + '\n') # ff.close() self.dirichlet_coefficients = dcoeffs[1:] self.coefficient_period = 0 # HUH? self.coefficient_type = 0 # HUH? self.quasidegree = 1 # HUH? self.checkselfdual() self.texname = "L(s,f)" self.texnamecompleteds = "\\Lambda(s,f)" if self.selfdual: self.texnamecompleted1ms = "\\Lambda(1-s,f)" else: self.texnamecompleted1ms = "\\Lambda(1-s,\\overline{f})" self.title = "$L(s,f)$, " + "where $f$ is a holomorphic Hilbert cusp form with parallel weight " + str(self.weight) + ", level norm " + str(f['level_norm']) + ", and character " + str(self.character) self.citation = '' self.credit = '' self.generateSageLfunction() constructor_logger(self, args)
def initLfunction(L, args, request): ''' Sets the properties to show on the homepage of an L-function page. ''' info = {'title': L.title} try: info['citation'] = L.citation except AttributeError: info['citation'] = "" try: info['support'] = L.support except AttributeError: info['support'] = "" info['Ltype'] = L.Ltype() # Here we should decide which values are indeed special values # According to Brian, odd degree has special value at 1, and even # degree has special value at 1/2. # (however, I'm not sure this is true if L is not primitive -- GT) # Now we usually display both if L.Ltype() != "artin" or (L.Ltype() == "artin" and L.sign != 0): # if is_even(L.degree) : # info['sv12'] = specialValueString(L, 0.5, '1/2') # if is_odd(L.degree): # info['sv1'] = specialValueString(L, 1, '1') info['sv1'] = specialValueString(L, 1, '1') info['sv12'] = specialValueString(L, 0.5, '1/2') info['args'] = args info['credit'] = L.credit # info['citation'] = L.citation try: info['factorization'] = L.factorization except: pass try: info['url'] = L.url except: info['url'] = '' info['degree'] = int(L.degree) info['zeroeslink'] = (request.url.replace('/L/', '/L/Zeros/'). replace('/Lfunction/', '/L/Zeros/'). replace('/L-function/', '/L/Zeros/')) # url_for('zeroesLfunction', **args) info['plotlink'] = (request.url.replace('/L/', '/L/Plot/'). replace('/Lfunction/', '/L/Plot/'). replace('/L-function/', '/L/Plot/')) # info['plotlink'] = url_for('plotLfunction', **args) info['bread'] = [] info['properties2'] = set_gaga_properties(L) # Create friendlink by removing 'L/' and ending '/' friendlink = request.url.replace('/L/', '/').replace('/L-function/', '/').replace('/Lfunction/', '/') splitlink = friendlink.rpartition('/') friendlink = splitlink[0] + splitlink[2] logger.debug(L.Ltype()) if L.Ltype() == 'maass': if L.group == 'GL2': minNumberOfCoefficients = 100 # TODO: Fix this to take level into account if len(L.dirichlet_coefficients) < minNumberOfCoefficients: info['zeroeslink'] = '' info['plotlink'] = '' info['bread'] = get_bread(2, [('Maass Form', url_for('.l_function_maass_browse_page')), ('\(' + L.texname + '\)', request.url)]) info['friends'] = [('Maass Form ', friendlink)] else: info['bread'] = get_bread(L.degree, [('Maass Form', url_for('.l_function_maass_gln_browse_page', degree='degree' + str(L.degree))), (L.dbid, request.url)]) elif L.Ltype() == 'riemann': info['bread'] = get_bread(1, [('Riemann Zeta', request.url)]) info['friends'] = [('\(\mathbb Q\)', url_for('number_fields.by_label', label='1.1.1.1')), ('Dirichlet Character \(\\chi_{1}(1,\\cdot)\)', url_for('render_Character', arg1=1, arg2=1))] elif L.Ltype() == 'dirichlet': info['navi'] = getPrevNextNavig(L.charactermodulus, L.characternumber, "L") snum = str(L.characternumber) smod = str(L.charactermodulus) charname = '\(\\chi_{%s}({%s},\\cdot)\)' % (smod, snum) info['bread'] = get_bread(1, [(charname, request.url)]) info['friends'] = [('Dirichlet Character ' + str(charname), friendlink)] elif L.Ltype() == 'ellipticcurve': label = L.label while friendlink[len(friendlink) - 1].isdigit(): # Remove any number at the end to get isogeny class url friendlink = friendlink[0:len(friendlink) - 1] info['friends'] = [('Isogeny class ' + label, friendlink)] for i in range(1, L.nr_of_curves_in_class + 1): info['friends'].append(('Elliptic curve ' + label + str(i), friendlink + str(i))) if L.modform: info['friends'].append(('Modular form ' + label.replace('.', '.2'), url_for("emf.render_elliptic_modular_forms", level=L.modform['level'], weight=2, character=0, label=L.modform['iso']))) info['friends'].append(('L-function ' + label.replace('.', '.2'), url_for('.l_function_emf_page', level=L.modform['level'], weight=2, character=0, label=L.modform['iso'], number=0))) info['friends'].append( ('Symmetric square L-function', url_for(".l_function_ec_sym_page", power='2', label=label))) info['friends'].append( ('Symmetric cube L-function', url_for(".l_function_ec_sym_page", power='3', label=label))) info['bread'] = get_bread(2, [('Elliptic curve', url_for('.l_function_ec_browse_page')), (label, url_for('.l_function_ec_page', label=label))]) elif L.Ltype() == 'ellipticmodularform': friendlink = friendlink + L.addToLink # Strips off the embedding friendlink = friendlink.rpartition('/')[0] # number for the L-function if L.character: info['friends'] = [('Modular form ' + str( L.level) + '.' + str(L.weight) + '.' + str(L.character) + str(L.label), friendlink)] else: info['friends'] = [('Modular form ' + str(L.level) + '.' + str(L.weight) + str( L.label), friendlink)] if L.ellipticcurve: info['friends'].append( ('EC isogeny class ' + L.ellipticcurve, url_for("by_ec_label", label=L.ellipticcurve))) info['friends'].append(('L-function ' + str(L.level) + '.' + str(L.label), url_for('.l_function_ec_page', label=L.ellipticcurve))) for i in range(1, L.nr_of_curves_in_class + 1): info['friends'].append(('Elliptic curve ' + L.ellipticcurve + str(i), url_for("by_ec_label", label=L.ellipticcurve + str(i)))) info['friends'].append( ('Symmetric square L-function', url_for(".l_function_ec_sym_page", power='2', label=label))) info['friends'].append( ('Symmetric cube L-function', url_for(".l_function_ec_sym_page", power='3', label=label))) elif L.Ltype() == 'hilbertmodularform': friendlink = '/'.join(friendlink.split('/')[:-1]) info['friends'] = [('Hilbert Modular Form', friendlink.rpartition('/')[0])] elif L.Ltype() == 'dedekindzeta': info['friends'] = [('Number Field', friendlink)] elif L.Ltype() in ['lcalcurl', 'lcalcfile']: info['bread'] = [('L-function', url_for('.l_function_top_page'))] elif L.Ltype() == 'SymmetricPower': def ordinal(n): if n == 2: return "Square" elif n == 3: return "Cube" elif 10 <= n % 100 < 20: return str(n) + "th Power" else: return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(n % 10, "th") + " Power" friendlink = request.url.replace('/L/SymmetricPower/%d/' % L.m, '/') splitlink = friendlink.rpartition('/') friendlink = splitlink[0] + splitlink[2] friendlink2 = request.url.replace('/L/SymmetricPower/%d/' % L.m, '/L/') splitlink = friendlink2.rpartition('/') friendlink2 = splitlink[0] + splitlink[2] info['friends'] = [('Isogeny class ' + L.label, friendlink), ('Symmetric 1st Power', friendlink2)] for j in range(2, L.m + 2): if j != L.m: friendlink3 = request.url.replace('/L/SymmetricPower/%d/' % L.m, '/L/SymmetricPower/%d/' % j) info['friends'].append(('Symmetric %s' % ordinal(j), friendlink3)) elif L.Ltype() == 'siegelnonlift' or L.Ltype() == 'siegeleisenstein' or L.Ltype() == 'siegelklingeneisenstein' or L.Ltype() == 'siegelmaasslift': weight = str(L.weight) number = str(L.number) info['friends'] = [('Siegel Modular Form', friendlink)] elif L.Ltype() == "artin": # info['zeroeslink'] = '' # info['plotlink'] = '' info['friends'] = [('Artin representation', L.artin.url_for())] if L.sign == 0: # The root number is now unknown info['zeroeslink'] = '' info['plotlink'] = '' info['dirichlet'] = lfuncDStex(L, "analytic") info['eulerproduct'] = lfuncEPtex(L, "abstract") info['functionalequation'] = lfuncFEtex(L, "analytic") info['functionalequationSelberg'] = lfuncFEtex(L, "selberg") if len(request.args) == 0: lcalcUrl = request.url + '?download=lcalcfile' else: lcalcUrl = request.url + '&download=lcalcfile' info['downloads'] = [('Lcalcfile', lcalcUrl)] return info
def initLfunction(L, args, request): ''' Sets the properties to show on the homepage of an L-function page. ''' info = {'title': L.title} try: info['citation'] = L.citation except AttributeError: info['citation'] = "" try: info['support'] = L.support except AttributeError: info['support'] = "" info['Ltype'] = L.Ltype() # Here we should decide which values are indeed special values # According to Brian, odd degree has special value at 1, and even # degree has special value at 1/2. # (however, I'm not sure this is true if L is not primitive -- GT) # Now we usually display both if L.Ltype() != "artin" or (L.Ltype() == "artin" and L.sign != 0): # if is_even(L.degree) : # info['sv12'] = specialValueString(L, 0.5, '1/2') # if is_odd(L.degree): # info['sv1'] = specialValueString(L, 1, '1') info['sv1'] = specialValueString(L, 1, '1') info['sv12'] = specialValueString(L, 0.5, '1/2') info['args'] = args info['credit'] = L.credit # info['citation'] = L.citation try: info['factorization'] = L.factorization except: pass try: info['url'] = L.url except: info['url'] = '' info['degree'] = int(L.degree) info['zeroeslink'] = (request.url.replace('/L/', '/L/Zeros/'). replace('/Lfunction/', '/L/Zeros/'). replace('/L-function/', '/L/Zeros/')) # url_for('zeroesLfunction', **args) info['plotlink'] = (request.url.replace('/L/', '/L/Plot/'). replace('/Lfunction/', '/L/Plot/'). replace('/L-function/', '/L/Plot/')) # info['plotlink'] = url_for('plotLfunction', **args) info['bread'] = [] info['properties2'] = set_gaga_properties(L) # Create friendlink by removing 'L/' and ending '/' friendlink = request.url.replace('/L/', '/').replace('/L-function/', '/').replace('/Lfunction/', '/') splitlink = friendlink.rpartition('/') friendlink = splitlink[0] + splitlink[2] logger.debug(L.Ltype()) if L.Ltype() == 'maass': if L.group == 'GL2': minNumberOfCoefficients = 100 # TODO: Fix this to take level into account if len(L.dirichlet_coefficients) < minNumberOfCoefficients: info['zeroeslink'] = '' info['plotlink'] = '' info['bread'] = get_bread(2, [('Maass Form', url_for('.l_function_maass_browse_page')), ('\(' + L.texname + '\)', request.url)]) info['friends'] = [('Maass Form ', friendlink)] else: info['bread'] = get_bread(L.degree, [('Maass Form', url_for('.l_function_maass_gln_browse_page', degree='degree' + str(L.degree))), (L.dbid, request.url)]) elif L.Ltype() == 'riemann': info['bread'] = get_bread(1, [('Riemann Zeta', request.url)]) info['friends'] = [('\(\mathbb Q\)', url_for('number_fields.by_label', label='1.1.1.1')), ('Dirichlet Character \(\\chi_{1}(1,\\cdot)\)', url_character(type='Dirichlet', modulus=1, number=1))] elif L.Ltype() == 'dirichlet': mod, num = L.charactermodulus, L.characternumber Lpattern = r"\(L(s,\chi_{%s}(%s,·))\)" if mod > 1: pmod,pnum = WebDirichlet.prevprimchar(mod, num) Lprev = (Lpattern%(pmod,pnum),url_for('.l_function_dirichlet_page',modulus=pmod,number=pnum)) else: Lprev = ('','') nmod,nnum = WebDirichlet.nextprimchar(mod, num) Lnext = (Lpattern%(nmod,nnum),url_for('.l_function_dirichlet_page',modulus=nmod,number=nnum)) info['navi'] = (Lprev,Lnext) snum = str(L.characternumber) smod = str(L.charactermodulus) charname = WebDirichlet.char2tex(smod, snum) info['bread'] = get_bread(1, [(charname, request.url)]) info['friends'] = [('Dirichlet Character ' + str(charname), friendlink)] elif L.Ltype() == 'ellipticcurveQ': label = L.label while friendlink[len(friendlink) - 1].isdigit(): # Remove any number at the end to get isogeny class url friendlink = friendlink[0:len(friendlink) - 1] info['friends'] = [('Isogeny class ' + label, friendlink)] for i in range(1, L.nr_of_curves_in_class + 1): info['friends'].append(('Elliptic curve ' + label + str(i), friendlink + str(i))) if L.modform: info['friends'].append(('Modular form ' + label.replace('.', '.2'), url_for("emf.render_elliptic_modular_forms", level=L.modform['level'], weight=2, character=0, label=L.modform['iso']))) info['friends'].append(('L-function ' + label.replace('.', '.2'), url_for('.l_function_emf_page', level=L.modform['level'], weight=2, character=0, label=L.modform['iso'], number=0))) info['friends'].append( ('Symmetric square L-function', url_for(".l_function_ec_sym_page", power='2', label=label))) info['friends'].append( ('Symmetric cube L-function', url_for(".l_function_ec_sym_page", power='3', label=label))) info['bread'] = get_bread(2, [('Elliptic curve', url_for('.l_function_ec_browse_page')), (label, url_for('.l_function_ec_page', label=label))]) elif L.Ltype() == 'ellipticmodularform': friendlink = friendlink + L.addToLink # Strips off the embedding friendlink = friendlink.rpartition('/')[0] # number for the L-function if L.character: info['friends'] = [('Modular form ' + str( L.level) + '.' + str(L.weight) + '.' + str(L.character) + str(L.label), friendlink)] else: info['friends'] = [('Modular form ' + str(L.level) + '.' + str(L.weight) + str( L.label), friendlink)] if L.ellipticcurve: info['friends'].append( ('EC isogeny class ' + L.ellipticcurve, url_for("by_ec_label", label=L.ellipticcurve))) info['friends'].append(('L-function ' + str(L.level) + '.' + str(L.label), url_for('.l_function_ec_page', label=L.ellipticcurve))) for i in range(1, L.nr_of_curves_in_class + 1): info['friends'].append(('Elliptic curve ' + L.ellipticcurve + str(i), url_for("by_ec_label", label=L.ellipticcurve + str(i)))) info['friends'].append( ('Symmetric square L-function', url_for(".l_function_ec_sym_page", power='2', label=label))) info['friends'].append( ('Symmetric cube L-function', url_for(".l_function_ec_sym_page", power='3', label=label))) elif L.Ltype() == 'hilbertmodularform': friendlink = '/'.join(friendlink.split('/')[:-1]) info['friends'] = [('Hilbert Modular Form', friendlink.rpartition('/')[0])] elif L.Ltype() == 'dedekindzeta': info['friends'] = [('Number Field', friendlink)] elif L.Ltype() in ['lcalcurl', 'lcalcfile']: info['bread'] = [('L-functions', url_for('.l_function_top_page'))] elif L.Ltype() == 'SymmetricPower': def ordinal(n): if n == 2: return "Square" elif n == 3: return "Cube" elif 10 <= n % 100 < 20: return str(n) + "th Power" else: return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(n % 10, "th") + " Power" if L.m == 2: info['bread'] = get_bread(3, [("Symmetric square of Elliptic curve", url_for('.l_function_ec_sym2_browse_page')), (L.label, url_for('.l_function_ec_sym_page', label=L.label,power=L.m))]) elif L.m == 3: info['bread'] = get_bread(4, [("Symmetric cube of Elliptic curve", url_for('.l_function_ec_sym3_browse_page')), (L.label, url_for('.l_function_ec_sym_page', label=L.label,power=L.m))]) else: info['bread'] = [('L-functions', url_for('.l_function_top_page')), ('Symmetric %s of Elliptic curve ' % ordinal(L.m) + str(L.label), url_for('.l_function_ec_sym_page', label=L.label,power=L.m))] friendlink = request.url.replace('/L/SymmetricPower/%d/' % L.m, '/') splitlink = friendlink.rpartition('/') friendlink = splitlink[0] + splitlink[2] friendlink2 = request.url.replace('/L/SymmetricPower/%d/' % L.m, '/L/') splitlink = friendlink2.rpartition('/') friendlink2 = splitlink[0] + splitlink[2] info['friends'] = [('Isogeny class ' + L.label, friendlink), ('Symmetric 1st Power', friendlink2)] for j in range(2, L.m + 2): if j != L.m: friendlink3 = request.url.replace('/L/SymmetricPower/%d/' % L.m, '/L/SymmetricPower/%d/' % j) info['friends'].append(('Symmetric %s' % ordinal(j), friendlink3)) elif L.Ltype() == 'siegelnonlift' or L.Ltype() == 'siegeleisenstein' or L.Ltype() == 'siegelklingeneisenstein' or L.Ltype() == 'siegelmaasslift': weight = str(L.weight) number = str(L.number) info['friends'] = [('Siegel Modular Form', friendlink)] elif L.Ltype() == "artin": # info['zeroeslink'] = '' # info['plotlink'] = '' info['friends'] = [('Artin representation', L.artin.url_for())] if L.sign == 0: # The root number is now unknown info['zeroeslink'] = '' info['plotlink'] = '' info['dirichlet'] = lfuncDStex(L, "analytic") info['eulerproduct'] = lfuncEPtex(L, "abstract") info['functionalequation'] = lfuncFEtex(L, "analytic") info['functionalequationSelberg'] = lfuncFEtex(L, "selberg") if len(request.args) == 0: lcalcUrl = request.url + '?download=lcalcfile' else: lcalcUrl = request.url + '&download=lcalcfile' info['downloads'] = [('Lcalcfile', lcalcUrl)] return info
def __init__(self, **args): constructor_logger(self, args) def ordinal(n): if n == 2: return "Square" elif n == 3: return "Cube" elif 10 <= n % 100 < 20: return str(n) + "th Power" else: return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(n % 10, "th") + " Power" # Put the arguments into the object dictionary # They are: power, underlying_type, field, label (for EC) self.__dict__.update(args) try: self.m = int(self.power) logger.debug(self.m) except TypeError: raise TypeError("The power has to be an integer") if self.underlying_type != 'EllipticCurve' or self.field != 'Q': raise TypeError("The symmetric L-functions have been implemented only for Elliptic Curves over Q") # Create the elliptic curve curves = base.getDBConnection().elliptic_curves.curves Edata = curves.find_one({'lmfdb_label': self.label + '1'}) if Edata is None: raise KeyError('No elliptic curve with label %s exists in the database' % self.label) else: self.E = EllipticCurve([int(a) for a in Edata['ainvs']]) if self.E.has_cm(): raise TypeError('This Elliptic curve has complex multiplication' + ' and the symmetric power of its L-function is ' + 'then not primitive. This has not yet been implemented') from lmfdb.symL.symL import SymmetricPowerLFunction self.S = SymmetricPowerLFunction(self.E, self.m) self.title = "The Symmetric %s $L$-function $L(s,E,\mathrm{sym}^%d)$ of Elliptic Curve Isogeny Class %s" % (ordinal(self.m), self.m, self.label) self.dirichlet_coefficients = self.S._coeffs self.sageLfunction = self.S._construct_L() # Initialize some default values self.coefficient_period = 0 self.degree = self.m + 1 self.Q_fe = self.S._Q_fe self.poles = self.S._poles self.residues = self.S._residues self.mu_fe = self.S._mu_fe self.nu_fe = self.S._nu_fe self.kappa_fe = self.mu_fe self.lambda_fe = self.nu_fe self.sign = self.S.root_number self.motivic_weight = self.m self.selfdual = True self.langlands = True self.texname = "L(s, E, \mathrm{sym}^%d)" % self.m # default name. will be set later, for most L-functions self.texnamecompleteds = "\\Lambda(s,E,\mathrm{sym}^{%d})" % self.S.m # default name. will be set later, for most L-functions self.texnamecompleted1ms = "\\Lambda(1-{s}, E,\mathrm{sym}^{%d})" % self.S.m # default name. will be set later, for most L-functions self.primitive = True # should be changed later self.citation = ' ' self.credit = ' ' self.level = self.S.conductor self.euler = "\\begin{align} L(s,E, \\mathrm{sym}^{%d}) = & \\prod_{p \\nmid %d } \\prod_{j=0}^{%d} \\left(1- \\frac{\\alpha_p^j\\beta_p^{%d-j}}{p^{s}}\\right)^{-1} " % (self.m, self.E.conductor(), self.m, self.m) for p in self.S.bad_primes: poly = self.S.eulerFactor(p) poly_string = " " if len(poly) > 1: poly_string = "\\\\ & \\times (1" if poly[1] != 0: if poly[1] == 1: poly_string += "+%d^{ -s}" % p elif poly[1] == -1: poly_string += "-%d^{- s}" % p elif poly[1] < 0: poly_string += "%d\\ %d^{- s}" % (poly[1], p) else: poly_string += "+%d\\ %d^{- s}" % (poly[1], p) for j in range(2, len(poly)): if poly[j] == 0: continue if poly[j] == 1: poly_string += "%d^{-%d s}" % (p, j) elif poly[j] == -1: poly_string += "-%d^{-%d s}" % (p, j) elif poly[j] < 0: poly_string += "%d \\ %d^{-%d s}" % (poly[j], p, j) else: poly_string += "+%d\\ %d^{-%d s}" % (poly[j], p, j) poly_string += ")^{-1}" self.euler += poly_string self.euler += "\\end{align}"
def createLcalcfile_ver2(self, url): logger.debug("Starting Lcalc") """ Creates the lcalcfile of L, version 1 """ return LfunctionLcalc.createLcalcfile_ver2(self, url)
def __init__(self, **args): constructor_logger(self, args) # Check for compulsory arguments if not 'dbid' in args.keys(): raise KeyError("You have to supply dbid for the L-function of a Maass form") # Initialize default values self.dbName = 'MaassWaveForm' # Set default database self.dbColl = 'HT' # Set default collection # Put the arguments into the object dictionary self.__dict__.update(args) # Fetch the information from the database if self.dbName == 'Lfunction': # Data from Lemurell connection = base.getDBConnection() db = pymongo.database.Database(connection, self.dbName) collection = pymongo.collection.Collection(db, self.dbColl) dbEntry = collection.find_one({'_id': self.dbid}) # Extract the L-function information from the database entry self.__dict__.update(dbEntry) # Kludge to deal with improperly formatted SL or GL in the database # Current database entries only have SL in titles. Note, this # will break for PSL or PGL. Ideally, the database entries # should be changed. self.title = re.sub(r'(?<!\\)SL', r'\SL', self.title) self.title = re.sub(r'(?<!\\)GL', r'\GL', self.title) self.coefficient_period = 0 self.poles = [] self.residues = [] # Extract the L-function information from the lcalfile in the database self.parseLcalcfile_ver1(self.lcalcfile) else: # GL2 data from Then or Stromberg host = base.getDBConnection().host port = base.getDBConnection().port DB = MaassDB(host=host, port=port) logger.debug("count={0}".format(DB.count())) logger.debug(self.dbid) self.mf = WebMaassForm(DB, self.dbid, get_dirichlet_c_only=1) self.group = 'GL2' logger.debug(self.mf.R) logger.debug(self.mf.symmetry) # Extract the L-function information from the Maass form object self.symmetry = self.mf.symmetry self.eigenvalue = float(self.mf.R) self.level = int(self.mf.level) self.charactermodulus = self.level self.weight = int(self.mf.weight) self.characternumber = int(self.mf.character) # We now use the Conrey naming scheme for characters # in Maas forms too. # if self.characternumber <> 1: # raise KeyError, 'TODO L-function of Maass form with non-trivial character not implemented. ' if self.level > 1: try: self.fricke = self.mf.cusp_evs[1] logger.info("Fricke: {0}".format(self.fricke)) except: raise KeyError('No Fricke information available for Maass form so not able to compute the L-function. ') else: # no fricke for level 1 self.fricke = 1 # Todo: If self has dimension >1, link to specific L-functions self.dirichlet_coefficients = self.mf.coeffs if self.dirichlet_coefficients[0] == 0: self.dirichlet_coefficients.pop(0) # Set properties of the L-function self.coefficient_type = 2 self.selfdual = True self.primitive = True self.quasidegree = 2 self.Q_fe = float(sqrt(self.level)) / float(math.pi) logger.debug("Symmetry: {0}".format(self.symmetry)) if self.symmetry == "odd" or self.symmetry == 1: self.sign = -1 aa = 1 else: self.sign = 1 aa = 0 logger.debug("Sign (without Fricke): {0}".format(self.sign)) if self.level > 1: self.sign = self.fricke * self.sign logger.debug("Sign: {0}".format(self.sign)) self.kappa_fe = [0.5, 0.5] self.lambda_fe = [0.5 * aa + self.eigenvalue * I / 2, 0.5 * aa - self.eigenvalue * I / 2] self.mu_fe = [aa + self.eigenvalue * I, aa - self.eigenvalue * I] self.nu_fe = [] self.langlands = True self.degree = 2 self.poles = [] self.residues = [] self.coefficient_period = 0 self.checkselfdual() self.texname = "L(s,f)" self.texnamecompleteds = "\\Lambda(s,f)" if self.selfdual: self.texnamecompleted1ms = "\\Lambda(1-s,f)" else: self.texnamecompleted1ms = "\\Lambda(1-s,\\overline{f})" if self.characternumber != 1: characterName = " character \(\chi_{%s}(%s,\cdot)\)" % (self.level, self.characternumber) else: characterName = " trivial character" self.title = "$L(s,f)$, where $f$ is a Maass cusp form with level %s, eigenvalue %s, and %s" % ( self.level, self.eigenvalue, characterName) self.citation = '' self.credit = '' self.generateSageLfunction()
def __init__(self, **args): # Check for compulsory arguments if not ('weight' in args.keys() and 'level' in args.keys()): raise KeyError("You have to supply weight and level for an elliptic modular form L-function") logger.debug(str(args)) self.addToLink = '' # This is to take care of the case where character and/or label is not given # Initialize default values if not args['character']: args['character'] = 0 # Trivial character is default self.addToLink = '/0' if not args['label']: args['label'] = 'a' # No label, is OK If space is one-dimensional self.addToLink += '/a' if not args['number']: args['number'] = 0 # Default choice of embedding of the coefficients self.addToLink += '/0' modform_translation_limit = 101 # Put the arguments into the object dictionary self.__dict__.update(args) # logger.debug(str(self.character)+str(self.label)+str(self.number)) self.weight = int(self.weight) self.motivic_weight = 1 self.level = int(self.level) self.character = int(self.character) # if self.character > 0: # raise KeyError, "The L-function of a modular form with non-trivial # character has not been implemented yet." self.number = int(self.number) # Create the modular form try: self.MF = WebNewForm(self.weight, self.level, self.character, self.label, verbose=1) except: raise KeyError("No data available yet for this modular form, so" + " not able to compute it's L-function") # Extract the L-function information from the elliptic modular form self.automorphyexp = float(self.weight - 1) / float(2) self.Q_fe = float(sqrt(self.level) / (2 * math.pi)) # logger.debug("ALeigen: " + str(self.MF.atkin_lehner_eigenvalues())) self.kappa_fe = [1] self.lambda_fe = [self.automorphyexp] self.mu_fe = [] self.nu_fe = [Rational(str(self.weight - 1) + '/2')] self.selfdual = True self.langlands = True self.primitive = True self.degree = 2 self.poles = [] self.residues = [] self.numcoeff = 20 + int(5 * math.ceil( self.weight * sqrt(self.level))) # just testing NB: Need to learn how to use more coefficients self.algebraic_coefficients = [] # Get the data for the corresponding elliptic curve if possible if self.level <= modform_translation_limit and self.weight == 2: self.ellipticcurve = EC_from_modform(self.level, self.label) self.nr_of_curves_in_class = nr_of_EC_in_isogeny_class(self.ellipticcurve) else: self.ellipticcurve = False # Appending list of Dirichlet coefficients GaloisDegree = self.MF.degree() # number of forms in the Galois orbit # logger.debug("Galois degree: " + str(GaloisDegree)) if GaloisDegree == 1: self.algebraic_coefficients = self.MF.q_expansion_embeddings( self.numcoeff + 1)[1:self.numcoeff + 1] # when coeffs are rational, q_expansion_embedding() # is the list of Fourier coefficients self.coefficient_type = 2 # In this case, the L-function also comes from an elliptic curve. We tell that to lcalc, even if the coefficients are not produced using the elliptic curve else: # logger.debug("Start computing coefficients.") embeddings = self.MF.q_expansion_embeddings(self.numcoeff + 1) for n in range(1, self.numcoeff + 1): self.algebraic_coefficients.append(embeddings[n][self.number]) self.coefficient_type = 0 # In this case the coefficients are neither periodic nor coming from an elliptic curve # logger.debug("Done computing coefficients.") self.dirichlet_coefficients = [] for n in range(1, len(self.algebraic_coefficients) + 1): self.dirichlet_coefficients.append( self.algebraic_coefficients[n - 1] / float(n ** self.automorphyexp)) if self.level == 1: # For level 1, the sign is always plus self.sign = 1 else: # for level not 1, calculate sign from Fricke involution and weight if self.character > 0: self.sign = signOfEmfLfunction(self.level, self.weight, self.algebraic_coefficients) else: self.sign = self.MF.atkin_lehner_eigenvalues()[self.level] * (-1) ** (float(self.weight / 2)) # logger.debug("Sign: " + str(self.sign)) self.coefficient_period = 0 self.quasidegree = 1 self.checkselfdual() self.texname = "L(s,f)" self.texnamecompleteds = "\\Lambda(s,f)" if self.selfdual: self.texnamecompleted1ms = "\\Lambda(1-s,f)" else: self.texnamecompleted1ms = "\\Lambda(1-s,\\overline{f})" if self.character != 0: characterName = " character \(%s\)" % (self.MF.conrey_character_name()) else: characterName = " trivial character" self.title = "$L(s,f)$, where $f$ is a holomorphic cusp form with weight %s, level %s, and %s" % ( self.weight, self.level, characterName) self.citation = '' self.credit = '' self.generateSageLfunction() constructor_logger(self, args)