def make_cm_query(cm_disc_str): cm_list = parse_ints_to_list_flash(cm_disc_str, "CM discriminant", max_val=None) for d in cm_list: if not ((d < 0) and (d % 4 in [0,1])): raise ValueError("A CM discriminant must be a fundamental discriminant of an imaginary quadratic field.") cm_list += [-el for el in cm_list] return cm_list
def parse_dim_args(dim_args, default_dim_args): res={} for v in ['k','j']: arg = dim_args.get(v) if dim_args else None if not arg: arg = default_dim_args.get(v) if default_dim_args else None if arg: res[v] = parse_ints_to_list_flash(arg, "$"+v+"$") args={} if 'k' in res: if res['k'][-1] > MAXWT: flash(Markup("Error: <span style='color:black'>$k$</span> cannot exceed <span style='color:black'>%s</span>." % MAXWT), "error") raise ValueError("dim_args") if len(res['k']) > MAXWTRANGE: flash(Markup("Error: range for <span style='color:black'>$k$</span> cannot include more than %s</span> values." % MAXWTRANGE), "error") raise ValueError("dim_args") args = {'k_range':res['k']} if 'j' in res: if res['j'][-1] > MAXJ: flash(Markup("Error: <span style='color:black'>$j$</span> cannot exceed <span style='color:black'>%s</span>." % MAXJ), "error") raise ValueError("dim_args") args['j_range'] = [j for j in res['j'] if j%2 == 0] if not args['j_range']: flash(Markup("Error: <span style='color:black'>$j$</span> should be a nonnegative even integer."), "error") raise ValueError("dim_args") return args
def parse_dim_args(dim_args, default_dim_args): res = {} for v in ['k', 'j']: arg = dim_args.get(v) if dim_args else None if not arg: arg = default_dim_args.get(v) if default_dim_args else None if arg: res[v] = parse_ints_to_list_flash(arg, "$" + v + "$") args = {} if 'k' in res: if res['k'][-1] > MAXWT: flash_error( "<span style='color:black'>$k$</span> cannot exceed %s.", MAXWT) raise ValueError("dim_args") if len(res['k']) > MAXWTRANGE: flash_error( "range for <span style='color:black'>$k$</span> cannot include more than %s values.", MAXWTRANGE) raise ValueError("dim_args") args = {'k_range': res['k']} if 'j' in res: if res['j'][-1] > MAXJ: flash_error( "<span style='color:black'>$j$</span> cannot exceed %s.", MAXJ) raise ValueError("dim_args") args['j_range'] = [j for j in res['j'] if j % 2 == 0] if not args['j_range']: flash_error( "<span style='color:black'>$j$</span> should be a nonnegative even integer." ) raise ValueError("dim_args") return args
def search(info): """ query processing for Sato-Tate groups -- returns rendered results page """ if 'jump' in info: return redirect(url_for('.by_label', label=info['jump']), 301) if 'label' in info: return redirect(url_for('.by_label', label=info['label']), 301) search_type = info.get("search_type", info.get("hst", "List")) template_kwds = { 'bread': [('Sato-Tate Groups', url_for('.index')), ('Search Results', '.')], 'credit': credit_string, 'learnmore': learnmore_list() } title = 'Sato-Tate Group Search Results' err_title = 'Sato-Tate Groups Search Input Error' count = parse_count(info, 50) start = parse_start(info) # if user clicked refine search always restart at 0 if 'refine' in info: start = 0 ratonly = (info.get('include_irrational', 'no').strip().lower() == 'no') if search_type == "Random" and not ratonly: info['err'] = err = 'Cannot select random irrational Sato-Tate group' flash_error(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) query = {'rational': True} if ratonly else {} try: parse_ints(info, query, 'weight', 'weight') if 'weight' in query: weight_list = parse_ints_to_list_flash(info.get('weight'), 'weight') parse_ints(info, query, 'degree', 'degree') if 'degree' in query: degree_list = parse_ints_to_list_flash(info.get('degree'), 'degree') if info.get('identity_component'): query['identity_component'] = info['identity_component'] parse_ints(info, query, 'components', 'components') if 'components' in query: components_list = parse_ints_to_list_flash(info.get('components'), 'components') parse_rational(info, query, 'trace_zero_density', 'trace zero density') except ValueError as err: info['err'] = str(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) # Check mu(n) groups first (these are not stored in the database) results = [] if ((not 'weight' in query or 0 in weight_list) and (not 'degree' in query or 1 in degree_list) and (not 'identity_component' in query or query['identity_component'] == 'SO(1)') and (not 'trace_zero_density' in query or query['trace_zero_density'] == '0')): if not 'components' in query: components_list = range(1, 3 if ratonly else start + count + 1) elif ratonly: components_list = [n for n in range(1, 3) if n in components_list] nres = len( components_list) if 'components' in query or ratonly else INFINITY if search_type == "Random" and nres > 0: # Need to return mu(1) and mu(2) sometimes otherlen = db.gps_sato_tate.count(query) r = ZZ.random_element(nres + otherlen) if r < nres: return redirect( url_for(".by_label", label="0.1.%d" % components_list[r]), 307) for n in itertools.islice(components_list, start, start + count): results.append(mu_info(n)) else: nres = 0 if 'result_count' in info: nres += db.gps_sato_tate.count(query) return jsonify({"nres": str(nres)}) if search_type == "Random": label = db.gps_sato_tate.random(query, "label") if label is not None: return redirect(url_for(".by_label", label=label), 307) # Now lookup other (rational) ST groups in database if nres != INFINITY: start2 = start - nres if start > nres else 0 proj = [ 'label', 'weight', 'degree', 'real_dimension', 'identity_component', 'name', 'pretty', 'components', 'component_group', 'trace_zero_density', 'moments' ] try: res = db.gps_sato_tate.search(query, proj, limit=max(count - len(results), 0), offset=start2, info=info) except QueryCanceledError as err: ctx = ctx_proc_userdata() flash_error( 'The search query took longer than expected! Please help us improve by reporting this error <a href="%s" target=_blank>here</a>.' % ctx['feedbackpage']) info['err'] = str(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) info['number'] += nres if start < info['number'] and len(results) < count: for v in res: v['identity_component'] = st0_pretty(v['identity_component']) v['component_group'] = sg_pretty(v['component_group']) v['trace_moments'] = trace_moments(v['moments']) results.append(v) else: info['number'] = 'infinity' info['start'] = start info['count'] = count info['st0_list'] = st0_list info['st0_dict'] = st0_dict info['results'] = results info['stgroup_url'] = lambda dbc: url_for('.by_label', label=dbc['label']) return render_template('st_results.html', info=info, title=title, **template_kwds)
def render_sample_page(family, sam, args, bread): info = { 'args': to_dict(args), 'sam': sam, 'latex': latex, 'type': sam.type(), 'name': sam.name(), 'full_name': sam.full_name(), 'weight': sam.weight(), 'fdeg': sam.degree_of_field(), 'is_eigenform': sam.is_eigenform(), 'field_poly': sam.field_poly() } if sam.is_integral() is not None: info['is_integral'] = sam.is_integral() if 'Sp4Z' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=0) if 'Sp4Z_2' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=2) info['space'] = '$' + family.latex_name.replace( 'k', '{' + str(sam.weight()) + '}') + '$' if 'space_url' in info: bread.append((info['space'], info['space_url'])) info['space_href'] = '<a href="%s">%s</d>' % ( info['space_url'], info['space']) if 'space_url' in info else info['space'] if info['field_poly'].disc() < 10**10: label = poly_to_field_label(info['field_poly']) if label: info['field_label'] = label info['field_url'] = url_for('number_fields.by_label', label=label) info['field_href'] = '<a href="%s">%s</a>' % (info['field_url'], field_pretty(label)) bread.append((info['name'], '')) title = 'Siegel modular forms sample ' + info['full_name'] properties = [('Space', info['space_href']), ('Name', info['name']), ('Type', '<br>'.join(info['type'].split(','))), ('Weight', prop_int_pretty(info['weight'])), ('Hecke eigenform', "yes" if info['is_eigenform'] else "no"), ('Field degree', prop_int_pretty(info['fdeg']))] try: evs_to_show = parse_ints_to_list_flash(args.get('ev_index'), 'list of $l$') fcs_to_show = parse_ints_to_list_flash(args.get('fc_det'), 'list of $\\det(F)$') except ValueError: evs_to_show = [] fcs_to_show = [] info['evs_to_show'] = sorted([ n for n in (evs_to_show if len(evs_to_show) else sam.available_eigenvalues()[:10]) ]) info['fcs_to_show'] = sorted([ n for n in (fcs_to_show if len(fcs_to_show) else sam. available_Fourier_coefficients()[1:6]) ]) info['evs_avail'] = [n for n in sam.available_eigenvalues()] info['fcs_avail'] = [n for n in sam.available_Fourier_coefficients()] # Do not attempt to constuct a modulus ideal unless the field has a reasonably small discriminant # otherwise sage may not even be able to factor the discriminant info['field'] = sam.field() if info['field_poly'].disc() < 10**80: null_ideal = sam.field().ring_of_integers().ideal(0) info['modulus'] = null_ideal modulus = args.get('modulus', '').strip() m = 0 if modulus: try: O = sam.field().ring_of_integers() m = O.ideal([O(str(b)) for b in modulus.split(',')]) except Exception: info['error'] = True flash_error( "Unable to construct modulus ideal from specified generators %s.", modulus) if m == 1: info['error'] = True flash_error( "The ideal %s is the unit ideal, please specify a different modulus.", '(' + modulus + ')') m = 0 info['modulus'] = m # Hack to reduce polynomials and to handle non integral stuff def redc(c): return m.reduce(c * c.denominator()) / m.reduce(c.denominator()) def redp(f): c = f.dict() return f.parent()(dict((e, redc(c[e])) for e in c)) def safe_reduce(f): if not m: return latex(f) try: if f in sam.field(): return latex(redc(f)) else: return latex(redp(f)) except ZeroDivisionError: return '\\textrm{Unable to reduce} \\bmod\\mathfrak{m}' info['reduce'] = safe_reduce else: info['reduce'] = latex # check that explicit formula is not ridiculously big if sam.explicit_formula(): info['explicit_formula_bytes'] = len(sam.explicit_formula()) if len(sam.explicit_formula()) < 100000: info['explicit_formula'] = sam.explicit_formula() return render_template("ModularForm_GSp4_Q_sample.html", title=title, bread=bread, properties=properties, info=info)
def search(**args): """ query processing for Sato-Tate groups -- returns rendered results page """ info = to_dict(args) if 'jump' in info: return redirect(url_for('.by_label', label=info['jump']), 301) if 'label' in info: return redirect(url_for('.by_label', label=info['label']), 301) template_kwds = {'bread':[('Sato-Tate Groups', url_for('.index')),('Search Results', '.')], 'credit':credit_string, 'learnmore':learnmore_list()} title = 'Sato-Tate Group Search Results' err_title = 'Sato-Tate Groups Search Input Error' count = parse_count(info, 25) start = parse_start(info) # if user clicked refine search always restart at 0 if 'refine' in info: start = 0 ratonly = True if info.get('rational_only','no').strip().lower() == 'yes' else False query = {'rational':True} if ratonly else {} try: parse_ints(info,query,'weight','weight') if 'weight' in query: weight_list = parse_ints_to_list_flash(info.get('weight'),'weight') parse_ints(info,query,'degree','degree') if 'degree' in query: degree_list = parse_ints_to_list_flash(info.get('degree'),'degree') if info.get('identity_component'): query['identity_component'] = info['identity_component'] parse_ints(info,query,'components','components') if 'components' in query: components_list = parse_ints_to_list_flash(info.get('components'), 'components') parse_rational(info,query,'trace_zero_density','trace zero density') except ValueError as err: info['err'] = str(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) # Check mu(n) groups first (these are not stored in the database) results = [] if (not 'weight' in query or 0 in weight_list) and \ (not 'degree' in query or 1 in degree_list) and \ (not 'identity_component' in query or query['identity_component'] == 'SO(1)') and \ (not 'trace_zero_density' in query or query['trace_zero_density'] == '0'): if not 'components' in query: components_list = xrange(1,3 if ratonly else start+count+1) elif ratonly: components_list = [n for n in range(1,3) if n in components_list] nres = len(components_list) if 'components' in query or ratonly else INFINITY for n in itertools.islice(components_list,start,start+count): results.append(mu_info(n)) else: nres = 0 if 'result_count' in info: nres += db.gps_sato_tate.count(query) return jsonify({"nres":str(nres)}) # Now lookup other (rational) ST groups in database if nres != INFINITY: start2 = start - nres if start > nres else 0 proj = ['label','weight','degree','real_dimension','identity_component','name','pretty','components','component_group','trace_zero_density','moments'] try: res = db.gps_sato_tate.search(query, proj, limit=max(count - len(results), 0), offset=start2, info=info) except QueryCanceledError as err: ctx = ctx_proc_userdata() flash_error('The search query took longer than expected! Please help us improve by reporting this error <a href="%s" target=_blank>here</a>.' % ctx['feedbackpage']) info['err'] = str(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) info['number'] += nres if start < info['number'] and len(results) < count: for v in res: v['identity_component'] = st0_pretty(v['identity_component']) v['component_group'] = sg_pretty(v['component_group']) v['trace_moments'] = trace_moments(v['moments']) results.append(v) else: info['number'] = 'infinity' info['start'] = start info['count'] = count info['st0_list'] = st0_list info['st0_dict'] = st0_dict info['results'] = results info['stgroup_url'] = lambda dbc: url_for('.by_label', label=dbc['label']) return render_template('st_results.html', info=info, title=title, **template_kwds)
def search(info): """ query processing for Sato-Tate groups -- returns rendered results page """ if 'jump' in info: return redirect(url_for('.by_label', label=info['jump']), 301) if 'label' in info: return redirect(url_for('.by_label', label=info['label']), 301) search_type = info.get("search_type", info.get("hst", "List")) template_kwds = { 'bread': get_bread("Search results"), 'credit': credit_string, 'learnmore': learnmore_list() } title = 'Sato-Tate group search results' err_title = 'Sato-Tate group search input error' count = parse_count(info, 50) start = parse_start(info) # if user clicked refine search always restart at 0 if 'refine' in info: start = 0 ratonly = (info.get('include_irrational', 'no').strip().lower() == 'no') if search_type == "Random" and not ratonly: info['err'] = err = 'Cannot select random irrational Sato-Tate group' flash_error(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) query = {'rational': True} if ratonly else {} try: parse_ints(info, query, 'weight', 'weight') if 'weight' in query: weight_list = parse_ints_to_list_flash(info.get('weight'), 'weight') parse_ints(info, query, 'degree', 'degree') if 'degree' in query: degree_list = parse_ints_to_list_flash(info.get('degree'), 'degree') if info.get('identity_component'): query['identity_component'] = info['identity_component'] parse_ints(info, query, 'components', 'components') def refine_components(current, condition): if current is None: return condition return [x for x in condition if x in current] # The following are used to constraint which mu(n) will show up in search results components_list = None ommitted = set() if 'components' in query: components_list = parse_ints_to_list_flash(info.get('components'), 'components') parse_component_group(info, query) gps = query.get("component_group") if gps: if isinstance(gps, dict): gps = gps["$in"] else: gps = [gps] if not ratonly: cyclic_labels = set( db.gps_small.search({"cyclic": True}, "label")) irrat = [] for code in gps: if code in cyclics: irrat.append(cyclics[code]) elif re.match(cyclicre, code): irrat.append(int(code[1:])) elif not ratonly and code in cyclic_labels: irrat.append(int(code.split(".")[0])) components_list = refine_components(components_list, irrat) parse_rational(info, query, 'trace_zero_density', 'trace zero density') parse_ints(info, query, 'second_trace_moment') parse_ints(info, query, 'fourth_trace_moment') for name, ones in [('second_trace_moment', [1, 2]), ('fourth_trace_moment', [1, 2, 4])]: if name in query: # E(x^2) for mu(1) and mu(2) are 1; others are 0 # E(x^4) for mu(1), mu(2) and mu(4) are 1; others are 0 E = parse_ints_to_list_flash(info.get(name), name.replace("_", " ")) if 0 not in E: components_list = refine_components(components_list, ones) if 1 not in E: ommitted.update(ones) parse_ints(info, query, 'first_a2_moment') parse_bool(info, query, 'maximal') if "first_a2_moment" in query or query.get("maximal"): # mu(n) do not have a2 moments and none are maximal components_list = [] except ValueError as err: info['err'] = str(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) # Check mu(n) groups first (these are not stored in the database) results = [] if ((not 'weight' in query or 0 in weight_list) and (not 'degree' in query or 1 in degree_list) and (not 'identity_component' in query or query['identity_component'] == 'SO(1)') and (not 'trace_zero_density' in query or query['trace_zero_density'] == '0')): nres = None if components_list is None: components_list = range( 1, 3 if ratonly else (start + count + 1 + len(ommitted))) nres = None if ratonly else INFINITY elif ratonly: components_list = [n for n in range(1, 3) if n in components_list] components_list = [n for n in components_list if n not in ommitted] if nres is None: nres = len(components_list) if search_type == "Random" and nres > 0: # Need to return mu(1), mu(2) or mu(4) sometimes otherlen = db.gps_sato_tate.count(query) r = ZZ.random_element(nres + otherlen) if r < nres: return redirect( url_for(".by_label", label="0.1.%d" % components_list[r]), 307) for n in itertools.islice(components_list, start, start + count): results.append(mu_info(n)) else: nres = 0 if 'result_count' in info: nres += db.gps_sato_tate.count(query) return jsonify({"nres": str(nres)}) if search_type == "Random": label = db.gps_sato_tate.random(query, "label") if label is not None: return redirect(url_for(".by_label", label=label), 307) # Now lookup other (rational) ST groups in database if nres != INFINITY: start2 = start - nres if start > nres else 0 proj = [ 'label', 'weight', 'degree', 'real_dimension', 'identity_component', 'name', 'pretty', 'components', 'component_group', 'trace_zero_density', 'moments' ] try: res = db.gps_sato_tate.search(query, proj, limit=max(count - len(results), 0), offset=start2, info=info) except QueryCanceledError as err: ctx = ctx_proc_userdata() flash_error( 'The search query took longer than expected! Please help us improve by reporting this error <a href="%s" target=_blank>here</a>.' % ctx['feedbackpage']) info['err'] = str(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) info['number'] += nres if start < info['number'] and len(results) < count: for v in res: v['identity_component'] = st0_pretty(v['identity_component']) v['component_group'] = sg_pretty(v['component_group']) v['trace_moments'] = trace_moments(v['moments']) results.append(v) else: info['number'] = 'infinity' info['start'] = start info['count'] = count info['st0_list'] = st0_list info['st0_dict'] = st0_dict info['results'] = results info['stgroup_url'] = lambda dbc: url_for('.by_label', label=dbc['label']) return render_template('st_results.html', info=info, title=title, **template_kwds)
def render_sample_page(family, sam, args, bread): info = { 'args': to_dict(args), 'sam': sam, 'latex': latex, 'type':sam.type(), 'name':sam.name(), 'full_name': sam.full_name(), 'weight':sam.weight(), 'fdeg':sam.degree_of_field(), 'is_eigenform':sam.is_eigenform(), 'field_poly': sam.field_poly()} if sam.is_integral() != None: info['is_integral'] = sam.is_integral() if 'Sp4Z' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=0) if 'Sp4Z_2' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=2) info['space'] = '$'+family.latex_name.replace('k', '{' + str(sam.weight()) + '}')+'$' if 'space_url' in info: bread.append((info['space'], info['space_url'])) info['space_href'] = '<a href="%s">%s</d>'%(info['space_url'],info['space']) if 'space_url' in info else info['space'] if info['field_poly'].disc() < 10**10: label = poly_to_field_label(info['field_poly']) if label: info['field_label'] = label info['field_url'] = url_for('number_fields.by_label', label=label) info['field_href'] = '<a href="%s">%s</a>'%(info['field_url'], field_pretty(label)) bread.append((info['name'], '')) title='Siegel Modular Forms Sample ' + info['full_name'] properties = [('Space', info['space_href']), ('Name', info['name']), ('Type', '<br>'.join(info['type'].split(','))), ('Weight', str(info['weight'])), ('Hecke eigenform', str(info['is_eigenform'])), ('Field degree', str(info['fdeg']))] try: evs_to_show = parse_ints_to_list_flash(args.get('ev_index'), 'list of $l$') fcs_to_show = parse_ints_to_list_flash(args.get('fc_det'), 'list of $\\det(F)$') except ValueError: evs_to_show = [] fcs_to_show = [] info['evs_to_show'] = sorted([n for n in (evs_to_show if len(evs_to_show) else sam.available_eigenvalues()[:10])]) info['fcs_to_show'] = sorted([n for n in (fcs_to_show if len(fcs_to_show) else sam.available_Fourier_coefficients()[1:6])]) info['evs_avail'] = [n for n in sam.available_eigenvalues()] info['fcs_avail'] = [n for n in sam.available_Fourier_coefficients()] # Do not attempt to constuct a modulus ideal unless the field has a reasonably small discriminant # otherwise sage may not even be able to factor the discriminant info['field'] = sam.field() if info['field_poly'].disc() < 10**80: null_ideal = sam.field().ring_of_integers().ideal(0) info['modulus'] = null_ideal modulus = args.get('modulus','').strip() m = 0 if modulus: try: O = sam.field().ring_of_integers() m = O.ideal([O(str(b)) for b in modulus.split(',')]) except Exception: info['error'] = True flash_error("Unable to construct modulus ideal from specified generators %s.", modulus) if m == 1: info['error'] = True flash_error("The ideal %s is the unit ideal, please specify a different modulus.", '('+modulus+')') m = 0 info['modulus'] = m # Hack to reduce polynomials and to handle non integral stuff def redc(c): return m.reduce(c*c.denominator())/m.reduce(c.denominator()) def redp(f): c = f.dict() return f.parent()(dict((e,redc(c[e])) for e in c)) def safe_reduce(f): if not m: return latex(f) try: if f in sam.field(): return latex(redc(f)) else: return latex(redp(f)) except ZeroDivisionError: return '\\textrm{Unable to reduce} \\bmod\\mathfrak{m}' info['reduce'] = safe_reduce else: info['reduce'] = latex # check that explicit formula is not ridiculously big if sam.explicit_formula(): info['explicit_formula_bytes'] = len(sam.explicit_formula()) if len(sam.explicit_formula()) < 100000: info['explicit_formula'] = sam.explicit_formula() return render_template("ModularForm_GSp4_Q_sample.html", title=title, bread=bread, properties2=properties, info=info)