LeanFun RevOLVER

4.2 Banded multiplication, differentiation and conversion

In Jacobi and ultraspherical bases, multiplication by \(x\) is tridiagonal. Differentiation raises the parameters and has a single superdiagonal. One-step conversion has bandwidth \((0,1)\) for Jacobi and \((0,2)\) for ultraspherical bases. These sparse matrices are those of the ultraspherical spectral method [OT13], used by ApproxFun [AF]. The identities with denominators cleared hold over every commutative \(\mathbb {Q}\)-algebra. Divided entries and bandwidths require nonvanishing denominators; these conditions hold in the real orthogonality ranges.

In a Jacobi target basis, write \(s=\alpha +\beta \). For input degree \(n\ge 1\), only rows \(n+1,n,n-1\) can be nonzero, with respective entries

\[ \frac{2(n+1)(n+s+1)}{(2n+s+1)(2n+s+2)},\qquad \frac{\beta ^2-\alpha ^2}{(2n+s)(2n+s+2)},\qquad \frac{2(n+\alpha )(n+\beta )}{(2n+s)(2n+s+1)}. \]

Column zero has entries \(2/(s+2)\) in row one and \((\beta -\alpha )/(s+2)\) in row zero. The divided formulas hold over fields with a rational algebra structure when the displayed denominator factors are nonzero; cleared identities hold over commutative rational algebras. For real \(\alpha ,\beta {\gt}-1\) all factors are nonzero and the matrix has bandwidths \((1,1)\).

Reference: [DLMF, 18.9.1–18.9.2].

Lean Formalisation
theorem Polynomial.jacobi_mul_matrix_succ.{u_1} {R : Type u_1} [CommRing R] [Algebra ℚ R] (α β : R)
  (b : Module.Basis ℕ R (Polynomial R)) (hb : ∀ (k : ℕ), b k = Polynomial.jacobi α β k) (n i : ℕ) :
  (2 * ↑n + α + β + 3) * (2 * ↑n + α + β + 2) * (2 * ↑n + α + β + 4) *
      b.toMatrix (fun j => Polynomial.X * Polynomial.jacobi α β j) i (n + 1) =
    ((if i = n + 2 then 2 * (↑n + 2) * (↑n + α + β + 2) * (2 * ↑n + α + β + 2) else 0) -
        if i = n + 1 then (2 * ↑n + α + β + 3) * (α ^ 2 - β ^ 2) else 0) +
      if i = n then 2 * (↑n + α + 1) * (↑n + β + 1) * (2 * ↑n + α + β + 4) else 0
Lean proof
/-- Cleared multiplication entries for positive-index columns (DLMF 18.9.1--2). -/
theorem jacobi_mul_matrix_succ
    (hb : ∀ k, b k = jacobi α β k) (n i : ℕ) :
    ((2 * n + α + β + 3) * (2 * n + α + β + 2) * (2 * n + α + β + 4)) *
        b.toMatrix (fun j ↦ X * jacobi α β j) i (n + 1) =
      (if i = n + 2 then 2 * (n + 2) * (n + α + β + 2) *
        (2 * n + α + β + 2) else 0) -
      (if i = n + 1 then (2 * n + α + β + 3) * (α ^ 2 - β ^ 2) else 0) +
      (if i = n then 2 * (n + α + 1) * (n + β + 1) *
        (2 * n + α + β + 4) else 0) := by
  have he : C ((2 * n + α + β + 3) * (2 * n + α + β + 2) *
        (2 * n + α + β + 4)) * (X * jacobi α β (n + 1)) =
      C (2 * (n + 2) * (n + α + β + 2) * (2 * n + α + β + 2)) *
        jacobi α β (n + 2) -
      C ((2 * n + α + β + 3) * (α ^ 2 - β ^ 2)) * jacobi α β (n + 1) +
      C (2 * (n + α + 1) * (n + β + 1) * (2 * n + α + β + 4)) * jacobi α β n := by
    have h := jacobi_recurrence α β n
    simp only [map_mul, map_add, map_sub, map_pow, map_natCast, map_ofNat] at h ⊢
    linear_combination -h
  have h := congrArg (fun p : R[X] ↦ b.repr p i) he
  simp only [← smul_eq_C_mul] at h
  simp only [map_add, map_sub, map_smul, Finsupp.coe_add, Finsupp.coe_sub,
    Pi.add_apply, Pi.sub_apply, Finsupp.coe_smul, Pi.smul_apply, smul_eq_mul] at h
  simpa [Basis.toMatrix_apply, ← hb, Finsupp.single_apply, eq_comm, mul_ite] using h
source

Jacobi differentiation from \((\alpha ,\beta )\) to \((\alpha +1,\beta +1)\) has entry \((n+\alpha +\beta +2)/2\) in row \(n\), column \(n+1\). Gegenbauer differentiation from \(\lambda \) to \(\lambda +1\) has entry \(2\lambda \) in row \(n\), column \(n+1\). All other entries vanish, including column zero. These are identities over commutative rational algebras whenever the specified target bases exist; both matrices have bandwidths \((0,1)\). The concrete real bases above supply them throughout their orthogonality ranges.

References: [DLMF, 18.9.15, 18.9.19]; [OT13].

Lean Formalisation
theorem Polynomial.jacobi_derivative_matrix_succ.{u_1} {R : Type u_1} [CommRing R] [Algebra ℚ R] (α β : R)
  (b : Module.Basis ℕ R (Polynomial R)) (hb : ∀ (k : ℕ), b k = Polynomial.jacobi (α + 1) (β + 1) k) (n i : ℕ) :
  b.toMatrix (fun j => Polynomial.derivative (Polynomial.jacobi α β j)) i (n + 1) =
    if i = n then (algebraMap ℚ R) (1 / 2) * (↑n + α + β + 2) else 0
Lean proof
/-- Differentiation has one nonzero diagonal in the doubly shifted Jacobi basis
(DLMF 18.9.15; Olver--Townsend 2013). -/
theorem jacobi_derivative_matrix_succ
    (hb : ∀ k, b k = jacobi (α + 1) (β + 1) k) (n i : ℕ) :
    b.toMatrix (fun j ↦ derivative (jacobi α β j)) i (n + 1) =
      if i = n then algebraMap ℚ R (1 / 2) * (n + α + β + 2) else 0 := by
  rw [Basis.toMatrix_apply, derivative_jacobi_succ, ← smul_eq_C_mul, ← hb]
  simp [Finsupp.single_apply, eq_comm]
source

Let \(s=\alpha +\beta \). For input degree \(n\ge 1\), conversion raising \(\alpha \) has entries \((n+s+1)/(2n+s+1)\) in row \(n\) and \(-(n+\beta )/(2n+s+1)\) in row \(n-1\). Conversion raising \(\beta \) has the same diagonal entry and \((n+\alpha )/(2n+s+1)\) in row \(n-1\). Column zero is the unit column at zero. All other entries vanish. The divided formulas require \(2n+s+1\ne 0\) over a field; the cleared identities hold over every commutative rational algebra with the specified target basis. For real \(\alpha ,\beta {\gt}-1\) both matrices have bandwidths \((0,1)\) with no additional denominator hypotheses.

Reference: [DLMF, 18.9.5] and its reflection.

Lean Formalisation
theorem Polynomial.jacobi_raise_beta_matrix_succ.{u_1} {R : Type u_1} [CommRing R] [Algebra ℚ R] (α β : R)
  (b : Module.Basis ℕ R (Polynomial R)) (hb : ∀ (k : ℕ), b k = Polynomial.jacobi α (β + 1) k) (n i : ℕ) :
  (2 * ↑n + α + β + 3) * b.toMatrix (Polynomial.jacobi α β) i (n + 1) =
    (if i = n + 1 then ↑n + α + β + 2 else 0) + if i = n then ↑n + α + 1 else 0
Lean proof
/-- Cleared entries for raising the second parameter (DLMF 18.9.5). -/
theorem jacobi_raise_beta_matrix_succ
    (hb : ∀ k, b k = jacobi α (β + 1) k) (n i : ℕ) :
    (2 * n + α + β + 3) * b.toMatrix (jacobi α β) i (n + 1) =
      (if i = n + 1 then n + α + β + 2 else 0) +
        (if i = n then n + α + 1 else 0) := by
  have h := congrArg (fun p : R[X] ↦ b.repr p i) (jacobi_raise_beta α β n)
  simp only [← smul_eq_C_mul] at h
  simp only [map_add, map_smul, Finsupp.coe_add, Pi.add_apply,
    Finsupp.coe_smul, Pi.smul_apply, smul_eq_mul, ← hb] at h
  simpa [Basis.toMatrix_apply, Finsupp.single_apply, eq_comm, mul_ite] using h
source
Reference details: Cleared Jacobi derivative lowering
Theorem 4.2.4 Cleared Jacobi derivative lowering
✓ 🤖

For \(n\ge 0\) over every commutative \(\mathbb {Q}\)-algebra, put \(s=\alpha +\beta \). Then

\begin{align*} (2n+s+2)(1-X^2)(P_{n+1}^{(\alpha ,\beta )})’ & = (n+1)[\alpha -\beta -(2n+s+2)X]P_{n+1}^{(\alpha ,\beta )}\\ & \quad +2(n+\alpha +1)(n+\beta +1)P_n^{(\alpha ,\beta )}. \end{align*}

This includes degenerate parameters, without division by parameter factors.

Reference: [DLMF, 18.9.17], with its degree shifted by one.

Lean Formalisation
theorem Polynomial.jacobi_derivative_lowering.{u_1} {R : Type u_1} [CommRing R] [Algebra ℚ R] (α β : R) (n : ℕ) :
  Polynomial.C (2 * ↑n + α + β + 2) * (1 - Polynomial.X ^ 2) * Polynomial.derivative (Polynomial.jacobi α β (n + 1)) -
        Polynomial.C (↑n + 1) * (Polynomial.C (α - β) - Polynomial.C (2 * ↑n + α + β + 2) * Polynomial.X) *
          Polynomial.jacobi α β (n + 1) -
      Polynomial.C (2 * (↑n + α + 1) * (↑n + β + 1)) * Polynomial.jacobi α β n =
    0
Lean proof
/-- The cleared first-order lowering identity, including degenerate parameters.
This derivative form complements the three-term recurrence (DLMF 18.9). -/
theorem jacobi_derivative_lowering {R : Type*} [CommRing R] [Algebra ℚ R]
    (α β : R) (n : ℕ) :
    C (2 * n + α + β + 2) * (1 - X ^ 2) * derivative (jacobi α β (n + 1)) -
      C (n + 1 : R) * (C (α - β) - C (2 * n + α + β + 2) * X) * jacobi α β (n + 1) -
      C (2 * (n + α + 1) * (n + β + 1)) * jacobi α β n = 0 := by
  have h := jacobi_lower_of_nonzero (X : ℚ[X][X]) (C X) n (fun k hk ↦ by
    have hc := congrArg (fun p : ℚ[X][X] ↦ p.coeff 1) hk
    norm_num [coeff_add, coeff_natCast_ite, coeff_one] at hc)
  let f : ℚ[X][X] →ₐ[ℚ] R := eval₂AlgHom (aeval β) α (fun _ ↦ Commute.all _ _)
  have hm := congrArg (Polynomial.map f.toRingHom) h
  simp only [Polynomial.map_mul, Polynomial.map_sub,
    Polynomial.map_pow, Polynomial.map_one, Polynomial.map_zero,
    Polynomial.map_C, map_X, ← derivative_map, map_jacobi] at hm
  simpa [f, eval₂_add, eval₂_sub, eval₂_mul, eval₂_pow, eval₂_natCast, eval₂_ofNat] using hm
source

In a Gegenbauer basis, column \(n\ge 1\) of multiplication has entries \((n+1)/(2(n+\lambda ))\) in row \(n+1\) and \((n+2\lambda -1)/(2(n+\lambda ))\) in row \(n-1\); the diagonal is zero. Column zero has entry \(1/(2\lambda )\) in row one. Over a field the divided formulas require their denominators nonzero; cleared identities hold over commutative rational algebras. For real \(\lambda {\gt}-1/2\), \(\lambda \ne 0\), the matrix has bandwidths \((1,1)\).

Reference: [DLMF, 18.9.1, Table 18.9.1].

Lean Formalisation
theorem Polynomial.gegenbauer_mul_matrix_succ.{u_1} {R : Type u_1} [CommRing R] [Algebra ℚ R] (lam : R)
  (b : Module.Basis ℕ R (Polynomial R)) (hb : ∀ (k : ℕ), b k = Polynomial.gegenbauer lam k) (n i : ℕ) :
  2 * (↑n + lam + 1) * b.toMatrix (fun j => Polynomial.X * Polynomial.gegenbauer lam j) i (n + 1) =
    (if i = n + 2 then ↑n + 2 else 0) + if i = n then ↑n + 2 * lam else 0
Lean proof
/-- Cleared multiplication entries in the positive-index columns (DLMF 18.9.1). -/
theorem gegenbauer_mul_matrix_succ
    (hb : ∀ k, b k = gegenbauer lam k) (n i : ℕ) :
    (2 * (n + lam + 1)) * b.toMatrix (fun j ↦ X * gegenbauer lam j) i (n + 1) =
      (if i = n + 2 then (n : R) + 2 else 0) + (if i = n then n + 2 * lam else 0) := by
  have h := congrArg (fun p : R[X] ↦ b.repr p i) (gegenbauer_recurrence lam n)
  rw [mul_assoc] at h
  simp only [← smul_eq_C_mul] at h
  simp [← hb, Finsupp.single_apply, eq_comm] at h
  change _ * (b.repr (X * gegenbauer lam (n + 1))) i = _
  rw [← hb]
  split_ifs at h ⊢ <;> first | omega | linear_combination h
source

Conversion from parameter \(\lambda \) to \(\lambda +1\) has entries \(\lambda /(n+\lambda )\) in row \(n\) and \(-\lambda /(n+\lambda )\) in row \(n-2\) of column \(n\ge 2\). Column one has entry \(\lambda /(\lambda +1)\) in row one; column zero is the unit column at zero. All other entries vanish. Over a field the divided formulas require their denominators nonzero; cleared identities hold over commutative rational algebras. For real \(\lambda {\gt}-1/2\) the target basis exists and the matrix has bandwidths \((0,2)\), also at the degenerate source parameter zero.

References: [DLMF, 18.9.7]; [OT13].

Lean Formalisation
theorem Polynomial.gegenbauer_conversion_matrix_zero.{u_1} {R : Type u_1} [CommRing R] [Algebra ℚ R] (lam : R)
  (b : Module.Basis ℕ R (Polynomial R)) (hb : ∀ (k : ℕ), b k = Polynomial.gegenbauer (lam + 1) k) (i : ℕ) :
  b.toMatrix (Polynomial.gegenbauer lam) i 0 = if i = 0 then 1 else 0
Lean proof
/-- Conversion preserves the constant column (DLMF 18.9.7). -/
theorem gegenbauer_conversion_matrix_zero
    (hb : ∀ k, b k = gegenbauer (lam + 1) k) (i : ℕ) :
    b.toMatrix (gegenbauer lam) i 0 = if i = 0 then 1 else 0 := by
  have hb0 : b 0 = 1 := by rw [hb, gegenbauer_zero]
  simp [Basis.toMatrix_apply, ← hb0, Finsupp.single_apply, eq_comm]
source

Example (Julia).

The conversion matrix of Theorem 4.2.6 for \(\lambda =0.7\) reproduces each \(C_n^{(\lambda )}(x)\) from values of \(C^{(\lambda +1)}\), both computed by the recurrence of Theorem 3.3.6. Its 40 nonzeros lie on the diagonal and the second superdiagonal, the bandwidths \((0,2)\).

function gegenbauer(n, lam, x)      # three-term recurrence
    n == 0 && return 1.0
    a, b = 1.0, 2lam*x
    for k in 1:n-1
        a, b = b, (2(k + lam)*x*b - (k + 2lam - 1)*a)/(k + 1)
    end
    b
end
N, lam = 20, 0.7
S = zeros(N+1, N+1)                 # conversion C^(lam) -> C^(lam+1)
S[1, 1] = 1
S[2, 2] = lam/(lam + 1)
for n in 2:N
    S[n+1, n+1] = lam/(n + lam)
    S[n-1, n+1] = -lam/(n + lam)
end
x = 0.37
maximum(abs(gegenbauer(n, lam, x) -
    sum(S[i+1, n+1]*gegenbauer(i, lam + 1, x) for i in 0:N)) for n in 0:N)
                                    # about 1e-16
band = all(S[i, j] == 0 for i in 1:N+1, j in 1:N+1 if !(0 <= j - i <= 2))
(count(!iszero, S), band)           # (40, true)
Theorem 4.2.7 Polynomial multiplication bandwidth in Gegenbauer bases
✓ 🤖

For real Gegenbauer bases with \(\lambda {\gt}-1/2\), \(\lambda \ne 0\), a polynomial multiplier \(p\) has bandwidths \((d,d)\), where \(d=\operatorname {natDegree}p\).

Reference: [OT13, Sections 2–3].

Lean Formalisation
theorem Polynomial.gegenbauerBasis_polynomial_mul_isBanded {lam : ℝ} (hlam : -(1 / 2) < lam) (hzero : lam ≠ 0)
  (p : Polynomial ℝ) :
  ((Polynomial.gegenbauerBasis hlam hzero).toMatrix fun j => p * (Polynomial.gegenbauerBasis hlam hzero) j).IsBanded
    p.natDegree p.natDegree
Lean proof
/-- A polynomial multiplier of degree `d` has bandwidths `(d,d)` in the
Gegenbauer basis throughout its nondegenerate orthogonality range. -/
theorem gegenbauerBasis_polynomial_mul_isBanded {lam : ℝ}
    (hlam : -(1 / 2) < lam) (hzero : lam ≠ 0) (p : ℝ[X]) :
    ((gegenbauerBasis hlam hzero).toMatrix
      (fun j ↦ p * gegenbauerBasis hlam hzero j)).IsBanded p.natDegree p.natDegree := by
  simpa only [gegenbauerBasis, Sequence.basis_eq_self] using
    (isOrthogonal_gegenbauerSequence hlam hzero).polynomial_mul_isBanded
      (hasFiniteMoments_gegenbauerMeasure hlam)
      (hasPositiveDefiniteIntegral_gegenbauerMeasure hlam)
      (fun n ↦ isUnit_iff_ne_zero.mpr
        (leadingCoeff_ne_zero.mpr ((gegenbauerSequence hlam hzero).ne_zero n))) p
source
Reference details: Finite Gegenbauer recurrence domain and related results
Definition 4.2.8 Finite Gegenbauer recurrence domain
✓ 🤖
#

For a field \(K\) and a coefficient count \(n\), the Gegenbauer Clenshaw domain requires \((k+2)\ne 0\) in \(K\) for every \(0\le k{\lt}n-2\). There is no condition when \(n\le 2\).

Lean Formalisation
def Polynomial.GegenbauerClenshawInput.{u_2} (K : Type u_2) [Field K] (n : ℕ) : Prop
Lean definition
/-- Nonzero denominators at exactly the recurrence indices used by an expansion. -/
def GegenbauerClenshawInput (K : Type*) [Field K] (n : ℕ) : Prop :=
  ∀ i : Fin (n - 2), (i.val : K) + 2 ≠ 0
source
Theorem 4.2.9 Rational-algebra Gegenbauer inputs
✓ 🤖

Over a field with a rational algebra structure, \(k+2\ne 0\) for every \(k\in \mathbb {N}\). Thus every coefficient count \(n\) satisfies the Gegenbauer Clenshaw denominator conditions of Definition 4.2.8.

Lean Formalisation
theorem Polynomial.GegenbauerClenshawInput.ofRatAlgebra.{u_1} {K : Type u_1} [Field K] [Algebra ℚ K] (n : ℕ) :
  Polynomial.GegenbauerClenshawInput K n
Lean proof
/-- Rational algebras over fields admit every finite Gegenbauer recurrence. -/
theorem GegenbauerClenshawInput.ofRatAlgebra (n : ℕ) :
    GegenbauerClenshawInput K n := by
  let : CharZero K := Algebra.charZero_of_charZero ℚ K
  intro i
  exact_mod_cast (show i.val + 2 ≠ 0 by omega)
source
Definition 4.2.10 Finite Gegenbauer Clenshaw evaluator
✓ 🤖

For a field \(K\), parameters \(\lambda ,x\in K\), \(n\) coefficients \(c_0,\ldots ,c_{n-1}\), and the denominator conditions of Definition 4.2.8, use finite Clenshaw evaluation with

\[ a_k=\frac{2(k+\lambda +1)x}{k+2},\quad b_k=-\frac{k+2\lambda }{k+2}\quad (0\le k{\lt}n-2),\qquad p_0=1,\quad p_1=2\lambda x. \]

References: [Cle55]; [DLMF, Table 18.9.1].

Lean Formalisation
def Polynomial.clenshawGegenbauer.{u_1} {K : Type u_1} [Field K] (lam x : K) (c : ℕ → K) (n : ℕ)
  (_d : Polynomial.GegenbauerClenshawInput K n := by exact Polynomial.GegenbauerClenshawInput.ofRatAlgebra _) : K
Lean definition
/-- Executable evaluation with finite denominator certificates (DLMF Table 18.9.1). -/
def clenshawGegenbauer (lam x : K) (c : ℕ → K) (n : ℕ)
    (_d : GegenbauerClenshawInput K n :=
      by exact Polynomial.GegenbauerClenshawInput.ofRatAlgebra _) : K :=
  finiteClenshaw n (fun k ↦ 2 * (k.val + lam + 1) * x / (k.val + 2))
    (fun k ↦ -(k.val + 2 * lam) / (k.val + 2)) (fun i ↦ c i.val) 1 (2 * lam * x)
source
Theorem 4.2.11 Gegenbauer Clenshaw evaluation
✓ 🤖

Over a field with a rational algebra structure, for every parameter \(\lambda \), use

\[ a_k=\frac{2(k+\lambda +1)x}{k+2},\qquad b_k=-\frac{k+2\lambda }{k+2},\qquad p_0=1,\quad p_1=2\lambda x. \]

The evaluator returns \(\sum _{i=0}^{n-1}c_iC_i^{(\lambda )}(x)\). Only positive natural denominators occur, so this includes \(\lambda =0\).

References: [Cle55]; [DLMF, Table 18.9.1].

Lean Formalisation
theorem Polynomial.clenshawGegenbauer_eq_sum.{u_1} {K : Type u_1} [Field K] [Algebra ℚ K] (lam x : K) (c : ℕ → K) (n : ℕ) :
  Polynomial.clenshawGegenbauer lam x c n ⋯ =
    ∑ i ∈ Finset.range n, c i * Polynomial.eval x (Polynomial.gegenbauer lam i)
Lean proof
/-- Clenshaw evaluation is exact for every Gegenbauer parameter. -/
theorem clenshawGegenbauer_eq_sum (lam x : K) (c : ℕ → K) (n : ℕ) :
    clenshawGegenbauer lam x c n =
      ∑ i ∈ Finset.range n, c i * (gegenbauer lam i).eval x := by
  let : CharZero K := Algebra.charZero_of_charZero ℚ K
  have hp (k : ℕ) : (gegenbauer lam (k + 2)).eval x =
      (2 * (k + lam + 1) * x / (k + 2)) * (gegenbauer lam (k + 1)).eval x +
        (-(k + 2 * lam) / (k + 2)) * (gegenbauer lam k).eval x := by
    have hd : (k : K) + 2 ≠ 0 := by exact_mod_cast (show k + 2 ≠ 0 by omega)
    have h := congrArg (fun p : K[X] ↦ p.eval x) (gegenbauer_recurrence lam k)
    simp only [eval_sub, eval_add, eval_mul, eval_C, eval_X, eval_zero] at h
    field_simp [hd]
    linear_combination h
  have he := clenshaw_eq_sum _ _ c (fun k ↦ (gegenbauer lam k).eval x) hp n
  have hf := finiteClenshaw_eq
    (fun k ↦ 2 * (k + lam + 1) * x / (k + 2))
    (fun k ↦ -(k + 2 * lam) / (k + 2)) c 1 (2 * lam * x) n
  simpa [clenshawGegenbauer] using hf.trans (by simpa using he)
source
Definition 4.2.12 Finite Jacobi recurrence domain
✓ 🤖
#

For a field \(K\), parameters \(\alpha ,\beta \in K\) and a coefficient count \(n\), the Jacobi Clenshaw domain requires \(2\ne 0\) when \(n\ge 2\), and

\[ d_k=2(k+2)(k+\alpha +\beta +2)(2k+\alpha +\beta +2)\ne 0 \qquad (0\le k{\lt}n-2). \]

Empty and constant expansions impose no denominator conditions.

Lean Formalisation
inductive Polynomial.JacobiClenshawInput.{u_1} {K : Type u_1} [Field K] (α β : K) (n : ℕ) : Prop
Lean definition
/-- Classical denominators needed by the first `n` Jacobi coefficients. -/
structure JacobiClenshawInput (α β : K) (n : ℕ) : Prop where
  two_ne_zero : 2 ≤ n → (2 : K) ≠ 0
  denominator_ne_zero : ∀ i : Fin (n - 2),
    2 * (i.val + 2 : K) * (i.val + α + β + 2) * (2 * i.val + α + β + 2) ≠ 0
source
Theorem 4.2.13 Constructing finite Jacobi inputs
✓ 🤖

In a field with a rational algebra structure, if \(d_k\ne 0\) for every \(k\ge 0\), the denominator conditions of Definition 4.2.12 hold for every coefficient count \(n\). For real \(\alpha ,\beta {\gt}-1\), these denominator conditions hold without further assumptions.

Lean Formalisation
theorem Polynomial.JacobiClenshawInput.ofDenominators.{u_1} {K : Type u_1} [Field K] [Algebra ℚ K] (α β : K)
  (hd : ∀ (k : ℕ), 2 * (↑k + 2) * (↑k + α + β + 2) * (2 * ↑k + α + β + 2) ≠ 0) (n : ℕ) :
  Polynomial.JacobiClenshawInput α β n
Lean proof
/-- Global recurrence nonvanishing supplies every finite input. -/
theorem JacobiClenshawInput.ofDenominators (α β : K)
    (hd : ∀ k : ℕ, 2 * (k + 2 : K) * (k + α + β + 2) * (2 * k + α + β + 2) ≠ 0)
    (n : ℕ) : JacobiClenshawInput α β n := by
  let : CharZero K := Algebra.charZero_of_charZero ℚ K
  exact ⟨fun _ ↦ by norm_num, fun i ↦ hd i.val⟩
source
Definition 4.2.14 Finite Jacobi Clenshaw evaluator
✓ 🤖

For a field \(K\), parameters \(\alpha ,\beta ,x\in K\), \(n\) coefficients \(c_0,\ldots ,c_{n-1}\), and the denominator conditions of Definition 4.2.12, return \(0\) if \(n=0\) and \(c_0\) if \(n=1\). For \(n\ge 2\), use finite Clenshaw evaluation with

\[ a_k=\frac{(2k+\alpha +\beta +3) ((2k+\alpha +\beta +2)(2k+\alpha +\beta +4)x+\alpha ^2-\beta ^2)}{d_k}, \qquad b_k=-\frac{2(k+\alpha +1)(k+\beta +1)(2k+\alpha +\beta +4)}{d_k} \quad (0\le k{\lt}n-2), \]

where \(d_k=2(k+2)(k+\alpha +\beta +2)(2k+\alpha +\beta +2)\), and \(p_0=1\), \(p_1=\alpha +1+\tfrac 12(\alpha +\beta +2)(x-1)\). References: [Cle55]; [DLMF, 18.9.1–2].

Lean Formalisation
def Polynomial.clenshawJacobi.{u_1} {K : Type u_1} [Field K] (α β x : K) (c : ℕ → K) (n : ℕ)
  (_d : Polynomial.JacobiClenshawInput α β n) : K
Lean definition
/-- Finite Jacobi evaluation; empty and constant expansions need no division.
References: Clenshaw (1955), DLMF 18.9.1--2. -/
def clenshawJacobi (α β x : K) (c : ℕ → K) (n : ℕ)
    (_d : JacobiClenshawInput α β n) : K :=
  match n with
  | 0 => 0
  | 1 => c 0
  | m + 2 => finiteClenshaw (m + 2)
    (fun k ↦ (2 * k.val + α + β + 3) *
      ((2 * k.val + α + β + 2) * (2 * k.val + α + β + 4) * x + (α ^ 2 - β ^ 2)) /
        (2 * (k.val + 2) * (k.val + α + β + 2) * (2 * k.val + α + β + 2)))
    (fun k ↦ -(2 * (k.val + α + 1) * (k.val + β + 1) * (2 * k.val + α + β + 4)) /
      (2 * (k.val + 2) * (k.val + α + β + 2) * (2 * k.val + α + β + 2)))
    (fun i ↦ c i.val) 1 ((α + 1) + (α + β + 2) / 2 * (x - 1))
source

Over a field with a rational algebra structure, write

\[ d_k=2(k+2)(k+\alpha +\beta +2)(2k+\alpha +\beta +2). \]

Assume \(d_k\ne 0\) for every \(k\in \mathbb {N}\). Use

\[ \begin{aligned} a_k& =\frac{(2k+\alpha +\beta +3) ((2k+\alpha +\beta +2)(2k+\alpha +\beta +4)x+\alpha ^2-\beta ^2)}{d_k},\\ b_k& =-\frac{2(k+\alpha +1)(k+\beta +1)(2k+\alpha +\beta +4)}{d_k}. \end{aligned} \]

with \(p_0=1\) and \(p_1=\alpha +1+\tfrac 12(\alpha +\beta +2)(x-1)\). The evaluator returns \(\sum _{i=0}^{n-1}c_iP_i^{(\alpha ,\beta )}(x)\). For real \(\alpha ,\beta {\gt}-1\), all \(d_k\) are positive and no extra hypotheses are needed. In particular, \(\alpha +\beta =-1\) is included.

References: [Cle55]; [DLMF, 18.9.1–2].

Lean Formalisation
theorem Polynomial.clenshawJacobi_eq_sum.{u_1} {K : Type u_1} [Field K] [Algebra ℚ K] (α β x : K) (c : ℕ → K)
  (hd : ∀ (k : ℕ), 2 * (↑k + 2) * (↑k + α + β + 2) * (2 * ↑k + α + β + 2) ≠ 0) (n : ℕ) :
  Polynomial.clenshawJacobi α β x c n ⋯ = ∑ i ∈ Finset.range n, c i * Polynomial.eval x (Polynomial.jacobi α β i)
Lean proof
/-- Exact Jacobi evaluation wherever the forward recurrence denominators are nonzero. -/
theorem clenshawJacobi_eq_sum (α β x : K) (c : ℕ → K)
    (hd : ∀ k : ℕ,
      2 * (k + 2 : K) * (k + α + β + 2) * (2 * k + α + β + 2) ≠ 0) (n : ℕ) :
    clenshawJacobi α β x c n (JacobiClenshawInput.ofDenominators α β hd n) =
      ∑ i ∈ Finset.range n, c i * (jacobi α β i).eval x := by
  have hp (k : ℕ) : (jacobi α β (k + 2)).eval x =
      ((2 * k + α + β + 3) *
        ((2 * k + α + β + 2) * (2 * k + α + β + 4) * x + (α ^ 2 - β ^ 2)) /
          (2 * (k + 2) * (k + α + β + 2) * (2 * k + α + β + 2))) *
        (jacobi α β (k + 1)).eval x +
      (-(2 * (k + α + 1) * (k + β + 1) * (2 * k + α + β + 4)) /
          (2 * (k + 2) * (k + α + β + 2) * (2 * k + α + β + 2))) *
        (jacobi α β k).eval x := by
    have h := congrArg (fun p : K[X] ↦ p.eval x) (jacobi_recurrence α β k)
    simp only [eval_mul, eval_sub, eval_add, eval_C, eval_X] at h
    rw [div_mul_eq_mul_div, div_mul_eq_mul_div, ← add_div, eq_div_iff (hd k)]
    linear_combination h
  have he := clenshaw_eq_sum _ _ c (fun k ↦ (jacobi α β k).eval x) hp n
  rw [clenshawJacobi_eq_clenshaw]
  simpa [jacobi_one, map_div, mul_comm, div_eq_mul_inv] using he
source

Chebyshev expansions enter the ultraspherical bases through \(C^{(1)}=U\). Conversion \(T\to C^{(1)}\) has bandwidth \((0,2)\), and the \(k\)th derivative maps \(T\) to \(C^{(k)}\) with a single nonzero diagonal \(k\) places above the main one. Multiplication in the \(T\) basis has a Toeplitz-plus-Hankel form. The entry formula below includes the adjustments required by the full constant term.

Over a commutative rational algebra, \(C_n^{(1)}=U_n\) and \(2T_{n+2}=C_{n+2}^{(1)}-C_n^{(1)}\). For \(k,n\ge 0\),

\[ D^{k+1}T_{n+k+1}=2^k k!(n+k+1)C_n^{(k+1)}. \]

Over a characteristic-zero field, \(D^kT_n=0\) when \(n{\lt}k\). These identities retain the full constant coefficient convention.

References: [DLMF, 18.7.4 and 18.9.9]; [OT13, §2].

Lean Formalisation
theorem Polynomial.gegenbauer_one_eq_chebyshev_U.{u_1} (R : Type u_1) [CommRing R] [Algebra ℚ R] (n : ℕ) :
  Polynomial.gegenbauer 1 n = Polynomial.Chebyshev.U R ↑n
Lean proof
/-- Parameter-one Gegenbauer polynomials are Chebyshev U, with no rescaling
(DLMF 18.7.4). -/
theorem gegenbauer_one_eq_chebyshev_U (R : Type*) [CommRing R] [Algebra ℚ R] (n : ℕ) :
    gegenbauer (1 : R) n = Chebyshev.U R n := by
  let f : ℚ →ₐ[ℚ] R := Algebra.ofId ℚ R
  have h := congrArg (Polynomial.map f.toRingHom) (gegenbauer_one_eq_U_rat n)
  simpa only [map_gegenbauer, map_one, Chebyshev.map_U] using h
source
Reference details: Chebyshev representations in \(1/x^2\)

For real or complex \(x\ne 0\) and \(n\in \mathbb {N}\),

\[ U_n(x)=(2x)^n\, {}_2F_1\! \left(-\tfrac n2,\tfrac {1-n}2;-n;\frac1{x^2}\right), \]

and for \(n\ge 1\),

\[ T_n(x)=2^{n-1}x^n\, {}_2F_1\! \left(-\tfrac n2,\tfrac {1-n}2;1-n;\frac1{x^2}\right), \]

where \({}_2F_1\) is the Gauss series of Definition 1.2.6.

Reference: [DLMF, 18.5.11_1 and 18.5.11_3].

Lean Formalisation
theorem Polynomial.eval_chebyshev_U_eq_ordinaryHypergeometric_inv_sq.{u_1} {𝕂 : Type u_1} [RCLike 𝕂] (x : 𝕂ˣ) (n : ℕ) :
  Polynomial.eval (↑x) (Polynomial.Chebyshev.U 𝕂 ↑n) =
    (2 * ↑x) ^ n *
      ordinaryHypergeometricOn (GaussParameters.quadratic n (-↑n) ⋯)
        (GaussSeriesPoint.ofTerminating (GaussParameters.quadratic n (-↑n) ⋯) (n / 2) ⋯ (↑x ^ 2)⁻¹)
Lean proof
/-- Chebyshev U's classical inverse-square representation, including degree zero. -/
theorem eval_chebyshev_U_eq_ordinaryHypergeometric_inv_sq (x : 𝕂ˣ) (n : ℕ) :
    (Chebyshev.U 𝕂 n).eval x.val =
      (2 * x.val) ^ n * ordinaryHypergeometricOn
        (GaussParameters.quadratic n (-(n : 𝕂))
          (GaussParameters.pochhammer_neg_nat_ne_zero n (n / 2) (Nat.div_le_self _ _)))
        (.ofTerminating _ (n / 2) (GaussParameters.quadratic_has_termination n _ _) (x.val ^ 2)⁻¹) := by
  have hc : (ascPochhammer 𝕂 (n / 2)).eval (1 - 1 - (n : 𝕂)) ≠ 0 := by
    rw [sub_self, zero_sub, ascPochhammer_eval_neg_eq_descPochhammer,
      descPochhammer_eval_eq_descFactorial]
    refine mul_ne_zero (pow_ne_zero _ (by norm_num)) (Nat.cast_ne_zero.mpr ?_)
    rw [Ne, Nat.descFactorial_eq_zero_iff_lt]
    omega
  have hnf : (n.factorial : 𝕂) ≠ 0 := Nat.cast_ne_zero.mpr (Nat.factorial_ne_zero n)
  rw [← gegenbauer_one_eq_chebyshev_U, eval_gegenbauer_eq_ordinaryHypergeometric_inv_sq 1 x n hc,
    ascPochhammer_eval_one, div_self hnf, mul_one]
  rw [ordinaryHypergeometricOn_terminating, ordinaryHypergeometricOn_terminating]
  simp only [ordinaryHypergeometricCoefficientOn,
    GaussParameters.quadratic, GaussParameters.ofTerminating, sub_self, zero_sub]
  congr 1
  apply Finset.sum_congr rfl
  intro k hk
  by_cases h : (ascPochhammer 𝕂 k).eval (-(n : 𝕂) / 2) *
      (ascPochhammer 𝕂 k).eval ((1 - (n : 𝕂)) / 2) = 0
  · simp only [h, ite_true]
  · simp only [h, ite_false]
source

Over a field with a rational algebra structure, take a target polynomial basis \(c_i=C_i^{(1)}\). With rows indexing output coefficients and columns input coefficients, conversion \(S\) from \(T\) has columns

\[ S_{i0}=\delta _{i0},\qquad S_{i1}=\tfrac 12\delta _{i1},\qquad S_{i,n+2}=\tfrac 12(\delta _{i,n+2}-\delta _{in}). \]

Thus its bandwidths are \((0,2)\). The constant column is not halved. The result is also instantiated on the concrete real polynomial bases.

Reference: [OT13, equation (2.8)].

Lean Formalisation
theorem Polynomial.chebyshev_gegenbauer_conversion_zero.{u_1} {K : Type u_1} [Field K] [Algebra ℚ K]
  (b : Module.Basis ℕ K (Polynomial K)) (hb : ∀ (j : ℕ), b j = Polynomial.gegenbauer 1 j) (i : ℕ) :
  b.toMatrix (fun j => Polynomial.Chebyshev.T K ↑j) i 0 = if i = 0 then 1 else 0
Lean proof
/-- Conversion leaves the constant column unchanged (Olver--Townsend, 2.8). -/
theorem chebyshev_gegenbauer_conversion_zero
    (hb : ∀ j, b j = gegenbauer (1 : K) j) (i : ℕ) :
    b.toMatrix (fun j : ℕ ↦ Chebyshev.T K j) i 0 = if i = 0 then 1 else 0 := by
  have hb0 : b 0 = 1 := by rw [hb, gegenbauer_zero]
  simp [Basis.toMatrix_apply, Chebyshev.T_zero, ← hb0, Finsupp.single_apply, eq_comm]
source

For \(k\ge 0\), differentiation of order \(k+1\) from \(T\) into a target basis \(C^{(k+1)}\) has entries

\[ (D_{k+1})_{i,n+k+1}=2^k k!(n+k+1)\delta _{in}, \]

with columns below \(k+1\) zero. Its bandwidths are \((0,k+1)\). These identities hold over a field with a rational algebra structure and are instantiated on the real polynomial bases.

Reference: [OT13, Section 3].

Lean Formalisation
theorem Polynomial.chebyshev_iterate_derivative_matrix.{u_1} {K : Type u_1} [Field K] [Algebra ℚ K]
  (b : Module.Basis ℕ K (Polynomial K)) (k : ℕ) (hb : ∀ (j : ℕ), b j = Polynomial.gegenbauer (↑k + 1) j) (n i : ℕ) :
  b.toMatrix (fun j => (⇑Polynomial.derivative)^[k + 1] (Polynomial.Chebyshev.T K ↑j)) i (n + k + 1) =
    if i = n then 2 ^ k * ↑k.factorial * (↑n + ↑k + 1) else 0
Lean proof
/-- A nonzero column of the `(k+1)`st derivative has one ultraspherical entry
(Olver--Townsend, Section 3). -/
theorem chebyshev_iterate_derivative_matrix (k : ℕ)
    (hb : ∀ j, b j = gegenbauer (k + 1 : K) j) (n i : ℕ) :
    b.toMatrix (fun j : ℕ ↦ derivative^[k + 1] (Chebyshev.T K j)) i (n + k + 1) =
      if i = n then (2 : K) ^ k * k.factorial * (n + k + 1) else 0 := by
  rw [Basis.toMatrix_apply, iterate_derivative_chebyshev_T,
    ← smul_eq_C_mul, ← hb]
  simp [Finsupp.single_apply, eq_comm]
source

Write \(p=\sum _m a_mT_m\) with a full constant coefficient, and let \(M\) represent multiplication by \(p\) in the \(T\) basis. Then

\[ M_{i0}=a_i,\qquad M_{0j}=\tfrac 12a_j\quad (j{\gt}0),\qquad M_{ij}=\frac{(1+\delta _{ij})a_{|i-j|}+a_{i+j}}2\quad (i,j{\gt}0). \]

In particular the positive diagonal is \(a_0+a_{2i}/2\). These are the Toeplitz-plus-Hankel entries with the exceptional row, column and constant coefficient accounted for.

References: [OT13, Section 2.2, equation (2.7)]; [DLMF, 18.18.21].

Lean Formalisation
theorem Polynomial.two_mul_chebyshevBasis_repr_mul (m j i : ℕ) :
  2 * (Polynomial.chebyshevBasis.repr (Polynomial.chebyshevBasis m * Polynomial.chebyshevBasis j)) i =
    (if i = m + j then 1 else 0) + if i = (↑m - ↑j).natAbs then 1 else 0
Lean proof
/-- Coordinates of a product of two Chebyshev modes, with the factor two cleared. -/
theorem two_mul_chebyshevBasis_repr_mul (m j i : ℕ) :
    2 * chebyshevBasis.repr (chebyshevBasis m * chebyshevBasis j) i =
      (if i = m + j then 1 else 0) +
        (if i = ((m : ℤ) - j).natAbs then 1 else 0) := by
  have h := congrArg (fun p : ℝ[X] ↦ chebyshevBasis.repr p i) (Chebyshev.T_mul_T ℝ m j)
  rw [mul_assoc, ← C_ofNat 2, ← smul_eq_C_mul] at h
  have ha : Chebyshev.T ℝ ((m : ℤ) + j) = chebyshevBasis (m + j) := by
    simp [chebyshevBasis_apply]
  have hs : Chebyshev.T ℝ ((m : ℤ) - j) = chebyshevBasis ((m : ℤ) - j).natAbs := by
    rw [chebyshevBasis_apply, Chebyshev.T_natAbs]
  rw [ha, hs, ← chebyshevBasis_apply m, ← chebyshevBasis_apply j] at h
  simpa only [map_smul, Finsupp.smul_apply, smul_eq_mul, map_add, Finsupp.add_apply,
    Basis.repr_self, Finsupp.single_apply, eq_comm] using h
source
Definition 4.2.21 Integer ultraspherical basis ladder
✓ 🤖

Let \(B_0\) be the Chebyshev coordinate basis and, for integers \(k\ge 1\), let \(B_k\) be the Gegenbauer basis with \(\lambda =k\).

Reference: [OT13, Section 3].

Lean Formalisation
def Polynomial.ultrasphericalBasis : ℕ → Module.Basis ℕ ℝ (Polynomial ℝ)
Lean definition
/-- Coordinate bases for the ultraspherical method: T at zero, C^(k) at k>0. -/
noncomputable def ultrasphericalBasis : ℕ → Basis ℕ ℝ ℝ[X]
  | 0 => chebyshevBasis
  | k + 1 => gegenbauerBasis
      (by linarith [Nat.cast_nonneg (α := ℝ) k] : -(1 / 2 : ℝ) < (k : ℝ) + 1)
      (by positivity : (k : ℝ) + 1 ≠ 0)
source
Reference details: Rungs of the ultraspherical ladder
Theorem 4.2.22 Rungs of the ultraspherical ladder
✓ 🤖

\(B_0\) is the Chebyshev coordinate basis, and for \(k,j\ge 0\) the \(j\)th vector of \(B_{k+1}\) is \(C_j^{(k+1)}\).

Lean Formalisation
theorem Polynomial.ultrasphericalBasis_zero : Polynomial.ultrasphericalBasis 0 = Polynomial.chebyshevBasis
Lean proof
@[simp] theorem ultrasphericalBasis_zero : ultrasphericalBasis 0 = chebyshevBasis := rfl
source

Conversion \(B_k\to B_{k+r}\) has bandwidths \((0,2r)\). Differentiation \(D^k\) from \(B_0\) to \(B_k\) has bandwidths \((0,k)\), including \(k=0\). Consequently, for \(0\le k\le N\), differentiation represented from \(B_0\) to \(B_N\) has bandwidths \((0,2N-k)\).

Reference: [OT13, Section 3].

Lean Formalisation
theorem Polynomial.ultrasphericalBasis_step_isBanded (k : ℕ) :
  ((Polynomial.ultrasphericalBasis (k + 1)).toMatrix ⇑(Polynomial.ultrasphericalBasis k)).IsBanded 0 2
Lean proof
/-- One step of the basis ladder has bandwidths (0,2), including the T entry. -/
theorem ultrasphericalBasis_step_isBanded (k : ℕ) :
    ((ultrasphericalBasis (k + 1)).toMatrix (ultrasphericalBasis k)).IsBanded 0 2 := by
  cases k with
  | zero =>
    simpa only [ultrasphericalBasis, Nat.cast_zero, zero_add] using
      chebyshevBasis_conversion_isBanded
  | succ k =>
    have he : (ultrasphericalBasis (k + 1) : ℕ → ℝ[X]) = gegenbauer (k + 1 : ℝ) := by
      funext j
      exact ultrasphericalBasis_succ_apply k j
    rw [he]
    apply gegenbauer_conversion_matrix_isBanded (k + 1 : ℝ)
    · intro j
      simp [ultrasphericalBasis, Nat.cast_add, Nat.cast_one]
    · intro n
      exact ne_of_gt (by positivity)
source

Use the existing real bases \(B_0=T\), \(B_k=C^{(k)}\) for \(k\ge 1\), evaluated at complex arguments. For \(k\le N\), conversion from \(B_k\) to \(B_N\) computes coordinate \(i\) from indices \(j{\lt}i+2(N-k)+1\). Under the weighted summability condition of matrix reconstruction, it preserves the represented function. In either direction, the weighted summability condition gives reconstruction by the contributions \(\gamma _i\) of Theorem 4.1.15. For reverse conversion, these may be factored into coefficients and modes when each coefficient row converges. Forward conversion has finite rows, so this additional row convergence is automatic.

Lean Formalisation
theorem Polynomial.ultraspherical_series_conversion_eq_sum {k N : ℕ} (hk : k ≤ N) (a : ℕ → ℂ) (i : ℕ) :
  (Polynomial.ultrasphericalBasis k).seriesCoefficientMap (Polynomial.ultrasphericalBasis N) LinearMap.id
      Complex.ofRealHom
      (Module.Basis.SeriesCoefficientInput.ofBanded (Polynomial.ultrasphericalBasis k)
        (Polynomial.ultrasphericalBasis N) LinearMap.id Complex.ofRealHom a ⋯ i) =
    ∑ j ∈ Finset.range (i + 2 * (N - k) + 1),
      a j * ↑(((Polynomial.ultrasphericalBasis N).repr ((Polynomial.ultrasphericalBasis k) j)) i)
Lean proof
/-- Raising levels computes each certified output coefficient from a finite window. -/
theorem ultraspherical_series_conversion_eq_sum {k N : ℕ} (hk : k ≤ N)
    (a : ℕ → ℂ) (i : ℕ) :
    (ultrasphericalBasis k).seriesCoefficientMap (ultrasphericalBasis N)
      LinearMap.id Complex.ofRealHom (.ofBanded _ _ _ _ a
        (ultrasphericalBasis_conversion_isBanded hk) i) =
      ∑ j ∈ Finset.range (i + 2 * (N - k) + 1),
        a j * ((ultrasphericalBasis N).repr (ultrasphericalBasis k j) i : ℂ) :=
  (ultrasphericalBasis k).seriesCoefficientMap_eq_sum_of_isBanded
    (ultrasphericalBasis N) LinearMap.id Complex.ofRealHom a
    (ultrasphericalBasis_conversion_isBanded hk) i
source

Banded classical operators: see Theorems 4.1.4, 4.2.1, 4.2.2, 4.2.3, 4.2.5 and 4.2.6.

A differential equation combines these maps. Each differentiated term first lands in its own basis; conversion brings the terms to a common target so that their coefficient matrices can be added.