Skip to content

Commit

Permalink
Merge pull request #6270 from LMFDB/main
Browse files Browse the repository at this point in the history
main -> dev
  • Loading branch information
roed314 authored Nov 20, 2024
2 parents 61a071b + c8be045 commit d27dd17
Show file tree
Hide file tree
Showing 13 changed files with 465 additions and 51 deletions.
10 changes: 6 additions & 4 deletions lmfdb/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,12 @@ def options():
return render_template(
"database_options.html",
title="Access options for the LMFDB database",
learnmore=[("API", url_for(".index")),
("Table statistics", url_for(".stats")),
("lmfdb-lite", "https://www.github.com/roed314/lmfdb-lite"),
("Install the LMFDB locally", "https://github.com/LMFDB/lmfdb/blob/main/GettingStarted.md")],
learnmore=[
("Auxiliary datasets", url_for("datasets")),
("API", url_for(".index")),
("Table statistics", url_for(".stats")),
("lmfdb-lite", "https://www.github.com/roed314/lmfdb-lite"),
("Install the LMFDB locally", "https://github.com/LMFDB/lmfdb/blob/main/GettingStarted.md")],
bread=[("Access options", " ")],
)

Expand Down
2 changes: 1 addition & 1 deletion lmfdb/api/templates/database_options.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<div style="max-width:700px;">
<p>
There are three options available to access large amounts of data from the LMFDB.
The LMFDB contains two types of underlying data: the main PostgreSQL database and a collection of <a href="{{url_for('datasets')}}">auxiliary datasets</a>. There are three options available for accessing large parts of the main database.
</p>
</div>

Expand Down
4 changes: 4 additions & 0 deletions lmfdb/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,10 @@ def groups():

# @app.route("/Group/history")

@app.route('/datasets')
@app.route('/datasets/')
def datasets():
return render_template('datasets.html', title='Auxiliary datasets', bread=[("Datasets", " ")])

def groups_history():
t = 'Groups'
Expand Down
113 changes: 110 additions & 3 deletions lmfdb/elliptic_curves/elliptic_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ def learnmore_list():
('Completeness of the data', url_for(".completeness_page")),
('Reliability of the data', url_for(".reliability_page")),
('Elliptic curve labels', url_for(".labels_page")),
('Congruent number curves', url_for(".render_congruent_number_data"))]
('Congruent number curves', url_for(".render_congruent_number_data")),
('Stein-Watkins dataset', url_for(".render_sw_ecdb")),
('BHKSSW dataset', url_for(".render_bhkssw"))]


def learnmore_list_add(learnmore_label, learnmore_url):
Expand Down Expand Up @@ -931,14 +933,14 @@ def render_congruent_number_data():
return redirect(url_for(".render_single_congruent_number", n=info['lookup']))
learnmore = learnmore_list_remove('Congruent numbers and curves')
t = 'Congruent numbers and congruent number curves'
bread = get_bread(t)
bread = [("Datasets", url_for("datasets")), (t, " ")]
if 'filename' in info:
filepath = os.path.join(congruent_number_data_directory,info['filename'])
if os.path.isfile(filepath) and os.access(filepath, os.R_OK):
return send_file(filepath, as_attachment=True)
else:
flash_error('File {} not found'.format(info['filename']))
return redirect(url_for(".rational_elliptic_curves"))
return redirect(url_for(".render_congruent_number_data"))

return render_template("congruent_number_data.html", info=info, title=t, bread=bread, learnmore=learnmore)

Expand All @@ -952,6 +954,111 @@ def render_single_congruent_number(n):
bread = get_bread() + [("Congruent numbers", url_for(".render_congruent_number_data")), (n, "")]
return render_template("single_congruent_number.html", info=info, title=t, bread=bread, learnmore=learnmore_list())

@ec_page.route("/stein-watkins")
def render_sw_ecdb():
info = to_dict(request.args)
learnmore = learnmore_list_remove('Stein-Watkins dataset')
t = 'Stein-Watkins elliptic curve database'
bread = [("Datasets", url_for("datasets")), ("Stein-Watkins dataset", " ")]
if 'Fetch' in info:
errors = []
if info.get("ctype") == "all":
fname = "a.{:03d}"
kmax = 999
elif info.get("ctype") == "prime":
fname = "p.{:02d}"
kmax = 99
else:
errors.append("Invalid conductor type")
if 'k' in info and not errors:
k = info["k"].strip()
if k.isdigit():
k = int(k)
if k <= kmax:
fname = fname.format(k)
else:
errors.append(f"k must be at most {kmax}")
else:
errors.append(f"k must be a nonnegative integer at most {kmax}")
if not errors:
filepath = os.path.expanduser('~/data/stein_watkins_ecdb/' + fname)
if os.path.isfile(filepath) and os.access(filepath, os.R_OK):
return send_file(filepath, as_attachment=True)
errors.append(f"File {fname} not found")
for err in errors:
flash_error(err)

return render_template("sw_ecdb.html", info=info, comma=comma, title=t, bread=bread, learnmore=learnmore)

@ec_page.route("/BHKSSW")
def render_bhkssw():
info = to_dict(request.args)
learnmore = learnmore_list_remove('BHKSSW dataset')
t = 'Balakrishnan-Ho-Kaplan-Spicer-Stein-Watkins elliptic curve database'
bread = [("Datasets", url_for("datasets")), ("BHKSSW dataset", " ")]
if 'filename' in info:
filepath = os.path.join(os.path.expanduser('~/data/bhkssw_ecdb/' + info['filename']))
if os.path.isfile(filepath) and os.access(filepath, os.R_OK):
return send_file(filepath, as_attachment=True)
else:
flash_error('File {} not found'.format(info['filename']))
return redirect(url_for(".render_bhkssw"))
# This format was nice, but not possible with the 30-second timeout limitation
#info['files'] = [ # number of curves, size in MB, lower bound, upper bound, filename
# (2249362, 151, "0", r"1 \cdot 10^8", "1e8db.txt"),
# (1758056, 123, r"1 \cdot 10^8", r"2 \cdot 10^8", "2e8db.txt"),
# (11300506, 798, r"2 \cdot 10^8", r"1 \cdot 10^9", "1e9db.txt"),
# (11982016, 866, r"1 \cdot 10^9", r"2 \cdot 10^9", "2e9db.txt"),
# (10976368, 800, r"2 \cdot 10^9", r"3 \cdot 10^9", "3e9db.txt"),
# (10395560, 768, r"3 \cdot 10^9", r"4 \cdot 10^9", "4e9db.txt"),
# (9932368, 744, r"4 \cdot 10^9", r"5 \cdot 10^9", "5e9db.txt"),
# (9584588, 720, r"5 \cdot 10^9", r"6 \cdot 10^9", "6e9db.txt"),
# (9385318, 707, r"6 \cdot 10^9", r"7 \cdot 10^9", "7e9db.txt"),
# (9071666, 685, r"7 \cdot 10^9", r"8 \cdot 10^9", "8e9db.txt"),
# (8975214, 679, r"8 \cdot 10^9", r"9 \cdot 10^9", "9e9db.txt"),
# (8788686, 666, r"9 \cdot 10^9", r"1.0 \cdot 10^{10}", "10e9db.txt"),
# (8642210, 664, r"1.0 \cdot 10^{10}", r"1.1 \cdot 10^{10}", "11e9db.txt"),
# (8477024, 652, r"1.1 \cdot 10^{10}", r"1.2 \cdot 10^{10}", "12e9db.txt"),
# (8383290, 645, r"1.2 \cdot 10^{10}", r"1.3 \cdot 10^{10}", "13e9db.txt"),
# (8275108, 638, r"1.3 \cdot 10^{10}", r"1.4 \cdot 10^{10}", "14e9db.txt"),
# (8143456, 628, r"1.4 \cdot 10^{10}", r"1.5 \cdot 10^{10}", "15e9db.txt"),
# (8106334, 626, r"1.5 \cdot 10^{10}", r"1.6 \cdot 10^{10}", "16e9db.txt"),
# (7959996, 615, r"1.6 \cdot 10^{10}", r"1.7 \cdot 10^{10}", "17e9db.txt"),
# (7903210, 611, r"1.7 \cdot 10^{10}", r"1.8 \cdot 10^{10}", "18e9db.txt"),
# (7849564, 607, r"1.8 \cdot 10^{10}", r"1.9 \cdot 10^{10}", "19e9db.txt"),
# (7781996, 602, r"1.9 \cdot 10^{10}", r"2.0 \cdot 10^{10}", "20e9db.txt"),
# (7822372, 605, r"2.0 \cdot 10^{10}", r"2.1 \cdot 10^{10}", "21e9db.txt"),
# (7636198, 591, r"2.1 \cdot 10^{10}", r"2.2 \cdot 10^{10}", "22e9db.txt"),
# (7562706, 586, r"2.2 \cdot 10^{10}", r"2.3 \cdot 10^{10}", "23e9db.txt"),
# (7593218, 588, r"2.3 \cdot 10^{10}", r"2.4 \cdot 10^{10}", "24e9db.txt"),
# (7505566, 582, r"2.4 \cdot 10^{10}", r"2.5 \cdot 10^{10}", "25e9db.txt"),
# (7409408, 575, r"2.5 \cdot 10^{10}", r"2.6 \cdot 10^{10}", "26e9db.txt"),
# (7312946, 567, r"2.6 \cdot 10^{10}", r"2.7 \cdot 10^{10}", "27e9db.txt"),
#]
if 'Fetch' in info:
fname = "{}.txt"
kmax = 2699
errors = []
if 'k' in info and not errors:
k = info["k"].strip()
if k.isdigit():
k = int(k)
if k <= kmax:
fname = fname.format(k)
else:
errors.append(f"k must be at most {kmax}")
else:
errors.append(f"k must be a positive integer at most {kmax}")
if not errors:
filepath = os.path.expanduser('~/data/bhkssw_split/' + fname)
if os.path.isfile(filepath) and os.access(filepath, os.R_OK):
return send_file(filepath, as_attachment=True)
errors.append(f"File {fname} not found")
for err in errors:
flash_error(err)

return render_template("bhkssw.html", info=info, comma=comma, title=t, bread=bread, learnmore=learnmore)

sorted_code_names = ['curve', 'simple_curve', 'mwgroup', 'gens', 'tors', 'intpts', 'cond', 'disc', 'jinv', 'cm', 'faltings', 'stable_faltings', 'rank', 'analytic_rank', 'reg', 'real_period', 'cp', 'ntors', 'sha', 'L1', 'bsd_formula', 'qexp', 'moddeg', 'manin', 'localdata', 'galrep']

code_names = {'curve': 'Define the curve',
Expand Down
137 changes: 137 additions & 0 deletions lmfdb/elliptic_curves/templates/bhkssw.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
{% extends 'homepage.html' %}

{% block content %}

<p>
This dataset contains all 238,764,310 {{KNOWL('ec.q', 'elliptic curves')}} over $\Q$ with {{ KNOWL('ec.q.naive_height', 'naive height') }} up to $2.7 \cdot 10^{10}$ and is described in <a href="https://doi.org/10.1112/S1461157016000152">Balakrishnan-Ho-Kaplan-Spicer-Stein-Watkins</a>.
</p>

<h3>File and data format</h3>

<p>
The data is stored in text files, indexed from $k=0$ to $k=2699$. The file $k$.txt contains all of the elliptic curves whose minimal short Weierstrass form $y^2 = x^3 + A x + B$ has naive height $H$ in the range: the $k$th file contains data for $k \cdot 10^7 < H \le (k+1) \cdot 10^7$.
</p>

<p>
Each line corresponds to an elliptic curve, with columns separated by | characters and format given as follows. If a column has not been computed it is saved as the empty string.
</p>

<table class="ntdata">
<tr>
<th>Column(s)</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td>$H$</td>
<td>{{KNOWL('ec.q.naive_height', 'Naive height')}}</td>
<td>$19003704300$</td>
</tr>
<tr>
<td>$a_1$, $a_2$, $a_3$, $a_4$, $a_6$</td>
<td>$a$-invariants for the {{KNOWL('ec.q.minimal_weierstrass_equation', 'reduced minimal model')}}</td>
<td>$1$, $-1$, $0$, $-102$, $-389$</td>
</tr>
<tr>
<td>$p_1$, $p_2$</td>
<td>Parameters to form the elliptic curve, which is isomorphic to $y^2 = x^3 + p_1 x + p_2$</td>
<td>$-1635$, $-26530$</td>
</tr>
<tr>
<td>$N$</td>
<td>{{KNOWL('ec.q.conductor', 'Conductor')}}</td>
<td>$5940675$</td>
</tr>
<tr>
<td>$\operatorname{tam}$</td>
<td>{{KNOWL('ec.tamagawa_number', 'Tamagawa product')}}</td>
<td>$1$</td>
</tr>
<tr>
<td>$n_1$, $n_2$</td>
<td>structure of {{KNOWL('ec.q.torsion_subgroup', 'torsion subgroup')}}, $\Z/n_1 \times \Z/n_2$ where $n_1 \in {1, 2}$ and $n_1 \mid n_2$</td>
<td>$1$, $1$</td>
</tr>
<tr>
<td>$\operatorname{sel}_2$</td>
<td>$2$-rank of the {{KNOWL('ag.selmer_group', '$2$-Selmer group')}}</td>
<td>$2$</td>
</tr>
<tr>
<td>$w$</td>
<td>Root number (sign of functional equation)</td>
<td>$-1$</td>
</tr>
<tr>
<td>$r_{\mathrm{an},0}$</td>
<td>Running analytic_rank_upper_bound in Sage with parameter $\delta$ (see below) returns $r_{\mathrm{an},0}$, which is an upper bound for the rank</td>
<td>$0$</td>
</tr>
<tr>
<td>$\operatorname{mw}_{\mathrm{ub}}, \operatorname{mw}_{\mathrm{lb}}, \operatorname{mw}_{\mathrm{time}}$</td>
<td>Upper and lower bounds returned by mwrank in Sage, as well as the the time used</td>
<td>$2, 2, 0.052$</td>
</tr>
<tr>
<td>$\delta$</td>
<td>Running analytic_rank_upper_bound in Sage with parameter $\delta$ returns $r_{\mathrm{an},0}$ (see above), which is an upper bound for the rank.</td>
<td>$2.0$</td>
</tr>
<tr>
<td>$\operatorname{magma}$</td>
<td>Rank computed by the Magma function MordellWeilShaInformation (almost always null)</td>
<td>$2$</td>
</tr>
<tr>
<td>$r$</td>
<td>{{KNOWL('ec.rank', 'rank')}}</td>
<td>$4$</td>
</tr>
<tr>
<td>$\operatorname{CM}$</td>
<td>1 if $E$ has {{KNOWL('ec.complex_multiplication', 'CM')}}, 0 otherwise</td>
<td>$0$</td>
</tr>
</table>

<h3>Download</h3>

<form>
<table>
<tr>
<td align="right">$k = $</td>
<td align="left">
<input type="text" name="k" size="7" placeholder="123">
<span class="formexample">integer from 0 to 2699</span>
</td>
</tr>
<tr>
<td align="left">
<button type="submit" name="Fetch" value="fetch">Fetch file</button>
</td>
</tr>
</table>
</form>

{# This format was nice since it gave statistics and provided direct download links, but the files are too big to download given the current 30-second timeout limitation.
<table class="ntdata">
<tr>
<th>File</th>
<th>Size (MB)</th>
<th>Number of curves</th>
<th>Lower height bound</th>
<th>Upper height bound</th>
</tr>
{% for ncurves, size, lower, upper, fname in info.files %}
<tr>
<td><a href="{{ url_for('.render_bhkssw', filename=fname) }}">{{fname}}</a></td>
<td>{{size}}</td>
<td>{{comma(ncurves)}}</td>
<td>${{lower}}$</td>
<td>${{upper}}$</td>
</tr>
{% endfor %}
</table>
#}

{% endblock %}
2 changes: 1 addition & 1 deletion lmfdb/elliptic_curves/templates/congruent_number_data.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ <h2>Data files</h2>
<pre>000137 [[-3136/25,77112/125],[-38025/289,2151240/4913]]</pre>
</td>
<td>
For eight rank 2 curves, the second generator is not known and given as [?,?]
For three rank 2 curves, the second generator is not known and given as [?,?]
</td>
</tr>

Expand Down
Loading

0 comments on commit d27dd17

Please sign in to comment.