Identify abelian number fields in the jump box without polredabs (LMFDB#5471) - #42
Identify abelian number fields in the jump box without polredabs (LMFDB#5471)#42roed-math wants to merge 4 commits into
Conversation
…LMFDB#5471) Add a fast path to WebNumberField.from_polynomial implementing jwj61's abelian identification: after polredbest, certify the field abelian with galoisinit over an order maximal at the small primes of the discriminant (never factoring the discriminant), compute the field discriminant from that order, query nf_fields by degree/signature/discriminant, and confirm candidates by exhibiting a verified root of their defining polynomial, so any label returned is provably correct; all failures fall back to the unchanged polredabs path. Inputs whose degree exceeds every field in nf_fields now return "not in database" immediately instead of running polredabs (a degree 94 kernel polynomial went from >300s to 0.15s; the issue's degree 47 field is identified from a non-reduced polynomial in ~2s). Verified: all 36 number_fields tests pass (3 new: identified jumps for the issue's degree 47 field and Q(zeta_32) from non-reduced polynomials, abelian_nf_label unit checks, fast large-degree jump); pyflakes clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…LMFDB#5471) Two review fixes, both of which could make the abelian fast path return None and fall back to the expensive polredabs path (neither could produce a wrong label, which the exact root check still rules out). Recognize a large ramified prime that appears in the discriminant as a prime power: in a field of degree at least 4 a ramified p contributes p^e with e > 1, and the index contributes further powers, so the cofactor left after dividing out the small primes is typically p^e rather than p and is_pseudoprime() rejected it, leaving p out of S and making DK (hence the database query) wrong. Use is_pseudoprime_power(get_data=True) and append the base; a cofactor with several large primes is still left unfactored. The selection of these primes moves to a helper _known_discriminant_primes. Give nfroots the defining polynomial rather than the conditional nf structure: nfinit([T, S]) is only certified maximal at the primes of S, and the PARI manual warns that nfroots may miss a root when handed such a structure, while it recovers in polynomial time from nf.pol. The exact substitution certificate and the polredabs fallback are unchanged. Verified: all 38 number_fields tests pass, including two new regressions (a discriminant whose large ramified prime occurs as p^7, and an abelian field entered with an index divisible by two primes above 10^5, so that nfroots runs against a conditional order); pyflakes and ruff clean. On the degree 47 conductor 283 example nfroots goes from 0.37s to 0.78s and the whole fast path takes 1.5s, against more than 300s for polredabs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Pushed fd85f3d, which addresses both review points. Only 1.
|
…MFDB#5471) Passing nf.pol to nfroots for every candidate protects against the root that a conditional nf structure can miss, but it also slows down the candidates that succeed, which is the case the fast path exists for: on the degree 47 conductor 283 example nfroots went from 0.37s to 0.78s. A missed root can only show up as an empty result, so try the nf form first and ask again with the defining polynomial only when nothing came back, which is exactly the situation that would otherwise fall through to polredabs. The degree 47 lookup is back to 1.18s end to end, and a candidate that really is not isomorphic to K costs a second nfroots call that returns immediately (0.00s at degree 8 and 16). Verified: all 38 number_fields tests pass; pyflakes and ruff clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Correction to the timing note in my previous comment: passing A root missed because of the conditional order can only surface as an empty result, so the Degree 47, conductor 283,
That query returns a single candidate and it matches, so the second call never runs. Degree 8 and 16 are unaffected either way ( The trade is not free in every shape: the degree 16 query returns 16 candidates, so the 15 non-isomorphic ones now do two Verified: all 38 |
|
GPT signed off. |
|
Superseded by LMFDB#7176, opened upstream from this same branch. Closing here; review continues upstream. |
Looking up a number field by polynomial always ran polredbest+polredabs, which can hang — e.g. kernel polynomials of Dirichlet characters of large degree run for many minutes without producing an answer. This implements the abelian-case identification proposed by @jwj61: after polredbest, certify the field abelian with galoisinit on an order maximal at the small primes of the discriminant (the discriminant is never factored), read off the field discriminant from that order, query nf_fields by degree/signature/discriminant, and confirm candidates by exhibiting a root of their defining polynomial in the input field, so any label returned is provably correct; on any failure we fall back to the unchanged polredabs path. In addition, polynomials whose degree exceeds every field in nf_fields now return "not in the database" immediately: a degree-94 kernel polynomial of conductor 283 that previously ran polredabs for >300s now answers in 0.15s, and the degree-47 example from the issue is identified from a non-reduced defining polynomial in ~2s with a certificate. Tested on abelian fields of degree 8, 16 and 47 entered via deliberately non-reduced polynomials, plus non-Galois/non-abelian negatives; all 36 number_fields tests pass. Addresses LMFDB#5471.
🤖 Generated with Claude Code