The reference plan backed by the existing allocation-conscious schoolbook multiplication.
35.2. HexPolyFast: fast dense polynomials
35.2.1. Introduction
HexPolyFast adds proof-carrying fast algorithms to the normalized dense
polynomials from HexPoly. The underlying multiplication
and Euclidean operations remain the semantic reference. Optimized kernels
are selected explicitly, and their laws state exact equality with that
reference rather than equality only up to normalization or a unit.
The library covers full and clipped Karatsuba multiplication, Newton
reciprocals and division, half-gcd, product and remainder trees, reusable
multipoint evaluation and interpolation, and Padé approximation. It is
Mathlib-free. Its other direct dependency is
HexTruncatedSeries, whose fixed-precision
series representation supplies the Newton-inversion boundary.
35.2.2. Multiplication plans
Hex.DensePoly.MulPlan packages full multiplication, specialized
squaring, and an arbitrary product slice. Its three proof fields identify
all results with the existing DensePoly product. A plan is an ordinary
value, not a typeclass instance, so callers can choose a coefficient-specific
kernel locally without changing global arithmetic.
Hex.DensePoly.schoolbookPlan.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] : Hex.DensePoly.MulPlan RHex.DensePoly.schoolbookPlan.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] : Hex.DensePoly.MulPlan R
Hex.DensePoly.karatsubaPlan.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (cutoff : Nat) : Hex.DensePoly.MulPlan RHex.DensePoly.karatsubaPlan.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (cutoff : Nat) : Hex.DensePoly.MulPlan R
A lawful Karatsuba plan.
Hex.DensePoly.mulWith.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a b : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.mulWith.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a b : Hex.DensePoly R) : Hex.DensePoly R
Multiply using an explicit plan.
Hex.DensePoly.squareWith.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.squareWith.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a : Hex.DensePoly R) : Hex.DensePoly R
Square using an explicit plan.
Hex.DensePoly.mulLow.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (len : Nat) (a b : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.mulLow.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (len : Nat) (a b : Hex.DensePoly R) : Hex.DensePoly R
Keep the first len coefficients of a planned product.
Hex.DensePoly.mulSlice.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (lo len : Nat) (a b : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.mulSlice.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (lo len : Nat) (a b : Hex.DensePoly R) : Hex.DensePoly R
Keep len coefficients beginning at product degree lo.
Hex.DensePoly.mulMiddleChecked.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a b : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.mulMiddleChecked.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a b : Hex.DensePoly R) : Hex.DensePoly R
Checked middle product. Operands are ordered by size; an empty operand has zero middle product.
The following example selects a small Karatsuba cutoff and checks full and clipped multiplication against the schoolbook semantics.
open Hex Hex.DensePoly
namespace HexPolyFastChapterMul
private def a : DensePoly Int :=
#p[3, -2, 0, 5, 1]
private def b : DensePoly Int :=
#p[-1, 6, 2]
private def plan : MulPlan Int :=
karatsubaPlan 2
#guard mulWith plan a b = a * b
#guard squareWith plan a = a * a
#guard
mulSlice plan 2 3 a b =
schoolbookSlice 2 3 a b
#guard mulSlice plan 30 4 a b = 0
end HexPolyFastChapterMul
The projection theorems are the public semantic boundary. Dispatch cutoffs, recursive splits, and clipped allocation do not appear in their statements.
Hex.DensePoly.mulWith_eq.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a b : Hex.DensePoly R) : Hex.DensePoly.mulWith plan a b = a * bHex.DensePoly.mulWith_eq.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a b : Hex.DensePoly R) : Hex.DensePoly.mulWith plan a b = a * b
Planned multiplication has the existing dense-polynomial semantics.
Hex.DensePoly.squareWith_eq.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a : Hex.DensePoly R) : Hex.DensePoly.squareWith plan a = a * aHex.DensePoly.squareWith_eq.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (a : Hex.DensePoly R) : Hex.DensePoly.squareWith plan a = a * a
Planned squaring has the existing dense-polynomial semantics.
Hex.DensePoly.coeff_mulLow.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (len i : Nat) (a b : Hex.DensePoly R) : (Hex.DensePoly.mulLow plan len a b).coeff i = if i < len then (a * b).coeff i else 0Hex.DensePoly.coeff_mulLow.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (len i : Nat) (a b : Hex.DensePoly R) : (Hex.DensePoly.mulLow plan len a b).coeff i = if i < len then (a * b).coeff i else 0
Coefficient law for a planned low product.
Hex.DensePoly.coeff_mulSlice.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (lo len i : Nat) (a b : Hex.DensePoly R) : (Hex.DensePoly.mulSlice plan lo len a b).coeff i = if i < len then (a * b).coeff (lo + i) else 0Hex.DensePoly.coeff_mulSlice.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (lo len i : Nat) (a b : Hex.DensePoly R) : (Hex.DensePoly.mulSlice plan lo len a b).coeff i = if i < len then (a * b).coeff (lo + i) else 0
Coefficient law for an arbitrary planned slice.
35.2.3. Cyclic products and series bridges
Cyclic and negacyclic products fold a planned ordinary product modulo
x^n - 1 and x^n + 1. The proof-taking forms require positive length;
the checked forms return none for length zero.
Hex.DensePoly.mulCyclic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (_hn : 0 < n) (a b : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.mulCyclic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (_hn : 0 < n) (a b : Hex.DensePoly R) : Hex.DensePoly R
Cyclic convolution of positive length n.
Hex.DensePoly.mulNegacyclic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (_hn : 0 < n) (a b : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.mulNegacyclic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (_hn : 0 < n) (a b : Hex.DensePoly R) : Hex.DensePoly R
Negacyclic convolution of positive length n.
Hex.DensePoly.mulCyclic_eq_modByMonic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (hn : 0 < n) (hone : 1 ≠ 0) (a b : Hex.DensePoly R) : Hex.DensePoly.mulCyclic plan n hn a b = (a * b).modByMonic (Hex.DensePoly.cyclicModulus n) ⋯Hex.DensePoly.mulCyclic_eq_modByMonic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (hn : 0 < n) (hone : 1 ≠ 0) (a b : Hex.DensePoly R) : Hex.DensePoly.mulCyclic plan n hn a b = (a * b).modByMonic (Hex.DensePoly.cyclicModulus n) ⋯
Planned cyclic multiplication is polynomial remainder modulo x^n - 1.
Hex.DensePoly.mulNegacyclic_eq_modByMonic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (hn : 0 < n) (hone : 1 ≠ 0) (a b : Hex.DensePoly R) : Hex.DensePoly.mulNegacyclic plan n hn a b = (a * b).modByMonic (Hex.DensePoly.negacyclicModulus n) ⋯Hex.DensePoly.mulNegacyclic_eq_modByMonic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (hn : 0 < n) (hone : 1 ≠ 0) (a b : Hex.DensePoly R) : Hex.DensePoly.mulNegacyclic plan n hn a b = (a * b).modByMonic (Hex.DensePoly.negacyclicModulus n) ⋯
Planned negacyclic multiplication is polynomial remainder modulo
x^n + 1.
Hex.DensePoly.mulCyclic?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (a b : Hex.DensePoly R) : Option (Hex.DensePoly R)Hex.DensePoly.mulCyclic?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (a b : Hex.DensePoly R) : Option (Hex.DensePoly R)
Checked cyclic convolution; length zero has no quotient-ring meaning.
Hex.DensePoly.mulNegacyclic?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (a b : Hex.DensePoly R) : Option (Hex.DensePoly R)Hex.DensePoly.mulNegacyclic?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (n : Nat) (a b : Hex.DensePoly R) : Option (Hex.DensePoly R)
Checked negacyclic convolution; length zero has no quotient-ring meaning.
Reversal converts the leading end of a polynomial to the low end of a fixed series prefix. The guarded coefficient theorem matters because natural-number subtraction saturates below zero.
Hex.DensePoly.reverseSeries.{u} {R : Type u} [Zero R] [DecidableEq R] (f : Hex.DensePoly R) (n : Nat) : Hex.TSeries R nHex.DensePoly.reverseSeries.{u} {R : Type u} [Zero R] [DecidableEq R] (f : Hex.DensePoly R) (n : Nat) : Hex.TSeries R n
Reverse a dense polynomial from its leading end into an exactly n-term
truncated series, padding with zeros when n exceeds the polynomial size.
Hex.DensePoly.coeff_reverseSeries.{u} {R : Type u} [Zero R] [DecidableEq R] (f : Hex.DensePoly R) (n i : Nat) (hi : i < n) : (f.reverseSeries n).coeff i = if i < f.size then f.coeff (f.size - 1 - i) else 0Hex.DensePoly.coeff_reverseSeries.{u} {R : Type u} [Zero R] [DecidableEq R] (f : Hex.DensePoly R) (n i : Nat) (hi : i < n) : (f.reverseSeries n).coeff i = if i < f.size then f.coeff (f.size - 1 - i) else 0
Coefficient law for zero-extending polynomial reversal.
Hex.DensePoly.polyOfSeries.{u} {R : Type u} [Zero R] [DecidableEq R] {n : Nat} (a : Hex.TSeries R n) : Hex.DensePoly RHex.DensePoly.polyOfSeries.{u} {R : Type u} [Zero R] [DecidableEq R] {n : Nat} (a : Hex.TSeries R n) : Hex.DensePoly R
Convert all represented coefficients of a truncated series to a normalized dense polynomial.
Hex.DensePoly.seriesMulUpTo.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) {n : Nat} (m : Nat) (a b : Hex.TSeries R n) : Hex.TSeries R nHex.DensePoly.seriesMulUpTo.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) {n : Nat} (m : Nat) (a b : Hex.TSeries R n) : Hex.TSeries R n
Multiply two series through degree m - 1 with a polynomial
multiplication plan.
Hex.DensePoly.reciprocalWith.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) {n : Nat} (g : Hex.TSeries R n) (u : R) : Hex.TSeries R nHex.DensePoly.reciprocalWith.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) {n : Nat} (g : Hex.TSeries R n) (u : R) : Hex.TSeries R n
Newton reciprocal at the full represented precision. Each doubling step
uses plan.slice 0 k; no schoolbook TSeries product is executed by this
definition.
Hex.DensePoly.reciprocalWith_eq.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) {n : Nat} (g : Hex.TSeries R n) (u : R) : Hex.DensePoly.reciprocalWith plan g u = g.invOfUnit uHex.DensePoly.reciprocalWith_eq.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) {n : Nat} (g : Hex.TSeries R n) (u : R) : Hex.DensePoly.reciprocalWith plan g u = g.invOfUnit u
The plan-driven reciprocal has the established truncated-series semantics. The inverse-witness hypothesis is intentionally not needed for algorithmic agreement; it is needed by the defining inverse equation below.
35.2.4. Newton division
Hex.DensePoly.DivPlan caches a divisor and a finite-precision
reciprocal. The capacity records the largest quotient prefix the plan can
serve. Monic construction works over a commutative ring; field construction
uses the inverse of the leading coefficient.
Hex.DensePoly.DivPlan.ofMonic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (mul : Hex.DensePoly.MulPlan R) (q : Hex.DensePoly R) (hq : q.Monic) (hqne : q ≠ 0) (capacity : Nat) : Hex.DensePoly.DivPlan RHex.DensePoly.DivPlan.ofMonic.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (mul : Hex.DensePoly.MulPlan R) (q : Hex.DensePoly R) (hq : q.Monic) (hqne : q ≠ 0) (capacity : Nat) : Hex.DensePoly.DivPlan R
Build a cached plan for a nonzero monic divisor.
Hex.DensePoly.DivPlan.ofNonzero.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (mul : Hex.DensePoly.MulPlan F) (q : Hex.DensePoly F) (hqne : q ≠ 0) (capacity : Nat) : Hex.DensePoly.DivPlan FHex.DensePoly.DivPlan.ofNonzero.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (mul : Hex.DensePoly.MulPlan F) (q : Hex.DensePoly F) (hqne : q ≠ 0) (capacity : Nat) : Hex.DensePoly.DivPlan F
Build a cached plan for an arbitrary nonzero divisor over a field.
Hex.DensePoly.DivPlan.divMod.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.DivPlan R) (p : Hex.DensePoly R) (hcap : p.quotientLength plan.divisor ≤ plan.capacity) : Hex.DensePoly R × Hex.DensePoly RHex.DensePoly.DivPlan.divMod.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.DivPlan R) (p : Hex.DensePoly R) (hcap : p.quotientLength plan.divisor ≤ plan.capacity) : Hex.DensePoly R × Hex.DensePoly R
Divide using a cached reciprocal. The proof ensures the cached precision covers the requested quotient; it is erased from executable code.
Hex.DensePoly.DivPlan.mod.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.DivPlan R) (p : Hex.DensePoly R) (hcap : p.quotientLength plan.divisor ≤ plan.capacity) : Hex.DensePoly RHex.DensePoly.DivPlan.mod.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.DivPlan R) (p : Hex.DensePoly R) (hcap : p.quotientLength plan.divisor ≤ plan.capacity) : Hex.DensePoly R
Remainder-only cached division.
The one-shot interfaces preserve all existing conventions, including division by zero and a divisor larger than the dividend.
Hex.DensePoly.divModMonicWith.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (mul : Hex.DensePoly.MulPlan R) (p q : Hex.DensePoly R) (hq : q.Monic) : Hex.DensePoly R × Hex.DensePoly RHex.DensePoly.divModMonicWith.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (mul : Hex.DensePoly.MulPlan R) (p q : Hex.DensePoly R) (hq : q.Monic) : Hex.DensePoly R × Hex.DensePoly R
One-shot reciprocal division by a monic polynomial.
Hex.DensePoly.divModWith.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (mul : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly F × Hex.DensePoly FHex.DensePoly.divModWith.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (mul : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly F × Hex.DensePoly F
One-shot reciprocal division over a field.
Hex.DensePoly.divModWith_eq.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (mul : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.divModWith mul p q = p.divMod qHex.DensePoly.divModWith_eq.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (mul : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.divModWith mul p q = p.divMod q
One-shot field reciprocal division is extensionally the existing verified long-division operation.
open Hex Hex.DensePoly
namespace HexPolyFastChapterDivision
private def a : DensePoly Rat :=
#p[3, -2, 0, 5, 1]
private def b : DensePoly Rat :=
#p[2, -3, 1]
#guard
divModWith (karatsubaPlan 2) a b =
divMod a b
#guard
divModWith (karatsubaPlan 2) a 0 =
(0, a)
#guard
divModWith (karatsubaPlan 2) (a * b) b =
(a, 0)
end HexPolyFastChapterDivision
35.2.5. Half-gcd
Hex.DensePoly.GcdStep is the two-by-two polynomial transformation
used by half-gcd. It keeps this library independent of the matrix hierarchy.
Recursive high-half calls predict and group the existing Euclidean quotient
sequence; a checked fallback preserves exact executable behavior.
Hex.DensePoly.gcdWith.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly FHex.DensePoly.gcdWith.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly F
Gcd projection of the half-gcd engine.
Hex.DensePoly.xgcdWith.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.XGCDResult FHex.DensePoly.xgcdWith.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.XGCDResult F
Plan-driven half-gcd extended gcd.
Hex.DensePoly.xgcdLeftWith.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.XGCDLeftResult FHex.DensePoly.xgcdLeftWith.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.XGCDLeftResult F
One-sided result projection of the half-gcd engine. It shares the full
matrix computation with xgcdWith; this API omits the unused result field but
does not promise a cheaper algorithm.
Hex.DensePoly.gcdWith_eq.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.gcdWith plan p q = p.gcd qHex.DensePoly.gcdWith_eq.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.gcdWith plan p q = p.gcd q
Half-gcd returns exactly the established gcd.
Hex.DensePoly.xgcdWith_eq.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.xgcdWith plan p q = p.xgcd qHex.DensePoly.xgcdWith_eq.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.xgcdWith plan p q = p.xgcd q
Half-gcd returns exactly the established extended-gcd result, including the raw gcd scaling and both Bezout coefficients.
Hex.DensePoly.xgcdLeftWith_eq.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.xgcdLeftWith plan p q = p.xgcdLeft qHex.DensePoly.xgcdLeftWith_eq.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) (p q : Hex.DensePoly F) : Hex.DensePoly.xgcdLeftWith plan p q = p.xgcdLeft q
The one-sided half-gcd projection agrees exactly with the established one-sided extended gcd.
35.2.6. Product trees and multipoint operations
Hex.DensePoly.ProductTree caches the root of a balanced tree without
retaining its intermediate levels. Its observations expose the original
leaves, reconstruct levels on demand, and compute individual node products
from their represented leaf blocks.
Hex.DensePoly.ProductTree.build.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (leaves : Array (Hex.DensePoly R)) : Hex.DensePoly.ProductTree RHex.DensePoly.ProductTree.build.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.MulPlan R) (leaves : Array (Hex.DensePoly R)) : Hex.DensePoly.ProductTree R
Build a balanced product tree without retaining intermediate levels. The
empty tree has root 1 and one singleton level containing that root.
Hex.DensePoly.ProductTree.level?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.ProductTree R) (i : Nat) : Option (Array (Hex.DensePoly R))Hex.DensePoly.ProductTree.level?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.ProductTree R) (i : Nat) : Option (Array (Hex.DensePoly R))
A balanced level reconstructed from the leaves, from leaves upward. The
empty tree has the singleton level [1].
Hex.DensePoly.ProductTree.root.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.ProductTree R) : Hex.DensePoly RHex.DensePoly.ProductTree.root.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.ProductTree R) : Hex.DensePoly R
The product represented by the root node.
Hex.DensePoly.ProductTree.nodeProduct?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.ProductTree R) (level index : Nat) : Option (Hex.DensePoly R)Hex.DensePoly.ProductTree.nodeProduct?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.ProductTree R) (level index : Nat) : Option (Hex.DensePoly R)
Product represented by a valid balanced node. The observation is semantic: it folds exactly that node's leaf block, independently of the internal level layout.
Hex.DensePoly.RemainderTree caches a reciprocal plan at every node for
an arbitrary ordered collection of nonzero monic divisors. The caller chooses
only the root capacity; proper nodes derive the exact precision they need from
their sibling subtree.
A nonzero monic polynomial suitable as a remainder-tree leaf.
Constructor
Hex.DensePoly.MonicLeaf.mk.{u}
Fields
poly : Hex.DensePoly R
Leaf divisor.
monic : self.poly.Monic
The divisor is monic.
ne : self.poly ≠ 0
The divisor is nonzero.
Hex.DensePoly.RemainderTree.build.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (mul : Hex.DensePoly.MulPlan R) (capacity : Nat) (leaves : Array (Hex.DensePoly.MonicLeaf R)) (hone : 1 ≠ 0) : Hex.DensePoly.RemainderTree RHex.DensePoly.RemainderTree.build.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (mul : Hex.DensePoly.MulPlan R) (capacity : Nat) (leaves : Array (Hex.DensePoly.MonicLeaf R)) (hone : 1 ≠ 0) : Hex.DensePoly.RemainderTree R
Build a cached remainder tree. capacity is the reciprocal capacity of the
root; every proper node derives the exact worst-case capacity it needs from its
sibling subtree. The empty leaf sequence is represented without an internal
root.
Hex.DensePoly.RemainderTree.rootDegree.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.RemainderTree R) : NatHex.DensePoly.RemainderTree.rootDegree.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.RemainderTree R) : Nat
Degree of the root product, computed as the sum of the leaf degrees.
Hex.DensePoly.RemainderTree.remainders?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.RemainderTree R) (p : Hex.DensePoly R) : Option (Array (Hex.DensePoly R))Hex.DensePoly.RemainderTree.remainders?.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.RemainderTree R) (p : Hex.DensePoly R) : Option (Array (Hex.DensePoly R))
Compute all leaf remainders with the cached reciprocal plans. Returns
none exactly when the input needs more reciprocal precision than the root
capacity. Proper-node capacities are sufficient by construction.
Hex.DensePoly.RemainderTree.remainders?_isSome_of_capacity.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.RemainderTree R) (p : Hex.DensePoly R) (hcap : p.size ≤ tree.rootDegree + tree.capacity) : (tree.remainders? p).isSome = trueHex.DensePoly.RemainderTree.remainders?_isSome_of_capacity.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.RemainderTree R) (p : Hex.DensePoly R) (hcap : p.size ≤ tree.rootDegree + tree.capacity) : (tree.remainders? p).isSome = true
A caller-supplied root capacity covering the input above the root degree makes the entire traversal succeed. Every proper-node guard follows from the sibling-degree capacities recorded by construction.
Hex.DensePoly.RemainderTree.remainders?_sound.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.RemainderTree R) (p : Hex.DensePoly R) (results : Array (Hex.DensePoly R)) (h : tree.remainders? p = some results) : p.RemainderSpec tree.entries.toList results.toListHex.DensePoly.RemainderTree.remainders?_sound.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (tree : Hex.DensePoly.RemainderTree R) (p : Hex.DensePoly R) (results : Array (Hex.DensePoly R)) (h : tree.remainders? p = some results) : p.RemainderSpec tree.entries.toList results.toList
Every successful traversal returns, in leaf order, the canonical-size remainder of the input modulo each leaf polynomial.
Hex.DensePoly.EvalPlan specializes the leaves to x - a and caches
the reciprocal plans used by its remainder tree. Evaluation is total: inputs
within capacity use the tree, and oversized inputs use direct pointwise
evaluation.
Hex.DensePoly.EvalPlan.build.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (mul : Hex.DensePoly.MulPlan R) (points : Array R) : Hex.DensePoly.EvalPlan RHex.DensePoly.EvalPlan.build.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (mul : Hex.DensePoly.MulPlan R) (points : Array R) : Hex.DensePoly.EvalPlan R
Build the point-product tree and all finite-capacity reciprocal plans.
Hex.DensePoly.EvalPlan.treeView.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.EvalPlan R) : Hex.DensePoly.ProductTree RHex.DensePoly.EvalPlan.treeView.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.EvalPlan R) : Hex.DensePoly.ProductTree R
Rebuild the observational leaf-and-root product-tree view. Constructing an evaluation plan does not eagerly recompute this redundant product tree.
Hex.DensePoly.EvalPlan.eval.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.EvalPlan R) (f : Hex.DensePoly R) : Array RHex.DensePoly.EvalPlan.eval.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.EvalPlan R) (f : Hex.DensePoly R) : Array R
Specification of multipoint evaluation. The compiled implementation below replaces this direct map by the cached remainder tree.
Hex.DensePoly.EvalPlan.get_eval.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.EvalPlan R) (f : Hex.DensePoly R) (i : Nat) (hi : i < plan.size) : (plan.eval f)[i] = f.eval plan.points[i]Hex.DensePoly.EvalPlan.get_eval.{u} {R : Type u} [DecidableEq R] [Lean.Grind.CommRing R] (plan : Hex.DensePoly.EvalPlan R) (f : Hex.DensePoly R) (i : Nat) (hi : i < plan.size) : (plan.eval f)[i] = f.eval plan.points[i]
Every output entry is evaluation at the corresponding planned point.
Hex.DensePoly.InterpPlan additionally requires a field and distinct
points. Plan construction rejects exactly duplicate points, while interpolation
rejects exactly a mismatch between point and value counts.
Hex.DensePoly.InterpPlan.build?.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (mul : Hex.DensePoly.MulPlan F) (points : Array F) : Option (Hex.DensePoly.InterpPlan F)Hex.DensePoly.InterpPlan.build?.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (mul : Hex.DensePoly.MulPlan F) (points : Array F) : Option (Hex.DensePoly.InterpPlan F)
Build a reusable interpolation plan exactly when the points are distinct.
Hex.DensePoly.InterpPlan.interpolate?.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.InterpPlan F) (values : Array F) : Option (Hex.DensePoly F)Hex.DensePoly.InterpPlan.interpolate?.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.InterpPlan F) (values : Array F) : Option (Hex.DensePoly F)
Interpolate a matching value array, rejecting only a count mismatch.
Hex.DensePoly.InterpPlan.interpolate?_sound.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.InterpPlan F) (values : Array F) (p : Hex.DensePoly F) (hsome : plan.interpolate? values = some p) : p.size ≤ plan.size ∧ ∀ (i : Nat) (hi : i < plan.size), p.eval plan.points[i] = values.getD i 0Hex.DensePoly.InterpPlan.interpolate?_sound.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.InterpPlan F) (values : Array F) (p : Hex.DensePoly F) (hsome : plan.interpolate? values = some p) : p.size ≤ plan.size ∧ ∀ (i : Nat) (hi : i < plan.size), p.eval plan.points[i] = values.getD i 0
A successful interpolation has the requested values and no more coefficients than there are points.
Hex.DensePoly.InterpPlan.interpolate?_unique.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.InterpPlan F) (values : Array F) (p q : Hex.DensePoly F) (hsome : plan.interpolate? values = some p) (hqsize : q.size ≤ plan.size) (hqvalues : ∀ (i : Nat) (hi : i < plan.size), q.eval plan.points[i] = values.getD i 0) : q = pHex.DensePoly.InterpPlan.interpolate?_unique.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.InterpPlan F) (values : Array F) (p q : Hex.DensePoly F) (hsome : plan.interpolate? values = some p) (hqsize : q.size ≤ plan.size) (hqvalues : ∀ (i : Nat) (hi : i < plan.size), q.eval plan.points[i] = values.getD i 0) : q = p
The successful interpolation is the unique polynomial of size at most the point count with the supplied values.
open Hex Hex.DensePoly
namespace HexPolyFastChapterPoints
private def points : Array Rat :=
#[-1, 0, 2]
private def values : Array Rat :=
#[6, 3, 3]
private def expected : DensePoly Rat :=
#p[3, -2, 1]
private def interpolated : Option (DensePoly Rat) :=
(InterpPlan.build?
(karatsubaPlan 2) points).bind
(fun plan => plan.interpolate? values)
#guard interpolated = some expected
#guard
(InterpPlan.build? (karatsubaPlan 2)
(#[1, 2, 1] : Array Rat)).isNone
end HexPolyFastChapterPoints
35.2.7. Padé approximation
Hex.DensePoly.PadeApproximant carries a homogeneous numerator and
denominator, their degree bounds, nontriviality, and the required low-order
congruence. Hex.DensePoly.NormalizedPade strengthens the denominator's
constant coefficient to one.
Hex.DensePoly.padeHomogeneous.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) {k : Nat} (s : Hex.TSeries F k) (m n : Nat) : Hex.DensePoly.PadeApproximant s m nHex.DensePoly.padeHomogeneous.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) {k : Nat} (s : Hex.TSeries F k) (m n : Nat) : Hex.DensePoly.PadeApproximant s m n
Compute a homogeneous Padé approximant with the selected multiplication plan. The half-gcd prefix stops precisely when the remainder crosses the numerator-size boundary.
Hex.DensePoly.pade?.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) {k : Nat} (s : Hex.TSeries F k) (m n : Nat) : Option (Hex.DensePoly.NormalizedPade s m n)Hex.DensePoly.pade?.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) {k : Nat} (s : Hex.TSeries F k) (m n : Nat) : Option (Hex.DensePoly.NormalizedPade s m n)
Compute the normalized rational-series Padé form when its denominator can be made a unit at the origin.
Hex.DensePoly.pade?_eq_none_iff.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) {k : Nat} (s : Hex.TSeries F k) (m n : Nat) : Hex.DensePoly.pade? plan s m n = none ↔ ¬Nonempty (Hex.DensePoly.NormalizedPade s m n)Hex.DensePoly.pade?_eq_none_iff.{u} {F : Type u} [DecidableEq F] [Lean.Grind.Field F] (plan : Hex.DensePoly.MulPlan F) {k : Nat} (s : Hex.TSeries F k) (m n : Nat) : Hex.DensePoly.pade? plan s m n = none ↔ ¬Nonempty (Hex.DensePoly.NormalizedPade s m n)
Normalized Padé construction fails exactly when no denominator with constant coefficient one satisfies the requested bounds and congruence.
The homogeneous result is total. The normalized operation returns none
exactly when no admissible denominator is invertible at the origin.
open Hex Hex.DensePoly
namespace HexPolyFastChapterPade
private def series : TSeries Rat 3 :=
TSeries.ofFn fun _ => 1
private def approximant :
Option (DensePoly Rat × DensePoly Rat) :=
(pade? (karatsubaPlan 2) series 1 1).map
(fun approx => (approx.p, approx.q))
#guard approximant = some (C 1, #p[1, -1])
end HexPolyFastChapterPade
35.2.8. Computational boundary and cross-references
All algorithms and correctness theorems in this chapter are Mathlib-free and
run natively in Lean. There is no separate Mathlib companion: the operations
reduce to the existing DensePoly semantics, which the
HexPoly chapter and its companion already connect to
Mathlib polynomials.
Coefficient-specific callers construct plans above this dependency boundary.
HexPolyZ supplies Kronecker and CRT-NTT integer kernels,
while HexPolyFp supplies direct and auxiliary-prime
NTT multiplication. The generic algorithms here remain their independent
semantic fallback.