def field_label(F, pretty=True, check=False): r""" Returns the LMFDB label of the field F. """ if F.absolute_degree() == 1: p = 'x' else: pp = F.absolute_polynomial() x = pp.parent().gen() p = str(pp).replace(str(x), 'x') l = poly_to_field_label(p) if l is None: if check: return False else: if pretty: return web_latex_split_on_pm(pp) else: return pp else: if check: return True if pretty: return field_pretty(l) else: return l
def field_label(F, pretty = True, check=False): r""" Returns the LMFDB label of the field F. """ if F.absolute_degree() == 1: p = 'x' else: pp = F.absolute_polynomial() x = pp.parent().gen() p = str(pp).replace(str(x), 'x') l = poly_to_field_label(p) if l is None: if check: return False else: if pretty: return web_latex_split_on_pm(pp) else: return pp else: if check: return True if pretty: return field_pretty(l) else: return l
def modular_form_display(label, number): try: number = int(number) except: number = 10 if number < 10: number = 10 # if number > 100000: # number = 20 # if number > 50000: # return "OK, I give up." # if number > 20000: # return "This incident will be reported to the appropriate authorities." # if number > 9600: # return "You have been banned from this website." # if number > 4800: # return "Seriously." # if number > 2400: # return "I mean it." # if number > 1200: # return "Please stop poking me." if number > 1000: number = 1000 C = lmfdb.base.getDBConnection() data = C.elliptic_curves.curves.find_one({'lmfdb_label': label}) if data is None: return elliptic_curve_jump_error(label, {}) ainvs = [int(a) for a in data['ainvs']] E = EllipticCurve(ainvs) modform = E.q_eigenform(number) modform_string = web_latex_split_on_pm(modform) return modform_string
def modular_form_display(label, number): try: number = int(number) except: number = 10 if number < 10: number = 10 # if number > 100000: # number = 20 # if number > 50000: # return "OK, I give up." # if number > 20000: # return "This incident will be reported to the appropriate authorities." # if number > 9600: # return "You have been banned from this website." # if number > 4800: # return "Seriously." # if number > 2400: # return "I mean it." # if number > 1200: # return "Please stop poking me." if number > 1000: number = 1000 data = db_ec().find_one({'lmfdb_label': label}) if data is None: return elliptic_curve_jump_error(label, {}) ainvs = [int(a) for a in data['ainvs']] E = EllipticCurve(ainvs) modform = E.q_eigenform(number) modform_string = web_latex_split_on_pm(modform) return modform_string
def make_torsion_growth(self): try: tor_gro = self.tor_gro self.torsion_growth_data_exists = True except AttributeError: self.torsion_growth_data_exists = False return self.tg = tg = {} tg['data'] = tgextra = [] # find all base-changes of this curve in the database, if any from lmfdb.ecnf.WebEllipticCurve import db_ecnf bcs = [ res['label'] for res in db_ecnf().find({'base_change': self.lmfdb_label}, projection={ 'label': True, '_id': False }) ] bcfs = [lab.split("-")[0] for lab in bcs] for F, T in tor_gro.items(): tg1 = {} tg1['bc'] = "Not in database" if ":" in F: F = F.replace(":", ".") field_data = nf_display_knowl(F, getDBConnection(), field_pretty(F)) deg = int(F.split(".")[0]) bcc = [x for x, y in zip(bcs, bcfs) if y == F] if bcc: from lmfdb.ecnf.main import split_full_label F, NN, I, C = split_full_label(bcc[0]) tg1['bc'] = bcc[0] tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C) else: field_data = web_latex_split_on_pm( coeff_to_poly(string2list(F))) deg = F.count(",") tg1['d'] = deg tg1['f'] = field_data tg1['t'] = '\(' + ' \\times '.join( ['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)' tg1['m'] = 0 tgextra.append(tg1) tgextra.sort(key=lambda x: x['d']) tg['n'] = len(tgextra) lastd = 1 for tg1 in tgextra: d = tg1['d'] if d != lastd: tg1['m'] = len([x for x in tgextra if x['d'] == d]) lastd = d tg['maxd'] = max(db_ecstats().find_one({'_id': 'torsion_growth'})['degrees'])
def test_web_latex_split_on_pm(self): r""" Checking utility: web_latex_split_on_pm """ x = var('x') f = x**2 + 1 expected = '\\(x^{2} \\) \\(\\mathstrut +\\mathstrut 1 \\)' self.assertEqual(web_latex_split_on_pm(f), expected)
def make_torsion_growth(self): if self.tor_gro is None: self.torsion_growth_data_exists = False return tor_gro = self.tor_gro self.torsion_growth_data_exists = True self.tg = tg = {} tg['data'] = tgextra = [] # find all base-changes of this curve in the database, if any bcs = list( db.ec_nfcurves.search( {'base_change': { '$contains': [self.lmfdb_label] }}, projection='label')) bcfs = [lab.split("-")[0] for lab in bcs] for F, T in tor_gro.items(): tg1 = {} tg1['bc'] = "Not in database" if ":" in F: F = F.replace(":", ".") field_data = nf_display_knowl(F, field_pretty(F)) deg = int(F.split(".")[0]) bcc = [x for x, y in zip(bcs, bcfs) if y == F] if bcc: from lmfdb.ecnf.main import split_full_label F, NN, I, C = split_full_label(bcc[0]) tg1['bc'] = bcc[0] tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C) else: field_data = web_latex_split_on_pm( coeff_to_poly(string2list(F))) deg = F.count(",") tg1['d'] = deg tg1['f'] = field_data tg1['t'] = '\(' + ' \\times '.join( ['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)' tg1['m'] = 0 tgextra.append(tg1) tgextra.sort(key=lambda x: x['d']) tg['n'] = len(tgextra) lastd = 1 for tg1 in tgextra: d = tg1['d'] if d != lastd: tg1['m'] = len([x for x in tgextra if x['d'] == d]) lastd = d ## Hard code for now #tg['maxd'] = max(db.ec_curves.stats.get_oldstat('torsion_growth')['degrees']) tg['maxd'] = 7
def q_expansion(self, prec_max=10): # Display the q-expansion, truncating to precision prec_max. Will be inside \( \). if self.has_exact_qexp: prec = min(self.qexp_prec, prec_max) if self.dim == 1: s = web_latex_split_on_pm(web_latex(coeff_to_power_series([self.qexp[n][0] for n in range(prec)],prec=prec),enclose=False)) else: s = self.eigs_as_seqseq_to_qexp(prec) return s else: return coeff_to_power_series([0,1], prec=2)._latex_()
def extend_from_db(self): setattr(self._value, "lmfdb_label", self._db_value) if not self._db_value is None and self._db_value != '': try: url = url_for("number_fields.by_label", label=self._db_value) except RuntimeError: emf_logger.critical("could not set url for the label") url = '' setattr(self._value, "lmfdb_url",url) setattr(self._value, "lmfdb_pretty", field_pretty(self._db_value)) else: setattr(self._value, "lmfdb_pretty", web_latex_split_on_pm(self._value.absolute_polynomial()))
def extend_from_db(self): setattr(self._value, "lmfdb_label", self._db_value) if not self._db_value is None and self._db_value != '': try: url = url_for("number_fields.by_label", label=self._db_value) except RuntimeError: emf_logger.critical("could not set url for the label") url = '' setattr(self._value, "lmfdb_url", url) setattr(self._value, "lmfdb_pretty", field_pretty(self._db_value)) else: setattr(self._value, "lmfdb_pretty", web_latex_split_on_pm(self._value.absolute_polynomial()))
def make_torsion_growth(self): if self.tor_gro is None: self.torsion_growth_data_exists = False return tor_gro = self.tor_gro self.torsion_growth_data_exists = True self.tg = tg = {} tg['data'] = tgextra = [] # find all base-changes of this curve in the database, if any bcs = list(db.ec_nfcurves.search({'base_change': {'$contains': [self.lmfdb_label]}}, projection='label')) bcfs = [lab.split("-")[0] for lab in bcs] for F, T in tor_gro.items(): tg1 = {} tg1['bc'] = "Not in database" if ":" in F: F = F.replace(":",".") field_data = nf_display_knowl(F, field_pretty(F)) deg = int(F.split(".")[0]) bcc = [x for x,y in zip(bcs, bcfs) if y==F] if bcc: from lmfdb.ecnf.main import split_full_label F, NN, I, C = split_full_label(bcc[0]) tg1['bc'] = bcc[0] tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C) else: field_data = web_latex_split_on_pm(coeff_to_poly(string2list(F))) deg = F.count(",") tg1['d'] = deg tg1['f'] = field_data tg1['t'] = '\(' + ' \\times '.join(['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)' tg1['m'] = 0 tgextra.append(tg1) tgextra.sort(key = lambda x: x['d']) tg['n'] = len(tgextra) lastd = 1 for tg1 in tgextra: d = tg1['d'] if d!=lastd: tg1['m'] = len([x for x in tgextra if x['d']==d]) lastd = d ## Hard-code this for now. While something like ## max(db.ec_curves.search({},projection='tor_degs')) might ## work, since 'tor_degs' is in the extra table it is very ## slow. Note that the *only* place where this number is used ## is in the ec-curve template where it says "The number ## fields ... of degree up to {{data.tg.maxd}} such that...". tg['maxd'] = 7
def modular_form_display(label, number): try: number = int(number) except ValueError: number = 10 if number < 10: number = 10 if number > 1000: number = 1000 ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label') if ainvs is None: return elliptic_curve_jump_error(label, {}) E = EllipticCurve(ainvs) modform = E.q_eigenform(number) modform_string = web_latex_split_on_pm(modform) return modform_string
def modular_form_display(label, number): try: number = int(number) except ValueError: number = 10 if number < 10: number = 10 if number > 1000: number = 1000 data = db_ec().find_one({'lmfdb_label': label}) if data is None: return elliptic_curve_jump_error(label, {}) E = EllipticCurve(parse_ainvs(data['xainvs'])) modform = E.q_eigenform(number) modform_string = web_latex_split_on_pm(modform) return modform_string
def make_torsion_growth(self): try: tor_gro = self.tor_gro self.torsion_growth_data_exists = True except AttributeError: self.torsion_growth_data_exists = False return self.tg = tg = {} tg['data'] = tgextra = [] # find all base-changes of this curve in the database, if any from lmfdb.ecnf.WebEllipticCurve import db_ecnf bcs = [res['label'] for res in db_ecnf().find({'base_change': self.lmfdb_label}, projection={'label': True, '_id': False})] bcfs = [lab.split("-")[0] for lab in bcs] for F, T in tor_gro.items(): tg1 = {} tg1['bc'] = "Not in database" if ":" in F: F = F.replace(":",".") field_data = nf_display_knowl(F, getDBConnection(), field_pretty(F)) deg = int(F.split(".")[0]) bcc = [x for x,y in zip(bcs, bcfs) if y==F] if bcc: from lmfdb.ecnf.main import split_full_label F, NN, I, C = split_full_label(bcc[0]) tg1['bc'] = bcc[0] tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C) else: field_data = web_latex_split_on_pm(coeff_to_poly(string2list(F))) deg = F.count(",") tg1['d'] = deg tg1['f'] = field_data tg1['t'] = '\(' + ' \\times '.join(['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)' tg1['m'] = 0 tgextra.append(tg1) tgextra.sort(key = lambda x: x['d']) tg['n'] = len(tgextra) lastd = 1 for tg1 in tgextra: d = tg1['d'] if d!=lastd: tg1['m'] = len([x for x in tgextra if x['d']==d]) lastd = d tg['maxd'] = max(db_ecstats().find_one({'_id': 'torsion_growth'})['degrees'])
def make_torsion_growth(self): if self.tor_gro is None: self.torsion_growth_data_exists = False return tor_gro = self.tor_gro self.torsion_growth_data_exists = True self.tg = tg = {} tg['data'] = tgextra = [] # find all base-changes of this curve in the database, if any bcs = list(db.ec_nfcurves.search({'base_change': {'$contains': [self.lmfdb_label]}}, projection='label')) bcfs = [lab.split("-")[0] for lab in bcs] for F, T in tor_gro.items(): tg1 = {} tg1['bc'] = "Not in database" if ":" in F: F = F.replace(":",".") field_data = nf_display_knowl(F, field_pretty(F)) deg = int(F.split(".")[0]) bcc = [x for x,y in zip(bcs, bcfs) if y==F] if bcc: from lmfdb.ecnf.main import split_full_label F, NN, I, C = split_full_label(bcc[0]) tg1['bc'] = bcc[0] tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C) else: field_data = web_latex_split_on_pm(coeff_to_poly(string2list(F))) deg = F.count(",") tg1['d'] = deg tg1['f'] = field_data tg1['t'] = '\(' + ' \\times '.join(['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)' tg1['m'] = 0 tgextra.append(tg1) tgextra.sort(key = lambda x: x['d']) tg['n'] = len(tgextra) lastd = 1 for tg1 in tgextra: d = tg1['d'] if d!=lastd: tg1['m'] = len([x for x in tgextra if x['d']==d]) lastd = d ## Hard code for now #tg['maxd'] = max(db.ec_curves.stats.get_oldstat('torsion_growth')['degrees']) tg['maxd'] = 7
def web_latex_poly(pol, name='x', keepzeta=False): """ Change the name of the variable in a polynomial. If keepzeta, then don't change the name of zetaN in the defining polynomial of a cyclotomic field. (keepzeta not implemented yet) """ # the next few lines were adapted from the lines after line 117 of web_newforms.py oldname = latex(pol.parent().gen()) subfrom = oldname.strip() subfrom = subfrom.replace("\\","\\\\") subfrom = subfrom.replace("{","\\{") # because x_{0} means somethgn in a regular expression if subfrom[0].isalpha(): subfrom = "\\b" + subfrom subto = name.replace("\\","\\\\") subto += " " # print "converting from",subfrom,"to", subto, "of", latex(pol) newpol = re.sub(subfrom, subto, latex(pol)) # print "result is",newpol return web_latex_split_on_pm(newpol)
def display_hecke_cutters(self): polynomials = [] truncated = False for p,F in self.hecke_cutters: cut = len(F) - 1 count = 0 while cut >= 0 and count < 8: if F[cut]: count += 1 cut -= 1 if count < 8 or cut == 0 and abs(F[0]) < 100: F = latex(coeff_to_poly(F, 'T%s'%p)) else: # truncate to the first 8 nonzero coefficients F = [0]*(cut+1) + F[cut+1:] F = latex(coeff_to_poly(F, 'T%s'%p)) + r' + \cdots' truncated = True polynomials.append(web_latex_split_on_pm(F)) title = 'linear operator' if len(polynomials) > 1: title += 's' knowl = display_knowl('mf.elliptic.hecke_cutter', title=title) desc = "<p>This newform can be constructed as the " if truncated or len(polynomials) > 1: if len(polynomials) > 1: desc += "intersection of the kernels " else: desc += "kernel " desc += "of the following %s acting on %s:</p>\n<table>" desc = desc % (knowl, self.display_newspace()) desc += "\n".join("<tr><td>%s</td></tr>" % F for F in polynomials) + "\n</table>" elif len(polynomials) == 1: desc += "kernel of the %s %s acting on %s." desc = desc % (knowl, polynomials[0], self.display_newspace()) else: desc = r"<p>There are no other newforms in %s.</p>"%(self.display_newspace()) return desc
def print_q_expansion(list): list=[str(c) for c in list] Qb=PolynomialRing(QQ,'b') Qq=PowerSeriesRing(Qb['a'],'q') return web_latex_split_on_pm(Qq([c for c in list]).add_bigoh(len(list)))
def render_field_webpage(args): data = None C = base.getDBConnection() info = {} bread = [('Global Number Fields', url_for(".number_field_render_webpage"))] # This function should not be called unless label is set. label = clean_input(args['label']) nf = WebNumberField(label) data = {} if nf.is_null(): bread.append(('Search results', ' ')) info['err'] = 'There is no field with label %s in the database' % label info['label'] = args['label_orig'] if 'label_orig' in args else args['label'] return search_input_error(info, bread) info['wnf'] = nf data['degree'] = nf.degree() data['class_number'] = nf.class_number() t = nf.galois_t() n = nf.degree() data['is_galois'] = nf.is_galois() data['is_abelian'] = nf.is_abelian() if nf.is_abelian(): conductor = nf.conductor() data['conductor'] = conductor dirichlet_chars = nf.dirichlet_group() if len(dirichlet_chars)>0: data['dirichlet_group'] = ['<a href = "%s">$\chi_{%s}(%s,·)$</a>' % (url_for('characters.render_Dirichletwebpage',modulus=data['conductor'], number=j), data['conductor'], j) for j in dirichlet_chars] data['dirichlet_group'] = r'$\lbrace$' + ', '.join(data['dirichlet_group']) + r'$\rbrace$' if data['conductor'].is_prime() or data['conductor'] == 1: data['conductor'] = "\(%s\)" % str(data['conductor']) else: data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), latex(data['conductor'].factor())) data['galois_group'] = group_display_knowl(n, t, C) data['cclasses'] = cclasses_display_knowl(n, t, C) data['character_table'] = character_table_display_knowl(n, t, C) data['class_group'] = nf.class_group() data['class_group_invs'] = nf.class_group_invariants() data['signature'] = nf.signature() data['coefficients'] = nf.coeffs() nf.make_code_snippets() D = nf.disc() ram_primes = D.prime_factors() data['disc_factor'] = nf.disc_factored_latex() if D.abs().is_prime() or D == 1: data['discriminant'] = "\(%s\)" % str(D) else: data['discriminant'] = "\(%s=%s\)" % (str(D), data['disc_factor']) npr = len(ram_primes) ram_primes = str(ram_primes)[1:-1] if ram_primes == '': ram_primes = r'\textrm{None}' data['frob_data'], data['seeram'] = frobs(nf) data['phrase'] = group_phrase(n, t, C) zk = nf.zk() Ra = PolynomialRing(QQ, 'a') zk = [latex(Ra(x)) for x in zk] zk = ['$%s$' % x for x in zk] zk = ', '.join(zk) grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh() else '' # Short version for properties grh_lab = nf.short_grh_string() if 'Not' in str(data['class_number']): grh_lab='' grh_label='' pretty_label = field_pretty(label) if label != pretty_label: pretty_label = "%s: %s" % (label, pretty_label) info.update(data) if nf.degree() > 1: gpK = nf.gpK() rootof1coeff = gpK.nfrootsof1()[2] rootofunity = Ra(str(pari("lift(%s)" % gpK.nfbasistoalg(rootof1coeff))).replace('x','a')) else: rootofunity = Ra('-1') info.update({ 'label': pretty_label, 'label_raw': label, 'polynomial': web_latex_split_on_pm(nf.poly()), 'ram_primes': ram_primes, 'integral_basis': zk, 'regulator': web_latex(nf.regulator()), 'unit_rank': nf.unit_rank(), 'root_of_unity': web_latex(rootofunity), 'fund_units': nf.units(), 'grh_label': grh_label }) bread.append(('%s' % info['label_raw'], ' ')) info['downloads_visible'] = True info['downloads'] = [('worksheet', '/')] info['friends'] = [] if nf.can_class_number(): # hide ones that take a lond time to compute on the fly # note that the first degree 4 number field missed the zero of the zeta function if abs(D**n) < 50000000: info['friends'].append(('L-function', "/L/NumberField/%s" % label)) info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t))) if 'dirichlet_group' in info: info['friends'].append(('Dirichlet group', url_for("characters.dirichlet_group_table", modulus=int(conductor), char_number_list=','.join( [str(a) for a in dirichlet_chars]), poly=info['polynomial']))) info['learnmore'] = [('Global number field labels', url_for( ".render_labels_page")), (Completename, url_for(".render_discriminants_page")), ('How data was computed', url_for(".how_computed_page"))] if info['signature'] == [0,1]: info['learnmore'].append(('Quadratic imaginary class groups', url_for(".render_class_group_data"))) # With Galois group labels, probably not needed here # info['learnmore'] = [('Global number field labels', # url_for(".render_labels_page")), ('Galois group # labels',url_for(".render_groups_page")), # (Completename,url_for(".render_discriminants_page"))] title = "Global Number Field %s" % info['label'] if npr == 1: primes = 'prime' else: primes = 'primes' properties2 = [('Label', label), ('Degree', '%s' % data['degree']), ('Signature', '$%s$' % data['signature']), ('Discriminant', '$%s$' % data['disc_factor']), ('Ramified ' + primes + '', '$%s$' % ram_primes), ('Class number', '%s %s' % (data['class_number'], grh_lab)), ('Class group', '%s %s' % (data['class_group_invs'], grh_lab)), ('Galois Group', group_display_short(data['degree'], t, C)) ] from lmfdb.math_classes import NumberFieldGaloisGroup try: info["tim_number_field"] = NumberFieldGaloisGroup(nf._data['coeffs']) v = nf.factor_perm_repn(info["tim_number_field"]) def dopow(m): if m==0: return '' if m==1: return '*' return '*<sup>%d</sup>'% m info["mydecomp"] = [dopow(x) for x in v] except AttributeError: pass # del info['_id'] return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, code=nf.code, friends=info.pop('friends'), learnmore=info.pop('learnmore'), info=info)
def print_q_expansion(list): list=[str(c) for c in list] Qa=PolynomialRing(QQ,'a') Qq=PowerSeriesRing(Qa,'q') return web_latex_split_on_pm(Qq([c for c in list]).add_bigoh(len(list)))
def nfpol(self): #return self.nf.web_poly() return web_latex_split_on_pm(self.k.polynomial())
def trace_expansion(self, prec_max=10): prec = min(len(self.traces)+1, prec_max) return web_latex_split_on_pm(web_latex(coeff_to_power_series([0] + self.traces[:prec-1],prec=prec),enclose=False))
def render_field_webpage(args): data = None info = {} bread = [('Global Number Fields', url_for(".number_field_render_webpage"))] # This function should not be called unless label is set. label = clean_input(args['label']) nf = WebNumberField(label) data = {} if nf.is_null(): bread.append(('Search Results', ' ')) info['err'] = 'There is no field with label %s in the database' % label info['label'] = args['label_orig'] if 'label_orig' in args else args['label'] return search_input_error(info, bread) info['wnf'] = nf data['degree'] = nf.degree() data['class_number'] = nf.class_number_latex() ram_primes = nf.ramified_primes() t = nf.galois_t() n = nf.degree() data['is_galois'] = nf.is_galois() data['is_abelian'] = nf.is_abelian() if nf.is_abelian(): conductor = nf.conductor() data['conductor'] = conductor dirichlet_chars = nf.dirichlet_group() if len(dirichlet_chars)>0: data['dirichlet_group'] = ['<a href = "%s">$\chi_{%s}(%s,·)$</a>' % (url_for('characters.render_Dirichletwebpage',modulus=data['conductor'], number=j), data['conductor'], j) for j in dirichlet_chars] data['dirichlet_group'] = r'$\lbrace$' + ', '.join(data['dirichlet_group']) + r'$\rbrace$' if data['conductor'].is_prime() or data['conductor'] == 1: data['conductor'] = "\(%s\)" % str(data['conductor']) else: factored_conductor = factor_base_factor(data['conductor'], ram_primes) factored_conductor = factor_base_factorization_latex(factored_conductor) data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), factored_conductor) data['galois_group'] = group_display_knowl(n, t) data['cclasses'] = cclasses_display_knowl(n, t) data['character_table'] = character_table_display_knowl(n, t) data['class_group'] = nf.class_group() data['class_group_invs'] = nf.class_group_invariants() data['signature'] = nf.signature() data['coefficients'] = nf.coeffs() nf.make_code_snippets() D = nf.disc() data['disc_factor'] = nf.disc_factored_latex() if D.abs().is_prime() or D == 1: data['discriminant'] = "\(%s\)" % str(D) else: data['discriminant'] = "\(%s=%s\)" % (str(D), data['disc_factor']) data['frob_data'], data['seeram'] = frobs(nf) # Bad prime information npr = len(ram_primes) ramified_algebras_data = nf.ramified_algebras_data() if isinstance(ramified_algebras_data,str): loc_alg = '' else: # [label, latex, e, f, c, gal] loc_alg = '' for j in range(npr): if ramified_algebras_data[j] is None: loc_alg += '<tr><td>%s<td colspan="7">Data not computed'%str(ram_primes[j]) else: mydat = ramified_algebras_data[j] p = ram_primes[j] loc_alg += '<tr><td rowspan="%d">$%s$</td>'%(len(mydat),str(p)) mm = mydat[0] myurl = url_for('local_fields.by_label', label=mm[0]) lab = mm[0] if mm[3]*mm[2]==1: lab = r'$\Q_{%s}$'%str(p) loc_alg += '<td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$'%(myurl,lab,mm[1],mm[2],mm[3],mm[4],mm[5],show_slope_content(mm[8],mm[6],mm[7])) for mm in mydat[1:]: lab = mm[0] if mm[3]*mm[2]==1: lab = r'$\Q_{%s}$'%str(p) loc_alg += '<tr><td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$'%(myurl,lab,mm[1],mm[2],mm[3],mm[4],mm[5],show_slope_content(mm[8],mm[6],mm[7])) loc_alg += '</tbody></table>' ram_primes = str(ram_primes)[1:-1] if ram_primes == '': ram_primes = r'\textrm{None}' data['phrase'] = group_phrase(n, t) zk = nf.zk() Ra = PolynomialRing(QQ, 'a') zk = [latex(Ra(x)) for x in zk] zk = ['$%s$' % x for x in zk] zk = ', '.join(zk) grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh() else '' # Short version for properties grh_lab = nf.short_grh_string() if 'Not' in str(data['class_number']): grh_lab='' grh_label='' pretty_label = field_pretty(label) if label != pretty_label: pretty_label = "%s: %s" % (label, pretty_label) info.update(data) if nf.degree() > 1: gpK = nf.gpK() rootof1coeff = gpK.nfrootsof1() rootofunityorder = int(rootof1coeff[1]) rootof1coeff = rootof1coeff[2] rootofunity = web_latex(Ra(str(pari("lift(%s)" % gpK.nfbasistoalg(rootof1coeff))).replace('x','a'))) rootofunity += ' (order $%d$)' % rootofunityorder else: rootofunity = web_latex(Ra('-1'))+ ' (order $2$)' info.update({ 'label': pretty_label, 'label_raw': label, 'polynomial': web_latex_split_on_pm(nf.poly()), 'ram_primes': ram_primes, 'integral_basis': zk, 'regulator': web_latex(nf.regulator()), 'unit_rank': nf.unit_rank(), 'root_of_unity': rootofunity, 'fund_units': nf.units(), 'grh_label': grh_label, 'loc_alg': loc_alg }) bread.append(('%s' % info['label_raw'], ' ')) info['downloads_visible'] = True info['downloads'] = [('worksheet', '/')] info['friends'] = [] if nf.can_class_number(): # hide ones that take a lond time to compute on the fly # note that the first degree 4 number field missed the zero of the zeta function if abs(D**n) < 50000000: info['friends'].append(('L-function', "/L/NumberField/%s" % label)) info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t))) if 'dirichlet_group' in info: info['friends'].append(('Dirichlet character group', url_for("characters.dirichlet_group_table", modulus=int(conductor), char_number_list=','.join( [str(a) for a in dirichlet_chars]), poly=info['polynomial']))) resinfo=[] galois_closure = nf.galois_closure() if galois_closure[0]>0: if len(galois_closure[1])>0: resinfo.append(('gc', galois_closure[1])) if len(galois_closure[2]) > 0: info['friends'].append(('Galois closure',url_for(".by_label", label=galois_closure[2][0]))) else: resinfo.append(('gc', [dnc])) sextic_twins = nf.sextic_twin() if sextic_twins[0]>0: if len(sextic_twins[1])>0: resinfo.append(('sex', r' $\times$ '.join(sextic_twins[1]))) else: resinfo.append(('sex', dnc)) siblings = nf.siblings() # [degsib list, label list] # first is list of [deg, num expected, list of knowls] if len(siblings[0])>0: for sibdeg in siblings[0]: if len(sibdeg[2]) ==0: sibdeg[2] = dnc else: sibdeg[2] = ', '.join(sibdeg[2]) if len(sibdeg[2])<sibdeg[1]: sibdeg[2] += ', some '+dnc resinfo.append(('sib', siblings[0])) for lab in siblings[1]: if lab != '': labparts = lab.split('.') info['friends'].append(("Degree %s sibling"%labparts[0] ,url_for(".by_label", label=lab))) arith_equiv = nf.arith_equiv() if arith_equiv[0]>0: if len(arith_equiv[1])>0: resinfo.append(('ae', ', '.join(arith_equiv[1]), len(arith_equiv[1]))) for aelab in arith_equiv[2]: info['friends'].append(('Arithmetically equivalent sibling',url_for(".by_label", label=aelab))) else: resinfo.append(('ae', dnc, len(arith_equiv[1]))) info['resinfo'] = resinfo learnmore = learnmore_list() #if info['signature'] == [0,1]: # info['learnmore'].append(('Quadratic imaginary class groups', url_for(".render_class_group_data"))) # With Galois group labels, probably not needed here # info['learnmore'] = [('Global number field labels', # url_for(".render_labels_page")), ('Galois group # labels',url_for(".render_groups_page")), # (Completename,url_for(".render_discriminants_page"))] title = "Global Number Field %s" % info['label'] if npr == 1: primes = 'prime' else: primes = 'primes' properties2 = [('Label', label), ('Degree', '$%s$' % data['degree']), ('Signature', '$%s$' % data['signature']), ('Discriminant', '$%s$' % data['disc_factor']), ('Ramified ' + primes + '', '$%s$' % ram_primes), ('Class number', '%s %s' % (data['class_number'], grh_lab)), ('Class group', '%s %s' % (data['class_group_invs'], grh_lab)), ('Galois Group', group_display_short(data['degree'], t)) ] downloads = [] for lang in [["Magma","magma"], ["SageMath","sage"], ["Pari/GP", "gp"]]: downloads.append(('Download {} code'.format(lang[0]), url_for(".nf_code_download", nf=label, download_type=lang[1]))) from lmfdb.artin_representations.math_classes import NumberFieldGaloisGroup try: info["tim_number_field"] = NumberFieldGaloisGroup(nf._data['coeffs']) v = nf.factor_perm_repn(info["tim_number_field"]) def dopow(m): if m==0: return '' if m==1: return '*' return '*<sup>%d</sup>'% m info["mydecomp"] = [dopow(x) for x in v] except AttributeError: pass return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, code=nf.code, friends=info.pop('friends'), downloads=downloads, learnmore=learnmore, info=info)
def defining_polynomial(self): if self.field_poly: return web_latex_split_on_pm(web_latex(coeff_to_poly(self.field_poly), enclose=False)) return None
def make_curve(self): # To start with the data fields of self are just those from # the database. We need to reformat these. # Old version: required constructing the actual elliptic curve # E, and computing some further data about it. # New version (May 2016): extra data fields now in the # database so we do not have to construct the curve or do any # computation with it on the fly. As a failsafe the old way # is still included. data = self.data = {} try: data['ainvs'] = [int(c) for c in self.xainvs[1:-1].split(',')] except AttributeError: data['ainvs'] = [int(ai) for ai in self.ainvs] data['conductor'] = N = ZZ(self.conductor) data['j_invariant'] = QQ(str(self.jinv)) data['j_inv_factor'] = latex(0) if data['j_invariant']: # don't factor 0 data['j_inv_factor'] = latex(data['j_invariant'].factor()) data['j_inv_str'] = unicode(str(data['j_invariant'])) data['j_inv_latex'] = web_latex(data['j_invariant']) mw = self.mw = {} mw['rank'] = self.rank mw['int_points'] = '' if self.xintcoords: a1, a2, a3, a4, a6 = [ZZ(a) for a in data['ainvs']] def lift_x(x): f = ((x + a2) * x + a4) * x + a6 b = (a1 * x + a3) d = (b * b + 4 * f).sqrt() return (x, (-b + d) / 2) mw['int_points'] = ', '.join( web_latex(lift_x(x)) for x in self.xintcoords) mw['generators'] = '' mw['heights'] = [] if self.gens: mw['generators'] = [ web_latex(tuple(P)) for P in parse_points(self.gens) ] mw['tor_order'] = self.torsion tor_struct = [int(c) for c in self.torsion_structure] if mw['tor_order'] == 1: mw['tor_struct'] = '\mathrm{Trivial}' mw['tor_gens'] = '' else: mw['tor_struct'] = ' \\times '.join( ['\Z/{%s}\Z' % n for n in tor_struct]) mw['tor_gens'] = ', '.join( web_latex(tuple(P)) for P in parse_points(self.torsion_generators)) # try to get all the data we need from the database entry (now in self) try: data['equation'] = self.equation local_data = self.local_data D = self.signD * prod( [ld['p']**ld['ord_disc'] for ld in local_data]) data['disc'] = D Nfac = Factorization([(ZZ(ld['p']), ld['ord_cond']) for ld in local_data]) Dfac = Factorization([(ZZ(ld['p']), ld['ord_disc']) for ld in local_data], unit=ZZ(self.signD)) data['minq_D'] = minqD = self.min_quad_twist['disc'] minq_label = self.min_quad_twist['label'] data['minq_label'] = db_ec().find_one( {'label': minq_label}, ['lmfdb_label'])['lmfdb_label'] data['minq_info'] = '(itself)' if minqD == 1 else '(by %s)' % minqD try: data['degree'] = self.degree except AttributeError: data['degree'] = 0 # invalid, but will be displayed nicely mw['heights'] = self.heights if self.number == 1: data['an'] = self.anlist data['ap'] = self.aplist else: r = db_ec().find_one({ 'lmfdb_iso': self.lmfdb_iso, 'number': 1 }, ['anlist', 'aplist']) data['an'] = r['anlist'] data['ap'] = r['aplist'] # otherwise fall back to computing it from the curve except AttributeError: self.E = EllipticCurve(data['ainvs']) data['equation'] = web_latex(self.E) data['disc'] = D = self.E.discriminant() Nfac = N.factor() Dfac = D.factor() bad_primes = [p for p, e in Nfac] try: data['degree'] = self.degree except AttributeError: try: data['degree'] = self.E.modular_degree() except RuntimeError: data['degree'] = 0 # invalid, but will be displayed nicely minq, minqD = self.E.minimal_quadratic_twist() data['minq_D'] = minqD if minqD == 1: data['minq_label'] = self.lmfdb_label data['minq_info'] = '(itself)' else: # This relies on the minimal twist being in the # database, which is true when the database only # contains the Cremona database. It would be a good # idea if, when the database is extended, we ensured # that for any curve included, all twists of smaller # conductor are also included. minq_ainvs = [str(c) for c in minq.ainvs()] data['minq_label'] = db_ec().find_one( { 'jinv': str(self.E.j_invariant()), 'ainvs': minq_ainvs }, ['lmfdb_label'])['lmfdb_label'] data['minq_info'] = '(by %s)' % minqD if self.gens: self.generators = [self.E(g) for g in parse_points(self.gens)] mw['heights'] = [P.height() for P in self.generators] data['an'] = self.E.anlist(20, python_ints=True) data['ap'] = self.E.aplist(100, python_ints=True) self.local_data = local_data = [] for p in bad_primes: ld = self.E.local_data(p, algorithm="generic") local_data_p = {} local_data_p['p'] = p local_data_p['cp'] = ld.tamagawa_number() local_data_p['kod'] = web_latex(ld.kodaira_symbol()).replace( '$', '') local_data_p['red'] = ld.bad_reduction_type() rootno = -ld.bad_reduction_type() if rootno == 0: rootno = self.E.root_number(p) local_data_p['rootno'] = rootno local_data_p['ord_cond'] = ld.conductor_valuation() local_data_p['ord_disc'] = ld.discriminant_valuation() local_data_p['ord_den_j'] = max( 0, -self.E.j_invariant().valuation(p)) local_data.append(local_data_p) # If we got the data from the database, the root numbers may # not have been stored there, so we have to compute them. If # there are additive primes this means constructing the curve. for ld in self.local_data: if not 'rootno' in ld: rootno = -ld['red'] if rootno == 0: try: E = self.E except AttributeError: self.E = E = EllipticCurve(data['ainvs']) rootno = E.root_number(ld['p']) ld['rootno'] = rootno minq_N, minq_iso, minq_number = split_lmfdb_label(data['minq_label']) data['disc_factor'] = latex(Dfac) data['cond_factor'] = latex(Nfac) data['disc_latex'] = web_latex(D) data['cond_latex'] = web_latex(N) data['galois_images'] = [ trim_galois_image_code(s) for s in self.mod_p_images ] data['non_maximal_primes'] = self.non_maximal_primes data['galois_data'] = [{ 'p': p, 'image': im } for p, im in zip(data['non_maximal_primes'], data['galois_images'])] data['CMD'] = self.cm data['CM'] = "no" data['EndE'] = "\(\Z\)" if self.cm: data['cm_ramp'] = [ p for p in ZZ(self.cm).support() if not p in self.non_surjective_primes ] data['cm_nramp'] = len(data['cm_ramp']) if data['cm_nramp'] == 1: data['cm_ramp'] = data['cm_ramp'][0] else: data['cm_ramp'] = ", ".join([str(p) for p in data['cm_ramp']]) data['cm_sqf'] = ZZ(self.cm).squarefree_part() data['CM'] = "yes (\(D=%s\))" % data['CMD'] if data['CMD'] % 4 == 0: d4 = ZZ(data['CMD']) // 4 data['EndE'] = "\(\Z[\sqrt{%s}]\)" % d4 else: data['EndE'] = "\(\Z[(1+\sqrt{%s})/2]\)" % data['CMD'] data['ST'] = st_link_by_name(1, 2, 'N(U(1))') else: data['ST'] = st_link_by_name(1, 2, 'SU(2)') data['p_adic_primes'] = [ p for i, p in enumerate(prime_range(5, 100)) if (N * data['ap'][i]) % p != 0 ] cond, iso, num = split_lmfdb_label(self.lmfdb_label) self.class_url = url_for(".by_double_iso_label", conductor=N, iso_label=iso) self.one_deg = ZZ(self.class_deg).is_prime() self.ncurves = db_ec().count({'lmfdb_iso': self.lmfdb_iso}) isodegs = [str(d) for d in self.isogeny_degrees if d > 1] if len(isodegs) < 3: data['isogeny_degrees'] = " and ".join(isodegs) else: data['isogeny_degrees'] = " and ".join( [", ".join(isodegs[:-1]), isodegs[-1]]) if self.twoadic_gens: from sage.matrix.all import Matrix data['twoadic_gen_matrices'] = ','.join( [latex(Matrix(2, 2, M)) for M in self.twoadic_gens]) data[ 'twoadic_rouse_url'] = ROUSE_URL_PREFIX + self.twoadic_label + ".html" # Leading term of L-function & BSD data bsd = self.bsd = {} r = self.rank if r >= 2: bsd['lder_name'] = "L^{(%s)}(E,1)/%s!" % (r, r) elif r: bsd['lder_name'] = "L'(E,1)" else: bsd['lder_name'] = "L(E,1)" bsd['reg'] = self.regulator bsd['omega'] = self.real_period bsd['sha'] = int(0.1 + self.sha_an) bsd['lder'] = self.special_value # Optimality (the optimal curve in the class is the curve # whose Cremona label ends in '1' except for '990h' which was # labelled wrongly long ago) if self.iso == '990h': data['Gamma0optimal'] = bool(self.number == 3) else: data['Gamma0optimal'] = bool(self.number == 1) data['p_adic_data_exists'] = False if data['Gamma0optimal']: data['p_adic_data_exists'] = (padic_db().find({ 'lmfdb_iso': self.lmfdb_iso }).count()) > 0 data['iwdata'] = [] try: pp = [int(p) for p in self.iwdata] badp = [l['p'] for l in self.local_data] rtypes = [l['red'] for l in self.local_data] data[ 'iw_missing_flag'] = False # flags that there is at least one "?" in the table data[ 'additive_shown'] = False # flags that there is at least one additive prime in table for p in sorted(pp): rtype = "" if p in badp: red = rtypes[badp.index(p)] # Additive primes are excluded from the table # if red==0: # continue #rtype = ["nsmult","add", "smult"][1+red] rtype = ["nonsplit", "add", "split"][1 + red] p = str(p) pdata = self.iwdata[p] if isinstance(pdata, type(u'?')): if not rtype: rtype = "ordinary" if pdata == "o?" else "ss" if rtype == "add": data['iwdata'] += [[p, rtype, "-", "-"]] data['additive_shown'] = True else: data['iwdata'] += [[p, rtype, "?", "?"]] data['iw_missing_flag'] = True else: if len(pdata) == 2: if not rtype: rtype = "ordinary" lambdas = str(pdata[0]) mus = str(pdata[1]) else: rtype = "ss" lambdas = ",".join([str(pdata[0]), str(pdata[1])]) mus = str(pdata[2]) mus = ",".join([mus, mus]) data['iwdata'] += [[p, rtype, lambdas, mus]] except AttributeError: # For curves with no Iwasawa data pass tamagawa_numbers = [ZZ(ld['cp']) for ld in local_data] cp_fac = [cp.factor() for cp in tamagawa_numbers] cp_fac = [ latex(cp) if len(cp) < 2 else '(' + latex(cp) + ')' for cp in cp_fac ] bsd['tamagawa_factors'] = r'\cdot'.join(cp_fac) bsd['tamagawa_product'] = prod(tamagawa_numbers) # Torsion growth data data['torsion_growth_data_exists'] = False try: tg = self.tor_gro data['torsion_growth_data_exists'] = True data['tgx'] = tgextra = [] # find all base-changes of this curve in the database, if any bcs = [ res['label'] for res in getDBConnection().elliptic_curves.nfcurves.find( {'base_change': self.lmfdb_label}, projection={ 'label': True, '_id': False }) ] bcfs = [lab.split("-")[0] for lab in bcs] for F, T in tg.items(): tg1 = {} tg1['bc'] = "Not in database" if ":" in F: F = F.replace(":", ".") field_data = nf_display_knowl(F, getDBConnection(), field_pretty(F)) deg = int(F.split(".")[0]) bcc = [x for x, y in zip(bcs, bcfs) if y == F] if bcc: from lmfdb.ecnf.main import split_full_label F, NN, I, C = split_full_label(bcc[0]) tg1['bc'] = bcc[0] tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C) else: field_data = web_latex_split_on_pm( coeff_to_poly(string2list(F))) deg = F.count(",") tg1['d'] = deg tg1['f'] = field_data tg1['t'] = '\(' + ' \\times '.join( ['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)' tg1['m'] = 0 tgextra.append(tg1) tgextra.sort(key=lambda x: x['d']) data['ntgx'] = len(tgextra) lastd = 1 for tg in tgextra: d = tg['d'] if d != lastd: tg['m'] = len([x for x in tgextra if x['d'] == d]) lastd = d data['tg_maxd'] = max(db_ecstats().find_one( {'_id': 'torsion_growth'})['degrees']) except AttributeError: pass # we have no torsion growth data data['newform'] = web_latex( PowerSeriesRing(QQ, 'q')(data['an'], 20, check=True)) data['newform_label'] = self.newform_label = newform_label( cond, 2, 1, iso) self.newform_link = url_for("emf.render_elliptic_modular_forms", level=cond, weight=2, character=1, label=iso) self.newform_exists_in_db = is_newform_in_db(self.newform_label) self._code = None self.class_url = url_for(".by_double_iso_label", conductor=N, iso_label=iso) self.friends = [('Isogeny class ' + self.lmfdb_iso, self.class_url), ('Minimal quadratic twist %s %s' % (data['minq_info'], data['minq_label']), url_for(".by_triple_label", conductor=minq_N, iso_label=minq_iso, number=minq_number)), ('All twists ', url_for(".rational_elliptic_curves", jinv=self.jinv)), ('L-function', url_for("l_functions.l_function_ec_page", conductor_label=N, isogeny_class_label=iso))] if not self.cm: if N <= 300: self.friends += [('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', conductor=N, isogeny=iso))] if N <= 50: self.friends += [('Symmetric cube L-function', url_for("l_functions.l_function_ec_sym_page", power='3', conductor=N, isogeny=iso))] if self.newform_exists_in_db: self.friends += [('Modular form ' + self.newform_label, self.newform_link)] self.downloads = [('Download coefficients of q-expansion', url_for(".download_EC_qexp", label=self.lmfdb_label, limit=1000)), ('Download all stored data', url_for(".download_EC_all", label=self.lmfdb_label)), ('Download Magma code', url_for(".ec_code_download", conductor=cond, iso=iso, number=num, label=self.lmfdb_label, download_type='magma')), ('Download Sage code', url_for(".ec_code_download", conductor=cond, iso=iso, number=num, label=self.lmfdb_label, download_type='sage')), ('Download GP code', url_for(".ec_code_download", conductor=cond, iso=iso, number=num, label=self.lmfdb_label, download_type='gp'))] try: self.plot = encode_plot(self.E.plot()) except AttributeError: self.plot = encode_plot(EllipticCurve(data['ainvs']).plot()) self.plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format( self.plot) self.properties = [('Label', self.lmfdb_label), (None, self.plot_link), ('Conductor', '\(%s\)' % data['conductor']), ('Discriminant', '\(%s\)' % data['disc']), ('j-invariant', '%s' % data['j_inv_latex']), ('CM', '%s' % data['CM']), ('Rank', '\(%s\)' % mw['rank']), ('Torsion Structure', '\(%s\)' % mw['tor_struct'])] self.title = "Elliptic Curve %s (Cremona label %s)" % ( self.lmfdb_label, self.label) self.bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('%s' % N, url_for(".by_conductor", conductor=N)), ('%s' % iso, url_for(".by_double_iso_label", conductor=N, iso_label=iso)), ('%s' % num, ' ')]
def render_hmf_webpage(**args): if 'data' in args: data = args['data'] label = data['label'] else: label = str(args['label']) data = get_hmf(label) if data is None: flash(Markup("Error: <span style='color:black'>%s</span> is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a" % args['label']), "error") return search_input_error() info = {} try: info['count'] = args['count'] except KeyError: info['count'] = 50 hmf_field = get_hmf_field(data['field_label']) gen_name = findvar(hmf_field['ideals']) nf = WebNumberField(data['field_label'], gen_name=gen_name) info['hmf_field'] = hmf_field info['field'] = nf info['base_galois_group'] = nf.galois_string() info['field_degree'] = nf.degree() info['field_disc'] = str(nf.disc()) info['field_poly'] = teXify_pol(str(nf.poly())) info.update(data) info['downloads'] = [ ('Modular form to Magma', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='magma')), ('Eigenvalues to Sage', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='sage')) ] # figure out friends # first try to see if there is an instance of this HMF on Lfun db url = 'ModularForm/GL2/TotallyReal/{}/holomorphic/{}'.format( info['field_label'], info['label']) Lfun = get_lfunction_by_url(url) if Lfun: instances = get_instances_by_Lhash_and_trace_hash(Lfun['Lhash'], Lfun['degree'], Lfun['trace_hash']) # This will also add the EC/G2C, as this how the Lfun was computed info['friends'] = names_and_urls(instances, exclude={url}) info['friends'] += [('L-function', url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))] else: # if there is no instance # old code if hmf_field['narrow_class_no'] == 1 and nf.disc()**2 * data['level_norm'] < 40000: info['friends'] = [('L-function', url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))] else: info['friends'] = [('L-function not available', "")] if data['dimension'] == 1: # Try to attach associated elliptic curve lab = split_class_label(info['label']) ec_from_hmf = db.ec_nfcurves.lookup(label + '1') if ec_from_hmf is None: info['friends'] += [('Elliptic curve not available', "")] else: info['friends'] += [('Isogeny class ' + info['label'], url_for("ecnf.show_ecnf_isoclass", nf=lab[0], conductor_label=lab[1], class_label=lab[2]))] bread = [("Modular Forms", url_for('modular_forms')), ('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ('%s' % data['label'], ' ')] t = "Hilbert Cusp Form %s" % info['label'] forms_dims = db.hmf_forms.search({'field_label': data['field_label'], 'level_ideal': data['level_ideal']}, projection='dimension') info['newspace_dimension'] = sum(forms_dims) # Get hecke_polynomial, hecke_eigenvalues and AL_eigenvalues try: numeigs = request.args['numeigs'] numeigs = int(numeigs) except: numeigs = 20 info['numeigs'] = numeigs hecke_pol = data['hecke_polynomial'] eigs = map(str, data['hecke_eigenvalues']) eigs = eigs[:min(len(eigs), numeigs)] AL_eigs = data['AL_eigenvalues'] primes = hmf_field['primes'] n = min(len(eigs), len(primes)) info['eigs'] = [{'eigenvalue': add_space_if_positive(teXify_pol(eigs[i])), 'prime_ideal': teXify_pol(primes[i]), 'prime_norm': primes[i][1:primes[i].index(',')]} for i in range(n)] try: display_eigs = request.args['display_eigs'] if display_eigs in ['True', 'true', '1', 'yes']: display_eigs = True else: display_eigs = False except KeyError: display_eigs = False if 'numeigs' in request.args: display_eigs = True info['hecke_polynomial'] = web_latex_split_on_pm(teXify_pol(hecke_pol)) if not AL_eigs: # empty list if data['level_norm']==1: # OK, no bad primes info['AL_eigs'] = 'none' else: # not OK, AL eigs are missing info['AL_eigs'] = 'missing' else: info['AL_eigs'] = [{'eigenvalue': teXify_pol(al[1]), 'prime_ideal': teXify_pol(al[0]), 'prime_norm': al[0][1:al[0].index(',')]} for al in data['AL_eigenvalues']] max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']]) display_eigs = display_eigs or (max_eig_len<=300) info['display_eigs'] = display_eigs if not display_eigs: for eig in info['eigs']: if len(eig['eigenvalue']) > 300: eig['eigenvalue'] = '...' info['level_ideal'] = teXify_pol(info['level_ideal']) if 'is_CM' in data: is_CM = data['is_CM'] else: is_CM = '?' info['is_CM'] = is_CM if 'is_base_change' in data: is_base_change = data['is_base_change'] else: is_base_change = '?' info['is_base_change'] = is_base_change if 'q_expansions' in data: info['q_expansions'] = data['q_expansions'] properties2 = [('Base field', '%s' % info['field'].field_pretty()), ('Weight', '%s' % data['weight']), ('Level norm', '%s' % data['level_norm']), ('Level', '$' + teXify_pol(data['level_ideal']) + '$'), ('Label', '%s' % data['label']), ('Dimension', '%s' % data['dimension']), ('CM', is_CM), ('Base change', is_base_change) ] return render_template("hilbert_modular_form.html", downloads=info["downloads"], info=info, properties2=properties2, credit=hmf_credit, title=t, bread=bread, friends=info['friends'], learnmore=learnmore_list())
def render_hmf_webpage(**args): if 'data' in args: data = args['data'] label = data['label'] else: label = str(args['label']) data = db_forms().find_one({'label': label}) if data is None: flash(Markup("Error: <span style='color:black'>%s</span> is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a" % args['label']), "error") return search_input_error() info = {} try: info['count'] = args['count'] except KeyError: info['count'] = 10 try: numeigs = request.args['numeigs'] numeigs = int(numeigs) except: numeigs = 20 info['numeigs'] = numeigs hmf_field = db_fields().find_one({'label': data['field_label']}) gen_name = findvar(hmf_field['ideals']) nf = WebNumberField(data['field_label'], gen_name=gen_name) info['hmf_field'] = hmf_field info['field'] = nf info['base_galois_group'] = nf.galois_string() info['field_degree'] = nf.degree() info['field_disc'] = str(nf.disc()) info['field_poly'] = teXify_pol(str(nf.poly())) info.update(data) info['downloads'] = [ ('Download to Magma', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='magma')), ('Download to Sage', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='sage')) ] if hmf_field['narrow_class_no'] == 1 and nf.disc()**2 * data['level_norm'] < 40000: info['friends'] = [('L-function', url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))] else: info['friends'] = [('L-function not available', "")] if data['dimension'] == 1: # Try to attach associated elliptic curve lab = split_class_label(info['label']) ec_from_hmf = db_ecnf().find_one({"label": label + '1'}) if ec_from_hmf == None: info['friends'] += [('Elliptic curve not available', "")] else: info['friends'] += [('Isogeny class ' + info['label'], url_for("ecnf.show_ecnf_isoclass", nf=lab[0], conductor_label=lab[1], class_label=lab[2]))] bread = [('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ('%s' % data[ 'label'], ' ')] t = "Hilbert Cusp Form %s" % info['label'] forms_space = db_search().find( {'field_label': data['field_label'], 'level_ideal': data['level_ideal']},{'dimension':True}) dim_space = 0 for v in forms_space: dim_space += v['dimension'] info['newspace_dimension'] = dim_space eigs = data['hecke_eigenvalues'] eigs = eigs[:min(len(eigs), numeigs)] primes = hmf_field['primes'] n = min(len(eigs), len(primes)) info['eigs'] = [{'eigenvalue': teXify_pol(eigs[i]), 'prime_ideal': teXify_pol(primes[i]), 'prime_norm': primes[i][1:primes[i].index(',')]} for i in range(n)] try: display_eigs = request.args['display_eigs'] if display_eigs in ['True', 'true', '1', 'yes']: display_eigs = True else: display_eigs = False except KeyError: display_eigs = False if 'numeigs' in request.args: display_eigs = True info['hecke_polynomial'] = web_latex_split_on_pm(teXify_pol(info['hecke_polynomial'])) if 'AL_eigenvalues_fixed' in data: if data['AL_eigenvalues_fixed'] == 'done': info['AL_eigs'] = [{'eigenvalue': teXify_pol(al[1]), 'prime_ideal': teXify_pol(al[0]), 'prime_norm': al[0][1:al[0].index(',')]} for al in data['AL_eigenvalues']] else: info['AL_eigs'] = [{'eigenvalue': '?', 'prime_ideal': '?'}] else: info['AL_eigs'] = [{'eigenvalue': '?', 'prime_ideal': '?'}] info['AL_eigs_count'] = len(info['AL_eigs']) != 0 max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']]) display_eigs = display_eigs or (max_eig_len<=300) info['display_eigs'] = display_eigs if not display_eigs: for eig in info['eigs']: if len(eig['eigenvalue']) > 300: eig['eigenvalue'] = '...' for eig in info['AL_eigs']: if len(eig['eigenvalue']) > 300: eig['eigenvalue'] = '...' info['level_ideal'] = teXify_pol(info['level_ideal']) if 'is_CM' in data: is_CM = data['is_CM'] else: is_CM = '?' info['is_CM'] = is_CM if 'is_base_change' in data: is_base_change = data['is_base_change'] else: is_base_change = '?' info['is_base_change'] = is_base_change if 'q_expansions' in data: info['q_expansions'] = data['q_expansions'] properties2 = [('Base field', '%s' % info['field'].field_pretty()), ('Weight', '%s' % data['weight']), ('Level norm', '%s' % data['level_norm']), ('Level', '$' + teXify_pol(data['level_ideal']) + '$'), ('Label', '%s' % data['label']), ('Dimension', '%s' % data['dimension']), ('CM', is_CM), ('Base change', is_base_change) ] return render_template("hilbert_modular_form.html", downloads=info["downloads"], info=info, properties2=properties2, credit=hmf_credit, title=t, bread=bread, friends=info['friends'], learnmore=learnmore_list())
def make_torsion_growth(self): try: tor_gro = self.tor_gro except AttributeError: # for curves with norsion growth data tor_gro = None if tor_gro is None: self.torsion_growth_data_exists = False return self.torsion_growth_data_exists = True self.tg = tg = {} tg['data'] = tgextra = [] # find all base-changes of this curve in the database, if any bcs = list( db.ec_nfcurves.search( {'base_change': { '$contains': [self.lmfdb_label] }}, projection='label')) bcfs = [lab.split("-")[0] for lab in bcs] for F, T in tor_gro.items(): tg1 = {} tg1['bc'] = "Not in database" # mongo did not allow "." in a dict key so we changed (e.g.) '3.1.44.1' to '3:1:44:1' # Here we change it back (but this code also works in case the fields already use ".") F = F.replace(":", ".") if "." in F: field_data = nf_display_knowl(F, field_pretty(F)) deg = int(F.split(".")[0]) bcc = [x for x, y in zip(bcs, bcfs) if y == F] if bcc: from lmfdb.ecnf.main import split_full_label F, NN, I, C = split_full_label(bcc[0]) tg1['bc'] = bcc[0] tg1['bc_url'] = url_for('ecnf.show_ecnf', nf=F, conductor_label=NN, class_label=I, number=C) else: field_data = web_latex_split_on_pm( coeff_to_poly(string2list(F))) deg = F.count(",") tg1['d'] = deg tg1['f'] = field_data tg1['t'] = '\(' + ' \\times '.join( ['\Z/{}\Z'.format(n) for n in T.split(",")]) + '\)' tg1['m'] = 0 tgextra.append(tg1) tgextra.sort(key=lambda x: x['d']) tg['n'] = len(tgextra) lastd = 1 for tg1 in tgextra: d = tg1['d'] if d != lastd: tg1['m'] = len([x for x in tgextra if x['d'] == d]) lastd = d ## Hard-code this for now. While something like ## max(db.ec_curves.search({},projection='tor_degs')) might ## work, since 'tor_degs' is in the extra table it is very ## slow. Note that the *only* place where this number is used ## is in the ec-curve template where it says "The number ## fields ... of degree up to {{data.tg.maxd}} such that...". tg['maxd'] = 7
def trace_expansion(self, prec_max=10): prec = min(self.texp_prec, prec_max) s = web_latex_split_on_pm(web_latex(coeff_to_power_series(self.texp[:prec], prec=prec), enclose=False)) if too_big(self.texp[:prec], 10**24): s = make_bigint(s) return s
def render_field_webpage(args): data = None info = {} bread = [('Global Number Fields', url_for(".number_field_render_webpage"))] # This function should not be called unless label is set. label = clean_input(args['label']) nf = WebNumberField(label) data = {} if nf.is_null(): bread.append(('Search Results', ' ')) info['err'] = 'There is no field with label %s in the database' % label info['label'] = args['label_orig'] if 'label_orig' in args else args[ 'label'] return search_input_error(info, bread) info['wnf'] = nf data['degree'] = nf.degree() data['class_number'] = nf.class_number_latex() ram_primes = nf.ramified_primes() t = nf.galois_t() n = nf.degree() data['is_galois'] = nf.is_galois() data['is_abelian'] = nf.is_abelian() if nf.is_abelian(): conductor = nf.conductor() data['conductor'] = conductor dirichlet_chars = nf.dirichlet_group() if len(dirichlet_chars) > 0: data['dirichlet_group'] = [ '<a href = "%s">$\chi_{%s}(%s,·)$</a>' % (url_for('characters.render_Dirichletwebpage', modulus=data['conductor'], number=j), data['conductor'], j) for j in dirichlet_chars ] data['dirichlet_group'] = r'$\lbrace$' + ', '.join( data['dirichlet_group']) + r'$\rbrace$' if data['conductor'].is_prime() or data['conductor'] == 1: data['conductor'] = "\(%s\)" % str(data['conductor']) else: factored_conductor = factor_base_factor(data['conductor'], ram_primes) factored_conductor = factor_base_factorization_latex( factored_conductor) data['conductor'] = "\(%s=%s\)" % (str( data['conductor']), factored_conductor) data['galois_group'] = group_display_knowl(n, t) data['cclasses'] = cclasses_display_knowl(n, t) data['character_table'] = character_table_display_knowl(n, t) data['class_group'] = nf.class_group() data['class_group_invs'] = nf.class_group_invariants() data['signature'] = nf.signature() data['coefficients'] = nf.coeffs() nf.make_code_snippets() D = nf.disc() data['disc_factor'] = nf.disc_factored_latex() if D.abs().is_prime() or D == 1: data['discriminant'] = "\(%s\)" % str(D) else: data['discriminant'] = "\(%s=%s\)" % (str(D), data['disc_factor']) data['frob_data'], data['seeram'] = frobs(nf) # Bad prime information npr = len(ram_primes) ramified_algebras_data = nf.ramified_algebras_data() if isinstance(ramified_algebras_data, str): loc_alg = '' else: # [label, latex, e, f, c, gal] loc_alg = '' for j in range(npr): if ramified_algebras_data[j] is None: loc_alg += '<tr><td>%s<td colspan="7">Data not computed' % str( ram_primes[j]) else: mydat = ramified_algebras_data[j] p = ram_primes[j] loc_alg += '<tr><td rowspan="%d">$%s$</td>' % (len(mydat), str(p)) mm = mydat[0] myurl = url_for('local_fields.by_label', label=mm[0]) lab = mm[0] if mm[3] * mm[2] == 1: lab = r'$\Q_{%s}$' % str(p) loc_alg += '<td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$' % ( myurl, lab, mm[1], mm[2], mm[3], mm[4], mm[5], show_slope_content(mm[8], mm[6], mm[7])) for mm in mydat[1:]: lab = mm[0] if mm[3] * mm[2] == 1: lab = r'$\Q_{%s}$' % str(p) loc_alg += '<tr><td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$' % ( myurl, lab, mm[1], mm[2], mm[3], mm[4], mm[5], show_slope_content(mm[8], mm[6], mm[7])) loc_alg += '</tbody></table>' ram_primes = str(ram_primes)[1:-1] if ram_primes == '': ram_primes = r'\textrm{None}' data['phrase'] = group_phrase(n, t) zk = nf.zk() Ra = PolynomialRing(QQ, 'a') zk = [latex(Ra(x)) for x in zk] zk = ['$%s$' % x for x in zk] zk = ', '.join(zk) grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh( ) else '' # Short version for properties grh_lab = nf.short_grh_string() if 'Not' in str(data['class_number']): grh_lab = '' grh_label = '' pretty_label = field_pretty(label) if label != pretty_label: pretty_label = "%s: %s" % (label, pretty_label) info.update(data) if nf.degree() > 1: gpK = nf.gpK() rootof1coeff = gpK.nfrootsof1() rootofunityorder = int(rootof1coeff[1]) rootof1coeff = rootof1coeff[2] rootofunity = web_latex( Ra( str(pari("lift(%s)" % gpK.nfbasistoalg(rootof1coeff))).replace( 'x', 'a'))) rootofunity += ' (order $%d$)' % rootofunityorder else: rootofunity = web_latex(Ra('-1')) + ' (order $2$)' info.update({ 'label': pretty_label, 'label_raw': label, 'polynomial': web_latex_split_on_pm(nf.poly()), 'ram_primes': ram_primes, 'integral_basis': zk, 'regulator': web_latex(nf.regulator()), 'unit_rank': nf.unit_rank(), 'root_of_unity': rootofunity, 'fund_units': nf.units(), 'grh_label': grh_label, 'loc_alg': loc_alg }) bread.append(('%s' % info['label_raw'], ' ')) info['downloads_visible'] = True info['downloads'] = [('worksheet', '/')] info['friends'] = [] if nf.can_class_number(): # hide ones that take a lond time to compute on the fly # note that the first degree 4 number field missed the zero of the zeta function if abs(D**n) < 50000000: info['friends'].append(('L-function', "/L/NumberField/%s" % label)) info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t))) if 'dirichlet_group' in info: info['friends'].append(('Dirichlet character group', url_for("characters.dirichlet_group_table", modulus=int(conductor), char_number_list=','.join( [str(a) for a in dirichlet_chars]), poly=info['polynomial']))) resinfo = [] galois_closure = nf.galois_closure() if galois_closure[0] > 0: if len(galois_closure[1]) > 0: resinfo.append(('gc', galois_closure[1])) if len(galois_closure[2]) > 0: info['friends'].append(('Galois closure', url_for(".by_label", label=galois_closure[2][0]))) else: resinfo.append(('gc', [dnc])) sextic_twins = nf.sextic_twin() if sextic_twins[0] > 0: if len(sextic_twins[1]) > 0: resinfo.append(('sex', r' $\times$ '.join(sextic_twins[1]))) else: resinfo.append(('sex', dnc)) siblings = nf.siblings() # [degsib list, label list] # first is list of [deg, num expected, list of knowls] if len(siblings[0]) > 0: for sibdeg in siblings[0]: if len(sibdeg[2]) == 0: sibdeg[2] = dnc else: sibdeg[2] = ', '.join(sibdeg[2]) if len(sibdeg[2]) < sibdeg[1]: sibdeg[2] += ', some ' + dnc resinfo.append(('sib', siblings[0])) for lab in siblings[1]: if lab != '': labparts = lab.split('.') info['friends'].append(("Degree %s sibling" % labparts[0], url_for(".by_label", label=lab))) arith_equiv = nf.arith_equiv() if arith_equiv[0] > 0: if len(arith_equiv[1]) > 0: resinfo.append( ('ae', ', '.join(arith_equiv[1]), len(arith_equiv[1]))) for aelab in arith_equiv[2]: info['friends'].append(('Arithmetically equivalent sibling', url_for(".by_label", label=aelab))) else: resinfo.append(('ae', dnc, len(arith_equiv[1]))) info['resinfo'] = resinfo learnmore = learnmore_list() #if info['signature'] == [0,1]: # info['learnmore'].append(('Quadratic imaginary class groups', url_for(".render_class_group_data"))) # With Galois group labels, probably not needed here # info['learnmore'] = [('Global number field labels', # url_for(".render_labels_page")), ('Galois group # labels',url_for(".render_groups_page")), # (Completename,url_for(".render_discriminants_page"))] title = "Global Number Field %s" % info['label'] if npr == 1: primes = 'prime' else: primes = 'primes' properties2 = [('Label', label), ('Degree', '$%s$' % data['degree']), ('Signature', '$%s$' % data['signature']), ('Discriminant', '$%s$' % data['disc_factor']), ('Ramified ' + primes + '', '$%s$' % ram_primes), ('Class number', '%s %s' % (data['class_number'], grh_lab)), ('Class group', '%s %s' % (data['class_group_invs'], grh_lab)), ('Galois Group', group_display_short(data['degree'], t))] downloads = [] for lang in [["Magma", "magma"], ["SageMath", "sage"], ["Pari/GP", "gp"]]: downloads.append(('Download {} code'.format(lang[0]), url_for(".nf_code_download", nf=label, download_type=lang[1]))) from lmfdb.artin_representations.math_classes import NumberFieldGaloisGroup try: info["tim_number_field"] = NumberFieldGaloisGroup(nf._data['coeffs']) v = nf.factor_perm_repn(info["tim_number_field"]) def dopow(m): if m == 0: return '' if m == 1: return '*' return '*<sup>%d</sup>' % m info["mydecomp"] = [dopow(x) for x in v] except AttributeError: pass return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, code=nf.code, friends=info.pop('friends'), downloads=downloads, learnmore=learnmore, info=info)
def print_q_expansion(list): list = [str(c) for c in list] Qb = PolynomialRing(QQ, 'b') b = QQ['b'].gen() Qq = PowerSeriesRing(Qb['a'], 'q') return web_latex_split_on_pm(Qq([c for c in list]).add_bigoh(len(list)))
def render_hmf_webpage(**args): if 'data' in args: data = args['data'] label = data['label'] else: label = str(args['label']) data = get_hmf(label) if data is None: flash_error( "%s is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a", args['label']) return search_input_error() info = {} try: info['count'] = args['count'] except KeyError: info['count'] = 50 hmf_field = get_hmf_field(data['field_label']) gen_name = findvar(hmf_field['ideals']) nf = WebNumberField(data['field_label'], gen_name=gen_name) info['hmf_field'] = hmf_field info['field'] = nf info['base_galois_group'] = nf.galois_string() info['field_degree'] = nf.degree() info['field_disc'] = str(nf.disc()) info['field_poly'] = teXify_pol(str(nf.poly())) info.update(data) info['downloads'] = [('Modular form to Magma', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='magma')), ('Eigenvalues to Sage', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='sage'))] # figure out friends # first try to see if there is an instance of this HMF on Lfun db url = 'ModularForm/GL2/TotallyReal/{}/holomorphic/{}'.format( info['field_label'], info['label']) Lfun = get_lfunction_by_url(url) if Lfun: instances = get_instances_by_Lhash_and_trace_hash( Lfun['Lhash'], Lfun['degree'], Lfun['trace_hash']) # This will also add the EC/G2C, as this how the Lfun was computed info['friends'] = names_and_urls(instances, exclude={url}) info['friends'] += [('L-function', url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))] else: # if there is no instance # old code if hmf_field['narrow_class_no'] == 1 and nf.disc( )**2 * data['level_norm'] < 40000: info['friends'] = [('L-function', url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))] else: info['friends'] = [('L-function not available', "")] if data['dimension'] == 1: # Try to attach associated elliptic curve lab = split_class_label(info['label']) ec_from_hmf = db.ec_nfcurves.lookup(label + '1') if ec_from_hmf is None: info['friends'] += [('Elliptic curve not available', "")] else: info['friends'] += [('Isogeny class ' + info['label'], url_for("ecnf.show_ecnf_isoclass", nf=lab[0], conductor_label=lab[1], class_label=lab[2]))] bread = [("Modular Forms", url_for('modular_forms')), ('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ('%s' % data['label'], ' ')] t = "Hilbert Cusp Form %s" % info['label'] forms_dims = db.hmf_forms.search( { 'field_label': data['field_label'], 'level_ideal': data['level_ideal'] }, projection='dimension') info['newspace_dimension'] = sum(forms_dims) # Get hecke_polynomial, hecke_eigenvalues and AL_eigenvalues try: numeigs = request.args['numeigs'] numeigs = int(numeigs) except: numeigs = 20 info['numeigs'] = numeigs hecke_pol = data['hecke_polynomial'] eigs = map(str, data['hecke_eigenvalues']) eigs = eigs[:min(len(eigs), numeigs)] AL_eigs = data['AL_eigenvalues'] primes = hmf_field['primes'] n = min(len(eigs), len(primes)) info['eigs'] = [{ 'eigenvalue': add_space_if_positive(teXify_pol(eigs[i])), 'prime_ideal': teXify_pol(primes[i]), 'prime_norm': primes[i][1:primes[i].index(',')] } for i in range(n)] try: display_eigs = request.args['display_eigs'] if display_eigs in ['True', 'true', '1', 'yes']: display_eigs = True else: display_eigs = False except KeyError: display_eigs = False if 'numeigs' in request.args: display_eigs = True info['hecke_polynomial'] = web_latex_split_on_pm(teXify_pol(hecke_pol)) if not AL_eigs: # empty list if data['level_norm'] == 1: # OK, no bad primes info['AL_eigs'] = 'none' else: # not OK, AL eigs are missing info['AL_eigs'] = 'missing' else: info['AL_eigs'] = [{ 'eigenvalue': teXify_pol(al[1]), 'prime_ideal': teXify_pol(al[0]), 'prime_norm': al[0][1:al[0].index(',')] } for al in data['AL_eigenvalues']] max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']]) display_eigs = display_eigs or (max_eig_len <= 300) info['display_eigs'] = display_eigs if not display_eigs: for eig in info['eigs']: if len(eig['eigenvalue']) > 300: eig['eigenvalue'] = '...' info['level_ideal'] = teXify_pol(info['level_ideal']) if 'is_CM' in data: is_CM = data['is_CM'] else: is_CM = '?' info['is_CM'] = is_CM if 'is_base_change' in data: is_base_change = data['is_base_change'] else: is_base_change = '?' info['is_base_change'] = is_base_change if 'q_expansions' in data: info['q_expansions'] = data['q_expansions'] properties2 = [('Base field', '%s' % info['field'].field_pretty()), ('Weight', '%s' % data['weight']), ('Level norm', '%s' % data['level_norm']), ('Level', '$' + teXify_pol(data['level_ideal']) + '$'), ('Label', '%s' % data['label']), ('Dimension', '%s' % data['dimension']), ('CM', is_CM), ('Base change', is_base_change)] return render_template("hilbert_modular_form.html", downloads=info["downloads"], info=info, properties2=properties2, credit=hmf_credit, title=t, bread=bread, friends=info['friends'], learnmore=learnmore_list())
def trace_expansion(self, prec_max=10): prec = min(self.texp_prec, prec_max) return web_latex_split_on_pm(web_latex(coeff_to_power_series(self.texp[:prec], prec=prec), enclose=False))
def trace_expansion(self, prec_max=10): prec = min(len(self.traces) + 1, prec_max) return web_latex_split_on_pm( web_latex(coeff_to_power_series([0] + self.traces[:prec - 1], prec=prec), enclose=False))
def render_hmf_webpage(**args): if 'data' in args: data = args['data'] label = data['label'] else: label = str(args['label']) data = get_hmf(label) if data is None: flash( Markup( "Error: <span style='color:black'>%s</span> is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a" % args['label']), "error") return search_input_error() info = {} try: info['count'] = args['count'] except KeyError: info['count'] = 10 hmf_field = get_hmf_field(data['field_label']) gen_name = findvar(hmf_field['ideals']) nf = WebNumberField(data['field_label'], gen_name=gen_name) info['hmf_field'] = hmf_field info['field'] = nf info['base_galois_group'] = nf.galois_string() info['field_degree'] = nf.degree() info['field_disc'] = str(nf.disc()) info['field_poly'] = teXify_pol(str(nf.poly())) info.update(data) info['downloads'] = [('Download to Magma', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='magma')), ('Download to Sage', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='sage'))] if hmf_field['narrow_class_no'] == 1 and nf.disc( )**2 * data['level_norm'] < 40000: info['friends'] = [('L-function', url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))] else: info['friends'] = [('L-function not available', "")] if data['dimension'] == 1: # Try to attach associated elliptic curve lab = split_class_label(info['label']) ec_from_hmf = db_ecnf().find_one({"label": label + '1'}) if ec_from_hmf == None: info['friends'] += [('Elliptic curve not available', "")] else: info['friends'] += [('Isogeny class ' + info['label'], url_for("ecnf.show_ecnf_isoclass", nf=lab[0], conductor_label=lab[1], class_label=lab[2]))] bread = [('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ('%s' % data['label'], ' ')] t = "Hilbert Cusp Form %s" % info['label'] forms_space = db_search().find( { 'field_label': data['field_label'], 'level_ideal': data['level_ideal'] }, {'dimension': True}) dim_space = 0 for v in forms_space: dim_space += v['dimension'] info['newspace_dimension'] = dim_space # Get hecke_polynomial, hecke_eigenvalues and AL_eigenvalues try: numeigs = request.args['numeigs'] numeigs = int(numeigs) except: numeigs = 20 info['numeigs'] = numeigs hecke_pol = data['hecke_polynomial'] eigs = data['hecke_eigenvalues'] eigs = eigs[:min(len(eigs), numeigs)] AL_eigs = data['AL_eigenvalues'] primes = hmf_field['primes'] n = min(len(eigs), len(primes)) info['eigs'] = [{ 'eigenvalue': teXify_pol(eigs[i]), 'prime_ideal': teXify_pol(primes[i]), 'prime_norm': primes[i][1:primes[i].index(',')] } for i in range(n)] try: display_eigs = request.args['display_eigs'] if display_eigs in ['True', 'true', '1', 'yes']: display_eigs = True else: display_eigs = False except KeyError: display_eigs = False if 'numeigs' in request.args: display_eigs = True info['hecke_polynomial'] = web_latex_split_on_pm(teXify_pol(hecke_pol)) if not AL_eigs: # empty list if data['level_norm'] == 1: # OK, no bad primes info['AL_eigs'] = 'none' else: # not OK, AL eigs are missing info['AL_eigs'] = 'missing' else: info['AL_eigs'] = [{ 'eigenvalue': teXify_pol(al[1]), 'prime_ideal': teXify_pol(al[0]), 'prime_norm': al[0][1:al[0].index(',')] } for al in data['AL_eigenvalues']] max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']]) display_eigs = display_eigs or (max_eig_len <= 300) info['display_eigs'] = display_eigs if not display_eigs: for eig in info['eigs']: if len(eig['eigenvalue']) > 300: eig['eigenvalue'] = '...' info['level_ideal'] = teXify_pol(info['level_ideal']) if 'is_CM' in data: is_CM = data['is_CM'] else: is_CM = '?' info['is_CM'] = is_CM if 'is_base_change' in data: is_base_change = data['is_base_change'] else: is_base_change = '?' info['is_base_change'] = is_base_change if 'q_expansions' in data: info['q_expansions'] = data['q_expansions'] properties2 = [('Base field', '%s' % info['field'].field_pretty()), ('Weight', '%s' % data['weight']), ('Level norm', '%s' % data['level_norm']), ('Level', '$' + teXify_pol(data['level_ideal']) + '$'), ('Label', '%s' % data['label']), ('Dimension', '%s' % data['dimension']), ('CM', is_CM), ('Base change', is_base_change)] return render_template("hilbert_modular_form.html", downloads=info["downloads"], info=info, properties2=properties2, credit=hmf_credit, title=t, bread=bread, friends=info['friends'], learnmore=learnmore_list())