Example #1
0
def elliptic_curve_search(info, query):
    parse_rational(info, query, 'jinv', 'j-invariant')
    parse_ints(info, query, 'conductor')
    parse_ints(info, query, 'torsion', 'torsion order')
    parse_ints(info, query, 'rank')
    parse_ints(info, query, 'sha', 'analytic order of Ш')
    parse_bracketed_posints(info,
                            query,
                            'torsion_structure',
                            maxlength=2,
                            check_divisibility='increasing')
    # speed up slow torsion_structure searches by also setting torsion
    #if 'torsion_structure' in query and not 'torsion' in query:
    #    query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
    if 'include_cm' in info:
        if info['include_cm'] == 'exclude':
            query['cm'] = 0
        elif info['include_cm'] == 'only':
            query['cm'] = {'$ne': 0}
    parse_element_of(info,
                     query,
                     field='isodeg',
                     qfield='isogeny_degrees',
                     split_interval=1000)
    #parse_ints(info,query,field='isodeg',qfield='isogeny_degrees')
    parse_primes(info,
                 query,
                 'surj_primes',
                 name='maximal primes',
                 qfield='nonmax_primes',
                 mode='complement')
    if info.get('surj_quantifier') == 'exactly':
        mode = 'exact'
    else:
        mode = 'append'
    parse_primes(info,
                 query,
                 'nonsurj_primes',
                 name='non-maximal primes',
                 qfield='nonmax_primes',
                 mode=mode,
                 radical='nonmax_rad')
    if 'optimal' in info and info['optimal'] == 'on':
        # fails on 990h3
        query['number'] = 1

    info['curve_url'] = lambda dbc: url_for(".by_triple_label",
                                            conductor=dbc['conductor'],
                                            iso_label=split_lmfdb_label(dbc[
                                                'lmfdb_iso'])[1],
                                            number=dbc['lmfdb_number'])
    info['iso_url'] = lambda dbc: url_for(".by_double_iso_label",
                                          conductor=dbc['conductor'],
                                          iso_label=split_lmfdb_label(dbc[
                                              'lmfdb_iso'])[1])
Example #2
0
def random_curve():
    label = db.ec_curvedata.random(projection='lmfdb_label')
    cond, iso, num = split_lmfdb_label(label)
    return url_for(".by_triple_label",
                   conductor=cond,
                   iso_label=iso,
                   number=num)
Example #3
0
    def by_label(label):
        """
        Searches for a specific elliptic curve isogeny class in the
        curves collection by its label, which can be either a curve
        label (e.g. "11.a1") or a class label (e.g. "11.a") in either
        LMFDB or Cremona format.
        """
        #print "label = %s" % label
        try:
            N, iso, number = split_lmfdb_label(label)
            if number:
                data = db_ec().find_one({"lmfdb_label" : label})
            else:
                data = db_ec().find_one({"lmfdb_label" : label+"1"})
        except AttributeError:
            try:
                N, iso, number = split_cremona_label(label)
                if number:
                    data = db_ec().find_one({"label" : label})
                else:
                    data = db_ec().find_one({"label" : label+"1"})
            except AttributeError:
                return "Invalid label" # caller must catch this and raise an error

        if data:
            return ECisog_class(data)
        return "Class not found" # caller must catch this and raise an error
Example #4
0
def download_EC_all(label):
    try:
        N, iso, number = split_lmfdb_label(label)
    except (ValueError,AttributeError):
        return elliptic_curve_jump_error(label, {})
    CDB = db_ec()
    if number:
        data = CDB.find_one({'lmfdb_label': label})
        if data is None:
            return elliptic_curve_jump_error(label, {})
        data_list = [data]
    else:
        data_list = sorted(list(CDB.find({'lmfdb_iso': label})), key=lambda E: E['number'])
        if len(data_list) == 0:
            return elliptic_curve_jump_error(label, {})

    # For each curve we will output all data fields except the '_id':
    # (This should also be possible by adding projection={'_id':False}
    # to the find() call but on testing that timed out.)
    for data in data_list:
        data.pop('_id')

    import json
    response = make_response('\n\n'.join(json.dumps(d) for d in data_list))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #5
0
def url_for_ec_class(ec_label):
    if not '-' in ec_label:
        (cond, iso, num) = split_lmfdb_label(ec_label)
        return url_for('ec.by_double_iso_label', conductor=cond, iso_label=iso)
    else:
        (nf, cond, iso, num) = split_full_label(ec_label)
        return url_for('ecnf.show_ecnf_isoclass', nf=nf, conductor_label=cond, class_label=iso)
Example #6
0
def padic_data():
    info = {}
    label = request.args['label']
    p = int(request.args['p'])
    info['p'] = p
    print "label = %s; p = %s" % (label,p)
    N, iso, number = split_lmfdb_label(label)
    # print N, iso, number
    if request.args['rank'] == '0':
        info['reg'] = 1
    elif number == '1':
        C = lmfdb.base.getDBConnection()
        data = C.elliptic_curves.curves.find_one({'lmfdb_iso': N + '.' + iso})
        data = C.elliptic_curves.padic_db.find_one({'lmfdb_iso': N + '.' + iso, 'p': p})
        info['data'] = data
        if data is None:
            info['reg'] = 'no data'
        else:
            val = int(data['val'])
            aprec = data['prec']
            reg = sage.all.Qp(p, aprec)(int(data['unit']), aprec - val) << val
            info['reg'] = web_latex(reg)
    else:
        info['reg'] = "no data"
    return render_template("padic_data.html", info=info)
Example #7
0
def by_ec_label(label):
    ec_logger.debug(label)
    try:
        N, iso, number = split_lmfdb_label(label)
    except AttributeError:
        ec_logger.debug("%s not a valid lmfdb label, trying cremona")
        try:
            N, iso, number = split_cremona_label(label)
        except AttributeError:
            ec_logger.debug("%s not a valid cremona label either, trying Weierstrass")
            eqn = label.replace(" ","")
            if weierstrass_eqn_regex.match(eqn) or short_weierstrass_eqn_regex.match(eqn):
                return by_weierstrass(eqn)
            else:
                return elliptic_curve_jump_error(label, {})

        # We permanently redirect to the lmfdb label
        if number:
            data = db_ec().find_one({'label': label})
            if data is None:
                return elliptic_curve_jump_error(label, {})
            ec_logger.debug(url_for(".by_ec_label", label=data['lmfdb_label']))
            return redirect(url_for(".by_ec_label", label=data['lmfdb_label']), 301)
        else:
            data = db_ec().find_one({'iso': label})
            if data is None:
                return elliptic_curve_jump_error(label, {})
            ec_logger.debug(url_for(".by_ec_label", label=data['lmfdb_label']))
            return redirect(url_for(".by_ec_label", label=data['lmfdb_iso']), 301)
    if number:
        return redirect(url_for(".by_triple_label", conductor=N, iso_label=iso, number=number))
    else:
        return redirect(url_for(".by_double_iso_label", conductor=N, iso_label=iso))
Example #8
0
    def by_label(label):
        """
        Searches for a specific elliptic curve isogeny class in the
        curves collection by its label, which can be either a curve
        label (e.g. "11.a1") or a class label (e.g. "11.a") in either
        LMFDB or Cremona format.
        """
        try:
            N, iso, number = split_lmfdb_label(label)
            if number:
                label = ".".join([N,iso])
            data = db.ec_curves.lucky({"lmfdb_iso" : label, 'number':1})
            data['label_type'] = 'LMFDB'
        except AttributeError:
            try:
                N, iso, number = split_cremona_label(label)
                if number:
                    label = "".join([N,iso])
                data = db.ec_curves.lucky({"iso" : label, 'number':1})
                data['label_type'] = 'Cremona'
            except AttributeError:
                return "Invalid label" # caller must catch this and raise an error

        if data:
            return ECisog_class(data)
        return "Class not found" # caller must catch this and raise an error
Example #9
0
    def by_label(label):
        """
        Searches for a specific elliptic curve isogeny class in the
        curves collection by its label, which can be either a curve
        label (e.g. "11.a1") or a class label (e.g. "11.a") in either
        LMFDB or Cremona format.
        """
        try:
            N, iso, number = split_lmfdb_label(label)
            if number:
                label = ".".join([N, iso])
            data = db.ec_curves.lucky({"lmfdb_iso": label, 'number': 1})
            data['label_type'] = 'LMFDB'
        except AttributeError:
            try:
                N, iso, number = split_cremona_label(label)
                if number:
                    label = "".join([N, iso])
                data = db.ec_curves.lucky({"iso": label, 'number': 1})
                data['label_type'] = 'Cremona'
            except AttributeError:
                return "Invalid label"  # caller must catch this and raise an error

        if data:
            return ECisog_class(data)
        return "Class not found"  # caller must catch this and raise an error
Example #10
0
    def by_label(label):
        """
        Searches for a specific elliptic curve isogeny class in the
        curves collection by its label, which can be either a curve
        label (e.g. "11.a1") or a class label (e.g. "11.a") in either
        LMFDB or Cremona format.
        """
        #print "label = %s" % label
        try:
            N, iso, number = split_lmfdb_label(label)
            if number:
                data = db_ec().find_one({"lmfdb_label": label})
            else:
                data = db_ec().find_one({"lmfdb_label": label + "1"})
        except AttributeError:
            try:
                N, iso, number = split_cremona_label(label)
                if number:
                    data = db_ec().find_one({"label": label})
                else:
                    data = db_ec().find_one({"label": label + "1"})
            except AttributeError:
                return "Invalid label"  # caller must catch this and raise an error

        if data:
            return ECisog_class(data)
        return "Class not found"  # caller must catch this and raise an error
Example #11
0
def url_for_ec_class(ec_label):
    if not '-' in ec_label:
        (cond, iso, num) = split_lmfdb_label(ec_label)
        return url_for('ec.by_double_iso_label', conductor=cond, iso_label=iso)
    else:
        (nf, cond, iso, num) = split_full_label(ec_label)
        return url_for('ecnf.show_ecnf_isoclass', nf=nf, conductor_label=cond, class_label=iso)
Example #12
0
def padic_data():
    info = {}
    label = request.args['label']
    p = int(request.args['p'])
    info['p'] = p
    N, iso, number = split_lmfdb_label(label)
    if request.args['rank'] == '0':
        info['reg'] = 1
    elif number == '1':
        C = lmfdb.base.getDBConnection()
        data = C.elliptic_curves.curves.find_one({'lmfdb_iso': N + '.' + iso})
        data = C.elliptic_curves.padic_db.find_one({
            'lmfdb_iso': N + '.' + iso,
            'p': p
        })
        info['data'] = data
        if data is None:
            info['reg'] = 'no data'
        else:
            val = int(data['val'])
            aprec = data['prec']
            reg = sage.all.Qp(p, aprec)(int(data['unit']), aprec - val) << val
            info['reg'] = web_latex(reg)
    else:
        info['reg'] = "no data"
    return render_template("ec-padic-data.html", info=info)
Example #13
0
def download_EC_all(label):
    try:
        N, iso, number = split_lmfdb_label(label)
    except (ValueError,AttributeError):
        return elliptic_curve_jump_error(label, {})
    CDB = db_ec()
    if number:
        data = CDB.find_one({'lmfdb_label': label})
        if data is None:
            return elliptic_curve_jump_error(label, {})
        data_list = [data]
    else:
        data_list = sorted(list(CDB.find({'lmfdb_iso': label})), key=lambda E: E['number'])
        if len(data_list) == 0:
            return elliptic_curve_jump_error(label, {})

    # For each curve we will output all data fields except the '_id':
    # (This should also be possible by adding projection={'_id':False}
    # to the find() call but on testing that timed out.)
    for data in data_list:
        data.pop('_id')

    import json
    response = make_response('\n\n'.join(json.dumps(d) for d in data_list))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #14
0
def download_EC_qexp(label, limit):
    N, iso, number = split_lmfdb_label(label)
    if number:
        ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label')
    else:
        ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_iso')
    E = EllipticCurve(ainvs)
    response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True)))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #15
0
def download_EC_qexp(label, limit):
    N, iso, number = split_lmfdb_label(label)
    if number:
        ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_label')
    else:
        ainvs = db.ec_curves.lookup(label, 'ainvs', 'lmfdb_iso')
    E = EllipticCurve(ainvs)
    response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True)))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #16
0
def download_EC_qexp(label, limit):
    CDB = db_ec()
    N, iso, number = split_lmfdb_label(label)
    if number:
        data = CDB.find_one({'lmfdb_label': label})
    else:
        data = CDB.find_one({'lmfdb_iso': label})
    E = EllipticCurve(parse_ainvs(data['ainvs']))
    response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True)))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #17
0
def download_EC_qexp(label, limit):
    CDB = db_ec()
    N, iso, number = split_lmfdb_label(label)
    if number:
        data = CDB.find_one({'lmfdb_label': label})
    else:
        data = CDB.find_one({'lmfdb_iso': label})
    E = EllipticCurve(parse_ainvs(data['ainvs']))
    response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True)))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #18
0
def EC_data(label):
    bread = get_bread([(label, url_for_label(label)), ("Data", " ")])
    if match_lmfdb_label(label):
        conductor, iso_class, number = split_lmfdb_label(label)
        if not number: # isogeny class
            return datapage(label, ["ec_classdata", "ec_padic"], bread=bread, label_col="lmfdb_iso", sorts=[[], ["p"]])
        iso_label = class_lmfdb_label(conductor, iso_class)
        labels = [label] * 8
        label_cols = ["lmfdb_label"] * 8
        labels[1] = labels[7] = iso_label
        label_cols[1] = label_cols[7] = "lmfdb_iso"
        sorts = [[], [], [], [], ["degree", "field"], ["prime"], ["prime"], ["p"]]
        return datapage(labels, ["ec_curvedata", "ec_classdata", "ec_mwbsd", "ec_iwasawa", "ec_torsion_growth", "ec_localdata", "ec_galrep", "ec_padic"], title=f"Elliptic curve data - {label}", bread=bread, label_cols=label_cols, sorts=sorts)
    return abort(404, f"Invalid label {label}")
Example #19
0
def by_ec_label(label):
    ec_logger.debug(label)

    # First see if we have an LMFDB label of a curve or class:
    try:
        N, iso, number = split_lmfdb_label(label)
        if number:
            return redirect(
                url_for(".by_triple_label",
                        conductor=N,
                        iso_label=iso,
                        number=number))
        else:
            return redirect(
                url_for(".by_double_iso_label", conductor=N, iso_label=iso))

    except AttributeError:
        ec_logger.debug("%s not a valid lmfdb label, trying cremona")
        # Next see if we have a Cremona label of a curve or class:
        try:
            N, iso, number = split_cremona_label(label)
        except AttributeError:
            ec_logger.debug(
                "%s not a valid cremona label either, trying Weierstrass")
            eqn = label.replace(" ", "")
            if weierstrass_eqn_regex.match(
                    eqn) or short_weierstrass_eqn_regex.match(eqn):
                return by_weierstrass(eqn)
            else:
                return elliptic_curve_jump_error(label, {})

        if number:  # it's a curve
            label_type = 'label'
        else:
            label_type = 'iso'

        data = db_ec().find_one({label_type: label})
        if data is None:
            return elliptic_curve_jump_error(label, {})
        ec_logger.debug(url_for(".by_ec_label", label=data['lmfdb_label']))
        iso = data['lmfdb_iso'].split(".")[1]
        if number:
            return redirect(
                url_for(".by_triple_label",
                        conductor=N,
                        iso_label=iso,
                        number=data['lmfdb_number']))
        else:
            return redirect(
                url_for(".by_double_iso_label", conductor=N, iso_label=iso))
Example #20
0
def download_EC_qexp(label, limit):
    ec_logger.debug(label)
    CDB = lmfdb.base.getDBConnection().elliptic_curves.curves
    N, iso, number = split_lmfdb_label(label)
    if number:
        data = CDB.find_one({'lmfdb_label': label})
    else:
        data = CDB.find_one({'lmfdb_iso': label})
    ainvs = data['ainvs']
    ec_logger.debug(ainvs)
    E = EllipticCurve([int(a) for a in ainvs])
    response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True)))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #21
0
def download_EC_qexp(label, limit):
    ec_logger.debug(label)
    CDB = lmfdb.base.getDBConnection().elliptic_curves.curves
    N, iso, number = split_lmfdb_label(label)
    if number:
        data = CDB.find_one({'lmfdb_label': label})
    else:
        data = CDB.find_one({'lmfdb_iso': label})
    ainvs = data['ainvs']
    ec_logger.debug(ainvs)
    E = EllipticCurve([int(a) for a in ainvs])
    response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True)))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #22
0
def download_EC_qexp(label, limit):
    try:
        N, iso, number = split_lmfdb_label(label)
    except (ValueError,AttributeError):
        return elliptic_curve_jump_error(label, {})
    if number:
        ainvs = db.ec_curvedata.lookup(label, 'ainvs', 'lmfdb_label')
    else:
        ainvs = db.ec_curvedata.lookup(label, 'ainvs', 'lmfdb_iso')
    if ainvs is None:
        return elliptic_curve_jump_error(label, {})        
    if limit > 100000:
        return redirect(url_for('.download_EC_qexp',label=label,limit=10000), 301)
    E = EllipticCurve(ainvs)
    response = make_response(','.join(str(an) for an in E.anlist(int(limit), python_ints=True)))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #23
0
def download_EC_all(label):
    try:
        N, iso, number = split_lmfdb_label(label)
    except (ValueError,AttributeError):
        return elliptic_curve_jump_error(label, {})
    if number:
        data = db.ec_curves.lookup(label, label_col='lmfdb_label')
        if data is None:
            return elliptic_curve_jump_error(label, {})
        data_list = [data]
    else:
        data_list = list(db.ec_curves.search({'lmfdb_iso': label}, projection=2, sort=['number']))
        if len(data_list) == 0:
            return elliptic_curve_jump_error(label, {})

    response = make_response('\n\n'.join(Json.dumps(d) for d in data_list))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #24
0
def download_EC_all(label):
    try:
        N, iso, number = split_lmfdb_label(label)
    except (ValueError,AttributeError):
        return elliptic_curve_jump_error(label, {})
    if number:
        data = db.ec_curvedata.lookup(label, label_col='lmfdb_label')
        if data is None:
            return elliptic_curve_jump_error(label, {})
        data_list = [data]
    else:
        data_list = list(db.ec_curvedata.search({'lmfdb_iso': label}, sort=['lmfdb_number']))
        if not data_list:
            return elliptic_curve_jump_error(label, {})

    response = make_response('\n\n'.join(Json.dumps(d) for d in data_list))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #25
0
def by_ec_label(label):
    ec_logger.debug(label)
    try:
        N, iso, number = split_lmfdb_label(label)
    except AttributeError:
        ec_logger.debug("%s not a valid lmfdb label, trying cremona")
        try:
            N, iso, number = split_cremona_label(label)
        except AttributeError:
            ec_logger.debug(
                "%s not a valid cremona label either, trying Weierstrass")
            eqn = label.replace(" ", "")
            if weierstrass_eqn_regex.match(
                    eqn) or short_weierstrass_eqn_regex.match(eqn):
                return by_weierstrass(eqn)
            else:
                return elliptic_curve_jump_error(label, {})

        # We permanently redirect to the lmfdb label
        if number:  # it's a curve
            data = db_ec().find_one({'label': label})
            if data is None:
                return elliptic_curve_jump_error(label, {})
            ec_logger.debug(url_for(".by_ec_label", label=data['lmfdb_label']))
            #return redirect(url_for(".by_ec_label", label=data['lmfdb_label']), 301)
            return render_curve_webpage_by_label(data['label'])
        else:  # it's an isogeny class
            data = db_ec().find_one({'iso': label})
            if data is None:
                return elliptic_curve_jump_error(label, {})
            ec_logger.debug(url_for(".by_ec_label", label=data['lmfdb_label']))
            #return redirect(url_for(".by_ec_label", label=data['iso']), 301)
            return render_isogeny_class(data['iso'])

    if number:
        return redirect(
            url_for(".by_triple_label",
                    conductor=N,
                    iso_label=iso,
                    number=number))
    else:
        return redirect(
            url_for(".by_double_iso_label", conductor=N, iso_label=iso))
Example #26
0
def padic_data():
    info = {}
    label = request.args['label']
    p = int(request.args['p'])
    info['p'] = p
    N, iso, number = split_lmfdb_label(label)
    if request.args['rank'] == '0':
        info['reg'] = 1
    elif number == '1':
        data = db.ec_padic.lucky({'lmfdb_iso': N + '.' + iso, 'p': p})
        if data is None:
            info['reg'] = 'no data'
        else:
            val = int(data['val'])
            aprec = data['prec']
            reg = sage.all.Qp(p, aprec)(int(data['unit']), aprec - val) << val
            info['reg'] = web_latex(reg)
    else:
        info['reg'] = "no data"
    return render_template("ec-padic-data.html", info=info)
Example #27
0
def padic_data():
    info = {}
    label = request.args['label']
    p = int(request.args['p'])
    info['p'] = p
    N, iso, number = split_lmfdb_label(label)
    if request.args['rank'] == '0':
        info['reg'] = 1
    elif number == '1':
        data = db.ec_padic.lucky({'lmfdb_iso': N + '.' + iso, 'p': p})
        if data is None:
            info['reg'] = 'no data'
        else:
            val = int(data['val'])
            aprec = data['prec']
            reg = Qp(p, aprec)(int(data['unit']), aprec - val) << val
            info['reg'] = web_latex(reg)
    else:
        info['reg'] = "no data"
    return render_template("ec-padic-data.html", info=info)
Example #28
0
def padic_data(label, p):
    try:
        N, iso, number = split_lmfdb_label(label)
    except AttributeError:
        return abort(404)
    info = {'p': p}
    if db.ec_curvedata.lookup(label, label_col='lmfdb_label', projection="rank") == 0:
        info['reg'] = 1
    elif number == '1':
        data = db.ec_padic.lucky({'lmfdb_iso': N + '.' + iso, 'p': p})
        if data is None:
            info['reg'] = 'no data'
        else:
            val = int(data['val'])
            aprec = data['prec']
            reg = Qp(p, aprec)(int(data['unit']), aprec - val) << val
            info['reg'] = web_latex(reg)
    else:
        info['reg'] = "no data"
    return render_template("ec-padic-data.html", info=info)
Example #29
0
def download_EC_all(label):
    CDB = lmfdb.base.getDBConnection().elliptic_curves.curves
    N, iso, number = split_lmfdb_label(label)
    if number:
        data = CDB.find_one({'lmfdb_label': label})
        if data is None:
            return elliptic_curve_jump_error(label, {})
        data_list = [data]
    else:
        data_list = sorted(list(CDB.find({'lmfdb_iso': label})),
                           key=lambda E: E['number'])
        if len(data_list) == 0:
            return elliptic_curve_jump_error(label, {})

    # titles of all entries of curves
    dump_data = []
    titles = [str(c) for c in data_list[0]]
    titles = [t for t in titles if t[0] != '_']
    titles.sort()
    dump_data.append(titles)
    for data in data_list:
        data1 = []
        for t in titles:
            d = data[t]
            if t == 'ainvs':
                data1.append(format_ainvs(d))
            elif t in ['torsion_generators', 'torsion_structure']:
                data1.append([eval(g) for g in d])
            elif t == 'x-coordinates_of_integral_points':
                data1.append(parse_list(d))
            elif t == 'gens':
                data1.append(parse_points(d))
            elif t in ['iso', 'label', 'lmfdb_iso', 'lmfdb_label']:
                data1.append(str(d))
            else:
                data1.append(d)
        dump_data.append(data1)
    response = make_response('\n'.join(str(an) for an in dump_data))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #30
0
def by_ec_label(label):
    ec_logger.debug(label)

    # First see if we have an LMFDB label of a curve or class:
    try:
        N, iso, number = split_lmfdb_label(label)
        if number:
            return redirect(url_for(".by_triple_label", conductor=N, iso_label=iso, number=number))
        else:
            return redirect(url_for(".by_double_iso_label", conductor=N, iso_label=iso))

    except AttributeError:
        ec_logger.debug("%s not a valid lmfdb label, trying cremona")
        # Next see if we have a Cremona label of a curve or class:
        try:
            N, iso, number = split_cremona_label(label)
        except AttributeError:
            ec_logger.debug("%s not a valid cremona label either, trying Weierstrass")
            eqn = label.replace(" ","")
            if weierstrass_eqn_regex.match(eqn) or short_weierstrass_eqn_regex.match(eqn):
                return by_weierstrass(eqn)
            else:
                return elliptic_curve_jump_error(label, {})

        if number: # it's a curve
            label_type = 'label'
        else:
            label_type = 'iso'

        data = db.ec_curves.lucky({label_type: label}, projection=1)
        if data is None:
            return elliptic_curve_jump_error(label, {}, wellformed_label=True, missing_curve=True)
        ec_logger.debug(url_for(".by_ec_label", label=data['lmfdb_label']))
        iso = data['lmfdb_iso'].split(".")[1]
        if number:
            return render_curve_webpage_by_label(label)
            #return redirect(url_for(".by_triple_label", conductor=N, iso_label=iso, number=data['lmfdb_number']))
        else:
            return render_isogeny_class(label)
Example #31
0
def download_EC_all(label):
    CDB = lmfdb.base.getDBConnection().elliptic_curves.curves
    N, iso, number = split_lmfdb_label(label)
    if number:
        data = CDB.find_one({"lmfdb_label": label})
        if data is None:
            return elliptic_curve_jump_error(label, {})
        data_list = [data]
    else:
        data_list = sorted(list(CDB.find({"lmfdb_iso": label})), key=lambda E: E["number"])
        if len(data_list) == 0:
            return elliptic_curve_jump_error(label, {})

    # titles of all entries of curves
    dump_data = []
    titles = [str(c) for c in data_list[0]]
    titles = [t for t in titles if t[0] != "_"]
    titles.sort()
    dump_data.append(titles)
    for data in data_list:
        data1 = []
        for t in titles:
            d = data[t]
            if t == "ainvs":
                data1.append(format_ainvs(d))
            elif t in ["torsion_generators", "torsion_structure"]:
                data1.append([eval(g) for g in d])
            elif t == "x-coordinates_of_integral_points":
                data1.append(split_list(d))
            elif t == "gens":
                data1.append(parse_points(d))
            elif t in ["iso", "label", "lmfdb_iso", "lmfdb_label"]:
                data1.append(str(d))
            else:
                data1.append(d)
        dump_data.append(data1)
    response = make_response("\n".join(str(an) for an in dump_data))
    response.headers["Content-type"] = "text/plain"
    return response
Example #32
0
def download_EC_all(label):
    CDB = lmfdb.base.getDBConnection().elliptic_curves.curves
    N, iso, number = split_lmfdb_label(label)
    if number:
        data = CDB.find_one({'lmfdb_label': label})
        if data is None:
            return elliptic_curve_jump_error(label, {})
        data_list = [data]
    else:
        data_list = sorted(list(CDB.find({'lmfdb_iso': label})), key=lambda E: E['number'])
        if len(data_list) == 0:
            return elliptic_curve_jump_error(label, {})

    # titles of all entries of curves
    dump_data = []
    titles = [str(c) for c in data_list[0]]
    titles = [t for t in titles if t[0] != '_']
    titles.sort()
    dump_data.append(titles)
    for data in data_list:
        data1 = []
        for t in titles:
            d = data[t]
            if t == 'ainvs':
                data1.append(format_ainvs(d))
            elif t in ['torsion_generators', 'torsion_structure']:
                data1.append([eval(g) for g in d])
            elif t == 'x-coordinates_of_integral_points':
                data1.append(parse_list(d))
            elif t == 'gens':
                data1.append(parse_points(d))
            elif t in ['iso', 'label', 'lmfdb_iso', 'lmfdb_label']:
                data1.append(str(d))
            else:
                data1.append(d)
        dump_data.append(data1)
    response = make_response('\n'.join(str(an) for an in dump_data))
    response.headers['Content-type'] = 'text/plain'
    return response
Example #33
0
def padic_data():
    info = {}
    label = request.args["label"]
    p = int(request.args["p"])
    info["p"] = p
    N, iso, number = split_lmfdb_label(label)
    if request.args["rank"] == "0":
        info["reg"] = 1
    elif number == "1":
        C = lmfdb.base.getDBConnection()
        data = C.elliptic_curves.curves.find_one({"lmfdb_iso": N + "." + iso})
        data = C.elliptic_curves.padic_db.find_one({"lmfdb_iso": N + "." + iso, "p": p})
        info["data"] = data
        if data is None:
            info["reg"] = "no data"
        else:
            val = int(data["val"])
            aprec = data["prec"]
            reg = sage.all.Qp(p, aprec)(int(data["unit"]), aprec - val) << val
            info["reg"] = web_latex(reg)
    else:
        info["reg"] = "no data"
    return render_template("padic_data.html", info=info)
Example #34
0
def elliptic_curve_search(info, query):
    parse_rational(info, query, 'jinv', 'j-invariant')
    parse_ints(info, query, 'conductor')
    parse_ints(info, query, 'torsion', 'torsion order')
    parse_ints(info, query, 'rank')
    parse_ints(info, query, 'sha', 'analytic order of &#1064;')
    parse_ints(info, query, 'num_int_pts', 'num_int_pts')
    parse_floats(info, query, 'regulator', 'regulator')
    parse_bool(info, query, 'semistable', 'semistable')
    parse_bracketed_posints(info,
                            query,
                            'torsion_structure',
                            maxlength=2,
                            check_divisibility='increasing')
    # speed up slow torsion_structure searches by also setting torsion
    #if 'torsion_structure' in query and not 'torsion' in query:
    #    query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
    if 'include_cm' in info:
        if info['include_cm'] == 'exclude':
            query['cm'] = 0
        elif info['include_cm'] == 'only':
            query['cm'] = {'$ne': 0}
    #parse_ints(info,query,field='cm_disc',qfield='cm')
    if 'cm_disc' in info:
        query['cm'] = info['cm_disc']
    parse_element_of(info,
                     query,
                     field='isodeg',
                     qfield='isogeny_degrees',
                     split_interval=1000)
    #parse_ints(info,query,field='isodeg',qfield='isogeny_degrees')
    parse_primes(info,
                 query,
                 'surj_primes',
                 name='maximal primes',
                 qfield='nonmax_primes',
                 mode='exclude')
    parse_primes(info,
                 query,
                 'nonsurj_primes',
                 name='non-maximal primes',
                 qfield='nonmax_primes',
                 mode=info.get('surj_quantifier'),
                 radical='nonmax_rad')
    parse_primes(info,
                 query,
                 'bad_primes',
                 name='bad primes',
                 qfield='bad_primes',
                 mode=info.get('bad_quantifier'))
    # The button which used to be labelled Optimal only no/yes"
    # (default no) has been renamed "Curves per isogeny class all/one"
    # (default one) but the only change in behavious is that we no
    # longer treat class 990h (where the optial curve is #3 not #1) as
    # special: the "one" option just restricts to curves whose
    # 'number' is 1.
    if 'optimal' in info and info['optimal'] == 'on':
        query.update({'number': 1})

        # Old behaviour was as follows:
        # For all isogeny classes except 990h the optimal curve is number 1, while for class 990h it is number 3.
        # So setting query['number'] = 1 is nearly correct, but fails on 990h3.
        # Instead, we use this more complicated query:
        # query.update({"$or":[{'iso':'990h', 'number':3}, {'iso':{'$ne':'990h'},'number':1}]})

    info['curve_ainvs'] = lambda dbc: str([ZZ(ai) for ai in dbc['ainvs']])
    info['curve_url_LMFDB'] = lambda dbc: url_for(".by_triple_label",
                                                  conductor=dbc['conductor'],
                                                  iso_label=split_lmfdb_label(
                                                      dbc['lmfdb_iso'])[1],
                                                  number=dbc['lmfdb_number'])
    info['iso_url_LMFDB'] = lambda dbc: url_for(".by_double_iso_label",
                                                conductor=dbc['conductor'],
                                                iso_label=split_lmfdb_label(
                                                    dbc['lmfdb_iso'])[1])
    info['curve_url_Cremona'] = lambda dbc: url_for(".by_ec_label",
                                                    label=dbc['label'])
    info['iso_url_Cremona'] = lambda dbc: url_for(".by_ec_label",
                                                  label=dbc['iso'])
Example #35
0
def random_curve():
    label = db.ec_curves.random(projection=1)['lmfdb_label']
    cond, iso, num = split_lmfdb_label(label)
    return redirect(
        url_for(".by_triple_label", conductor=cond, iso_label=iso, number=num))
Example #36
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)
Example #37
0
def random_curve():
    label = db.ec_curves.random(projection=1)['lmfdb_label']
    cond, iso, num = split_lmfdb_label(label)
    return redirect(url_for(".by_triple_label", conductor=cond, iso_label=iso, number=num))
Example #38
0
def elliptic_curve_search(info):

    if info.get('download') == '1' and info.get('Submit') and info.get('query'):
        return download_search(info)

    if 'SearchAgain' in info:
        return rational_elliptic_curves()

    query = {}
    bread = info.get('bread',[('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('Search Results', '.')])

    if 'jump' in info:
        label = info.get('label', '').replace(" ", "")
        m = match_lmfdb_label(label)
        if m:
            try:
                return by_ec_label(label)
            except ValueError:
                return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif label.startswith("Cremona:"):
            label = label[8:]
            m = match_cremona_label(label)
            if m:
                try:
                    return by_ec_label(label)
                except ValueError:
                    return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif match_cremona_label(label):
            return elliptic_curve_jump_error(label, info, cremona_label=True)
        elif label:
            # Try to parse a string like [1,0,3,2,4] as valid
            # Weistrass coefficients:
            lab = re.sub(r'\s','',label)
            lab = re.sub(r'^\[','',lab)
            lab = re.sub(r']$','',lab)
            try:
                labvec = lab.split(',')
                labvec = [QQ(str(z)) for z in labvec] # Rationals allowed
                E = EllipticCurve(labvec).minimal_model()
                # Now we do have a valid curve over Q, but it might
                # not be in the database.
                data = db_ec().find_one({'xainvs': EC_ainvs(E)})
                if data is None:
                    info['conductor'] = E.conductor()
                    return elliptic_curve_jump_error(label, info, missing_curve=True)
                return by_ec_label(data['lmfdb_label'])
            except (TypeError, ValueError, ArithmeticError):
                return elliptic_curve_jump_error(label, info)
        else:
            query['label'] = ''

    try:
        parse_rational(info,query,'jinv','j-invariant')
        parse_ints(info,query,'conductor')
        parse_ints(info,query,'torsion','torsion order')
        parse_ints(info,query,'rank')
        parse_ints(info,query,'sha','analytic order of &#1064;')
        parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,process=str,check_divisibility='increasing')
        # speed up slow torsion_structure searches by also setting torsion
        if 'torsion_structure' in query and not 'torsion' in query:
            query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
        if 'include_cm' in info:
            if info['include_cm'] == 'exclude':
                query['cm'] = 0
            elif info['include_cm'] == 'only':
                query['cm'] = {'$ne' : 0}

        parse_ints(info,query,field='isodeg',qfield='isogeny_degrees')

        parse_primes(info, query, 'surj_primes', name='surjective primes',
                     qfield='non-maximal_primes', mode='complement')
        if info.get('surj_quantifier') == 'exactly':
            mode = 'exact'
        else:
            mode = 'append'
        parse_primes(info, query, 'nonsurj_primes', name='non-surjective primes',
                     qfield='non-maximal_primes',mode=mode)
    except ValueError as err:
        info['err'] = str(err)
        return search_input_error(info, bread)

    count = parse_count(info,100)
    start = parse_start(info)

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

    info['query'] = query
    cursor = db_ec().find(query);
    cursor = cursor.sort([('conductor', ASCENDING), ('iso_nlabel', ASCENDING),
                       ('lmfdb_number', ASCENDING)]);
    # equivalent to
    # cursor = res
    # nres = res.count()
    # if(start >= nres):
    #     start -= (1 + (start - nres) / count) * count
    # if(start < 0):
    #    start = 0
    # res = res.skip(start).limit(count)
    try:
        start, nres, res = search_cursor_timeout_decorator(cursor, start, count);
    except ValueError as err:
        info['err'] = err;
        return search_input_error(info, bread)

    info['curves'] = res
    info['curve_url'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number'])
    info['iso_url'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1])
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)

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

    t = info.get('title','Elliptic Curves search results')
    return render_template("ec-search-results.html", info=info, credit=ec_credit(), bread=bread, title=t)
Example #39
0
    def make_form(self):
        # To start with the data fields of self are just those from
        # the database.  We need to reformat these and compute some
        # further (easy) data about it.
        #
        from lmfdb.ecnf.WebEllipticCurve import FIELD
        self.field = FIELD(self.field_label)
        pretty_field = field_pretty(self.field_label)
        self.field_knowl = nf_display_knowl(self.field_label, getDBConnection(), pretty_field)
        try:
            dims = db_dims().find_one({'field_label':self.field_label, 'level_label':self.level_label})['gl2_dims']
            self.newspace_dimension = dims[str(self.weight)]['new_dim']
        except TypeError:
            self.newspace_dimension = 'not available'
        self.newspace_label = "-".join([self.field_label,self.level_label])
        self.newspace_url = url_for(".render_bmf_space_webpage", field_label=self.field_label, level_label=self.level_label)
        K = self.field.K()

        if self.dimension>1:
            Qx = PolynomialRing(QQ,'x')
            self.hecke_poly = Qx(str(self.hecke_poly))
            F = NumberField(self.hecke_poly,'z')
            self.hecke_poly = web_latex(self.hecke_poly)
            def conv(ap):
                if '?' in ap:
                    return 'not known'
                else:
                    return F(str(ap))
            self.hecke_eigs = [conv(str(ap)) for ap in self.hecke_eigs]

        self.nap = len(self.hecke_eigs)
        self.nap0 = min(50, self.nap)
        self.hecke_table = [[web_latex(p.norm()),
                             ideal_label(p),
                             web_latex(p.gens_reduced()[0]),
                             web_latex(ap)] for p,ap in zip(primes_iter(K), self.hecke_eigs[:self.nap0])]
        level = ideal_from_label(K,self.level_label)
        self.level_ideal2 = web_latex(level)
        badp = level.prime_factors()
        self.have_AL = self.AL_eigs[0]!='?'
        if self.have_AL:
            self.AL_table = [[web_latex(p.norm()),
                             ideal_label(p),
                              web_latex(p.gens_reduced()[0]),
                              web_latex(ap)] for p,ap in zip(badp, self.AL_eigs)]
        self.sign = 'not determined'
        if self.sfe == 1:
            self.sign = "+1"
        elif self.sfe == -1:
            self.sign = "-1"

        if self.Lratio == '?':
            self.Lratio = "not determined"
            self.anrank = "not determined"
        else:
            self.Lratio = QQ(self.Lratio)
            self.anrank = "\(0\)" if self.Lratio!=0 else "odd" if self.sfe==-1 else "\(\ge2\), even"

        self.properties2 = [('Base field', pretty_field),
                            ('Weight', str(self.weight)),
                            ('Level norm', str(self.level_norm)),
                            ('Level', self.level_ideal2),
                            ('Label', self.label),
                            ('Dimension', str(self.dimension))
        ]

        if self.CM == '?':
            self.CM = 'not determined'
        elif self.CM == 0:
            self.CM = 'no'
        self.properties2.append(('CM', str(self.CM)))

        self.bc_extra = ''
        self.bcd = 0
        self.bct = self.bc!='?' and self.bc!=0
        if self.bc == '?':
            self.bc = 'not determined'
        elif self.bc == 0:
            self.bc = 'no'
        elif self.bc == 1:
            self.bcd = self.bc
            self.bc = 'yes'
        elif self.bc >1:
            self.bcd = self.bc
            self.bc = 'yes'
            self.bc_extra = ', of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{'+str(self.bcd)+'})\)'
        elif self.bc == -1:
            self.bc = 'no'
            self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\)'
        elif self.bc < -1:
            self.bcd = -self.bc
            self.bc = 'no'
            self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{'+str(self.bcd)+'})\)'
        self.properties2.append(('Base-change', str(self.bc)))

        curve = db_ecnf().find_one({'class_label':self.label})
        if curve:
            self.ec_status = 'exists'
            self.ec_url = url_for("ecnf.show_ecnf_isoclass", nf=self.field_label, conductor_label=self.level_label, class_label=self.label_suffix)
            curve_bc = curve['base_change']
            curve_bc_parts = [split_lmfdb_label(lab) for lab in curve_bc]
            bc_urls = [url_for("emf.render_elliptic_modular_forms", level=cond, weight=2, character=1, label=iso) for cond, iso, num in curve_bc_parts]
            bc_labels = [newform_label(cond,2,1,iso) for cond,iso,num in curve_bc_parts]
            bc_exists = [is_newform_in_db(lab) for lab in bc_labels]
            self.bc_forms = [{'exists':ex, 'label':lab, 'url':url} for ex,lab,url in zip(bc_exists, bc_labels, bc_urls)]
        else:
            self.bc_forms = []
            if self.bct:
                self.ec_status = 'none'
            else:
                self.ec_status = 'missing'

        self.properties2.append(('Sign', self.sign))
        self.properties2.append(('Analytic rank', self.anrank))

        self.friends = []
        if self.dimension==1:
            if self.ec_status == 'exists':
                self.friends += [('Elliptic curve isogeny class {}'.format(self.label), self.ec_url)]
            elif self.ec_status == 'missing':
                self.friends += [('Elliptic curve {} missing'.format(self.label), "")]
            else:
                self.friends += [('No elliptic curve', "")]

        self.friends += [ ('Newspace {}'.format(self.newspace_label),self.newspace_url)]
        self.friends += [ ('L-function not available','')]
Example #40
0
    def make_class(self):
        self.ainvs_str = self.ainvs
        self.ainvs = [int(a) for a in self.ainvs_str]
        self.E = EllipticCurve(self.ainvs)
        self.CM = self.E.has_cm()

        try:
            # Extract the isogeny degree matrix from the database
            size = len(self.isogeny_matrix)
            from sage.matrix.all import Matrix

            self.isogeny_matrix = Matrix(self.isogeny_matrix)
        except AttributeError:
            # Failsafe: construct it from scratch
            self.isogeny_matrix = self.E.isogeny_class(order="lmfdb").matrix()
            size = self.isogeny_matrix.nrows()
        self.ncurves = size

        # Create isogeny graph:
        self.graph = make_graph(self.isogeny_matrix)
        P = self.graph.plot(edge_labels=True)
        self.graph_img = encode_plot(P)
        self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img

        # Create a list of the curves in the class from the database
        self.db_curves = [self.E]
        self.optimal_flags = [False] * size
        self.degrees = [0] * size
        if self.degree:
            self.degrees[0] = self.degree
        else:
            try:
                self.degrees[0] = self.E.modular_degree()
            except RuntimeError:
                pass

        # Fill in the curves in the class by looking each one up in the db:

        self.cremona_labels = [self.label] + [0] * (size - 1)
        if self.number == 1:
            self.optimal_flags[0] = True
        for i in range(2, size + 1):
            Edata = db_ec().find_one({"lmfdb_label": self.lmfdb_iso + str(i)})
            Ei = EllipticCurve([int(a) for a in Edata["ainvs"]])
            self.cremona_labels[i - 1] = Edata["label"]
            if Edata["number"] == 1:
                self.optimal_flags[i - 1] = True
            if "degree" in Edata:
                self.degrees[i - 1] = Edata["degree"]
            else:
                try:
                    self.degrees[i - 1] = Ei.modular_degree()
                except RuntimeError:
                    pass
            self.db_curves.append(Ei)

        if self.iso == "990h":  # this isogeny class is labeled wrong in Cremona's tables
            self.optimal_flags = [False, False, True, False]

        self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix))

        N, iso, number = split_lmfdb_label(self.lmfdb_iso)

        self.newform = web_latex(self.E.q_eigenform(10))
        self.newform_label = newform_label(N, 2, 1, iso)
        self.newform_link = url_for("emf.render_elliptic_modular_forms", level=N, weight=2, character=1, label=iso)
        newform_exists_in_db = is_newform_in_db(self.newform_label)

        self.lfunction_link = url_for("l_functions.l_function_ec_page", label=self.lmfdb_iso)

        self.curves = [
            dict(
                [
                    ("label", self.lmfdb_iso + str(i + 1)),
                    ("url", url_for(".by_triple_label", conductor=N, iso_label=iso, number=i + 1)),
                    ("cremona_label", self.cremona_labels[i]),
                    ("ainvs", str(list(c.ainvs()))),
                    ("torsion", c.torsion_order()),
                    ("degree", self.degrees[i]),
                    ("optimal", self.optimal_flags[i]),
                ]
            )
            for i, c in enumerate(self.db_curves)
        ]

        self.friends = [("L-function", self.lfunction_link)]
        if not self.CM:
            self.friends += [
                (
                    "Symmetric square L-function",
                    url_for("l_functions.l_function_ec_sym_page", power="2", label=self.lmfdb_iso),
                ),
                (
                    "Symmetric 4th power L-function",
                    url_for("l_functions.l_function_ec_sym_page", power="4", label=self.lmfdb_iso),
                ),
            ]
        if newform_exists_in_db:
            self.friends += [("Modular form " + self.newform_label, self.newform_link)]

        self.properties = [
            ("Label", self.lmfdb_iso),
            ("Number of curves", str(self.ncurves)),
            ("Conductor", "\(%s\)" % N),
            ("CM", "%s" % self.CM),
            ("Rank", "\(%s\)" % self.rank),
            ("Graph", ""),
            (None, self.graph_link),
        ]

        self.downloads = [
            ("Download coefficients of newform", url_for(".download_EC_qexp", label=self.lmfdb_iso, limit=100)),
            ("Download stored data for all curves", url_for(".download_EC_all", label=self.lmfdb_iso)),
        ]

        if self.lmfdb_iso == self.iso:
            self.title = "Elliptic Curve Isogeny Class %s" % self.lmfdb_iso
        else:
            self.title = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % (self.lmfdb_iso, self.iso)

        self.bread = [
            ("Elliptic Curves", url_for("ecnf.index")),
            ("$\Q$", url_for(".rational_elliptic_curves")),
            ("%s" % N, url_for(".by_conductor", conductor=N)),
            ("%s" % iso, " "),
        ]
Example #41
0
def elliptic_curve_search(**args):
    info = to_dict(args)

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

    query = {}
    bread = [('Elliptic Curves', url_for("ecnf.index")),
             ('$\Q$', url_for(".rational_elliptic_curves")),
             ('Search Results', '.')]
    if 'SearchAgain' in args:
        return rational_elliptic_curves()

    if 'jump' in args:
        label = info.get('label', '').replace(" ", "")
        m = match_lmfdb_label(label)
        if m:
            try:
                return by_ec_label(label)
            except ValueError:
                return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif label.startswith("Cremona:"):
            label = label[8:]
            m = match_cremona_label(label)
            if m:
                try:
                    return by_ec_label(label)
                except ValueError:
                    return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif match_cremona_label(label):
            return elliptic_curve_jump_error(label, info, cremona_label=True)
        elif label:
            # Try to parse a string like [1,0,3,2,4] as valid
            # Weistrass coefficients:
            lab = re.sub(r'\s','',label)
            lab = re.sub(r'^\[','',lab)
            lab = re.sub(r']$','',lab)
            try:
                labvec = lab.split(',')
                labvec = [QQ(str(z)) for z in labvec] # Rationals allowed
                E = EllipticCurve(labvec)
                # Now we do have a valid curve over Q, but it might
                # not be in the database.
                ainvs = [str(c) for c in E.minimal_model().ainvs()]
                data = db_ec().find_one({'ainvs': ainvs})
                if data is None:
                    info['conductor'] = E.conductor()
                    return elliptic_curve_jump_error(label, info, missing_curve=True)
                return by_ec_label(data['lmfdb_label'])
            except (TypeError, ValueError, ArithmeticError):
                return elliptic_curve_jump_error(label, info)
        else:
            query['label'] = ''

    try:
        parse_rational(info,query,'jinv','j-invariant')
        parse_ints(info,query,'conductor')
        parse_ints(info,query,'torsion','torsion order')
        parse_ints(info,query,'rank')
        parse_ints(info,query,'sha','analytic order of &#1064;')
        parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,process=str,check_divisibility='increasing')
        if 'include_cm' in info:
            if info['include_cm'] == 'exclude':
                query['cm'] = 0
            elif info['include_cm'] == 'only':
                query['cm'] = {'$ne' : 0}

        parse_primes(info, query, 'surj_primes', name='surjective primes',
                     qfield='non-surjective_primes', mode='complement')
        if info.get('surj_quantifier') == 'exactly':
            mode = 'exact'
        else:
            mode = 'append'
        parse_primes(info, query, 'nonsurj_primes', name='non-surjective primes',
                     qfield='non-surjective_primes',mode=mode)
    except ValueError as err:
        info['err'] = str(err)
        return search_input_error(info, bread)

    count = parse_count(info,100)
    start = parse_start(info)

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

    info['query'] = query
    cursor = db_ec().find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0
    res = cursor.sort([('conductor', ASCENDING), ('iso_nlabel', ASCENDING),
                       ('lmfdb_number', ASCENDING)]).skip(start).limit(count)
    info['curves'] = res
    info['format_ainvs'] = format_ainvs
    info['curve_url'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number'])
    info['iso_url'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1])
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)

    
    if nres == 1:
        info['report'] = 'unique match'
    elif nres == 2: 
        info['report'] = 'displaying both matches'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    credit = 'John Cremona'
    if 'non-surjective_primes' in query:
        credit += 'and Andrew Sutherland'
    t = 'Elliptic Curves search results'
    return render_template("search_results.html", info=info, credit=credit, bread=bread, title=t)
Example #42
0
def random_curve():
    label = random_object_from_collection( db_ec() )['lmfdb_label']
    cond, iso, num = split_lmfdb_label(label)
    return redirect(url_for(".by_triple_label", conductor=cond, iso_label=iso, number=num))
Example #43
0
    def make_class(self):
        self.ainvs_str = self.ainvs
        self.ainvs = [int(a) for a in self.ainvs_str]
        self.E = EllipticCurve(self.ainvs)
        self.CM = self.E.has_cm()

        try:
            # Extract the isogeny degree matrix from the database
            size = len(self.isogeny_matrix)
            from sage.matrix.all import Matrix
            self.isogeny_matrix = Matrix(self.isogeny_matrix)
        except AttributeError:
            # Failsafe: construct it from scratch
            self.isogeny_matrix = self.E.isogeny_class(order="lmfdb").matrix()
            size = self.isogeny_matrix.nrows()
        self.ncurves = size

        # Create isogeny graph:
        self.graph = make_graph(self.isogeny_matrix)
        P = self.graph.plot(edge_labels=True)
        self.graph_img = encode_plot(P)
        self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img

        # Create a list of the curves in the class from the database
        self.db_curves = [self.E]
        self.optimal_flags = [False] * size
        self.degrees = [0] * size
        if self.degree:
            self.degrees[0] = self.degree
        else:
            try:
                self.degrees[0] = self.E.modular_degree()
            except RuntimeError:
                pass

        # Fill in the curves in the class by looking each one up in the db:

        self.cremona_labels = [self.label] + [0] * (size - 1)
        if self.number == 1:
            self.optimal_flags[0] = True
        for i in range(2, size + 1):
            Edata = db_ec().find_one({'lmfdb_label': self.lmfdb_iso + str(i)})
            Ei = EllipticCurve([int(a) for a in Edata['ainvs']])
            self.cremona_labels[i - 1] = Edata['label']
            if Edata['number'] == 1:
                self.optimal_flags[i - 1] = True
            if 'degree' in Edata:
                self.degrees[i - 1] = Edata['degree']
            else:
                try:
                    self.degrees[i - 1] = Ei.modular_degree()
                except RuntimeError:
                    pass
            self.db_curves.append(Ei)


        if self.iso == '990h':  # this isogeny class is labeled wrong in Cremona's tables
            self.optimal_flags = [False, False, True, False]

        self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix))

        N, iso, number = split_lmfdb_label(self.lmfdb_iso)

        self.newform = web_latex(self.E.q_eigenform(10))
        self.newform_label = newform_label(N,2,1,iso)
        self.newform_link = url_for("emf.render_elliptic_modular_forms", level=N, weight=2, character=1, label=iso)
        self.newform_exists_in_db = is_newform_in_db(self.newform_label)

        self.lfunction_link = url_for("l_functions.l_function_ec_page", label=self.lmfdb_iso)

        self.curves = [dict([('label',self.lmfdb_iso + str(i + 1)),
                             ('url',url_for(".by_triple_label", conductor=N, iso_label=iso, number=i+1)),
                             ('cremona_label',self.cremona_labels[i]),
                             ('ainvs',str(list(c.ainvs()))),
                             ('torsion',c.torsion_order()),
                             ('degree',self.degrees[i]),
                             ('optimal',self.optimal_flags[i])])
                       for i, c in enumerate(self.db_curves)]

        self.friends =  [('L-function', self.lfunction_link)]
        if not self.CM:
            if int(N)<=300:
                self.friends += [('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', label=self.lmfdb_iso))]
            if int(N)<=50:
                self.friends += [('Symmetric cube L-function', url_for("l_functions.l_function_ec_sym_page", power='3', label=self.lmfdb_iso))]
        if self.newform_exists_in_db:
            self.friends +=  [('Modular form ' + self.newform_label, self.newform_link)]

        self.properties = [('Label', self.lmfdb_iso),
                           ('Number of curves', str(self.ncurves)),
                           ('Conductor', '\(%s\)' % N),
                           ('CM', '%s' % self.CM),
                           ('Rank', '\(%s\)' % self.rank),
                           ('Graph', ''),(None, self.graph_link)
                           ]


        self.downloads = [('Download coefficients of newform', url_for(".download_EC_qexp", label=self.lmfdb_iso, limit=1000)),
                         ('Download stored data for all curves', url_for(".download_EC_all", label=self.lmfdb_iso))]

        if self.lmfdb_iso == self.iso:
            self.title = "Elliptic Curve Isogeny Class %s" % self.lmfdb_iso
        else:
            self.title = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % (self.lmfdb_iso, self.iso)

        self.bread = [('Elliptic Curves', url_for("ecnf.index")),
                      ('$\Q$', url_for(".rational_elliptic_curves")),
                      ('%s' % N, url_for(".by_conductor", conductor=N)),
                      ('%s' % iso, ' ')]
        self.code = {}
        self.code['show'] = {'sage':''} # use default show names
        self.code['class'] = {'sage':'E = EllipticCurve("%s1")\n'%(self.lmfdb_iso) + 'E.isogeny_class()\n'}
        self.code['curves'] = {'sage':'E.isogeny_class().curves'}
        self.code['rank'] = {'sage':'E.rank()'}
        self.code['q_eigenform'] = {'sage':'E.q_eigenform(10)'}
        self.code['matrix'] = {'sage':'E.isogeny_class().matrix()'}
        self.code['plot'] = {'sage':'E.isogeny_graph().plot(edge_labels=True)'}
Example #44
0
    def make_form(self, nap0=50):
        # To start with the data fields of self are just those from
        # the database.  We need to reformat these and compute some
        # further (easy) data about it.
        #
        from lmfdb.ecnf.WebEllipticCurve import FIELD
        self.field = FIELD(self.field_label)
        pretty_field = field_pretty(self.field_label)
        self.field_knowl = nf_display_knowl(self.field_label, pretty_field)
        try:
            dims = db.bmf_dims.lucky(
                {
                    'field_label': self.field_label,
                    'level_label': self.level_label
                },
                projection='gl2_dims')
            self.newspace_dimension = dims[str(self.weight)]['new_dim']
        except TypeError:
            self.newspace_dimension = 'not available'
        self.newspace_label = "-".join([self.field_label, self.level_label])
        self.newspace_url = url_for(".render_bmf_space_webpage",
                                    field_label=self.field_label,
                                    level_label=self.level_label)
        K = self.field.K()

        # 'hecke_poly_obj' is the non-LaTeX version of hecke_poly
        self.hecke_poly_obj = self.hecke_poly

        if self.dimension > 1:
            Qx = PolynomialRing(QQ, 'x')
            self.hecke_poly = Qx(str(self.hecke_poly))
            F = NumberField(self.hecke_poly, 'z')
            self.hecke_poly = web_latex(self.hecke_poly)

            def conv(ap):
                if '?' in ap:
                    return 'not known'
                else:
                    return F(str(ap))

            self.hecke_eigs = [conv(str(ap)) for ap in self.hecke_eigs]

        self.level = ideal_from_label(K, self.level_label)
        self.level_ideal2 = web_latex(self.level)
        badp = self.level.prime_factors()

        self.nap = len(self.hecke_eigs)
        self.nap0 = min(nap0, self.nap)
        self.neigs = self.nap0 + len(badp)
        self.hecke_table = [[
            web_latex(p.norm()),
            ideal_label(p),
            web_latex(p.gens_reduced()[0]),
            web_latex(ap)
        ] for p, ap in zip(primes_iter(K), self.hecke_eigs[:self.neigs])
                            if not p in badp]
        self.have_AL = self.AL_eigs[0] != '?'
        if self.have_AL:
            self.AL_table = [[
                web_latex(p.norm()),
                ideal_label(p),
                web_latex(p.gens_reduced()[0]),
                web_latex(ap)
            ] for p, ap in zip(badp, self.AL_eigs)]
            # The following helps to create Sage download data
            self.AL_table_data = [[p.gens_reduced(), ap]
                                  for p, ap in zip(badp, self.AL_eigs)]
        self.sign = 'not determined'

        try:
            if self.sfe == 1:
                self.sign = "$+1$"
            elif self.sfe == -1:
                self.sign = "$-1$"
        except AttributeError:
            self.sfe = '?'

        if self.Lratio == '?':
            self.Lratio = "not determined"
            self.anrank = "not determined"
        else:
            self.Lratio = QQ(self.Lratio)
            self.anrank = r"\(0\)" if self.Lratio != 0 else "odd" if self.sfe == -1 else r"\(\ge2\), even"

        self.properties = [('Label', self.label), ('Base field', pretty_field),
                           ('Weight', prop_int_pretty(self.weight)),
                           ('Level norm', prop_int_pretty(self.level_norm)),
                           ('Level', self.level_ideal2),
                           ('Dimension', prop_int_pretty(self.dimension))]

        try:
            if self.CM == '?':
                self.CM = 'not determined'
            elif self.CM == 0:
                self.CM = 'no'
            else:
                if int(self.CM) % 4 in [2, 3]:
                    self.CM = 4 * int(self.CM)
                self.CM = "$%s$" % self.CM
        except AttributeError:
            self.CM = 'not determined'
        self.properties.append(('CM', str(self.CM)))

        self.bc_extra = ''
        self.bcd = 0
        self.bct = self.bc != '?' and self.bc != 0
        if self.bc == '?':
            self.bc = 'not determined'
        elif self.bc == 0:
            self.bc = 'no'
        elif self.bc == 1:
            self.bcd = self.bc
            self.bc = 'yes'
        elif self.bc > 1:
            self.bcd = self.bc
            self.bc = 'yes'
            self.bc_extra = r', of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{' + str(
                self.bcd) + r'})\)'
        elif self.bc == -1:
            self.bc = 'no'
            self.bc_extra = r', but is a twist of the base change of a form over \(\mathbb{Q}\)'
        elif self.bc < -1:
            self.bcd = -self.bc
            self.bc = 'no'
            self.bc_extra = r', but is a twist of the base change of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{' + str(
                self.bcd) + r'})\)'
        self.properties.append(('Base change', str(self.bc)))

        curve_bc = db.ec_nfcurves.lucky({'class_label': self.label},
                                        projection="base_change")
        if curve_bc is not None:
            if curve_bc and "." not in curve_bc[0]:
                curve_bc = [
                    cremona_label_to_lmfdb_label(lab) for lab in curve_bc
                ]
            self.ec_status = 'exists'
            self.ec_url = url_for("ecnf.show_ecnf_isoclass",
                                  nf=self.field_label,
                                  conductor_label=self.level_label,
                                  class_label=self.label_suffix)
            curve_bc_parts = [split_lmfdb_label(lab) for lab in curve_bc]
            bc_urls = [
                url_for("cmf.by_url_newform_label",
                        level=cond,
                        weight=2,
                        char_orbit_label='a',
                        hecke_orbit=iso) for cond, iso, num in curve_bc_parts
            ]
            bc_labels = [
                ".".join([str(cond), str(2), 'a', iso])
                for cond, iso, _ in curve_bc_parts
            ]
            bc_exists = [db.mf_newforms.label_exists(lab) for lab in bc_labels]
            self.bc_forms = [{
                'exists': ex,
                'label': lab,
                'url': url
            } for ex, lab, url in zip(bc_exists, bc_labels, bc_urls)]
        else:
            self.bc_forms = []
            if self.bct or self.label in bmfs_with_no_curve:
                self.ec_status = 'none'
            else:
                self.ec_status = 'missing'

        self.properties.append(('Sign', self.sign))
        self.properties.append(('Analytic rank', self.anrank))

        self.friends = []
        self.friends += [('Newspace {}'.format(self.newspace_label),
                          self.newspace_url)]
        url = 'ModularForm/GL2/ImaginaryQuadratic/{}'.format(
            self.label.replace('-', '/'))
        Lfun = get_lfunction_by_url(url)
        if Lfun:
            instances = get_instances_by_Lhash_and_trace_hash(
                Lfun['Lhash'], Lfun['degree'], Lfun['trace_hash'])

            # This will also add the EC/G2C, as this how the Lfun was computed
            # and not add itself
            self.friends = names_and_urls(instances, exclude={url})
            self.friends.append(('L-function', '/L/' + url))
        else:
            # old code
            if self.dimension == 1:
                if self.ec_status == 'exists':
                    self.friends += [('Isogeny class {}'.format(self.label),
                                      self.ec_url)]
                elif self.ec_status == 'missing':
                    self.friends += [
                        ('Isogeny class {} missing'.format(self.label), "")
                    ]
                else:
                    self.friends += [('No elliptic curve', "")]

            self.friends += [('L-function not available', '')]
Example #45
0
    def make_form(self):
        # To start with the data fields of self are just those from
        # the database.  We need to reformat these and compute some
        # further (easy) data about it.
        #
        from lmfdb.ecnf.WebEllipticCurve import FIELD
        self.field = FIELD(self.field_label)
        pretty_field = field_pretty(self.field_label)
        self.field_knowl = nf_display_knowl(self.field_label, pretty_field)
        try:
            dims = db.bmf_dims.lucky({'field_label':self.field_label, 'level_label':self.level_label}, projection='gl2_dims')
            self.newspace_dimension = dims[str(self.weight)]['new_dim']
        except TypeError:
            self.newspace_dimension = 'not available'
        self.newspace_label = "-".join([self.field_label,self.level_label])
        self.newspace_url = url_for(".render_bmf_space_webpage", field_label=self.field_label, level_label=self.level_label)
        K = self.field.K()

        if self.dimension>1:
            Qx = PolynomialRing(QQ,'x')
            self.hecke_poly = Qx(str(self.hecke_poly))
            F = NumberField(self.hecke_poly,'z')
            self.hecke_poly = web_latex(self.hecke_poly)
            def conv(ap):
                if '?' in ap:
                    return 'not known'
                else:
                    return F(str(ap))
            self.hecke_eigs = [conv(str(ap)) for ap in self.hecke_eigs]

        self.nap = len(self.hecke_eigs)
        self.nap0 = min(50, self.nap)
        self.hecke_table = [[web_latex(p.norm()),
                             ideal_label(p),
                             web_latex(p.gens_reduced()[0]),
                             web_latex(ap)] for p,ap in zip(primes_iter(K), self.hecke_eigs[:self.nap0])]
        level = ideal_from_label(K,self.level_label)
        self.level_ideal2 = web_latex(level)
        badp = level.prime_factors()
        self.have_AL = self.AL_eigs[0]!='?'
        if self.have_AL:
            self.AL_table = [[web_latex(p.norm()),
                             ideal_label(p),
                              web_latex(p.gens_reduced()[0]),
                              web_latex(ap)] for p,ap in zip(badp, self.AL_eigs)]
        self.sign = 'not determined'
        
        try:
            if self.sfe == 1:
                self.sign = "+1"
            elif self.sfe == -1:
                self.sign = "-1"
        except AttributeError:
            self.sfe = '?'

        if self.Lratio == '?':
            self.Lratio = "not determined"
            self.anrank = "not determined"
        else:
            self.Lratio = QQ(self.Lratio)
            self.anrank = "\(0\)" if self.Lratio!=0 else "odd" if self.sfe==-1 else "\(\ge2\), even"

        self.properties2 = [('Base field', pretty_field),
                            ('Weight', str(self.weight)),
                            ('Level norm', str(self.level_norm)),
                            ('Level', self.level_ideal2),
                            ('Label', self.label),
                            ('Dimension', str(self.dimension))
        ]

        try:
            if self.CM == '?':
                self.CM = 'not determined'
            elif self.CM == 0:
                self.CM = 'no'
            else:
                if self.CM%4 in [2,3]:
                    self.CM = 4*self.CM
        except AttributeError:
            self.CM = 'not determined'
        self.properties2.append(('CM', str(self.CM)))

        self.bc_extra = ''
        self.bcd = 0
        self.bct = self.bc!='?' and self.bc!=0
        if self.bc == '?':
            self.bc = 'not determined'
        elif self.bc == 0:
            self.bc = 'no'
        elif self.bc == 1:
            self.bcd = self.bc
            self.bc = 'yes'
        elif self.bc >1:
            self.bcd = self.bc
            self.bc = 'yes'
            self.bc_extra = ', of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{'+str(self.bcd)+'})\)'
        elif self.bc == -1:
            self.bc = 'no'
            self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\)'
        elif self.bc < -1:
            self.bcd = -self.bc
            self.bc = 'no'
            self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{'+str(self.bcd)+'})\)'
        self.properties2.append(('Base-change', str(self.bc)))

        curve_bc = db.ec_nfcurves.lucky({'class_label':self.label}, projection="base_change")
        if curve_bc is not None:
            self.ec_status = 'exists'
            self.ec_url = url_for("ecnf.show_ecnf_isoclass", nf=self.field_label, conductor_label=self.level_label, class_label=self.label_suffix)
            curve_bc_parts = [split_lmfdb_label(lab) for lab in curve_bc]
            bc_urls = [url_for("cmf.by_url_newform_label", level=cond, weight=2, char_orbit_label='a', hecke_orbit=iso) for cond, iso, num in curve_bc_parts]
            bc_labels = [".".join( [str(cond), str(2), 'a', iso] ) for cond,iso,_ in curve_bc_parts]
            bc_exists = [db.mf_newforms.label_exists(lab) for lab in bc_labels]
            self.bc_forms = [{'exists':ex, 'label':lab, 'url':url} for ex,lab,url in zip(bc_exists, bc_labels, bc_urls)]
        else:
            self.bc_forms = []
            if self.bct:
                self.ec_status = 'none'
            else:
                self.ec_status = 'missing'

        self.properties2.append(('Sign', self.sign))
        self.properties2.append(('Analytic rank', self.anrank))

        self.friends = []
        self.friends += [('Newspace {}'.format(self.newspace_label),self.newspace_url)]
        url = 'ModularForm/GL2/ImaginaryQuadratic/{}'.format(
                self.label.replace('-', '/'))
        Lfun = get_lfunction_by_url(url)
        if Lfun:
            # first by Lhash
            instances = get_instances_by_Lhash(Lfun['Lhash'])
            # then by trace_hash
            instances += get_instances_by_trace_hash(Lfun['degree'], Lfun['trace_hash'])

            # This will also add the EC/G2C, as this how the Lfun was computed
            self.friends = names_and_urls(instances)
            # remove itself
            self.friends.remove(
                    ('Bianchi modular form {}'.format(self.label), '/' + url))
            self.friends.append(('L-function', '/L/'+url))
            
        else:
            # old code
            if self.dimension == 1:
                if self.ec_status == 'exists':
                    self.friends += [('Isogeny class {}'.format(self.label), self.ec_url)]
                elif self.ec_status == 'missing':
                    self.friends += [('Isogeny class {} missing'.format(self.label), "")]
                else:
                    self.friends += [('No elliptic curve', "")]

            self.friends += [ ('L-function not available','')]
Example #46
0
    def make_form(self):
        # To start with the data fields of self are just those from
        # the database.  We need to reformat these and compute some
        # further (easy) data about it.
        #
        from lmfdb.ecnf.WebEllipticCurve import FIELD
        self.field = FIELD(self.field_label)
        pretty_field = field_pretty(self.field_label)
        self.field_knowl = nf_display_knowl(self.field_label, pretty_field)
        try:
            dims = db.bmf_dims.lucky(
                {
                    'field_label': self.field_label,
                    'level_label': self.level_label
                },
                projection='gl2_dims')
            self.newspace_dimension = dims[str(self.weight)]['new_dim']
        except TypeError:
            self.newspace_dimension = 'not available'
        self.newspace_label = "-".join([self.field_label, self.level_label])
        self.newspace_url = url_for(".render_bmf_space_webpage",
                                    field_label=self.field_label,
                                    level_label=self.level_label)
        K = self.field.K()

        if self.dimension > 1:
            Qx = PolynomialRing(QQ, 'x')
            self.hecke_poly = Qx(str(self.hecke_poly))
            F = NumberField(self.hecke_poly, 'z')
            self.hecke_poly = web_latex(self.hecke_poly)

            def conv(ap):
                if '?' in ap:
                    return 'not known'
                else:
                    return F(str(ap))

            self.hecke_eigs = [conv(str(ap)) for ap in self.hecke_eigs]

        self.nap = len(self.hecke_eigs)
        self.nap0 = min(50, self.nap)
        self.hecke_table = [[
            web_latex(p.norm()),
            ideal_label(p),
            web_latex(p.gens_reduced()[0]),
            web_latex(ap)
        ] for p, ap in zip(primes_iter(K), self.hecke_eigs[:self.nap0])]
        level = ideal_from_label(K, self.level_label)
        self.level_ideal2 = web_latex(level)
        badp = level.prime_factors()
        self.have_AL = self.AL_eigs[0] != '?'
        if self.have_AL:
            self.AL_table = [[
                web_latex(p.norm()),
                ideal_label(p),
                web_latex(p.gens_reduced()[0]),
                web_latex(ap)
            ] for p, ap in zip(badp, self.AL_eigs)]
        self.sign = 'not determined'
        if self.sfe == 1:
            self.sign = "+1"
        elif self.sfe == -1:
            self.sign = "-1"

        if self.Lratio == '?':
            self.Lratio = "not determined"
            self.anrank = "not determined"
        else:
            self.Lratio = QQ(self.Lratio)
            self.anrank = "\(0\)" if self.Lratio != 0 else "odd" if self.sfe == -1 else "\(\ge2\), even"

        self.properties2 = [('Base field', pretty_field),
                            ('Weight', str(self.weight)),
                            ('Level norm', str(self.level_norm)),
                            ('Level', self.level_ideal2),
                            ('Label', self.label),
                            ('Dimension', str(self.dimension))]

        if self.CM == '?':
            self.CM = 'not determined'
        elif self.CM == 0:
            self.CM = 'no'
        self.properties2.append(('CM', str(self.CM)))

        self.bc_extra = ''
        self.bcd = 0
        self.bct = self.bc != '?' and self.bc != 0
        if self.bc == '?':
            self.bc = 'not determined'
        elif self.bc == 0:
            self.bc = 'no'
        elif self.bc == 1:
            self.bcd = self.bc
            self.bc = 'yes'
        elif self.bc > 1:
            self.bcd = self.bc
            self.bc = 'yes'
            self.bc_extra = ', of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{' + str(
                self.bcd) + '})\)'
        elif self.bc == -1:
            self.bc = 'no'
            self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\)'
        elif self.bc < -1:
            self.bcd = -self.bc
            self.bc = 'no'
            self.bc_extra = ', but is a twist of the base-change of a form over \(\mathbb{Q}\) with coefficients in \(\mathbb{Q}(\sqrt{' + str(
                self.bcd) + '})\)'
        self.properties2.append(('Base-change', str(self.bc)))

        curve_bc = db.ec_nfcurves.lucky({'class_label': self.label},
                                        projection="base_change")
        if curve_bc is not None:
            self.ec_status = 'exists'
            self.ec_url = url_for("ecnf.show_ecnf_isoclass",
                                  nf=self.field_label,
                                  conductor_label=self.level_label,
                                  class_label=self.label_suffix)
            curve_bc_parts = [split_lmfdb_label(lab) for lab in curve_bc]
            bc_urls = [
                url_for("emf.render_elliptic_modular_forms",
                        level=cond,
                        weight=2,
                        character=1,
                        label=iso) for cond, iso, num in curve_bc_parts
            ]
            bc_labels = [
                newform_label(cond, 2, 1, iso)
                for cond, iso, num in curve_bc_parts
            ]
            bc_exists = [is_newform_in_db(lab) for lab in bc_labels]
            self.bc_forms = [{
                'exists': ex,
                'label': lab,
                'url': url
            } for ex, lab, url in zip(bc_exists, bc_labels, bc_urls)]
        else:
            self.bc_forms = []
            if self.bct:
                self.ec_status = 'none'
            else:
                self.ec_status = 'missing'

        self.properties2.append(('Sign', self.sign))
        self.properties2.append(('Analytic rank', self.anrank))

        self.friends = []
        if self.dimension == 1:
            if self.ec_status == 'exists':
                self.friends += [
                    ('Elliptic curve isogeny class {}'.format(self.label),
                     self.ec_url)
                ]
            elif self.ec_status == 'missing':
                self.friends += [
                    ('Elliptic curve {} missing'.format(self.label), "")
                ]
            else:
                self.friends += [('No elliptic curve', "")]

        self.friends += [('Newspace {}'.format(self.newspace_label),
                          self.newspace_url)]
        self.friends += [('L-function not available', '')]
Example #47
0
def elliptic_curve_search(info, query):
    parse_rational_to_list(info,query,'jinv','j-invariant')
    parse_ints(info,query,'conductor')
    parse_ints(info,query,'torsion','torsion order')
    parse_ints(info,query,'rank')
    parse_ints(info,query,'sha','analytic order of &#1064;')
    parse_ints(info,query,'num_int_pts','num_int_pts')
    parse_ints(info,query,'class_size','class_size')
    parse_ints(info,query,'class_deg','class_deg')
    parse_floats(info,query,'regulator','regulator')
    parse_bool(info,query,'semistable','semistable')
    parse_bool(info,query,'potential_good_reduction','potential_good_reduction')
    parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,check_divisibility='increasing')
    # speed up slow torsion_structure searches by also setting torsion
    #if 'torsion_structure' in query and not 'torsion' in query:
    #    query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
    if 'include_cm' in info:
        if info['include_cm'] == 'exclude':
            query['cm'] = 0
        elif info['include_cm'] == 'only':
            query['cm'] = {'$ne' : 0}
    parse_ints(info,query,field='cm_disc',qfield='cm')
    parse_element_of(info,query,'isogeny_degrees',split_interval=1000,contained_in=get_stats().isogeny_degrees)
    parse_primes(info, query, 'surj_primes', name='maximal primes',
                 qfield='nonmax_primes', mode='exclude')
    parse_primes(info, query, 'nonsurj_primes', name='non-maximal primes',
                 qfield='nonmax_primes',mode=info.get('surj_quantifier'), radical='nonmax_rad')
    parse_primes(info, query, 'bad_primes', name='bad primes',
                 qfield='bad_primes',mode=info.get('bad_quantifier'))
    parse_primes(info, query, 'sha_primes', name='sha primes',
                 qfield='sha_primes',mode=info.get('sha_quantifier'))
    # The button which used to be labelled Optimal only no/yes"
    # (default: no) has been renamed "Curves per isogeny class
    # all/one" (default: all).  When this option is "one" we only list
    # one curve in each class, currently choosing the curve with
    # minimal Faltings heights, which is conjecturally the
    # Gamma_1(N)-optimal curve.
    if 'optimal' in info and info['optimal'] == 'on':
        query.update({'lmfdb_number':1})

    info['curve_ainvs'] = lambda dbc: str([ZZ(ai) for ai in dbc['ainvs']])
    info['curve_url_LMFDB'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number'])
    info['iso_url_LMFDB'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1])
    info['cremona_bound'] = CREMONA_BOUND
    info['curve_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['Clabel'])
    info['iso_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['Ciso'])
Example #48
0
    def make_class(self):
        # Extract the size of the isogeny class from the database
        classdata = db.ec_classdata.lucky({'lmfdb_iso': self.lmfdb_iso})
        self.class_size = ncurves = classdata['class_size']

        # Create a list of the curves in the class from the database
        number_key = 'Cnumber' if self.label_type == 'Cremona' else 'lmfdb_number'
        self.curves = [
            db.ec_curvedata.lucky({
                'lmfdb_iso': self.lmfdb_iso,
                number_key: i + 1
            }) for i in range(ncurves)
        ]

        # Set optimality flags.  The optimal curve is conditionally
        # number 1 except in one case which is labeled differently in
        # the Cremona tables.  We know which curve is optimal iff the
        # optimality code for curve #1 is 1 (except for class 990h).

        # Note that self is actually an elliptic curve, with number=1.

        # The code here allows us to update the display correctly by
        # changing one line in this file (defining OPTIMALITY_BOUND)
        # without changing the data.

        self.cremona_bound = CREMONA_BOUND
        self.optimality_bound = OPTIMALITY_BOUND
        self.optimality_known = (self.conductor < OPTIMALITY_BOUND) or (
            (self.conductor < CREMONA_BOUND) and ((self.optimality == 1) or
                                                  (self.Ciso == '990h')))
        self.optimal_label = self.Clabel if self.label_type == 'Cremona' else self.lmfdb_label

        if self.conductor < OPTIMALITY_BOUND:
            for c in self.curves:
                c['optimal'] = (c['Cnumber'] == (3 if self.Ciso == '990h' else
                                                 1))
                c['optimality_known'] = True
        elif self.conductor < CREMONA_BOUND:
            for c in self.curves:
                c['optimal'] = (c['optimality'] > 0
                                )  # this curve possibly optimal
                c['optimality_known'] = (c['optimality'] == 1
                                         )  # this curve certainly optimal
        else:
            for c in self.curves:
                c['optimal'] = None
                c['optimality_known'] = False

        for c in self.curves:
            c['ai'] = c['ainvs']
            c['curve_url_lmfdb'] = url_for(".by_triple_label",
                                           conductor=self.conductor,
                                           iso_label=self.iso_label,
                                           number=c['lmfdb_number'])
            c['curve_url_cremona'] = url_for(
                ".by_ec_label",
                label=c['Clabel']) if self.conductor < CREMONA_BOUND else "N/A"
            if self.label_type == 'Cremona':
                c['curve_label'] = c['Clabel']
                _, c_iso, c_number = split_cremona_label(c['Clabel'])
            else:
                c['curve_label'] = c['lmfdb_label']
                _, c_iso, c_number = split_lmfdb_label(c['lmfdb_label'])
            c['short_label'] = "{}{}".format(c_iso, c_number)

        from sage.matrix.all import Matrix
        M = classdata['isogeny_matrix']

        # permute rows/cols to match labelling: the rows/cols in the
        # ec_classdata table are with respect to LMFDB ordering.
        if self.label_type == 'Cremona':
            perm = lambda i: next(c for c in self.curves
                                  if c['Cnumber'] == i + 1)['lmfdb_number'] - 1
            M = [[M[perm(i)][perm(j)] for i in range(ncurves)]
                 for j in range(ncurves)]

        M = Matrix(M)

        self.isogeny_matrix_str = latex(M)

        # Create isogeny graph with appropriate vertex labels:

        self.graph = make_graph(M, [c['short_label'] for c in self.curves])
        P = self.graph.plot(edge_labels=True, vertex_size=1000)
        self.graph_img = encode_plot(P)
        self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img

        self.newform = raw_typeset(
            PowerSeriesRing(QQ, 'q')(classdata['anlist'], 20, check=True))
        self.newform_label = ".".join(
            [str(self.conductor),
             str(2), 'a', self.iso_label])
        self.newform_exists_in_db = db.mf_newforms.label_exists(
            self.newform_label)
        if self.newform_exists_in_db:
            char_orbit, hecke_orbit = self.newform_label.split('.')[2:]
            self.newform_link = url_for("cmf.by_url_newform_label",
                                        level=self.conductor,
                                        weight=2,
                                        char_orbit_label=char_orbit,
                                        hecke_orbit=hecke_orbit)

        self.lfunction_link = url_for("l_functions.l_function_ec_page",
                                      conductor_label=self.conductor,
                                      isogeny_class_label=self.iso_label)

        self.friends = [('L-function', self.lfunction_link)]

        if self.cm:
            # set CM field for Properties box.
            D = ZZ(self.cm).squarefree_part()
            coeffs = [(1 - D) // 4, -1, 1] if D % 4 == 1 else [-D, 0, 1]
            lab = db.nf_fields.lucky({'coeffs': coeffs}, projection='label')
            self.CMfield = field_pretty(lab)
        else:
            self.CMfield = "no"
            if self.conductor <= 300:
                self.friends += [('Symmetric square L-function',
                                  url_for("l_functions.l_function_ec_sym_page",
                                          power='2',
                                          conductor=self.conductor,
                                          isogeny=self.iso_label))]
            if self.conductor <= 50:
                self.friends += [('Symmetric cube L-function',
                                  url_for("l_functions.l_function_ec_sym_page",
                                          power='3',
                                          conductor=self.conductor,
                                          isogeny=self.iso_label))]
        if self.newform_exists_in_db:
            self.friends += [('Modular form ' + self.newform_label,
                              self.newform_link)]

        if self.label_type == 'Cremona':
            self.title = "Elliptic curve isogeny class with Cremona label {} (LMFDB label {})".format(
                self.Ciso, self.lmfdb_iso)
        elif self.conductor < CREMONA_BOUND:
            self.title = "Elliptic curve isogeny class with LMFDB label {} (Cremona label {})".format(
                self.lmfdb_iso, self.Ciso)
        else:
            self.title = "Elliptic curve isogeny class with LMFDB label {}".format(
                self.lmfdb_iso)

        self.properties = [
            ('Label',
             self.Ciso if self.label_type == 'Cremona' else self.lmfdb_iso),
            ('Number of curves', prop_int_pretty(ncurves)),
            ('Conductor', prop_int_pretty(self.conductor)),
            ('CM', '%s' % self.CMfield), ('Rank', prop_int_pretty(self.rank))
        ]
        if ncurves > 1:
            self.properties += [('Graph', ''), (None, self.graph_link)]

        self.downloads = [('q-expansion to text',
                           url_for(".download_EC_qexp",
                                   label=self.iso_label,
                                   limit=1000)),
                          ('All stored data to text',
                           url_for(".download_EC_all", label=self.iso_label))]

        self.bread = [('Elliptic curves', url_for("ecnf.index")),
                      (r'$\Q$', url_for(".rational_elliptic_curves")),
                      ('%s' % self.conductor,
                       url_for(".by_conductor", conductor=self.conductor)),
                      ('%s' % self.iso_label, ' ')]
        self.code = {}
        self.code['show'] = {'sage': ''}  # use default show names
        self.code['class'] = {
            'sage':
            'E = EllipticCurve("%s1")\n' % (self.iso_label) +
            'E.isogeny_class()\n'
        }
        self.code['curves'] = {'sage': 'E.isogeny_class().curves'}
        self.code['rank'] = {'sage': 'E.rank()'}
        self.code['q_eigenform'] = {'sage': 'E.q_eigenform(10)'}
        self.code['matrix'] = {'sage': 'E.isogeny_class().matrix()'}
        self.code['plot'] = {
            'sage': 'E.isogeny_graph().plot(edge_labels=True)'
        }
Example #49
0
def elliptic_curve_search(info, query):
    parse_rational(info,query,'jinv','j-invariant')
    parse_ints(info,query,'conductor')
    parse_ints(info,query,'torsion','torsion order')
    parse_ints(info,query,'rank')
    parse_ints(info,query,'sha','analytic order of &#1064;')
    parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,check_divisibility='increasing')
    # speed up slow torsion_structure searches by also setting torsion
    #if 'torsion_structure' in query and not 'torsion' in query:
    #    query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
    if 'include_cm' in info:
        if info['include_cm'] == 'exclude':
            query['cm'] = 0
        elif info['include_cm'] == 'only':
            query['cm'] = {'$ne' : 0}
    parse_element_of(info,query,field='isodeg',qfield='isogeny_degrees',split_interval=1000)
    #parse_ints(info,query,field='isodeg',qfield='isogeny_degrees')
    parse_primes(info, query, 'surj_primes', name='maximal primes',
                 qfield='nonmax_primes', mode='complement')
    if info.get('surj_quantifier') == 'exactly':
        mode = 'exact'
    else:
        mode = 'append'
    parse_primes(info, query, 'nonsurj_primes', name='non-maximal primes',
                 qfield='nonmax_primes',mode=mode, radical='nonmax_rad')
    if 'optimal' in info and info['optimal'] == 'on':
        # For all isogeny classes except 990h the optimal curve is number 1, while for class 990h it is number 3.
        # So setting query['number'] = 1 is nearly correct, but fails on 990h3.
        # Instead, we use this more complicated query:
        query.update({"$or":[{'iso':'990h', 'number':3}, {'iso':{'$ne':'990h'},'number':1}]})

    info['curve_url_LMFDB'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number'])
    info['iso_url_LMFDB'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1])
    info['curve_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['label'])
    info['iso_url_Cremona'] = lambda dbc: url_for(".by_ec_label", label=dbc['iso'])
Example #50
0
def random_curve():
    label = random_object_from_collection( db_ec() )['lmfdb_label']
    cond, iso, num = split_lmfdb_label(label)
    return redirect(url_for(".by_triple_label", conductor=cond, iso_label=iso, number=num))
Example #51
0
    def make_class(self):
        self.CM = self.cm
        N, iso, number = split_lmfdb_label(self.lmfdb_iso)

        # Extract the size of the isogeny class from the database
        ncurves = self.class_size
        # Create a list of the curves in the class from the database
        self.curves = [db_ec().find_one({'iso':self.iso, 'lmfdb_number': i+1})
                          for i in range(ncurves)]

        # Set optimality flags.  The optimal curve is number 1 except
        # in one case which is labeled differently in the Cremona tables
        for c in self.curves:
            c['optimal'] = (c['number']==(3 if self.label == '990h' else 1))
            c['ai'] = parse_ainvs(c['xainvs'])
            c['url'] = url_for(".by_triple_label", conductor=N, iso_label=iso, number=c['lmfdb_number'])

        from sage.matrix.all import Matrix
        self.isogeny_matrix = Matrix(self.isogeny_matrix)
        self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix))

        # Create isogeny graph:
        self.graph = make_graph(self.isogeny_matrix)
        P = self.graph.plot(edge_labels=True)
        self.graph_img = encode_plot(P)
        self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img


        self.newform =  web_latex(PowerSeriesRing(QQ, 'q')(self.anlist, 20, check=True))
        self.newform_label = newform_label(N,2,1,iso)
        self.newform_link = url_for("emf.render_elliptic_modular_forms", level=N, weight=2, character=1, label=iso)
        self.newform_exists_in_db = is_newform_in_db(self.newform_label)

        self.lfunction_link = url_for("l_functions.l_function_ec_page", conductor_label = N, isogeny_class_label = iso)

        self.friends =  [('L-function', self.lfunction_link)]
        if not self.CM:
            self.CM = "no"
            if int(N)<=300:
                self.friends += [('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', conductor = N, isogeny = iso))]
            if int(N)<=50:
                self.friends += [('Symmetric cube L-function', url_for("l_functions.l_function_ec_sym_page", power='3', conductor = N, isogeny = iso))]
        if self.newform_exists_in_db:
            self.friends +=  [('Modular form ' + self.newform_label, self.newform_link)]

        self.properties = [('Label', self.lmfdb_iso),
                           ('Number of curves', str(ncurves)),
                           ('Conductor', '\(%s\)' % N),
                           ('CM', '%s' % self.CM),
                           ('Rank', '\(%s\)' % self.rank),
                           ('Graph', ''),(None, self.graph_link)
                           ]


        self.downloads = [('Download coefficients of newform', url_for(".download_EC_qexp", label=self.lmfdb_iso, limit=1000)),
                         ('Download stored data for all curves', url_for(".download_EC_all", label=self.lmfdb_iso))]

        if self.lmfdb_iso == self.iso:
            self.title = "Elliptic Curve Isogeny Class %s" % self.lmfdb_iso
        else:
            self.title = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % (self.lmfdb_iso, self.iso)

        self.bread = [('Elliptic Curves', url_for("ecnf.index")),
                      ('$\Q$', url_for(".rational_elliptic_curves")),
                      ('%s' % N, url_for(".by_conductor", conductor=N)),
                      ('%s' % iso, ' ')]
        self.code = {}
        self.code['show'] = {'sage':''} # use default show names
        self.code['class'] = {'sage':'E = EllipticCurve("%s1")\n'%(self.lmfdb_iso) + 'E.isogeny_class()\n'}
        self.code['curves'] = {'sage':'E.isogeny_class().curves'}
        self.code['rank'] = {'sage':'E.rank()'}
        self.code['q_eigenform'] = {'sage':'E.q_eigenform(10)'}
        self.code['matrix'] = {'sage':'E.isogeny_class().matrix()'}
        self.code['plot'] = {'sage':'E.isogeny_graph().plot(edge_labels=True)'}
Example #52
0
    def make_class(self):
        self.CM = self.cm
        N, iso, number = split_lmfdb_label(self.lmfdb_iso)
        self.conductor = int(N)
        # Extract the size of the isogeny class from the database
        self.ncurves = ncurves = self.class_size
        # Create a list of the curves in the class from the database
        number_key = 'number' if self.label_type == 'Cremona' else 'lmfdb_number'
        self.curves = [
            db.ec_curves.lucky({
                'iso': self.iso,
                number_key: i + 1
            }) for i in range(ncurves)
        ]

        # Set optimality flags.  The optimal curve is number 1 except
        # in one case which is labeled differently in the Cremona tables
        self.optimality_known = (self.ncurves
                                 == 1) or (self.conductor < OPTIMALITY_BOUND)
        self.optimality_bound = OPTIMALITY_BOUND
        for c in self.curves:
            c['optimal'] = (c['number'] == (3 if self.iso == '990h' else 1))
            c['ai'] = c['ainvs']
            c['curve_url_lmfdb'] = url_for(".by_triple_label",
                                           conductor=N,
                                           iso_label=iso,
                                           number=c['lmfdb_number'])
            c['curve_url_cremona'] = url_for(".by_ec_label", label=c['label'])
            if self.label_type == 'Cremona':
                c['curve_label'] = c['label']
                _, c_iso, c_number = split_cremona_label(c['label'])
            else:
                c['curve_label'] = c['lmfdb_label']
                _, c_iso, c_number = split_lmfdb_label(c['lmfdb_label'])
            c['short_label'] = "{}{}".format(c_iso, c_number)

        from sage.matrix.all import Matrix
        if self.label_type == 'Cremona':
            # permute rows/cols
            perm = lambda i: (c for c in self.curves if c['number'] == i + 1
                              ).next()['lmfdb_number'] - 1
            self.isogeny_matrix = [[
                self.isogeny_matrix[perm(i)][perm(j)] for i in range(ncurves)
            ] for j in range(ncurves)]

        self.isogeny_matrix = Matrix(self.isogeny_matrix)

        self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix))

        # Create isogeny graph with appropriate vertex labels:

        self.graph = make_graph(self.isogeny_matrix,
                                [c['short_label'] for c in self.curves])
        P = self.graph.plot(edge_labels=True, vertex_size=1000)
        self.graph_img = encode_plot(P)
        self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img

        self.newform = web_latex(
            PowerSeriesRing(QQ, 'q')(self.anlist, 20, check=True))
        self.newform_label = db.mf_newforms.lucky(
            {
                'level': N,
                'weight': 2,
                'related_objects': {
                    '$contains': 'EllipticCurve/Q/%s/%s' % (N, iso)
                }
            }, 'label')
        self.newform_exists_in_db = self.newform_label is not None
        if self.newform_label is not None:
            char_orbit, hecke_orbit = self.newform_label.split('.')[2:]
            self.newform_link = url_for("cmf.by_url_newform_label",
                                        level=N,
                                        weight=2,
                                        char_orbit_label=char_orbit,
                                        hecke_orbit=hecke_orbit)

        self.lfunction_link = url_for("l_functions.l_function_ec_page",
                                      conductor_label=N,
                                      isogeny_class_label=iso)

        self.friends = [('L-function', self.lfunction_link)]
        if not self.CM:
            self.CM = "no"
            if int(N) <= 300:
                self.friends += [('Symmetric square L-function',
                                  url_for("l_functions.l_function_ec_sym_page",
                                          power='2',
                                          conductor=N,
                                          isogeny=iso))]
            if int(N) <= 50:
                self.friends += [('Symmetric cube L-function',
                                  url_for("l_functions.l_function_ec_sym_page",
                                          power='3',
                                          conductor=N,
                                          isogeny=iso))]
        if self.newform_exists_in_db:
            self.friends += [('Modular form ' + self.newform_label,
                              self.newform_link)]

        if self.label_type == 'Cremona':
            self.title = "Elliptic Curve Isogeny Class with Cremona label {} (LMFDB label {})".format(
                self.iso, self.lmfdb_iso)
            self.iso_label = self.iso
        else:
            self.title = "Elliptic Curve Isogeny Class with LMFDB label {} (Cremona label {})".format(
                self.lmfdb_iso, self.iso)
            self.iso_label = self.lmfdb_iso

        self.properties = [
            ('Label',
             self.iso if self.label_type == 'Cremona' else self.lmfdb_iso),
            ('Number of curves', str(ncurves)), ('Conductor', '%s' % N),
            ('CM', '%s' % self.CM), ('Rank', '%s' % self.rank)
        ]
        if self.ncurves > 1:
            self.properties += [('Graph', ''), (None, self.graph_link)]

        self.downloads = [('q-expansion to text',
                           url_for(".download_EC_qexp",
                                   label=self.lmfdb_iso,
                                   limit=1000)),
                          ('All stored data to text',
                           url_for(".download_EC_all", label=self.lmfdb_iso))]

        self.bread = [('Elliptic Curves', url_for("ecnf.index")),
                      ('$\Q$', url_for(".rational_elliptic_curves")),
                      ('%s' % N, url_for(".by_conductor", conductor=N)),
                      ('%s' % iso, ' ')]
        self.code = {}
        self.code['show'] = {'sage': ''}  # use default show names
        self.code['class'] = {
            'sage':
            'E = EllipticCurve("%s1")\n' % (self.lmfdb_iso) +
            'E.isogeny_class()\n'
        }
        self.code['curves'] = {'sage': 'E.isogeny_class().curves'}
        self.code['rank'] = {'sage': 'E.rank()'}
        self.code['q_eigenform'] = {'sage': 'E.q_eigenform(10)'}
        self.code['matrix'] = {'sage': 'E.isogeny_class().matrix()'}
        self.code['plot'] = {
            'sage': 'E.isogeny_graph().plot(edge_labels=True)'
        }
Example #53
0
def elliptic_curve_search(info):

    if info.get('download') == '1' and info.get('Submit') and info.get('query'):
        return download_search(info)

    if 'SearchAgain' in info:
        return rational_elliptic_curves()

    query = {}
    bread = info.get('bread',[('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('Search Results', '.')])

    if 'jump' in info:
        label = info.get('label', '').replace(" ", "")
        m = match_lmfdb_label(label)
        if m:
            try:
                return by_ec_label(label)
            except ValueError:
                return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif label.startswith("Cremona:"):
            label = label[8:]
            m = match_cremona_label(label)
            if m:
                try:
                    return by_ec_label(label)
                except ValueError:
                    return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif match_cremona_label(label):
            return elliptic_curve_jump_error(label, info, cremona_label=True)
        elif label:
            # Try to parse a string like [1,0,3,2,4] as valid
            # Weistrass coefficients:
            lab = re.sub(r'\s','',label)
            lab = re.sub(r'^\[','',lab)
            lab = re.sub(r']$','',lab)
            try:
                labvec = lab.split(',')
                labvec = [QQ(str(z)) for z in labvec] # Rationals allowed
                E = EllipticCurve(labvec)
                # Now we do have a valid curve over Q, but it might
                # not be in the database.
                ainvs = [str(c) for c in E.minimal_model().ainvs()]
                xainvs = ''.join(['[',','.join(ainvs),']'])
                data = db_ec().find_one({'xainvs': xainvs})
                if data is None:
                    data = db_ec().find_one({'ainvs': ainvs})
                    if data is None:
                        info['conductor'] = E.conductor()
                        return elliptic_curve_jump_error(label, info, missing_curve=True)
                return by_ec_label(data['lmfdb_label'])
            except (TypeError, ValueError, ArithmeticError):
                return elliptic_curve_jump_error(label, info)
        else:
            query['label'] = ''

    try:
        parse_rational(info,query,'jinv','j-invariant')
        parse_ints(info,query,'conductor')
        parse_ints(info,query,'torsion','torsion order')
        parse_ints(info,query,'rank')
        parse_ints(info,query,'sha','analytic order of &#1064;')
        parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,process=str,check_divisibility='increasing')
        # speed up slow torsion_structure searches by also setting torsion
        if 'torsion_structure' in query and not 'torsion' in query:
            query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
        if 'include_cm' in info:
            if info['include_cm'] == 'exclude':
                query['cm'] = 0
            elif info['include_cm'] == 'only':
                query['cm'] = {'$ne' : 0}

        parse_ints(info,query,field='isodeg',qfield='isogeny_degrees')

        parse_primes(info, query, 'surj_primes', name='surjective primes',
                     qfield='non-maximal_primes', mode='complement')
        if info.get('surj_quantifier') == 'exactly':
            mode = 'exact'
        else:
            mode = 'append'
        parse_primes(info, query, 'nonsurj_primes', name='non-surjective primes',
                     qfield='non-maximal_primes',mode=mode)
    except ValueError as err:
        info['err'] = str(err)
        return search_input_error(info, bread)

    count = parse_count(info,100)
    start = parse_start(info)

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

    info['query'] = query
    cursor = db_ec().find(query)
    nres = cursor.count()
    if(start >= nres):
        start -= (1 + (start - nres) / count) * count
    if(start < 0):
        start = 0
    res = cursor.sort([('conductor', ASCENDING), ('iso_nlabel', ASCENDING),
                       ('lmfdb_number', ASCENDING)]).skip(start).limit(count)
    info['curves'] = res
    info['format_ainvs'] = format_ainvs
    info['curve_url'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number'])
    info['iso_url'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1])
    info['number'] = nres
    info['start'] = start
    info['count'] = count
    info['more'] = int(start + count < nres)

    
    if nres == 1:
        info['report'] = 'unique match'
    elif nres == 2: 
        info['report'] = 'displaying both matches'
    else:
        if nres > count or start != 0:
            info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres)
        else:
            info['report'] = 'displaying all %s matches' % nres
    #credit = 'John Cremona'
    #if 'non-surjective_primes' in query or 'non-maximal_primes' in query:
    #    credit += ' and Andrew Sutherland'

    t = info.get('title','Elliptic Curves search results')
    return render_template("ec-search-results.html", info=info, credit=ec_credit(), bread=bread, title=t)
Example #54
0
def elliptic_curve_search(info, query):
    parse_rational(info,query,'jinv','j-invariant')
    parse_ints(info,query,'conductor')
    parse_ints(info,query,'torsion','torsion order')
    parse_ints(info,query,'rank')
    parse_ints(info,query,'sha','analytic order of &#1064;')
    parse_bracketed_posints(info,query,'torsion_structure',maxlength=2,check_divisibility='increasing')
    # speed up slow torsion_structure searches by also setting torsion
    #if 'torsion_structure' in query and not 'torsion' in query:
    #    query['torsion'] = reduce(mul,[int(n) for n in query['torsion_structure']],1)
    if 'include_cm' in info:
        if info['include_cm'] == 'exclude':
            query['cm'] = 0
        elif info['include_cm'] == 'only':
            query['cm'] = {'$ne' : 0}
    parse_element_of(info,query,field='isodeg',qfield='isogeny_degrees',split_interval=1000)
    #parse_ints(info,query,field='isodeg',qfield='isogeny_degrees')
    parse_primes(info, query, 'surj_primes', name='maximal primes',
                 qfield='nonmax_primes', mode='complement')
    if info.get('surj_quantifier') == 'exactly':
        mode = 'exact'
    else:
        mode = 'append'
    parse_primes(info, query, 'nonsurj_primes', name='non-maximal primes',
                 qfield='nonmax_primes',mode=mode, radical='nonmax_rad')
    if 'optimal' in info and info['optimal'] == 'on':
        # fails on 990h3
        query['number'] = 1

    info['curve_url'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number'])
    info['iso_url'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1])
Example #55
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)
Example #56
0
    def make_class(self):
        self.ainvs_str = self.ainvs
        self.ainvs = [int(a) for a in self.ainvs_str]
        self.E = EllipticCurve(self.ainvs)
        self.CM = self.E.has_cm()

        try:
            # Extract the isogeny degree matrix from the database
            size = len(self.isogeny_matrix)
            from sage.matrix.all import Matrix
            self.isogeny_matrix = Matrix(self.isogeny_matrix)
        except AttributeError:
            # Failsafe: construct it from scratch
            self.isogeny_matrix = self.E.isogeny_class(order="lmfdb").matrix()
            size = self.isogeny_matrix.nrows()
        self.ncurves = size

        # Create isogeny graph:
        self.graph = make_graph(self.isogeny_matrix)
        P = self.graph.plot(edge_labels=True)
        self.graph_img = encode_plot(P)
        self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img

        # Create a list of the curves in the class from the database
        self.db_curves = [self.E]
        self.optimal_flags = [False] * size
        self.degrees = [0] * size
        if self.degree:
            self.degrees[0] = self.degree
        else:
            try:
                self.degrees[0] = self.E.modular_degree()
            except RuntimeError:
                pass

        # Fill in the curves in the class by looking each one up in the db:

        self.cremona_labels = [self.label] + [0] * (size - 1)
        if self.number == 1:
            self.optimal_flags[0] = True
        for i in range(2, size + 1):
            Edata = db_ec().find_one({'lmfdb_label': self.lmfdb_iso + str(i)})
            Ei = EllipticCurve([int(a) for a in Edata['ainvs']])
            self.cremona_labels[i - 1] = Edata['label']
            if Edata['number'] == 1:
                self.optimal_flags[i - 1] = True
            if 'degree' in Edata:
                self.degrees[i - 1] = Edata['degree']
            else:
                try:
                    self.degrees[i - 1] = Ei.modular_degree()
                except RuntimeError:
                    pass
            self.db_curves.append(Ei)

        if self.iso == '990h':  # this isogeny class is labeled wrong in Cremona's tables
            self.optimal_flags = [False, False, True, False]

        self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix))

        N, iso, number = split_lmfdb_label(self.lmfdb_iso)

        self.newform = web_latex(self.E.q_eigenform(10))
        self.newform_label = newform_label(N, 2, 1, iso)
        self.newform_link = url_for("emf.render_elliptic_modular_forms",
                                    level=N,
                                    weight=2,
                                    character=1,
                                    label=iso)
        newform_exists_in_db = is_newform_in_db(self.newform_label)

        self.lfunction_link = url_for("l_functions.l_function_ec_page",
                                      label=self.lmfdb_iso)

        self.curves = [
            dict([('label', self.lmfdb_iso + str(i + 1)),
                  ('url',
                   url_for(".by_triple_label",
                           conductor=N,
                           iso_label=iso,
                           number=i + 1)),
                  ('cremona_label', self.cremona_labels[i]),
                  ('ainvs', str(list(c.ainvs()))),
                  ('torsion', c.torsion_order()), ('degree', self.degrees[i]),
                  ('optimal', self.optimal_flags[i])])
            for i, c in enumerate(self.db_curves)
        ]

        self.friends = [('L-function', self.lfunction_link)]
        if not self.CM:
            if int(N) <= 300:
                self.friends += [('Symmetric square L-function',
                                  url_for("l_functions.l_function_ec_sym_page",
                                          power='2',
                                          label=self.lmfdb_iso))]
            if int(N) <= 50:
                self.friends += [('Symmetric cube L-function',
                                  url_for("l_functions.l_function_ec_sym_page",
                                          power='3',
                                          label=self.lmfdb_iso))]
        if newform_exists_in_db:
            self.friends += [('Modular form ' + self.newform_label,
                              self.newform_link)]

        self.properties = [('Label', self.lmfdb_iso),
                           ('Number of curves', str(self.ncurves)),
                           ('Conductor', '\(%s\)' % N), ('CM', '%s' % self.CM),
                           ('Rank', '\(%s\)' % self.rank), ('Graph', ''),
                           (None, self.graph_link)]

        self.downloads = [('Download coefficients of newform',
                           url_for(".download_EC_qexp",
                                   label=self.lmfdb_iso,
                                   limit=100)),
                          ('Download stored data for all curves',
                           url_for(".download_EC_all", label=self.lmfdb_iso))]

        if self.lmfdb_iso == self.iso:
            self.title = "Elliptic Curve Isogeny Class %s" % self.lmfdb_iso
        else:
            self.title = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % (
                self.lmfdb_iso, self.iso)

        self.bread = [('Elliptic Curves', url_for("ecnf.index")),
                      ('$\Q$', url_for(".rational_elliptic_curves")),
                      ('%s' % N, url_for(".by_conductor", conductor=N)),
                      ('%s' % iso, ' ')]
Example #57
0
    def make_class(self):
        self.CM = self.cm
        N, iso, number = split_lmfdb_label(self.lmfdb_iso)

        # Extract the size of the isogeny class from the database
        ncurves = self.class_size
        # Create a list of the curves in the class from the database
        self.curves = [db.ec_curves.lucky({'iso':self.iso, 'lmfdb_number': i+1})
                          for i in range(ncurves)]

        # Set optimality flags.  The optimal curve is number 1 except
        # in one case which is labeled differently in the Cremona tables
        for c in self.curves:
            c['optimal'] = (c['number']==(3 if self.label == '990h' else 1))
            c['ai'] = c['ainvs']
            c['url'] = url_for(".by_triple_label", conductor=N, iso_label=iso, number=c['lmfdb_number'])

        from sage.matrix.all import Matrix
        self.isogeny_matrix = Matrix(self.isogeny_matrix)
        self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix))

        # Create isogeny graph:
        self.graph = make_graph(self.isogeny_matrix)
        P = self.graph.plot(edge_labels=True)
        self.graph_img = encode_plot(P)
        self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img


        self.newform =  web_latex(PowerSeriesRing(QQ, 'q')(self.anlist, 20, check=True))
        self.newform_label = db.mf_newforms.lucky({'level':N, 'weight':2, 'related_objects':{'$contains':'EllipticCurve/Q/%s/%s' % (N, iso)}},'label')
        self.newform_exists_in_db = self.newform_label is not None
        if self.newform_label is not None:
            char_orbit, hecke_orbit = self.newform_label.split('.')[2:]
            self.newform_link = url_for("cmf.by_url_newform_label", level=N, weight=2, char_orbit_label=char_orbit, hecke_orbit=hecke_orbit)

        self.lfunction_link = url_for("l_functions.l_function_ec_page", conductor_label = N, isogeny_class_label = iso)

        self.friends =  [('L-function', self.lfunction_link)]
        if not self.CM:
            self.CM = "no"
            if int(N)<=300:
                self.friends += [('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', conductor = N, isogeny = iso))]
            if int(N)<=50:
                self.friends += [('Symmetric cube L-function', url_for("l_functions.l_function_ec_sym_page", power='3', conductor = N, isogeny = iso))]
        if self.newform_exists_in_db:
            self.friends +=  [('Modular form ' + self.newform_label, self.newform_link)]

        self.properties = [('Label', self.lmfdb_iso),
                           ('Number of curves', str(ncurves)),
                           ('Conductor', '\(%s\)' % N),
                           ('CM', '%s' % self.CM),
                           ('Rank', '\(%s\)' % self.rank),
                           ('Graph', ''),(None, self.graph_link)
                           ]


        self.downloads = [('Download q-expansion', url_for(".download_EC_qexp", label=self.lmfdb_iso, limit=1000)),
                         ('Download stored data for all curves', url_for(".download_EC_all", label=self.lmfdb_iso))]

        if self.lmfdb_iso == self.iso:
            self.title = "Elliptic Curve Isogeny Class %s" % self.lmfdb_iso
        else:
            self.title = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % (self.lmfdb_iso, self.iso)

        self.bread = [('Elliptic Curves', url_for("ecnf.index")),
                      ('$\Q$', url_for(".rational_elliptic_curves")),
                      ('%s' % N, url_for(".by_conductor", conductor=N)),
                      ('%s' % iso, ' ')]
        self.code = {}
        self.code['show'] = {'sage':''} # use default show names
        self.code['class'] = {'sage':'E = EllipticCurve("%s1")\n'%(self.lmfdb_iso) + 'E.isogeny_class()\n'}
        self.code['curves'] = {'sage':'E.isogeny_class().curves'}
        self.code['rank'] = {'sage':'E.rank()'}
        self.code['q_eigenform'] = {'sage':'E.q_eigenform(10)'}
        self.code['matrix'] = {'sage':'E.isogeny_class().matrix()'}
        self.code['plot'] = {'sage':'E.isogeny_graph().plot(edge_labels=True)'}
Example #58
0
def elliptic_curve_search(**args):
    info = to_dict(args)

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

    query = {}
    bread = [
        ("Elliptic Curves", url_for("ecnf.index")),
        ("$\Q$", url_for(".rational_elliptic_curves")),
        ("Search Results", "."),
    ]
    if "SearchAgain" in args:
        return rational_elliptic_curves()

    if "jump" in args:
        label = info.get("label", "").replace(" ", "")
        m = match_lmfdb_label(label)
        if m:
            try:
                return by_ec_label(label)
            except ValueError:
                return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif label.startswith("Cremona:"):
            label = label[8:]
            m = match_cremona_label(label)
            if m:
                try:
                    return by_ec_label(label)
                except ValueError:
                    return elliptic_curve_jump_error(label, info, wellformed_label=True)
        elif match_cremona_label(label):
            return elliptic_curve_jump_error(label, info, cremona_label=True)
        elif label:
            # Try to parse a string like [1,0,3,2,4] as valid
            # Weistrass coefficients:
            lab = re.sub(r"\s", "", label)
            lab = re.sub(r"^\[", "", lab)
            lab = re.sub(r"]$", "", lab)
            try:
                labvec = lab.split(",")
                labvec = [QQ(str(z)) for z in labvec]  # Rationals allowed
                E = EllipticCurve(labvec)
                # Now we do have a valid curve over Q, but it might
                # not be in the database.
                ainvs = [str(c) for c in E.minimal_model().ainvs()]
                data = db_ec().find_one({"ainvs": ainvs})
                if data is None:
                    info["conductor"] = E.conductor()
                    return elliptic_curve_jump_error(label, info, missing_curve=True)
                return by_ec_label(data["lmfdb_label"])
            except (TypeError, ValueError, ArithmeticError):
                return elliptic_curve_jump_error(label, info)
        else:
            query["label"] = ""

    try:
        parse_rational(info, query, "jinv", "j-invariant")
        parse_ints(info, query, "conductor")
        parse_ints(info, query, "torsion", "torsion order")
        parse_ints(info, query, "rank")
        parse_ints(info, query, "sha", "analytic order of &#1064;")
        parse_bracketed_posints(
            info, query, "torsion_structure", maxlength=2, process=str, check_divisibility="increasing"
        )
        parse_primes(
            info, query, "surj_primes", name="surjective primes", qfield="non-surjective_primes", mode="complement"
        )
        if info.get("surj_quantifier") == "exactly":
            mode = "exact"
        else:
            mode = "append"
        parse_primes(
            info, query, "nonsurj_primes", name="non-surjective primes", qfield="non-surjective_primes", mode=mode
        )
    except ValueError as err:
        info["err"] = str(err)
        return search_input_error(info, bread)

    count = parse_count(info, 100)
    start = parse_start(info)

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

    info["query"] = query
    cursor = db_ec().find(query)
    nres = cursor.count()
    if start >= nres:
        start -= (1 + (start - nres) / count) * count
    if start < 0:
        start = 0
    res = (
        cursor.sort([("conductor", ASCENDING), ("iso_nlabel", ASCENDING), ("lmfdb_number", ASCENDING)])
        .skip(start)
        .limit(count)
    )
    info["curves"] = res
    info["format_ainvs"] = format_ainvs
    info["curve_url"] = lambda dbc: url_for(
        ".by_triple_label",
        conductor=dbc["conductor"],
        iso_label=split_lmfdb_label(dbc["lmfdb_iso"])[1],
        number=dbc["lmfdb_number"],
    )
    info["iso_url"] = lambda dbc: url_for(
        ".by_double_iso_label", conductor=dbc["conductor"], iso_label=split_lmfdb_label(dbc["lmfdb_iso"])[1]
    )
    info["number"] = nres
    info["start"] = start
    info["count"] = count
    info["more"] = int(start + count < nres)

    if nres == 1:
        info["report"] = "unique match"
    elif nres == 2:
        info["report"] = "displaying both matches"
    else:
        if nres > count or start != 0:
            info["report"] = "displaying matches %s-%s of %s" % (start + 1, min(nres, start + count), nres)
        else:
            info["report"] = "displaying all %s matches" % nres
    credit = "John Cremona"
    if "non-surjective_primes" in query:
        credit += "and Andrew Sutherland"
    t = "Elliptic Curves search results"
    return render_template("search_results.html", info=info, credit=credit, bread=bread, title=t)