def EC_data(label): bread = get_bread([(label, url_for_label(label)), ("Data", " ")]) if match_lmfdb_label(label): conductor, iso_class, number = split_lmfdb_label(label) if not number: # isogeny class return datapage(label, ["ec_classdata", "ec_padic"], bread=bread, label_col="lmfdb_iso", sorts=[[], ["p"]]) iso_label = class_lmfdb_label(conductor, iso_class) labels = [label] * 8 label_cols = ["lmfdb_label"] * 8 labels[1] = labels[7] = iso_label label_cols[1] = label_cols[7] = "lmfdb_iso" sorts = [[], [], [], [], ["degree", "field"], ["prime"], ["prime"], ["p"]] return datapage(labels, ["ec_curvedata", "ec_classdata", "ec_mwbsd", "ec_iwasawa", "ec_torsion_growth", "ec_localdata", "ec_galrep", "ec_padic"], title=f"Elliptic curve data - {label}", bread=bread, label_cols=label_cols, sorts=sorts) return abort(404, f"Invalid label {label}")
def elliptic_curve_jump(info): label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s', '', label) lab = re.sub(r'^\[', '', lab) lab = re.sub(r']$', '', lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec).minimal_model() # Now we do have a valid curve over Q, but it might # not be in the database. lmfdb_label = db.ec_curves.lucky({'ainvs': EC_ainvs(E)}, 'lmfdb_label') if lmfdb_label is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(lmfdb_label) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: return elliptic_curve_jump_error('', info)
def elliptic_curve_jump(info): label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec).minimal_model() # Now we do have a valid curve over Q, but it might # not be in the database. lmfdb_label = db.ec_curves.lucky({'ainvs': EC_ainvs(E)}, 'lmfdb_label') if lmfdb_label is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(lmfdb_label) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: return elliptic_curve_jump_error('', info)
def elliptic_curve_search(info): if info.get('download') == '1' and info.get('Submit') and info.get('query'): return download_search(info) if 'SearchAgain' in info: return rational_elliptic_curves() query = {} bread = info.get('bread',[('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('Search Results', '.')]) if 'jump' in info: label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec) # Now we do have a valid curve over Q, but it might # not be in the database. ainvs = [str(c) for c in E.minimal_model().ainvs()] xainvs = ''.join(['[',','.join(ainvs),']']) data = db_ec().find_one({'xainvs': xainvs}) if data is None: data = db_ec().find_one({'ainvs': ainvs}) if data is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(data['lmfdb_label']) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query['label'] = '' try: 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,process=str,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_ints(info,query,field='isodeg',qfield='isogeny_degrees') parse_primes(info, query, 'surj_primes', name='surjective primes', qfield='non-maximal_primes', mode='complement') if info.get('surj_quantifier') == 'exactly': mode = 'exact' else: mode = 'append' parse_primes(info, query, 'nonsurj_primes', name='non-surjective primes', qfield='non-maximal_primes',mode=mode) except ValueError as err: info['err'] = str(err) return search_input_error(info, bread) count = parse_count(info,100) start = parse_start(info) if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 info['query'] = query cursor = db_ec().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('conductor', ASCENDING), ('iso_nlabel', ASCENDING), ('lmfdb_number', ASCENDING)]).skip(start).limit(count) info['curves'] = res info['format_ainvs'] = format_ainvs 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]) info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) if nres == 1: info['report'] = 'unique match' elif nres == 2: info['report'] = 'displaying both matches' 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 #credit = 'John Cremona' #if 'non-surjective_primes' in query or 'non-maximal_primes' in query: # credit += ' and Andrew Sutherland' t = info.get('title','Elliptic Curves search results') return render_template("ec-search-results.html", info=info, credit=ec_credit(), bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args) query = {} bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('Search Results', '.')] if 'SearchAgain' in args: return rational_elliptic_curves() if 'jump' in args: label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec) # Now we do have a valid curve over Q, but it might # not be in the database. ainvs = [str(c) for c in E.minimal_model().ainvs()] data = db_ec().find_one({'ainvs': ainvs}) if data is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(data['lmfdb_label']) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query['label'] = '' if info.get('jinv'): j = clean_input(info['jinv']) j = j.replace('+', '') if not QQ_RE.match(j): info['err'] = 'Error parsing input for the j-invariant. It needs to be a rational number.' return search_input_error(info, bread) query['jinv'] = str(QQ(j)) # to simplify e.g. 1728/1 for field in ['conductor', 'torsion', 'rank', 'sha']: if info.get(field): info[field] = clean_input(info[field]) ran = info[field] ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): names = {'conductor': 'conductor', 'torsion': 'torsion order', 'rank': 'rank', 'sha': 'analytic order of Ш'} info['err'] = 'Error parsing input for the %s. It needs to be an integer (such as 25), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 4,9,16 or 4-25, 81-121).' % names[field] return search_input_error(info, bread) # Past input check 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] if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 if 'torsion_structure' in info and info['torsion_structure']: res = parse_torsion_structure(info['torsion_structure']) if 'Error' in res: info['err'] = res return search_input_error(info, bread) #update info for repeat searches info['torsion_structure'] = str(res).replace(' ','') query['torsion_structure'] = [str(r) for r in res] if info.get('surj_primes'): info['surj_primes'] = clean_input(info['surj_primes']) format_ok = LIST_POSINT_RE.match(info['surj_primes']) if format_ok: surj_primes = [int(p) for p in info['surj_primes'].split(',')] format_ok = all([ZZ(p).is_prime(proof=False) for p in surj_primes]) if format_ok: query['non-surjective_primes'] = {"$nin": surj_primes} else: info['err'] = 'Error parsing input for surjective primes. It needs to be a prime (such as 5), or a comma-separated list of primes (such as 2,3,11).' return search_input_error(info, bread) if info.get('nonsurj_primes'): info['nonsurj_primes'] = clean_input(info['nonsurj_primes']) format_ok = LIST_POSINT_RE.match(info['nonsurj_primes']) if format_ok: nonsurj_primes = [int(p) for p in info['nonsurj_primes'].split(',')] format_ok = all([ZZ(p).is_prime(proof=False) for p in nonsurj_primes]) if format_ok: if info['surj_quantifier'] == 'exactly': nonsurj_primes.sort() query['non-surjective_primes'] = nonsurj_primes else: if 'non-surjective_primes' in query: query['non-surjective_primes'] = { "$nin": surj_primes, "$all": nonsurj_primes } else: query['non-surjective_primes'] = { "$all": nonsurj_primes } else: info['err'] = 'Error parsing input for nonsurjective primes. It needs to be a prime (such as 5), or a comma-separated list of primes (such as 2,3,11).' return search_input_error(info, bread) if 'download' in info and info['download'] != '0': res = db_ec().find(query).sort([ ('conductor', ASCENDING), ('lmfdb_iso', ASCENDING), ('lmfdb_number', ASCENDING) ]) return download_search(info, res) count_default = 100 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default info['count'] = 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 cursor = db_ec().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('conductor', ASCENDING), ('lmfdb_iso', ASCENDING), ('lmfdb_number', ASCENDING) ]).skip(start).limit(count) info['curves'] = res info['format_ainvs'] = format_ainvs 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]) info['number'] = nres info['start'] = start if nres == 1: info['report'] = 'unique match' elif nres == 2: info['report'] = 'displaying both matches' 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 credit = 'John Cremona' if 'non-surjective_primes' in query: credit += 'and Andrew Sutherland' t = 'Elliptic Curves search results' return render_template("search_results.html", info=info, credit=credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args) if 'download' in info and info['download'] != '0': return download_search(info) query = {} bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('Search Results', '.')] if 'SearchAgain' in args: return rational_elliptic_curves() if 'jump' in args: label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec) # Now we do have a valid curve over Q, but it might # not be in the database. ainvs = [str(c) for c in E.minimal_model().ainvs()] data = db_ec().find_one({'ainvs': ainvs}) if data is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(data['lmfdb_label']) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query['label'] = '' try: 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,process=str,check_divisibility='increasing') if 'include_cm' in info: if info['include_cm'] == 'exclude': query['cm'] = 0 elif info['include_cm'] == 'only': query['cm'] = {'$ne' : 0} parse_primes(info, query, 'surj_primes', name='surjective primes', qfield='non-surjective_primes', mode='complement') if info.get('surj_quantifier') == 'exactly': mode = 'exact' else: mode = 'append' parse_primes(info, query, 'nonsurj_primes', name='non-surjective primes', qfield='non-surjective_primes',mode=mode) except ValueError as err: info['err'] = str(err) return search_input_error(info, bread) count = parse_count(info,100) start = parse_start(info) if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 info['query'] = query cursor = db_ec().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('conductor', ASCENDING), ('iso_nlabel', ASCENDING), ('lmfdb_number', ASCENDING)]).skip(start).limit(count) info['curves'] = res info['format_ainvs'] = format_ainvs 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]) info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) if nres == 1: info['report'] = 'unique match' elif nres == 2: info['report'] = 'displaying both matches' 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 credit = 'John Cremona' if 'non-surjective_primes' in query: credit += 'and Andrew Sutherland' t = 'Elliptic Curves search results' return render_template("search_results.html", info=info, credit=credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args) query = {} bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('Search Results', '.')] if 'SearchAgain' in args: return rational_elliptic_curves() if 'jump' in args: label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec) # Now we do have a valid curve over Q, but it might # not be in the database. ainvs = [str(c) for c in E.minimal_model().ainvs()] data = db_ec().find_one({'ainvs': ainvs}) if data is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(data['lmfdb_label']) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query['label'] = '' if info.get('jinv'): j = clean_input(info['jinv']) j = j.replace('+', '') if not QQ_RE.match(j): info['err'] = 'Error parsing input for the j-invariant. It needs to be a rational number.' return search_input_error(info, bread) query['jinv'] = str(QQ(j)) # to simplify e.g. 1728/1 for field in ['conductor', 'torsion', 'rank', 'sha']: if info.get(field): info[field] = clean_input(info[field]) ran = info[field] ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): names = {'conductor': 'conductor', 'torsion': 'torsion order', 'rank': 'rank', 'sha': 'analytic order of Ш'} info['err'] = 'Error parsing input for the %s. It needs to be an integer (such as 25), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 4,9,16 or 4-25, 81-121).' % names[field] return search_input_error(info, bread) # Past input check 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] if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 if 'torsion_structure' in info and info['torsion_structure']: res = parse_torsion_structure(info['torsion_structure'],2) if 'Error' in res: info['err'] = res return search_input_error(info, bread) #update info for repeat searches info['torsion_structure'] = str(res).replace(' ','') query['torsion_structure'] = [str(r) for r in res] if info.get('surj_primes'): info['surj_primes'] = clean_input(info['surj_primes']) format_ok = LIST_POSINT_RE.match(info['surj_primes']) if format_ok: surj_primes = [int(p) for p in info['surj_primes'].split(',')] format_ok = all([ZZ(p).is_prime(proof=False) for p in surj_primes]) if format_ok: query['non-surjective_primes'] = {"$nin": surj_primes} else: info['err'] = 'Error parsing input for surjective primes. It needs to be a prime (such as 5), or a comma-separated list of primes (such as 2,3,11).' return search_input_error(info, bread) if info.get('nonsurj_primes'): info['nonsurj_primes'] = clean_input(info['nonsurj_primes']) format_ok = LIST_POSINT_RE.match(info['nonsurj_primes']) if format_ok: nonsurj_primes = [int(p) for p in info['nonsurj_primes'].split(',')] format_ok = all([ZZ(p).is_prime(proof=False) for p in nonsurj_primes]) if format_ok: if info['surj_quantifier'] == 'exactly': nonsurj_primes.sort() query['non-surjective_primes'] = nonsurj_primes else: if 'non-surjective_primes' in query: query['non-surjective_primes'] = { "$nin": surj_primes, "$all": nonsurj_primes } else: query['non-surjective_primes'] = { "$all": nonsurj_primes } else: info['err'] = 'Error parsing input for nonsurjective primes. It needs to be a prime (such as 5), or a comma-separated list of primes (such as 2,3,11).' return search_input_error(info, bread) if 'download' in info and info['download'] != '0': res = db_ec().find(query).sort([ ('conductor', ASCENDING), ('iso_nlabel', ASCENDING), ('lmfdb_number', ASCENDING) ]) return download_search(info, res) count_default = 100 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default info['count'] = 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 cursor = db_ec().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('conductor', ASCENDING), ('iso_nlabel', ASCENDING), ('lmfdb_number', ASCENDING) ]).skip(start).limit(count) info['curves'] = res info['format_ainvs'] = format_ainvs 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]) info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) if nres == 1: info['report'] = 'unique match' elif nres == 2: info['report'] = 'displaying both matches' 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 credit = 'John Cremona' if 'non-surjective_primes' in query: credit += 'and Andrew Sutherland' t = 'Elliptic Curves search results' return render_template("search_results.html", info=info, credit=credit, bread=bread, title=t)
def elliptic_curve_search(info): if info.get('download') == '1' and info.get('Submit') and info.get('query'): return download_search(info) if 'SearchAgain' in info: return rational_elliptic_curves() query = {} bread = info.get('bread',[('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('Search Results', '.')]) if 'jump' in info: label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec).minimal_model() # Now we do have a valid curve over Q, but it might # not be in the database. data = db_ec().find_one({'xainvs': EC_ainvs(E)}) if data is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(data['lmfdb_label']) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query['label'] = '' try: 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,process=str,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_ints(info,query,field='isodeg',qfield='isogeny_degrees') parse_primes(info, query, 'surj_primes', name='surjective primes', qfield='non-maximal_primes', mode='complement') if info.get('surj_quantifier') == 'exactly': mode = 'exact' else: mode = 'append' parse_primes(info, query, 'nonsurj_primes', name='non-surjective primes', qfield='non-maximal_primes',mode=mode) except ValueError as err: info['err'] = str(err) return search_input_error(info, bread) count = parse_count(info,100) start = parse_start(info) if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 info['query'] = query cursor = db_ec().find(query); cursor = cursor.sort([('conductor', ASCENDING), ('iso_nlabel', ASCENDING), ('lmfdb_number', ASCENDING)]); # equivalent to # cursor = res # nres = res.count() # if(start >= nres): # start -= (1 + (start - nres) / count) * count # if(start < 0): # start = 0 # res = res.skip(start).limit(count) try: start, nres, res = search_cursor_timeout_decorator(cursor, start, count); except ValueError as err: info['err'] = err; return search_input_error(info, bread) info['curves'] = res 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]) info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) if nres == 1: info['report'] = 'unique match' elif nres == 2: info['report'] = 'displaying both matches' 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 t = info.get('title','Elliptic Curves search results') return render_template("ec-search-results.html", info=info, credit=ec_credit(), bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args) if "download" in info and info["download"] != "0": return download_search(info) query = {} bread = [ ("Elliptic Curves", url_for("ecnf.index")), ("$\Q$", url_for(".rational_elliptic_curves")), ("Search Results", "."), ] if "SearchAgain" in args: return rational_elliptic_curves() if "jump" in args: label = info.get("label", "").replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r"\s", "", label) lab = re.sub(r"^\[", "", lab) lab = re.sub(r"]$", "", lab) try: labvec = lab.split(",") labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec) # Now we do have a valid curve over Q, but it might # not be in the database. ainvs = [str(c) for c in E.minimal_model().ainvs()] data = db_ec().find_one({"ainvs": ainvs}) if data is None: info["conductor"] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(data["lmfdb_label"]) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query["label"] = "" try: 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, process=str, check_divisibility="increasing" ) parse_primes( info, query, "surj_primes", name="surjective primes", qfield="non-surjective_primes", mode="complement" ) if info.get("surj_quantifier") == "exactly": mode = "exact" else: mode = "append" parse_primes( info, query, "nonsurj_primes", name="non-surjective primes", qfield="non-surjective_primes", mode=mode ) except ValueError as err: info["err"] = str(err) return search_input_error(info, bread) count = parse_count(info, 100) start = parse_start(info) if "optimal" in info and info["optimal"] == "on": # fails on 990h3 query["number"] = 1 info["query"] = query cursor = db_ec().find(query) nres = cursor.count() if start >= nres: start -= (1 + (start - nres) / count) * count if start < 0: start = 0 res = ( cursor.sort([("conductor", ASCENDING), ("iso_nlabel", ASCENDING), ("lmfdb_number", ASCENDING)]) .skip(start) .limit(count) ) info["curves"] = res info["format_ainvs"] = format_ainvs 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] ) info["number"] = nres info["start"] = start info["count"] = count info["more"] = int(start + count < nres) if nres == 1: info["report"] = "unique match" elif nres == 2: info["report"] = "displaying both matches" 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 credit = "John Cremona" if "non-surjective_primes" in query: credit += "and Andrew Sutherland" t = "Elliptic Curves search results" return render_template("search_results.html", info=info, credit=credit, bread=bread, title=t)