def get_local_algebras(self): local_algs = self._data.get('local_algs', None) if local_algs is None: return None local_algebra_dict = {} R = PolynomialRing(QQ, 'x') for lab in local_algs: if lab[0] == 'm': # signals data about field not in lf db lab1 = lab[1:] # deletes marker m p, e, f, c = [int(z) for z in lab1.split('.')] deg = e * f if str(p) not in local_algebra_dict: local_algebra_dict[str(p)] = [[deg, e, f, c]] else: local_algebra_dict[str(p)].append([deg, e, f, c]) else: LF = db.lf_fields.lookup(lab) f = latex(R(LF['coeffs'])) p = LF['p'] thisdat = [ lab, f, LF['e'], LF['f'], LF['c'], transitive_group_display_knowl(LF['galois_label']), LF['t'], LF['u'], LF['slopes'] ] if str(p) not in local_algebra_dict: local_algebra_dict[str(p)] = [thisdat] else: local_algebra_dict[str(p)].append(thisdat) return local_algebra_dict
def projective_group(self): gapid = self._data['Proj_GAP'] if gapid[0]: label = f"{gapid[0]}.{gapid[1]}" name = db.gps_groups.lookup(label, "tex_name") if name: return abstract_group_display_knowl(label, f"${name}$") ntj = self._data['Proj_nTj'] if ntj[1]: return transitive_group_display_knowl(f"{ntj[0]}T{ntj[1]}") if gapid: return f'Group({gapid[0]}.{gapid[1]})' return 'data not computed'
def av_data(label): abvar = db.av_fq_isog.lookup(label) if abvar is None: return "This isogeny class is not in the database." inf = "<div>Dimension: " + str(abvar["g"]) + "<br />" if abvar["is_simple"]: nf = abvar["number_fields"][0] wnf = WebNumberField(nf) if not wnf.is_null(): inf += ("Number field: " + nf_display_knowl(nf, name=field_pretty(nf)) + "<br />") inf += "Galois group: " + transitive_group_display_knowl( abvar["galois_groups"][0]) + "<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 local_algebra_data(labels): labs = labels.split(',') f1 = labs[0].split('.') labs = sorted(labs, key=lambda u: (int(j) for j in u.split('.')), reverse=True) ans = '<div align="center">' ans += '$%s$-adic algebra' % str(f1[0]) ans += '</div>' ans += '<p>' ans += "<table class='ntdata'><th>Label<th>Polynomial<th>$e$<th>$f$<th>$c$<th>$G$<th>Slopes" fall = [db.lf_fields.lookup(label) for label in labs] for f in fall: l = str(f['label']) ans += '<tr><td><a href="%s">%s</a><td>' % (url_for_label(l), l) ans += format_coeffs(f['coeffs']) ans += '<td>%d<td>%d<td>%d<td>' % (f['e'], f['f'], f['c']) ans += transitive_group_display_knowl(f['galois_label']) ans += '<td>$' + show_slope_content(f['slopes'], f['t'], f['u']) + '$' ans += '</table>' if len(labs) != len(set(labs)): ans += '<p>Fields which appear more than once occur according to their given multiplicities in the algebra' return ans
def display_galois_group(self): if not hasattr(self, "galois_groups") or not self.galois_groups[0]: # the number field was not found in the database return "The Galois group of this isogeny class is not in the database." else: return transitive_group_display_knowl(self.galois_groups[0])
def pretty_galois_knowl(self): return transitive_group_display_knowl(self._data['GaloisLabel'])
def smallest_gal_t_format(self): galnt = self.smallest_gal_t() if len(galnt) == 1: return galnt[0] return transitive_group_display_knowl(f"{galnt[0]}T{galnt[1]}")
def make_passport_object(self, passport): from lmfdb.belyi.main import url_for_belyi_galmap_label, url_for_belyi_passport_label # all information about the map 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 = {} for elt in ("plabel", "abc", "num_orbits", "g", "abc", "deg", "maxdegbf", "is_primitive", "primitivization"): data[elt] = passport[elt] data["group"] = transitive_group_display_knowl(passport["group"]) data["geomtype"] = geomtypelet_to_geomtypename_dict[ passport["geomtype"]] data["lambdas"] = [str(c)[1:-1] for c in passport["lambdas"]] data["pass_size"] = passport["pass_size"] data["primitivization_url"] = url_for_belyi_passport_label( data['primitivization']) # Permutation triples galmaps_for_plabel = db.belyi_galmaps_fixed.search( {"plabel": passport["plabel"]}) # , sort = ['label_index']) galmapdata = [] for galmap in galmaps_for_plabel: # wrap number field nonsense F = belyi_base_field(galmap) # inLMFDB = False field = {} if F._data is None: field["in_LMFDB"] = False fld_coeffs = galmap["base_field"] pol = PolynomialRing(QQ, "x")(fld_coeffs) field["base_field"] = latex(pol) field["isQQ"] = False else: field["in_LMFDB"] = True if F.poly().degree() == 1: field["isQQ"] = True F.latex_poly = web_latex(F.poly(var="t")) field["base_field"] = F galmapdatum = [ galmap["label"].split("-")[-1], url_for_belyi_galmap_label(galmap["label"]), galmap["orbit_size"], field, galmap["triples_cyc"][0][0], galmap["triples_cyc"][0][1], galmap["triples_cyc"][0][2], ] galmapdata.append(galmapdatum) data["galmapdata"] = galmapdata # Properties properties = [ ("Label", passport["plabel"]), ("Group", str(passport["group"])), ("Orders", str(passport["abc"])), ("Genus", str(passport["g"])), ("Size", str(passport["pass_size"])), ("Galois orbits", str(passport["num_orbits"])), ] self.properties = properties # Friends self.friends = [] # Breadcrumbs label_spl = data["plabel"].split("-") groupstr = label_spl[0] gstr = str(data['g']) sigmas = label_spl[1] sigma0, sigma1, sigmaoo = sigmas.split("_") abcstr = str(data['abc']).replace(' ', '') # does lambdasstr need to be updated? lambdasstr = "%s-%s-%s" % (sigma0, sigma1, sigmaoo) lambdasgstr = lambdasstr + "-" + gstr self.bread = [ ("Belyi Maps", url_for(".index")), (groupstr, url_for(".by_url_belyi_search_group", group=groupstr)), ( abcstr, url_for(".by_url_belyi_search_group_triple", group=groupstr, abc=abcstr), ), ( lambdasgstr, url_for( ".by_url_belyi_passport_label", group=groupstr, abc=abcstr, sigma0=sigma0, sigma1=sigma1, sigmaoo=sigmaoo, g=gstr, ), ), ] # Title self.title = "Passport " + data["plabel"] # Code snippets (only for curves) self.code = {} self.__dict__.update(data) return
def __init__(self, galmap, triple=None): from lmfdb.belyi.main import url_for_belyi_passport_label, url_for_belyi_galmap_label # all information about the map 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 = {} # the stuff that does not need to be polished for elt in ("label", "plabel", "triples_cyc", "orbit_size", "g", "abc", "deg", "primitivization", "is_primitive"): data[elt] = galmap[elt] if triple: data["label"] += '-' + (triple).replace(' ', '') data["triple"] = triple data["group"] = transitive_group_display_knowl(galmap["group"]) data["geomtype"] = geomtypelet_to_geomtypename_dict[galmap["geomtype"]] data["lambdas"] = [str(c)[1:-1] for c in galmap["lambdas"]] data["primitivization_url"] = url_for_belyi_galmap_label( data['primitivization']) data["isQQ"] = False data["in_LMFDB"] = False F = belyi_base_field(galmap) if F._data is None: fld_coeffs = galmap["base_field"] pol = PolynomialRing(QQ, "t")(fld_coeffs) data["base_field"] = latex(pol) else: data["in_LMFDB"] = True if F.poly().degree() == 1: data["isQQ"] = True F.latex_poly = web_latex(F.poly(var="t")) data["base_field"] = F data['embeddings'] = galmap['embeddings'] # change pairs of floats to complex numbers embed_strs = [] for el in galmap["embeddings"]: if el[1] < 0: el_str = str(el[0]) + str(el[1]) + r"\sqrt{-1}" else: el_str = str(el[0]) + "+" + str(el[1]) + r"\sqrt{-1}" embed_strs.append(el_str) data["embeddings_and_triples"] = [] self.triple = None self.embedding = None for i in range(0, len(data["triples_cyc"])): my_dict = {} triple_str = ', '.join(data['triples_cyc'][i]) triple_link = triple_str.replace(' ', '') if triple_link == triple: self.triple = data['triples_cyc'][i] self.embedding = CC(data['embeddings'][i]) my_dict['triple'] = triple_str my_dict['triple_link'] = triple_link if data["isQQ"]: my_dict[ 'embedding'] = r"\text{not applicable (over $\mathbb{Q}$)}" else: my_dict['embedding'] = embed_strs[i] data['embeddings_and_triples'].append(my_dict) crv_str = galmap["curve"] if crv_str == "PP1": data["curve"] = r"\mathbb{P}^1" else: data["curve"] = make_curve_latex(crv_str, nu=self.embedding) data["map"] = make_map_latex(galmap["map"], nu=self.embedding) data["lambdas"] = [str(c)[1:-1] for c in galmap["lambdas"]] # Properties self.plot = db.belyi_galmap_portraits.lucky({"label": galmap['label']}, projection="portrait") plot_link = '<a href="{0}"><img src="{0}" width="200" height="200" style="background-color: white;"/></a>'.format( self.plot) properties = [("Label", galmap["label"])] if triple: properties += [("Triple", "$%s$" % triple)] if self.plot: properties += [(None, plot_link)] properties += [ ("Group", str(galmap["group"])), ("Orders", "$%s$" % (data["abc"])), ("Genus", prop_int_pretty(data["g"])), ("Size", prop_int_pretty(data["orbit_size"])), ] self.properties = properties # Friends self.friends = [("Passport", url_for_belyi_passport_label(galmap["plabel"]))] if galmap['label'] != galmap['primitivization']: self.friends.append( ("Primitivization", url_for_belyi_galmap_label(galmap["primitivization"]))) self.friends.extend(names_and_urls(galmap['friends'])) #add curve link, if in LMFDB if 'curve_label' in galmap.keys(): data['curve_label'] = galmap['curve_label'] for name, url in self.friends: if "curve" in name.lower() and data['curve_label'] in name: data["curve_url"] = url # Downloads if galmap["g"] <= 2: data_label = data["label"] if triple: spl = data_label.split("-") data_label = "-".join(spl[0:-1]) self.downloads = [ ( "Code to Magma", url_for(".belyi_galmap_magma_download", label=data_label), ), ( "Code to SageMath", url_for(".belyi_galmap_sage_download", label=data_label), ), ( "All data to text", url_for(".belyi_galmap_text_download", label=data_label), ), ] else: self.downloads = [] # Breadcrumbs label_spl = data["label"].split("-") groupstr = label_spl[0] letnum = label_spl[2] gstr = str(data['g']) sigmas = label_spl[1] sigma0, sigma1, sigmaoo = sigmas.split("_") abcstr = str(data['abc']).replace(' ', '') # does lambdasstr need to be updated? lambdasstr = "%s-%s-%s" % (sigma0, sigma1, sigmaoo) lambdasgstr = lambdasstr + "-" + gstr self.bread = [ ("Belyi Maps", url_for(".index")), (groupstr, url_for(".by_url_belyi_search_group", group=groupstr)), ( abcstr, url_for(".by_url_belyi_search_group_triple", group=groupstr, abc=abcstr), ), ( lambdasgstr, url_for( ".by_url_belyi_passport_label", group=groupstr, abc=abcstr, sigma0=sigma0, sigma1=sigma1, sigmaoo=sigmaoo, g=gstr, ), ), ( letnum, url_for( ".by_url_belyi_galmap_label", group=groupstr, abc=abcstr, sigma0=sigma0, sigma1=sigma1, sigmaoo=sigmaoo, g=gstr, letnum=letnum, ), ), ] # Title if self.triple: self.title = "Embedded Belyi map " + data["label"] else: self.title = "Belyi map orbit " + data["label"] # Code snippets (only for curves) self.code = {} self.__dict__.update(data) return
def container(self): galnt = self.smallest_gal_t() if len(galnt) == 1: return galnt[0] return transitive_group_display_knowl(f"{galnt[0]}T{galnt[1]}", cache=self._knowl_cache)
def make_object(self, curve, endo, tama, ratpts, clus, 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_factored_integer(data['cond']) data['analytic_rank'] = ZZ(curve['analytic_rank']) data['mw_rank'] = ZZ(0) if curve.get('mw_rank') is None else ZZ(curve['mw_rank']) # 0 will be marked as a lower bound data['mw_rank_proved'] = curve['mw_rank_proved'] data['analytic_rank_proved'] = curve['analytic_rank_proved'] data['hasse_weil_proved'] = curve['hasse_weil_proved'] 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'] = min_eqns_pretty(data['min_eqn']) data['disc_factor_latex'] = web_latex_factored_integer(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_factored_integer(i) for i in data['igusa_clebsch']] data['igusa_factor_latex'] = [ web_latex_factored_integer(j) for j in data['igusa'] ] data['aut_grp'] = abstract_group_display_knowl(curve['aut_grp_label'], f"${curve['aut_grp_tex']}$") data['geom_aut_grp'] = abstract_group_display_knowl(curve['geom_aut_grp_label'], f"${curve['geom_aut_grp_tex']}$") data['num_rat_wpts'] = ZZ(curve['num_rat_wpts']) 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['two_selmer_rank'] = ZZ(curve['two_selmer_rank']) data['torsion_order'] = curve['torsion_order'] data['end_ring_base'] = endo['ring_base'] data['end_ring_geom'] = endo['ring_geom'] data['real_period'] = decimal_pretty(str(curve['real_period'])) data['regulator'] = decimal_pretty(str(curve['regulator'])) if curve['regulator'] > -0.5 else 'unknown' if data['mw_rank'] == 0 and data['mw_rank_proved']: data['regulator'] = '1' # display an exact 1 when we know this data['tamagawa_product'] = ZZ(curve['tamagawa_product']) if curve.get('tamagawa_product') else 0 data['analytic_sha'] = ZZ(curve['analytic_sha']) if curve.get('analytic_sha') else 0 data['leading_coeff'] = decimal_pretty(str(curve['leading_coeff'])) if curve['leading_coeff'] else 'unknown' data['rat_pts'] = ratpts['rat_pts'] data['rat_pts_v'] = ratpts['rat_pts_v'] data['rat_pts_table'] = ratpts_table(ratpts['rat_pts'],ratpts['rat_pts_v']) data['rat_pts_simple_table'] = ratpts_simpletable(ratpts['rat_pts'],ratpts['rat_pts_v'],data['min_eqn']) data['mw_gens_v'] = ratpts['mw_gens_v'] lower = len([n for n in ratpts['mw_invs'] if n == 0]) upper = data['analytic_rank'] invs = ratpts['mw_invs'] if data['mw_gens_v'] or lower >= upper else [0 for n in range(upper-lower)] + ratpts['mw_invs'] if len(invs) == 0: data['mw_group'] = 'trivial' else: data['mw_group'] = r'\(' + r' \times '.join([ (r'\Z' if n == 0 else r'\Z/{%s}\Z' % n) for n in invs]) + r'\)' if lower >= upper: data['mw_gens_table'] = mw_gens_table (ratpts['mw_invs'], ratpts['mw_gens'], ratpts['mw_heights'], ratpts['rat_pts']) data['mw_gens_simple_table'] = mw_gens_simple_table (ratpts['mw_invs'], ratpts['mw_gens'], ratpts['mw_heights'], ratpts['rat_pts'], data['min_eqn']) 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'] = r"splitting field of \(%s\) with Galois group %s" % (intlist_to_poly(t[1]),transitive_group_display_knowl(f"{t[2][0]}T{t[2][1]}")) tamalist = [[item['p'],item['tamagawa_number']] for item in tama] data['local_table'] = local_table (data['cond'],data['abs_disc'],tamalist,data['bad_lfactors_pretty'],clus) 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" : min_eqn_pretty(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'] = (r"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'] = (r"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'] = real_geom_end_alg_name(curve['real_geom_end_alg']) data['geom_end_alg_name'] = geom_end_alg_name(curve['geom_end_alg']) data['end_alg_name'] = end_alg_name(curve['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: plot_from_db = db.g2c_plots.lucky({"label": curve['label']}) if (plot_from_db is None): self.plot = encode_plot(eqn_list_to_curve_plot(data['min_eqn'], ratpts['rat_pts'] if ratpts else [])) else: self.plot = plot_from_db['plot'] plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format(self.plot) properties += [ (None, plot_link), ('Conductor', prop_int_pretty(data['cond'])), ('Discriminant', prop_int_pretty(data['disc'])), ] if data['mw_rank_proved']: properties += [('Mordell-Weil group', data['mw_group'])] else: properties += [('Conductor', prop_int_pretty(data['cond']))] properties += [ ('Sato-Tate group', data['st_group_link']), (r'\(\End(J_{\overline{\Q}}) \otimes \R\)', r'\(%s\)' % data['real_geom_end_alg_name']), (r'\(\End(J_{\overline{\Q}}) \otimes \Q\)', r'\(%s\)' % data['geom_end_alg_name']), (r'\(\End(J) \otimes \Q\)', r'\(%s\)' % data['end_alg_name']), (r'\(\overline{\Q}\)-simple', bool_pretty(data['is_simple_geom'])), (r'\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])), ] # Friends self.friends = friends = [] if is_curve: friends.append(('Genus 2 curve %s.%s' % (data['slabel'][0], data['slabel'][1]), url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1]))) # first deal with ECs and MFs ecs = [] mfs = [] if 'split_labels' in data: for friend_label in data['split_labels']: if is_curve: ecs.append(("Elliptic curve " + friend_label, url_for_ec(friend_label))) else: ecs.append(("Elliptic curve " + ec_label_class(friend_label), url_for_ec_class(friend_label))) try: cond, iso = ec_label_class(friend_label).split(".") newform_label = ".".join([cond, str(2), 'a', iso]) mfs.append(("Modular form " + newform_label, url_for("cmf.by_url_newform_label", level=cond, weight=2, char_orbit_label='a', hecke_orbit=iso))) except ValueError: # means the friend isn't an elliptic curve over Q; adding Hilbert/Bianchi modular forms # is dealt with via the L-functions instances below pass ecs.sort(key=lambda x: key_for_numerically_sort(x[0])) mfs.sort(key=lambda x: key_for_numerically_sort(x[0])) # then again EC from lfun instances = [] for elt in db.lfunc_instances.search({'Lhash':data['Lhash'], 'type' : 'ECQP'}, 'url'): instances.extend(elt.split('|')) # and then the other isogeny friends instances.extend([ elt['url'] for elt in get_instances_by_Lhash_and_trace_hash(data["Lhash"], 4, int(data["Lhash"]) ) ]) exclude = {elt[1].rstrip('/').lstrip('/') for elt in self.friends if elt[1]} exclude.add(data['lfunc_url'].lstrip('/L/').rstrip('/')) for elt in ecs + mfs + names_and_urls(instances, exclude=exclude): # because of the splitting we must use G2C specific code add_friend(friends, elt) 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])))) friends.append(('L-function', data['lfunc_url'])) # Breadcrumbs self.bread = bread = [ ('Genus 2 curves', url_for(".index")), (r'$\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 f,h = fh = data['min_eqn'] g = simplify_hyperelliptic(fh) code['curve'] = {'sage':'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s));'%(f,h), 'magma':'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);'%(f,h) } code['simple_curve'] = {'sage':'X = HyperellipticCurve(R(%s))'%(g), 'magma':'X,pi:= SimplifiedModel(C);' } 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['geom_inv'] = {'sage':'C.igusa_clebsch_invariants(); [factor(a) for a in _]', 'magma':'IgusaClebschInvariants(C); IgusaInvariants(C); 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']]) + ']; // minimal model'} code['rat_pts_simp'] = {'magma': '[' + ','.join(["C![%s,%s,%s]"%(p[0],p[1],p[2]) for p in [simplify_hyperelliptic_point(data['min_eqn'], pt) for pt in ratpts['rat_pts']]]) + ']; // simplified model'} code['mw_group'] = {'magma':'MordellWeilGroupGenus2(Jacobian(C));'} 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 render_field_webpage(args): data = None info = {} bread = bread_prefix() # This function should not be called unless label is set. label = clean_input(args['label']) nf = WebNumberField(label) data = {} if nf.is_null(): if re.match(r'^\d+\.\d+\.\d+\.\d+$', label): flash_error("Number field %s was not found in the database.", label) else: flash_error("%s is not a valid label for a number field.", label) return redirect(url_for(".number_field_render_webpage")) info['wnf'] = nf data['degree'] = nf.degree() data['class_number'] = nf.class_number_latex() ram_primes = nf.ramified_primes() t = nf.galois_t() n = nf.degree() data['is_galois'] = nf.is_galois() data['autstring'] = r'\Gal' if data['is_galois'] else r'\Aut' data['is_abelian'] = nf.is_abelian() if nf.is_abelian(): conductor = nf.conductor() data['conductor'] = conductor dirichlet_chars = nf.dirichlet_group() if dirichlet_chars: data['dirichlet_group'] = [r'<a href = "%s">$\chi_{%s}(%s,·)$</a>' % (url_for('characters.render_Dirichletwebpage',modulus=data['conductor'], number=j), data['conductor'], j) for j in dirichlet_chars] if len(data['dirichlet_group']) == 1: data['dirichlet_group'] = r'<span style="white-space:nowrap">$\lbrace$' + data['dirichlet_group'][0] + r'$\rbrace$</span>' else: data['dirichlet_group'] = r'$\lbrace$' + ', '.join(data['dirichlet_group'][:-1]) + ', <span style="white-space:nowrap">' + data['dirichlet_group'][-1] + r'$\rbrace$</span>' if data['conductor'].is_prime() or data['conductor'] == 1: data['conductor'] = r"\(%s\)" % str(data['conductor']) else: factored_conductor = factor_base_factor(data['conductor'], ram_primes) factored_conductor = factor_base_factorization_latex(factored_conductor) data['conductor'] = r"\(%s=%s\)" % (str(data['conductor']), factored_conductor) data['galois_group'] = group_pretty_and_nTj(n,t,True) data['auts'] = db.gps_transitive.lookup(r'{}T{}'.format(n,t))['auts'] data['cclasses'] = cclasses_display_knowl(n, t) data['character_table'] = character_table_display_knowl(n, t) data['class_group'] = nf.class_group() data['class_group_invs'] = nf.class_group_invariants() data['signature'] = nf.signature() data['coefficients'] = nf.coeffs() nf.make_code_snippets() D = nf.disc() data['disc_factor'] = nf.disc_factored_latex() if D.abs().is_prime() or D == 1: data['discriminant'] = bigint_knowl(D,cutoff=60,sides=3) else: data['discriminant'] = bigint_knowl(D,cutoff=60,sides=3) + r"\(\medspace = %s\)" % data['disc_factor'] if nf.frobs(): data['frob_data'], data['seeram'] = see_frobs(nf.frobs()) else: # fallback in case we haven't computed them in a case data['frob_data'], data['seeram'] = frobs(nf) # This could put commas in the rd, we don't want to trigger spaces data['rd'] = ('$%s$' % fixed_prec(nf.rd(),2)).replace(',','{,}') # Bad prime information npr = len(ram_primes) ramified_algebras_data = nf.ramified_algebras_data() if isinstance(ramified_algebras_data, str): loc_alg = '' else: # [label, latex, e, f, c, gal] loc_alg = '' for j in range(npr): if ramified_algebras_data[j] is None: loc_alg += '<tr><td>$%s$</td><td colspan="7">Data not computed</td></tr>'%str(ram_primes[j]).rstrip('L') else: from lmfdb.local_fields.main import show_slope_content primefirstline=True mydat = ramified_algebras_data[j] p = ram_primes[j] loc_alg += '<tr><td rowspan="%d">$%s$</td>'%(len(mydat),str(p)) for mm in mydat: if primefirstline: primefirstline=False else: loc_alg += '<tr>' if len(mm)==4: # not in database if mm[1]*mm[2]==1: # Q_p loc_alg += '<td>$\\Q_{%d}$</td><td>$x$</td><td>$1$</td><td>$1$</td><td>$0$</td><td>%s</td><td>$%s$</td>'%(p,transitive_group_display_knowl("1T1", "Trivial"), show_slope_content([],1,1)) elif mm[1]*mm[2]==2: # quadratic loc_alg += '<td></td><td>Deg $2$</td><td>${}$</td><td>${}$</td><td>${}$</td><td>{}</td><td>${}$</td>'.format(mm[1],mm[2],mm[3],transitive_group_display_knowl("2T1", "$C_2$"), show_slope_content([],mm[1],mm[2])) elif mm[1]==1: # unramified # nT1 is cyclic except for n = 32 cyc = 33 if mm[2] == 32 else 1 loc_alg += '<td></td><td>Deg ${}$</td><td>${}$</td><td>${}$</td><td>${}$</td><td>{}</td><td>${}$</td>'.format(mm[1]*mm[2],mm[1],mm[2],mm[3],transitive_group_display_knowl(f"{mm[2]}T{cyc}"), show_slope_content([],mm[1],mm[2])) else: loc_alg += '<td></td><td>Deg ${}$</td><td>${}$</td><td>${}$</td><td>${}$</td><td></td><td></td>'.format( mm[1]*mm[2], mm[1], mm[2], mm[3]) else: lab = mm[0] myurl = url_for('local_fields.by_label', label=lab) if mm[3]*mm[2] == 1: lab = r'$\Q_{%s}$'%str(p) loc_alg += '<td><a href="%s">%s</a></td><td>$%s$</td><td>$%d$</td><td>$%d$</td><td>$%d$</td><td>%s</td><td>$%s$</td>'%(myurl,lab,mm[1],mm[2],mm[3],mm[4],mm[5],show_slope_content(mm[8],mm[6],mm[7])) loc_alg += '</tr>\n' loc_alg += '</tbody></table>\n' ram_primes = str(ram_primes)[1:-1] # Get rid of python L for big numbers ram_primes = ram_primes.replace('L', '') if not ram_primes: ram_primes = r'\textrm{None}' data['phrase'] = group_phrase(n, t) zkraw = nf.zk() Ra = PolynomialRing(QQ, 'a') zk = [latex(Ra(x)) for x in zkraw] zk = ['$%s$' % x for x in zk] zk = ', '.join(zk) zkraw = ', '.join(zkraw) grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh() else '' # Short version for properties grh_lab = nf.short_grh_string() if 'computed' in str(data['class_number']): grh_lab='' grh_label='' pretty_label = field_pretty(label) if label != pretty_label: pretty_label = "%s: %s" % (label, pretty_label) info.update(data) rootof1raw = unlatex(nf.root_of_1_gen()) rootofunity = raw_typeset(rootof1raw, nf.root_of_1_gen(), extra=' (order ${}$)'.format(nf.root_of_1_order())) safe_units = nf.units_safe() if 'too long' in safe_units: myunits = safe_units else: myunits = raw_typeset(unlatex(safe_units), safe_units) info.update({ 'label': pretty_label, 'label_raw': label, 'polynomial': raw_typeset(nf.poly()), 'ram_primes': ram_primes, 'integral_basis': raw_typeset(zkraw, zk), 'regulator': web_latex(nf.regulator()), 'unit_rank': nf.unit_rank(), 'root_of_unity': rootofunity, 'fund_units': myunits, 'cnf': nf.cnf(), 'grh_label': grh_label, 'loc_alg': loc_alg }) bread.append(('%s' % nf_label_pretty(info['label_raw']), ' ')) info['downloads_visible'] = True info['downloads'] = [('worksheet', '/')] info['friends'] = [] if nf.can_class_number(): # hide ones that take a long time to compute on the fly # note that the first degree 4 number field missed the zero of the zeta function if abs(D**n) < 50000000: info['friends'].append(('L-function', "/L/NumberField/%s" % label)) info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t))) if 'dirichlet_group' in info: info['friends'].append(('Dirichlet character group', url_for("characters.dirichlet_group_table", modulus=int(conductor), char_number_list=','.join( str(a) for a in dirichlet_chars), poly=nf.poly()))) resinfo = [] galois_closure = nf.galois_closure() if galois_closure[0]>0: if galois_closure[1]: resinfo.append(('gc', galois_closure[1])) if galois_closure[2]: info['friends'].append(('Galois closure',url_for(".by_label", label=galois_closure[2][0]))) else: resinfo.append(('gc', [dnc])) sextic_twins = nf.sextic_twin() if sextic_twins[0]>0: if sextic_twins[1]: resinfo.append(('sex', r' $\times$ '.join(sextic_twins[1]))) else: resinfo.append(('sex', dnc)) siblings = nf.siblings() # [degsib list, label list] # first is list of [deg, num expected, list of knowls] if siblings[0]: for sibdeg in siblings[0]: if not sibdeg[2]: sibdeg[2] = dnc else: nsibs = len(sibdeg[2]) sibdeg[2] = ', '.join(sibdeg[2]) if nsibs<sibdeg[1]: sibdeg[2] += ', some '+dnc resinfo.append(('sib', siblings[0])) for lab in siblings[1]: if lab: labparts = lab.split('.') info['friends'].append(("Degree %s sibling" % labparts[0], url_for(".by_label", label=lab))) arith_equiv = nf.arith_equiv() if arith_equiv[0]>0: if arith_equiv[1]: resinfo.append(('ae', ', '.join(arith_equiv[1]), len(arith_equiv[1]))) for aelab in arith_equiv[2]: info['friends'].append(('Arithmetically equivalent sibling',url_for(".by_label", label=aelab))) else: resinfo.append(('ae', dnc, len(arith_equiv[1]))) info['resinfo'] = resinfo learnmore = learnmore_list() title = "Number field %s" % info['label'] if npr == 1: primes = 'prime' else: primes = 'primes' if len(ram_primes) > 30: ram_primes = 'see page' else: ram_primes = '$%s$' % ram_primes properties = [('Label', nf_label_pretty(label)), ('Degree', prop_int_pretty(data['degree'])), ('Signature', '$%s$' % data['signature']), ('Discriminant', prop_int_pretty(D)), ('Root discriminant', '%s' % data['rd']), ('Ramified ' + primes + '', ram_primes), ('Class number', '%s %s' % (data['class_number'], grh_lab)), ('Class group', '%s %s' % (data['class_group_invs'], grh_lab)), ('Galois group', group_pretty_and_nTj(data['degree'], t))] downloads = [('Stored data to gp', url_for('.nf_download', nf=label, download_type='data'))] for lang in [["Magma","magma"], ["SageMath","sage"], ["Pari/GP", "gp"]]: downloads.append(('Download {} code'.format(lang[0]), url_for(".nf_download", nf=label, download_type=lang[1]))) from lmfdb.artin_representations.math_classes import NumberFieldGaloisGroup from lmfdb.artin_representations.math_classes import artin_label_pretty try: info["tim_number_field"] = NumberFieldGaloisGroup(nf._data['coeffs']) arts = [z.label() for z in info["tim_number_field"].artin_representations()] #print arts for ar in arts: info['friends'].append(('Artin representation '+artin_label_pretty(ar), url_for("artin_representations.render_artin_representation_webpage", label=ar))) v = nf.factor_perm_repn(info["tim_number_field"]) def dopow(m): if m == 0: return '' if m == 1: return '*' return '*<sup>%d</sup>' % m info["mydecomp"] = [dopow(x) for x in v] except AttributeError: pass return render_template("nf-show-field.html", properties=properties, title=title, bread=bread, code=nf.code, friends=info.pop('friends'), downloads=downloads, learnmore=learnmore, info=info, formatfield=formatfield, KNOWL_ID="nf.%s"%label)