Skip to content

Commit 0f78401

Browse files
roed314claude
andcommitted
Add curves as a search column for abvar/fq (LMFDB#6975)
Register a default-off Curves column on the abelian varieties over Fq search page, displaying the first curve equation (TeXified, with the count of remaining ones) and including the full list of equations in search downloads. The curves attribute of AbvarFq_isoclass now defaults to None so that rows whose curves have not been computed (stored as NULL and omitted from psycodict records) display an empty cell and download as null; the TeXification of stored equations is factored out of curve_display for reuse. Verified with a new test in test_av.py (full lmfdb/abvar/fq/test_av.py suite passes) plus manual checks of search pages, all download languages, and homepage regressions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5ef81bd commit 0f78401

3 files changed

Lines changed: 49 additions & 6 deletions

File tree

lmfdb/abvar/fq/isog_class.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,30 @@ def validate_label(label):
6969
raise ValueError("the final part must be of the form c1_c2_..._cg, with each ci consisting of lower case letters")
7070

7171

72+
def formatted_curve_equation(cv):
73+
"""
74+
TeXify a curve equation as stored in the curves column of av_fq_isog,
75+
appending "=0" if the stored string is a bare polynomial.
76+
"""
77+
cv = teXify_pol(cv)
78+
if "=" not in cv:
79+
cv = cv + "=0"
80+
return cv
81+
82+
83+
def curves_display_search(curves):
84+
"""
85+
A compact rendering of the curves column for search results pages;
86+
the full list is available on the homepage and in downloads.
87+
"""
88+
if not curves:
89+
return ""
90+
disp = "$%s$" % formatted_curve_equation(curves[0])
91+
if len(curves) > 1:
92+
disp += " and %s more" % (len(curves) - 1)
93+
return disp
94+
95+
7296
class AbvarFq_isoclass():
7397
"""
7498
Class for an isogeny class of abelian varieties over a finite field
@@ -80,6 +104,8 @@ def __init__(self, dbdata):
80104
dbdata["hyp_count"] = None
81105
if "jacobian_count" not in dbdata:
82106
dbdata["jacobian_count"] = None
107+
if "curves" not in dbdata:
108+
dbdata["curves"] = None
83109
# New invariants: cyclicity and noncyclic primes
84110
if "is_cyclic" not in dbdata:
85111
dbdata["is_cyclic"] = None
@@ -466,10 +492,7 @@ def twist_display(self, show_all):
466492

467493
def curve_display(self):
468494
def show_curve(cv):
469-
cv = teXify_pol(cv)
470-
if "=" not in cv:
471-
cv = cv + "=0"
472-
return " <li>$%s$</li>\n" % cv
495+
return " <li>$%s$</li>\n" % formatted_curve_equation(cv)
473496
if hasattr(self, "curves") and self.curves:
474497
s = "\n<ul>\n"
475498
cutoff = 20 if len(self.curves) > 30 else len(self.curves)

lmfdb/abvar/fq/main.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from lmfdb.api import datapage
1717
from . import abvarfq_page
1818
from .search_parsing import parse_nf_string, parse_galgrp
19-
from .isog_class import validate_label, AbvarFq_isoclass
19+
from .isog_class import validate_label, AbvarFq_isoclass, curves_display_search
2020
from .stats import AbvarFqStats
2121
from lmfdb.number_fields.web_number_field import nf_display_knowl, field_pretty
2222
from lmfdb.utils import redirect_no_cache
@@ -706,13 +706,15 @@ def extended_code(c):
706706
MathCol("abvar_counts", "ag.fq.point_counts", r"$\mathbb{F}_{q^k}$ points on variety", short_title="Fq^k points on variety", default=False),
707707
MathCol("jacobian_count", "av.jacobian_count", "Jacobians", default=False),
708708
MathCol("hyp_count", "av.hyperelliptic_count", "Hyperelliptic Jacobians", default=False),
709+
ProcessedCol("curves", "ag.jacobian", "Curves", curves_display_search, default=False,
710+
download_desc="Equations of curves whose Jacobians are in the isogeny class. For a base field GF(p^r) with r > 1, the variable a denotes a generator of the base field over its prime field. The list may be empty or missing if no such curves are known."),
709711
MathCol("twist_count", "av.twist", "Num. twists", default=False),
710712
MathCol("max_twist_degree", "av.twist", "Max. twist degree", default=False),
711713
MathCol("geometric_extension_degree", "av.endomorphism_field", "End. degree", default=False),
712714
ProcessedCol("number_fields", "av.fq.number_field", "Number fields", lambda nfs: ", ".join(nf_display_knowl(nf, field_pretty(nf)) for nf in nfs), default=False),
713715
SearchCol("galois_groups_pretty", "nf.galois_group", "Galois groups", download_col="galois_groups", default=False),
714716
SearchCol("decomposition_display_search", "av.decomposition", "Isogeny factors", download_col="decompositionraw")],
715-
db_cols=["label", "g", "q", "poly", "p_rank", "p_rank_deficit", "is_simple", "is_geometrically_simple", "simple_distinct", "simple_multiplicities", "is_primitive", "primitive_models", "curve_count", "curve_counts", "abvar_count", "abvar_counts", "jacobian_count", "hyp_count", "number_fields", "galois_groups", "slopes", "newton_elevation", "twist_count", "max_twist_degree", "geometric_extension_degree", "angle_rank", "angle_corank", "is_supersingular", "has_principal_polarization", "has_jacobian", "is_cyclic", "noncyclic_primes"])
717+
db_cols=["label", "g", "q", "poly", "p_rank", "p_rank_deficit", "is_simple", "is_geometrically_simple", "simple_distinct", "simple_multiplicities", "is_primitive", "primitive_models", "curve_count", "curve_counts", "curves", "abvar_count", "abvar_counts", "jacobian_count", "hyp_count", "number_fields", "galois_groups", "slopes", "newton_elevation", "twist_count", "max_twist_degree", "geometric_extension_degree", "angle_rank", "angle_corank", "is_supersingular", "has_principal_polarization", "has_jacobian", "is_cyclic", "noncyclic_primes"])
716718

717719
def abvar_postprocess(res, info, query):
718720
gals = set()

lmfdb/abvar/fq/test_av.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,24 @@ def test_download_curves(self):
158158
page = self.tc.get('Variety/Abelian/Fq/download_curves/5.3.ac_e_ai_v_abl', follow_redirects=True)
159159
assert 'No curves for abelian variety isogeny class 5.3.ac_e_ai_v_abl' in page.get_data(as_text=True)
160160

161+
def test_curves_search_column(self):
162+
r"""
163+
Test the curves column on search results pages, including downloads.
164+
"""
165+
# The column is available in the column dropdown
166+
page = self.tc.get("/Variety/Abelian/Fq/?q=4&g=1").get_data(as_text=True)
167+
assert '<option value="curves">' in page
168+
# A single curve is displayed as is, longer lists are truncated
169+
page = self.tc.get("/Variety/Abelian/Fq/?q=4&g=1&showcol=curves").get_data(as_text=True)
170+
assert "$y^2+y=x^3+a$" in page
171+
assert "$y^2+a y=x^3$ and 1 more" in page
172+
# Search downloads contain the full lists
173+
data = self.tc.get("/Variety/Abelian/Fq/?q=4&g=1&showcol=curves&Submit=sage&download=1&query=%7B%27q%27%3A+4%2C+%27g%27%3A+1%7D").get_data(as_text=True)
174+
assert '["y^2+a*y=x^3", "y^2+(a+1)*y=x^3"]' in data
175+
# Classes for which curves have not been computed display an empty cell
176+
page = self.tc.get("/Variety/Abelian/Fq/?q=729&g=2&showcol=curves").get_data(as_text=True)
177+
assert "2.729.aee_gmg" in page
178+
161179
def test_cyclic_group_of_points_display(self):
162180
r"""
163181
Check that the cyclic group of points information is displayed

0 commit comments

Comments
 (0)