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)
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'))
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'))
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)
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)
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'))
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") )
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") )
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'))
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") )
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"), )
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))
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'))
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)
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'))
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)
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))
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))
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)
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'))
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'))
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)
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)
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,·)$</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)
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)
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'))
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,·)$</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)
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'))
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)
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,·)$</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)
def get_bread(breads=[]): bc = [("Number Field Galois Group", url_for(".index"))] for b in breads: bc.append(b) return bc
def NF_redirect(): return redirect(url_for(".number_field_render_webpage", **request.args))
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,·)$</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, )
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)
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)
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)
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,·)$</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)