Skip to content

Validate Euler factor links to abelian varieties over Fq on L-function pages - #7165

Open
roed-math wants to merge 4 commits into
LMFDB:mainfrom
roed-math:ai/t37-euler-avfq-links
Open

Validate Euler factor links to abelian varieties over Fq on L-function pages#7165
roed-math wants to merge 4 commits into
LMFDB:mainfrom
roed-math:ai/t37-euler-avfq-links

Conversation

@roed-math

Copy link
Copy Markdown
Contributor

Closes #4535.
Closes #4922.

L-function pages of motivic weight 1 link each good-prime Euler factor to the corresponding isogeny class of abelian varieties over F_p (feature introduced in #6573). This PR hardens that linking.

A new Lfactor_to_gq check confirms the factor is genuinely the reciprocal Weil polynomial of an abelian variety over F_p (even degree, integral, lead p^g, self-dual) before a label is displayed, so malformed or non-Weil factors now give an empty cell instead of a ValueError-driven 500 or a wrong/garbage label, while out-of-range (g,q) still shows a plain unlinked label.

The av/Fq coverage lookup now happens lazily at first use instead of at module import, and the row's prime is passed in so the label can be checked against it.

Verified against av_fq_isog data (11.a links 1.2.c at p=2 with 5 = #E(F_2) points; genus 2 curve 169.a links 2.2.d_f, its reduced Jacobian) and covered by new tests in test_lfunctions.py; the full lfunctions suite passes.


Ported from roed-math#29, where the full write-up and comment history live.

🤖 Generated with Claude Code

roed314 and others added 4 commits July 19, 2026 11:59
…FDB#4535, LMFDB#4922)

The isogeny class column of the L-function Euler factor table (added in
LMFDB#6573) derived (g, q) from the factor's leading coefficient via
nth_root, which raises ValueError (a 500 page) when the coefficient is
not a perfect g-th power, and produced garbage labels for factors that
are not genuine Weil polynomials (negative lead, non-self-dual).  Add
Lfactor_to_gq, which checks that the factor is the reciprocal Weil
polynomial of an abelian variety over F_p (even degree, integral,
constant term 1, leading coefficient p^g, self-duality
a_{2g-i} = q^{g-i} a_i) and pass the row's prime in from lfuncEPhtml,
leaving the cell empty otherwise; out-of-range (g, q) still shows a
plain unlinked label.  Also defer the AbvarFqStats query from module
import to first use.

Verified on 11.a (links 1.2.c at p=2, matching 5 = #E(F_2)), genus 2
curve 169.a (2.2.d_f at p=2, the reduced Jacobian, matching
av_fq_isog.poly and 19 points), an EC/NF and degree 6/8 CMF pages
(labels beyond av/Fq coverage stay unlinked), and EC/G2C isogeny class
pages; new tests in test_lfunctions.py plus the full suite (25 passed)
and pyflakes are clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…v/Fq links (LMFDB#4535)

Lfactor_to_gq checked reciprocity but not the root condition, so self-dual
non-Weil factors like [1, 10, 2] (x^2 + 10x + 2 violates the Hasse bound at
p = 2) produced links to wrong or nonexistent isogeny classes.  Now the
reversal must pass Sage's exact is_weil_polynomial (Sturm's theorem, no
floating point; 26-53us per call for g = 1..6).  For proper prime powers,
where Weil does not imply realizable (x^2 + 25 over F_25, Honda-Tate), the
link emitter confirms the label against av_fq_isog; pages always pass a
prime, where Weil is exactly Honda-Tate, so page renders add no queries.
polynomial_unroll now rejects empty/non-list payloads with ValueError
(previously IndexError escaped to a 500) and gives prod an initial
polynomial so exponent-0 factorizations no longer raise; Lfactor_to_gq
catches these and returns None.

Verified: new must-reject unit tests ([1,10,2], boundary (x+2)^2, malformed
flat/factored payloads); av/Fq link counts on six real L-function pages
(EC/Q 11.a, G2C 169.a, EC/NF deg 4, deg 6, deg 8) identical before/after;
full lfunctions suite 27 passed; pyflakes clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Follow-up to the review of the malformed-Euler-factor hardening.  Behavior
for valid local factors is unchanged: valid in-range factors still link to
av/Fq, valid factors outside database coverage still show a plain label,
and bad primes still get no link.

Renderer: the nested row() in lfuncEPhtml indexed poly[0] and chose a
formatter before its try block, so an empty local factor raised IndexError
and a malformed factorization raised ValueError out of the page (a 500);
the fallback caught only IndexError, used the outer loop variable j instead
of the row's prime, and emitted duplicated closing tags with the wrong
number of cells.  Row preparation now lives in a module-level
euler_factor_row_data(), which validates the input shape inside the
exception boundary and returns (factors, gal_groups, isog_class); row()
builds the HTML once from that triple.  Malformed data give one valid row
with the row's own prime, the factor 'not available' and an empty isogeny
cell.  Only the exceptions expected from malformed factor payloads are
caught.  The show more/less rows now also account for the isogeny column.

polynomial_unroll: expanding a factorization with [fac] * exponent turns a
zero or negative exponent into an empty list, so a malformed factor could
silently vanish while a valid one remained, contradicting the contract that
exponent-zero factorizations are malformed.  Every entry is now validated
(two elements, nonempty coefficient list, strictly positive integer
exponent, bool rejected explicitly) and the factors are accumulated by
exponentiation rather than list expansion.

Tests: test_euler_factor_isogeny_class_out_of_range no longer assumes
dimension 3 data stop at q = 25 (that becomes false as av_fq_isog grows);
it patches AbvarExists instead.  New tests cover exponent validation, the
extracted row preparation, and lfuncEPhtml itself for both degree 2 (no
Galois column) and degree 4 (Galois column), checking the fallback row's
prime and the table's column count.  The three new tests fail on the
previous commit and pass here.

Verified: sage -python -m pytest lmfdb/lfunctions/test_lfunctions.py
(30 passed); pyflakes, pylint and ruff clean; the EC and genus 2 isogeny
class pages, which also call Lfactor_to_label, still render their av/Fq
links.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants