コード例 #1
0
 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
コード例 #2
0
ファイル: math_classes.py プロジェクト: tomgrubbmath/lmfdb
 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'
コード例 #3
0
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
コード例 #4
0
ファイル: main.py プロジェクト: tomgrubbmath/lmfdb
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
コード例 #5
0
ファイル: isog_class.py プロジェクト: assaferan/lmfdb
 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])
コード例 #6
0
ファイル: math_classes.py プロジェクト: tomgrubbmath/lmfdb
 def pretty_galois_knowl(self):
     return transitive_group_display_knowl(self._data['GaloisLabel'])
コード例 #7
0
ファイル: math_classes.py プロジェクト: tomgrubbmath/lmfdb
 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]}")
コード例 #8
0
ファイル: web_belyi.py プロジェクト: tomgrubbmath/lmfdb
    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
コード例 #9
0
ファイル: web_belyi.py プロジェクト: tomgrubbmath/lmfdb
    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
コード例 #10
0
 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)
コード例 #11
0
ファイル: web_g2c.py プロジェクト: tomgrubbmath/lmfdb
    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);'}
コード例 #12
0
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,&middot;)$</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='&nbsp;(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)