The leading coefficient, or 0 for the zero polynomial.
9.6. Euclidean operations
Over a field the dense representation supports division with remainder, quotient and remainder operators, and gcd. The entry points are the leading coefficient and the monic predicate.
A polynomial is monic when its leading coefficient is 1.
Hex.DensePoly.monic_iff_leadingCoeff_eq_one.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] {p : Hex.DensePoly R} : p.Monic ↔ p.leadingCoeff = 1Hex.DensePoly.monic_iff_leadingCoeff_eq_one.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] {p : Hex.DensePoly R} : p.Monic ↔ p.leadingCoeff = 1
Characterization of Monic by the leading coefficient equation.
Division has two flavours. Hex.DensePoly.divModMonic divides by
a monic divisor over any commutative ring. No division of coefficients
is needed because the leading coefficient is 1.
Hex.DensePoly.divMod is the field version: it scales by the
inverse of the divisor's leading coefficient and so requires a Div on
the coefficient type.
Hex.DensePoly.divModMonic.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] (p q : Hex.DensePoly R) (_hmonic : q.Monic) : Hex.DensePoly R × Hex.DensePoly RHex.DensePoly.divModMonic.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] (p q : Hex.DensePoly R) (_hmonic : q.Monic) : Hex.DensePoly R × Hex.DensePoly R
Divide by a monic polynomial. The remainder has degree below the divisor whenever the fuel is sufficient, which is the case for normalized dense polynomials.
Hex.DensePoly.divMod.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly R × Hex.DensePoly RHex.DensePoly.divMod.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly R × Hex.DensePoly R
Polynomial division with remainder over a field.
The Div, Mod, and Dvd instances expose the field quotient and
remainder as p / q, p % q, and q ∣ p, and the extended algorithm
returns the gcd with its Bezout coefficients.
Hex.DensePoly.div.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.div.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly R
Quotient from polynomial long division over a field.
Hex.DensePoly.mod.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.mod.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly R
Remainder from polynomial long division over a field.
Hex.DensePoly.modByMonic.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] (p q : Hex.DensePoly R) (hmonic : q.Monic) : Hex.DensePoly RHex.DensePoly.modByMonic.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] (p q : Hex.DensePoly R) (hmonic : q.Monic) : Hex.DensePoly R
Remainder from long division by a monic polynomial over a commutative ring.
Hex.DensePoly.gcd.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly RHex.DensePoly.gcd.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly R
Polynomial gcd over a field. Computed by the plain remainder sequence
(gcdAux), not the extended algorithm: the gcd value is independent of the
Bezout coefficients, and computing them costs an extra polynomial multiplication
per step (O(deg³) vs O(deg²)). xgcd stays available for callers that
genuinely need Bezout coefficients.
Hex.DensePoly.xgcd.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly.XGCDResult RHex.DensePoly.xgcd.{u} {R : Type u} [Zero R] [DecidableEq R] [One R] [Add R] [Sub R] [Mul R] [Div R] (p q : Hex.DensePoly R) : Hex.DensePoly.XGCDResult R
Extended gcd over a field, returning the gcd together with Bezout coefficients.
9.6.1. Worked example: division over the rationals
This block works over DensePoly Rat. It divides x² - 1 by x - 1,
reads off the quotient and remainder, checks the Euclidean
reconstruction, and computes a gcd.
open Hex Hex.DensePoly
namespace HexPolyChapterEuclid
-- p = x² - 1, q = x - 1
private def p : DensePoly Rat := ofCoeffs #[-1, 0, 1]
private def q : DensePoly Rat := ofCoeffs #[-1, 1]
-- x² - 1 = (x - 1)(x + 1), so the division is exact.
-- Quotient x + 1, remainder 0.
#guard (divMod p q).1.toArray.toList = [1, 1]
#guard (divMod p q).2 = (0 : DensePoly Rat)
#guard (p / q).toArray.toList = [1, 1]
#guard p % q = (0 : DensePoly Rat)
-- Euclidean reconstruction: (p / q) · q + (p % q) = p.
#guard (p / q) * q + (p % q) = p
-- q is monic, so it also divides p through the
-- ring-only path.
#guard q.leadingCoeff = 1
#guard modByMonic p q (⊢ q.Monic All goals completed! 🐙) = (0 : DensePoly Rat)
-- gcd(x² - 1, x + 1) = x + 1: a monic gcd.
#guard gcd p (ofCoeffs #[1, 1]) = ofCoeffs #[1, 1]
end HexPolyChapterEuclid