def group_pretty_and_nTj(n, t, useknowls=False, skip_nTj=False, cache={}): label = base_label(n, t) string = label if cache: group = cache.get(label) else: group = db.gps_transitive.lookup(label) group_obj = WebGaloisGroup.from_data(group) if useknowls and group is not None: ntj = '<a title = "' + label + ' [nf.galois_group.data]" knowl="nf.galois_group.data" kwargs="n=' + str( n) + '&t=' + str(t) + '">' + label + '</a>' else: ntj = label pretty = group_obj.display_short(True) if group else '' if pretty != '': # modify if we use knowls and have the gap id if useknowls: gp_label = f"{group['order']}.{group['gapid']}" pretty = abstract_group_display_knowl(gp_label, cache=cache) if skip_nTj: # This is used for statistics where we want to display the abstract group, but we still need to be able to get back to the nTj label for searching if useknowls and pretty.startswith('<a title = "Group'): # Use the nTj knowl string = '<a title = "' + label + ' [nf.galois_group.data]" knowl="nf.galois_group.data" kwargs="n=' + str( n) + '&t=' + str(t) + '">' + pretty + '</a>' else: string = pretty + '<span style="display:none">%s</span>' % label else: string = pretty + ' (as ' + ntj + ')' else: string = ntj return string
def render_glnQ_group(args): info = {} if 'label' in args: label = clean_input(args['label']) info = db.gps_qrep.lucky({'label': label}) info['dispmat'] = dispmat info['groupname'] = '${}$'.format(group_names_pretty(info['group'])) info['groupknowl'] = abstract_group_display_knowl( info['group'], info['groupname']) title = r'$\GL(' + str(info['dim']) + r',\Q)$ subgroup ' + label prop = [('Label', '%s' % label), ('Order', r'\(%s\)' % info['order']), ('Dimension', '%s' % info['dim'])] bread = get_bread([(label, )]) # downloads = [('Code to Magma', url_for(".hgcwa_code_download", label=label, download_type='magma')), # ('Code to Gap', url_for(".hgcwa_code_download", label=label, download_type='gap'))] return render_template( "glnQ-show-group.html", title=title, bread=bread, info=info, properties=prop, #friends=friends, learnmore=learnmore_list(), #downloads=downloads, credit=credit_string)
def group_display_inertia(code): if str(code[0]) == "t": return transitive_group_display_knowl(base_label(*code[1])) if code[1] == [1,1]: return "trivial" ans = "Intransitive group isomorphic to "+abstract_group_display_knowl(f"{code[1][0]}.{code[1][1]}") return ans
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 getgroup(m1, ell): pind = {2: 0, 3: 1, 5: 2, 7: 3, 11: 4, 13: 5} if not m1[3][2]: return [m1[2], m1[0]] myA = m1[3][0] myB = m1[3][1] if not myA and not myB: # myA = myB = [] return [abstract_group_display_knowl("1.1", "$C_1$"), 1] mono = db.hgm_families.lucky({'A': myA, 'B': myB}, projection="mono") if mono is None: return ['??', 1] newthing = mono[pind[ell]] newthing = dogapthing(newthing[1]) return [newthing[2], newthing[0]]
def dogapthing(m1): mnew = str(m1[2]) mnew = mnew.replace(' ', '') if GAP_ID_RE.match(mnew): mnew = mnew[1:-1] two = mnew.split(',') two = [int(j) for j in two] try: m1[2] = abstract_group_display_knowl(f"{two[0]}.{two[1]}") except TypeError: m1[2] = f'Group({two[0]}.{two[1]})' else: # Fix multiple backslashes m1[2] = re.sub(r'\\+', r'\\', m1[2]) m1[2] = '$%s$' % m1[2] return m1
def structure_group_knowl(self): inv = self.H.invariants() label = ".".join(str(v) for v in inv) parts = defaultdict(list) if label: for piece in label.split("."): if "_" in piece: base, exp = map(ZZ, piece.split("_")) else: base = ZZ(piece) exp = 1 for p, e in base.factor(): parts[p].extend([p ** e] * exp) for v in parts.values(): v.sort() primary = sum((parts[p] for p in sorted(parts)), []) dblabel = db.gps_groups.lucky({"abelian": True, "primary_abelian_invariants": primary}, "label") if dblabel is None: abgp_url = url_for('abstract.by_abelian_label', label=label) return f'<a href= %s >{self.structure}</a>' % abgp_url return abstract_group_display_knowl(dblabel, f"{self.structure}")
def render_field_webpage(args): data = None info = {} if 'label' in args: label = clean_input(args['label']) data = db.lf_fields.lookup(label) if data is None: if re.match(r'^\d+\.\d+\.\d+\.\d+$', label): flash_error("Field %s was not found in the database.", label) else: flash_error("%s is not a valid label for a $p$-adic field.", label) return redirect(url_for(".index")) title = '$p$-adic field ' + prettyname(data) titletag = 'p-adic field ' + prettyname(data) polynomial = coeff_to_poly(data['coeffs']) p = data['p'] Qp = r'\Q_{%d}' % p e = data['e'] f = data['f'] cc = data['c'] gt = int(data['galois_label'].split('T')[1]) gn = data['n'] the_gal = WebGaloisGroup.from_nt(gn, gt) isgal = ' Galois' if the_gal.order() == gn else ' not Galois' abelian = ' and abelian' if the_gal.is_abelian() else '' galphrase = 'This field is' + isgal + abelian + r' over $\Q_{%d}.$' % p autstring = r'\Gal' if the_gal.order() == gn else r'\Aut' prop2 = [ ('Label', label), ('Base', r'\(%s\)' % Qp), ('Degree', r'\(%s\)' % data['n']), ('e', r'\(%s\)' % e), ('f', r'\(%s\)' % f), ('c', r'\(%s\)' % cc), ('Galois group', group_pretty_and_nTj(gn, gt)), ] # Look up the unram poly so we can link to it unramlabel = db.lf_fields.lucky({'p': p, 'n': f, 'c': 0}, projection=0) if unramlabel is None: logger.fatal("Cannot find unramified field!") unramfriend = '' else: unramfriend = url_for_label(unramlabel) unramdata = db.lf_fields.lookup(unramlabel) Px = PolynomialRing(QQ, 'x') Pt = PolynomialRing(QQ, 't') Ptx = PolynomialRing(Pt, 'x') if data['f'] == 1: unramp = r'$%s$' % Qp eisenp = Ptx(str(data['eisen']).replace('y', 'x')) eisenp = raw_typeset(eisenp, web_latex(eisenp)) else: unramp = data['unram'].replace('t', 'x') unramp = raw_typeset(unramp, web_latex(Px(str(unramp)))) unramp = prettyname( unramdata ) + ' $\\cong ' + Qp + '(t)$ where $t$ is a root of ' + unramp eisenp = Ptx(str(data['eisen']).replace('y', 'x')) eisenp = raw_typeset(str(eisenp), web_latex(eisenp), extra=r'$\ \in' + Qp + '(t)[x]$') rflabel = db.lf_fields.lucky( { 'p': p, 'n': { '$in': [1, 2] }, 'rf': data['rf'] }, projection=0) if rflabel is None: logger.fatal("Cannot find discriminant root field!") rffriend = '' else: rffriend = url_for_label(rflabel) gsm = data['gsm'] if gsm == [0]: gsm = 'Not computed' elif gsm == [-1]: gsm = 'Does not exist' else: gsm = lf_formatfield(','.join(str(b) for b in gsm)) if 'wild_gap' in data: wild_inertia = abstract_group_display_knowl( f"{data['wild_gap'][0]}.{data['wild_gap'][1]}") else: wild_inertia = 'data not computed' info.update({ 'polynomial': raw_typeset(polynomial), 'n': data['n'], 'p': p, 'c': data['c'], 'e': data['e'], 'f': data['f'], 't': data['t'], 'u': data['u'], 'rf': lf_display_knowl(rflabel, name=printquad(data['rf'], p)), 'base': lf_display_knowl(str(p) + '.1.0.1', name='$%s$' % Qp), 'hw': data['hw'], 'slopes': show_slopes(data['slopes']), 'gal': group_pretty_and_nTj(gn, gt, True), 'gt': gt, 'inertia': group_display_inertia(data['inertia']), 'wild_inertia': wild_inertia, 'unram': unramp, 'eisen': eisenp, 'gms': data['gms'], 'gsm': gsm, 'galphrase': galphrase, 'autstring': autstring, 'subfields': format_subfields(data['subfields'], p), 'aut': data['aut'], }) friends = [('Galois group', "/GaloisGroup/%dT%d" % (gn, gt))] if unramfriend != '': friends.append(('Unramified subfield', unramfriend)) if rffriend != '': friends.append(('Discriminant root field', rffriend)) if db.nf_fields.exists({'local_algs': {'$contains': label}}): friends.append( ('Number fields with this completion', url_for('number_fields.number_field_render_webpage') + "?completions={}".format(label))) bread = get_bread([(label, ' ')]) return render_template( "lf-show-field.html", title=title, titletag=titletag, bread=bread, info=info, properties=prop2, friends=friends, learnmore=learnmore_list(), KNOWL_ID="lf.%s" % label, )
def render_group_webpage(args): data = {} if 'label' in args: label = clean_input(args['label']) label = label.replace('t', 'T') data = db.gps_transitive.lookup(label) if data is None: if re.match(r'^\d+T\d+$', label): flash_error("Group %s was not found in the database.", label) else: flash_error("%s is not a valid label for a Galois group.", label) return redirect(url_for(".index")) title = 'Galois group: ' + label wgg = WebGaloisGroup.from_nt(data['n'], data['t']) data['wgg'] = wgg n = data['n'] t = data['t'] data['yesno'] = yesno order = data['order'] data['orderfac'] = latex(ZZ(order).factor()) orderfac = latex(ZZ(order).factor()) data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac)) if order == 1: data['ordermsg'] = "$1$" if ZZ(order).is_prime(): data['ordermsg'] = "$%s$ (is prime)" % order pgroup = len(ZZ(order).prime_factors()) < 2 if wgg.num_conjclasses() < 50: data['cclasses'] = wgg.conjclasses() if ZZ(order) < ZZ(10000000) and wgg.num_conjclasses() < 21: data['chartable'] = chartable(n, t) data['gens'] = wgg.generator_string() if n == 1 and t == 1: data['gens'] = 'None needed' data['num_cc'] = comma(wgg.num_conjclasses()) data['parity'] = "$%s$" % data['parity'] data['subinfo'] = subfield_display(n, data['subfields']) data['resolve'] = resolve_display(data['quotients']) if data['gapid'] == 0: data['gapid'] = "not available" else: gp_label = f"{data['order']}.{data['gapid']}" data['gapid'] = abstract_group_display_knowl(gp_label, gp_label) data['otherreps'] = wgg.otherrep_list() ae = data['arith_equiv'] if ae > 0: if ae > 1: data[ 'arith_equiv'] = r'A number field with this Galois group has %d <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields.' % ae else: data[ 'arith_equiv'] = r'A number field with this Galois group has exactly one <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> field.' elif ae > -1: data[ 'arith_equiv'] = r'A number field with this Galois group has no <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields.' else: data[ 'arith_equiv'] = r'Data on whether or not a number field with this Galois group has <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields has not been computed.' intreps = list(db.gps_gmodules.search({'n': n, 't': t})) if intreps: data['int_rep_classes'] = [str(z[0]) for z in intreps[0]['gens']] for onerep in intreps: onerep['gens'] = [ list_to_latex_matrix(z[1]) for z in onerep['gens'] ] data['int_reps'] = intreps data['int_reps_complete'] = int_reps_are_complete(intreps) dcq = data['moddecompuniq'] if dcq[0] == 0: data['decompunique'] = 0 else: data['decompunique'] = dcq[0] data['isoms'] = [[mult2mult(z[0]), mult2mult(z[1])] for z in dcq[1]] data['isoms'] = [[ modules2string(n, t, z[0]), modules2string(n, t, z[1]) ] for z in data['isoms']] #print dcq[1] #print data['isoms'] friends = [] if db.nf_fields.exists({'degree': n, 'galt': t}): friends.append( ('Number fields with this Galois group', url_for('number_fields.number_field_render_webpage') + "?galois_group=%dT%d" % (n, t))) if db.lf_fields.exists({'n': n, 'galT': t}): friends.append( ('$p$-adic fields with this Galois group', url_for('local_fields.index') + "?gal=%dT%d" % (n, t))) prop2 = [ ('Label', label), ('Degree', prop_int_pretty(data['n'])), ('Order', prop_int_pretty(order)), ('Cyclic', yesno(data['cyc'])), ('Abelian', yesno(data['ab'])), ('Solvable', yesno(data['solv'])), ('Primitive', yesno(data['prim'])), ('$p$-group', yesno(pgroup)), ] pretty = group_display_short(n, t, emptyifnotpretty=True) if len(pretty) > 0: prop2.extend([('Group:', pretty)]) data['pretty_name'] = pretty data['name'] = re.sub(r'_(\d+)', r'_{\1}', data['name']) data['name'] = re.sub(r'\^(\d+)', r'^{\1}', data['name']) data['nilpotency'] = '$%s$' % data['nilpotency'] if data['nilpotency'] == '$-1$': data['nilpotency'] += ' (not nilpotent)' bread = get_bread([(label, ' ')]) return render_template("gg-show-group.html", title=title, bread=bread, info=data, properties=prop2, friends=friends, KNOWL_ID="gg.%s" % label, learnmore=learnmore_list())
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);'}