The set-up of a search: the polynomial of a coefficient list, the remainder chain, the reversal #
The C code works with the polynomial f = ∑ cᵢ Xⁱ of the coefficient list c and its degree d,
the refusals speak about the binary form Φ_c of degree N = 2 ⌈n / 2⌉
(Ratpoints.binaryFormPoly), where n + 1 is the length of c. Φ_c is the homogenization of f
of degree N, so it is squarefree exactly when f is squarefree and N ≤ d + 1: the two
conditions that the C code tests, the second when it drops the leading zeros, the first with the
remainder chain of its Sturm step. The rows of the chain, as polynomials over ℚ, form a
generalized Sturm sequence, positive rational multiples of the entries of Mathlib's
Polynomial.sturmSeq, along which the coprimality of f and f' passes down to the last two rows,
so that the chain detects a repeated factor of f. In each of its three cases the reversal check
replaces c by its reflection in the even degree D = d + d % 2 of the binary form, which
exchanges x and z in the binary form and so does not change whether it is squarefree, and its
refusal, of c₀ = c₁ = 0 for even d, stands for X ^ 2 ∣ Φ_c; so once the test of the leading
zeros has passed, the remainder chain of the polynomial that the check hands on detects exactly the
forms that are not squarefree. The map of the points of the reversed curve to those of the caller's
curve (Ratpoints.Sieve.swapPoint) is a bijection between the points of height at most H.
Main definitions #
Ratpoints.poly: the polynomialf = ∑ cᵢ Xⁱoverℚof a coefficient listc.
Main statements #
Ratpoints.getD_degree_ne_zero_of_pos,Ratpoints.natDegree_poly: the entry ofcat a positive degree is not zero, and the degree offisRatpoints.degree c.Ratpoints.poly_take_of_degree_lt: the entries ofcabove its degree do not changef.Ratpoints.binaryForm_eq_mul_eval:F(a, b) = b ^ D f(a / b)forb ≠ 0, with the even degreeD = d + d % 2.Ratpoints.binaryFormPoly_eq_homogenize:Φ_cis the homogenization offof degreeN.Ratpoints.squarefree_binaryFormPoly_iff:Φ_cis squarefree if and only iffis squarefree andN ≤ d + 1.Ratpoints.not_squarefree_binaryFormPoly_of_lt,Ratpoints.not_squarefree_binaryFormPoly_of_getD_zero: a drop of⌈n / 2⌉by the leading zeros, andc₀ = c₁ = 0, leave a form that is not squarefree.Ratpoints.Sturm.IsChain.exists_mul_eq,Ratpoints.Sturm.IsChain.natDegree_lt: three consecutive rowss_k,s_(k+1),s_(k+2)of a remainder chain satisfyA s_k = Q s_(k+1) - g s_(k+2)with integersA, g > 0, and the degrees decrease fromf'on.Ratpoints.Sturm.run_chain_eq_none_iff: ford ≥ 1andc_d ≠ 0, the remainder chain of the model isnoneexactly when the polynomial ofc₀, …, c_dis not squarefree.Ratpoints.Setup.getD_eq_of_reversal_eq_ok,Ratpoints.Setup.binaryForm_eq_of_reversal_eq_ok: the list that the reversal check reversescto is the reflection ofcin the degreeD, and its binary form is that ofcwithxandzexchanged.Ratpoints.Setup.degree_eq_of_reversal_eq_ok,Ratpoints.Setup.eq_of_reversal_eq_ok_false: the degree that the check returns is that of the list it returns, and without a reversal these arecand its degree.Ratpoints.Setup.one_le_of_reversal_eq_ok,Ratpoints.Setup.degree_le_of_reversal_eq_ok: the check keeps the degree at least1, and does not raise it.Ratpoints.Setup.squarefree_binaryFormPoly_iff_of_reversal_eq_ok: once the test of the leading zeros has passed,Φ_cis squarefree exactly when the polynomial that the check hands on is.Ratpoints.Setup.exists_reversal_eq_error_iff,Ratpoints.Setup.not_squarefree_binaryFormPoly_of_reversal_eq_error: the check refuses exactly the even degrees withc₀ = c₁ = 0when its switch lets it run, and only forms that are not squarefree.Ratpoints.Sturm.run_chain_eq_none_iff_of_reversal_eq_ok: once the test of the leading zeros has passed, the remainder chain of the polynomial that the check hands on is none exactly whenΦ_cis not squarefree.Ratpoints.Sieve.isPoint_swapPoint,Ratpoints.Sieve.perm_map_swapPoint_bruteForce: the map of a reversed search sends the points of the reversed curve to points of the caller's curve, and the brute-force reference of the one, mapped, is a permutation of that of the other.Ratpoints.IsNormalizedPair.swapPoint,Ratpoints.Sieve.swapPoint_inj: the map keeps the pairs(x, z)of normalized points of height at mostH(Ratpoints.IsNormalizedPair), with or without the equation, and it is injective on the normalized triples.
The polynomial f = ∑ cᵢ Xⁱ over ℚ with the coefficient list c, constant term first, which
the C code works with; Ratpoints.binaryFormPoly c is its homogenization of degree 2 ⌈n / 2⌉,
where n + 1 is the length of c (Ratpoints.binaryFormPoly_eq_homogenize). Mathlib's
Polynomial.ofCoeffList builds the same polynomial from the list c.map (↑); the sum here has
the shape of Ratpoints.binaryFormPoly, so that Ratpoints.binaryFormPoly_eq_homogenize holds
term by term.
Equations
- Ratpoints.poly c = ∑ i ∈ Finset.range c.length, Polynomial.C ↑(c.getD i 0) * Polynomial.X ^ i
Instances For
The entries of c above its degree are zero, so dropping them does not change the polynomial
Ratpoints.poly c; with n = d + 1 for the degree d of c, this turns the polynomial of
Ratpoints.Sturm.run_chain_eq_none_iff into Ratpoints.poly c.
The binary form Ratpoints.binaryFormPoly c is squarefree exactly when the polynomial
Ratpoints.poly c is squarefree and the degree 2 ⌈n / 2⌉ of the form, n + 1 the length of c,
exceeds the degree of the polynomial by at most one: the two conditions that the C code tests, the
second when it drops the leading zeros, the first with the remainder chain of its Sturm step.
When the leading zeros of c lower ⌈n / 2⌉, for n + 1 the length of c, the square of the
second variable divides the binary form Ratpoints.binaryFormPoly c.
With c₀ = c₁ = 0, the square of the first variable divides the binary form
Ratpoints.binaryFormPoly c, whatever the degree, the zero polynomial included.
The polynomial of an array #
The steps of the chain as polynomials #
Remainder chains #
Three consecutive rows s_k, s_(k+1), s_(k+2) of a remainder chain satisfy
A s_k = Q s_(k+1) - g s_(k+2) with integers A, g > 0, the relation of a generalized Sturm
sequence; compare Mathlib's Polynomial.sturmSeq, which has A = g = 1 and Q the quotient
(Polynomial.sturmSeq_cons): the integer factors keep the rows integral, and the rows are positive
rational multiples of its entries.
For the coefficients c₀, …, c_d of a polynomial f of degree d ≥ 1, the remainder chain is
none, where sturm.c returns -1, exactly when f is not squarefree over ℚ; for the degree
d of c, f is Ratpoints.poly c (Ratpoints.poly_take_of_degree_lt).
The reversal #
Two lists whose degrees round up to the same even number N and whose entries are reflected at
N have binary forms with x and z exchanged.
In each of the three cases of the reversal check Ratpoints.Setup.reversal, the reversed list
is the reflection of c in the even degree d + d % 2 of the binary form (with c_(d+1) = 0 in
its third case, of odd d).
The new leading coefficient of a reversal by Ratpoints.Setup.reversal, c₁ when c₀ = 0 and
c₀ otherwise, is not zero, so the degree that the check returns is that of its list, also without
a reversal.
The reversal check Ratpoints.Setup.reversal keeps the degree at least 1: it lowers only an
even degree d ≥ 2, to d - 1, when c₀ = 0, and keeps it otherwise.
The reversal check Ratpoints.Setup.reversal does not raise the degree: it lowers only an even
degree d ≥ 2, to d - 1, when c₀ = 0, and keeps it otherwise.
The binary form of the reversed list is that of c with x and z exchanged, since the list
is the reflection of c in the even degree d + d % 2 of the binary form.
Once the test of the leading zeros has passed, the binary form Ratpoints.binaryFormPoly c is
squarefree exactly when the polynomial of the list that the reversal check hands on is, whether it
reverses or not: the reflection does not change whether the homogenization of degree d + d % 2 is
squarefree (Polynomial.squarefree_homogenize_iff_squarefree_reflect).
The refusal of the reversal check is sound: it refuses only when the square of the first
variable divides Ratpoints.binaryFormPoly c
(Ratpoints.not_squarefree_binaryFormPoly_of_getD_zero).
Once the test of the leading zeros has passed, the remainder chain of the polynomial that the
reversal check hands on is none exactly when Ratpoints.binaryFormPoly c is not squarefree, whether
the check reverses or not: the polynomial has the degree d' ≥ 1 that the check returns
(Ratpoints.Setup.one_le_of_reversal_eq_ok), so that the chain detects its repeated factors
(Ratpoints.Sturm.run_chain_eq_none_iff), and it is squarefree exactly when
Ratpoints.binaryFormPoly c is
(Ratpoints.Setup.squarefree_binaryFormPoly_iff_of_reversal_eq_ok).
The map of a reversed search #
The map of the reversal keeps the pairs (x, z) of normalized points of height at most H:
it exchanges x and z, negating both for x < 0.
A point of a curve whose binary form is that of c with x and z exchanged gives a point of
the curve of c: since the degree of Ratpoints.binaryForm is even, F(-x, -z) = F(x, z), and
the map keeps the normalized pairs (Ratpoints.IsNormalizedPair.swapPoint).
The brute-force reference of a curve whose binary form is that of c with x and z
exchanged, mapped by Ratpoints.Sieve.swapPoint, is a permutation of the reference of c: the map
sends the points of the one curve one to one onto those of the other, and neither list has
duplicates.