Esempio n. 1
0
def nf_knowl_guts(label):
    out = ''
    wnf = WebNumberField(label)
    if wnf.is_null():
        return 'Cannot find global number field %s' % label
    out += "Global number field %s" % label
    out += '<div>'
    out += 'Defining polynomial: '
    out += "\(%s\)" % latex(wnf.poly())
    D = wnf.disc()
    Dfact = wnf.disc_factored_latex()
    if D.abs().is_prime() or D == 1:
        Dfact = "\(%s\)" % str(D)
    else:
        Dfact = '%s = \(%s\)' % (str(D),Dfact)
    out += '<br>Discriminant: '
    out += Dfact
    out += '<br>Signature: '
    out += str(wnf.signature())
    out += '<br>Galois group: '+group_pretty_and_nTj(wnf.degree(),wnf.galois_t(), True)
    out += '<br>Class number: %s ' % str(wnf.class_number_latex())
    if wnf.can_class_number():
        out += wnf.short_grh_string()
    out += '</div>'
    out += '<div align="right">'
    out += '<a href="%s">%s home page</a>' % (str(url_for("number_fields.number_field_render_webpage", natural=label)),label)
    out += '</div>'
    return out
Esempio n. 2
0
def nf_knowl_guts(label):
    out = ''
    wnf = WebNumberField(label)
    if wnf.is_null():
        return 'Cannot find global number field %s' % label
    out += "Global number field %s" % label
    out += '<div>'
    out += 'Defining polynomial: '
    out += "\(%s\)" % latex(wnf.poly())
    D = wnf.disc()
    Dfact = wnf.disc_factored_latex()
    if D.abs().is_prime() or D == 1:
        Dfact = "\(%s\)" % str(D)
    else:
        Dfact = '%s = \(%s\)' % (str(D), Dfact)
    out += '<br>Discriminant: '
    out += Dfact
    out += '<br>Signature: '
    out += str(wnf.signature())
    out += '<br>Galois group: ' + group_pretty_and_nTj(wnf.degree(),
                                                       wnf.galois_t(), True)
    out += '<br>Class number: %s ' % str(wnf.class_number_latex())
    if wnf.can_class_number():
        out += wnf.short_grh_string()
    out += '</div>'
    out += '<div align="right">'
    out += '<a href="%s">%s home page</a>' % (str(
        url_for("number_fields.number_field_render_webpage",
                natural=label)), label)
    out += '</div>'
    return out
Esempio n. 3
0
def local_field_data(label):
    f = db.lf_fields.lookup(label)
    nicename = ''
    if f['n'] < 3:
        nicename = ' = '+ prettyname(f)
    ans = '$p$-adic field %s%s<br><br>'% (label, nicename)
    ans += r'Extension of $\Q_{%s}$ defined by %s<br>'%(str(f['p']),web_latex(coeff_to_poly(f['coeffs'])))
    gt = int(f['galois_label'].split('T')[1])
    gn = f['n']
    ans += 'Degree: %s<br>' % str(gn)
    ans += 'Ramification index $e$: %s<br>' % str(f['e'])
    ans += 'Residue field degree $f$: %s<br>' % str(f['f'])
    ans += 'Discriminant ideal:  $(p^{%s})$ <br>' % str(f['c'])
    ans += 'Galois group $G$: %s<br>' % group_pretty_and_nTj(gn, gt, True)
    ans += '<div align="right">'
    ans += '<a href="%s">%s home page</a>' % (str(url_for("local_fields.by_label", label=label)),label)
    ans += '</div>'
    return ans
Esempio n. 4
0
File: main.py Progetto: LMFDB/lmfdb
def local_field_data(label):
    f = db.lf_fields.lookup(label)
    nicename = ''
    if f['n'] < 3:
        nicename = ' = '+ prettyname(f)
    ans = 'Local number field %s%s<br><br>'% (label, nicename)
    ans += 'Extension of $\Q_{%s}$ defined by %s<br>'%(str(f['p']),web_latex(coeff_to_poly(f['coeffs'])))
    gt = f['gal']
    gn = f['n']
    ans += 'Degree: %s<br>' % str(gt)
    ans += 'Ramification index $e$: %s<br>' % str(f['e'])
    ans += 'Residue field degree $f$: %s<br>' % str(f['f'])
    ans += 'Discriminant ideal:  $(p^{%s})$ <br>' % str(f['c'])
    ans += 'Galois group $G$: %s<br>' % group_pretty_and_nTj(gn, gt, True)
    ans += '<div align="right">'
    ans += '<a href="%s">%s home page</a>' % (str(url_for("local_fields.by_label", label=label)),label)
    ans += '</div>'
    return ans
Esempio n. 5
0
 def galois_string(self):
     if not self.haskey('galt'):
         return 'Not computed'
     n = self._data['degree']
     t = self._data['galt']
     return group_pretty_and_nTj(n, t)
Esempio n. 6
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 colspan="7">Data not computed' % str(
                    ram_primes[j]).rstrip('L')
            else:
                from lmfdb.local_fields.main import show_slope_content
                mydat = ramified_algebras_data[j]
                p = ram_primes[j]
                loc_alg += '<tr><td rowspan="%d">$%s$</td>' % (len(mydat),
                                                               str(p))
                mm = mydat[0]
                myurl = url_for('local_fields.by_label', label=mm[0])
                lab = mm[0]
                if mm[3] * mm[2] == 1:
                    lab = r'$\Q_{%s}$' % str(p)
                loc_alg += '<td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$' % (
                    myurl, lab, mm[1], mm[2], mm[3], mm[4], mm[5],
                    show_slope_content(mm[8], mm[6], mm[7]))
                for mm in mydat[1:]:
                    lab = mm[0]
                    myurl = url_for('local_fields.by_label', label=lab)
                    if mm[3] * mm[2] == 1:
                        lab = r'$\Q_{%s}$' % str(p)
                    loc_alg += '<tr><td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$' % (
                        myurl, lab, mm[1], mm[2], mm[3], mm[4], mm[5],
                        show_slope_content(mm[8], mm[6], mm[7]))
        loc_alg += '</tbody></table>'

    ram_primes = str(ram_primes)[1:-1]
    # 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)
    zk = nf.zk()
    Ra = PolynomialRing(QQ, 'a')
    zk = [latex(Ra(x)) for x in zk]
    zk = ['$%s$' % x for x in zk]
    zk = ', '.join(zk)
    grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh(
    ) else ''
    # Short version for properties
    grh_lab = nf.short_grh_string()
    if '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)
    rootofunity = '%s (order $%d$)' % (nf.root_of_1_gen(),
                                       nf.root_of_1_order())

    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex(nf.poly()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': rootofunity,
        'fund_units': nf.units_safe(),
        '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 lond time to compute on the fly
        # note that the first degree 4 number field missed the zero of the zeta function
        if abs(D**n) < 50000000:
            info['friends'].append(('L-function', "/L/NumberField/%s" % label))
    info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t)))
    if 'dirichlet_group' in info:
        info['friends'].append(('Dirichlet character group',
                                url_for("characters.dirichlet_group_table",
                                        modulus=int(conductor),
                                        char_number_list=','.join(
                                            str(a) for a in dirichlet_chars),
                                        poly=info['polynomial'])))
    resinfo = []
    galois_closure = nf.galois_closure()
    if galois_closure[0] > 0:
        if 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,
                           credit=NF_credit,
                           title=title,
                           bread=bread,
                           code=nf.code,
                           friends=info.pop('friends'),
                           downloads=downloads,
                           learnmore=learnmore,
                           info=info,
                           KNOWL_ID="nf.%s" % label)
Esempio n. 7
0
 def galois_string(self):
     if not self.haskey('galt'):
         return 'Not computed'
     n = self._data['degree']
     t = self._data['galt']
     return group_pretty_and_nTj(n, t)
Esempio n. 8
0
 def galois_string(self):
     if not self.haskey('galois_label'):
         return 'Not computed'
     n = self._data['degree']
     t = int(self._data['galois_label'].split('T')[1])
     return group_pretty_and_nTj(n, t)
Esempio n. 9
0
File: main.py Progetto: cscmnu/lmfdb
def galformatter(gal):
    n, t = galdata(gal)
    return group_pretty_and_nTj(n, t, True, cache=galcache())
Esempio n. 10
0
File: main.py Progetto: cscmnu/lmfdb
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 = "/LocalNumberField/%s" % 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 = web_latex(eisenp)

        else:
            unramp = data['unram'].replace('t', 'x')
            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 = '$' + web_latex(eisenp, False) + '\\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 = "/LocalNumberField/%s" % 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]))

        info.update({
            'polynomial':
            web_latex(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']),
            '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))

        bread = get_bread([(label, ' ')])
        return render_template(
            "lf-show-field.html",
            credit=LF_credit,
            title=title,
            titletag=titletag,
            bread=bread,
            info=info,
            properties=prop2,
            friends=friends,
            learnmore=learnmore_list(),
            KNOWL_ID="lf.%s" % label,
        )
Esempio n. 11
0
def contformatter(cont):
    n, t = galdata(cont)
    if t == 0: # no T number
        return cont
    return group_pretty_and_nTj(n, t, True, cache=contcache())
Esempio n. 12
0
def projformatter(proj):
    if isinstance(proj, list):
        proj = "%sT%s" % tuple(proj)
    n, t = galdata(proj)
    return group_pretty_and_nTj(n, t, True, cache=projcache(), skip_nTj=True)
Esempio n. 13
0
lf_columns = SearchColumns([
    LinkCol("label", "lf.field.label", "Label", url_for_label, default=True),
    ProcessedCol("coeffs",
                 "lf.defining_polynomial",
                 "Polynomial",
                 format_coeffs,
                 default=True),
    MathCol("p", "lf.qp", "$p$", default=True),
    MathCol("e", "lf.ramification_index", "$e$", default=True),
    MathCol("f", "lf.residue_field_degree", "$f$", default=True),
    MathCol("c", "lf.discriminant_exponent", "$c$", default=True),
    MultiProcessedCol(
        "gal",
        "nf.galois_group",
        "Galois group", ["n", "gal", "cache"],
        lambda n, t, cache: group_pretty_and_nTj(n, t, cache=cache),
        default=True),
    MultiProcessedCol("slopes",
                      "lf.slope_content",
                      "Slope content", ["slopes", "t", "u"],
                      show_slope_content,
                      default=True,
                      mathmode=True)
],
                           db_cols=[
                               "c", "coeffs", "e", "f", "gal", "label", "n",
                               "p", "slopes", "t", "u"
                           ])


def lf_postprocess(res, info, query):
Esempio n. 14
0
File: main.py Progetto: LMFDB/lmfdb
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 <span style='color:black'>%s</span> was not found in the database.", label)
            else:
                flash_error("<span style='color:black'>%s</span> is not a valid label for a local number field.", label)
            return redirect(url_for(".index"))
        title = 'Local Number 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 = data['gal']
        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+' over $\Q_{%d}$.'%p
        autstring = r'\Gal' if the_gal.order() == gn else r'\Aut'
        prop2 = [
            ('Label', label),
            ('Base', '\(%s\)' % Qp),
            ('Degree', '\(%s\)' % data['n']),
            ('e', '\(%s\)' % e),
            ('f', '\(%s\)' % f),
            ('c', '\(%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 = "/LocalNumberField/%s" % unramlabel
            unramdata = db.lf_fields.lookup(unramlabel)

        Px = PolynomialRing(QQ, 'x')
        Pxt=PolynomialRing(Px,'t')
        Pt = PolynomialRing(QQ, 't')
        Ptx = PolynomialRing(Pt, 'x')
        if data['f'] == 1:
            unramp = r'$%s$' % Qp
            # Eliminate t from the eisenstein polynomial
            eisenp = Pxt(str(data['eisen']).replace('y','x'))
            eisenp = Pt(str(data['unram'])).resultant(eisenp)
            eisenp = web_latex(eisenp)

        else:
            unramp = data['unram'].replace('t','x')
            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 = '$'+web_latex(eisenp, False)+'\\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 = "/LocalNumberField/%s" % rflabel
        gsm = data['gsm']
        if gsm == [0]:
            gsm = 'Not computed'
        elif gsm == [-1]:
            gsm = 'Does not exist'
        else:
            gsm = web_latex(coeff_to_poly(gsm))


        info.update({
                    'polynomial': web_latex(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']),
                    '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))

        bread = get_bread([(label, ' ')])
        return render_template("lf-show-field.html", credit=LF_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore_list())
Esempio n. 15
0
def render_field_webpage(args):
    data = None
    info = {}
    bread = [('Global Number Fields', url_for(".number_field_render_webpage"))]

    # This function should not be called unless label is set.
    label = clean_input(args['label'])
    nf = WebNumberField(label)
    data = {}
    if nf.is_null():
        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 global 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['is_abelian'] = nf.is_abelian()
    if nf.is_abelian():
        conductor = nf.conductor()
        data['conductor'] = conductor
        dirichlet_chars = nf.dirichlet_group()
        if len(dirichlet_chars)>0:
            data['dirichlet_group'] = ['<a href = "%s">$\chi_{%s}(%s,&middot;)$</a>' % (url_for('characters.render_Dirichletwebpage',modulus=data['conductor'], number=j), data['conductor'], j) for j in dirichlet_chars]
            data['dirichlet_group'] = r'$\lbrace$' + ', '.join(data['dirichlet_group']) + r'$\rbrace$'
        if data['conductor'].is_prime() or data['conductor'] == 1:
            data['conductor'] = "\(%s\)" % str(data['conductor'])
        else:
            factored_conductor = factor_base_factor(data['conductor'], ram_primes)
            factored_conductor = factor_base_factorization_latex(factored_conductor)
            data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), factored_conductor)
    data['galois_group'] = group_pretty_and_nTj(n,t,True)
    data['cclasses'] = cclasses_display_knowl(n, t)
    data['character_table'] = character_table_display_knowl(n, t)
    data['class_group'] = nf.class_group()
    data['class_group_invs'] = nf.class_group_invariants()
    data['signature'] = nf.signature()
    data['coefficients'] = nf.coeffs()
    nf.make_code_snippets()
    D = nf.disc()
    data['disc_factor'] = nf.disc_factored_latex()
    if D.abs().is_prime() or D == 1:
        data['discriminant'] = "\(%s\)" % str(D)
    else:
        data['discriminant'] = "\(%s=%s\)" % (str(D), data['disc_factor'])
    data['frob_data'], data['seeram'] = frobs(nf)
    # 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 colspan="7">Data not computed'%str(ram_primes[j]).rstrip('L')
            else:
                mydat = ramified_algebras_data[j]
                p = ram_primes[j]
                loc_alg += '<tr><td rowspan="%d">$%s$</td>'%(len(mydat),str(p))
                mm = mydat[0]
                myurl = url_for('local_fields.by_label', label=mm[0])
                lab = mm[0]
                if mm[3]*mm[2]==1:
                    lab = r'$\Q_{%s}$'%str(p)
                loc_alg += '<td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$'%(myurl,lab,mm[1],mm[2],mm[3],mm[4],mm[5],show_slope_content(mm[8],mm[6],mm[7]))
                for mm in mydat[1:]:
                    lab = mm[0]
                    if mm[3]*mm[2]==1:
                        lab = r'$\Q_{%s}$'%str(p)
                    loc_alg += '<tr><td><a href="%s">%s</a><td>$%s$<td>$%d$<td>$%d$<td>$%d$<td>%s<td>$%s$'%(myurl,lab,mm[1],mm[2],mm[3],mm[4],mm[5],show_slope_content(mm[8],mm[6],mm[7]))
        loc_alg += '</tbody></table>'

    ram_primes = str(ram_primes)[1:-1]
    # Get rid of python L for big numbers
    ram_primes = ram_primes.replace('L', '')
    if ram_primes == '':
        ram_primes = r'\textrm{None}'
    data['phrase'] = group_phrase(n, t)
    zk = nf.zk()
    Ra = PolynomialRing(QQ, 'a')
    zk = [latex(Ra(x)) for x in zk]
    zk = ['$%s$' % x for x in zk]
    zk = ', '.join(zk)
    grh_label = '<small>(<a title="assuming GRH" knowl="nf.assuming_grh">assuming GRH</a>)</small>' if nf.used_grh() else ''
    # Short version for properties
    grh_lab = nf.short_grh_string()
    if 'Not' in str(data['class_number']):
        grh_lab=''
        grh_label=''
    pretty_label = field_pretty(label)
    if label != pretty_label:
        pretty_label = "%s: %s" % (label, pretty_label)

    info.update(data)
    if nf.degree() > 1:
        gpK = nf.gpK()
        rootof1coeff = gpK.nfrootsof1()
        rootofunityorder = int(rootof1coeff[1])
        rootof1coeff = rootof1coeff[2]
        rootofunity = web_latex(Ra(str(pari("lift(%s)" % gpK.nfbasistoalg(rootof1coeff))).replace('x','a'))) 
        rootofunity += ' (order $%d$)' % rootofunityorder
    else:
        rootofunity = web_latex(Ra('-1'))+ ' (order $2$)'

    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex_split_on_pm(nf.poly()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': rootofunity,
        'fund_units': nf.units(),
        'grh_label': grh_label,
        'loc_alg': loc_alg
    })

    bread.append(('%s' % info['label_raw'], ' '))
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', '/')]
    info['friends'] = []
    if nf.can_class_number():
        # hide ones that take a lond time to compute on the fly
        # note that the first degree 4 number field missed the zero of the zeta function
        if abs(D**n) < 50000000:
            info['friends'].append(('L-function', "/L/NumberField/%s" % label))
    info['friends'].append(('Galois group', "/GaloisGroup/%dT%d" % (n, t)))
    if 'dirichlet_group' in info:
        info['friends'].append(('Dirichlet character group', url_for("characters.dirichlet_group_table",
                                                           modulus=int(conductor),
                                                           char_number_list=','.join(
                                                               [str(a) for a in dirichlet_chars]),
                                                           poly=info['polynomial'])))
    resinfo=[]
    galois_closure = nf.galois_closure()
    if galois_closure[0]>0:
        if len(galois_closure[1])>0:
            resinfo.append(('gc', galois_closure[1]))
            if len(galois_closure[2]) > 0:
                info['friends'].append(('Galois closure',url_for(".by_label", label=galois_closure[2][0])))
        else:
            resinfo.append(('gc', [dnc]))

    sextic_twins = nf.sextic_twin()
    if sextic_twins[0]>0:
        if len(sextic_twins[1])>0:
            resinfo.append(('sex', r' $\times$ '.join(sextic_twins[1])))
        else:
            resinfo.append(('sex', dnc))

    siblings = nf.siblings()
    # [degsib list, label list]
    # first is list of [deg, num expected, list of knowls]
    if len(siblings[0])>0:
        for sibdeg in siblings[0]:
            if len(sibdeg[2]) ==0:
                sibdeg[2] = dnc
            else:
                sibdeg[2] = ', '.join(sibdeg[2])
                if len(sibdeg[2])<sibdeg[1]:
                    sibdeg[2] += ', some '+dnc
                
        resinfo.append(('sib', siblings[0]))
        for lab in siblings[1]:
            if lab != '':
                labparts = lab.split('.')
                info['friends'].append(("Degree %s sibling"%labparts[0] ,url_for(".by_label", label=lab)))

    arith_equiv = nf.arith_equiv()
    if arith_equiv[0]>0:
        if len(arith_equiv[1])>0:
            resinfo.append(('ae', ', '.join(arith_equiv[1]), len(arith_equiv[1])))
            for aelab in arith_equiv[2]:
                info['friends'].append(('Arithmetically equivalent sibling',url_for(".by_label", label=aelab)))
        else:
            resinfo.append(('ae', dnc, len(arith_equiv[1])))

    info['resinfo'] = resinfo
    learnmore = learnmore_list()
    title = "Global Number Field %s" % info['label']

    if npr == 1:
        primes = 'prime'
    else:
        primes = 'primes'

    if len(label)>25:
        label = label[:16]+'...'+label[-6:]
    properties2 = [('Label', label),
                   ('Degree', '$%s$' % data['degree']),
                   ('Signature', '$%s$' % data['signature']),
                   ('Discriminant', '$%s$' % data['disc_factor']),
                   ('Root discriminant', '%s' % data['rd']),
                   ('Ramified ' + primes + '', '$%s$' % ram_primes),
                   ('Class number', '%s %s' % (data['class_number'], grh_lab)),
                   ('Class group', '%s %s' % (data['class_group_invs'], grh_lab)),
                   ('Galois Group', group_pretty_and_nTj(data['degree'], t))
                   ]
    downloads = []
    for lang in [["Magma","magma"], ["SageMath","sage"], ["Pari/GP", "gp"]]:
        downloads.append(('Download {} code'.format(lang[0]),
                          url_for(".nf_code_download", nf=label, download_type=lang[1])))
    from lmfdb.artin_representations.math_classes import NumberFieldGaloisGroup
    try:
        info["tim_number_field"] = NumberFieldGaloisGroup(nf._data['coeffs'])
        v = nf.factor_perm_repn(info["tim_number_field"])
        def dopow(m):
            if m==0: return ''
            if m==1: return '*'
            return '*<sup>%d</sup>'% m

        info["mydecomp"] = [dopow(x) for x in v]
    except AttributeError:
        pass
    return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, code=nf.code, friends=info.pop('friends'), downloads=downloads, learnmore=learnmore, info=info, KNOWL_ID="nf.%s"%label)