def field_display_gen(self, label, poly): if label is None: if poly: return polyquo_knowl(poly) else: return 'Unknown' elif label == u'1.1.1.1': # rationals, special case return nf_display_knowl(label, name=r"\(\Q\)") else: return nf_display_knowl(label, field_pretty(label))
def display_number_field(self): if self.number_field == "": return "The number field of this isogeny class is not in the database." else: C = getDBConnection() return nf_display_knowl(self.number_field, C, field_pretty(self.number_field))
def field_knowl(self): from lmfdb.WebNumberField import nf_display_knowl nfgg = self.number_field_galois_group() if nfgg.url_for(): return nf_display_knowl(nfgg.label(), getDBConnection(), nfgg.polredabshtml()) else: return nfgg.polredabshtml()
def field_stats(F): ff = F.replace(".",":") return {'nforms': field_data[ff]['nforms'], 'maxnorm': field_data[ff]['max_norm'], 'field_knowl': nf_display_knowl(F, getDBConnection(), F), 'forms': url_for('hmf.hilbert_modular_form_render_webpage', field_label=F) }
def render_hiwf_webpage(**args): data = None if 'label' in args: label = str(args['label']) data = db.halfmf_forms.lookup(label) if data is None: return "No such field" info = {} info.update(data) info['friends'] = [] bread = [('Half Integral Weight Cusp Forms', url_for(".half_integral_weight_form_render_webpage")), ('%s' % data['label'], ' ')] t = "Half Integral Weight Cusp Forms %s" % info['label'] credit = 'Samuele Anni and Soma Purkait' dim = data['dim'] dimtheta = data['dimtheta'] dimnew = dim - dimtheta info['dimension'] = dim info['dimtheta'] = dimtheta info['dimnew'] = dimnew chi = data['character'] info['ch_lab'] = chi.replace('.', '/') chi1 = chi.split(".") chi2 = "\chi_{" + chi1[0] + "}(" + chi1[1] + ",\cdot)" info['char'] = chi2 info['newpart'] = data['newpart'] new = [] for n in data['newpart']: v = {} v['dim'] = n['dim_image'] s = [] for h in n['half_forms']: s.append(my_latex_from_qexp(print_q_expansion(h))) v['hiwf'] = s v['mf'] = n['mf_label'] v['nf'] = n['nf_label'] v['field_knowl'] = nf_display_knowl(n['nf_label'], n['nf_label']) new.append(v) info['new'] = new if dimtheta != 0: theta = [] for m in data['thetas']: for n in m: n_lab = n.replace('.', '/') n_l = n.split(".") n_lat = "\chi_{" + n_l[0] + "}(" + n_l[1] + ",\cdot)" v = [n_lab, n_lat] theta.append(v) info['theta'] = theta else: info['theta'] = data['thetas'] return render_template("half_integral_weight_form.html", info=info, credit=credit, title=t, bread=bread)
def field_knowl(self): from lmfdb.WebNumberField import nf_display_knowl nfgg = self.number_field_galois_group() if nfgg.url_for(): return nf_display_knowl(nfgg.label(), nfgg.polredabshtml()) else: return nfgg.polredabshtml()
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 show_ecnf1(nf): if nf == "1.1.1.1": return redirect(url_for("ec.rational_elliptic_curves", **request.args)) if request.args: return elliptic_curve_search(data=request.args) start = 0 count = 50 try: nf_label = nf_string_to_label(nf) except ValueError: return search_input_error() query = {'field_label': nf_label} cursor = db_ecnf().find(query) nres = cursor.count() if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_nlabel', ASC), ('number', ASC)]).skip(start).limit(count) bread = [('Elliptic Curves', url_for(".index")), (nf_label, url_for('.show_ecnf1', nf=nf_label))] res = list(res) for e in res: e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), field_pretty(e['field_label'])) info = {} info['field'] = nf_label info['query'] = query info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs #don't risk recomputing all the ecnf stats just to show curves for a single number field #if nf_label: #info['stats'] = ecnf_field_summary(nf_label) if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curves over %s' % field_pretty(nf_label) return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t, learnmore=learnmore_list())
def cm_format(D): if D == 1: return 'Not CM' elif D == 0: return 'Unknown' else: cm_label = "2.0.%s.1" % (-D) return nf_display_knowl(cm_label, field_pretty(cm_label))
def render_hiwf_webpage(**args): C = getDBConnection() data = None if 'label' in args: label = str(args['label']) data = C.halfintegralmf.forms.find_one({'label': label}) if data is None: return "No such field" info = {} info.update(data) info['friends'] = [] bread = [('Half Integral Weight Cusp Forms', url_for(".half_integral_weight_form_render_webpage")), ('%s' % data['label'], ' ')] t = "Half Integral Weight Cusp Forms %s" % info['label'] credit = 'Samuele Anni and Soma Purkait' f = C.halfintegralmf.forms.find_one({'level': data['level'], 'weight': data['weight']}) dim = f['dim'] dimtheta = f['dimtheta'] dimnew=dim-dimtheta info['dimension'] = dim info['dimtheta']= dimtheta info['dimnew'] = dimnew chi = f['character'] info['ch_lab']= chi.replace('.','/') chi1=chi.split(".") chi2="\chi_{"+chi1[0]+"}("+chi1[1]+",\cdot)" info['char']= chi2 info['newpart']=f['newpart'] new=[] for n in f['newpart']: v={} v['dim'] = n['dim_image'] s=[] for h in n['half_forms']: s.append(my_latex_from_qexp(print_q_expansion(h))) v['hiwf'] = s v['mf'] = n['mf_label'] v['nf'] = n['nf_label'] v['field_knowl'] = nf_display_knowl(n['nf_label'], getDBConnection(), n['nf_label']) new.append(v) info['new']= new if dimtheta !=0: theta=[] for m in f['thetas']: for n in m: n_lab= n.replace('.','/') n_l=n.split(".") n_lat="\chi_{"+n_l[0]+"}("+n_l[1]+",\cdot)" v=[n_lab, n_lat] theta.append(v) info['theta']= theta else: info['theta']= f['thetas'] return render_template("half_integral_weight_form.html", info=info, credit=credit, title=t, bread=bread)
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 show_ecnf1(nf): if nf == "1.1.1.1": return redirect(url_for("ec.rational_elliptic_curves", **request.args)) if request.args: return elliptic_curve_search(data=request.args) start = 0 count = 50 nf_label = parse_field_string(nf) query = {"field_label": nf_label} cursor = db_ecnf().find(query) nres = cursor.count() if start >= nres: start -= (1 + (start - nres) / count) * count if start < 0: start = 0 res = ( cursor.sort( [ ("field_label", ASC), ("conductor_norm", ASC), ("conductor_label", ASC), ("iso_label", ASC), ("number", ASC), ] ) .skip(start) .limit(count) ) bread = [("Elliptic Curves", url_for(".index")), (nf_label, url_for(".show_ecnf1", nf=nf_label))] res = list(res) for e in res: e["field_knowl"] = nf_display_knowl(e["field_label"], getDBConnection(), e["field_label"]) info = {} info["field"] = nf_label info["query"] = query info["curves"] = res # [ECNF(e) for e in res] info["number"] = nres info["start"] = start info["count"] = count info["more"] = int(start + count < nres) info["field_pretty"] = field_pretty info["web_ainvs"] = web_ainvs if nres == 1: info["report"] = "unique match" else: if nres > count or start != 0: info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres) else: info["report"] = "displaying all %s matches" % nres t = "Elliptic Curves over %s" % field_pretty(nf_label) return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def stats_for_field(self, F): forms = self.forms # pipeline = [{"$match": {'field_label':F}}, # {"$project" : { 'level_norm' : 1 }}, # {"$group":{"_id":"level_norm", "nforms": {"$sum": 2}, "maxnorm" : {"$max": '$level_norm'}}}] # res = forms.aggregate(pipeline).next() res = [f["level_norm"] for f in forms.find({"field_label": F}, ["level_norm"])] stats = {} stats["nforms"] = len(res) # res['nforms'] stats["maxnorm"] = max(res + [0]) # res['maxnorm'] stats["field_knowl"] = nf_display_knowl(F, lmfdb.base.getDBConnection(), F) stats["forms"] = url_for("hmf.hilbert_modular_form_render_webpage", field_label=F) return stats
def stats_for_field(self, F): forms = self.forms # pipeline = [{"$match": {'field_label':F}}, # {"$project" : { 'level_norm' : 1 }}, # {"$group":{"_id":"level_norm", "nforms": {"$sum": 2}, "maxnorm" : {"$max": '$level_norm'}}}] # res = forms.aggregate(pipeline).next() res = [f['level_norm'] for f in forms.find({'field_label':F}, ['level_norm'])] stats = {} stats['nforms'] = len(res) # res['nforms'] stats['maxnorm'] = max(res+[0]) # res['maxnorm'] stats['field_knowl'] = nf_display_knowl(F, lmfdb.base.getDBConnection(), F) stats['forms'] = url_for('hmf.hilbert_modular_form_render_webpage', field_label=F) return stats
def av_data(label): abvar = db.av_fqisog.lookup(label) wnf = WebNumberField(abvar['nf']) inf = '<div>Dimension: ' + str(abvar['g']) + '<br />' if not wnf.is_null(): inf += 'Number field: ' + nf_display_knowl(abvar['nf'], name = abvar['nf']) + '<br />' inf += 'Galois group: ' + group_display_knowl(abvar['gal']['n'],abvar['gal']['t']) + '<br />' inf += '$p$-rank: ' + str(abvar['p_rank']) + '</div>' inf += '<div align="right">' g, q, iso = split_label(label) url = url_for("abvarfq.abelian_varieties_by_gqi", g = g, q = q, iso = iso) inf += '<a href="%s">%s home page</a>' % (url, label) inf += '</div>' return inf
def show_ecnf1(nf): if nf == "1.1.1.1": return redirect(url_for("ec.rational_elliptic_curves", **request.args)) if request.args: return elliptic_curve_search(data=request.args) start = 0 count = 50 try: nf_label = nf_string_to_label(nf) except ValueError: return search_input_error() query = {'field_label': nf_label} cursor = db_ecnf().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_nlabel', ASC), ('number', ASC)]).skip(start).limit(count) bread = [('Elliptic Curves', url_for(".index")), (nf_label, url_for('.show_ecnf1', nf=nf_label))] res = list(res) for e in res: e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), field_pretty(e['field_label'])) info = {} info['field'] = nf_label info['query'] = query info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs #don't risk recomputing all the ecnf stats just to show curves for a single number field #if nf_label: #info['stats'] = ecnf_field_summary(nf_label) if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curves over %s' % field_pretty(nf_label) return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t, learnmore=learnmore_list())
def av_data(label): C = getDBConnection() abvar = C.abvar.fq_isog.find_one({ 'label' : label }) wnf = WebNumberField(abvar['nf']) inf = '<div>Dimension: ' + str(abvar['g']) + '<br />' if not wnf.is_null(): inf += 'Number field: ' + nf_display_knowl(abvar['nf'], C, name = abvar['nf']) + '<br />' inf += 'Galois group: ' + group_display_knowl(abvar['gal']['n'],abvar['gal']['t'],C) + '<br />' inf += '$p$-rank: ' + str(abvar['p_rank']) + '</div>' inf += '<div align="right">' g, q, iso = split_label(label) url = url_for("abvarfq.abelian_varieties_by_gqi", g = g, q = q, iso = iso) inf += '<a href="%s">%s home page</a>' % (url, label) inf += '</div>' return inf
def cyc_display(self): if self.char_degree == 1: name = r'\(\Q\)' else: m = self.char_order if self.dim == self.char_degree and self.field_poly_root_of_unity: # the relative dimension is 1 and the coefficient field is cyclotomic # We want to display it using the appropriate root of unity m = self.field_poly_root_of_unity if m == 4: name = r'\(\Q(i)\)' else: name = r'\(\Q(\zeta_{%s})\)' % m if self.char_degree < 24: return nf_display_knowl(cyclolookup[self.char_order], name=name) else: return name
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 nf_link(mf): nf_label = mf.get('nf_label') if nf_label: name = field_pretty(nf_label) if name == nf_label and len(name) > 16: # truncate if too long parts = nf_label.split('.') parts[2] = r'\(\cdots\)' name = '.'.join(parts) return nf_display_knowl(nf_label, name) elif mf['dim'] == mf['char_degree'] and mf.get( 'field_poly_root_of_unity'): return r'\(\Q(\zeta_{%s})\)' % mf['field_poly_root_of_unity'] else: poly = mf.get('field_poly') if poly: return polyquo_knowl(poly) return ""
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 init_hmf_stats(self, use_yaml_file=True): # it works with False but is much slower if self._stats: return if not self._counts: self.init_hmf_count() #print("Computing HMF stats...") if use_yaml_file: import yaml import os.path #print("Reading hmf stats yaml file") _curdir = os.path.dirname(os.path.abspath(__file__)) stats = yaml.load(open(os.path.join(_curdir, "hmf_stats.yaml"))) for d in self._counts['degrees']: statsd = stats[int(d)] for F in statsd['fields']: statsd['counts'][F]['field_knowl'] = nf_display_knowl(F, getDBConnection(), F) statsd['counts'][F]['forms'] = url_for('hmf.hilbert_modular_form_render_webpage', field_label=F) self._stats[d] = statsd else: for d in self._counts['degrees']: self._stats[d] = self.stats_for_degree(d)
def init_hmf_stats(self, use_yaml_file=True): # it works with False but is much slower if self._stats: return if not self._counts: self.init_hmf_count() #print("Computing HMF stats...") if use_yaml_file: import yaml import os.path #print("Reading hmf stats yaml file") _curdir = os.path.dirname(os.path.abspath(__file__)) stats = yaml.load(open(os.path.join(_curdir, "hmf_stats.yaml"))) for d in self._counts['degrees']: statsd = stats[int(d)] for F in statsd['fields']: statsd['counts'][F]['field_knowl'] = nf_display_knowl(F, lmfdb.base.getDBConnection(), F) statsd['counts'][F]['forms'] = url_for('hmf.hilbert_modular_form_render_webpage', field_label=F) self._stats[d] = statsd else: for d in self._counts['degrees']: self._stats[d] = self.stats_for_degree(d)
def show_ecnf1(nf): if request.args: return elliptic_curve_search(data=request.args) start = 0 count = 20 query = {'field_label' : nf} cursor = db_ecnf().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_label', ASC), ('number', ASC)]).skip(start).limit(count) bread = [('Elliptic Curves', url_for(".index")), (nf, url_for('.show_ecnf1', nf=nf))] res = list(res) for e in res: e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label']) info = {} info['field'] = nf info['query'] = query info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curves over %s' % field_pretty(nf) return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args['data']) if 'download' in info and info['download'] != 0: return download_search(info) bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')] if 'jump' in info: label = info.get('label', '').replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label.strip()) except ValueError: if not 'query' in info: info['query'] = {} info['err'] = '' return search_input_error(info, bread) return show_ecnf(nf, cond_label, iso_label, number) query = {} try: parse_ints(info,query,'conductor_norm') parse_noop(info,query,'conductor_label') parse_nf_string(info,query,'field',name="base number field",qfield='field_label') parse_nf_elt(info,query,'jinv',name='j-invariant') parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2) except ValueError: return search_input_error(info, bread) if 'include_isogenous' in info and info['include_isogenous'] == 'off': info['number'] = 1 query['number'] = 1 if 'include_base_change' in info and info['include_base_change'] == 'off': query['base_change'] = [] else: info['include_base_change'] = "on" info['query'] = query count = parse_count(info, 50) start = parse_start(info) # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_nlabel', ASC), ('number', ASC)]).skip(start).limit(count) res = list(res) for e in res: e['numb'] = str(e['number']) e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), field_pretty(e['field_label'])) info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curve search results' return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args["data"]) if "download" in info and info["download"] != 0: return download_search(info) if not "query" in info: info["query"] = {} bread = [("Elliptic Curves", url_for(".index")), ("Search Results", ".")] if "jump" in info: label = info.get("label", "").replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label.strip()) except ValueError: info["err"] = "" return search_input_error(info, bread) return show_ecnf(nf, cond_label, iso_label, number) query = {} try: parse_ints(info, query, "conductor_norm") parse_noop(info, query, "conductor_label") parse_nf_string(info, query, "field", name="base number field", qfield="field_label") parse_nf_elt(info, query, "jinv", name="j-invariant") parse_ints(info, query, "torsion", name="Torsion order", qfield="torsion_order") parse_bracketed_posints(info, query, "torsion_structure", maxlength=2) if "torsion_structure" in query and not "torsion_order" in query: query["torsion_order"] = reduce(mul, [int(n) for n in query["torsion_structure"]], 1) except ValueError: return search_input_error(info, bread) if "include_isogenous" in info and info["include_isogenous"] == "off": info["number"] = 1 query["number"] = 1 if "include_base_change" in info and info["include_base_change"] == "off": query["base_change"] = [] else: info["include_base_change"] = "on" if "include_Q_curves" in info: if info["include_Q_curves"] == "exclude": query["q_curve"] = False elif info["include_Q_curves"] == "only": query["q_curve"] = True if "include_cm" in info: if info["include_cm"] == "exclude": query["cm"] = 0 elif info["include_cm"] == "only": query["cm"] = {"$ne": 0} info["query"] = query count = parse_count(info, 50) start = parse_start(info) # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if start >= nres: start -= (1 + (start - nres) / count) * count if start < 0: start = 0 res = ( cursor.sort( [ ("field_label", ASC), ("conductor_norm", ASC), ("conductor_label", ASC), ("iso_nlabel", ASC), ("number", ASC), ] ) .skip(start) .limit(count) ) res = list(res) for e in res: e["numb"] = str(e["number"]) e["field_knowl"] = nf_display_knowl(e["field_label"], getDBConnection(), field_pretty(e["field_label"])) info["curves"] = res # [ECNF(e) for e in res] info["number"] = nres info["start"] = start info["count"] = count info["more"] = int(start + count < nres) info["field_pretty"] = field_pretty info["web_ainvs"] = web_ainvs if nres == 1: info["report"] = "unique match" else: if nres > count or start != 0: info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres) else: info["report"] = "displaying all %s matches" % nres t = "Elliptic Curve search results" return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds): r""" Set the info for on modular form. """ info = to_dict(kwds) info['level'] = level info['weight'] = weight info['character'] = character info['label'] = label if level is None or weight is None or character is None or label is None: s = "In set info for one form but do not have enough args!" s += "level={0},weight={1},character={2},label={3}".format( level, weight, character, label) emf_logger.critical(s) emf_logger.debug("In set_info_for_one_mf: info={0}".format(info)) prec = my_get(info, 'prec', default_prec, int) bprec = my_get(info, 'bprec', default_display_bprec, int) emf_logger.debug("PREC: {0}".format(prec)) emf_logger.debug("BITPREC: {0}".format(bprec)) try: WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label) if not WNF.has_updated(): raise IndexError( "Unfortunately, we do not have this newform in the database.") info['character_order'] = WNF.character.order info['code'] = WNF.code emf_logger.debug("defined webnewform for rendering!") except IndexError as e: info['error'] = e.message url0 = url_for("mf.modular_form_main_page") url1 = url_for("emf.render_elliptic_modular_forms") url2 = url_for("emf.render_elliptic_modular_forms", level=level) url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight) url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) bread = [(MF_TOP, url0), (EMF_TOP, url1)] bread.append(("Level %s" % level, url2)) bread.append(("Weight %s" % weight, url3)) bread.append(("Character \( %s \)" % (WNF.character.latex_name), url4)) bread.append( ("Newform %d.%d.%d.%s" % (level, weight, int(character), label), '')) info['bread'] = bread properties2 = list() friends = list() space_url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character) friends.append( ('\( S_{%s}(%s, %s)\)' % (WNF.weight, WNF.level, WNF.character.latex_name), space_url)) if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url: friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty, WNF.base_ring.lmfdb_url)) if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_label: friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_url)) friends = uniq(friends) friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url())) if WNF.dimension == 0 and not info.has_key('error'): info['error'] = "This space is empty!" info['title'] = 'Newform ' + WNF.hecke_orbit_label info['learnmore'] = [('History of modular forms', url_for('.holomorphic_mf_history'))] if 'error' in info: return info ## Until we have figured out how to do the embeddings correctly we don't display the Satake ## parameters for non-trivial characters.... ## Example to illustrate the different cases ## base = CyclotomicField(n) -- of degree phi(n) ## coefficient_field = NumberField( p(x)) for some p in base['x'] of degree m ## we would then have cdeg = m*phi(n) and bdeg = phi(n) ## and rdeg = m ## Unfortunately, for e.g. base = coefficient_field = CyclotomicField(6) ## we get coefficient_field.relative_degree() == 2 although it should be 1 cdeg = WNF.coefficient_field.absolute_degree() bdeg = WNF.base_ring.absolute_degree() if cdeg == 1: rdeg = 1 else: ## just setting rdeg = WNF.coefficient_field.relative_degree() does not give correct result... ## rdeg = QQ(cdeg) / QQ(bdeg) cf_is_QQ = (cdeg == 1) br_is_QQ = (bdeg == 1) if cf_is_QQ: info['satake'] = WNF.satake if WNF.complexity_of_first_nonvanishing_coefficients( ) > default_max_height: info['qexp'] = "" info['qexp_display'] = '' info['hide_qexp'] = True n, c = WNF.first_nonvanishing_coefficient() info['trace_nv'] = latex(WNF.first_nonvanishing_coefficient_trace()) info['norm_nv'] = '\\approx ' + latex( WNF.first_nonvanishing_coefficient_norm().n()) info['index_nv'] = n else: if WNF.prec < prec: #get WNF record at larger prec WNF.prec = prec WNF.update_from_db() info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ') info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label) info["hide_qexp"] = False info['max_cn_qexp'] = WNF.q_expansion.prec() ## All combinations should be tested... ## 13/4/4/a -> base ring = coefficient_field = QQ(zeta_6) ## 13/3/8/a -> base_ring = QQ(zeta_4), coefficient_field has poly x^2+(2\zeta_4+2x-3\zeta_$ over base_ring ## 13/4/3/a -> base_ring = coefficient_field = QQ(zeta_3) ## 13/4/1/a -> all rational ## 13/6/1/a/ -> base_ring = QQ, coefficient_field = Q(sqrt(17)) ## These are variables which needs to be set properly below info['polvars'] = {'base_ring': 'x', 'coefficient_field': '\\alpha'} if not cf_is_QQ: if rdeg > 1: # not WNF.coefficient_field == WNF.base_ring: ## Here WNF.base_ring should be some cyclotomic field and we have an extension over this. p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = web_latex_poly(p1, '\\alpha') # make the variable \alpha c_pol_ltx_x = web_latex_poly(p1, 'x') zeta = p1.base_ring().gens()[0] # p2 = zeta.minpoly() #this is not used anymore # b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore z1 = zeta.multiplicative_order() info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x, z1 ] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label ] if z1 == 4: info[ 'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format( c_pol_ltx) info['polvars']['base_ring'] = 'i' elif z1 <= 2: info[ 'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format( c_pol_ltx) else: info[ 'polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\) ' % ( c_pol_ltx, z1, z1) info['polvars']['base_ring'] = '\zeta_{{ {0} }}'.format(z1) if z1 == 3: info[ 'polynomial_st'] += 'is a primitive cube root of unity.' else: info[ 'polynomial_st'] += 'is a primitive {0}-th root of unity.'.format( z1) elif not br_is_QQ: ## Now we have base and coefficient field being equal, meaning that since the coefficient field is not QQ it is some cyclotomic field ## generated by some \zeta_n p1 = WNF.coefficient_field.absolute_polynomial() z1 = WNF.coefficient_field.gens()[0].multiplicative_order() c_pol_ltx = web_latex_poly(p1, '\\zeta_{{{0}}}'.format(z1)) c_pol_ltx_x = web_latex_poly(p1, 'x') info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x ] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label ] if z1 == 4: info[ 'polynomial_st'] = '<div class="where">where \(\zeta_4=e^{{\\frac{{\\pi i}}{{ 2 }} }}=i \).</div>'.format( c_pol_ltx) info['polvars']['coefficient_field'] = 'i' elif z1 <= 2: info['polynomial_st'] = '' else: info[ 'polynomial_st'] = '<div class="where">where \(\zeta_{{{0}}}=e^{{\\frac{{2\\pi i}}{{ {0} }} }}\) '.format( z1) info['polvars']['coefficient_field'] = '\zeta_{{{0}}}'.format( z1) if z1 == 3: info[ 'polynomial_st'] += 'is a primitive cube root of unity.</div>' else: info[ 'polynomial_st'] += 'is a primitive {0}-th root of unity.</div>'.format( z1) else: info['polynomial_st'] = '' if info["hide_qexp"]: info['polynomial_st'] = '' info['degree'] = int(cdeg) if cdeg == 1: info['is_rational'] = 1 info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty ] else: info['is_rational'] = 0 emf_logger.debug("PREC2: {0}".format(prec)) info['embeddings'] = WNF._embeddings[ 'values'] #q_expansion_embeddings(prec, bprec,format='latex') info['embeddings_len'] = len(info['embeddings']) properties2 = [('Level', str(level)), ('Weight', str(weight)), ('Character', '$' + WNF.character.latex_name + '$'), ('Label', WNF.hecke_orbit_label), ('Dimension of Galois orbit', str(WNF.dimension))] if (ZZ(level)).is_squarefree(): info['twist_info'] = WNF.twist_info if isinstance(info['twist_info'], list) and len(info['twist_info']) > 0: info['is_minimal'] = info['twist_info'][0] if (info['twist_info'][0]): s = 'Is minimal<br>' else: s = 'Is a twist of lower level<br>' properties2 += [('Twist info', s)] else: info['twist_info'] = 'Twist info currently not available.' properties2 += [('Twist info', 'not available')] args = list() for x in range(5, 200, 10): args.append({'digits': x}) alev = None CM = WNF._cm_values if CM is not None: if CM.has_key('tau') and len(CM['tau']) != 0: info['CM_values'] = CM info['is_cm'] = WNF.is_cm if WNF.is_cm == 1: info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc) info['cm_disc'] = WNF.cm_disc info['cm_field_knowl'] = nf_display_knowl( info['cm_field'], getDBConnection(), field_pretty(info['cm_field'])) info['cm_field_url'] = url_for("number_fields.by_label", label=info["cm_field"]) if WNF.is_cm is None or WNF.is_cm == -1: s = '- Unknown (insufficient data)<br>' elif WNF.is_cm == 1: s = 'Yes<br>' else: s = 'No<br>' properties2.append(('CM', s)) alev = WNF.atkin_lehner_eigenvalues() info['atkinlehner'] = None if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1: s1 = " Atkin-Lehner eigenvalues " s2 = "" for Q in alev.keys(): s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q]) properties2.append((s1, s2)) emf_logger.debug("properties={0}".format(properties2)) # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() # if isinstance(alev,dict) and len(alev.keys())>0: # emf_logger.debug("alev={0}".format(alev)) # info['atkinlehner'] = list() # for Q in alev.keys(): # s = "\(" + latex(c) + "\)" # Q = alev[c][0] # ev = alev[c][1] # info['atkinlehner'].append([Q, c, ev]) if (level == 1): poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6', '') if poly != '': d, monom, coeffs = poly emf_logger.critical("poly={0}".format(poly)) info['explicit_formulas'] = '\(' for i in range(len(coeffs)): c = QQ(coeffs[i]) s = "" if d > 1 and i > 0 and c > 0: s = "+" if c < 0: s = "-" if c.denominator() > 1: cc = "\\frac{{ {0} }}{{ {1} }}".format( abs(c.numerator()), c.denominator()) else: cc = str(abs(c)) s += "{0} \cdot ".format(cc) a = monom[i][0] b = monom[i][1] if a == 1: a = "" if b == 1: b = "" if a == 0 and b != 0: s += "E_6^{{ {0} }}(z)".format(b) elif b == 0 and a != 0: s += "E_4^{{ {0} }}(z)".format(a) else: s += "E_4^{{ {0} }}(z) \cdot E_6^{{ {1} }}(z)".format(a, b) info['explicit_formulas'] += s info['explicit_formulas'] += " \)" # cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + '&label=' + str(label) # never used if len(WNF.parent.hecke_orbits) > 1: for label_other in WNF.parent.hecke_orbits.keys(): if (label_other != label): s = 'Modular form ' if character: s += newform_label(level, weight, character, label_other) else: s += newform_label(level, weight, 1, label_other) url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label_other) friends.append((s, url)) s = 'L-Function ' if character: s += newform_label(level, weight, character, label) else: s += newform_label(level, weight, 1, label) # url = # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s" # %(level,weight,character,label,0) url = '/L' + url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label) if WNF.coefficient_field_degree > 1: for h in range(WNF.coefficient_field_degree): s0 = s + ".{0}".format(h) url0 = url + "{0}/".format(h) friends.append((s0, url0)) else: friends.append((s, url)) # if there is an elliptic curve over Q associated to self we also list that if WNF.weight == 2 and WNF.coefficient_field_degree == 1: llabel = str(level) + '.' + label s = 'Elliptic curve isogeny class ' + llabel url = '/EllipticCurve/Q/' + llabel friends.append((s, url)) info['properties2'] = properties2 info['friends'] = friends info['max_cn'] = WNF.max_available_prec() return info
def make_form(self): # To start with the data fields of self are just those from # the database. We need to reformat these and compute some # further (easy) data about it. # from lmfdb.ecnf.WebEllipticCurve import FIELD self.field = FIELD(self.field_label) pretty_field = field_pretty(self.field_label) self.field_knowl = nf_display_knowl(self.field_label, pretty_field) try: dims = db.bmf_dims.lucky( { 'field_label': self.field_label, 'level_label': self.level_label }, projection='gl2_dims') self.newspace_dimension = dims[str(self.weight)]['new_dim'] except TypeError: self.newspace_dimension = 'not available' self.newspace_label = "-".join([self.field_label, self.level_label]) self.newspace_url = url_for(".render_bmf_space_webpage", field_label=self.field_label, level_label=self.level_label) K = self.field.K() if self.dimension > 1: Qx = PolynomialRing(QQ, 'x') self.hecke_poly = Qx(str(self.hecke_poly)) F = NumberField(self.hecke_poly, 'z') self.hecke_poly = web_latex(self.hecke_poly) def conv(ap): if '?' in ap: return 'not known' else: return F(str(ap)) self.hecke_eigs = [conv(str(ap)) for ap in self.hecke_eigs] self.nap = len(self.hecke_eigs) self.nap0 = min(50, self.nap) self.hecke_table = [[ web_latex(p.norm()), ideal_label(p), web_latex(p.gens_reduced()[0]), web_latex(ap) ] for p, ap in zip(primes_iter(K), self.hecke_eigs[:self.nap0])] level = ideal_from_label(K, self.level_label) self.level_ideal2 = web_latex(level) badp = level.prime_factors() self.have_AL = self.AL_eigs[0] != '?' if self.have_AL: self.AL_table = [[ web_latex(p.norm()), ideal_label(p), web_latex(p.gens_reduced()[0]), web_latex(ap) ] for p, ap in zip(badp, self.AL_eigs)] self.sign = 'not determined' if self.sfe == 1: self.sign = "+1" elif self.sfe == -1: self.sign = "-1" if self.Lratio == '?': self.Lratio = "not determined" self.anrank = "not determined" else: self.Lratio = QQ(self.Lratio) self.anrank = "\(0\)" if self.Lratio != 0 else "odd" if self.sfe == -1 else "\(\ge2\), even" self.properties2 = [('Base field', pretty_field), ('Weight', str(self.weight)), ('Level norm', str(self.level_norm)), ('Level', self.level_ideal2), ('Label', self.label), ('Dimension', str(self.dimension))] if self.CM == '?': self.CM = 'not determined' elif self.CM == 0: self.CM = 'no' self.properties2.append(('CM', str(self.CM))) self.bc_extra = '' self.bcd = 0 self.bct = self.bc != '?' and self.bc != 0 if self.bc == '?': self.bc = 'not determined' elif self.bc == 0: self.bc = 'no' elif self.bc == 1: self.bcd = self.bc self.bc = 'yes' elif self.bc > 1: self.bcd = self.bc self.bc = 'yes' self.bc_extra = ', of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{' + str( self.bcd) + '})\)' elif self.bc == -1: self.bc = 'no' self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\)' elif self.bc < -1: self.bcd = -self.bc self.bc = 'no' self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{' + str( self.bcd) + '})\)' self.properties2.append(('Base-change', str(self.bc))) curve_bc = db.ec_nfcurves.lucky({'class_label': self.label}, projection="base_change") if curve_bc is not None: self.ec_status = 'exists' self.ec_url = url_for("ecnf.show_ecnf_isoclass", nf=self.field_label, conductor_label=self.level_label, class_label=self.label_suffix) curve_bc_parts = [split_lmfdb_label(lab) for lab in curve_bc] bc_urls = [ url_for("emf.render_elliptic_modular_forms", level=cond, weight=2, character=1, label=iso) for cond, iso, num in curve_bc_parts ] bc_labels = [ newform_label(cond, 2, 1, iso) for cond, iso, num in curve_bc_parts ] bc_exists = [is_newform_in_db(lab) for lab in bc_labels] self.bc_forms = [{ 'exists': ex, 'label': lab, 'url': url } for ex, lab, url in zip(bc_exists, bc_labels, bc_urls)] else: self.bc_forms = [] if self.bct: self.ec_status = 'none' else: self.ec_status = 'missing' self.properties2.append(('Sign', self.sign)) self.properties2.append(('Analytic rank', self.anrank)) self.friends = [] if self.dimension == 1: if self.ec_status == 'exists': self.friends += [ ('Elliptic curve isogeny class {}'.format(self.label), self.ec_url) ] elif self.ec_status == 'missing': self.friends += [ ('Elliptic curve {} missing'.format(self.label), "") ] else: self.friends += [('No elliptic curve', "")] self.friends += [('Newspace {}'.format(self.newspace_label), self.newspace_url)] self.friends += [('L-function not available', '')]
def make_form(self): # To start with the data fields of self are just those from # the database. We need to reformat these and compute some # further (easy) data about it. # from lmfdb.ecnf.WebEllipticCurve import FIELD self.field = FIELD(self.field_label) pretty_field = field_pretty(self.field_label) self.field_knowl = nf_display_knowl(self.field_label, getDBConnection(), pretty_field) try: dims = db_dims().find_one({'field_label':self.field_label, 'level_label':self.level_label})['gl2_dims'] self.newspace_dimension = dims[str(self.weight)]['new_dim'] except TypeError: self.newspace_dimension = 'not available' self.newspace_label = "-".join([self.field_label,self.level_label]) self.newspace_url = url_for(".render_bmf_space_webpage", field_label=self.field_label, level_label=self.level_label) K = self.field.K() if self.dimension>1: Qx = PolynomialRing(QQ,'x') self.hecke_poly = Qx(str(self.hecke_poly)) F = NumberField(self.hecke_poly,'z') self.hecke_poly = web_latex(self.hecke_poly) def conv(ap): if '?' in ap: return 'not known' else: return F(str(ap)) self.hecke_eigs = [conv(str(ap)) for ap in self.hecke_eigs] self.nap = len(self.hecke_eigs) self.nap0 = min(50, self.nap) self.hecke_table = [[web_latex(p.norm()), ideal_label(p), web_latex(p.gens_reduced()[0]), web_latex(ap)] for p,ap in zip(primes_iter(K), self.hecke_eigs[:self.nap0])] level = ideal_from_label(K,self.level_label) self.level_ideal2 = web_latex(level) badp = level.prime_factors() self.have_AL = self.AL_eigs[0]!='?' if self.have_AL: self.AL_table = [[web_latex(p.norm()), ideal_label(p), web_latex(p.gens_reduced()[0]), web_latex(ap)] for p,ap in zip(badp, self.AL_eigs)] self.sign = 'not determined' if self.sfe == 1: self.sign = "+1" elif self.sfe == -1: self.sign = "-1" if self.Lratio == '?': self.Lratio = "not determined" self.anrank = "not determined" else: self.Lratio = QQ(self.Lratio) self.anrank = "\(0\)" if self.Lratio!=0 else "odd" if self.sfe==-1 else "\(\ge2\), even" self.properties2 = [('Base field', pretty_field), ('Weight', str(self.weight)), ('Level norm', str(self.level_norm)), ('Level', self.level_ideal2), ('Label', self.label), ('Dimension', str(self.dimension)) ] if self.CM == '?': self.CM = 'not determined' elif self.CM == 0: self.CM = 'no' self.properties2.append(('CM', str(self.CM))) self.bc_extra = '' self.bcd = 0 self.bct = self.bc!='?' and self.bc!=0 if self.bc == '?': self.bc = 'not determined' elif self.bc == 0: self.bc = 'no' elif self.bc == 1: self.bcd = self.bc self.bc = 'yes' elif self.bc >1: self.bcd = self.bc self.bc = 'yes' self.bc_extra = ', of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{'+str(self.bcd)+'})\)' elif self.bc == -1: self.bc = 'no' self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\)' elif self.bc < -1: self.bcd = -self.bc self.bc = 'no' self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{'+str(self.bcd)+'})\)' self.properties2.append(('Base-change', str(self.bc))) curve = db_ecnf().find_one({'class_label':self.label}) if curve: self.ec_status = 'exists' self.ec_url = url_for("ecnf.show_ecnf_isoclass", nf=self.field_label, conductor_label=self.level_label, class_label=self.label_suffix) curve_bc = curve['base_change'] curve_bc_parts = [split_lmfdb_label(lab) for lab in curve_bc] bc_urls = [url_for("emf.render_elliptic_modular_forms", level=cond, weight=2, character=1, label=iso) for cond, iso, num in curve_bc_parts] bc_labels = [newform_label(cond,2,1,iso) for cond,iso,num in curve_bc_parts] bc_exists = [is_newform_in_db(lab) for lab in bc_labels] self.bc_forms = [{'exists':ex, 'label':lab, 'url':url} for ex,lab,url in zip(bc_exists, bc_labels, bc_urls)] else: self.bc_forms = [] if self.bct: self.ec_status = 'none' else: self.ec_status = 'missing' self.properties2.append(('Sign', self.sign)) self.properties2.append(('Analytic rank', self.anrank)) self.friends = [] if self.dimension==1: if self.ec_status == 'exists': self.friends += [('Elliptic curve isogeny class {}'.format(self.label), self.ec_url)] elif self.ec_status == 'missing': self.friends += [('Elliptic curve {} missing'.format(self.label), "")] else: self.friends += [('No elliptic curve', "")] self.friends += [ ('Newspace {}'.format(self.newspace_label),self.newspace_url)] self.friends += [ ('L-function not available','')]
def elliptic_curve_search(info): if info.get('download') == '1' and info.get('Submit') and info.get( 'query'): return download_search(info) if not 'query' in info: info['query'] = {} bread = info.get('bread', [('Elliptic Curves', url_for(".index")), ('Search Results', '.')]) if 'jump' in info: label = info.get('label', '').replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label.strip()) except ValueError: info['err'] = '' return search_input_error(info, bread) return redirect( url_for(".show_ecnf", nf=nf, conductor_label=cond_label, class_label=iso_label, number=number), 301) query = {} if 'jinv' in info: if info.get('field', '').strip() == '2.2.5.1': info['jinv'] = info['jinv'].replace('phi', 'a') if info.get('field', '').strip() == '2.0.4.1': info['jinv'] = info['jinv'].replace('i', 'a') try: parse_ints(info, query, 'conductor_norm') parse_noop(info, query, 'conductor_label') parse_nf_string(info, query, 'field', name="base number field", qfield='field_label') parse_nf_elt(info, query, 'jinv', name='j-invariant') parse_ints(info, query, 'torsion', name='Torsion order', qfield='torsion_order') parse_bracketed_posints(info, query, 'torsion_structure', maxlength=2) if 'torsion_structure' in query and not 'torsion_order' in query: query['torsion_order'] = reduce( mul, [int(n) for n in query['torsion_structure']], 1) parse_ints(info, query, field='isodeg', qfield='isogeny_degrees') except (TypeError, ValueError): return search_input_error(info, bread) if query.get('jinv'): query['jinv'] = ','.join(query['jinv']) if query.get('field_label') == '1.1.1.1': return redirect(url_for("ec.rational_elliptic_curves", **request.args), 301) if 'include_isogenous' in info and info['include_isogenous'] == 'off': info['number'] = 1 query['number'] = 1 if 'include_base_change' in info and info['include_base_change'] == 'off': query['base_change'] = [] else: info['include_base_change'] = "on" if 'include_Q_curves' in info: if info['include_Q_curves'] == 'exclude': query['q_curve'] = False elif info['include_Q_curves'] == 'only': query['q_curve'] = True if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne': 0} info['query'] = query count = parse_count(info, 50) start = parse_start(info) # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_nlabel', ASC), ('number', ASC)]).skip(start).limit(count) res = list(res) for e in res: e['numb'] = str(e['number']) e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), field_pretty(e['field_label'])) info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = info.get('title', 'Elliptic Curve search results') return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args['data']) if 'download' in info and info['download'] != 0: return download_search(info) if not 'query' in info: info['query'] = {} bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')] if 'jump' in info: label = info.get('label', '').replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label.strip()) except ValueError: info['err'] = '' return search_input_error(info, bread) return show_ecnf(nf, cond_label, iso_label, number) query = {} try: parse_ints(info,query,'conductor_norm') parse_noop(info,query,'conductor_label') parse_nf_string(info,query,'field',name="base number field",qfield='field_label') parse_nf_elt(info,query,'jinv',name='j-invariant') parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2) if 'torsion_structure' in query and not 'torsion_order' in query: query['torsion_order'] = reduce(mul,[int(n) for n in query['torsion_structure']],1) except ValueError: return search_input_error(info, bread) if 'include_isogenous' in info and info['include_isogenous'] == 'off': info['number'] = 1 query['number'] = 1 if 'include_base_change' in info and info['include_base_change'] == 'off': query['base_change'] = [] else: info['include_base_change'] = "on" if 'include_Q_curves' in info: if info['include_Q_curves'] == 'exclude': query['q_curve'] = False elif info['include_Q_curves'] == 'only': query['q_curve'] = True if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne' : 0} info['query'] = query count = parse_count(info, 50) start = parse_start(info) # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_nlabel', ASC), ('number', ASC)]).skip(start).limit(count) res = list(res) for e in res: e['numb'] = str(e['number']) e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), field_pretty(e['field_label'])) info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curve search results' return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
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 make_class(self): # Create a list of the curves in the class from the database self.db_curves = [ c for c in db_ecnf().find({ 'field_label': self.field_label, 'conductor_norm': self.conductor_norm, 'conductor_label': self.conductor_label, 'iso_nlabel': self.iso_nlabel }).sort('number') ] # Rank or bounds try: self.rk = web_latex(self.db_curves[0]['rank']) except KeyError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.db_curves[0]['rank_bounds']) except KeyError: self.rank_bounds = [0, sage.rings.infinity.Infinity] self.rk_bnds = "not recorded" # Extract the isogeny degree matrix from the database if possible, else create it if hasattr(self, 'isogeny_matrix'): from sage.matrix.all import Matrix self.isogeny_matrix = Matrix(self.isogeny_matrix) else: self.isogeny_matrix = make_iso_matrix(self.db_curves) # Create isogeny graph: self.graph = make_graph(self.isogeny_matrix) P = self.graph.plot(edge_labels=True) self.graph_img = encode_plot(P) self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix)) self.field = field_pretty(self.field_label) self.field_knowl = nf_display_knowl(self.field_label, lmfdb.base.getDBConnection(), self.field) def curve_url(c): return url_for(".show_ecnf", nf=c['field_label'], conductor_label=c['conductor_label'], class_label=c['iso_label'], number=c['number']) self.curves = [[ c['short_label'], curve_url(c), web_ainvs(self.field_label, c['ainvs']) ] for c in self.db_curves] self.urls = {} self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=self.conductor_label) self.urls['field'] = url_for('.show_ecnf1', nf=self.field_label) sig = self.signature totally_real = sig[1] == 0 imag_quadratic = sig == [0, 1] if totally_real: self.hmf_label = "-".join( [self.field_label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field_label, label=self.hmf_label) self.urls['Lfunction'] = url_for("l_functions.l_function_hmf_page", field=self.field_label, label=self.hmf_label, character='0', number='0') if imag_quadratic: self.bmf_label = "-".join( [self.field_label, self.conductor_label, self.iso_label]) self.friends = [] if totally_real: self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])] self.friends += [('L-function', self.urls['Lfunction'])] if imag_quadratic: self.friends += [ ('Bianchi Modular Form %s not available' % self.bmf_label, '') ] self.properties = [('Base field', self.field), ('Label', self.class_label), (None, self.graph_link), ('Conductor', '%s' % self.conductor_label)] if self.rk != '?': self.properties += [('Rank', '%s' % self.rk)] else: if self.rk_bnds == 'not recorded': self.properties += [('Rank', '%s' % self.rk_bnds)] else: self.properties += [('Rank bounds', '%s' % self.rk_bnds)] self.bread = [('Elliptic Curves ', url_for(".index")), (self.field_label, self.urls['field']), (self.conductor_label, self.urls['conductor']), ('isogeny class %s' % self.short_label, self.urls['class'])]
def quad_field_knowl(disc): r = 2 if disc > 0 else 0 field_label = "2.%d.%d.1" % (r, abs(disc)) field_name = field_pretty(field_label) return nf_display_knowl(field_label, field_name)
def make_class(self): # Create a list of the curves in the class from the database self.db_curves = [c for c in db_ec().find( {'field_label': self.field_label, 'conductor_label': self.conductor_label, 'iso_label': self.iso_label}).sort('number')] # Rank or bounds try: self.rk = web_latex(self.db_curves[0]['rank']) except KeyError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.db_curves[0]['rank_bounds']) except KeyError: self.rank_bounds = [0, sage.rings.infinity.Infinity] self.rk_bnds = "not recorded" # Extract the isogeny degree matrix from the database if possible, else create it if hasattr(self, 'isogeny_matrix'): from sage.matrix.all import Matrix self.isogeny_matrix = Matrix(self.isogeny_matrix) else: self.isogeny_matrix = make_iso_matrix(self.db_curves) # Create isogeny graph: self.graph = make_graph(self.isogeny_matrix) P = self.graph.plot(edge_labels=True) self.graph_img = encode_plot(P) self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix)) self.field = field_pretty(self.field_label) self.field_knowl = nf_display_knowl(self.field_label, lmfdb.base.getDBConnection(), self.field) def curve_url(c): return url_for(".show_ecnf", nf=c['field_label'], conductor_label=c['conductor_label'], class_label=c['iso_label'], number=c['number']) self.curves = [[c['short_label'], curve_url(c), web_ainvs(self.field_label,c['ainvs'])] for c in self.db_curves] self.urls = {} self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=self.conductor_label) self.urls['field'] = url_for('.show_ecnf1', nf=self.field_label) sig = self.signature totally_real = sig[1] == 0 imag_quadratic = sig == [0,1] if totally_real: self.hmf_label = "-".join([self.field_label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field_label, label=self.hmf_label) self.urls['Lfunction'] = url_for("l_functions.l_function_hmf_page", field=self.field_label, label=self.hmf_label, character='0', number='0') if imag_quadratic: self.bmf_label = "-".join([self.field_label, self.conductor_label, self.iso_label]) self.friends = [] if totally_real: self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])] self.friends += [('L-function', self.urls['Lfunction'])] if imag_quadratic: self.friends += [('Bianchi Modular Form %s not available' % self.bmf_label, '')] self.properties = [('Base field', self.field), ('Label', self.class_label), (None, self.graph_link), ('Conductor', '%s' % self.conductor_label) ] if self.rk != '?': self.properties += [('Rank', '%s' % self.rk)] else: if self.rk_bnds == 'not recorded': self.properties += [('Rank', '%s' % self.rk_bnds)] else: self.properties += [('Rank bounds', '%s' % self.rk_bnds)] self.bread = [('Elliptic Curves ', url_for(".index")), (self.field_label, self.urls['field']), (self.conductor_label, self.urls['conductor']), ('isogeny class %s' % self.short_label, self.urls['class'])]
def display_number_field(self): if self.nf == "": return "The number field of this isogeny class is not in the database." else: return nf_display_knowl(self.nf,field_pretty(self.nf))
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds): r""" Set the info for on modular form. """ info = to_dict(kwds) info['level'] = level info['weight'] = weight info['character'] = character info['label'] = label if level is None or weight is None or character is None or label is None: s = "In set info for one form but do not have enough args!" s += "level={0},weight={1},character={2},label={3}".format(level, weight, character, label) emf_logger.critical(s) emf_logger.debug("In set_info_for_one_mf: info={0}".format(info)) prec = my_get(info, 'prec', default_prec, int) bprec = my_get(info, 'bprec', default_display_bprec, int) emf_logger.debug("PREC: {0}".format(prec)) emf_logger.debug("BITPREC: {0}".format(bprec)) try: WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label) if not WNF.has_updated(): raise IndexError("Unfortunately, we do not have this newform in the database.") info['character_order'] = WNF.character.order info['code'] = WNF.code emf_logger.debug("defined webnewform for rendering!") except IndexError as e: info['error'] = e.message url0 = url_for("mf.modular_form_main_page") url1 = url_for("emf.render_elliptic_modular_forms") url2 = url_for("emf.render_elliptic_modular_forms", level=level) url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight) url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) bread = [(MF_TOP, url0), (EMF_TOP, url1)] bread.append(("Level %s" % level, url2)) bread.append(("Weight %s" % weight, url3)) bread.append(("Character \( %s \)" % (WNF.character.latex_name), url4)) bread.append(("Newform %d.%d.%d.%s" % (level, weight, int(character), label),'')) info['bread'] = bread properties2 = list() friends = list() space_url = url_for('emf.render_elliptic_modular_forms',level=level, weight=weight, character=character) friends.append(('\( S_{%s}(%s, %s)\)'%(WNF.weight, WNF.level, WNF.character.latex_name), space_url)) if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url: friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty, WNF.base_ring.lmfdb_url)) if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_label: friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_url)) friends = uniq(friends) friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url())) if WNF.dimension==0 and not info.has_key('error'): info['error'] = "This space is empty!" info['title'] = 'Newform ' + WNF.hecke_orbit_label info['learnmore'] = [('History of modular forms', url_for('.holomorphic_mf_history'))] if 'error' in info: return info ## Until we have figured out how to do the embeddings correctly we don't display the Satake ## parameters for non-trivial characters.... ## Example to illustrate the different cases ## base = CyclotomicField(n) -- of degree phi(n) ## coefficient_field = NumberField( p(x)) for some p in base['x'] of degree m ## we would then have cdeg = m*phi(n) and bdeg = phi(n) ## and rdeg = m ## Unfortunately, for e.g. base = coefficient_field = CyclotomicField(6) ## we get coefficient_field.relative_degree() == 2 although it should be 1 cdeg = WNF.coefficient_field.absolute_degree() bdeg = WNF.base_ring.absolute_degree() if cdeg == 1: rdeg = 1 else: ## just setting rdeg = WNF.coefficient_field.relative_degree() does not give correct result... ## rdeg = QQ(cdeg)/QQ(bdeg) cf_is_QQ = (cdeg == 1) br_is_QQ = (bdeg == 1) if cf_is_QQ: info['satake'] = WNF.satake if WNF.complexity_of_first_nonvanishing_coefficients() > default_max_height: info['qexp'] = "" info['qexp_display'] = '' info['hide_qexp'] = True n,c = WNF.first_nonvanishing_coefficient() info['trace_nv'] = latex(WNF.first_nonvanishing_coefficient_trace()) info['norm_nv'] = '\\approx ' + latex(WNF.first_nonvanishing_coefficient_norm().n()) info['index_nv'] = n else: if WNF.prec < prec: #get WNF record at larger prec WNF.prec = prec WNF.update_from_db() info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ') info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label) info["hide_qexp"] = False info['max_cn_qexp'] = WNF.q_expansion.prec() ## All combinations should be tested... ## 13/4/4/a -> base ring = coefficient_field = QQ(zeta_6) ## 13/3/8/a -> base_ring = QQ(zeta_4), coefficient_field has poly x^2+(2\zeta_4+2x-3\zeta_$ over base_ring ## 13/4/3/a -> base_ring = coefficient_field = QQ(zeta_3) ## 13/4/1/a -> all rational ## 13/6/1/a/ -> base_ring = QQ, coefficient_field = Q(sqrt(17)) ## These are variables which needs to be set properly below info['polvars'] = {'base_ring':'x','coefficient_field':'\\alpha'} if not cf_is_QQ: if rdeg>1: # not WNF.coefficient_field == WNF.base_ring: ## Here WNF.base_ring should be some cyclotomic field and we have an extension over this. p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = web_latex_poly(p1, '\\alpha') # make the variable \alpha c_pol_ltx_x = web_latex_poly(p1, 'x') zeta = p1.base_ring().gens()[0] # p2 = zeta.minpoly() #this is not used anymore # b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore z1 = zeta.multiplicative_order() info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'),c_pol_ltx_x, z1] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label] if z1==4: info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format(c_pol_ltx) info['polvars']['base_ring']='i' elif z1<=2: info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(c_pol_ltx) else: info['polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\) '%(c_pol_ltx, z1,z1) info['polvars']['base_ring']='\zeta_{{ {0} }}'.format(z1) if z1==3: info['polynomial_st'] += 'is a primitive cube root of unity.' else: info['polynomial_st'] += 'is a primitive {0}-th root of unity.'.format(z1) elif not br_is_QQ: ## Now we have base and coefficient field being equal, meaning that since the coefficient field is not QQ it is some cyclotomic field ## generated by some \zeta_n p1 = WNF.coefficient_field.absolute_polynomial() z1 = WNF.coefficient_field.gens()[0].multiplicative_order() c_pol_ltx = web_latex_poly(p1, '\\zeta_{{{0}}}'.format(z1)) c_pol_ltx_x = web_latex_poly(p1, 'x') info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label] if z1==4: info['polynomial_st'] = '<div class="where">where \(\zeta_4=e^{{\\frac{{\\pi i}}{{ 2 }} }}=i \).</div>'.format(c_pol_ltx) info['polvars']['coefficient_field']='i' elif z1<=2: info['polynomial_st'] = '' else: info['polynomial_st'] = '<div class="where">where \(\zeta_{{{0}}}=e^{{\\frac{{2\\pi i}}{{ {0} }} }}\) '.format(z1) info['polvars']['coefficient_field']='\zeta_{{{0}}}'.format(z1) if z1==3: info['polynomial_st'] += 'is a primitive cube root of unity.</div>' else: info['polynomial_st'] += 'is a primitive {0}-th root of unity.</div>'.format(z1) else: info['polynomial_st'] = '' if info["hide_qexp"]: info['polynomial_st'] = '' info['degree'] = int(cdeg) if cdeg==1: info['is_rational'] = 1 info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty ] else: info['is_rational'] = 0 emf_logger.debug("PREC2: {0}".format(prec)) info['embeddings'] = WNF._embeddings['values'] #q_expansion_embeddings(prec, bprec,format='latex') info['embeddings_len'] = len(info['embeddings']) properties2 = [('Level', str(level)), ('Weight', str(weight)), ('Character', '$' + WNF.character.latex_name + '$'), ('Label', WNF.hecke_orbit_label), ('Dimension of Galois orbit', str(WNF.dimension))] if (ZZ(level)).is_squarefree(): info['twist_info'] = WNF.twist_info if isinstance(info['twist_info'], list) and len(info['twist_info'])>0: info['is_minimal'] = info['twist_info'][0] if(info['twist_info'][0]): s = 'Is minimal<br>' else: s = 'Is a twist of lower level<br>' properties2 += [('Twist info', s)] else: info['twist_info'] = 'Twist info currently not available.' properties2 += [('Twist info', 'not available')] args = list() for x in range(5, 200, 10): args.append({'digits': x}) alev = None CM = WNF._cm_values if CM is not None: if CM.has_key('tau') and len(CM['tau']) != 0: info['CM_values'] = CM info['is_cm'] = WNF.is_cm if WNF.is_cm == 1: info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc) info['cm_disc'] = WNF.cm_disc info['cm_field_knowl'] = nf_display_knowl(info['cm_field'], getDBConnection(), field_pretty(info['cm_field'])) info['cm_field_url'] = url_for("number_fields.by_label", label=info["cm_field"]) if WNF.is_cm is None or WNF.is_cm==-1: s = '- Unknown (insufficient data)<br>' elif WNF.is_cm == 1: s = 'Yes<br>' else: s = 'No<br>' properties2.append(('CM', s)) alev = WNF.atkin_lehner_eigenvalues() info['atkinlehner'] = None if isinstance(alev,dict) and len(alev.keys())>0 and level != 1: s1 = " Atkin-Lehner eigenvalues " s2 = "" for Q in alev.keys(): s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q]) properties2.append((s1, s2)) emf_logger.debug("properties={0}".format(properties2)) # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() # if isinstance(alev,dict) and len(alev.keys())>0: # emf_logger.debug("alev={0}".format(alev)) # info['atkinlehner'] = list() # for Q in alev.keys(): # s = "\(" + latex(c) + "\)" # Q = alev[c][0] # ev = alev[c][1] # info['atkinlehner'].append([Q, c, ev]) if(level == 1): poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6','') if poly != '': d,monom,coeffs = poly emf_logger.critical("poly={0}".format(poly)) info['explicit_formulas'] = '\(' for i in range(len(coeffs)): c = QQ(coeffs[i]) s = "" if d>1 and i >0 and c>0: s="+" if c<0: s="-" if c.denominator()>1: cc = "\\frac{{ {0} }}{{ {1} }}".format(abs(c.numerator()),c.denominator()) else: cc = str(abs(c)) s += "{0} \cdot ".format(cc) a = monom[i][0]; b = monom[i][1] if a == 0 and b != 0: s+="E_6^{{ {0} }}".format(b) elif b ==0 and a != 0: s+="E_4^{{ {0} }}".format(a) else: s+="E_4^{{ {0} }}E_6^{{ {1} }}".format(a,b) info['explicit_formulas'] += s info['explicit_formulas'] += " \)" # cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + '&label=' + str(label) # never used if len(WNF.parent.hecke_orbits) > 1: for label_other in WNF.parent.hecke_orbits.keys(): if(label_other != label): s = 'Modular form ' if character: s += newform_label(level,weight,character,label_other) else: s += newform_label(level,weight,1,label_other) url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label_other) friends.append((s, url)) s = 'L-Function ' if character: s += newform_label(level,weight,character,label) else: s += newform_label(level,weight,1,label) # url = # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s" # %(level,weight,character,label,0) url = '/L' + url_for( 'emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label) if WNF.coefficient_field_degree > 1: for h in range(WNF.coefficient_field_degree): s0 = s + ".{0}".format(h) url0 = url + "{0}/".format(h) friends.append((s0, url0)) else: friends.append((s, url)) # if there is an elliptic curve over Q associated to self we also list that if WNF.weight == 2 and WNF.coefficient_field_degree == 1: llabel = str(level) + '.' + label s = 'Elliptic curve isogeny class ' + llabel url = '/EllipticCurve/Q/' + llabel friends.append((s, url)) info['properties2'] = properties2 info['friends'] = friends info['max_cn'] = WNF.max_available_prec() return info
def make_class(self): # Create a list of the curves in the class from the database self.db_curves = [ c for c in db_ecnf().find({ 'field_label': self.field_label, 'conductor_norm': self.conductor_norm, 'conductor_label': self.conductor_label, 'iso_nlabel': self.iso_nlabel }).sort('number') ] # Rank or bounds try: self.rk = web_latex(self.db_curves[0]['rank']) except KeyError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.db_curves[0]['rank_bounds']) except KeyError: self.rank_bounds = [0, Infinity] self.rk_bnds = "not recorded" # Extract the isogeny degree matrix from the database if not hasattr(self, 'isogeny_matrix'): # this would happen if the class is initiated with a curve # which is not #1 in its class: self.isogeny_matrix = self.db_curves[0].isogeny_matrix self.isogeny_matrix = Matrix(self.isogeny_matrix) self.one_deg = ZZ(self.class_deg).is_prime() # Create isogeny graph: self.graph = make_graph(self.isogeny_matrix) P = self.graph.plot(edge_labels=True) self.graph_img = encode_plot(P) self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img self.isogeny_matrix_str = latex(Matrix(self.isogeny_matrix)) self.field = FIELD(self.field_label) self.field_name = field_pretty(self.field_label) self.field_knowl = nf_display_knowl(self.field_label, lmfdb.base.getDBConnection(), self.field_name) def curve_url(c): return url_for(".show_ecnf", nf=c['field_label'], conductor_label=c['conductor_label'], class_label=c['iso_label'], number=c['number']) self.curves = [[ c['short_label'], curve_url(c), web_ainvs(self.field_label, c['ainvs']) ] for c in self.db_curves] self.urls = {} self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=self.conductor_label) self.urls['field'] = url_for('.show_ecnf1', nf=self.field_label) sig = self.signature totally_real = sig[1] == 0 imag_quadratic = sig == [0, 1] if totally_real: self.hmf_label = "-".join( [self.field_label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field_label, label=self.hmf_label) if sig[0] <= 2: self.urls['Lfunction'] = url_for( "l_functions.l_function_ecnf_page", field_label=self.field_label, conductor_label=self.conductor_label, isogeny_class_label=self.iso_label) elif self.abs_disc**2 * self.conductor_norm < 40000: # we shouldn't trust the Lfun computed on the fly for large conductor self.urls['Lfunction'] = url_for( "l_functions.l_function_hmf_page", field=self.field_label, label=self.hmf_label, character='0', number='0') if imag_quadratic: self.bmf_label = "-".join( [self.field_label, self.conductor_label, self.iso_label]) self.bmf_url = url_for('bmf.render_bmf_webpage', field_label=self.field_label, level_label=self.conductor_label, label_suffix=self.iso_label) self.urls['Lfunction'] = url_for( "l_functions.l_function_ecnf_page", field_label=self.field_label, conductor_label=self.conductor_label, isogeny_class_label=self.iso_label) self.friends = [] if totally_real: self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])] if imag_quadratic: #self.friends += [('Bianchi Modular Form %s not available' % self.bmf_label, '')] self.friends += [('Bianchi Modular Form %s' % self.bmf_label, self.bmf_url)] if 'Lfunction' in self.urls: self.friends += [('L-function', self.urls['Lfunction'])] else: self.friends += [('L-function not available', "")] self.properties = [('Base field', self.field_name), ('Label', self.class_label), (None, self.graph_link), ('Conductor', '%s' % self.conductor_label)] if self.rk != '?': self.properties += [('Rank', '%s' % self.rk)] else: if self.rk_bnds == 'not recorded': self.properties += [('Rank', '%s' % self.rk_bnds)] else: self.properties += [('Rank bounds', '%s' % self.rk_bnds)] self.bread = [('Elliptic Curves ', url_for(".index")), (self.field_label, self.urls['field']), (self.conductor_label, self.urls['conductor']), ('isogeny class %s' % self.short_label, self.urls['class'])]
def make_class(self): # Create a list of the curves in the class from the database self.db_curves = list(db.ec_nfcurves.search( {'field_label': self.field_label, 'conductor_norm': self.conductor_norm, 'conductor_label': self.conductor_label, 'iso_nlabel': self.iso_nlabel})) # Rank or bounds try: self.rk = web_latex(self.db_curves[0]['rank']) except KeyError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.db_curves[0]['rank_bounds']) except KeyError: self.rank_bounds = [0, Infinity] self.rk_bnds = "not recorded" # Extract the isogeny degree matrix from the database if not hasattr(self, 'isogeny_matrix'): # this would happen if the class is initiated with a curve # which is not #1 in its class: self.isogeny_matrix = self.db_curves[0].isogeny_matrix self.isogeny_matrix = Matrix(self.isogeny_matrix) self.one_deg = ZZ(self.class_deg).is_prime() # Create isogeny graph: self.graph = make_graph(self.isogeny_matrix) P = self.graph.plot(edge_labels=True) self.graph_img = encode_plot(P) self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img self.isogeny_matrix_str = latex(Matrix(self.isogeny_matrix)) self.field = FIELD(self.field_label) self.field_name = field_pretty(self.field_label) self.field_knowl = nf_display_knowl(self.field_label, self.field_name) def curve_url(c): return url_for(".show_ecnf", nf=c['field_label'], conductor_label=c['conductor_label'], class_label=c['iso_label'], number=c['number']) self.curves = [[c['short_label'], curve_url(c), web_ainvs(self.field_label,c['ainvs'])] for c in self.db_curves] self.urls = {} self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=self.conductor_label) self.urls['field'] = url_for('.show_ecnf1', nf=self.field_label) sig = self.signature totally_real = sig[1] == 0 imag_quadratic = sig == [0,1] if totally_real: self.hmf_label = "-".join([self.field_label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field_label, label=self.hmf_label) if sig[0] <= 2: self.urls['Lfunction'] = url_for("l_functions.l_function_ecnf_page", field_label=self.field_label, conductor_label=self.conductor_label, isogeny_class_label=self.iso_label) elif self.abs_disc ** 2 * self.conductor_norm < 40000: # we shouldn't trust the Lfun computed on the fly for large conductor self.urls['Lfunction'] = url_for("l_functions.l_function_hmf_page", field=self.field_label, label=self.hmf_label, character='0', number='0') if imag_quadratic: self.bmf_label = "-".join([self.field_label, self.conductor_label, self.iso_label]) self.bmf_url = url_for('bmf.render_bmf_webpage', field_label=self.field_label, level_label=self.conductor_label, label_suffix=self.iso_label) self.urls['Lfunction'] = url_for("l_functions.l_function_ecnf_page", field_label=self.field_label, conductor_label=self.conductor_label, isogeny_class_label=self.iso_label) self.friends = [] if totally_real: self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])] if imag_quadratic: #self.friends += [('Bianchi Modular Form %s not available' % self.bmf_label, '')] self.friends += [('Bianchi Modular Form %s' % self.bmf_label, self.bmf_url)] if 'Lfunction' in self.urls: self.friends += [('L-function', self.urls['Lfunction'])] else: self.friends += [('L-function not available', "")] self.properties = [('Base field', self.field_name), ('Label', self.class_label), (None, self.graph_link), ('Conductor', '%s' % self.conductor_label) ] if self.rk != '?': self.properties += [('Rank', '%s' % self.rk)] else: if self.rk_bnds == 'not recorded': self.properties += [('Rank', '%s' % self.rk_bnds)] else: self.properties += [('Rank bounds', '%s' % self.rk_bnds)] self.bread = [('Elliptic Curves ', url_for(".index")), (self.field_label, self.urls['field']), (self.conductor_label, self.urls['conductor']), ('isogeny class %s' % self.short_label, self.urls['class'])]
nf, cond_label, iso_label, number = split_full_label(label.strip()) except ValueError: info['err'] = '' bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')] return search_input_error(info, bread) return redirect(url_for(".show_ecnf", nf=nf, conductor_label=cond_label, class_label=iso_label, number=number), 301) @search_wrap(template="ecnf-search-results.html", table=db.ec_nfcurves, title='Elliptic Curve Search Results', err_title='Elliptic Curve Search Input Error', shortcuts={'jump':elliptic_curve_jump, 'download':download_search}, cleaners={'numb':lambda e: str(e['number']), 'field_knowl':lambda e: nf_display_knowl(e['field_label'], field_pretty(e['field_label']))}, bread=lambda:[('Elliptic Curves', url_for(".index")), ('Search Results', '.')], credit=lambda:ecnf_credit) def elliptic_curve_search(info, query): parse_nf_string(info,query,'field',name="base number field",qfield='field_label') if query.get('field_label') == '1.1.1.1': return redirect(url_for("ec.rational_elliptic_curves", **request.args), 301) parse_ints(info,query,'conductor_norm') parse_noop(info,query,'conductor_label') parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2) if 'torsion_structure' in query and not 'torsion_order' in query: query['torsion_order'] = reduce(mul,[int(n) for n in query['torsion_structure']],1) parse_ints(info,query,field='isodeg',qfield='isogeny_degrees')
def elliptic_curve_search(**args): info = to_dict(args['data']) if 'jump' in info: label = info.get('label', '').replace(" ", "") label_parts = label.split("-",1) nf = label_parts[0] label = label_parts[1] return show_ecnf(nf,label) query = {} if 'conductor_norm' in info: Nnorm = clean_input(info['conductor_norm']) Nnorm = Nnorm.replace('..', '-').replace(' ', '') tmp = parse_range2(Nnorm, 'conductor_norm') if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'include_isogenous' in info and info['include_isogenous'] == 'off': query['number'] = 1 if 'field' in info: query['field_label'] = info['field'] info['query'] = query # process count and start if not default: count_default = 20 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default start_default = 0 if info.get('start'): try: start = int(info['start']) if(start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_label', ASC), ('number', ASC)]).skip(start).limit(count) bread = []#[('Elliptic Curves over Number Fields', url_for(".elliptic_curve_search")), ] bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')] res = list(res) for e in res: e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label']) info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curve search results' return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def render_bmf_space_webpage(field_label, level_label): info = {} t = "Bianchi modular forms of level %s over %s" % (level_label, field_label) credit = bianchi_credit bread = [('Modular Forms', url_for('mf.modular_form_main_page')), ('Bianchi Modular Forms', url_for(".index")), (field_pretty(field_label), url_for(".render_bmf_field_dim_table_gl2", field_label=field_label)), (level_label, '')] friends = [] properties2 = [] if not field_label_regex.match(field_label): info['err'] = "%s is not a valid label for an imaginary quadratic field" % field_label else: pretty_field_label = field_pretty(field_label) if not db_dims().find({'field_label': field_label}): info['err'] = "no dimension information exists in the database for field %s" % pretty_field_label else: t = "Bianchi Modular Forms of level %s over %s" % (level_label, pretty_field_label) data = db_dims().find({'field_label': field_label, 'level_label': level_label}) nres = data.count() if nres==0: info['err'] = "no dimension information exists in the database for level %s and field %s" % (level_label, pretty_field_label) else: data = data.next() info['label'] = data['label'] info['nf'] = nf = WebNumberField(field_label) info['field_label'] = field_label info['pretty_field_label'] = pretty_field_label info['level_label'] = level_label info['level_norm'] = data['level_norm'] info['field_poly'] = teXify_pol(str(nf.poly())) info['field_knowl'] = nf_display_knowl(field_label, getDBConnection(), pretty_field_label) w = 'i' if nf.disc()==-4 else 'a' L = nf.K().change_names(w) alpha = L.gen() info['field_gen'] = latex(alpha) I = ideal_from_label(L,level_label) info['level_gen'] = latex(I.gens_reduced()[0]) info['level_fact'] = web_latex_ideal_fact(I.factor(), enclose=False) dim_data = data['gl2_dims'] weights = dim_data.keys() weights.sort(key=lambda w: int(w)) for w in weights: dim_data[w]['dim']=dim_data[w]['cuspidal_dim'] info['dim_data'] = dim_data info['weights'] = weights info['nweights'] = len(weights) newdim = data['gl2_dims']['2']['new_dim'] newforms = db_forms().find({'field_label':field_label, 'level_label':level_label}).sort('label_suffix', ASCENDING) info['nfdata'] = [{ 'label': f['short_label'], 'url': url_for(".render_bmf_webpage",field_label=f['field_label'], level_label=f['level_label'], label_suffix=f['label_suffix']), 'wt': f['weight'], 'dim': f['dimension'], 'sfe': "+1" if f['sfe']==1 else "-1", 'bc': bc_info(f['bc']), 'cm': cm_info(f['CM']), } for f in newforms] info['nnewforms'] = len(info['nfdata']) properties2 = [('Base field', pretty_field_label), ('Level',info['level_label']), ('Norm',str(info['level_norm'])), ('New dimension',str(newdim))] friends = [('Newform {}'.format(f['label']), f['url']) for f in info['nfdata'] ] return render_template("bmf-space.html", info=info, credit=credit, title=t, bread=bread, properties2=properties2, friends=friends)
def make_object(self, curve, endo, tama, ratpts, is_curve): from lmfdb.genus2_curves.main import url_for_curve_label # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary # most of the data from the database gets polished/formatted before we put it in the data dictionary data = self.data = {} data['label'] = curve['label'] if is_curve else curve['class'] data['slabel'] = data['label'].split('.') # set attributes common to curves and isogeny classes here data['Lhash'] = curve['Lhash'] data['cond'] = ZZ(curve['cond']) data['cond_factor_latex'] = web_latex(factor(int(data['cond']))) data['analytic_rank'] = ZZ(curve['analytic_rank']) data['st_group'] = curve['st_group'] data['st_group_link'] = st_link_by_name(1,4,data['st_group']) data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg']) data['is_gl2_type'] = curve['is_gl2_type'] data['root_number'] = ZZ(curve['root_number']) data['lfunc_url'] = url_for("l_functions.l_function_genus2_page", cond=data['slabel'][0], x=data['slabel'][1]) data['bad_lfactors'] = literal_eval(curve['bad_lfactors']) data['bad_lfactors_pretty'] = [ (c[0], list_to_factored_poly_otherorder(c[1])) for c in data['bad_lfactors']] if is_curve: # invariants specific to curve data['class'] = curve['class'] data['abs_disc'] = ZZ(curve['disc_key'][3:]) # use disc_key rather than abs_disc (will work when abs_disc > 2^63) data['disc'] = curve['disc_sign'] * curve['abs_disc'] data['min_eqn'] = literal_eval(curve['eqn']) data['min_eqn_display'] = list_to_min_eqn(data['min_eqn']) data['disc_factor_latex'] = web_latex(factor(data['disc'])) data['igusa_clebsch'] = [ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv'])] data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])] data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])] data['igusa_clebsch_factor_latex'] = [web_latex(zfactor(i)) for i in data['igusa_clebsch']] data['igusa_factor_latex'] = [ web_latex(zfactor(j)) for j in data['igusa'] ] data['aut_grp_id'] = curve['aut_grp_id'] data['geom_aut_grp_id'] = curve['geom_aut_grp_id'] data['num_rat_wpts'] = ZZ(curve['num_rat_wpts']) data['two_selmer_rank'] = ZZ(curve['two_selmer_rank']) data['has_square_sha'] = "square" if curve['has_square_sha'] else "twice a square" P = curve['non_solvable_places'] if len(P): sz = "except over " sz += ", ".join([QpName(p) for p in P]) last = " and" if len(P) > 2: last = ", and" sz = last.join(sz.rsplit(",",1)) else: sz = "everywhere" data['non_solvable_places'] = sz data['torsion_order'] = curve['torsion_order'] data['torsion_factors'] = [ ZZ(a) for a in literal_eval(curve['torsion_subgroup']) ] if len(data['torsion_factors']) == 0: data['torsion_subgroup'] = '\mathrm{trivial}' else: data['torsion_subgroup'] = ' \\times '.join([ '\Z/{%s}\Z' % n for n in data['torsion_factors'] ]) data['end_ring_base'] = endo['ring_base'] data['end_ring_geom'] = endo['ring_geom'] data['tama'] = '' for i in range(tama.count()): item = tama.next() if item['tamagawa_number'] > 0: tamgwnr = str(item['tamagawa_number']) else: tamgwnr = 'N/A' data['tama'] += tamgwnr + ' (p = ' + str(item['p']) + ')' if (i+1 < tama.count()): data['tama'] += ', ' if ratpts: if len(ratpts['rat_pts']): data['rat_pts'] = ', '.join(web_latex('(' +' : '.join(P) + ')') for P in ratpts['rat_pts']) data['rat_pts_v'] = 2 if ratpts['rat_pts_v'] else 1 # data['mw_rank'] = ratpts['mw_rank'] # data['mw_rank_v'] = ratpts['mw_rank_v'] else: data['rat_pts_v'] = 0 if curve['two_torsion_field'][0]: data['two_torsion_field_knowl'] = nf_display_knowl (curve['two_torsion_field'][0], getDBConnection(), field_pretty(curve['two_torsion_field'][0])) else: t = curve['two_torsion_field'] data['two_torsion_field_knowl'] = """splitting field of \(%s\) with Galois group %s"""%(intlist_to_poly(t[1]),group_display_knowl(t[2][0],t[2][1],getDBConnection())) else: # invariants specific to isogeny class curves_data = g2c_db_curves().find({"class" : curve['class']},{'_id':int(0),'label':int(1),'eqn':int(1),'disc_key':int(1)}).sort([("disc_key", ASCENDING), ("label", ASCENDING)]) if not curves_data: raise KeyError("No curves found in database for isogeny class %s of genus 2 curve %s." %(curve['class'],curve['label'])) data['curves'] = [ {"label" : c['label'], "equation_formatted" : list_to_min_eqn(literal_eval(c['eqn'])), "url": url_for_curve_label(c['label'])} for c in curves_data ] lfunc_data = g2c_db_lfunction_by_hash(curve['Lhash']) if not lfunc_data: raise KeyError("No Lfunction found in database for isogeny class of genus 2 curve %s." %curve['label']) if lfunc_data and lfunc_data.get('euler_factors'): data['good_lfactors'] = [[nth_prime(n+1),lfunc_data['euler_factors'][n]] for n in range(len(lfunc_data['euler_factors'])) if nth_prime(n+1) < 30 and (data['cond'] % nth_prime(n+1))] data['good_lfactors_pretty'] = [ (c[0], list_to_factored_poly_otherorder(c[1])) for c in data['good_lfactors']] # Endomorphism data over QQ: data['gl2_statement_base'] = gl2_statement_base(endo['factorsRR_base'], r'\(\Q\)') data['factorsQQ_base'] = endo['factorsQQ_base'] data['factorsRR_base'] = endo['factorsRR_base'] data['end_statement_base'] = """Endomorphism %s over \(\Q\):<br>""" %("ring" if is_curve else "algebra") + \ end_statement(data['factorsQQ_base'], endo['factorsRR_base'], ring=data['end_ring_base'] if is_curve else None) # Field over which all endomorphisms are defined data['end_field_label'] = endo['fod_label'] data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs']) data['end_field_statement'] = end_field_statement(data['end_field_label'], data['end_field_poly']) # Endomorphism data over QQbar: data['factorsQQ_geom'] = endo['factorsQQ_geom'] data['factorsRR_geom'] = endo['factorsRR_geom'] if data['end_field_label'] != '1.1.1.1': data['gl2_statement_geom'] = gl2_statement_base(data['factorsRR_geom'], r'\(\overline{\Q}\)') data['end_statement_geom'] = """Endomorphism %s over \(\overline{\Q}\):""" %("ring" if is_curve else "algebra") + \ end_statement(data['factorsQQ_geom'], data['factorsRR_geom'], field=r'\overline{\Q}', ring=data['end_ring_geom'] if is_curve else None) data['real_geom_end_alg_name'] = end_alg_name(curve['real_geom_end_alg']) # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant): if is_curve: data['end_lattice'] = (endo['lattice'])[1:-1] if data['end_lattice']: data['end_lattice_statement'] = end_lattice_statement(data['end_lattice']) # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple) data['is_simple_geom'] = endo['is_simple_geom'] data['split_field_label'] = endo['spl_fod_label'] data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs']) data['split_field_statement'] = split_field_statement(data['is_simple_geom'], data['split_field_label'], data['split_field_poly']) # Elliptic curve factors for non-simple Jacobians if not data['is_simple_geom']: data['split_coeffs'] = endo['spl_facs_coeffs'] if 'spl_facs_labels' in endo and len(endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']): data['split_labels'] = endo['spl_facs_labels'] data['split_condnorms'] = endo['spl_facs_condnorms'] data['split_statement'] = split_statement(data['split_coeffs'], data.get('split_labels'), data['split_condnorms']) # Properties self.properties = properties = [('Label', data['label'])] if is_curve: self.plot = encode_plot(eqn_list_to_curve_plot(data['min_eqn'], data['rat_pts'].split(',') if 'rat_pts' in data else [])) plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(self.plot) properties += [ (None, plot_link), ('Conductor',str(data['cond'])), ('Discriminant', str(data['disc'])), ] properties += [ ('Sato-Tate group', data['st_group_link']), ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\R\)', '\(%s\)' % data['real_geom_end_alg_name']), ('\(\\overline{\\Q}\)-simple', bool_pretty(data['is_simple_geom'])), ('\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])), ] # Friends self.friends = friends = [('L-function', data['lfunc_url'])] if is_curve: friends.append(('Isogeny class %s.%s' % (data['slabel'][0], data['slabel'][1]), url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1]))) for friend in g2c_db_lfunction_instances().find({'Lhash':data['Lhash']},{'_id':False,'url':True}): if 'url' in friend: add_friend (friends, lfunction_friend_from_url(friend['url'])) if 'urls' in friend: for url in friends['urls']: add_friend (friends, lfunction_friend_from_url(friend['url'])) if 'split_labels' in data: for friend_label in data['split_labels']: if is_curve: add_friend (friends, ("Elliptic curve " + friend_label, url_for_ec(friend_label))) else: add_friend (friends, ("EC isogeny class " + ec_label_class(friend_label), url_for_ec_class(friend_label))) if is_curve: friends.append(('Twists', url_for(".index_Q", g20 = str(data['g2'][0]), g21 = str(data['g2'][1]), g22 = str(data['g2'][2])))) # Breadcrumbs self.bread = bread = [ ('Genus 2 Curves', url_for(".index")), ('$\Q$', url_for(".index_Q")), ('%s' % data['slabel'][0], url_for(".by_conductor", cond=data['slabel'][0])), ('%s' % data['slabel'][1], url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1])) ] if is_curve: bread += [ ('%s' % data['slabel'][2], url_for(".by_url_isogeny_class_discriminant", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2])), ('%s' % data['slabel'][3], url_for(".by_url_curve_label", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2], num=data['slabel'][3])) ] # Title self.title = "Genus 2 " + ("Curve " if is_curve else "Isogeny Class ") + data['label'] # Code snippets (only for curves) if not is_curve: return self.code = code = {} code['show'] = {'sage':'','magma':''} # use default show names code['curve'] = {'sage':'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s))'%(data['min_eqn'][0],data['min_eqn'][1]), 'magma':'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'%(data['min_eqn'][0],data['min_eqn'][1])} if data['abs_disc'] % 4096 == 0: ind2 = [a[0] for a in data['bad_lfactors']].index(2) bad2 = data['bad_lfactors'][ind2][1] magma_cond_option = ': ExcFactors:=[*<2,Valuation('+str(data['cond'])+',2),R!'+str(bad2)+'>*]' else: magma_cond_option = '' code['cond'] = {'magma': 'Conductor(LSeries(C%s)); Factorization($1);'% magma_cond_option} code['disc'] = {'magma':'Discriminant(C); Factorization(Integers()!$1);'} code['igusa_clebsch'] = {'sage':'C.igusa_clebsch_invariants(); [factor(a) for a in _]', 'magma':'IgusaClebschInvariants(C); [Factorization(Integers()!a): a in $1];'} code['igusa'] = {'magma':'IgusaInvariants(C); [Factorization(Integers()!a): a in $1];'} code['g2'] = {'magma':'G2Invariants(C);'} code['aut'] = {'magma':'AutomorphismGroup(C); IdentifyGroup($1);'} code['autQbar'] = {'magma':'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);'} code['num_rat_wpts'] = {'magma':'#Roots(HyperellipticPolynomials(SimplifiedModel(C)));'} if ratpts: code['rat_pts'] = {'magma': '[' + ','.join(["C![%s,%s,%s]"%(p[0],p[1],p[2]) for p in ratpts['rat_pts']]) + '];' } code['two_selmer'] = {'magma':'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);'} code['has_square_sha'] = {'magma':'HasSquareSha(Jacobian(C));'} code['locally_solvable'] = {'magma':'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsEverywhereLocally(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);'} code['torsion_subgroup'] = {'magma':'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);'}
def make_object(self, curve, endo, tama, ratpts, is_curve): from lmfdb.genus2_curves.main import url_for_curve_label # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary # most of the data from the database gets polished/formatted before we put it in the data dictionary data = self.data = {} data['label'] = curve['label'] if is_curve else curve['class'] data['slabel'] = data['label'].split('.') # set attributes common to curves and isogeny classes here data['Lhash'] = str(curve['Lhash']) data['cond'] = ZZ(curve['cond']) data['cond_factor_latex'] = web_latex(factor(int(data['cond']))) data['analytic_rank'] = ZZ(curve['analytic_rank']) data['st_group'] = curve['st_group'] data['st_group_link'] = st_link_by_name(1, 4, data['st_group']) data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg']) data['is_gl2_type'] = curve['is_gl2_type'] data['root_number'] = ZZ(curve['root_number']) data['lfunc_url'] = url_for("l_functions.l_function_genus2_page", cond=data['slabel'][0], x=data['slabel'][1]) data['bad_lfactors'] = literal_eval(curve['bad_lfactors']) data['bad_lfactors_pretty'] = [(c[0], list_to_factored_poly_otherorder(c[1])) for c in data['bad_lfactors']] if is_curve: # invariants specific to curve data['class'] = curve['class'] data['abs_disc'] = ZZ(curve['abs_disc']) data['disc'] = curve['disc_sign'] * data['abs_disc'] data['min_eqn'] = literal_eval(curve['eqn']) data['min_eqn_display'] = list_to_min_eqn(data['min_eqn']) data['disc_factor_latex'] = web_latex(factor(data['disc'])) data['igusa_clebsch'] = [ ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv']) ] data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])] data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])] data['igusa_clebsch_factor_latex'] = [ web_latex(zfactor(i)) for i in data['igusa_clebsch'] ] data['igusa_factor_latex'] = [ web_latex(zfactor(j)) for j in data['igusa'] ] data['aut_grp_id'] = curve['aut_grp_id'] data['geom_aut_grp_id'] = curve['geom_aut_grp_id'] data['num_rat_wpts'] = ZZ(curve['num_rat_wpts']) data['two_selmer_rank'] = ZZ(curve['two_selmer_rank']) data['has_square_sha'] = "square" if curve[ 'has_square_sha'] else "twice a square" P = curve['non_solvable_places'] if len(P): sz = "except over " sz += ", ".join([QpName(p) for p in P]) last = " and" if len(P) > 2: last = ", and" sz = last.join(sz.rsplit(",", 1)) else: sz = "everywhere" data['non_solvable_places'] = sz data['torsion_order'] = curve['torsion_order'] data['torsion_factors'] = [ ZZ(a) for a in literal_eval(curve['torsion_subgroup']) ] if len(data['torsion_factors']) == 0: data['torsion_subgroup'] = '\mathrm{trivial}' else: data['torsion_subgroup'] = ' \\times '.join( ['\Z/{%s}\Z' % n for n in data['torsion_factors']]) data['end_ring_base'] = endo['ring_base'] data['end_ring_geom'] = endo['ring_geom'] data['tama'] = '' for item in tama: if item['tamagawa_number'] > 0: tamgwnr = str(item['tamagawa_number']) else: tamgwnr = 'N/A' data['tama'] += tamgwnr + ' (p = ' + str(item['p']) + '), ' data['tama'] = data['tama'][:-2] # trim last ", " if ratpts: if len(ratpts['rat_pts']): data['rat_pts'] = ', '.join( web_latex('(' + ' : '.join(map(str, P)) + ')') for P in ratpts['rat_pts']) data['rat_pts_v'] = 2 if ratpts['rat_pts_v'] else 1 # data['mw_rank'] = ratpts['mw_rank'] # data['mw_rank_v'] = ratpts['mw_rank_v'] else: data['rat_pts_v'] = 0 if curve['two_torsion_field'][0]: data['two_torsion_field_knowl'] = nf_display_knowl( curve['two_torsion_field'][0], field_pretty(curve['two_torsion_field'][0])) else: t = curve['two_torsion_field'] data[ 'two_torsion_field_knowl'] = """splitting field of \(%s\) with Galois group %s""" % ( intlist_to_poly( t[1]), group_display_knowl(t[2][0], t[2][1])) else: # invariants specific to isogeny class curves_data = list( db.g2c_curves.search({"class": curve['class']}, ['label', 'eqn'])) if not curves_data: raise KeyError( "No curves found in database for isogeny class %s of genus 2 curve %s." % (curve['class'], curve['label'])) data['curves'] = [{ "label": c['label'], "equation_formatted": list_to_min_eqn(literal_eval(c['eqn'])), "url": url_for_curve_label(c['label']) } for c in curves_data] lfunc_data = db.lfunc_lfunctions.lucky( {'Lhash': str(curve['Lhash'])}) if not lfunc_data: raise KeyError( "No Lfunction found in database for isogeny class of genus 2 curve %s." % curve['label']) if lfunc_data and lfunc_data.get('euler_factors'): data['good_lfactors'] = [ [nth_prime(n + 1), lfunc_data['euler_factors'][n]] for n in range(len(lfunc_data['euler_factors'])) if nth_prime(n + 1) < 30 and (data['cond'] % nth_prime(n + 1)) ] data['good_lfactors_pretty'] = [ (c[0], list_to_factored_poly_otherorder(c[1])) for c in data['good_lfactors'] ] # Endomorphism data over QQ: data['gl2_statement_base'] = gl2_statement_base( endo['factorsRR_base'], r'\(\Q\)') data['factorsQQ_base'] = endo['factorsQQ_base'] data['factorsRR_base'] = endo['factorsRR_base'] data['end_statement_base'] = """Endomorphism %s over \(\Q\):<br>""" %("ring" if is_curve else "algebra") + \ end_statement(data['factorsQQ_base'], endo['factorsRR_base'], ring=data['end_ring_base'] if is_curve else None) # Field over which all endomorphisms are defined data['end_field_label'] = endo['fod_label'] data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs']) data['end_field_statement'] = end_field_statement( data['end_field_label'], data['end_field_poly']) # Endomorphism data over QQbar: data['factorsQQ_geom'] = endo['factorsQQ_geom'] data['factorsRR_geom'] = endo['factorsRR_geom'] if data['end_field_label'] != '1.1.1.1': data['gl2_statement_geom'] = gl2_statement_base( data['factorsRR_geom'], r'\(\overline{\Q}\)') data['end_statement_geom'] = """Endomorphism %s over \(\overline{\Q}\):""" %("ring" if is_curve else "algebra") + \ end_statement(data['factorsQQ_geom'], data['factorsRR_geom'], field=r'\overline{\Q}', ring=data['end_ring_geom'] if is_curve else None) data['real_geom_end_alg_name'] = end_alg_name( curve['real_geom_end_alg']) # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant): if is_curve: data['end_lattice'] = (endo['lattice'])[1:-1] if data['end_lattice']: data['end_lattice_statement'] = end_lattice_statement( data['end_lattice']) # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple) data['is_simple_geom'] = endo['is_simple_geom'] data['split_field_label'] = endo['spl_fod_label'] data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs']) data['split_field_statement'] = split_field_statement( data['is_simple_geom'], data['split_field_label'], data['split_field_poly']) # Elliptic curve factors for non-simple Jacobians if not data['is_simple_geom']: data['split_coeffs'] = endo['spl_facs_coeffs'] if 'spl_facs_labels' in endo and len( endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']): data['split_labels'] = endo['spl_facs_labels'] data['split_condnorms'] = endo['spl_facs_condnorms'] data['split_statement'] = split_statement(data['split_coeffs'], data.get('split_labels'), data['split_condnorms']) # Properties self.properties = properties = [('Label', data['label'])] if is_curve: self.plot = encode_plot( eqn_list_to_curve_plot( data['min_eqn'], data['rat_pts'].split(',') if 'rat_pts' in data else [])) plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format( self.plot) properties += [ (None, plot_link), ('Conductor', str(data['cond'])), ('Discriminant', str(data['disc'])), ] properties += [ ('Sato-Tate group', data['st_group_link']), ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\R\)', '\(%s\)' % data['real_geom_end_alg_name']), ('\(\\overline{\\Q}\)-simple', bool_pretty(data['is_simple_geom'])), ('\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])), ] # Friends self.friends = friends = [('L-function', data['lfunc_url'])] if is_curve: friends.append(('Isogeny class %s.%s' % (data['slabel'][0], data['slabel'][1]), url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1]))) for friend_url in db.lfunc_instances.search({'Lhash': data['Lhash']}, 'url'): if '|' in friend_url: for url in friend_url.split('|'): add_friend(friends, lfunction_friend_from_url(url)) else: add_friend(friends, lfunction_friend_from_url(friend_url)) if 'split_labels' in data: for friend_label in data['split_labels']: if is_curve: add_friend(friends, ("Elliptic curve " + friend_label, url_for_ec(friend_label))) else: add_friend( friends, ("EC isogeny class " + ec_label_class(friend_label), url_for_ec_class(friend_label))) if is_curve: friends.append(('Twists', url_for(".index_Q", g20=str(data['g2'][0]), g21=str(data['g2'][1]), g22=str(data['g2'][2])))) # Breadcrumbs self.bread = bread = [('Genus 2 Curves', url_for(".index")), ('$\Q$', url_for(".index_Q")), ('%s' % data['slabel'][0], url_for(".by_conductor", cond=data['slabel'][0])), ('%s' % data['slabel'][1], url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1]))] if is_curve: bread += [('%s' % data['slabel'][2], url_for(".by_url_isogeny_class_discriminant", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2])), ('%s' % data['slabel'][3], url_for(".by_url_curve_label", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2], num=data['slabel'][3]))] # Title self.title = "Genus 2 " + ("Curve " if is_curve else "Isogeny Class ") + data['label'] # Code snippets (only for curves) if not is_curve: return self.code = code = {} code['show'] = {'sage': '', 'magma': ''} # use default show names code['curve'] = { 'sage': 'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s))' % (data['min_eqn'][0], data['min_eqn'][1]), 'magma': 'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);' % (data['min_eqn'][0], data['min_eqn'][1]) } if data['abs_disc'] % 4096 == 0: ind2 = [a[0] for a in data['bad_lfactors']].index(2) bad2 = data['bad_lfactors'][ind2][1] magma_cond_option = ': ExcFactors:=[*<2,Valuation(' + str( data['cond']) + ',2),R!' + str(bad2) + '>*]' else: magma_cond_option = '' code['cond'] = { 'magma': 'Conductor(LSeries(C%s)); Factorization($1);' % magma_cond_option } code['disc'] = { 'magma': 'Discriminant(C); Factorization(Integers()!$1);' } code['igusa_clebsch'] = { 'sage': 'C.igusa_clebsch_invariants(); [factor(a) for a in _]', 'magma': 'IgusaClebschInvariants(C); [Factorization(Integers()!a): a in $1];' } code['igusa'] = { 'magma': 'IgusaInvariants(C); [Factorization(Integers()!a): a in $1];' } code['g2'] = {'magma': 'G2Invariants(C);'} code['aut'] = {'magma': 'AutomorphismGroup(C); IdentifyGroup($1);'} code['autQbar'] = { 'magma': 'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);' } code['num_rat_wpts'] = { 'magma': '#Roots(HyperellipticPolynomials(SimplifiedModel(C)));' } if ratpts: code['rat_pts'] = { 'magma': '[' + ','.join([ "C![%s,%s,%s]" % (p[0], p[1], p[2]) for p in ratpts['rat_pts'] ]) + '];' } code['two_selmer'] = { 'magma': 'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);' } code['has_square_sha'] = {'magma': 'HasSquareSha(Jacobian(C));'} code['locally_solvable'] = { 'magma': 'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsEverywhereLocally(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);' } code['torsion_subgroup'] = { 'magma': 'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);' }
def display_number_field(self): if self.nf == "": return "The number field of this isogeny class is not in the database." else: return nf_display_knowl(self.nf, field_pretty(self.nf))
def display_number_field(self): if self.number_field == "": return "The number field of this isogeny class is not in the database." else: C = getDBConnection() return nf_display_knowl(self.number_field,C,field_pretty(self.number_field))
def elliptic_curve_search(**args): info = to_dict(args["data"]) if "jump" in info: label = info.get("label", "").replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label) except IndexError: if not "query" in info: info["query"] = {} bread = [("Elliptic Curves", url_for(".index"))] info["err"] = "No elliptic curve in the database has label %s." % label return search_input_error(info, bread) return show_ecnf(nf, cond_label, iso_label, number) query = {} bread = [("Elliptic Curves", url_for(".index")), ("Search Results", ".")] if "conductor_norm" in info: Nnorm = clean_input(info["conductor_norm"]) Nnorm = Nnorm.replace("..", "-").replace(" ", "") tmp = parse_range2(Nnorm, "conductor_norm") if tmp[0] == "$or" and "$or" in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query["$or"]] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if "conductor_label" in info: query["conductor_label"] = info["conductor_label"] if "jinv" in info: query["jinv"] = info["jinv"] if info.get("torsion"): ran = info["torsion"] = clean_input(info["torsion"]) ran = ran.replace("..", "-").replace(" ", "") if not LIST_RE.match(ran): info[ "err" ] = "Error parsing input for the torsion order. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 4,9,16 or 4-25, 81-121)." return search_input_error(info, bread) # Past input check tmp = parse_range2(ran, "torsion_order") # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == "$or" and "$or" in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query["$or"]] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if "torsion_structure" in info and info["torsion_structure"]: res = parse_torsion_structure(info["torsion_structure"], 2) if "Error" in res: info["err"] = res return search_input_error(info, bread) # update info for repeat searches info["torsion_structure"] = str(res).replace(" ", "") query["torsion_structure"] = [int(r) for r in res] if "include_isogenous" in info and info["include_isogenous"] == "off": query["number"] = 1 if "include_base_change" in info and info["include_base_change"] == "off": query["base_change"] = [] else: info["include_base_change"] = "on" if "field" in info: query["field_label"] = parse_field_string(info["field"]) info["query"] = query # process count and start if not default: count_default = 50 if info.get("count"): try: count = int(info["count"]) except: count = count_default else: count = count_default start_default = 0 if info.get("start"): try: start = int(info["start"]) if start < 0: start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if start >= nres: start -= (1 + (start - nres) / count) * count if start < 0: start = 0 res = ( cursor.sort( [ ("field_label", ASC), ("conductor_norm", ASC), ("conductor_label", ASC), ("iso_label", ASC), ("number", ASC), ] ) .skip(start) .limit(count) ) res = list(res) for e in res: e["numb"] = str(e["number"]) e["field_knowl"] = nf_display_knowl(e["field_label"], getDBConnection(), e["field_label"]) info["curves"] = res # [ECNF(e) for e in res] info["number"] = nres info["start"] = start info["count"] = count info["more"] = int(start + count < nres) info["field_pretty"] = field_pretty info["web_ainvs"] = web_ainvs if nres == 1: info["report"] = "unique match" else: if nres > count or start != 0: info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres) else: info["report"] = "displaying all %s matches" % nres t = "Elliptic Curve search results" return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args['data']) if 'jump' in info: label = info.get('label', '').replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label) except IndexError: if not 'query' in info: info['query'] = {} bread = [("Elliptic Curves", url_for(".index"))] info['err'] = 'No elliptic curve in the database has label %s.' % label return search_input_error(info, bread) return show_ecnf(nf, cond_label, iso_label, number) query = {} bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')] if 'conductor_norm' in info: Nnorm = clean_input(info['conductor_norm']) Nnorm = Nnorm.replace('..', '-').replace(' ', '') tmp = parse_range2(Nnorm, 'conductor_norm') if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'conductor_label' in info: query['conductor_label'] = info['conductor_label'] if 'jinv' in info: query['jinv'] = info['jinv'] if info.get('torsion'): ran = info['torsion'] = clean_input(info['torsion']) ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): info['err'] = 'Error parsing input for the torsion order. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 4,9,16 or 4-25, 81-121).' return search_input_error(info, bread) # Past input check tmp = parse_range2(ran, 'torsion_order') # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'torsion_structure' in info and info['torsion_structure']: info['torsion_structure'] = clean_input(info['torsion_structure']) if not TORS_RE.match(info['torsion_structure']): info['err'] = 'Error parsing input for the torsion structure. It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4]. Moreover, each integer should be bigger than 1, and each divides the next.' return search_input_error(info, bread) query['torsion_structure'] = parse_list(info['torsion_structure']) if 'include_isogenous' in info and info['include_isogenous'] == 'off': query['number'] = 1 if 'include_base_change' in info and info['include_base_change'] == 'off': query['base_change'] = [] else: info['include_base_change'] = "on" if 'field' in info: query['field_label'] = parse_field_string(info['field']) info['query'] = query # process count and start if not default: count_default = 50 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default start_default = 0 if info.get('start'): try: start = int(info['start']) if(start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_label', ASC), ('number', ASC)]).skip(start).limit(count) res = list(res) for e in res: e['numb'] = str(e['number']) e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label']) info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curve search results' return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args['data']) if 'jump' in info: label = info.get('label', '').replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label.strip()) except IndexError: if not 'query' in info: info['query'] = {} bread = [("Elliptic Curves", url_for(".index"))] info[ 'err'] = 'No elliptic curve in the database has label %s.' % label return search_input_error(info, bread) return show_ecnf(nf, cond_label, iso_label, number) query = {} bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')] if 'conductor_norm' in info: Nnorm = clean_input(info['conductor_norm']) Nnorm = Nnorm.replace('..', '-').replace(' ', '') tmp = parse_range2(Nnorm, 'conductor_norm') if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'conductor_label' in info: query['conductor_label'] = info['conductor_label'] if 'jinv' in info: query['jinv'] = info['jinv'] if info.get('torsion'): ran = info['torsion'] = clean_input(info['torsion']) ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): info[ 'err'] = 'Error parsing input for the torsion order. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 4,9,16 or 4-25, 81-121).' return search_input_error(info, bread) # Past input check tmp = parse_range2(ran, 'torsion_order') # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'torsion_structure' in info and info['torsion_structure']: res = parse_torsion_structure(info['torsion_structure'], 2) if 'Error' in res: info['err'] = res return search_input_error(info, bread) #update info for repeat searches info['torsion_structure'] = str(res).replace(' ', '') query['torsion_structure'] = [int(r) for r in res] if 'include_isogenous' in info and info['include_isogenous'] == 'off': query['number'] = 1 if 'include_base_change' in info and info['include_base_change'] == 'off': query['base_change'] = [] else: info['include_base_change'] = "on" if 'field' in info: query['field_label'] = parse_field_string(info['field']) info['query'] = query # process count and start if not default: count_default = 50 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default start_default = 0 if info.get('start'): try: start = int(info['start']) if (start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_nlabel', ASC), ('number', ASC)]).skip(start).limit(count) res = list(res) for e in res: e['numb'] = str(e['number']) e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label']) info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curve search results' return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args["data"]) if "jump" in info: label = info.get("label", "").replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) label_parts = label.split("-", 2) nf = label_parts[0] cond_label = label_parts[1] cur_label = label_parts[2] return show_ecnf(nf, cond_label, cur_label) ##!!! query = {} if "conductor_norm" in info: Nnorm = clean_input(info["conductor_norm"]) Nnorm = Nnorm.replace("..", "-").replace(" ", "") tmp = parse_range2(Nnorm, "conductor_norm") if tmp[0] == "$or" and "$or" in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query["$or"]] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if "conductor_label" in info: query["conductor_label"] = info["conductor_label"] if "include_isogenous" in info and info["include_isogenous"] == "off": query["number"] = 1 if "field" in info: query["field_label"] = info["field"] info["query"] = query # process count and start if not default: count_default = 50 if info.get("count"): try: count = int(info["count"]) except: count = count_default else: count = count_default start_default = 0 if info.get("start"): try: start = int(info["start"]) if start < 0: start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if start >= nres: start -= (1 + (start - nres) / count) * count if start < 0: start = 0 res = ( cursor.sort( [ ("field_label", ASC), ("conductor_norm", ASC), ("conductor_label", ASC), ("iso_label", ASC), ("number", ASC), ] ) .skip(start) .limit(count) ) bread = [("Elliptic Curves", url_for(".index")), ("Search Results", ".")] res = list(res) for e in res: e["numb"] = str(e["number"]) e["field_knowl"] = nf_display_knowl(e["field_label"], getDBConnection(), e["field_label"]) info["curves"] = res # [ECNF(e) for e in res] info["number"] = nres info["start"] = start info["count"] = count info["more"] = int(start + count < nres) info["field_pretty"] = field_pretty info["web_ainvs"] = web_ainvs if nres == 1: info["report"] = "unique match" else: if nres > count or start != 0: info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres) else: info["report"] = "displaying all %s matches" % nres t = "Elliptic Curve search results" return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def render_bmf_space_webpage(field_label, level_label): info = {} t = "Bianchi modular forms of level %s over %s" % (level_label, field_label) credit = bianchi_credit bread = [('Bianchi modular forms', url_for(".index")), (field_pretty(field_label), url_for(".render_bmf_field_dim_table_gl2", field_label=field_label)), (level_label, '')] friends = [] properties2 = [] if not field_label_regex.match(field_label): info[ 'err'] = "%s is not a valid label for an imaginary quadratic field" % field_label else: pretty_field_label = field_pretty(field_label) if not db_dims().find({'field_label': field_label}): info[ 'err'] = "no dimension information exists in the database for field %s" % pretty_field_label else: t = "Bianchi Modular Forms of level %s over %s" % ( level_label, pretty_field_label) data = db_dims().find({ 'field_label': field_label, 'level_label': level_label }) nres = data.count() if nres == 0: info[ 'err'] = "no dimension information exists in the database for level %s and field %s" % ( level_label, pretty_field_label) else: data = data.next() info['label'] = data['label'] nf = WebNumberField(field_label) info['base_galois_group'] = nf.galois_string() info['field_label'] = field_label info['pretty_field_label'] = pretty_field_label info['level_label'] = level_label info['level_norm'] = data['level_norm'] info['field_degree'] = nf.degree() info['field_classno'] = nf.class_number() info['field_disc'] = str(nf.disc()) info['field_poly'] = teXify_pol(str(nf.poly())) info['field_knowl'] = nf_display_knowl(field_label, getDBConnection(), pretty_field_label) w = 'i' if nf.disc() == -4 else 'a' L = nf.K().change_names(w) alpha = L.gen() info['field_gen'] = latex(alpha) I = ideal_from_label(L, level_label) info['level_gen'] = latex(I.gens_reduced()[0]) info['level_fact'] = latex(I.factor()) dim_data = data['gl2_dims'] weights = dim_data.keys() weights.sort(key=lambda w: int(w)) for w in weights: dim_data[w]['dim'] = dim_data[w]['cuspidal_dim'] info['dim_data'] = dim_data info['weights'] = weights info['nweights'] = len(weights) newdim = data['gl2_dims']['2']['new_dim'] newforms = db_forms().find({ 'field_label': field_label, 'level_label': level_label }).sort('label_suffix', ASCENDING) info['nfdata'] = [{ 'label': f['short_label'], 'url': url_for(".render_bmf_webpage", field_label=f['field_label'], level_label=f['level_label'], label_suffix=f['label_suffix']), 'wt': f['weight'], 'dim': f['dimension'], 'sfe': "+1" if f['sfe'] == 1 else "-1", 'bc': bc_info(f['bc']), 'cm': cm_info(f['CM']), } for f in newforms] info['nnewforms'] = len(info['nfdata']) properties2 = [('Base field', pretty_field_label), ('Level', info['level_label']), ('Norm', str(info['level_norm'])), ('New dimension', str(newdim))] friends = [('Newform {}'.format(f['label']), f['url']) for f in info['nfdata']] return render_template("bmf-space.html", info=info, credit=credit, title=t, bread=bread, properties2=properties2, friends=friends)