Example #1
0
def number_field_render_webpage():
    args = request.args
    sig_list = sum([[[d - 2 * r2, r2] for r2 in range(
        1 + (d // 2))] for d in range(1, 7)], []) + sum([[[d, 0]] for d in range(7, 11)], [])
    sig_list = sig_list[:10]
    if len(args) == 0:
        init_nf_count()
        discriminant_list_endpoints = [-10000, -1000, -100, 0, 100, 1000, 10000]
        discriminant_list = ["%s..%s" % (start, end - 1) for start, end in zip(
            discriminant_list_endpoints[:-1], discriminant_list_endpoints[1:])]
        info = {
            'degree_list': range(1, max_deg + 1),
            'signature_list': sig_list,
            'class_number_list': range(1, 6) + ['6..10'],
            'count': '20',
            'nfields': comma(nfields),
            'maxdeg': max_deg,
            'discriminant_list': discriminant_list
        }
        t = 'Global Number Fields'
        bread = [('Global Number Fields', url_for(".number_field_render_webpage"))]
        info['learnmore'] = [(Completename, url_for(".render_discriminants_page")), ('How data was computed', url_for(".how_computed_page")), ('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), ('Quadratic imaginary class groups', url_for(".render_class_group_data"))]
        return render_template("number_field_all.html", info=info, credit=NF_credit, title=t, bread=bread, learnmore=info.pop('learnmore'))
    else:
        return number_field_search(**args)
Example #2
0
def render_groups_page():
    info = {}
    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page")) ]
    t = 'Galois group labels'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Galois group labels', ' ')]
    C = base.getDBConnection()
    return render_template("galois_groups.html", al=aliastable(C), info=info, credit=NF_credit, title=t, bread=bread, learnmore=info.pop('learnmore'))
Example #3
0
def render_groups_page():
    info = {}
    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page"))]
    t = 'Galois group labels'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Galois group labels', ' ')]
    C = base.getDBConnection()
    return render_template("galois_groups.html", al=aliastable(C), info=info, credit=NF_credit, title=t, bread=bread, learnmore=info.pop('learnmore'))
Example #4
0
def number_field_render_webpage():
    args = request.args
    sig_list = sum([[[d - 2 * r2, r2] for r2 in range(1 + (d // 2))] for d in range(1, 7)], []) + sum(
        [[[d, 0]] for d in range(7, 11)], []
    )
    sig_list = sig_list[:10]
    if len(args) == 0:
        init_nf_count()
        discriminant_list_endpoints = [-10000, -1000, -100, 0, 100, 1000, 10000]
        discriminant_list = [
            "%s..%s" % (start, end - 1)
            for start, end in zip(discriminant_list_endpoints[:-1], discriminant_list_endpoints[1:])
        ]
        info = {
            "degree_list": range(1, max_deg + 1),
            "signature_list": sig_list,
            "class_number_list": range(1, 6) + ["6..10"],
            "count": "20",
            "nfields": comma(nfields),
            "maxdeg": max_deg,
            "discriminant_list": discriminant_list,
        }
        t = "Global Number Fields"
        bread = [("Global Number Fields", url_for(".number_field_render_webpage"))]
        info["learnmore"] = [
            ("Global number field labels", url_for(".render_labels_page")),
            ("Galois group labels", url_for(".render_groups_page")),
            (Completename, url_for(".render_discriminants_page")),
        ]
        return render_template(
            "number_field_all.html", info=info, credit=NF_credit, title=t, bread=bread
        )  # , learnmore=info.pop('learnmore'))
    else:
        return number_field_search(**args)
Example #5
0
def number_field_render_webpage():
    args = request.args
    sig_list = sum([[[d - 2 * r2, r2] for r2 in range(
        1 + (d // 2))] for d in range(1, 7)], []) + sum([[[d, 0]] for d in range(7, 11)], [])
    sig_list = sig_list[:10]
    if len(args) == 0:
        init_nf_count()
        discriminant_list_endpoints = [-10000, -1000, -100, 0, 100, 1000, 10000]
        discriminant_list = ["%s..%s" % (start, end - 1) for start, end in zip(
            discriminant_list_endpoints[:-1], discriminant_list_endpoints[1:])]
        info = {
            'degree_list': range(1, max_deg + 1),
            'signature_list': sig_list,
            'class_number_list': range(1, 6) + ['6..10'],
            'count': '20',
            'nfields': comma(nfields),
            'maxdeg': max_deg,
            'discriminant_list': discriminant_list
        }
        t = 'Global Number Fields'
        bread = [('Global Number Fields', url_for(".number_field_render_webpage"))]
        info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page"))]
        return render_template("number_field_all.html", info=info, credit=NF_credit, title=t, bread=bread)  # , learnmore=info.pop('learnmore'))
    else:
        return number_field_search(**args)
Example #6
0
def how_computed_page():
    info = {}
    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), 
        ('Galois group labels', url_for(".render_groups_page")), 
        (Completename, url_for(".render_discriminants_page")) ]
    t = 'How Number Field Data was Computed'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Galois group labels', ' ')]
    return render_template("single.html", kid='dq.nf.howcomputed', 
        credit=NF_credit, title=t, bread=bread, learnmore=info.pop('learnmore'))
Example #7
0
def how_computed_page():
    info = {}
    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), 
        ('Galois group labels', url_for(".render_groups_page")), 
        (Completename, url_for(".render_discriminants_page")) ]
    t = 'How Number Field Data was Computed'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Galois group labels', ' ')]
    return render_template("single.html", kid='dq.nf.howcomputed', 
        credit=NF_credit, title=t, bread=bread, learnmore=info.pop('learnmore'))
Example #8
0
def how_computed_page():
    info = {}
    info["learnmore"] = [
        ("Global number field labels", url_for(".render_labels_page")),
        ("Galois group labels", url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page")),
    ]
    t = "How Number Field Data was Computed"
    bread = [("Global Number Fields", url_for(".number_field_render_webpage")), ("Galois group labels", " ")]
    return render_template(
        "single.html", kid="dq.nf.howcomputed", credit=NF_credit, title=t, bread=bread, learnmore=info.pop("learnmore")
    )
Example #9
0
def render_discriminants_page():
    info = {}
    info["learnmore"] = [
        ("Global number field labels", url_for(".render_labels_page")),
        ("Galois group labels", url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page")),
    ]
    t = "Completeness of Global Number Field Data"
    bread = [("Global Number Fields", url_for(".number_field_render_webpage")), (Completename, " ")]
    return render_template(
        "discriminant_ranges.html", info=info, credit=NF_credit, title=t, bread=bread, learnmore=info.pop("learnmore")
    )
Example #10
0
def render_class_group_data():
    info = to_dict(request.args)
    #nf_logger.info('******************* ')
    #for k in info.keys():
    # nf_logger.info(str(k) + ' ---> ' + str(info[k]))
    #nf_logger.info('******************* ')
    info['learnmore'] = [
        ('Global number field labels', url_for(".render_labels_page")),
        ('Galois group labels', url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page"))
    ]
    t = 'Class Groups of Quadratic Imaginary Fields'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")),
             (t, ' ')]
    info['message'] = ''
    info['filename'] = 'none'
    if 'Fetch' in info:
        if 'k' in info:
            # remove non-digits
            k = re.sub(r'\D', '', info['k'])
            if k == "":
                info['message'] = 'The value of k is either invalid or empty'
                return class_group_request_error(info, bread)
            k = int(k)
            if k > 4095:
                info['message'] = 'The value of k is too large'
                return class_group_request_error(info, bread)
        else:
            info['message'] = 'The value of k is missing'
            return class_group_request_error(info, bread)
        info['filenamebase'] = str(info['filenamebase'])
        if info['filenamebase'] in [
                'cl3mod8', 'cl7mod8', 'cl4mod16', 'cl8mod16'
        ]:
            filepath = "%s/%s/%s.%d.gz" % (class_group_data_directory,
                                           info['filenamebase'],
                                           info['filenamebase'], k)
            if os.path.isfile(filepath) and os.access(filepath, os.R_OK):
                return send_file(filepath, as_attachment=True)
            else:
                info['message'] = 'File not found'
                return class_group_request_error(info, bread)
        else:
            info['message'] = 'Invalid congruence requested'
            return class_group_request_error(info, bread)

    return render_template("class_group_data.html",
                           info=info,
                           credit="A. Mosunov and M. J. Jacobson, Jr.",
                           title=t,
                           bread=bread,
                           learnmore=info.pop('learnmore'))
Example #11
0
def render_labels_page():
    info = {}
    info["learnmore"] = [
        ("Global number field labels", url_for(".render_labels_page")),
        ("Galois group labels", url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page")),
        ("Quadratic imaginary class groups", url_for(".render_class_group_data")),
    ]
    t = "Number field labels"
    bread = [("Global Number Fields", url_for(".number_field_render_webpage")), ("Number field labels", "")]
    return render_template(
        "number_field_labels.html", info=info, credit=NF_credit, title=t, bread=bread, learnmore=info.pop("learnmore")
    )
Example #12
0
def render_class_group_data():
    info = to_dict(request.args)
    # nf_logger.info('******************* ')
    # for k in info.keys():
    # nf_logger.info(str(k) + ' ---> ' + str(info[k]))
    # nf_logger.info('******************* ')
    info["learnmore"] = [
        ("Global number field labels", url_for(".render_labels_page")),
        ("Galois group labels", url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page")),
    ]
    t = "Class Groups of Quadratic Imaginary Fields"
    bread = [("Global Number Fields", url_for(".number_field_render_webpage")), (t, " ")]
    info["message"] = ""
    info["filename"] = "none"
    if "Fetch" in info:
        if "k" in info:
            # remove non-digits
            k = re.sub(r"\D", "", info["k"])
            if k == "":
                info["message"] = "The value of k is either invalid or empty"
                return class_group_request_error(info, bread)
            k = int(k)
            if k > 4095:
                info["message"] = "The value of k is too large"
                return class_group_request_error(info, bread)
        else:
            info["message"] = "The value of k is missing"
            return class_group_request_error(info, bread)
        info["filenamebase"] = str(info["filenamebase"])
        if info["filenamebase"] in ["cl3mod8", "cl7mod8", "cl4mod16", "cl8mod16"]:
            filepath = "%s/%s/%s.%d.gz" % (class_group_data_directory, info["filenamebase"], info["filenamebase"], k)
            if os.path.isfile(filepath) and os.access(filepath, os.R_OK):
                return send_file(filepath, as_attachment=True)
            else:
                info["message"] = "File not found"
                return class_group_request_error(info, bread)
        else:
            info["message"] = "Invalid congruence requested"
            return class_group_request_error(info, bread)

    return render_template(
        "class_group_data.html",
        info=info,
        credit="A. Mosunov and M. J. Jacobson, Jr.",
        title=t,
        bread=bread,
        learnmore=info.pop("learnmore"),
    )
Example #13
0
def random_nfglobal():
    label = random_object_from_collection( getDBConnection().numberfields.fields )['label']
    #This version leaves the word 'random' in the URL:
    #return render_field_webpage({'label': label})
    #This version uses the number field's own URL:
    #url =
    return redirect(url_for(".by_label", label= label))
Example #14
0
def random_nfglobal():
    label = random_object_from_collection( getDBConnection().numberfields.fields )['label']
    #This version leaves the word 'random' in the URL:
    #return render_field_webpage({'label': label})
    #This version uses the number field's own URL:
    #url =
    return redirect(url_for(".by_label", label= label))
Example #15
0
def render_discriminants_page():
    info = {}
    info['learnmore'] = [
        ('Global number field labels', url_for(".render_labels_page")),
        ('Galois group labels', url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page"))
    ]
    t = 'Completeness of Global Number Field Data'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")),
             (Completename, ' ')]
    return render_template("discriminant_ranges.html",
                           info=info,
                           credit=NF_credit,
                           title=t,
                           bread=bread,
                           learnmore=info.pop('learnmore'))
Example #16
0
def by_label(label):
    try:
        return render_field_webpage({'label': nf_string_to_label(label)})
    except ValueError:
        bread = [('Global Number Fields',
                  url_for(".number_field_render_webpage")),
                 ('Search results', ' ')]
        return search_input_error({'err': ''}, bread)
Example #17
0
def render_labels_page():
    info = {}
    info['learnmore'] = [
        ('Global number field labels', url_for(".render_labels_page")),
        ('Galois group labels', url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page")),
        ('Quadratic imaginary class groups',
         url_for(".render_class_group_data"))
    ]
    t = 'Number field labels'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")),
             ('Number field labels', '')]
    return render_template("number_field_labels.html",
                           info=info,
                           credit=NF_credit,
                           title=t,
                           bread=bread,
                           learnmore=info.pop('learnmore'))
Example #18
0
def search():
    if request.method == "GET":
        val = request.args.get("val", "no value")
        bread = get_bread([("Search for '%s'" % val, url_for('.search'))])
        return render_template("nfgg-search.html", title="Search for Galois groups of number fields", bread=bread, val=val)
    elif request.method == "POST":
        return "ERROR: we always do http get to explicitly display the search parameters"
    else:
        return flask.redirect(404)
Example #19
0
def random_nfglobal():
    from sage.misc.prandom import randint
    C = getDBConnection()
    init_nf_count()
    n = randint(0, nfields - 1)
    label = C.numberfields.fields.find()[n]['label']
    #This version leaves the word 'random' in the URL:
    #return render_field_webpage({'label': label})
    #This version uses the number field's own URL:
    #url =
    return redirect(url_for(".by_label", label=label))
Example #20
0
def random_nfglobal():
    from sage.misc.prandom import randint
    C = getDBConnection()
    init_nf_count()
    n = randint(0,nfields-1)
    label = C.numberfields.fields.find()[n]['label']
    #This version leaves the word 'random' in the URL:
    #return render_field_webpage({'label': label})
    #This version uses the number field's own URL:
    #url =
    return redirect(url_for(".by_label", label= label))
Example #21
0
def search():
    if request.method == "GET":
        val = request.args.get("val", "no value")
        bread = get_bread([("Search for '%s'" % val, url_for('.search'))])
        return render_template(
            "nfgg-search.html",
            title="Search for Galois groups of number fields",
            bread=bread,
            val=val)
    elif request.method == "POST":
        return "ERROR: we always do http get to explicitly display the search parameters"
    else:
        return flask.redirect(404)
Example #22
0
def render_class_group_data():
    info = to_dict(request.args)
    #nf_logger.info('******************* ')
    #for k in info.keys():
    # nf_logger.info(str(k) + ' ---> ' + str(info[k]))
    #nf_logger.info('******************* ')
    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page"))]
    t = 'Class Groups of Quadratic Imaginary Fields'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), (t, ' ')]
    info['message'] =  ''
    info['filename']='none'
    if 'Fetch' in info:
        if 'k' in info:
            # remove non-digits
            k = re.sub(r'\D', '', info['k'])
            if k == "":
                info['message'] = 'The value of k is either invalid or empty'
                return class_group_request_error(info, bread)
            k = int(k)
            if k>4095:
                info['message'] = 'The value of k is too large'
                return class_group_request_error(info, bread)
        else:
            info['message'] = 'The value of k is missing'
            return class_group_request_error(info, bread)
        info['filenamebase'] = str(info['filenamebase'])
        if info['filenamebase'] in ['cl3mod8', 'cl7mod8', 'cl4mod16', 'cl8mod16']:
            filepath = "%s/%s/%s.%d.gz" % (class_group_data_directory,info['filenamebase'],info['filenamebase'],k)
            if os.path.isfile(filepath) and os.access(filepath, os.R_OK):
                return send_file(filepath, as_attachment=True)
            else:
                info['message'] = 'File not found'
                return class_group_request_error(info, bread)
        else:
            info['message'] = 'Invalid congruence requested'
            return class_group_request_error(info, bread)

    return render_template("class_group_data.html", info=info, credit="A. Mosunov and M. J. Jacobson, Jr.", title=t, bread=bread, learnmore=info.pop('learnmore'))
Example #23
0
def global_numberfield_summary():
    init_nf_count()
    return r'This database contains %s <a title="global number fields" knowl="nf">global number fields</a> of <a title="degree" knowl="nf.degree">degree</a> $n\leq %d$.  In addition, extensive data on <a href="%s">class groups of quadratic imaginary fields</a> is available for download.' %(comma(nfields),max_deg,url_for('number_fields.render_class_group_data'))
Example #24
0
def number_field_search(**args):
    info = to_dict(args)

    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page")), ('Quadratic imaginary class groups', url_for(".render_class_group_data"))]
    t = 'Global Number Field search results'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Search results', ' ')]

    # for k in info.keys():
    #  nf_logger.debug(str(k) + ' ---> ' + str(info[k]))
    # nf_logger.debug('******************* '+ str(info['search']))

    if 'natural' in info:
        query = {'label_orig': info['natural']}
        try:
            parse_nf_string(info,query,'natural',name="Label",qfield='label')
            return redirect(url_for(".by_label", label= clean_input(query['label'])))
        except ValueError:
            query['err'] = info['err']
            return search_input_error(query, bread)

    query = {}
    try:
        parse_galgrp(info,query, qfield='galois')
        parse_ints(info,query,'degree')
        parse_bracketed_posints(info,query,'signature',split=False,exactlength=2)
        parse_signed_ints(info,query,'discriminant',qfield=('disc_sign','disc_abs_key'),parse_one=make_disc_key)
        parse_ints(info,query,'class_number')
        parse_bracketed_posints(info,query,'class_group',split=False,check_divisibility='increasing')
        parse_primes(info,query,'ur_primes',name='Unramified primes',qfield='ramps',mode='complement',to_string=True)
        if 'ram_quantifier' in info and str(info['ram_quantifier']) == 'some':
            mode = 'append'
        else:
            mode = 'exact'
        parse_primes(info,query,'ram_primes','ramified primes','ramps',mode,to_string=True)
    except ValueError:
        return search_input_error(info, bread)
    count = parse_count(info)
    start = parse_start(info)

    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    C = base.getDBConnection()
    # nf_logger.debug(query)
    info['query'] = dict(query)
    if 'lucky' in args:
        one = C.numberfields.fields.find_one(query)
        if one:
            label = one['label']
            return redirect(url_for(".by_label", clean_input(label)))

    fields = C.numberfields.fields

    res = fields.find(query)

    if 'download' in info and info['download'] != '0':
        return download_search(info, res)

    res = res.sort([('degree', ASC), ('disc_abs_key', ASC),('disc_sign', ASC)])
    nres = res.count()
    res = res.skip(start).limit(count)

    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0

    info['fields'] = res
    info['number'] = nres
    info['start'] = start
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres

    info['wnf'] = WebNumberField.from_data
    return render_template("number_field_search.html", info=info, title=t, bread=bread)
Example #25
0
def by_label(label):
    try:
        return render_field_webpage({'label': nf_string_to_label(label)})
    except ValueError:
        bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Search results', ' ')]
        return search_input_error({'err':''}, bread)
Example #26
0
def render_field_webpage(args):
    data = None
    C = base.getDBConnection()
    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():
        bread.append(('Search results', ' '))
        info['err'] = 'There is no field with label %s in the database' % label2
        info['label'] = args['label_orig'] if 'label_orig' in args else args['label']
        return search_input_error(info, bread)

    info['wnf'] = nf
    from lmfdb.WebNumberField import nf_display_knowl
    data['degree'] = nf.degree()
    data['class_number'] = nf.class_number()
    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:
            data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), latex(data['conductor'].factor()))
    data['galois_group'] = group_display_knowl(n, t, C)
    data['cclasses'] = cclasses_display_knowl(n, t, C)
    data['character_table'] = character_table_display_knowl(n, t, C)
    data['class_group'] = nf.class_group()
    data['class_group_invs'] = nf.class_group_invariants()
    data['signature'] = nf.signature()
    data['coefficients'] = nf.coeffs()
    D = nf.disc()
    ram_primes = D.prime_factors()
    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'])
    npr = len(ram_primes)
    ram_primes = str(ram_primes)[1:-1]
    if ram_primes == '':
        ram_primes = r'\textrm{None}'
    data['frob_data'], data['seeram'] = frobs(nf.K())
    data['phrase'] = group_phrase(n, t, C)
    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)
    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex_split_on_pm(nf.K().defining_polynomial()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': web_latex(nf.K().primitive_root_of_unity()),
        'fund_units': nf.units(),
        'grh_label': grh_label
    })

    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 group', url_for("characters.dirichlet_group_table",
                                                           modulus=int(conductor),
                                                           char_number_list=','.join(
                                                               [str(a) for a in dirichlet_chars]),
                                                           poly=info['polynomial'])))
    info['learnmore'] = [('Global number field labels', url_for(
        ".render_labels_page")), 
        (Completename, url_for(".render_discriminants_page")),
        ('How data was computed', url_for(".how_computed_page"))]
    if info['signature'] == [0,1]:
        info['learnmore'].append(('Quadratic imaginary class groups', url_for(".render_class_group_data")))
    # With Galois group labels, probably not needed here
    # info['learnmore'] = [('Global number field labels',
    # url_for(".render_labels_page")), ('Galois group
    # labels',url_for(".render_groups_page")),
    # (Completename,url_for(".render_discriminants_page"))]
    title = "Global Number Field %s" % info['label']

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

    properties2 = [('Degree:', '%s' % data['degree']),
                   ('Signature:', '$%s$' % data['signature']),
                   ('Discriminant:', '$%s$' % data['disc_factor']),
                   ('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_display_short(data['degree'], t, C))
                   ]
    from lmfdb.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
#    del info['_id']
    return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, friends=info.pop('friends'), learnmore=info.pop('learnmore'), info=info)
Example #27
0
def number_field_search(**args):
    info = to_dict(args)

    info['learnmore'] = [
        ('Global number field labels', url_for(".render_labels_page")),
        ('Galois group labels', url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page")),
        ('Quadratic imaginary class groups',
         url_for(".render_class_group_data"))
    ]
    t = 'Global Number Field search results'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")),
             ('Search results', ' ')]

    # for k in info.keys():
    #  nf_logger.debug(str(k) + ' ---> ' + str(info[k]))
    # nf_logger.debug('******************* '+ str(info['search']))

    if 'natural' in info:
        field_id = info['natural']
        field_id_parsed = parse_field_string(info['natural'])
        if FIELD_LABEL_RE.match(field_id_parsed):
            field_id_parsed = split_label(
                field_id_parsed)  # allows factored labels 11.11.11e20.1
        return render_field_webpage({
            'label': field_id_parsed,
            'label_orig': field_id
        })
    query = {}
    dlist = []
    for field in [
            'galois_group', 'degree', 'signature', 'discriminant',
            'class_number', 'class_group'
    ]:
        if info.get(field):
            info[field] = clean_input(info[field])
            if field in ['class_group', 'signature']:
                # different regex for the two types
                if (field == 'signature' and PAIR_RE.match(info[field])) or (
                        field == 'class_group' and IF_RE.match(info[field])):
                    query[field] = info[field][1:-1]
                else:
                    name = 'class group' if field == 'class_group' else 'signature'
                    info[
                        'err'] = 'Error parsing input for %s.  It needs to be a pair of integers in square brackets, such as [2,3] or [3,3]' % name
                    return search_input_error(info, bread)
            else:
                if field == 'galois_group':
                    try:
                        gcs = complete_group_codes(info[field])
                        if len(gcs) == 1:
                            query['galois'] = make_galois_pair(
                                gcs[0][0], gcs[0][1])


# list(gcs[0])
                        if len(gcs) > 1:
                            query['galois'] = {
                                '$in':
                                [make_galois_pair(x[0], x[1]) for x in gcs]
                            }
                    except NameError as code:
                        info[
                            'err'] = 'Error parsing input for Galois group: unknown group label %s.  It needs to be a <a title = "Galois group labels" knowl="nf.galois_group.name">group label</a>, such as C5 or 5T1, or comma separated list of labels.' % code
                        return search_input_error(info, bread)
                else:  # not signature, class group, or galois group
                    ran = info[field]
                    ran = ran.replace('..', '-')
                    if LIST_RE.match(ran):
                        if field == 'discriminant':
                            # dlist will contain the disc conditions
                            # as sage ints
                            dlist = parse_discs(ran)
                            # now convert to a query
                            tmp = list_to_query(dlist)
                            # Two cases, could be a list of sign/inequalties
                            # or an '$or'
                            if len(tmp) == 1:
                                tmp = tmp[0]
                            else:
                                query[tmp[0][0]] = tmp[0][1]
                                tmp = tmp[1]
                        else:
                            tmp = parse_range2(ran, field)
                        # work around syntax for $or
                        # we have to foil out multiple or conditions
                        if tmp[0] == '$or' and '$or' in query:
                            newors = []
                            for y in tmp[1]:
                                oldors = [dict.copy(x) for x in query['$or']]
                                for x in oldors:
                                    x.update(y)
                                newors.extend(oldors)
                            tmp[1] = newors
                        query[tmp[0]] = tmp[1]
                    else:
                        name = re.sub('_', ' ', field)
                        info[
                            'err'] = 'Error parsing input for %s.  It needs to be an integer (such as 5), a range of integers (such as 2-100 or 2..100), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-100).' % name
                        return search_input_error(info, bread)
    if info.get('ur_primes'):
        # now we want a list of strings, no spaces, which might be big ints
        info['ur_primes'] = clean_input(info['ur_primes'])
        if LIST_SIMPLE_RE.match(info['ur_primes']):
            ur_primes = info['ur_primes'].split(',')
            # Assuming this will be the only nor in the query
            query['$nor'] = [{'ramps': x} for x in ur_primes]
        else:
            info[
                'err'] = 'Error parsing input for unramified primes.  It needs to be an integer (such as 5), or a comma-separated list of integers (such as 2,3,11).'
            return search_input_error(info, bread)
    if info.get('ram_primes'):
        # now we want a list of strings, no spaces, which might be big ints
        info['ram_primes'] = clean_input(info['ram_primes'])
        if LIST_SIMPLE_RE.match(info['ram_primes']):
            ram_primes = info['ram_primes'].split(',')
            if str(info['ram_quantifier']) == 'some':
                query['ramps'] = {'$all': ram_primes}
            else:
                query['ramps'] = ram_primes
        else:
            info[
                'err'] = 'Error parsing input for ramified primes.  It needs to be an integer (such as 5), or a comma-separated list of integers (such as 2,3,11).'
            return search_input_error(info, bread)

    count_default = 20
    if info.get('count'):
        try:
            count = int(info['count'])
        except:
            count = count_default
            info['count'] = count
    else:
        info['count'] = count_default
        count = count_default
    info['count'] = int(info['count'])

    start_default = 0
    if info.get('start'):
        try:
            start = int(info['start'])
            if (start < 0):
                start += (1 - (start + 1) / count) * count
        except:
            start = start_default
    else:
        start = start_default
    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    C = base.getDBConnection()
    # nf_logger.debug(query)
    info['query'] = dict(query)
    if 'lucky' in args:
        one = C.numberfields.fields.find_one(query)
        if one:
            label = one['label']
            return render_field_webpage({'label': label})

    fields = C.numberfields.fields

    res = fields.find(query).sort([('degree', ASC), ('disc_abs_key', ASC),
                                   ('disc_sign', ASC), ('label', ASC)])

    if 'download' in info and info['download'] != '0':
        return download_search(info, res)

    nres = res.count()
    res = res.skip(start).limit(count)

    if (start >= nres):
        start -= (1 + (start - nres) / count) * count
    if (start < 0):
        start = 0

    info['fields'] = res
    info['number'] = nres
    info['start'] = start
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (
                start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres

    info['wnf'] = WebNumberField.from_data
    return render_template("number_field_search.html",
                           info=info,
                           title=t,
                           bread=bread)
Example #28
0
def render_labels_page():
    info = {}
    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page")), ('Quadratic imaginary class groups', url_for(".render_class_group_data"))]
    t = 'Number field labels'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Number field labels', '')]
    return render_template("single.html", info=info, credit=NF_credit, kid='nf.label', title=t, bread=bread, learnmore=info.pop('learnmore'))
Example #29
0
def number_field_search(**args):
    info = to_dict(args)

    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page")), ('Quadratic imaginary class groups', url_for(".render_class_group_data"))]
    t = 'Global Number Field search results'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Search results', ' ')]

    # for k in info.keys():
    #  nf_logger.debug(str(k) + ' ---> ' + str(info[k]))
    # nf_logger.debug('******************* '+ str(info['search']))

    if 'natural' in info:
        query = {'label_orig': info['natural']}
        try:
            parse_nf_string(info,query,'natural',name="Label",qfield='label')
            return redirect(url_for(".by_label", label= clean_input(query['label'])))
        except ValueError:
            query['err'] = info['err']
            return search_input_error(query, bread)

    query = {}
    try:
        parse_galgrp(info,query, qfield='galois')
        parse_ints(info,query,'degree')
        parse_bracketed_posints(info,query,'signature',split=False,exactlength=2)
        parse_signed_ints(info,query,'discriminant',qfield=('disc_sign','disc_abs_key'),parse_one=make_disc_key)
        parse_ints(info,query,'class_number')
        parse_bracketed_posints(info,query,'class_group',split=False,check_divisibility='increasing')
        parse_primes(info,query,'ur_primes',name='Unramified primes',qfield='ramps',mode='complement',to_string=True)
        if 'ram_quantifier' in info and str(info['ram_quantifier']) == 'some':
            mode = 'append'
        else:
            mode = 'exact'
        parse_primes(info,query,'ram_primes','ramified primes','ramps',mode,to_string=True)
    except ValueError:
        return search_input_error(info, bread)
    count = parse_count(info)
    start = parse_start(info)

    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    C = base.getDBConnection()
    # nf_logger.debug(query)
    info['query'] = dict(query)
    if 'lucky' in args:
        one = C.numberfields.fields.find_one(query)
        if one:
            label = one['label']
            return redirect(url_for(".by_label", clean_input(label)))

    fields = C.numberfields.fields

    res = fields.find(query)

    if 'download' in info and info['download'] != '0':
        return download_search(info, res)

    res = res.sort([('degree', ASC), ('disc_abs_key', ASC),('disc_sign', ASC)])
    nres = res.count()
    res = res.skip(start).limit(count)

    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0

    info['fields'] = res
    info['number'] = nres
    info['start'] = start
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres

    info['wnf'] = WebNumberField.from_data
    return render_template("number_field_search.html", info=info, title=t, bread=bread)
Example #30
0
def render_field_webpage(args):
    data = None
    C = base.getDBConnection()
    info = {}
    bread = [('Global Number Fields', url_for(".number_field_render_webpage"))]

    if 'label' in args:
        label = clean_input(args['label'])
        nf = WebNumberField(label)
        data = {}
    if nf.is_null():
        bread.append(('Search results', ' '))
        label2 = re.sub(r'[<>]', '', args['label'])
        if 'You need to enter a field' in label2:
            info['err'] = label2
        else:
            info['err'] = 'No such field: %s in the database' % label2
        info['label'] = args['label_orig'] if 'label_orig' in args else args['label']
        return search_input_error(info, bread)

    info['wnf'] = nf
    data['degree'] = nf.degree()
    data['class_number'] = nf.class_number()
    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()
        data['dirichlet_group'] = ['<a href = "%s">$\chi_{%s}(%s,&middot;)$</a>' % (url_for("render_Character", arg1=data['conductor'], arg2=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:
            data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), latex(data['conductor'].factor()))
    data['galois_group'] = group_display_knowl(n, t, C)
    data['cclasses'] = cclasses_display_knowl(n, t, C)
    data['character_table'] = character_table_display_knowl(n, t, C)
    data['class_group'] = nf.class_group()
    data['class_group_invs'] = nf.class_group_invariants()
    data['signature'] = nf.signature()
    data['coefficients'] = nf.coeffs()
    D = nf.disc()
    ram_primes = D.prime_factors()
    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'])
    npr = len(ram_primes)
    ram_primes = str(ram_primes)[1:-1]
    if ram_primes == '':
        ram_primes = r'\textrm{None}'
    data['frob_data'], data['seeram'] = frobs(nf.K())
    data['phrase'] = group_phrase(n, t, C)
    zk = pari(nf.K()).nf_subst('a')
    zk = list(zk.nf_get_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()
    pretty_label = field_pretty(label)
    if label != pretty_label:
        pretty_label = "%s: %s" % (label, pretty_label)

    info.update(data)
    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex_split_on_pm(nf.K().defining_polynomial()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': web_latex(nf.K().primitive_root_of_unity()),
        'fund_units': nf.units(),
        'grh_label': grh_label
    })

    bread.append(('%s' % info['label_raw'], ' '))
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', '/')]
    info['friends'] = []
    if nf.can_class_number():
        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 group', url_for("dirichlet_group_table",
                                                           modulus=int(conductor),
                                                           char_number_list=','.join(
                                                               [str(a) for a in dirichlet_chars]),
                                                           poly=info['polynomial'])))
    info['learnmore'] = [('Global number field labels', url_for(
        ".render_labels_page")), (Completename, url_for(".render_discriminants_page"))]
    # With Galois group labels, probably not needed here
    # info['learnmore'] = [('Global number field labels',
    # url_for(".render_labels_page")), ('Galois group
    # labels',url_for(".render_groups_page")),
    # (Completename,url_for(".render_discriminants_page"))]
    title = "Global Number Field %s" % info['label']

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

    properties2 = [('Degree:', '%s' % data['degree']),
                   ('Signature:', '$%s$' % data['signature']),
                   ('Discriminant:', '$%s$' % data['disc_factor']),
                   ('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_display_short(data['degree'], t, C))
                   ]
    from lmfdb.math_classes import NumberFieldGaloisGroup
    try:
        info["tim_number_field"] = NumberFieldGaloisGroup.find_one({"label": label})
        v = nf.factor_perm_repn(info["tim_number_field"])
        info["mydecomp"] = ['*' if x>0 else '' for x in v]
    except AttributeError:
        pass
#    del info['_id']
    return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, friends=info.pop('friends'), learnmore=info.pop('learnmore'), info=info)
Example #31
0
def render_discriminants_page():
    info = {}
    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page"))]
    t = 'Completeness of Global Number Field Data'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), (Completename, ' ')]
    return render_template("discriminant_ranges.html", info=info, credit=NF_credit, title=t, bread=bread, learnmore=info.pop('learnmore'))
Example #32
0
def number_field_search(**args):
    info = to_dict(args)

    info["learnmore"] = [
        ("Global number field labels", url_for(".render_labels_page")),
        ("Galois group labels", url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page")),
        ("Quadratic imaginary class groups", url_for(".render_class_group_data")),
    ]
    t = "Global Number Field search results"
    bread = [("Global Number Fields", url_for(".number_field_render_webpage")), ("Search results", " ")]

    # for k in info.keys():
    #  nf_logger.debug(str(k) + ' ---> ' + str(info[k]))
    # nf_logger.debug('******************* '+ str(info['search']))

    if "natural" in info:
        query = {"label_orig": info["natural"]}
        try:
            parse_nf_string(info, query, "natural", name="Label", qfield="label")
            return redirect(url_for(".by_label", label=clean_input(query["label"])))
        except ValueError:
            query["err"] = info["err"]
            return search_input_error(query, bread)

    query = {}
    try:
        parse_galgrp(info, query, qfield="galois")
        parse_ints(info, query, "degree")
        parse_bracketed_posints(info, query, "signature", split=False, exactlength=2)
        parse_signed_ints(info, query, "discriminant", qfield=("disc_sign", "disc_abs_key"), parse_one=make_disc_key)
        parse_ints(info, query, "class_number")
        parse_bracketed_posints(info, query, "class_group", split=False, check_divisibility="increasing")
        parse_primes(
            info, query, "ur_primes", name="Unramified primes", qfield="ramps", mode="complement", to_string=True
        )
        if "ram_quantifier" in info and str(info["ram_quantifier"]) == "some":
            mode = "append"
        else:
            mode = "exact"
        parse_primes(info, query, "ram_primes", "ramified primes", "ramps", mode, to_string=True)
    except ValueError:
        return search_input_error(info, bread)
    count = parse_count(info)
    start = parse_start(info)

    if info.get("paging"):
        try:
            paging = int(info["paging"])
            if paging == 0:
                start = 0
        except:
            pass

    C = base.getDBConnection()
    # nf_logger.debug(query)
    info["query"] = dict(query)
    if "lucky" in args:
        one = C.numberfields.fields.find_one(query)
        if one:
            label = one["label"]
            return redirect(url_for(".by_label", clean_input(label)))

    fields = C.numberfields.fields

    res = fields.find(query)

    if "download" in info and info["download"] != "0":
        return download_search(info, res)

    res = res.sort([("degree", ASC), ("disc_abs_key", ASC), ("disc_sign", ASC)])
    nres = res.count()
    res = res.skip(start).limit(count)

    if start >= nres:
        start -= (1 + (start - nres) / count) * count
    if start < 0:
        start = 0

    info["fields"] = res
    info["number"] = nres
    info["start"] = start
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count or start != 0:
            info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres)
        else:
            info["report"] = "displaying all %s matches" % nres

    info["wnf"] = WebNumberField.from_data
    return render_template("number_field_search.html", info=info, title=t, bread=bread)
Example #33
0
def render_field_webpage(args):
    data = None
    C = base.getDBConnection()
    info = {}
    bread = [('Global Number Fields', url_for(".number_field_render_webpage"))]

    if 'label' in args:
        label = clean_input(args['label'])
        nf = WebNumberField(label)
        data = {}
    if nf.is_null():
        bread.append(('Search results', ' '))
        label2 = re.sub(r'[<>]', '', args['label'])
        if 'You need to enter a field' in label2:
            info['err'] = label2
        else:
            info['err'] = 'No such field: %s in the database' % label2
        info['label'] = args['label_orig'] if 'label_orig' in args else args['label']
        return search_input_error(info, bread)

    info['wnf'] = nf
    data['degree'] = nf.degree()
    data['class_number'] = nf.class_number()
    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()
        data['dirichlet_group'] = ['<a href = "%s">$\chi_{%s}(%s,&middot;)$</a>' % (url_for("render_Character", arg1=data['conductor'], arg2=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:
            data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), latex(data['conductor'].factor()))
    data['galois_group'] = group_display_knowl(n, t, C)
    data['cclasses'] = cclasses_display_knowl(n, t, C)
    data['character_table'] = character_table_display_knowl(n, t, C)
    data['class_group'] = nf.class_group()
    data['class_group_invs'] = nf.class_group_invariants()
    data['signature'] = nf.signature()
    D = nf.disc()
    ram_primes = D.prime_factors()
    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'])
    npr = len(ram_primes)
    ram_primes = str(ram_primes)[1:-1]
    if ram_primes == '':
        ram_primes = r'\textrm{None}'
    data['frob_data'], data['seeram'] = frobs(nf.K())
    data['phrase'] = group_phrase(n, t, C)
    zk = pari(nf.K()).nf_subst('a')
    zk = list(zk.nf_get_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()
    pretty_label = field_pretty(label)
    if label != pretty_label:
        pretty_label = "%s: %s" % (label, pretty_label)

    info.update(data)
    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex_split_on_pm(nf.K().defining_polynomial()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': web_latex(nf.K().primitive_root_of_unity()),
        'fund_units': nf.units(),
        'grh_label': grh_label
    })

    bread.append(('%s' % info['label_raw'], ' '))
    info['downloads_visible'] = True
    info['downloads'] = [('worksheet', '/')]
    info['friends'] = []
    if nf.can_class_number():
        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 group', url_for("dirichlet_group_table",
                                                           modulus=int(conductor),
                                                           char_number_list=','.join(
                                                               [str(a) for a in dirichlet_chars]),
                                                           poly=info['polynomial'])))
    info['learnmore'] = [('Global number field labels', url_for(
        ".render_labels_page")), (Completename, url_for(".render_discriminants_page"))]
    # With Galois group labels, probably not needed here
    # info['learnmore'] = [('Global number field labels',
    # url_for(".render_labels_page")), ('Galois group
    # labels',url_for(".render_groups_page")),
    # (Completename,url_for(".render_discriminants_page"))]
    title = "Global Number Field %s" % info['label']

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

    properties2 = [('Degree:', '%s' % data['degree']),
                   ('Signature:', '$%s$' % data['signature']),
                   ('Discriminant:', '$%s$' % data['disc_factor']),
                   ('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_display_short(data['degree'], t, C))
                   ]
    from lmfdb.math_classes import NumberFieldGaloisGroup
    try:
        info["tim_number_field"] = NumberFieldGaloisGroup.find_one({"label": label})
        v = nf.factor_perm_repn(info["tim_number_field"])
        info["mydecomp"] = ['*' if x>0 else '' for x in v]
    except AttributeError:
        pass
#    del info['_id']
    return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, friends=info.pop('friends'), learnmore=info.pop('learnmore'), info=info)
Example #34
0
def get_bread(breads=[]):
    bc = [("Number Field Galois Group", url_for(".index"))]
    for b in breads:
        bc.append(b)
    return bc
Example #35
0
def global_numberfield_summary():
    init_nf_count()
    return r'This database contains %s <a title="global number fields" knowl="nf">global number fields</a> of <a title="degree" knowl="nf.degree">degree</a> $n\leq %d$.  In addition, extensive data on <a href="%s">class groups of quadratic imaginary fields</a> is available for download.' %(comma(nfields),max_deg,url_for('number_fields.render_class_group_data'))
Example #36
0
def NF_redirect():
    return redirect(url_for(".number_field_render_webpage", **request.args))
Example #37
0
def render_field_webpage(args):
    data = None
    C = base.getDBConnection()
    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():
        bread.append(("Search results", " "))
        info["err"] = "There is no field with label %s in the database" % label2
        info["label"] = args["label_orig"] if "label_orig" in args else args["label"]
        return search_input_error(info, bread)

    info["wnf"] = nf
    from lmfdb.WebNumberField import nf_display_knowl

    data["degree"] = nf.degree()
    data["class_number"] = nf.class_number()
    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:
            data["conductor"] = "\(%s=%s\)" % (str(data["conductor"]), latex(data["conductor"].factor()))
    data["galois_group"] = group_display_knowl(n, t, C)
    data["cclasses"] = cclasses_display_knowl(n, t, C)
    data["character_table"] = character_table_display_knowl(n, t, C)
    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()
    ram_primes = D.prime_factors()
    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"])
    npr = len(ram_primes)
    ram_primes = str(ram_primes)[1:-1]
    if ram_primes == "":
        ram_primes = r"\textrm{None}"
    data["frob_data"], data["seeram"] = frobs(nf.K())
    data["phrase"] = group_phrase(n, t, C)
    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)
    info.update(
        {
            "label": pretty_label,
            "label_raw": label,
            "polynomial": web_latex_split_on_pm(nf.K().defining_polynomial()),
            "ram_primes": ram_primes,
            "integral_basis": zk,
            "regulator": web_latex(nf.regulator()),
            "unit_rank": nf.unit_rank(),
            "root_of_unity": web_latex(nf.K().primitive_root_of_unity()),
            "fund_units": nf.units(),
            "grh_label": grh_label,
        }
    )

    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 group",
                url_for(
                    "characters.dirichlet_group_table",
                    modulus=int(conductor),
                    char_number_list=",".join([str(a) for a in dirichlet_chars]),
                    poly=info["polynomial"],
                ),
            )
        )
    info["learnmore"] = [
        ("Global number field labels", url_for(".render_labels_page")),
        (Completename, url_for(".render_discriminants_page")),
        ("How data was computed", url_for(".how_computed_page")),
    ]
    if info["signature"] == [0, 1]:
        info["learnmore"].append(("Quadratic imaginary class groups", url_for(".render_class_group_data")))
    # With Galois group labels, probably not needed here
    # info['learnmore'] = [('Global number field labels',
    # url_for(".render_labels_page")), ('Galois group
    # labels',url_for(".render_groups_page")),
    # (Completename,url_for(".render_discriminants_page"))]
    title = "Global Number Field %s" % info["label"]

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

    properties2 = [
        ("Degree:", "%s" % data["degree"]),
        ("Signature:", "$%s$" % data["signature"]),
        ("Discriminant:", "$%s$" % data["disc_factor"]),
        ("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_display_short(data["degree"], t, C)),
    ]
    from lmfdb.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
    #    del info['_id']
    return render_template(
        "number_field.html",
        properties2=properties2,
        credit=NF_credit,
        title=title,
        bread=bread,
        friends=info.pop("friends"),
        learnmore=info.pop("learnmore"),
        info=info,
    )
Example #38
0
def number_field_search(**args):
    info = to_dict(args)

    info["learnmore"] = [
        ("Global number field labels", url_for(".render_labels_page")),
        ("Galois group labels", url_for(".render_groups_page")),
        (Completename, url_for(".render_discriminants_page")),
    ]
    t = "Global Number Field search results"
    bread = [("Global Number Fields", url_for(".number_field_render_webpage")), ("Search results", " ")]

    # for k in info.keys():
    #  nf_logger.debug(str(k) + ' ---> ' + str(info[k]))
    # nf_logger.debug('******************* '+ str(info['search']))
    if "natural" in info:
        field_id = info["natural"]
        field_id_parsed = parse_field_string(info["natural"])
        if FIELD_LABEL_RE.match(field_id_parsed):
            field_id_parsed = split_label(field_id_parsed)  # allows factored labels 11.11.11e20.1
        return render_field_webpage({"label": field_id_parsed, "label_orig": field_id})
    query = {}
    dlist = []
    for field in ["galois_group", "degree", "signature", "discriminant", "class_number", "class_group"]:
        if info.get(field):
            info[field] = clean_input(info[field])
            if field in ["class_group", "signature"]:
                # different regex for the two types
                if (field == "signature" and PAIR_RE.match(info[field])) or (
                    field == "class_group" and IF_RE.match(info[field])
                ):
                    query[field] = info[field][1:-1]
                else:
                    name = "class group" if field == "class_group" else "signature"
                    info["err"] = (
                        "Error parsing input for %s.  It needs to be a pair of integers in square brackets, such as [2,3] or [3,3]"
                        % name
                    )
                    return search_input_error(info, bread)
            else:
                if field == "galois_group":
                    try:
                        gcs = complete_group_codes(info[field])
                        if len(gcs) == 1:
                            query["galois"] = make_galois_pair(gcs[0][0], gcs[0][1])
                        # list(gcs[0])
                        if len(gcs) > 1:
                            query["galois"] = {"$in": [make_galois_pair(x[0], x[1]) for x in gcs]}
                    except NameError as code:
                        info["err"] = (
                            'Error parsing input for Galois group: unknown group label %s.  It needs to be a <a title = "Galois group labels" knowl="nf.galois_group.name">group label</a>, such as C5 or 5T1, or comma separated list of labels.'
                            % code
                        )
                        return search_input_error(info, bread)
                else:  # not signature, class group, or galois group
                    ran = info[field]
                    ran = ran.replace("..", "-")
                    if LIST_RE.match(ran):
                        if field == "discriminant":
                            # dlist will contain the disc conditions
                            # as sage ints
                            dlist = parse_discs(ran)
                            # now convert to a query
                            tmp = list_to_query(dlist)
                            # Two cases, could be a list of sign/inequalties
                            # or an '$or'
                            if len(tmp) == 1:
                                tmp = tmp[0]
                            else:
                                query[tmp[0][0]] = tmp[0][1]
                                tmp = tmp[1]
                        else:
                            tmp = parse_range2(ran, field)
                        # work around syntax for $or
                        # we have to foil out multiple or conditions
                        if tmp[0] == "$or" and "$or" in query:
                            newors = []
                            for y in tmp[1]:
                                oldors = [dict.copy(x) for x in query["$or"]]
                                for x in oldors:
                                    x.update(y)
                                newors.extend(oldors)
                            tmp[1] = newors
                        query[tmp[0]] = tmp[1]
                    else:
                        name = re.sub("_", " ", field)
                        info["err"] = (
                            "Error parsing input for %s.  It needs to be an integer (such as 5), a range of integers (such as 2-100 or 2..100), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-100)."
                            % name
                        )
                        return search_input_error(info, bread)
    if info.get("ur_primes"):
        # now we want a list of strings, no spaces, which might be big ints
        info["ur_primes"] = clean_input(info["ur_primes"])
        if LIST_SIMPLE_RE.match(info["ur_primes"]):
            ur_primes = info["ur_primes"].split(",")
            # Assuming this will be the only nor in the query
            query["$nor"] = [{"ramps": x} for x in ur_primes]
        else:
            info[
                "err"
            ] = "Error parsing input for unramified primes.  It needs to be an integer (such as 5), or a comma-separated list of integers (such as 2,3,11)."
            return search_input_error(info, bread)
    if info.get("ram_primes"):
        # now we want a list of strings, no spaces, which might be big ints
        info["ram_primes"] = clean_input(info["ram_primes"])
        if LIST_SIMPLE_RE.match(info["ram_primes"]):
            ram_primes = info["ram_primes"].split(",")
            if str(info["ram_quantifier"]) == "some":
                query["ramps"] = {"$all": ram_primes}
            else:
                query["ramps"] = ram_primes
        else:
            info[
                "err"
            ] = "Error parsing input for ramified primes.  It needs to be an integer (such as 5), or a comma-separated list of integers (such as 2,3,11)."
            return search_input_error(info, bread)

    count_default = 20
    if info.get("count"):
        try:
            count = int(info["count"])
        except:
            count = count_default
            info["count"] = count
    else:
        info["count"] = count_default
        count = count_default
    info["count"] = int(info["count"])

    start_default = 0
    if info.get("start"):
        try:
            start = int(info["start"])
            if start < 0:
                start += (1 - (start + 1) / count) * count
        except:
            start = start_default
    else:
        start = start_default
    if info.get("paging"):
        try:
            paging = int(info["paging"])
            if paging == 0:
                start = 0
        except:
            pass

    C = base.getDBConnection()
    # nf_logger.debug(query)
    info["query"] = dict(query)
    if "lucky" in args:
        one = C.numberfields.fields.find_one(query)
        if one:
            label = one["label"]
            return render_field_webpage({"label": label})

    fields = C.numberfields.fields

    res = fields.find(query).sort([("degree", ASC), ("disc_abs_key", ASC), ("disc_sign", ASC), ("label", ASC)])

    if "download" in info and info["download"] != "0":
        return download_search(info, res)

    nres = res.count()
    res = res.skip(start).limit(count)

    if start >= nres:
        start -= (1 + (start - nres) / count) * count
    if start < 0:
        start = 0

    info["fields"] = res
    info["number"] = nres
    info["start"] = start
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count or start != 0:
            info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres)
        else:
            info["report"] = "displaying all %s matches" % nres

    info["wnf"] = WebNumberField.from_data
    return render_template("number_field_search.html", info=info, title=t, bread=bread)
Example #39
0
def by_label(label):
    try:
        return render_field_webpage({"label": nf_string_to_label(label)})
    except ValueError:
        bread = [("Global Number Fields", url_for(".number_field_render_webpage")), ("Search results", " ")]
        return search_input_error({"err": ""}, bread)
Example #40
0
def get_bread(breads=[]):
    bc = [("Number Field Galois Group", url_for(".index"))]
    for b in breads:
        bc.append(b)
    return bc
Example #41
0
def NF_redirect():
    return redirect(url_for(".number_field_render_webpage", **request.args))
Example #42
0
def number_field_search(**args):
    info = to_dict(args)

    info['learnmore'] = [('Global number field labels', url_for(".render_labels_page")), ('Galois group labels', url_for(".render_groups_page")), (Completename, url_for(".render_discriminants_page"))]
    t = 'Global Number Field search results'
    bread = [('Global Number Fields', url_for(".number_field_render_webpage")), ('Search results', ' ')]

    # for k in info.keys():
    #  nf_logger.debug(str(k) + ' ---> ' + str(info[k]))
    # nf_logger.debug('******************* '+ str(info['search']))
    if 'natural' in info:
        field_id = info['natural']
        field_id_parsed = parse_field_string(info['natural'])
        if FIELD_LABEL_RE.match(field_id_parsed):
            field_id_parsed = split_label(field_id_parsed)  # allows factored labels 11.11.11e20.1
        return render_field_webpage({'label': field_id_parsed, 'label_orig': field_id})
    query = {}
    dlist = []
    for field in ['galois_group', 'degree', 'signature', 'discriminant', 'class_number', 'class_group']:
        if info.get(field):
            info[field] = clean_input(info[field])
            if field in ['class_group', 'signature']:
                # different regex for the two types
                if (field == 'signature' and PAIR_RE.match(info[field])) or (field == 'class_group' and IF_RE.match(info[field])):
                    query[field] = info[field][1:-1]
                else:
                    name = 'class group' if field == 'class_group' else 'signature'
                    info['err'] = 'Error parsing input for %s.  It needs to be a pair of integers in square brackets, such as [2,3] or [3,3]' % name
                    return search_input_error(info, bread)
            else:
                if field == 'galois_group':
                    try:
                        gcs = complete_group_codes(info[field])
                        if len(gcs) == 1:
                            query['galois'] = make_galois_pair(gcs[0][0], gcs[0][1])
# list(gcs[0])
                        if len(gcs) > 1:
                            query['galois'] = {'$in': [make_galois_pair(x[0], x[1]) for x in gcs]}
                    except NameError as code:
                        info['err'] = 'Error parsing input for Galois group: unknown group label %s.  It needs to be a <a title = "Galois group labels" knowl="nf.galois_group.name">group label</a>, such as C5 or 5T1, or comma separated list of labels.' % code
                        return search_input_error(info, bread)
                else:  # not signature, class group, or galois group
                    ran = info[field]
                    ran = ran.replace('..', '-')
                    if LIST_RE.match(ran):
                        if field == 'discriminant':
                            # dlist will contain the disc conditions
                            # as sage ints
                            dlist = parse_discs(ran)
                            # now convert to a query
                            tmp = list_to_query(dlist)
                            # Two cases, could be a list of sign/inequalties
                            # or an '$or'
                            if len(tmp) == 1:
                                tmp = tmp[0]
                            else:
                                query[tmp[0][0]] = tmp[0][1]
                                tmp = tmp[1]
                        else:
                            tmp = parse_range2(ran, field)
                        # work around syntax for $or
                        # we have to foil out multiple or conditions
                        if tmp[0] == '$or' and '$or' in query:
                            newors = []
                            for y in tmp[1]:
                                oldors = [dict.copy(x) for x in query['$or']]
                                for x in oldors:
                                    x.update(y)
                                newors.extend(oldors)
                            tmp[1] = newors
                        query[tmp[0]] = tmp[1]
                    else:
                        name = re.sub('_', ' ', field)
                        info['err'] = 'Error parsing input for %s.  It needs to be an integer (such as 5), a range of integers (such as 2-100 or 2..100), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-100).' % name
                        return search_input_error(info, bread)
    if info.get('ur_primes'):
        # now we want a list of strings, no spaces, which might be big ints
        info['ur_primes'] = clean_input(info['ur_primes'])
        if LIST_SIMPLE_RE.match(info['ur_primes']):
            ur_primes = info['ur_primes'].split(',')
            # Assuming this will be the only nor in the query
            query['$nor'] = [{'ramps': x} for x in ur_primes]
        else:
            info['err'] = 'Error parsing input for unramified primes.  It needs to be an integer (such as 5), or a comma-separated list of integers (such as 2,3,11).'
            return search_input_error(info, bread)
    if info.get('ram_primes'):
        # now we want a list of strings, no spaces, which might be big ints
        info['ram_primes'] = clean_input(info['ram_primes'])
        if LIST_SIMPLE_RE.match(info['ram_primes']):
            ram_primes = info['ram_primes'].split(',')
            if str(info['ram_quantifier']) == 'some':
                query['ramps'] = {'$all': ram_primes}
            else:
                query['ramps'] = ram_primes
        else:
            info['err'] = 'Error parsing input for ramified primes.  It needs to be an integer (such as 5), or a comma-separated list of integers (such as 2,3,11).'
            return search_input_error(info, bread)

    count_default = 20
    if info.get('count'):
        try:
            count = int(info['count'])
        except:
            count = count_default
            info['count'] = count
    else:
        info['count'] = count_default
        count = count_default
    info['count'] = int(info['count'])

    start_default = 0
    if info.get('start'):
        try:
            start = int(info['start'])
            if(start < 0):
                start += (1 - (start + 1) / count) * count
        except:
            start = start_default
    else:
        start = start_default
    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    C = base.getDBConnection()
    # nf_logger.debug(query)
    info['query'] = dict(query)
    if 'lucky' in args:
        one = C.numberfields.fields.find_one(query)
        if one:
            label = one['label']
            return render_field_webpage({'label': label})

    fields = C.numberfields.fields

    res = fields.find(
        query).sort([('degree', ASC), ('disc_abs_key', ASC), ('disc_sign', ASC), ('label', ASC)])

    if 'download' in info and info['download'] != '0':
        return download_search(info, res)

    nres = res.count()
    res = res.skip(start).limit(count)

    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0

    info['fields'] = res
    info['number'] = nres
    info['start'] = start
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres

    info['wnf'] = WebNumberField.from_data
    return render_template("number_field_search.html", info=info, title=t, bread=bread)
Example #43
0
def render_field_webpage(args):
    data = None
    C = base.getDBConnection()
    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():
        bread.append(('Search results', ' '))
        info['err'] = 'There is no field with label %s in the database' % label2
        info['label'] = args['label_orig'] if 'label_orig' in args else args['label']
        return search_input_error(info, bread)

    info['wnf'] = nf
    from lmfdb.WebNumberField import nf_display_knowl
    data['degree'] = nf.degree()
    data['class_number'] = nf.class_number()
    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:
            data['conductor'] = "\(%s=%s\)" % (str(data['conductor']), latex(data['conductor'].factor()))
    data['galois_group'] = group_display_knowl(n, t, C)
    data['cclasses'] = cclasses_display_knowl(n, t, C)
    data['character_table'] = character_table_display_knowl(n, t, C)
    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()
    ram_primes = D.prime_factors()
    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'])
    npr = len(ram_primes)
    ram_primes = str(ram_primes)[1:-1]
    if ram_primes == '':
        ram_primes = r'\textrm{None}'
    data['frob_data'], data['seeram'] = frobs(nf.K())
    data['phrase'] = group_phrase(n, t, C)
    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)
    info.update({
        'label': pretty_label,
        'label_raw': label,
        'polynomial': web_latex_split_on_pm(nf.K().defining_polynomial()),
        'ram_primes': ram_primes,
        'integral_basis': zk,
        'regulator': web_latex(nf.regulator()),
        'unit_rank': nf.unit_rank(),
        'root_of_unity': web_latex(nf.K().primitive_root_of_unity()),
        'fund_units': nf.units(),
        'grh_label': grh_label
    })

    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 group', url_for("characters.dirichlet_group_table",
                                                           modulus=int(conductor),
                                                           char_number_list=','.join(
                                                               [str(a) for a in dirichlet_chars]),
                                                           poly=info['polynomial'])))
    info['learnmore'] = [('Global number field labels', url_for(
        ".render_labels_page")), 
        (Completename, url_for(".render_discriminants_page")),
        ('How data was computed', url_for(".how_computed_page"))]
    if info['signature'] == [0,1]:
        info['learnmore'].append(('Quadratic imaginary class groups', url_for(".render_class_group_data")))
    # With Galois group labels, probably not needed here
    # info['learnmore'] = [('Global number field labels',
    # url_for(".render_labels_page")), ('Galois group
    # labels',url_for(".render_groups_page")),
    # (Completename,url_for(".render_discriminants_page"))]
    title = "Global Number Field %s" % info['label']

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

    properties2 = [('Degree:', '%s' % data['degree']),
                   ('Signature:', '$%s$' % data['signature']),
                   ('Discriminant:', '$%s$' % data['disc_factor']),
                   ('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_display_short(data['degree'], t, C))
                   ]
    from lmfdb.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
#    del info['_id']
    return render_template("number_field.html", properties2=properties2, credit=NF_credit, title=title, bread=bread, friends=info.pop('friends'), learnmore=info.pop('learnmore'), info=info)