示例#1
0
def genus2_curve_search(**args):
    info = to_dict(args)
    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_dict"] = real_geom_end_alg_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
    query = {}  # database callable
    bread = [('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('Search Results', '.')]
    #if 'SearchAgain' in args:
    #    return rational_genus2_curves()

    if 'jump' in args:
        return render_curve_webpage_by_label(info["jump"])

    if info.get("disc"):
        field = "abs_disc"
        ran = info["disc"]
        ran = ran.replace('..', '-').replace(' ','')
        # Past input check
        dlist = parse_discs(ran)
        tmp = g2_list_to_query(dlist)

        if len(tmp) == 1:
            tmp = tmp[0]
        else:
            query[tmp[0][0]] = tmp[0][1]
            tmp = tmp[1]

        # 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 info.get("is_gl2_type"):
        if info['is_gl2_type'] == "True":
            query['is_gl2_type']= True
        elif info['is_gl2_type'] == "False":
            query['is_gl2_type']= False

    for fld in ['st_group', 'real_geom_end_alg']:
        if info.get(fld):
            query[fld] = info[fld]
    for fld in ['aut_grp', 'geom_aut_grp','igusa_clebsch']:
        if info.get(fld):
            query[fld] = map(int,info[fld].strip()[1:-1].split(","))
    if info.get('torsion'):
        res = parse_torsion_structure(info['torsion'],4)
        if 'Error' in res:
            # no error handling of malformed input yet!
            info['torsion'] = ''
            #info['err'] = res
            #return search_input_error(info, bread)
        else:
            #update info for repeat searches
            info['torsion'] = str(res).replace(' ','')
            query['torsion'] = [int(r) for r in res]

    if info.get('ic0'):
        query['igusa_clebsch']=[info['ic0'], info['ic1'], info['ic2'], info['ic3'] ]
        

    for fld in ["cond", "num_rat_wpts", "torsion_order", "two_selmer_rank"]:
        if info.get(fld):
            field = fld
            ran = str(info[field])
            ran = ran.replace('..', '-').replace(' ','')
            # 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]

    info["query"] = dict(query)

    count_default = 50
    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_g2c().curves.find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0

    res = cursor.sort([("cond", pymongo.ASCENDING),
                                            ("class", pymongo.ASCENDING),
                                            ("disc_key", pymongo.ASCENDING),
                                            ("label", pymongo.ASCENDING)]).skip(start).limit(count)
    nres = res.count()
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    res_clean = []
    
    
    for v in res:
        v_clean = {}
        v_clean["label"] = v["label"]
        v_clean["isog_label"] = v["class"]
        isogeny_class = db_g2c().isogeny_classes.find_one({'label' : isog_label(v["label"])})
        v_clean["is_gl2_type"] = isogeny_class["is_gl2_type"]
        if isogeny_class["is_gl2_type"] == True:
            v_clean["is_gl2_type_display"] = '&#10004;' #checkmark
        else:
            v_clean["is_gl2_type_display"] = ''
        v_clean["equation_formatted"] = list_to_min_eqn(v["min_eqn"])
        v_clean["st_group_name"] = st_group_name(isogeny_class['st_group'])
        res_clean.append(v_clean)

    info["curves"] = res_clean

    info["curve_url"] = lambda dbc: url_for_label(dbc['label'])
    info["isog_url"] = lambda dbc: isog_url_for_label(dbc['label'])
    info["start"] = start
    info["count"] = count
    info["more"] = int(start+count<nres)
    credit = credit_string
    title = 'Genus 2 Curves search results'
    return render_template("search_results_g2.html", info=info, credit=credit, bread=bread, title=title)
示例#2
0
def genus2_curve_search(**args):
    info = to_dict(args)
    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_dict"] = real_geom_end_alg_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
    query = {}  # database callable
    bread = [('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('Search Results', '.')]
    #if 'SearchAgain' in args:
    #    return rational_genus2_curves()

    if 'jump' in args:
        return render_curve_webpage_by_label(info["jump"])

    if info.get("disc"):
        field = "abs_disc"
        ran = info["disc"]
        ran = ran.replace('..', '-').replace(' ','')
        # Past input check
        dlist = parse_discs(ran)
        tmp = g2_list_to_query(dlist)

        if len(tmp) == 1:
            tmp = tmp[0]
        else:
            query[tmp[0][0]] = tmp[0][1]
            tmp = tmp[1]

        # 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 info.get("is_gl2_type"):
        if info['is_gl2_type'] == "True":
            query['is_gl2_type']= True
        elif info['is_gl2_type'] == "False":
            query['is_gl2_type']= False

    for fld in ['st_group', 'real_geom_end_alg']:
        if info.get(fld):
            query[fld] = info[fld]
    for fld in ['aut_grp', 'geom_aut_grp','torsion','igusa_clebsch']:
        if info.get(fld):
            query[fld] = map(int,info[fld].strip()[1:-1].split(","))
    if info.get('ic0'):
        query['igusa_clebsch']=[info['ic0'], info['ic1'], info['ic2'], info['ic3'] ]
        

    for fld in ["cond", "num_rat_wpts", "torsion_order", "two_selmer_rank"]:
        if info.get(fld):
            field = fld
            ran = str(info[field])
            ran = ran.replace('..', '-').replace(' ','')
            # 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]

    info["query"] = dict(query)

    count_default = 50
    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_g2c().curves.find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0

    res = cursor.sort([("cond", pymongo.ASCENDING),
                                            ("class", pymongo.ASCENDING),
                                            ("disc_key", pymongo.ASCENDING),
                                            ("label", pymongo.ASCENDING)]).skip(start).limit(count)
    nres = res.count()
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    res_clean = []
    
    
    for v in res:
        v_clean = {}
        v_clean["label"] = v["label"]
        v_clean["isog_label"] = v["class"]
        isogeny_class = db_g2c().isogeny_classes.find_one({'label' : isog_label(v["label"])})
        v_clean["is_gl2_type"] = isogeny_class["is_gl2_type"]
        if isogeny_class["is_gl2_type"] == True:
            v_clean["is_gl2_type_display"] = '&#10004;' #checkmark
        else:
            v_clean["is_gl2_type_display"] = ''
        v_clean["equation_formatted"] = list_to_min_eqn(v["min_eqn"])
        v_clean["st_group_name"] = st_group_name(isogeny_class['st_group'])
        res_clean.append(v_clean)

    info["curves"] = res_clean

    info["curve_url"] = lambda dbc: url_for_label(dbc['label'])
    info["isog_url"] = lambda dbc: isog_url_for_label(dbc['label'])
    info["start"] = start
    info["count"] = count
    info["more"] = int(start+count<nres)
    credit = credit_string
    title = 'Genus 2 Curves search results'
    return render_template("search_results_g2.html", info=info, credit=credit, bread=bread, title=title)
示例#3
0
def genus2_curve_search(**args):
    info = to_dict(args)
    query = {}  # database callable
    bread = [('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")), ('Search Results', '.')]
    #if 'SearchAgain' in args:
    #    return rational_genus2_curves()

    if 'jump' in args:
        return render_curve_webpage_by_label(info["jump"])

    if info.get("disc"):
        field = "abs_disc"
        ran = info["disc"]
        ran = ran.replace('..', '-').replace(' ', '')
        # Past input check
        dlist = parse_discs(ran)
        tmp = g2_list_to_query(dlist)

        if len(tmp) == 1:
            tmp = tmp[0]
        else:
            query[tmp[0][0]] = tmp[0][1]
            tmp = tmp[1]

        print tmp

        # 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 info.get("is_gl2_type"):
        query['is_gl2_type'] = bool(info['is_gl2_type'])

    for fld in ['aut_grp', 'geom_aut_grp', 'st_group', 'real_geom_end_alg']:
        if info.get(fld):
            query[fld] = info[fld]
    for fld in ['aut_grp', 'geom_aut_grp']:
        if info.get(fld):
            query[fld] = eval(info[fld])

    if info.get("cond"):
        field = "cond"
        ran = str(info[field])
        ran = ran.replace('..', '-').replace(' ', '')
        # Past input check
        tmp = parse_range2(ran, field)

        print tmp

        # 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 info.get("count"):
        try:
            count = int(info["count"])
        except:
            count = 100
    else:
        count = 100

    info["query"] = dict(query)
    #res = db_g2c().curves.find(query).sort([("cond", pymongo.ASCENDING),
    #("label", pymongo.ASCENDING)]).limit(count)
    res = db_g2c().curves.find(query).sort([("cond", pymongo.ASCENDING),
                                            ("class", pymongo.ASCENDING),
                                            ("disc_key", pymongo.ASCENDING),
                                            ("label", pymongo.ASCENDING)])
    nres = res.count()
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count:
            info["report"] = "displaying first %s of %s matches" % (count,
                                                                    nres)
        else:
            info["report"] = "displaying all %s matches" % nres
    res_clean = []

    for v in res:
        v_clean = {}
        v_clean["label"] = v["label"]
        v_clean["isog_label"] = v["class"]
        isogeny_class = db_g2c().isogeny_classes.find_one(
            {'label': isog_label(v["label"])})
        v_clean["is_gl2_type"] = isogeny_class["is_gl2_type"]
        v_clean["equation_formatted"] = list_to_min_eqn(v["min_eqn"])
        res_clean.append(v_clean)

    info["curves"] = res_clean

    info["curve_url"] = lambda dbc: url_for_label(dbc['label'])
    info["isog_url"] = lambda dbc: isog_url_for_label(dbc['label'])
    credit = credit_string
    title = 'Genus 2 Curves search results'
    return render_template("search_results_g2.html",
                           info=info,
                           credit=credit,
                           bread=bread,
                           title=title)
示例#4
0
文件: main.py 项目: paulhus/lmfdb
def elliptic_curve_search(**args):
    info = to_dict(args['data'])
    if 'jump' in info:
        label = info.get('label', '').replace(" ", "")
        # This label should be a full isogeny class label or a full
        # curve label (including the field_label component)
        try:
            nf, cond_label, iso_label, number = split_full_label(label.strip())
        except IndexError:
            if not 'query' in info:
                info['query'] = {}
            bread = [("Elliptic Curves", url_for(".index"))]
            info[
                'err'] = 'No elliptic curve in the database has label %s.' % label
            return search_input_error(info, bread)

        return show_ecnf(nf, cond_label, iso_label, number)

    query = {}
    bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')]

    if 'conductor_norm' in info:
        Nnorm = clean_input(info['conductor_norm'])
        Nnorm = Nnorm.replace('..', '-').replace(' ', '')
        tmp = parse_range2(Nnorm, 'conductor_norm')
        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 'conductor_label' in info:
        query['conductor_label'] = info['conductor_label']

    if 'jinv' in info:
        query['jinv'] = info['jinv']

    if info.get('torsion'):
        ran = info['torsion'] = clean_input(info['torsion'])
        ran = ran.replace('..', '-').replace(' ', '')
        if not LIST_RE.match(ran):
            info[
                'err'] = 'Error parsing input for the torsion order.  It needs to be an integer (such as 5), 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).'
            return search_input_error(info, bread)
        # Past input check
        tmp = parse_range2(ran, 'torsion_order')
        # 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 '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'] = [int(r) for r in res]

    if 'include_isogenous' in info and info['include_isogenous'] == 'off':
        query['number'] = 1

    if 'include_base_change' in info and info['include_base_change'] == 'off':
        query['base_change'] = []
    else:
        info['include_base_change'] = "on"

    if 'field' in info:
        query['field_label'] = parse_field_string(info['field'])

    info['query'] = query

    # process count and start if not default:

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

    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


# make the query and trim results according to start/count:

    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if (start >= nres):
        start -= (1 + (start - nres) / count) * count
    if (start < 0):
        start = 0
    res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC),
                       ('conductor_label', ASC), ('iso_nlabel', ASC),
                       ('number', ASC)]).skip(start).limit(count)

    res = list(res)
    for e in res:
        e['numb'] = str(e['number'])
        e['field_knowl'] = nf_display_knowl(e['field_label'],
                                            getDBConnection(),
                                            e['field_label'])

    info['curves'] = res  # [ECNF(e) for e in res]
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)
    info['field_pretty'] = field_pretty
    info['web_ainvs'] = web_ainvs
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (
                start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    t = 'Elliptic Curve search results'
    return render_template("ecnf-search-results.html",
                           info=info,
                           credit=ecnf_credit,
                           bread=bread,
                           title=t)
示例#5
0
def number_field_search(**args):
    info = to_dict(args)

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

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

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

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

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

    fields = C.numberfields.fields

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

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

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

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

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

    info['wnf'] = WebNumberField.from_data
    return render_template("number_field_search.html", info=info, title=t, bread=bread)
示例#6
0
文件: main.py 项目: CleryFabien/lmfdb
def galois_group_search(**args):
    info = to_dict(args)
    bread = get_bread([("Search results", url_for('.search'))])
    C = base.getDBConnection()
    query = {}
    if 'jump_to' in info:
        return render_group_webpage({'label': info['jump_to']})

    for param in ['n', 't']:
        if info.get(param):
            info[param] = clean_input(info[param])
            ran = info[param]
            ran = ran.replace('..', '-')
            if LIST_RE.match(ran):
                tmp = parse_range2(ran, param)
            else:
                names = {'n': 'degree', 't': 't'}
                info[
                    'err'] = 'Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[
                        param]
                return search_input_error(info, bread)
            # 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]
    for param in ['cyc', 'solv', 'prim', 'parity']:
        if info.get(param):
            info[param] = str(info[param])
            if info[param] == str(1):
                query[param] = 1
            elif info[param] == str(-1):
                query[param] = -1 if param == 'parity' else 0

    # Determine if we have any composite degrees
    info['show_subs'] = True
    if info.get('n'):
        info[
            'show_subs'] = False  # now only show subs if a composite n is allowed
        nparam = info.get('n')
        nparam.replace('..', '-')
        nlist = nparam.split(',')
        found = False
        for nl in nlist:
            if '-' in nl:
                inx = nl.index('-')
                ll, hh = nl[:inx], nl[inx + 1:]
                hh = int(hh)
                jj = int(ll)
                while jj <= hh and not found:
                    if not (ZZ(jj).is_prime() or ZZ(jj) == 1):
                        found = True
                    jj += 1
                if found:
                    break
            else:
                jj = ZZ(nl)
                if not (ZZ(jj).is_prime() or ZZ(jj) == 1):
                    found = True
                    break
        if found:
            info['show_subs'] = True

    count_default = 20
    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
    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    res = C.transitivegroups.groups.find(query).sort([('n', pymongo.ASCENDING),
                                                      ('t', pymongo.ASCENDING)
                                                      ])
    nres = res.count()
    res = res.skip(start).limit(count)

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

    info['groups'] = res
    info['group_display'] = group_display_shortC(C)
    info['report'] = "found %s groups" % nres
    info['yesno'] = yesno
    info['wgg'] = WebGaloisGroup.from_data
    info['start'] = start
    info['number'] = nres
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (
                start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres

    return render_template("gg-search.html",
                           info=info,
                           title="Galois Group Search Result",
                           bread=bread,
                           credit=GG_credit)
示例#7
0
def number_field_search(**args):
    info = to_dict(args)

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

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

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

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

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

    fields = C.numberfields.fields

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

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

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

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

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

    info["wnf"] = WebNumberField.from_data
    return render_template("number_field_search.html", info=info, title=t, bread=bread)
示例#8
0
def hgm_search(**args):
    info = to_dict(args)
    bread = get_bread([("Search results", url_for('.search'))])
    C = base.getDBConnection()
    query = {}
    if 'jump_to' in info:
        return render_hgm_webpage({'label': info['jump_to']})

    # t, generic, irreducible
    # 'A', 'B', 'hodge'
    for param in ['t', 'A', 'B']:
        if (param == 't' and PAIR_RE.match(info['t'])) or (param == 'A' and IF_RE.match(info[param])) or (param == 'B' and IF_RE.match(info[param])):
            query[param] = parse_list(info[param])
        else:
            print "Bad input"
            
    for param in ['degree','weight','sign']:
        if info.get(param):
            info[param] = clean_input(info[param])
            if param == 'gal':
                try:
                    gcs = complete_group_codes(info[param])
                    if len(gcs) == 1:
                        tmp = ['gal', list(gcs[0])]
                    if len(gcs) > 1:
                        tmp = [{'gal': list(x)} for x in gcs]
                        tmp = ['$or', tmp]
                except NameError as code:
                    info['err'] = 'Error parsing input for A: unknown group label %s.  It needs to be a <a title = "Galois group labels" knowl="nf.galois_group.name">group label</a>, such as C5 or 5T1, or comma separated list of labels.' % code
                    return search_input_error(info, bread)
            else:
                ran = info[param]
                ran = ran.replace('..', '-')
                if LIST_RE.match(ran):
                    tmp = parse_range2(ran, param)
                else:
                    names = {'weight': 'weight', 'degree': 'degree', 'sign': 'sign'}
                    info['err'] = 'Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[param]
                    return search_input_error(info, bread)
            # 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]

    count_default = 20
    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
    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    # logger.debug(query)
    res = C.hgm.motives.find(query).sort([('degree', pymongo.ASCENDING), 
        ('label', pymongo.ASCENDING)])
    nres = res.count()
    res = res.skip(start).limit(count)

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

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

    return render_template("hgm-search.html", info=info, title="Hypergeometric Motive over $\Q$ Search Result", bread=bread, credit=HGM_credit)
示例#9
0
def elliptic_curve_search(**args):
    info = to_dict(args["data"])
    if "jump" in info:
        label = info.get("label", "").replace(" ", "")
        # This label should be a full isogeny class label or a full
        # curve label (including the field_label component)
        label_parts = label.split("-", 2)
        nf = label_parts[0]
        cond_label = label_parts[1]
        cur_label = label_parts[2]
        return show_ecnf(nf, cond_label, cur_label)  ##!!!

    query = {}

    if "conductor_norm" in info:
        Nnorm = clean_input(info["conductor_norm"])
        Nnorm = Nnorm.replace("..", "-").replace(" ", "")
        tmp = parse_range2(Nnorm, "conductor_norm")
        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 "conductor_label" in info:
        query["conductor_label"] = info["conductor_label"]

    if "include_isogenous" in info and info["include_isogenous"] == "off":
        query["number"] = 1

    if "field" in info:
        query["field_label"] = info["field"]

    info["query"] = query

    # process count and start if not default:

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

    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

    # make the query and trim results according to start/count:

    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if start >= nres:
        start -= (1 + (start - nres) / count) * count
    if start < 0:
        start = 0
    res = (
        cursor.sort(
            [
                ("field_label", ASC),
                ("conductor_norm", ASC),
                ("conductor_label", ASC),
                ("iso_label", ASC),
                ("number", ASC),
            ]
        )
        .skip(start)
        .limit(count)
    )

    bread = [("Elliptic Curves", url_for(".index")), ("Search Results", ".")]

    res = list(res)
    for e in res:
        e["numb"] = str(e["number"])
        e["field_knowl"] = nf_display_knowl(e["field_label"], getDBConnection(), e["field_label"])

    info["curves"] = res  # [ECNF(e) for e in res]
    info["number"] = nres
    info["start"] = start
    info["count"] = count
    info["more"] = int(start + count < nres)
    info["field_pretty"] = field_pretty
    info["web_ainvs"] = web_ainvs
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count or start != 0:
            info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres)
        else:
            info["report"] = "displaying all %s matches" % nres
    t = "Elliptic Curve search results"
    return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
示例#10
0
文件: main.py 项目: paulhus/lmfdb
def local_field_search(**args):
    info = to_dict(args)
    bread = get_bread([("Search results", url_for('.search'))])
    C = base.getDBConnection()
    query = {}
    if 'jump_to' in info:
        return render_field_webpage({'label': info['jump_to']})

    for param in ['p', 'n', 'c', 'e', 'gal']:
        if info.get(param):
            info[param] = clean_input(info[param])
            if param == 'gal':
                try:
                    gcs = complete_group_codes(info[param])
                    if len(gcs) == 1:
                        tmp = ['gal', list(gcs[0])]
                    if len(gcs) > 1:
                        tmp = [{'gal': list(x)} for x in gcs]
                        tmp = ['$or', tmp]
                except NameError as code:
                    info['err'] = 'Error parsing input for Galois group: unknown group label %s.  It needs to be a <a title = "Galois group labels" knowl="nf.galois_group.name">group label</a>, such as C5 or 5T1, or comma separated list of labels.' % code
                    return search_input_error(info, bread)
            else:
                ran = info[param]
                ran = ran.replace('..', '-')
                if LIST_RE.match(ran):
                    tmp = parse_range2(ran, param)
                else:
                    names = {'p': 'prime p', 'n': 'degree', 'c':
                             'discriminant exponent c', 'e': 'ramification index e'}
                    info['err'] = 'Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[param]
                    return search_input_error(info, bread)
            # 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]

    count_default = 20
    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
    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    # logger.debug(query)
    res = C.localfields.fields.find(query).sort([('p', pymongo.ASCENDING), (
        'n', pymongo.ASCENDING), ('c', pymongo.ASCENDING), ('label', pymongo.ASCENDING)])
    nres = res.count()
    res = res.skip(start).limit(count)

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

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

    return render_template("lf-search.html", info=info, title="Local Number Field Search Result", bread=bread, credit=LF_credit)
示例#11
0
文件: main.py 项目: sfrechet/lmfdb
def elliptic_curve_search(**args):
    info = to_dict(args["data"])
    if "jump" in info:
        label = info.get("label", "").replace(" ", "")
        # This label should be a full isogeny class label or a full
        # curve label (including the field_label component)
        try:
            nf, cond_label, iso_label, number = split_full_label(label)
        except IndexError:
            if not "query" in info:
                info["query"] = {}
            bread = [("Elliptic Curves", url_for(".index"))]
            info["err"] = "No elliptic curve in the database has label %s." % label
            return search_input_error(info, bread)

        return show_ecnf(nf, cond_label, iso_label, number)

    query = {}
    bread = [("Elliptic Curves", url_for(".index")), ("Search Results", ".")]

    if "conductor_norm" in info:
        Nnorm = clean_input(info["conductor_norm"])
        Nnorm = Nnorm.replace("..", "-").replace(" ", "")
        tmp = parse_range2(Nnorm, "conductor_norm")
        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 "conductor_label" in info:
        query["conductor_label"] = info["conductor_label"]

    if "jinv" in info:
        query["jinv"] = info["jinv"]

    if info.get("torsion"):
        ran = info["torsion"] = clean_input(info["torsion"])
        ran = ran.replace("..", "-").replace(" ", "")
        if not LIST_RE.match(ran):
            info[
                "err"
            ] = "Error parsing input for the torsion order.  It needs to be an integer (such as 5), 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)."
            return search_input_error(info, bread)
        # Past input check
        tmp = parse_range2(ran, "torsion_order")
        # 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 "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"] = [int(r) for r in res]

    if "include_isogenous" in info and info["include_isogenous"] == "off":
        query["number"] = 1

    if "include_base_change" in info and info["include_base_change"] == "off":
        query["base_change"] = []
    else:
        info["include_base_change"] = "on"

    if "field" in info:
        query["field_label"] = parse_field_string(info["field"])

    info["query"] = query

    # process count and start if not default:

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

    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

    # make the query and trim results according to start/count:

    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if start >= nres:
        start -= (1 + (start - nres) / count) * count
    if start < 0:
        start = 0
    res = (
        cursor.sort(
            [
                ("field_label", ASC),
                ("conductor_norm", ASC),
                ("conductor_label", ASC),
                ("iso_label", ASC),
                ("number", ASC),
            ]
        )
        .skip(start)
        .limit(count)
    )

    res = list(res)
    for e in res:
        e["numb"] = str(e["number"])
        e["field_knowl"] = nf_display_knowl(e["field_label"], getDBConnection(), e["field_label"])

    info["curves"] = res  # [ECNF(e) for e in res]
    info["number"] = nres
    info["start"] = start
    info["count"] = count
    info["more"] = int(start + count < nres)
    info["field_pretty"] = field_pretty
    info["web_ainvs"] = web_ainvs
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count or start != 0:
            info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres)
        else:
            info["report"] = "displaying all %s matches" % nres
    t = "Elliptic Curve search results"
    return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
示例#12
0
文件: main.py 项目: elguindy/lmfdb
def elliptic_curve_search(**args):
    info = to_dict(args['data'])
    if 'jump' in info:
        label = info.get('label', '').replace(" ", "")
        label_parts = label.split("-",1)
        nf = label_parts[0]
        label = label_parts[1]
        return show_ecnf(nf,label)

    query = {}

    if 'conductor_norm' in info:
        Nnorm = clean_input(info['conductor_norm'])
        Nnorm = Nnorm.replace('..', '-').replace(' ', '')
        tmp = parse_range2(Nnorm, 'conductor_norm')
        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 'include_isogenous' in info and info['include_isogenous'] == 'off':
        query['number'] = 1

    if 'field' in info:
        query['field_label'] = info['field']

    info['query'] = query

# process count and start if not default:

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

    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

# make the query and trim results according to start/count:

    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0
    res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_label', ASC), ('number', ASC)]).skip(start).limit(count)

    bread = []#[('Elliptic Curves over Number Fields', url_for(".elliptic_curve_search")),             ]
    bread = [('Elliptic Curves', url_for(".index")),
             ('Search Results', '.')]

    res = list(res)
    for e in res:
        e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label'])
    info['curves'] = res # [ECNF(e) for e in res]
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['field_pretty'] = field_pretty
    info['web_ainvs'] = web_ainvs
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    t = 'Elliptic Curve search results'
    return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
示例#13
0
def elliptic_curve_search(**args):
    info = to_dict(args)
    query = {}
    bread = [("Elliptic Curves", url_for("rational_elliptic_curves")), ("Search Results", ".")]
    if "jump" in args:
        label = info.get("label", "").replace(" ", "")
        m = lmfdb_label_regex.match(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 = cremona_label_regex.match(label)
            if m:
                try:
                    return by_ec_label(label)
                except ValueError:
                    return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif cremona_label_regex.match(label):
            return elliptic_curve_jump_error(label, info, cremona_label=True)
        elif label:
            # Try to parse a string like [1,0,3,2,4]
            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)
                ainvs = [str(c) for c in E.minimal_model().ainvs()]
                C = lmfdb.base.getDBConnection()
                data = C.elliptic_curves.curves.find_one({"ainvs": ainvs})
                if data is None:
                    return elliptic_curve_jump_error(label, info)
                return by_ec_label(data["lmfdb_label"])
            except (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"] = j

    for field in ["conductor", "torsion", "rank", "sha_an"]:
        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_an": "analytic order of &#1064;",
                }
                info["err"] = (
                    "Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11)."
                    % 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
            if field == "sha_an":  # database sha_an values are not all exact!
                query[tmp[0]] = {"$gt": tmp[1] - 0.1, "$lt": tmp[1] + 0.1}
                print query
            else:
                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"]:
        info["torsion_structure"] = clean_input(info["torsion_structure"])
        if not TORS_RE.match(info["torsion_structure"]):
            info[
                "err"
            ] = "Error parsing input for the torsion structure.  It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4].  Moreover, each integer should be bigger than 1, and each divides the next."
            return search_input_error(info, bread)
        query["torsion_structure"] = [str(a) for a in parse_list(info["torsion_structure"])]

    info["query"] = query

    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

    print query
    cursor = lmfdb.base.getDBConnection().elliptic_curves.curves.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["number"] = nres
    info["start"] = start
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count or start != 0:
            info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres)
        else:
            info["report"] = "displaying all %s matches" % nres
    credit = "John Cremona"
    t = "Elliptic Curves"
    return render_template("elliptic_curve/elliptic_curve_search.html", info=info, credit=credit, bread=bread, title=t)
示例#14
0
def genus2_curve_search(**args):
    info = to_dict(args)
    query = {}  # database callable
    bread = [('Genus 2 Curves', url_for(".index")),
             ('$\Q$', url_for(".index_Q")),
             ('Search Results', '.')]
    #if 'SearchAgain' in args:
    #    return rational_genus2_curves()

    if 'jump' in args:
        return render_curve_webpage_by_label(info["jump"])

    if info.get("disc"):
        field = "abs_disc"
        ran = info["disc"]
        ran = ran.replace('..', '-').replace(' ','')
        # Past input check
        dlist = parse_discs(ran)
        tmp = g2_list_to_query(dlist)

        if len(tmp) == 1:
            tmp = tmp[0]
        else:
            query[tmp[0][0]] = tmp[0][1]
            tmp = tmp[1]

        print tmp

        # 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 info.get("is_gl2_type"):
       query['is_gl2_type']=bool(info['is_gl2_type'])    

    for fld in ['aut_grp', 'geom_aut_grp','st_group','real_geom_end_alg']:
        if info.get(fld):
            query[fld] = info[fld]
    for fld in ['aut_grp', 'geom_aut_grp']:
        if info.get(fld):
            query[fld] = eval(info[fld])

    if info.get("cond"):
        field = "cond"
        ran = str(info[field])
        ran = ran.replace('..', '-').replace(' ','')
        # Past input check
        tmp = parse_range2(ran, field)

        print tmp

        # 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 info.get("count"):
        try:
            count = int(info["count"])
        except:
            count = 100
    else:
        count = 100

    info["query"] = dict(query)
    #res = db_g2c().curves.find(query).sort([("cond", pymongo.ASCENDING),
    #("label", pymongo.ASCENDING)]).limit(count)
    res = db_g2c().curves.find(query).sort([("cond", pymongo.ASCENDING),
                                            ("class", pymongo.ASCENDING),
                                            ("disc_key", pymongo.ASCENDING),
                                            ("label", pymongo.ASCENDING)])
    nres = res.count()
    if nres == 1:
        info["report"] = "unique match"
    else:
        if nres > count:
            info["report"] = "displaying first %s of %s matches" % (count, nres)
        else:
            info["report"] = "displaying all %s matches" % nres
    res_clean = []
    
    
    for v in res:
        v_clean = {}
        v_clean["label"] = v["label"]
        v_clean["isog_label"] = v["class"]
        isogeny_class = db_g2c().isogeny_classes.find_one({'label' : isog_label(v["label"])})
        v_clean["is_gl2_type"] = isogeny_class["is_gl2_type"]
        v_clean["equation_formatted"] = list_to_min_eqn(v["min_eqn"])
        res_clean.append(v_clean)

    info["curves"] = res_clean

    info["curve_url"] = lambda dbc: url_for_label(dbc['label'])
    info["isog_url"] = lambda dbc: isog_url_for_label(dbc['label'])
    credit = 'Genus 2 Team'
    title = 'Genus 2 Curves search results'
    return render_template("search_results_g2.html", info=info, credit=credit, bread=bread, title=title)
示例#15
0
文件: main.py 项目: sibilant/lmfdb
def elliptic_curve_search(**args):
    info = to_dict(args['data'])
    if 'jump' in info:
        label = info.get('label', '').replace(" ", "")
        # This label should be a full isogeny class label or a full
        # curve label (including the field_label component)
        try:
            nf, cond_label, iso_label, number = split_full_label(label)
        except IndexError:
            if not 'query' in info:
                info['query'] = {}
            bread = [("Elliptic Curves", url_for(".index"))]
            info['err'] = 'No elliptic curve in the database has label %s.' % label
            return search_input_error(info, bread)

        return show_ecnf(nf, cond_label, iso_label, number)

    query = {}
    bread = [('Elliptic Curves', url_for(".index")),
             ('Search Results', '.')]

    if 'conductor_norm' in info:
        Nnorm = clean_input(info['conductor_norm'])
        Nnorm = Nnorm.replace('..', '-').replace(' ', '')
        tmp = parse_range2(Nnorm, 'conductor_norm')
        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 'conductor_label' in info:
        query['conductor_label'] = info['conductor_label']

    if 'jinv' in info:
        query['jinv'] = info['jinv']

    if info.get('torsion'):
        ran = info['torsion'] = clean_input(info['torsion'])
        ran = ran.replace('..', '-').replace(' ', '')
        if not LIST_RE.match(ran):
            info['err'] = 'Error parsing input for the torsion order.  It needs to be an integer (such as 5), 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).'
            return search_input_error(info, bread)
        # Past input check
        tmp = parse_range2(ran, 'torsion_order')
        # 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 'torsion_structure' in info and info['torsion_structure']:
        info['torsion_structure'] = clean_input(info['torsion_structure'])
        if not TORS_RE.match(info['torsion_structure']):
            info['err'] = 'Error parsing input for the torsion structure.  It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4].  Moreover, each integer should be bigger than 1, and each divides the next.'
            return search_input_error(info, bread)
        query['torsion_structure'] = parse_list(info['torsion_structure'])

    if 'include_isogenous' in info and info['include_isogenous'] == 'off':
        query['number'] = 1

    if 'include_base_change' in info and info['include_base_change'] == 'off':
        query['base_change'] = []
    else:
        info['include_base_change'] = "on"

    if 'field' in info:
        query['field_label'] = parse_field_string(info['field'])

    info['query'] = query

# process count and start if not default:

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

    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

# make the query and trim results according to start/count:

    cursor = db_ecnf().find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0
    res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_label', ASC), ('number', ASC)]).skip(start).limit(count)

    res = list(res)
    for e in res:
        e['numb'] = str(e['number'])
        e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label'])

    info['curves'] = res  # [ECNF(e) for e in res]
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)
    info['field_pretty'] = field_pretty
    info['web_ainvs'] = web_ainvs
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    t = 'Elliptic Curve search results'
    return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
示例#16
0
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 &#1064;'}
                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)
示例#17
0
def elliptic_curve_search(**args):
    info = to_dict(args)
    query = {}
    bread = [('Elliptic Curves', url_for("rational_elliptic_curves")),
             ('Search Results', '.')]
    if 'jump' in args:
        label = info.get('label', '').replace(" ", "")
        m = lmfdb_label_regex.match(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 = cremona_label_regex.match(label)
            if m:
                try:
                    return by_ec_label(label)
                except ValueError:
                    return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif cremona_label_regex.match(label):
            return elliptic_curve_jump_error(label, info, cremona_label=True)
        elif label:
            # Try to parse a string like [1,0,3,2,4]
            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)
                ainvs = [str(c) for c in E.minimal_model().ainvs()]
                C = lmfdb.base.getDBConnection()
                data = C.elliptic_curves.curves.find_one({'ainvs': ainvs})
                if data is None:
                    return elliptic_curve_jump_error(label, info)
                return by_ec_label(data['lmfdb_label'])
            except (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'] = j

    for field in ['conductor', 'torsion', 'rank', 'sha_an']:
        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_an': 'analytic order of &#1064;'}
                info['err'] = 'Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % 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]
#            query[field] = parse_range2(info[field])

    if 'optimal' in info and info['optimal'] == 'on':
        # fails on 990h3
        query['number'] = 1

    if 'torsion_structure' in info and info['torsion_structure']:
        info['torsion_structure'] = clean_input(info['torsion_structure'])
        if not TORS_RE.match(info['torsion_structure']):
            info['err'] = 'Error parsing input for the torsion structure.  It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4].  Moreover, each integer should be bigger than 1, and each divides the next.'
            return search_input_error(info, bread)
        query['torsion_structure'] = [str(a) for a in parse_list(info['torsion_structure'])]

    info['query'] = query

    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

    print query
    cursor = lmfdb.base.getDBConnection().elliptic_curves.curves.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['number'] = nres
    info['start'] = start
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    credit = 'John Cremona'
    t = 'Elliptic Curves'
    return render_template("elliptic_curve/elliptic_curve_search.html", info=info, credit=credit, bread=bread, title=t)
示例#18
0
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 &#1064;'}
                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)
示例#19
0
def hgm_search(**args):
    info = to_dict(args)
    bread = get_bread([("Search results", url_for('.search'))])
    C = base.getDBConnection()
    query = {}
    if 'jump_to' in info:
        return render_hgm_webpage({'label': info['jump_to']})

    family_search = False
    if info.get('Submit Family') or info.get('family'):
        family_search = True

    # generic, irreducible not in DB yet
    for param in [
            'A', 'B', 'hodge', 'a2', 'b2', 'a3', 'b3', 'a5', 'b5', 'a7', 'b7'
    ]:
        if info.get(param):
            info[param] = clean_input(info[param])
            if IF_RE.match(info[param]):
                query[param] = parse_list(info[param])
                query[param].sort()
            else:
                name = param
                if field == 'hodge':
                    name = 'Hodge vector'
                info[
                    'err'] = 'Error parsing input for %s.  It needs to be a list of integers in square brackets, such as [2,3] or [1,1,1]' % name
                return search_input_error(info, bread)

    if info.get('t') and not family_search:
        info['t'] = clean_input(info['t'])
        try:
            tsage = QQ(str(info['t']))
            tlist = [int(tsage.numerator()), int(tsage.denominator())]
            query['t'] = tlist
        except:
            info[
                'err'] = 'Error parsing input for t.  It needs to be a rational number, such as 2/3 or -3'

    # sign can only be 1, -1, +1
    if info.get('sign') and not family_search:
        sign = info['sign']
        sign = re.sub(r'\s', '', sign)
        sign = clean_input(sign)
        if sign == '+1':
            sign = '1'
        if not (sign == '1' or sign == '-1'):
            info[
                'err'] = 'Error parsing input %s for sign.  It needs to be 1 or -1' % sign
            return search_input_error(info, bread)
        query['sign'] = int(sign)

    for param in ['degree', 'weight', 'conductor']:
        # We don't look at conductor in family searches
        if info.get(param) and not (param == 'conductor' and family_search):
            if param == 'conductor':
                cond = info['conductor']
                try:
                    cond = re.sub(r'(\d)\s+(\d)', r'\1 * \2',
                                  cond)  # implicit multiplication of numbers
                    cond = cond.replace(r'..', r'-')  # all ranges use -
                    cond = re.sub(r'[a..zA..Z]', '', cond)
                    cond = clean_input(cond)
                    tmp = parse_range2(cond, 'cond', myZZ)
                except:
                    info[
                        'err'] = 'Error parsing input for conductor.  It needs to be an integer (e.g., 8), a range of integers (e.g. 10-100), or a list of such (e.g., 5,7,8,10-100).  Integers may be given in factored form (e.g. 2^5 3^2) %s' % cond
                    return search_input_error(info, bread)
            else:  # not conductor
                info[param] = clean_input(info[param])
                ran = info[param]
                ran = ran.replace(r'..', r'-')
                if LIST_RE.match(ran):
                    tmp = parse_range2(ran, param)
                else:
                    names = {'weight': 'weight', 'degree': 'degree'}
                    info[
                        'err'] = 'Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[
                            param]
                    return search_input_error(info, bread)
            # 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]

    #print query
    count_default = 20
    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
    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    # logger.debug(query)
    if family_search:
        res = C.hgm.families.find(query).sort([('label', pymongo.ASCENDING)])
    else:
        res = C.hgm.motives.find(query).sort([('cond', pymongo.ASCENDING),
                                              ('label', pymongo.ASCENDING)])
    nres = res.count()
    res = res.skip(start).limit(count)

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

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

    if family_search:
        return render_template(
            "hgm-search.html",
            info=info,
            title="Hypergeometric Family over $\Q$ Search Result",
            bread=bread,
            credit=HGM_credit)
    else:
        return render_template(
            "hgm-search.html",
            info=info,
            title="Hypergeometric Motive over $\Q$ Search Result",
            bread=bread,
            credit=HGM_credit)
示例#20
0
文件: main.py 项目: am-github/lmfdb
def galois_group_search(**args):
    info = to_dict(args)
    bread = get_bread([("Search results", url_for('.search'))])
    C = base.getDBConnection()
    query = {}
    if 'jump_to' in info:
        return render_group_webpage({'label': info['jump_to']})

    for param in ['n', 't']:
        if info.get(param):
            info[param] = clean_input(info[param])
            ran = info[param]
            ran = ran.replace('..', '-')
            if LIST_RE.match(ran):
                tmp = parse_range2(ran, param)
            else:
                names = {'n': 'degree', 't': 't'}
                info['err'] = 'Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[param]
                return search_input_error(info, bread)
            # 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]
    for param in ['cyc', 'solv', 'prim', 'parity']:
        if info.get(param):
            info[param] = str(info[param])
            if info[param] == str(1):
                query[param] = 1
            elif info[param] == str(-1):
                query[param] = -1 if param == 'parity' else 0

    # Determine if we have any composite degrees
    info['show_subs'] = True
    if info.get('n'):
        info['show_subs'] = False  # now only show subs if a composite n is allowed
        nparam = info.get('n')
        nparam.replace('..', '-')
        nlist = nparam.split(',')
        found = False
        for nl in nlist:
            if '-' in nl:
                inx = nl.index('-')
                ll, hh = nl[:inx], nl[inx + 1:]
                hh = int(hh)
                jj = int(ll)
                while jj <= hh and not found:
                    if not(ZZ(jj).is_prime() or ZZ(jj) == 1):
                        found = True
                    jj += 1
                if found:
                    break
            else:
                jj = ZZ(nl)
                if not (ZZ(jj).is_prime() or ZZ(jj) == 1):
                    found = True
                    break
        if found:
            info['show_subs'] = True

    count_default = 50
    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
    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    res = C.transitivegroups.groups.find(query).sort([('n', pymongo.ASCENDING), ('t', pymongo.ASCENDING)])
    nres = res.count()
    res = res.skip(start).limit(count)

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

    info['groups'] = res
    info['group_display'] = group_display_prettyC(C)
    info['report'] = "found %s groups" % nres
    info['yesno'] = yesno
    info['wgg'] = WebGaloisGroup.from_data
    info['start'] = start
    info['number'] = nres
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres

    return render_template("gg-search.html", info=info, title="Galois Group Search Result", bread=bread, credit=GG_credit)
示例#21
0
def number_field_search(**args):
    info = to_dict(args)

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

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

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


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

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

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

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

    fields = C.numberfields.fields

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

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

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

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

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

    info['wnf'] = WebNumberField.from_data
    return render_template("number_field_search.html",
                           info=info,
                           title=t,
                           bread=bread)
示例#22
0
def elliptic_curve_search(**args):
    info = to_dict(args)
    query = {}
    bread = [('Elliptic Curves', url_for(".rational_elliptic_curves")),
             ('Search Results', '.')]
    if 'jump' in args:
        label = info.get('label', '').replace(" ", "")
        m = lmfdb_label_regex.match(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 = cremona_label_regex.match(label)
            if m:
                try:
                    return by_ec_label(label)
                except ValueError:
                    return elliptic_curve_jump_error(label,
                                                     info,
                                                     wellformed_label=True)
        elif cremona_label_regex.match(label):
            return elliptic_curve_jump_error(label, info, cremona_label=True)
        elif label:
            # Try to parse a string like [1,0,3,2,4]
            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)
                ainvs = [str(c) for c in E.minimal_model().ainvs()]
                C = lmfdb.base.getDBConnection()
                data = C.elliptic_curves.curves.find_one({'ainvs': ainvs})
                if data is None:
                    return elliptic_curve_jump_error(label, info)
                return by_ec_label(data['lmfdb_label'])
            except (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'] = j

    for field in ['conductor', 'torsion', 'rank', 'sha_an']:
        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_an': 'analytic order of &#1064;'
                }
                info[
                    'err'] = 'Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % 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
            if field == 'sha_an':  # database sha_an values are not all exact!
                query[tmp[0]] = {'$gt': tmp[1] - 0.1, '$lt': tmp[1] + 0.1}
            else:
                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']:
        info['torsion_structure'] = clean_input(info['torsion_structure'])
        if not TORS_RE.match(info['torsion_structure']):
            info[
                'err'] = 'Error parsing input for the torsion structure.  It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4].  Moreover, each integer should be bigger than 1, and each divides the next.'
            return search_input_error(info, bread)
        query['torsion_structure'] = [
            str(a) for a in parse_list(info['torsion_structure'])
        ]

    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)

    info['query'] = query

    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 = lmfdb.base.getDBConnection().elliptic_curves.curves.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['number'] = nres
    info['start'] = start
    if nres == 1:
        info['report'] = 'unique match'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (
                start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    credit = 'John Cremona'
    if 'non-surjective_primes' in query:
        credit += 'and Andrew Sutherland'
    t = 'Elliptic Curves'
    return render_template("search_results.html",
                           info=info,
                           credit=credit,
                           bread=bread,
                           title=t)
示例#23
0
文件: main.py 项目: WarrenMoore/lmfdb
def hgm_search(**args):
    info = to_dict(args)
    bread = get_bread([("Search results", url_for('.search'))])
    C = base.getDBConnection()
    query = {}
    if 'jump_to' in info:
        return render_hgm_webpage({'label': info['jump_to']})

    family_search = False
    if info.get('Submit Family') or info.get('family'):
        family_search = True

    # generic, irreducible not in DB yet
    for param in ['A', 'B', 'hodge', 'a2', 'b2', 'a3', 'b3', 'a5', 'b5', 'a7', 'b7']:
        if info.get(param):
            info[param] = clean_input(info[param])
            if IF_RE.match(info[param]):
                query[param] = parse_list(info[param])
                query[param].sort()
            else:
                name = param
                if field == 'hodge':
                    name = 'Hodge vector'
                info['err'] = 'Error parsing input for %s.  It needs to be a list of integers in square brackets, such as [2,3] or [1,1,1]' % name
                return search_input_error(info, bread)

    if info.get('t') and not family_search:
        info['t'] = clean_input(info['t'])
        try:
            tsage = QQ(str(info['t']))
            tlist = [int(tsage.numerator()), int(tsage.denominator())]
            query['t'] = tlist
        except:
            info['err'] = 'Error parsing input for t.  It needs to be a rational number, such as 2/3 or -3'

    # sign can only be 1, -1, +1
    if info.get('sign') and not family_search:
        sign = info['sign']
        sign = re.sub(r'\s','',sign)
        sign = clean_input(sign)
        if sign == '+1':
            sign = '1'
        if not (sign == '1' or sign == '-1'):
            info['err'] = 'Error parsing input %s for sign.  It needs to be 1 or -1' % sign
            return search_input_error(info, bread)
        query['sign'] = int(sign)


    for param in ['degree','weight','conductor']:
        # We don't look at conductor in family searches
        if info.get(param) and not (param=='conductor' and family_search):
            if param=='conductor':
                cond = info['conductor']
                try:
                    cond = re.sub(r'(\d)\s+(\d)', r'\1 * \2', cond) # implicit multiplication of numbers
                    cond = cond.replace(r'..', r'-') # all ranges use -
                    cond = re.sub(r'[a..zA..Z]', '', cond)
                    cond = clean_input(cond)
                    tmp = parse_range2(cond, 'cond', myZZ)
                except:
                    info['err'] = 'Error parsing input for conductor.  It needs to be an integer (e.g., 8), a range of integers (e.g. 10-100), or a list of such (e.g., 5,7,8,10-100).  Integers may be given in factored form (e.g. 2^5 3^2) %s' % cond
                    return search_input_error(info, bread)
            else: # not conductor
                info[param] = clean_input(info[param])
                ran = info[param]
                ran = ran.replace(r'..', r'-')
                if LIST_RE.match(ran):
                    tmp = parse_range2(ran, param)
                else:
                    names = {'weight': 'weight', 'degree': 'degree'}
                    info['err'] = 'Error parsing input for the %s.  It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[param]
                    return search_input_error(info, bread)
            # 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]

    #print query
    count_default = 20
    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
    if info.get('paging'):
        try:
            paging = int(info['paging'])
            if paging == 0:
                start = 0
        except:
            pass

    # logger.debug(query)
    if family_search:
        res = C.hgm.families.find(query).sort([('label', pymongo.ASCENDING)])
    else:
        res = C.hgm.motives.find(query).sort([('cond', pymongo.ASCENDING), ('label', pymongo.ASCENDING)])
    nres = res.count()
    res = res.skip(start).limit(count)

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

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

    if family_search:
        return render_template("hgm-search.html", info=info, title="Hypergeometric Family over $\Q$ Search Result", bread=bread, credit=HGM_credit)
    else:
        return render_template("hgm-search.html", info=info, title="Hypergeometric Motive over $\Q$ Search Result", bread=bread, credit=HGM_credit)