def search(info, query): parse_ints(info, query, 'level', name='Level') parse_ints(info, query, 'weight', name='Weight') parse_character(info, query, 'character', name='Character') parse_floats(info, query, 'spectral_parameter', name='Spectral parameter') if info.get('symmetry'): query['symmetry'] = int(info['symmetry'])
def artin_representation_search(info, query): query['Hide'] = 0 info['sign_code'] = 0 parse_primes(info, query, "unramified", name="Unramified primes", qfield="BadPrimes", mode="complement") parse_primes(info, query, "ramified", name="Ramified primes", qfield="BadPrimes", mode="append") parse_element_of(info, query, "root_number", qfield="GalConjSigns") parse_restricted(info, query, "frobenius_schur_indicator", qfield="Indicator", allowed=[1, 0, -1], process=int) parse_container(info, query, 'container', qfield='Container', name="Smallest permutation representation") parse_galgrp(info, query, "group", name="Group", qfield=("Galn", "Galt")) parse_ints(info, query, 'dimension', qfield='Dim') parse_ints(info, query, 'conductor', qfield='Conductor') parse_bool(info, query, 'Is_Even')
def number_field_search(info, query): parse_ints(info,query,'degree') parse_galgrp(info,query, qfield=('degree', 'galt')) parse_bracketed_posints(info,query,'signature',qfield=('degree','r2'),exactlength=2,extractor=lambda L: (L[0]+2*L[1],L[1])) parse_signed_ints(info,query,'discriminant',qfield=('disc_sign','disc_abs')) parse_floats(info, query, 'rd') parse_ints(info,query,'class_number') parse_bool(info,query,'cm_field',qfield='cm') parse_bracketed_posints(info,query,'class_group',check_divisibility='increasing',process=int) parse_primes(info,query,'ur_primes',name='Unramified primes', qfield='ramps',mode='complement') # modes are now contained (in), exactly, include if 'ram_quantifier' in info and str(info['ram_quantifier']) == 'include': mode='append' elif 'ram_quantifier' in info and str(info['ram_quantifier']) == 'contained': mode='subsets' else: mode='exact' parse_primes(info,query,'ram_primes',name='Ramified primes', qfield='ramps',mode=mode,radical='disc_rad') ## This seems not to be used #if 'lucky' in info: # label = db.nf_fields.lucky(query, 0) # if label: # return redirect(url_for(".by_label", label=clean_input(label))) info['wnf'] = WebNumberField.from_data info['gg_display'] = group_pretty_and_nTj
def bianchi_modular_form_search(info, query): """Function to handle requests from the top page, either jump to one newform or do a search. """ parse_nf_string(info, query, 'field_label', name='base number field') parse_noop(info, query, 'label') parse_ints(info, query, 'dimension') parse_ints(info, query, 'level_norm') parse_primes(info, query, 'field_bad_primes', name='field bad primes', qfield='field_bad_primes',mode=info.get('field_bad_quantifier')) parse_primes(info, query, 'level_bad_primes', name='level bad primes', qfield='level_bad_primes',mode=info.get('level_bad_quantifier')) if 'sfe' not in info: info['sfe'] = "any" elif info['sfe'] != "any": query['sfe'] = int(info['sfe']) if 'include_cm' in info: if info['include_cm'] in ['exclude', 'off']: query['CM'] = 0 # will exclude NULL values elif info['include_cm'] == 'only': query['CM'] = {'$ne': 0} # will exclude NULL values if info.get('include_base_change') =='exclude': query['bc'] = 0 elif info.get('include_base_change') == 'only': query['bc'] = {'$ne': 0}
def abelian_variety_browse(**args): info = to_dict(args) if not('table_dimension_range' in info) or (info['table_dimension_range']==''): info['table_dimension_range'] = "1-6" if not('table_field_range' in info) or (info['table_field_range']==''): info['table_field_range'] = "2-27" table_params = {} av_stats=AbvarFqStats() # Handle dimension range gs = av_stats.gs try: if ',' in info['table_dimension_range']: flash_error("You cannot use commas in the table ranges.") raise ValueError parse_ints(info,table_params,'table_dimension_range',qfield='g') except (ValueError, AttributeError, TypeError): gmin, gmax = 1, 6 else: if isinstance(table_params['g'], int): gmin = gmax = table_params['g'] else: gmin = table_params['g'].get('$gte',min(gs) if gs else table_params['g'].get('$lte',1)) gmax = table_params['g'].get('$lte',max(gs) if gs else table_params['g'].get('$gte',20)) # Handle field range qs = av_stats.qs try: if ',' in info['table_field_range']: flash_error("You cannot use commas in the table ranges.") raise ValueError parse_ints(info,table_params,'table_field_range',qfield='q') except (ValueError, AttributeError, TypeError): qmin, qmax = 2, 27 else: if isinstance(table_params['q'], int): qmin = qmax = table_params['q'] else: qmin = table_params['q'].get('$gte',min(qs) if qs else table_params['q'].get('$lte',0)) qmax = table_params['q'].get('$lte',max(qs) if qs else table_params['q'].get('$gte',1000)) info['table'] = defaultdict(lambda: defaultdict(int)) if gmin == gmax: info['table_dimension_range'] = "{0}".format(gmin) else: info['table_dimension_range'] = "{0}-{1}".format(gmin, gmax) if qmin == qmax: info['table_field_range'] = "{0}".format(qmin) else: info['table_field_range'] = "{0}-{1}".format(qmin, qmax) for (g,q), cnt in av_stats._counts.items(): if qmin <= q <= qmax and gmin <= g <= gmax: info['table'][q][g] = cnt info['col_heads'] = [q for q in qs if q >= qmin and q <= qmax] info['row_heads'] = [g for g in gs if g >= gmin and g <= gmax] return render_template("abvarfq-index.html", title="Isogeny Classes of Abelian Varieties over Finite Fields", info=info, credit=abvarfq_credit, bread=get_bread(), learnmore=learnmore_list())
def abelian_variety_browse(**args): info = to_dict(args) if not('table_dimension_range' in info) or (info['table_dimension_range']==''): info['table_dimension_range'] = "1-6" if not('table_field_range' in info) or (info['table_field_range']==''): info['table_field_range'] = "2-27" table_params = {} av_stats=AbvarFqStats() # Handle dimension range gs = av_stats.gs try: if ',' in info['table_dimension_range']: flash(Markup("Error: You cannot use commas in the table ranges."), "error") raise ValueError parse_ints(info,table_params,'table_dimension_range',qfield='g') except (ValueError, AttributeError, TypeError): gmin, gmax = 1, 6 else: if isinstance(table_params['g'], int): gmin = gmax = table_params['g'] else: gmin = table_params['g'].get('$gte',min(gs) if gs else table_params['g'].get('$lte',1)) gmax = table_params['g'].get('$lte',max(gs) if gs else table_params['g'].get('$gte',20)) # Handle field range qs = av_stats.qs try: if ',' in info['table_field_range']: flash(Markup("Error: You cannot use commas in the table ranges."), "error") raise ValueError parse_ints(info,table_params,'table_field_range',qfield='q') except (ValueError, AttributeError, TypeError): qmin, qmax = 2, 27 else: if isinstance(table_params['q'], int): qmin = qmax = table_params['q'] else: qmin = table_params['q'].get('$gte',min(qs) if qs else table_params['q'].get('$lte',0)) qmax = table_params['q'].get('$lte',max(qs) if qs else table_params['q'].get('$gte',1000)) info['table'] = defaultdict(lambda: defaultdict(int)) if gmin == gmax: info['table_dimension_range'] = "{0}".format(gmin) else: info['table_dimension_range'] = "{0}-{1}".format(gmin, gmax) if qmin == qmax: info['table_field_range'] = "{0}".format(qmin) else: info['table_field_range'] = "{0}-{1}".format(qmin, qmax) for (g,q), cnt in av_stats._counts.items(): if qmin <= q <= qmax and gmin <= g <= gmax: info['table'][q][g] = cnt info['col_heads'] = [q for q in qs if q >= qmin and q <= qmax] info['row_heads'] = [g for g in gs if g >= gmin and g <= gmax] return render_template("abvarfq-index.html", title="Isogeny Classes of Abelian Varieties over Finite Fields", info=info, credit=abvarfq_credit, bread=get_bread(), learnmore=learnmore_list())
def search(info, query): parse_ints(info, query, 'level', name='Level') parse_ints(info, query, 'weight', name='Weight') parse_character(info, query, 'character', name='Character') parse_floats(info, query, 'spectral_parameter', name='Spectral parameter', allow_singletons=True) if info.get('symmetry'): query['symmetry'] = int(info['symmetry']) query['__sort__'] = ['level', 'weight', 'conrey_index', 'spectral_parameter']
def half_integral_weight_form_search(info, query): parse_ints(info, query, 'weight') parse_ints(info, query, 'level') if info.get('character','').strip(): if re.match('^\d+.\d+$', info['character'].strip()): query['character'] = info['character'].strip() else: flash_error("%s is not a valid Dirichlet character label, it should be of the form q.n", info['character']) raise ValueError
def half_integral_weight_form_search(info, query): parse_ints(info, query, 'weight') parse_ints(info, query, 'level') if info.get('character','').strip(): if re.match(r'^\d+.\d+$', info['character'].strip()): query['character'] = info['character'].strip() else: flash_error("%s is not a valid Dirichlet character label, it should be of the form q.n", info['character']) raise ValueError
def elliptic_curve_search(info, query): parse_rational(info,query,'jinv','j-invariant') parse_ints(info,query,'conductor') parse_ints(info,query,'torsion','torsion order') parse_ints(info,query,'rank') parse_ints(info,query,'sha','analytic order of Ш') parse_ints(info,query,'num_int_pts','num_int_pts') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,check_divisibility='increasing') # speed up slow torsion_structure searches by also setting torsion #if 'torsion_structure' in query and not 'torsion' in query: # query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1) if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne' : 0} parse_element_of(info,query,field='isodeg',qfield='isogeny_degrees',split_interval=1000) #parse_ints(info,query,field='isodeg',qfield='isogeny_degrees') parse_primes(info, query, 'surj_primes', name='maximal primes', qfield='nonmax_primes', mode='complement') if info.get('surj_quantifier') == 'exactly': mode = 'exact' else: mode = 'append' parse_primes(info, query, 'nonsurj_primes', name='non-maximal primes', qfield='nonmax_primes',mode=mode, radical='nonmax_rad') if info.get('bad_quantifier') == 'exactly': mode = 'exact' elif info.get('bad_quantifier') == 'exclude': mode = 'complement' else: mode = 'append' parse_primes(info, query, 'bad_primes', name='bad primes', qfield='bad_primes',mode=mode) # The button which used to be labelled Optimal only no/yes" # (default no) has been renamed "Curves per isogeny class all/one" # (default one) but the only change in behavious is that we no # longer treat class 990h (where the optial curve is #3 not #1) as # special: the "one" option just restricts to curves whose # 'number' is 1. if 'optimal' in info and info['optimal'] == 'on': query.update({'number':1}) # Old behaviour was as follows: # For all isogeny classes except 990h the optimal curve is number 1, while for class 990h it is number 3. # So setting query['number'] = 1 is nearly correct, but fails on 990h3. # Instead, we use this more complicated query: # query.update({"$or":[{'iso':'990h', 'number':3}, {'iso':{'$ne':'990h'},'number':1}]}) info['curve_ainvs'] = lambda dbc: str([ZZ(ai) for ai in dbc['ainvs']]) info['curve_url_LMFDB'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number']) info['iso_url_LMFDB'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1]) info['curve_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['label']) info['iso_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['iso'])
def rep_galois_modl_search(info, query): for field, name in (('dim','Dimension'), ('det','Determinant'), ('level',None), ('minimum','Minimal vector length'), ('class_number',None), ('aut','Group order')): parse_ints(info, query, field, name) # Check if length of gram is triangular gram = info.get('gram') if gram and not (9 + 8*ZZ(gram.count(','))).is_square(): flash(Markup("Error: <span style='color:black'>%s</span> is not a valid input for Gram matrix. It must be a list of integer vectors of triangular length, such as [1,2,3]." % (gram)),"error") raise ValueError parse_list(info, query, 'gram', process=vect_to_sym)
def lattice_search(info, query): for field, name in [('dim','Dimension'),('det','Determinant'),('level',None), ('minimum','Minimal vector length'), ('class_number',None), ('aut','Group order')]: parse_ints(info, query, field, name) # Check if length of gram is triangular gram = info.get('gram') if gram and not (9 + 8*ZZ(gram.count(','))).is_square(): flash_error("%s is not a valid input for Gram matrix. It must be a list of integer vectors of triangular length, such as [1,2,3].", gram) raise ValueError parse_list(info, query, 'gram', process=vect_to_sym)
def belyi_search(info, query): if "group" in query: info["group"] = query["group"] parse_bracketed_posints(info, query, "abc_list", "a, b, c", maxlength=3) if query.get("abc_list"): if len(query["abc_list"]) == 3: a, b, c = sorted(query["abc_list"]) query["a_s"] = a query["b_s"] = b query["c_s"] = c elif len(query["abc_list"]) == 2: a, b = sorted(query["abc_list"]) sub_query = [] sub_query.append({"a_s": a, "b_s": b}) sub_query.append({"b_s": a, "c_s": b}) query["$or"] = sub_query elif len(query["abc_list"]) == 1: a = query["abc_list"][0] query["$or"] = [{"a_s": a}, {"b_s": a}, {"c_s": a}] query.pop("abc_list") # a naive hack if info.get("abc"): for elt in ["a_s", "b_s", "c_s"]: info_hack = {} info_hack[elt] = info["abc"] parse_ints(info_hack, query, elt) parse_ints(info, query, "g", "g") parse_ints(info, query, "deg", "deg") parse_ints(info, query, "orbit_size", "orbit_size") parse_ints(info, query, "pass_size", "pass_size") parse_nf_string(info, query, 'field', name="base number field", qfield='base_field_label') # invariants and drop-list items don't require parsing -- they are all strings (supplied by us, not the user) for fld in ["geomtype", "group"]: if info.get(fld): query[fld] = info[fld] parse_bool(info, query, "is_primitive", name="is_primitive") if info.get("primitivization"): primitivization = info["primitivization"] if re.match(GALMAP_RE, primitivization): # 7T6-7_4.2.1_4.2.1-b query["primitivization"] = primitivization else: raise ValueError("%s is not a valid Belyi map label", primitivization)
def elliptic_curve_search(info, query): parse_nf_string(info,query,'field',name="base number field",qfield='field_label') if query.get('field_label') == '1.1.1.1': return redirect(url_for("ec.rational_elliptic_curves", **request.args), 301) parse_ints(info,query,'conductor_norm') parse_noop(info,query,'conductor_label') parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2) if 'torsion_structure' in query and not 'torsion_order' in query: t_o = 1 for n in query['torsion_structure']: t_o *= int(n) query['torsion_order'] = t_o parse_element_of(info,query,field='isodeg',qfield='isogeny_degrees',split_interval=1000) if 'jinv' in info: if info.get('field','').strip() == '2.2.5.1': info['jinv'] = info['jinv'].replace('phi','a') if info.get('field','').strip() == '2.0.4.1': info['jinv'] = info['jinv'].replace('i','a') parse_nf_elt(info,query,'jinv',name='j-invariant') if query.get('jinv'): query['jinv'] =','.join(query['jinv']) if 'include_isogenous' in info and info['include_isogenous'] == 'off': info['number'] = 1 query['number'] = 1 if 'include_base_change' in info: if info['include_base_change'] == 'off': query['base_change'] = [] if info['include_base_change'] == 'only': query['base_change'] = {'$ne':[]} else: info['include_base_change'] = "on" if 'include_Q_curves' in info: if info['include_Q_curves'] == 'exclude': query['q_curve'] = False elif info['include_Q_curves'] == 'only': query['q_curve'] = True if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne' : 0} info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs
def galois_group_search(info, query): def includes_composite(s): s = s.replace(' ','').replace('..','-') for interval in s.split(','): if '-' in interval[1:]: ix = interval.index('-',1) a,b = int(interval[:ix]), int(interval[ix+1:]) if b == a: if a != 1 and not a.is_prime(): return True if b > a and b > 3: return True else: a = ZZ(interval) if a != 1 and not a.is_prime(): return True parse_ints(info,query,'n','degree') parse_ints(info,query,'t') parse_ints(info,query,'order') parse_ints(info,query,'nilpotency') parse_bracketed_posints(info, query, qfield='gapidfull', split=False, exactlength=2, keepbrackets=True, name='GAP id', field='gapid') for param in ('cyc', 'solv', 'prim'): parse_bool(info, query, param, process=int, blank=['0','Any']) parse_restricted(info,query,'parity',allowed=[1,-1],process=int,blank=['0','Any']) if 'order' in query and 'n' not in query: query['__sort__'] = ['order', 'gapid', 'n', 't'] degree_str = prep_ranges(info.get('n')) info['show_subs'] = degree_str is None or (LIST_RE.match(degree_str) and includes_composite(degree_str)) info['group_display'] = group_display_short info['yesno'] = yesno info['wgg'] = WebGaloisGroup.from_data
def elliptic_curve_search(info, query): parse_rational(info,query,'jinv','j-invariant') parse_ints(info,query,'conductor') parse_ints(info,query,'torsion','torsion order') parse_ints(info,query,'rank') parse_ints(info,query,'sha','analytic order of Ш') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,check_divisibility='increasing') # speed up slow torsion_structure searches by also setting torsion #if 'torsion_structure' in query and not 'torsion' in query: # query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1) if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne' : 0} parse_element_of(info,query,field='isodeg',qfield='isogeny_degrees',split_interval=1000) #parse_ints(info,query,field='isodeg',qfield='isogeny_degrees') parse_primes(info, query, 'surj_primes', name='maximal primes', qfield='nonmax_primes', mode='complement') if info.get('surj_quantifier') == 'exactly': mode = 'exact' else: mode = 'append' parse_primes(info, query, 'nonsurj_primes', name='non-maximal primes', qfield='nonmax_primes',mode=mode, radical='nonmax_rad') if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 info['curve_url'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number']) info['iso_url'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1])
def elliptic_curve_search(info, query): parse_rational(info,query,'jinv','j-invariant') parse_ints(info,query,'conductor') parse_ints(info,query,'torsion','torsion order') parse_ints(info,query,'rank') parse_ints(info,query,'sha','analytic order of Ш') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,check_divisibility='increasing') # speed up slow torsion_structure searches by also setting torsion #if 'torsion_structure' in query and not 'torsion' in query: # query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1) if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne' : 0} parse_element_of(info,query,field='isodeg',qfield='isogeny_degrees',split_interval=1000) #parse_ints(info,query,field='isodeg',qfield='isogeny_degrees') parse_primes(info, query, 'surj_primes', name='maximal primes', qfield='nonmax_primes', mode='complement') if info.get('surj_quantifier') == 'exactly': mode = 'exact' else: mode = 'append' parse_primes(info, query, 'nonsurj_primes', name='non-maximal primes', qfield='nonmax_primes',mode=mode, radical='nonmax_rad') if 'optimal' in info and info['optimal'] == 'on': # For all isogeny classes except 990h the optimal curve is number 1, while for class 990h it is number 3. # So setting query['number'] = 1 is nearly correct, but fails on 990h3. # Instead, we use this more complicated query: query.update({"$or":[{'iso':'990h', 'number':3}, {'iso':{'$ne':'990h'},'number':1}]}) info['curve_url_LMFDB'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number']) info['iso_url_LMFDB'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1]) info['curve_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['label']) info['iso_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['iso'])
def artin_representation_search(info, query): query['Hide'] = 0 info['sign_code'] = 0 parse_primes(info,query,"unramified",name="Unramified primes", qfield="BadPrimes",mode="complement") parse_primes(info,query,"ramified",name="Ramified primes", qfield="BadPrimes",mode="append") parse_element_of(info,query,"root_number",qfield="GalConjSigns") parse_restricted(info,query,"frobenius_schur_indicator",qfield="Indicator", allowed=[1,0,-1],process=int) parse_container(info,query, 'container',qfield='Container', name="Smallest permutation representation") parse_galgrp(info,query,"group",name="Group",qfield=("Galn","Galt")) parse_ints(info,query,'dimension',qfield='Dim') parse_ints(info,query,'conductor',qfield='Conductor')
def hilbert_modular_form_search(info, query): parse_nf_string(info, query, 'field_label', name="Field") parse_ints(info, query, 'deg', name='Field degree') parse_ints(info, query, 'disc', name="Field discriminant") parse_ints(info, query, 'dimension') parse_ints(info, query, 'level_norm', name="Level norm") parse_hmf_weight(info, query, 'weight', qfield=('parallel_weight', 'weight')) parse_primes(info, query, 'field_bad_primes', name='field bad primes', qfield='field_bad_primes', mode=info.get('field_bad_quantifier')) parse_primes(info, query, 'level_bad_primes', name='level bad primes', qfield='level_bad_primes', mode=info.get('level_bad_quantifier')) if 'cm' in info: if info['cm'] == 'exclude': query['is_CM'] = 'no' elif info['cm'] == 'only': query['is_CM'] = 'yes' if 'bc' in info: if info['bc'] == 'exclude': query['is_base_change'] = 'no' elif info['bc'] == 'only': query['is_base_change'] = 'yes'
def belyi_search(info, query): info["geometry_types_list"] = geometry_types_list info["geometry_types_dict"] = geometry_types_dict info["belyi_galmap_url"] = url_for_belyi_galmap_label if "group" in query: info["group"] = query["group"] parse_bracketed_posints(info, query, "abc_list", "a, b, c", maxlength=3) if query.get("abc_list"): if len(query["abc_list"]) == 3: a, b, c = sorted(query["abc_list"]) query["a_s"] = a query["b_s"] = b query["c_s"] = c elif len(query["abc_list"]) == 2: a, b = sorted(query["abc_list"]) sub_query = [] sub_query.append({"a_s": a, "b_s": b}) sub_query.append({"b_s": a, "c_s": b}) query["$or"] = sub_query elif len(query["abc_list"]) == 1: a = query["abc_list"][0] query["$or"] = [{"a_s": a}, {"b_s": a}, {"c_s": a}] query.pop("abc_list") # a naive hack if info.get("abc"): for elt in ["a_s", "b_s", "c_s"]: info_hack = {} info_hack[elt] = info["abc"] parse_ints(info_hack, query, elt) parse_ints(info, query, "g", "g") parse_ints(info, query, "deg", "deg") parse_ints(info, query, "orbit_size", "orbit_size") parse_ints(info, query, "pass_size", "pass_size") parse_nf_string(info, query, 'field', name="base number field", qfield='base_field_label') # invariants and drop-list items don't require parsing -- they are all strings (supplied by us, not the user) for fld in ["geomtype", "group"]: if info.get(fld): query[fld] = info[fld] info["nf_link"] = lambda elt: field_display_gen( elt.get('base_field_label'), elt.get('base_field'), truncate=16) parse_bool(info, query, "is_primitive", name="is_primitive")
def higher_genus_w_automorphisms_search(info, query): if info.get('signature'): # allow for ; in signature info['signature'] = info['signature'].replace(';',',') parse_bracketed_posints(info,query,'signature',split=False,name='Signature',keepbrackets=True) if query.get('signature'): query['signature'] = info['signature'] = str(sort_sign(ast.literal_eval(query['signature']))).replace(' ','') parse_gap_id(info,query,'group',qfield='group') parse_ints(info,query,'g0') parse_ints(info,query,'genus') parse_ints(info,query,'dim') parse_ints(info,query,'group_order') if 'inc_hyper' in info: if info['inc_hyper'] == 'exclude': query['hyperelliptic'] = False elif info['inc_hyper'] == 'only': query['hyperelliptic'] = True if 'inc_cyc_trig' in info: if info['inc_cyc_trig'] == 'exclude': query['cyclic_trigonal'] = False elif info['inc_cyc_trig'] == 'only': query['cyclic_trigonal'] = True if 'inc_full' in info: if info['inc_full'] == 'exclude': query['full_auto'] = {'$exists': True} elif info['inc_full'] == 'only': query['full_auto'] = {'$exists': False} query['cc.1'] = 1 info['group_display'] = group_display info['sign_display'] = sign_display if 'sort_order' in info: if info['sort_order'] == '': query['__sort__'] = ['genus', 'group_order', 'g0','dim'] elif info['sort_order'] == 'genus': query['__sort__'] = ['genus', 'group_order', 'g0', 'dim'] elif info['sort_order'] == 'descgenus': query['__sort__'] = [('genus',-1), 'group_order', 'g0', 'dim'] elif info['sort_order'] == 'g0': query['__sort__'] = ['g0', 'genus', 'group_order', 'dim'] elif info['sort_order'] == 'descg0': query['__sort__'] = [('g0',-1), 'genus', 'group_order', 'dim'] elif info.get('sort_order') == 'dim': query['__sort__'] = ['dim', 'genus', 'group_order', 'g0'] elif info.get('sort_order') == 'descdim': query['__sort__'] = [('dim',-1), 'genus', 'group_order', 'g0'] elif info.get('sort_order') == 'group_order': query['__sort__'] = ['group_order', 'genus', 'g0', 'dim'] elif info.get('sort_order') == 'descgroup_order': query['__sort__'] = [('group_order',-1), 'genus', 'g0', 'dim'] else: query['__sort__'] = ['genus', 'group_order', 'g0', 'dim']
def hecke_algebras_search(info, query): for field, name in (('level', 'Level'), ('weight', 'Weight'), ('num_orbits', 'Number of Hecke orbits'), ('ell', 'characteristic')): parse_ints(info, query, field, name) if info.get('ell'): if int(info.get('ell')) > 13: flash_error( "No data for primes or integers greater than $13$ is available" ) return redirect(url_for(".hecke_algebras_render_webpage")) elif int(info.get('ell')) not in [2, 3, 5, 7, 11, 13]: flash_error("No data for integers which are not primes") return redirect(url_for(".hecke_algebras_render_webpage")) if info.get('orbit_label'): check = [int(i) for i in info['orbit_label'].split(".")] if 'level' in info and info.get('level'): try: for field in ['level', 'weight']: if info.get(field): int(info.get(field)) except ValueError: flash_error( "Orbit label %s and input Level or Weight are not compatible", info.get('orbit_label')) return redirect(url_for(".hecke_algebras_render_webpage")) if int(info.get('level')) != check[0]: flash_error( "Orbit label %s and Level %s are not compatible inputs", info.get('orbit_label'), info.get('level')) return redirect(url_for(".hecke_algebras_render_webpage")) if 'weight' in info and info.get('weight'): if int(info.get('weight')) != check[1]: flash_error( "Orbit label %s and Weight %s are not compatible inputs", info.get('orbit_label'), info.get('weight')) return redirect(url_for(".hecke_algebras_render_webpage")) if 'ell' in info and info.get('ell'): return render_hecke_algebras_webpage_l_adic( orbit_label=info.get('orbit_label'), prime=info.get('ell')) else: return hecke_algebras_by_orbit_label(info.get('orbit_label')) # If 'ell' is included, we use a different table if info.get('ell'): query['__table__'] = db.hecke_ladic query['__projection__'] = ['orbit_label', 'index', 'level', 'weight']
def local_field_search(info,query): parse_galgrp(info,query,'gal',qfield=('n','galT')) parse_ints(info,query,'p',name='Prime p') parse_ints(info,query,'n',name='Degree') parse_ints(info,query,'c',name='Discriminant exponent c') parse_ints(info,query,'e',name='Ramification index e') parse_rats(info,query,'topslope',qfield='top_slope',name='Top slope', process=ratproc) info['group_display'] = group_pretty_and_nTj info['display_poly'] = format_coeffs info['slopedisp'] = show_slope_content
def local_field_search(info,query): parse_ints(info,query,'p',name='Prime p') parse_ints(info,query,'n',name='Degree') parse_galgrp(info,query,'gal',qfield=('galois_label','n')) parse_ints(info,query,'c',name='Discriminant exponent c') parse_ints(info,query,'e',name='Ramification index e') parse_rats(info,query,'topslope',qfield='top_slope',name='Top slope', process=ratproc) info['group_display'] = group_pretty_and_nTj info['display_poly'] = format_coeffs info['slopedisp'] = show_slope_content info['search_array'] = LFSearchArray()
def artin_representation_search(info, query): query['Hide'] = 0 info['sign_code'] = 0 parse_primes(info, query, "unramified", name="Unramified primes", qfield="BadPrimes", mode="exclude") parse_primes(info, query, "ramified", name="Ramified primes", qfield="BadPrimes", mode=info.get("ram_quantifier")) parse_element_of(info, query, "root_number", qfield="GalConjSigns") parse_restricted(info, query, "frobenius_schur_indicator", qfield="Indicator", allowed=[1, 0, -1], process=int) parse_container(info, query, 'container', qfield='Container', name="Smallest permutation representation") parse_galgrp(info, query, "group", name="Group", qfield=("GaloisLabel", None)) parse_ints(info, query, 'dimension', qfield='Dim') parse_ints(info, query, 'conductor', qfield='Conductor') parse_projective_group(info, query, 'projective_image', qfield='Proj_GAP') parse_projective_type(info, query, 'projective_image_type', qfield='Proj_GAP') # Backward support for old URLs if 'Is_Even' in info: info['parity'] = info.pop('Is_Even') parse_bool(info, query, 'parity', qfield='Is_Even')
def bianchi_modular_form_search(info, query): """Function to handle requests from the top page, either jump to one newform or do a search. """ parse_nf_string(info, query, 'field_label', name='base number field') parse_noop(info, query, 'label') parse_ints(info, query, 'dimension') parse_ints(info, query, 'level_norm') if not 'sfe' in info: info['sfe'] = "any" elif info['sfe'] != "any": query['sfe'] = int(info['sfe']) if 'include_cm' in info: if info['include_cm'] == 'exclude': query['CM'] = 0 # will exclude NULL values elif info['include_cm'] == 'only': query['CM'] = {'$ne': 0} # will exclude NULL values if 'include_base_change' in info and info['include_base_change'] == 'off': query['bc'] = 0 else: info['include_base_change'] = "on"
def number_field_search(info, query): parse_ints(info,query,'degree') parse_galgrp(info,query, qfield=('degree', 'galt')) parse_bracketed_posints(info,query,'signature',qfield=('degree','r2'),exactlength=2,extractor=lambda L: (L[0]+2*L[1],L[1])) parse_signed_ints(info,query,'discriminant',qfield=('disc_sign','disc_abs')) parse_floats(info, query, 'rd') parse_floats(info, query, 'regulator') parse_ints(info,query,'class_number') parse_ints(info,query,'num_ram') parse_bool(info,query,'cm_field',qfield='cm') parse_bracketed_posints(info,query,'class_group',check_divisibility='increasing',process=int) parse_primes(info,query,'ur_primes',name='Unramified primes', qfield='ramps',mode='complement') # modes are now contained (in), exactly, include if 'ram_quantifier' in info and str(info['ram_quantifier']) == 'include': mode='append' elif 'ram_quantifier' in info and str(info['ram_quantifier']) == 'contained': mode='subsets' else: mode='exact' parse_primes(info,query,'ram_primes',name='Ramified primes', qfield='ramps',mode=mode,radical='disc_rad') ## This seems not to be used #if 'lucky' in info: # label = db.nf_fields.lucky(query, 0) # if label: # return redirect(url_for(".by_label", label=clean_input(label))) info['wnf'] = WebNumberField.from_data info['gg_display'] = group_pretty_and_nTj
def galois_group_search(info, query): def includes_composite(s): s = s.replace(' ','').replace('..','-') for interval in s.split(','): if '-' in interval[1:]: ix = interval.index('-',1) a,b = int(interval[:ix]), int(interval[ix+1:]) if b == a: if a != 1 and not a.is_prime(): return True if b > a and b > 3: return True else: a = ZZ(interval) if a != 1 and not a.is_prime(): return True parse_ints(info,query,'n','degree') parse_ints(info,query,'t') parse_ints(info,query,'order') parse_bracketed_posints(info, query, qfield='gapidfull', split=False, exactlength=2, keepbrackets=True, name='GAP id', field='gapid') for param in ('cyc', 'solv', 'prim'): parse_bool(info, query, param, process=int, blank=['0','Any']) parse_restricted(info,query,'parity',allowed=[1,-1],process=int,blank=['0','Any']) if 'order' in query and 'n' not in query: query['__sort__'] = ['order', 'gapid', 'n', 't'] degree_str = prep_ranges(info.get('n')) info['show_subs'] = degree_str is None or (LIST_RE.match(degree_str) and includes_composite(degree_str)) info['group_display'] = group_display_pretty info['yesno'] = yesno info['wgg'] = WebGaloisGroup.from_data
def hecke_algebras_search(info, query): for field, name in (('level','Level'), ('weight','Weight'), ('num_orbits', 'Number of Hecke orbits'), ('ell','characteristic')): parse_ints(info, query, field, name) if info.get('ell'): if int(info.get('ell'))>13: flash(Markup("No data for primes or integers greater than $13$ is available"), "error") return redirect(url_for(".hecke_algebras_render_webpage")) elif int(info.get('ell')) not in [2,3,5,7,11,13]: flash(Markup("No data for integers which are not primes"), "error") return redirect(url_for(".hecke_algebras_render_webpage")) if info.get('orbit_label'): check=[int(i) for i in info['orbit_label'].split(".")] if 'level' in info and info.get('level'): try: for field in ['level','weight']: if info.get(field): int(info.get(field)) except ValueError: flash(Markup("Orbit label <span style='color:black'>%s</span> and input Level or Weight are not compatible" %(info.get('orbit_label'))),"error") return redirect(url_for(".hecke_algebras_render_webpage")) if int(info.get('level'))!=check[0]: flash(Markup("Orbit label <span style='color:black'>%s</span> and Level <span style='color:black'>%s</span> are not compatible inputs" %(info.get('orbit_label'), info.get('level'))),"error") return redirect(url_for(".hecke_algebras_render_webpage")) if 'weight' in info and info.get('weight'): if int(info.get('weight'))!=check[1]: flash(Markup("Orbit label <span style='color:black'>%s</span> and Weight <span style='color:black'>%s</span> are not compatible inputs" %(info.get('orbit_label'), info.get('weight'))), "error") return redirect(url_for(".hecke_algebras_render_webpage")) if 'ell' in info and info.get('ell'): return render_hecke_algebras_webpage_l_adic(orbit_label=info.get('orbit_label'), prime=info.get('ell')) else: return hecke_algebras_by_orbit_label(info.get('orbit_label')) # If 'ell' is included, we use a different table if info.get('ell'): query['__table__'] = db.hecke_ladic query['__projection__'] = ['orbit_label','index','level','weight']
def elliptic_curve_search(info, query): parse_nf_string(info,query,'field',name="base number field",qfield='field_label') if query.get('field_label') == '1.1.1.1': return redirect(url_for("ec.rational_elliptic_curves", **request.args), 301) parse_ints(info,query,'conductor_norm') parse_noop(info,query,'conductor_label') parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2) if 'torsion_structure' in query and not 'torsion_order' in query: t_o = 1 for n in query['torsion_structure']: t_o *= int(n) query['torsion_order'] = t_o parse_element_of(info,query,field='isodeg',qfield='isogeny_degrees',split_interval=1000) if 'jinv' in info: if info.get('field','').strip() == '2.2.5.1': info['jinv'] = info['jinv'].replace('phi','a') if info.get('field','').strip() == '2.0.4.1': info['jinv'] = info['jinv'].replace('i','a') if not 'a' in info['jinv'] and not info.get('field'): # rational j-invariant allowed for any field parse_rational(info, query, 'jinv', name='j-invariant') if query.get('jinv'): query['jinv'] = {'$regex': '^' + query['jinv'] + '(,0)*$'} # nf elements like j,0,0,0 else: # j-invariant is a number field element parse_nf_elt(info, query, 'jinv', name='j-invariant') if query.get('jinv'): query['jinv'] = ','.join(query['jinv']) if info.get('one') == "yes": info['number'] = 1 query['number'] = 1 if 'include_base_change' in info: if info['include_base_change'] in ['exclude', 'off']: # off for backward compat with urls query['base_change'] = [] if info['include_base_change'] == 'only': query['base_change'] = {'$ne':[]} else: info['include_base_change'] = "on" if 'include_Q_curves' in info: if info['include_Q_curves'] == 'exclude': query['q_curve'] = False elif info['include_Q_curves'] == 'only': query['q_curve'] = True if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne' : 0} parse_ints(info,query,field='cm_disc',qfield='cm') info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs
def hilbert_modular_form_search(info, query): parse_nf_string(info,query,'field_label',name="Field") parse_ints(info,query,'deg', name='Field degree') parse_ints(info,query,'disc',name="Field discriminant") parse_ints(info,query,'dimension') parse_ints(info,query,'level_norm', name="Level norm") parse_hmf_weight(info,query,'weight',qfield=('parallel_weight','weight')) if 'cm' in info: if info['cm'] == 'exclude': query['is_CM'] = 'no' elif info['cm'] == 'only': query['is_CM'] = 'yes' if 'bc' in info: if info['bc'] == 'exclude': query['is_base_change'] = 'no' elif info['bc'] == 'only': query['is_base_change'] = 'yes'
def hgm_search(info, query): info["search_type"] = search_type = info.get("search_type", info.get("hst", "Motive")) if search_type in ["Family", "RandomFamily"]: query['__title__'] = r'Hypergeometric Family over $\Q$ Search Result' query['__err_title__'] = r'Hypergeometric Family over $\Q$ Search Input Error' query['__table__'] = db.hgm_families queryab = {} p = info.get('p', '2') for param in ['A', 'B']: parse_bracketed_posints(info, queryab, param, split=True, keepbrackets=True, listprocess=lambda a: sorted(a, reverse=True)) parse_bracketed_posints(info, queryab, 'Ap', qfield='A'+p, split=True, keepbrackets=True, listprocess=lambda a: sorted(a, reverse=True)) parse_bracketed_posints(info, queryab, 'Bp', qfield='B'+p, split=True, keepbrackets=True, listprocess=lambda a: sorted(a, reverse=True)) parse_bracketed_posints(info, queryab, 'Apperp', qfield='Au'+p, split=True, keepbrackets=True, listprocess=lambda a: sorted(a, reverse=True)) parse_bracketed_posints(info, queryab, 'Bpperp', qfield='Bu'+p, split=True, keepbrackets=True, listprocess=lambda a: sorted(a, reverse=True)) # Combine the parts of the query if there are A,B parts if queryab: queryabrev = {} for k in queryab.keys(): queryabrev[k+'rev'] = queryab[k] query['$or'] = [queryab, queryabrev] # generic, irreducible not in DB yet parse_ints(info, query, 'degree') parse_ints(info, query, 'weight') parse_bracketed_posints(info, query, 'famhodge', 'family Hodge vector',split=True) parse_restricted(info, query, 'sign', allowed=['+1',1,-1], process=int) # Make a version to search reversed way if search_type not in ["Family", "RandomFamily"]: parse_ints(info, query, 'conductor', 'Conductor' , 'cond') parse_rational(info, query, 't') parse_bracketed_posints(info, query, 'hodge', 'Hodge vector') query['__sort__'] = ['degree', 'weight', 'A', 'B', 'label'] # Should search on analytic conductor when available # Sorts A and B first by length, then by the elements of the list; could go another way info['make_label'] = make_abt_label info['make_t_label'] = make_t_label info['ab_label'] = ab_label info['display_t'] = display_t info['factorint'] = factorint
def common_parse(info, query): parse_ints(info, query, "modulus", name="modulus") parse_ints(info, query, "conductor", name="conductor") parse_ints(info, query, "order", name="order") if 'parity' in info: parity = info['parity'] if parity == 'even': query['parity'] = 1 elif parity == 'odd': query['parity'] = -1 parse_bool(info, query, "is_primitive", name="is_primitive") parse_bool(info, query, "is_real", name="is_real") parse_bool(info, query, "is_minimal", name="is_minimal")
def number_field_search(info, query): parse_ints(info, query, 'degree') parse_galgrp(info, query, qfield=('galois_label', 'degree')) parse_bracketed_posints(info, query, 'signature', qfield=('degree', 'r2'), exactlength=2, allow0=True, extractor=lambda L: (L[0] + 2 * L[1], L[1])) parse_signed_ints(info, query, 'discriminant', qfield=('disc_sign', 'disc_abs')) parse_floats(info, query, 'rd') parse_floats(info, query, 'regulator') parse_ints(info, query, 'class_number') parse_ints(info, query, 'num_ram') parse_bool(info, query, 'cm_field', qfield='cm') parse_bool(info, query, 'is_galois') parse_bracketed_posints(info, query, 'class_group', check_divisibility='increasing', process=int) parse_primes(info, query, 'ur_primes', name='Unramified primes', qfield='ramps', mode='exclude') parse_primes(info, query, 'ram_primes', name='Ramified primes', qfield='ramps', mode=info.get('ram_quantifier'), radical='disc_rad') parse_subfield(info, query, 'subfield', qfield='subfields', name='Intermediate field') parse_padicfields(info, query, 'completions', qfield='local_algs', name='$p$-adic completions') info['wnf'] = WebNumberField.from_data info['gg_display'] = group_pretty_and_nTj
def belyi_search(info, query): info["geometry_types_list"] = geometry_types_list info["geometry_types_dict"] = geometry_types_dict info["belyi_galmap_url"] = lambda label: url_for_belyi_galmap_label(label) if "group" in query: info["group"] = query["group"] parse_bracketed_posints(info, query, "abc_list", "a, b, c", maxlength=3) if query.get("abc_list"): if len(query["abc_list"]) == 3: a, b, c = sorted(query["abc_list"]) query["a_s"] = a query["b_s"] = b query["c_s"] = c elif len(query["abc_list"]) == 2: a, b = sorted(query["abc_list"]) sub_query = [] sub_query.append({"a_s": a, "b_s": b}) sub_query.append({"b_s": a, "c_s": b}) query["$or"] = sub_query elif len(query["abc_list"]) == 1: a = query["abc_list"][0] query["$or"] = [{"a_s": a}, {"b_s": a}, {"c_s": a}] query.pop("abc_list") # a naive hack if info.get("abc"): for elt in ["a_s", "b_s", "c_s"]: info_hack = {} info_hack[elt] = info["abc"] parse_ints(info_hack, query, elt) parse_ints(info, query, "g", "g") parse_ints(info, query, "deg", "deg") parse_ints(info, query, "orbit_size", "orbit_size") # invariants and drop-list items don't require parsing -- they are all strings (supplied by us, not the user) for fld in ["geomtype", "group"]: if info.get(fld): query[fld] = info[fld]
def elliptic_curve_search(info, query): parse_nf_string(info,query,'field',name="base number field",qfield='field_label') if query.get('field_label') == '1.1.1.1': return redirect(url_for("ec.rational_elliptic_curves", **request.args), 301) parse_ints(info,query,'conductor_norm') parse_noop(info,query,'conductor_label') parse_ints(info,query,'torsion',name='Torsion order',qfield='torsion_order') parse_bracketed_posints(info,query,'torsion_structure',maxlength=2) if 'torsion_structure' in query and not 'torsion_order' in query: query['torsion_order'] = reduce(mul,[int(n) for n in query['torsion_structure']],1) parse_ints(info,query,field='isodeg',qfield='isogeny_degrees') if 'jinv' in info: if info.get('field','').strip() == '2.2.5.1': info['jinv'] = info['jinv'].replace('phi','a') if info.get('field','').strip() == '2.0.4.1': info['jinv'] = info['jinv'].replace('i','a') parse_nf_elt(info,query,'jinv',name='j-invariant') if query.get('jinv'): query['jinv'] =','.join(query['jinv']) if 'include_isogenous' in info and info['include_isogenous'] == 'off': info['number'] = 1 query['number'] = 1 if 'include_base_change' in info: if info['include_base_change'] == 'off': query['base_change'] = [] if info['include_base_change'] == 'only': query['base_change'] = {'$ne':[]} else: info['include_base_change'] = "on" if 'include_Q_curves' in info: if info['include_Q_curves'] == 'exclude': query['q_curve'] = False elif info['include_Q_curves'] == 'only': query['q_curve'] = True if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne' : 0} info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs
def belyi_search(info, query): info['geometry_types_list'] = geometry_types_list info['geometry_types_dict'] = geometry_types_dict info["belyi_galmap_url"] = lambda label: url_for_belyi_galmap_label(label) if 'group' in query: info['group'] = query['group'] parse_bracketed_posints(info, query, 'abc_list', 'a, b, c', maxlength=3) if query.get('abc_list'): if len(query['abc_list']) == 3: a, b, c = sorted(query['abc_list']) query['a_s'] = a query['b_s'] = b query['c_s'] = c elif len(query['abc_list']) == 2: a, b = sorted(query['abc_list']) sub_query = [] sub_query.append({'a_s': a, 'b_s': b}) sub_query.append({'b_s': a, 'c_s': b}) query['$or'] = sub_query elif len(query['abc_list']) == 1: a = query['abc_list'][0] query['$or'] = [{'a_s': a}, {'b_s': a}, {'c_s': a}] query.pop('abc_list') # a naive hack if info.get('abc'): for elt in ['a_s', 'b_s', 'c_s']: info_hack = {} info_hack[elt] = info['abc'] parse_ints(info_hack, query, elt) parse_ints(info, query, 'g', 'g') parse_ints(info, query, 'deg', 'deg') parse_ints(info, query, 'orbit_size', 'orbit_size') # invariants and drop-list items don't require parsing -- they are all strings (supplied by us, not the user) for fld in ['geomtype', 'group']: if info.get(fld): query[fld] = info[fld]
def belyi_search(info, query): info['geometry_types_list'] = geometry_types_list info['geometry_types_dict'] = geometry_types_dict info["belyi_galmap_url"] = lambda label: url_for_belyi_galmap_label(label) if 'group' in query: info['group'] = query['group'] parse_bracketed_posints(info, query, 'abc_list', 'a, b, c', maxlength=3) if query.get('abc_list'): if len(query['abc_list']) == 3: a, b, c = sorted(query['abc_list']) query['a_s'] = a query['b_s'] = b query['c_s'] = c elif len(query['abc_list']) == 2: a, b = sorted(query['abc_list']) sub_query = [] sub_query.append( {'a_s': a, 'b_s': b} ) sub_query.append( {'b_s': a, 'c_s': b} ) query['$or'] = sub_query elif len(query['abc_list']) == 1: a = query['abc_list'][0] query['$or'] = [{'a_s': a}, {'b_s': a}, {'c_s': a}] query.pop('abc_list') # a naive hack if info.get('abc'): for elt in ['a_s', 'b_s', 'c_s']: info_hack = {} info_hack[elt] = info['abc'] parse_ints(info_hack, query, elt) parse_ints(info, query, 'g','g') parse_ints(info, query, 'deg', 'deg') parse_ints(info, query, 'orbit_size', 'orbit_size') # invariants and drop-list items don't require parsing -- they are all strings (supplied by us, not the user) for fld in ['geomtype','group']: if info.get(fld): query[fld] = info[fld]
def hgm_search(info, query): family_search = False if info.get('Submit Family') or info.get('family'): family_search = True query['__title__'] = r'Hypergeometric Family over $\Q$ Search Result' query[ '__err_title__'] = r'Hypergeometric Family over $\Q$ Search Input Error' query['__table__'] = db.hgm_families queryab = {} for param in [ 'A', 'B', 'A2', 'B2', 'A3', 'B3', 'A5', 'B5', 'A7', 'B7', 'Au2', 'Bu2', 'Au3', 'Bu3', 'Au5', 'Bu5', 'Au7', 'Bu7' ]: parse_bracketed_posints(info, queryab, param, split=False, listprocess=lambda a: sorted(a, reverse=True)) # Combine the parts of the query if there are A,B parts if queryab: queryabrev = {} for k in queryab.keys(): queryabrev[k + 'rev'] = queryab[k] query['$or'] = [queryab, queryabrev] # generic, irreducible not in DB yet parse_ints(info, query, 'degree') parse_ints(info, query, 'weight') parse_bracketed_posints(info, query, 'famhodge', 'family Hodge vector', split=False) parse_restricted(info, query, 'sign', allowed=['+1', 1, -1], process=int) # Make a version to search reversed way if not family_search: parse_ints(info, query, 'conductor', 'Conductor', 'cond') parse_rational(info, query, 't') parse_bracketed_posints(info, query, 'hodge', 'Hodge vector') info['make_label'] = make_abt_label info['make_t_label'] = make_t_label info['ab_label'] = ab_label info['display_t'] = display_t info['family'] = family_search info['factorint'] = factorint
def render_search_results_page(args, bread): if args.get("table"): return render_dimension_table_page(args, bread) if args.get("lookup"): return redirect(url_for('.by_label',label=args['label'])) info = { 'args': to_dict(args) } query = {} try: parse_ints (info['args'], query, 'deg', 'degree', qfield="degree") parse_ints (info['args'], query, 'wt', '$k$', qfield="weight") parse_ints (info['args'], query, 'fdeg', 'field degree') except ValueError: info['error'] = True if not info.get('error'): info['results'] = sample.Samples(query) bread.append(('Search results', '')) return render_template( "ModularForm_GSp4_Q_search_results.html", title='Siegel modular forms search results', bread=bread, info=info)
def render_search_results_page(args, bread): if args.get("table"): return render_dimension_table_page(args, bread) if args.get("lookup"): return redirect(url_for('.by_label',label=args['label'])) info = { 'args': to_dict(args) } query = {} try: parse_ints (info['args'], query, 'deg', 'degree') parse_ints (info['args'], query, 'wt', '$k$') parse_ints (info['args'], query, 'fdeg', 'field degree') except ValueError: info['error'] = True if not info.get('error'): info['results'] = sample.Samples(query) bread.append(('Search Results', '')) return render_template( "ModularForm_GSp4_Q_search_results.html", title='Siegel Modular Forms Search Results', bread=bread, info=info)
def hgm_search(info, query): family_search = False if info.get('Submit Family') or info.get('family'): family_search = True query['__title__'] = r'Hypergeometric Family over $\Q$ Search Result' query['__err_title__'] = r'Hypergeometric Family over $\Q$ Search Input Error' query['__table__'] = db.hgm_families queryab = {} for param in ['A', 'B', 'A2', 'B2', 'A3', 'B3', 'A5', 'B5', 'A7', 'B7', 'Au2', 'Bu2', 'Au3', 'Bu3', 'Au5', 'Bu5', 'Au7', 'Bu7']: parse_bracketed_posints(info, queryab, param, split=False, listprocess=lambda a: sorted(a, reverse=True)) # Combine the parts of the query if there are A,B parts if queryab: queryabrev = {} for k in queryab.keys(): queryabrev[k+'rev'] = queryab[k] query['$or'] = [queryab, queryabrev] # generic, irreducible not in DB yet parse_ints(info, query, 'degree') parse_ints(info, query, 'weight') parse_bracketed_posints(info, query, 'famhodge', 'family Hodge vector',split=False) parse_restricted(info, query, 'sign', allowed=['+1',1,-1], process=int) # Make a version to search reversed way if not family_search: parse_ints(info, query, 'conductor', 'Conductor' , 'cond') parse_rational(info, query, 't') parse_bracketed_posints(info, query, 'hodge', 'Hodge vector') info['make_label'] = make_abt_label info['make_t_label'] = make_t_label info['ab_label'] = ab_label info['display_t'] = display_t info['family'] = family_search info['factorint'] = factorint
def galois_group_search(info, query): def includes_composite(s): s = s.replace(' ', '').replace('..', '-') for interval in s.split(','): if '-' in interval[1:]: ix = interval.index('-', 1) a, b = int(interval[:ix]), int(interval[ix + 1:]) if b == a: if a != 1 and not a.is_prime(): return True if b > a and b > 3: return True else: a = ZZ(interval) if a != 1 and not a.is_prime(): return True if info.get('jump', '').strip(): jump_list = [ "1T1", "2T1", "3T1", "4T1", "4T2", "5T1", "6T1", "7T1", "8T1", "8T2", "8T3", "8T5", "9T1", "9T2", "10T1", "11T1", "12T1", "12T2", "12T5", "13T1", "14T1", "15T1", "16T1", "16T2", "16T3", "16T4", "16T5", "16T7", "16T8", "16T14", "17T1", "18T1", "18T2", "19T1", "20T1", "20T2", "20T3", "21T1", "22T1", "23T1", "24T1", "24T2", "24T3", "24T4", "24T5", "24T6", "24T8", "25T1", "25T2", "26T1", "27T1", "27T2", "27T4", "28T1", "28T2", "28T3", "29T1", "30T1", "31T1", "32T32", "32T33", "32T34", "32T35", "32T36", "32T37", "32T38", "32T39", "32T40", "32T41", "32T42", "32T43", "32T44", "32T45", "32T46", "32T47", "32T48", "32T49", "32T50", "32T51", "33T1", "34T1", "35T1", "36T1", "36T2", "36T3", "36T4", "36T7", "36T9", "37T1", "38T1", "39T1", "40T1", "40T2", "40T3", "40T4", "40T5", "40T7", "40T8", "40T13", "41T1", "42T1", "43T1", "44T1", "44T2", "44T3", "45T1", "45T2", "46T1", "47T1" ] strip_label = info.get('jump', '').strip().upper() # If the user entered a simple label if re.match(r'^\d+T\d+$', strip_label): return redirect(url_for('.by_label', label=strip_label), 301) try: parse_galgrp( info, query, qfield=['label', 'n'], name='a Galois group label', field='jump', list_ok=False, err_msg= "It needs to be a transitive group in nTj notation, such as 5T1, a GAP id, such as [4,1], or a <a title = 'Galois group labels' knowl='nf.galois_group.name'>group label</a>" ) except ValueError: return redirect(url_for('.index')) if query.get('label', '') in jump_list: return redirect(url_for('.by_label', label=query['label']), 301) else: # convert this to a regular search info['gal'] = info['jump'] parse_ints(info, query, 'n', 'degree') parse_ints(info, query, 't') parse_ints(info, query, 'order') parse_ints(info, query, 'arith_equiv') parse_ints(info, query, 'nilpotency') parse_galgrp(info, query, qfield=['label', 'n'], name='Galois group', field='gal') for param in ('cyc', 'solv', 'prim'): parse_bool(info, query, param, process=int, blank=['0', 'Any']) if info.get("parity") == "even": query["parity"] = 1 elif info.get("parity") == "odd": query["parity"] = -1 #parse_restricted(info,query,'parity',allowed=[1,-1],process=int,blank=['0','Any']) if 'order' in query and 'n' not in query: query['__sort__'] = ['order', 'gapid', 'n', 't'] degree_str = prep_ranges(info.get('n')) info['show_subs'] = degree_str is None or (LIST_RE.match(degree_str) and includes_composite(degree_str)) info['group_display'] = group_display_short info['yesno'] = yesno info['wgg'] = WebGaloisGroup.from_data
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 abelian_variety_search(info, query): parse_ints(info,query,'q',name='base field') parse_ints(info,query,'g',name='dimension') parse_bool(info,query,'simple',qfield='is_simp') parse_bool(info,query,'primitive',qfield='is_prim') parse_bool_unknown(info, query, 'jacobian', qfield='is_jac') parse_bool_unknown(info, query, 'polarizable', qfield='is_pp') parse_ints(info,query,'p_rank') parse_ints(info,query,'ang_rank') parse_newton_polygon(info,query,'newton_polygon',qfield='slps') parse_string_start(info,query,'initial_coefficients',qfield='poly_str',initial_segment=["1"]) parse_string_start(info,query,'abvar_point_count',qfield='A_cnts_str') parse_string_start(info,query,'curve_point_count',qfield='C_cnts_str',first_field='pt_cnt') if info.get('simple_quantifier') == 'contained': parse_subset(info,query,'simple_factors',qfield='simple_distinct',mode='subsets') elif info.get('simple_quantifier') == 'exactly': parse_subset(info,query,'simple_factors',qfield='simple_distinct',mode='exact') elif info.get('simple_quantifier') == 'include': parse_submultiset(info,query,'simple_factors',mode='append') for n in range(1,6): parse_ints(info,query,'dim%s_factors'%n) for n in range(1,4): parse_ints(info,query,'dim%s_distinct'%n) parse_nf_string(info,query,'number_field',qfield='nf') parse_galgrp(info,query,qfield=('galois_n','galois_t'))
def common_parse(info, query): parse_ints(info, query, "q", name="base field") parse_ints(info, query, "p", name="base cardinality") parse_ints(info, query, "g", name="dimension") parse_ints(info, query, "geom_deg", qfield="geometric_extension_degree") parse_bool(info, query, "simple", qfield="is_simple") parse_bool(info, query, "geom_simple", qfield="is_geometrically_simple") parse_bool(info, query, "primitive", qfield="is_primitive") parse_bool_unknown(info, query, "jacobian", qfield="has_jacobian") parse_bool_unknown(info, query, "polarizable", qfield="has_principal_polarization") parse_ints(info, query, "p_rank") parse_ints(info, query, "p_rank_deficit") parse_ints(info, query, "angle_rank") parse_ints(info, query, "jac_cnt", qfield="jacobian_count", name="Number of Jacobians") parse_ints(info, query, "hyp_cnt", qfield="hyp_count", name="Number of Hyperelliptic Jacobians") parse_ints(info, query, "twist_count") parse_ints(info, query, "max_twist_degree") parse_ints(info, query, "size") parse_newton_polygon(info, query, "newton_polygon", qfield="slopes") parse_string_start(info, query, "initial_coefficients", qfield="poly_str", initial_segment=["1"]) parse_string_start(info, query, "abvar_point_count", qfield="abvar_counts_str", first_field="abvar_count") parse_string_start(info, query, "curve_point_count", qfield="curve_counts_str", first_field="curve_count") if info.get("simple_quantifier") in ["subset", "exactly"]: parse_subset(info, query, "simple_factors", qfield="simple_distinct", mode=info.get("simple_quantifier")) else: parse_submultiset(info, query, "simple_factors") if info.get("use_geom_decomp") == "on": dimstr = "geom_dim" nf_qfield = "geometric_number_fields" gal_qfield = "geometric_galois_groups" else: dimstr = "dim" nf_qfield = "number_fields" gal_qfield = "galois_groups" for n in range(1, 6): parse_ints(info, query, "dim%s_factors" % n, qfield="%s%s_factors" % (dimstr, n)) for n in range(1, 4): parse_ints(info, query, "dim%s_distinct" % n, qfield="%s%s_distinct" % (dimstr, n)) parse_nf_string(info, query, "number_field", qfield=nf_qfield) parse_galgrp(info, query, "galois_group", qfield=gal_qfield) if 'geom_squarefree' in info: if info['geom_squarefree'] == 'Yes': query['is_squarefree'] = True elif info['geom_squarefree'] == 'YesAndGeom': query['is_squarefree'] = True query['is_geometrically_squarefree'] = True elif info['geom_squarefree'] == 'YesNotGeom': query['is_squarefree'] = True query['is_geometrically_squarefree'] = False elif info['geom_squarefree'] == 'No': query['is_squarefree'] = False elif info['geom_squarefree'] == 'NotGeom': query['is_geometrically_squarefree'] = False
def group_search(info, query): info['group_url'] = get_url info['getname'] = lambda xx: '$' + group_names_pretty(xx) + '$' parse_ints(info, query, 'order', 'order') parse_ints(info, query, 'dim', 'dim')
def genus2_curve_search(info, query): info["st_group_list"] = st_group_list info["st_group_dict"] = st_group_dict info["real_geom_end_alg_list"] = real_geom_end_alg_list info["real_geom_end_alg_to_ST0_dict"] = real_geom_end_alg_to_ST0_dict info["aut_grp_list"] = aut_grp_list info["aut_grp_dict"] = aut_grp_dict info["geom_aut_grp_list"] = geom_aut_grp_list info["geom_aut_grp_dict"] = geom_aut_grp_dict info["geom_end_alg_list"] = geom_end_alg_list info["geom_end_alg_dict"] = geom_end_alg_dict parse_ints(info,query,'abs_disc','absolute discriminant') parse_bool(info,query,'is_gl2_type','is of GL2-type') parse_bool(info,query,'has_square_sha','has square Sha') parse_bool(info,query,'locally_solvable','is locally solvable') parse_bool(info,query,'is_simple_geom','is geometrically simple') parse_ints(info,query,'cond','conductor') parse_ints(info,query,'num_rat_pts','rational points') parse_ints(info,query,'num_rat_wpts','rational Weierstrass points') parse_bracketed_posints(info, query, 'torsion', 'torsion structure', maxlength=4,check_divisibility="increasing") parse_ints(info,query,'torsion_order','torsion order') if 'torsion' in query and not 'torsion_order' in query: query['torsion_order'] = reduce(mul,[int(n) for n in query['torsion']],1) if 'torsion' in query: query['torsion_subgroup'] = str(query['torsion']).replace(" ","") query.pop('torsion') # search using string key, not array of ints parse_ints(info,query,'two_selmer_rank','2-Selmer rank') parse_ints(info,query,'analytic_rank','analytic rank') # G2 invariants and drop-list items don't require parsing -- they are all strings (supplied by us, not the user) if 'g20' in info and 'g21' in info and 'g22' in info: query['g2_inv'] = "['%s','%s','%s']"%(info['g20'], info['g21'], info['g22']) if 'class' in info: query['class'] = info['class'] for fld in ('st_group', 'real_geom_end_alg', 'aut_grp_id', 'geom_aut_grp_id', 'geom_end_alg'): if info.get(fld): query[fld] = info[fld] info["curve_url"] = lambda label: url_for_curve_label(label) info["class_url"] = lambda label: url_for_isogeny_class_label(label)