The Budan–Fourier theorem #
For a nonzero real polynomial p and a < b with p a ≠ 0, p b ≠ 0, let V(x) be the number of
sign variations of the derivative tower p, p', p'', …, p^(deg p) evaluated at x. Then the number
of real roots of p in (a, b], counted with multiplicity, is at most V(a) - V(b), and the
difference is even.
The local analysis at a point c where a whole block of the tower vanishes is done by the sign
recursions BudanFourier.Rseq and BudanFourier.Lseq, which give the signs of the tower just to
the right and just to the left of c. The sign-variation toolkit is the one of Sturm.
Main definitions #
BudanFourier.fourierSeq p: the derivative tower[p, p', …, p^(deg p)].BudanFourier.fourierVar p x: its number of sign variations atx.
Main results #
BudanFourier.budan_fourier: the Budan–Fourier inequality and the parity of the difference.BudanFourier.fourierVar_drop_at_critical_point: the drop offourierVarat one critical point is the multiplicity of the root plus an even number.BudanFourier.signs_right_eq_Rseq,BudanFourier.signs_left_eq_Lseq: the signs of the tower on either side of a point.
References #
- S. Basu, R. Pollack, M.-F. Roy, Algorithms in Real Algebraic Geometry, 2nd ed., Springer, 2006, §2.2.
- W. Li, L. C. Paulson, Counting polynomial roots in Isabelle/HOL: a formal proof of the Budan–Fourier theorem, CPP 2019, 52–64.
The Fourier sequence (derivative tower) of p: p, p', p'', …, p^(deg p).
Equations
- BudanFourier.fourierSeq p = List.map (fun (k : ℕ) => (⇑Polynomial.derivative)^[k] p) (List.range (p.natDegree + 1))
Instances For
The Fourier sequence has deg p + 1 entries.
The Fourier sequence is never empty (it always contains at least p).
Membership in the Fourier sequence: its entries are exactly the iterated derivatives
p^(k) for 0 ≤ k ≤ deg p.
Fourier sign variations of p at x: the number of sign changes in the derivative tower
evaluated at x, with zeros dropped. The eval-analogue, on the derivative tower, of the count used
for Sturm's theorem.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Bridge to the Sturm toolkit. fourierVar p x is, definitionally, Sturm.signVarAt applied
to the derivative tower. This single rfl makes the entire sign-variation toolkit from Sturm
(locally-constant on root-free intervals, signChanges/wallCount parity engine, interior
cancellation) act directly on the Fourier sequence.
fourierVar is locally constant. On a closed interval where no member of the derivative
tower vanishes, the Fourier sign-variation count does not change. Reused verbatim from the generic
Sturm.signVarAt_eq_of_no_root; this is the "nothing happens between critical points" half of the
global telescoping argument.
Every member of the derivative tower is nonzero. For k ≤ deg p, the k-th derivative
p^(k) has nonzero coefficient (deg p).descFactorial k · leadingCoeff p in degree deg p − k
(char 0), so it is nonzero. Unlike the Sturm chain this is the only nonvanishing we get — two
consecutive tower members can still share a root, which is exactly why the local analysis differs
from Sturm's coprime chain.
The product of the derivative tower is nonzero (the analogue of Sturm.sturmSeq_prod_ne_zero):
its roots are exactly the "critical points" where some p^(k) vanishes, the only places where
fourierVar can move.
Half-open root count splits additively (with multiplicity). For a ≤ d ≤ b, the roots of a
multiset in (a, b] are those in (a, d] plus those in (d, b]. The multiplicity-aware companion
of Sturm's Finset split; needed because Budan–Fourier counts roots with multiplicity.
The recursive monotonicity lemmas (foundation of the block analysis) #
The derivative tower steps p^(k+1) = (p^(k))′. So if p^(k) vanishes at c and p^(k+1) keeps a
constant nonzero sign just off c, then p^(k) is strictly monotone there and its sign just off c
is determined: same sign as p^(k+1) on the right, opposite on the left. This one-step
recursion replaces the Taylor/rootMultiplicity bookkeeping entirely.
Sign just right of a root = sign of the derivative there. If q(c) = 0 and q′ keeps the
constant nonzero sign s on (c, z], then sign (q z) = s.
Sign just left of a root = opposite sign of the derivative there. If q(c) = 0 and q′
keeps the constant nonzero sign s on [z, c), then sign (q z) = -s.
Per-member off-c sign recursion #
For each tower member, its sign just off c is fixed by whether it vanishes at c:
- kept (
q(c) ≠ 0): the sign just offcequalssign (q c)(both sides), by local constancy; - vanishing (
q(c) = 0): on the right it copies the derivative's sign, on the left the opposite — one step of the lemma recursion. Iterated up a vanishing block, these give: right ofcthe block copies the first kept sign above it (no new sign change), left ofcit alternates.
Kept member, right of c: constant sign.
Kept member, left of c: constant sign.
Vanishing member, right of c: copies the derivative's sign.
Vanishing member, left of c: opposite of the derivative's sign.
The pure sign-list combinatorics (items 2+3, decoupled from polynomials) #
The two off-c sign sequences are abstracted as list functions of the at-c sign list s (entry
0 = vanishing member, ±1 = kept). Building from the right with the item-1 recursions:
Rseq(signs atb): a vanishing entry copies the value above it (headD);Lseq(signs ata): a vanishing entry negates the value above it. The right side collapses (signChanges (Rseq s) = signChanges s, i.e.V(b) = V(c)); the left side adds the leading-zero run plus an even surplus (the Budan–Fourier drop + parity).
Signs just right of c: a vanishing member copies the sign above it.
Equations
- BudanFourier.Rseq [] = []
- BudanFourier.Rseq (σ :: rest) = if σ = 0 then (BudanFourier.Rseq rest).headD 0 :: BudanFourier.Rseq rest else σ :: BudanFourier.Rseq rest
Instances For
Signs just left of c: a vanishing member negates the sign above it.
Equations
- BudanFourier.Lseq [] = []
- BudanFourier.Lseq (σ :: rest) = if σ = 0 then -(BudanFourier.Lseq rest).headD 0 :: BudanFourier.Lseq rest else σ :: BudanFourier.Lseq rest
Instances For
Right side collapses to the at-c count. The vanishing members copy their kept successor, so
they destutter away: signChanges (Rseq s) = signChanges s. (Also: Rseq s is all-nonzero and shares
its leading surviving sign with s.) Needs the last entry nonzero (the leading coefficient never
vanishes).
Left side adds the leading-zero run plus an even surplus. The Budan–Fourier drop: the top
vanishing block alternates (contributing its length = rootMult), interior blocks contribute an even
amount. Carries the head sign-parity relation Lhead = (-1)^{leadingZeros} · Rhead as the induction
invariant.
Plumbing: the polynomial tower realizes the abstract sign lists Rseq/Lseq #
The two list lemmas Rseq_spec/Lseq_spec are stated about an abstract list of signs. Here we show
that, for the derivative tower, the sign pattern at b (right of the critical point c) is Rseq
of the pattern at c, and the pattern at a (left) is Lseq of it — the per-member recursion of
the monotonicity lemmas, threaded up the tower via its derivative-chain structure.
The top derivative p^(deg p) is a nonzero constant, so it never vanishes.
The last member of the Fourier sequence is p^(deg p).
The last member of the Fourier sequence never vanishes.
The i-th member of the Fourier sequence is p^(i).
The Fourier sequence is a derivative chain: each member is the derivative of the previous.
Right side = Rseq. For a derivative chain L whose last member is nonzero at c and none
of whose members vanishes on (c, b], the sign pattern at b equals Rseq of the pattern at c.
Left side = Lseq. Symmetric to signs_right_eq_Rseq: the sign pattern at a (left of c)
equals Lseq of the pattern at c.
The leading-zero run of a sign list has the prescribed length. If the first r entries are
0 and entry r (when present) is nonzero, then takeWhile (· = 0) has length exactly r.
Local drop at a critical point — the analytic core. The one piece with no
Sturm analogue: the derivative tower is not a coprime chain, so a whole block of consecutive
members p^(i), …, p^(j) may vanish at c. Stated in additive form V(a) = V(b) + #roots(a,b] + 2e, which packages BOTH the Budan–Fourier inequality #roots ≤ V(a)−V(b) and the even-difference
parity into a single existential that adds cleanly across the global induction (the locally-constant
case is e = 0, #roots = 0).
The Budan–Fourier theorem. For nonzero p and a < b with neither endpoint a root, the
number of real roots of p in (a, b] counted with multiplicity is bounded by the drop in Fourier
sign variations, and has the same parity as that drop.
Proof: strong induction on the number of distinct critical points (roots of the
tower's product Pc) in (a, b]; peel the maximum one, split just below it, recurse left and apply
the local drop fourierVar_drop_at_critical_point on the right, combining the two additive
existentials.
The derivative tower is not a Sturm chain. An abstract Sturm chain (Eisermann, Def. 3.10)
asks that whenever an interior member vanishes at a point, its two neighbours there have product
< 0. At a root r of multiplicity at least 2, the member p' (index 1 of fourierSeq p)
is interior, since the tower has at least three members, and vanishes at r; yet the product of
its neighbours p (r) * p'' (r) is 0, because p vanishes at r too.
The paper's witness: for p_A = (x - 1)^2 (x + 1), the interior member p_A' vanishes at
x = 1 and p_A (1) * p_A'' (1) = 0, so the antipodal axiom fails there.