Mathlib.Analysis

Analysis helpers staged for upstreaming: Bernoulli KL inequalities, functional-equation facts, scalar arithmetic, half-disc polar integration, and one-dimensional smooth descent bounds.

Approximation 176 core · 238 supporting · 1 submodule Chebyshev and Jackson approximation theory. Analytic 6 core · 9 supporting · 1 submodule Analytic parametric-integral results. Calculus 220 core · 223 supporting · 5 submodules Calculus — Mathlib-shaped helpers: HolderTaylor. Complex 23 core · 29 supporting · 2 submodules Complex-analytic tools for the argument principle and geometry near circles. Convex 2 core · 5 supporting · 2 submodules Convex-analysis helpers staged for upstreaming: reciprocal-product convexity and supporting inequalities for optimization arguments. Duality 21 core · 46 supporting · 1 submodule Moment-prior duality results. Fourier 27 core · 70 supporting · 9 submodules Two groups of results. Inner­Product­Space 21 core · 27 supporting · 5 submodules Projection, Gram-matrix, positive-definite square-root, reproducing-kernel, and Frisch–Waugh–Lovell results in inner-product spaces. Interval­Arithmetic 210 core · 164 supporting · 11 submodules Certified interval arithmetic for real and complex calculations, including elementary operations, finite-dimensional linear algebra, transcendental functions, quadrature, finite search, and contour integration. Normed 1 core · 3 supporting · 1 submodule Normed-space and normed-ring infrastructure for infinite sums and product-series estimates. Normed­Space 21 core · 28 supporting · 3 submodules Finite nets, inverse perturbation bounds, and normed-space duality. Quantization 22 core · 32 supporting · 13 submodules Paired weighted scalar L1 quantization on a compact real interval. Real­Interpolation 17 core · 18 supporting · 11 submodules For a pair of Banach spaces continuously embedded in a common vector space, the quadratic K-functional K(t, v)² is the infimum of ‖v₀‖₀² + t²·‖v₁‖₁² over decompositions v = v₀ + v₁, and the interpolation norm of exponent Special­Functions 17 core · 25 supporting · 3 submodules SpecialFunctions — Mathlib-shaped helpers for real-power convergence, power integrals, and Jacobi polynomials. Specific­Limits 1 core · 3 supporting · 1 submodule Explicit bounds for polynomially weighted geometric series and related quantitative limit estimates.
Matrix­Euclidean 4 core · 0 supporting This module fixes the Euclidean matrix carrier and its spectral operator norm.

Common finite-dimensional notation for collision-safe spectral laws

This module fixes the Euclidean matrix carrier and its spectral operator norm. The remaining modules use these definitions for rectangular Moore--Penrose inverses, nonnormal functional calculus, and finite atomic laws.

abbrev Euc reviewed
Causalean.Mathlib.Analysis

Euc n is real Euclidean n-space with its two-norm.

Definition (Lean source)
n :
ℕ
Euc n :
Type
abbrev RectMatrix reviewed
Causalean.Mathlib.Analysis

RectMatrix rows cols is the type of real rows-by-cols matrices.

Definition (Lean source)
rows cols :
ℕ
RectMatrix rows cols :
Type
Matrix (Fin rows) (Fin cols) ℝ
Causalean.Mathlib.Analysis.RectMatrix · Causalean/Mathlib/Analysis/MatrixEuclidean.lean:24
def matrixCLM reviewed
Causalean.Mathlib.Analysis

A real rectangular matrix regarded as a continuous linear map between Euclidean spaces.

Definition (Lean source)
rows cols :
ℕ
A :
RectMatrix rows cols
matrixCLM A :
Euc cols →L[ℝ] Euc rows
Causalean.Mathlib.Analysis.matrixCLM · Causalean/Mathlib/Analysis/MatrixEuclidean.lean:27 · uses Euc , RectMatrix
def singularValue reviewed
Causalean.Mathlib.Analysis

The zero-based singular value of a real rectangular matrix, in decreasing order.

Definition (Lean source)
rows cols :
ℕ
A :
RectMatrix rows cols
j :
ℕ
singularValue A j :
ℝ
Causalean.Mathlib.Analysis.singularValue · Causalean/Mathlib/Analysis/MatrixEuclidean.lean:32 · uses RectMatrix
Diagonalizable­Functional­Calculus 9 core · 13 supporting This module treats separately diagonalized real matrices, including nonnormal matrices and arbitrary eigenvalue multiplicities. ★ norm_applyFunction_sub_le_dim_sq

Collision-safe two-diagonalizer functional calculus

This module treats separately diagonalized real matrices, including nonnormal matrices and arbitrary eigenvalue multiplicities. Equal eigenvalues are aggregated into canonical spectral projectors. The cross-projector identity makes common-eigenvalue summands vanish before any divided difference is formed, yielding a gap-free two-diagonalizer bound.

structure RealDiagonalization reviewed
Causalean.Mathlib.Analysis

A real diagonalization certificate A = S diag(α) S⁻¹, carrying both inverse identities.

Definition (Lean source)
n :
ℕ
A :
basis :
basisInv :
eigenvalue :
Fin n → ℝ
basis_mul_inv :
basis * basisInv = 1
inv_mul_basis :
basisInv * basis = 1
reconstruct :
A = basis * diagonal eigenvalue * basisInv
Causalean.Mathlib.Analysis.RealDiagonalization · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:19 · uses RectMatrix
def spectralValues reviewed
Causalean.Mathlib.Analysis.RealDiagonalization

The finite set of distinct real eigenvalues in a diagonalization certificate.

Definition (Lean source)
n :
ℕ
spectralValues D :
Finset ℝ
Finset.univ.image D.eigenvalue
Causalean.Mathlib.Analysis.RealDiagonalization.spectralValues · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:28 · uses RealDiagonalization , RectMatrix
def specCount reviewed
Causalean.Mathlib.Analysis.RealDiagonalization

The number of distinct real eigenvalues in a diagonalization certificate.

Definition (Lean source)
n :
ℕ
specCount D :
ℕ
D.spectralValues.card
Causalean.Mathlib.Analysis.RealDiagonalization.specCount · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:33 · uses RealDiagonalization , RectMatrix
def conditionNumber reviewed
Causalean.Mathlib.Analysis.RealDiagonalization

The condition number certificate ‖S‖ ‖S⁻¹‖ of a chosen diagonalizer.

Definition (Lean source)
n :
ℕ
conditionNumber D :
ℝ
‖D.basis‖ * ‖D.basisInv‖
Causalean.Mathlib.Analysis.RealDiagonalization.conditionNumber · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:38 · uses RealDiagonalization , RectMatrix
def projector reviewed
Causalean.Mathlib.Analysis.RealDiagonalization

The aggregate spectral projector at a value, summing every diagonal coordinate whose eigenvalue equals that value.

Definition (Lean source)
n :
ℕ
x :
ℝ
projector D x :
D.basis * diagonal (fun i => if D.eigenvalue i = x then 1 else 0) * D.basisInv
Causalean.Mathlib.Analysis.RealDiagonalization.projector · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:43 · uses RealDiagonalization , RectMatrix
def applyFunction reviewed
Causalean.Mathlib.Analysis.RealDiagonalization

Applying a scalar function through a real diagonalization certificate.

Definition (Lean source)
n :
ℕ
f :
ℝ → ℝ
applyFunction D f :
D.basis * diagonal (f ∘ D.eigenvalue) * D.basisInv
Causalean.Mathlib.Analysis.RealDiagonalization.applyFunction · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:49 · uses RealDiagonalization , RectMatrix
theorem norm_applyFunction_sub_le_dim_sq reviewed
Causalean.Mathlib.Analysis

For two real n × n matrices A and B with chosen real diagonalizations, a one-Lipschitz scalar function f, and numbers κA and κB bounding the two diagonalizer condition numbers, the operator-norm distance between f applied to A and f applied to B is at most n²·κA·κB times the operator norm of A − B. No gap between the eigenvalues of A and those of B is assumed: eigenvalues shared by the two matrices are allowed.

Formal statement
n :
ℕ
f :
ℝ → ℝ
hf :
κA κB :
ℝ
hκA :
DA.conditionNumber ≤ κA
hκB :
DB.conditionNumber ≤ κB
‖DA.applyFunction f - DB.applyFunction f‖ ≤ (n : ℝ) ^ 2 * κA * κB * ‖A - B‖
Proof (Lean source)
theorem norm_applyFunction_sub_le_dim_sq {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) (f : ℝ → ℝ) (hf : LipschitzWith 1 f) {κA κB : ℝ} (hκA : DA.conditionNumber ≤ κA) (hκB : DB.conditionNumber ≤ κB) : ‖DA.applyFunction f - DB.applyFunction f‖ ≤ (n : ℝ) ^ 2 * κA * κB * ‖A - B‖ := by have hcountA : (DA.specCount : ℝ) ≤ n := by unfold RealDiagonalization.specCount RealDiagonalization.spectralValues exact_mod_cast (show (Finset.univ.image DA.eigenvalue).card ≤ n by simpa using (Finset.card_image_le (s := (Finset.univ : Finset (Fin n))) (f := DA.eigenvalue))) have hcountB : (DB.specCount : ℝ) ≤ n := by unfold RealDiagonalization.specCount RealDiagonalization.spectralValues exact_mod_cast (show (Finset.univ.image DB.eigenvalue).card ≤ n by simpa using (Finset.card_image_le (s := (Finset.univ : Finset (Fin n))) (f := DB.eigenvalue))) have hκA0 : 0 ≤ κA := le_trans (mul_nonneg (norm_nonneg DA.basis) (norm_nonneg DA.basisInv)) hκA have hκB0 : 0 ≤ κB := le_trans (mul_nonneg (norm_nonneg DB.basis) (norm_nonneg DB.basisInv)) hκB calc ‖DA.applyFunction f - DB.applyFunction f‖ ≤ (DA.specCount : ℝ) * (DB.specCount : ℝ) * κA * κB * ‖A - B‖ := norm_applyFunction_sub_le DA DB f hf hκA hκB _ ≤ (n : ℝ) * (n : ℝ) * κA * κB * ‖A - B‖ := by gcongr _ = (n : ℝ) ^ 2 * κA * κB * ‖A - B‖ := by ring
def SpectrumBound reviewed
Causalean.Mathlib.Analysis.RealDiagonalization

A diagonalization has spectrum bounded by R when all listed real eigenvalues have absolute value at most R.

Definition (Lean source)
n :
ℕ
R :
ℝ
i :
SpectrumBound D R :
Prop
|D.eigenvalue i| ≤ R
Causalean.Mathlib.Analysis.RealDiagonalization.SpectrumBound · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:445 · uses RealDiagonalization , RectMatrix
def anchorEval reviewed
Causalean.Mathlib.Analysis

The left-right evaluation of a matrix between two Euclidean anchor vectors.

Definition (Lean source)
n :
ℕ
a c :
Euc n
M :
anchorEval a c M :
ℝ
inner ℝ a (matrixCLM M c)
13 supporting declarations (lemmas, instances)
  • projector_independent theorem — Aggregate projectors are independent of the eigenbasis and of coordinate choices within repeated eigenspaces.
    n :
    ℕ
    x :
    ℝ
    D.projector x = D'.projector x
    Proof (Lean source)
    theorem projector_independent {n : ℕ} {A : RectMatrix n n} (D D' : RealDiagonalization A) (x : ℝ) : D.projector x = D'.projector x := by simpa [RealDiagonalization.projector, RealDiagonalization.applyFunction, Function.comp_def] using applyFunction_independent_aux D D' (fun z => if z = x then 1 else 0)
    Causalean.Mathlib.Analysis.projector_independent · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:112
  • applyFunction_independent theorem — Finite functional calculus is independent of the chosen real diagonalization certificate.
    n :
    ℕ
    f :
    ℝ → ℝ
    D.applyFunction f = D'.applyFunction f
    Proof (Lean source)
    theorem applyFunction_independent {n : ℕ} {A : RectMatrix n n} (D D' : RealDiagonalization A) (f : ℝ → ℝ) : D.applyFunction f = D'.applyFunction f := by exact applyFunction_independent_aux D D' f
    Causalean.Mathlib.Analysis.applyFunction_independent · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:121
  • sum_projector_eq_one theorem — The aggregate spectral projectors sum to the identity.
    n :
    ℕ
    ∑ x ∈ D.spectralValues, D.projector x = 1
    Proof (Lean source)
    theorem sum_projector_eq_one {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) : ∑ x ∈ D.spectralValues, D.projector x = 1 := by unfold RealDiagonalization.projector RealDiagonalization.spectralValues rw [← Finset.sum_mul, ← Matrix.mul_sum] have hdiag : (∑ x ∈ Finset.univ.image D.eigenvalue, diagonal (fun i => if D.eigenvalue i = x then 1 else 0)) = (1 : RectMatrix n n) := by funext i j rw [Matrix.sum_apply] simp only [Matrix.diagonal_apply, Matrix.one_apply] by_cases hij : i = j · subst j simp · simp [hij] change D.basis * (∑ x ∈ Finset.univ.image D.eigenvalue, diagonal (fun i => if D.eigenvalue i = x then 1 else 0)) * D.basisInv = 1 rw [hdiag, Matrix.mul_one] exact D.basis_mul_inv
    Causalean.Mathlib.Analysis.sum_projector_eq_one · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:127
  • applyFunction_eq_sum_projector theorem — Functional calculus is the sum of the scalar values times aggregate spectral projectors.
    n :
    ℕ
    f :
    ℝ → ℝ
    D.applyFunction f = ∑ x ∈ D.spectralValues, f x • D.projector x
    Proof (Lean source)
    theorem applyFunction_eq_sum_projector {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) (f : ℝ → ℝ) : D.applyFunction f = ∑ x ∈ D.spectralValues, f x • D.projector x := by unfold RealDiagonalization.applyFunction RealDiagonalization.projector have hdiag : diagonal (f ∘ D.eigenvalue) = ∑ x ∈ D.spectralValues, f x • diagonal (fun i => if D.eigenvalue i = x then 1 else 0) := by funext i j rw [Matrix.sum_apply] simp only [Matrix.diagonal_apply] by_cases hij : i = j · subst j simp [RealDiagonalization.spectralValues, Function.comp_apply] · simp [hij] rw [hdiag] simp [Finset.mul_sum, Finset.sum_mul]
    Causalean.Mathlib.Analysis.applyFunction_eq_sum_projector · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:148
  • projector_mul_operator theorem — An aggregate projector extracts its own eigenvalue on either side of its operator.
    n :
    ℕ
    x :
    ℝ
    hx :
    x ∈ D.spectralValues
    conclusion 1
    D.projector x * A = x • D.projector x
    conclusion 2
    A * D.projector x = x • D.projector x
    Proof (Lean source)
    theorem projector_mul_operator {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) {x : ℝ} (hx : x ∈ D.spectralValues) : D.projector x * A = x • D.projector x ∧ A * D.projector x = x • D.projector x := by have _ := hx let E : RectMatrix n n := Matrix.diagonal (fun i => if D.eigenvalue i = x then (1 : ℝ) else 0) let L : RectMatrix n n := Matrix.diagonal D.eigenvalue have hEL : E * L = x • E := by funext i j by_cases hij : i = j · subst j by_cases hix : D.eigenvalue i = x <;> simp [E, L, hix] · simp [E, L, hij] have hLE : L * E = x • E := by funext i j by_cases hij : i = j · subst j by_cases hix : D.eigenvalue i = x <;> simp [E, L, hix] · simp [E, L, hij] constructor · calc D.projector x * A = D.projector x * (D.basis * L * D.basisInv) := by exact congrArg (fun M => D.projector x * M) D.reconstruct _ = (D.basis * E * D.basisInv) * (D.basis * L * D.basisInv) := by rfl _ = D.basis * (E * L) * D.basisInv := by rw [Matrix.mul_assoc (D.basis * E) D.basisInv, Matrix.mul_assoc D.basis L, ← Matrix.mul_assoc D.basisInv D.basis, D.inv_mul_basis, Matrix.one_mul] simp only [Matrix.mul_assoc] _ = D.basis * (x • E) * D.basisInv := by rw [hEL] _ = x • (D.basis * E * D.basisInv) := by simp _ = x • D.projector x := by rfl · calc A * D.projector x = (D.basis * L * D.basisInv) * D.projector x := by exact congrArg (fun M => M * D.projector x) D.reconstruct _ = (D.basis * L * D.basisInv) * (D.basis * E * D.basisInv) := by rfl _ = D.basis * (L * E) * D.basisInv := by rw [Matrix.mul_assoc (D.basis * L) D.basisInv, Matrix.mul_assoc D.basis E, ← Matrix.mul_assoc D.basisInv D.basis, D.inv_mul_basis, Matrix.one_mul] simp only [Matrix.mul_assoc] _ = D.basis * (x • E) * D.basisInv := by rw [hLE] _ = x • (D.basis * E * D.basisInv) := by simp _ = x • D.projector x := by rfl
    Causalean.Mathlib.Analysis.projector_mul_operator · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:166
  • crossProjector_sub theorem — Cross-projecting two separately diagonalized operators gives E_λ (A-B) F_γ = (λ-γ) E_λ F_γ.
    n :
    ℕ
    x y :
    ℝ
    hx :
    x ∈ DA.spectralValues
    hy :
    y ∈ DB.spectralValues
    DA.projector x * (A - B) * DB.projector y = (x - y) • (DA.projector x * DB.projector y)
    Proof (Lean source)
    theorem crossProjector_sub {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) {x y : ℝ} (hx : x ∈ DA.spectralValues) (hy : y ∈ DB.spectralValues) : DA.projector x * (A - B) * DB.projector y = (x - y) • (DA.projector x * DB.projector y) := by have hAx := (projector_mul_operator DA hx).1 have hBy := (projector_mul_operator DB hy).2 calc DA.projector x * (A - B) * DB.projector y = (DA.projector x * A) * DB.projector y - DA.projector x * (B * DB.projector y) := by simp only [Matrix.mul_sub, Matrix.sub_mul, Matrix.mul_assoc] _ = (x • DA.projector x) * DB.projector y - DA.projector x * (y • DB.projector y) := by rw [hAx, hBy] _ = (x - y) • (DA.projector x * DB.projector y) := by simp [sub_smul]
    Causalean.Mathlib.Analysis.crossProjector_sub · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:218
  • crossProjector_common_eigenvalue_vanish theorem — At a common eigenvalue the cross-projected perturbation vanishes, so the corresponding divided-difference summand is zero without division by λ-γ.
    n :
    ℕ
    x :
    ℝ
    hAx :
    x ∈ DA.spectralValues
    hBx :
    x ∈ DB.spectralValues
    DA.projector x * (A - B) * DB.projector x = 0
    Proof (Lean source)
    theorem crossProjector_common_eigenvalue_vanish {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) {x : ℝ} (hAx : x ∈ DA.spectralValues) (hBx : x ∈ DB.spectralValues) : DA.projector x * (A - B) * DB.projector x = 0 := by rw [crossProjector_sub DA DB hAx hBx, sub_self, zero_smul]
    Causalean.Mathlib.Analysis.crossProjector_common_eigenvalue_vanish · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:237
  • applyFunction_sub_eq_dividedDifference theorem — Collision-safe divided-difference expansion for two unrelated diagonalizers. Equal-node summands are explicitly zero and therefore never divide by zero.
    n :
    ℕ
    f :
    ℝ → ℝ
    DA.applyFunction f - DB.applyFunction f
    = ∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, if x = y then 0 else ((f x - f y) / (x - y)) • (DA.projector x * (A - B) * DB.projector y)
    Proof (Lean source)
    theorem applyFunction_sub_eq_dividedDifference {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) (f : ℝ → ℝ) : DA.applyFunction f - DB.applyFunction f = ∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, if x = y then 0 else ((f x - f y) / (x - y)) • (DA.projector x * (A - B) * DB.projector y) := by have hsummand (x : ℝ) (hx : x ∈ DA.spectralValues) (y : ℝ) (hy : y ∈ DB.spectralValues) : (if x = y then 0 else ((f x - f y) / (x - y)) • (DA.projector x * (A - B) * DB.projector y)) = (f x - f y) • (DA.projector x * DB.projector y) := by by_cases hxy : x = y · subst y simp · rw [if_neg hxy, crossProjector_sub DA DB hx hy, smul_smul] congr 1 field_simp [sub_ne_zero.mpr hxy] rw [applyFunction_eq_sum_projector DA f, applyFunction_eq_sum_projector DB f] have hfirst : (∑ x ∈ DA.spectralValues, f x • DA.projector x) * (∑ y ∈ DB.spectralValues, DB.projector y) = ∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, f x • (DA.projector x * DB.projector y) := by rw [Finset.sum_mul] apply Finset.sum_congr rfl intro x hx rw [Matrix.mul_sum] apply Finset.sum_congr rfl intro y hy simp have hsecond : (∑ x ∈ DA.spectralValues, DA.projector x) * (∑ y ∈ DB.spectralValues, f y • DB.projector y) = ∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, f y • (DA.projector x * DB.projector y) := by rw [Finset.sum_mul] apply Finset.sum_congr rfl intro x hx rw [Matrix.mul_sum] apply Finset.sum_congr rfl intro y hy simp calc (∑ x ∈ DA.spectralValues, f x • DA.projector x) - ∑ y ∈ DB.spectralValues, f y • DB.projector y = (∑ x ∈ DA.spectralValues, f x • DA.projector x) * (∑ y ∈ DB.spectralValues, DB.projector y) - (∑ x ∈ DA.spectralValues, DA.projector x) * (∑ y ∈ DB.spectralValues, f y • DB.projector y) := by rw [sum_projector_eq_one DA, sum_projector_eq_one DB, Matrix.mul_one, Matrix.one_mul] _ = ∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, (f x - f y) • (DA.projector x * DB.projector y) := by rw [hfirst, hsecond] simp [← Finset.sum_sub_distrib, sub_smul] _ = ∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, if x = y then 0 else ((f x - f y) / (x - y)) • (DA.projector x * (A - B) * DB.projector y) := by apply Finset.sum_congr rfl intro x hx apply Finset.sum_congr rfl intro y hy exact (hsummand x hx y hy).symm
    Causalean.Mathlib.Analysis.applyFunction_sub_eq_dividedDifference · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:245
  • norm_projector_le_conditionNumber theorem — Every aggregate projector has norm at most the condition number of its diagonalizer.
    n :
    ℕ
    x :
    ℝ
    ‖D.projector x‖ ≤ D.conditionNumber
    Proof (Lean source)
    theorem norm_projector_le_conditionNumber {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) (x : ℝ) : ‖D.projector x‖ ≤ D.conditionNumber := by let E : RectMatrix n n := diagonal (fun i => if D.eigenvalue i = x then (1 : ℝ) else 0) have hE : ‖E‖ ≤ 1 := by rw [show E = diagonal (fun i => if D.eigenvalue i = x then (1 : ℝ) else 0) from rfl, Matrix.l2_opNorm_diagonal, pi_norm_le_iff_of_nonneg (by norm_num)] intro i split <;> simp unfold RealDiagonalization.projector RealDiagonalization.conditionNumber calc ‖D.basis * diagonal (fun i => if D.eigenvalue i = x then 1 else 0) * D.basisInv‖ ≤ ‖D.basis * diagonal (fun i => if D.eigenvalue i = x then 1 else 0)‖ * ‖D.basisInv‖ := Matrix.l2_opNorm_mul _ _ _ ≤ (‖D.basis‖ * ‖Matrix.diagonal (fun i => if D.eigenvalue i = x then (1 : ℝ) else 0)‖) * ‖D.basisInv‖ := by gcongr exact Matrix.l2_opNorm_mul D.basis (diagonal (fun i => if D.eigenvalue i = x then (1 : ℝ) else 0)) _ ≤ (‖D.basis‖ * 1) * ‖D.basisInv‖ := by gcongr _ = ‖D.basis‖ * ‖D.basisInv‖ := by ring
    Causalean.Mathlib.Analysis.norm_projector_le_conditionNumber · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:315
  • norm_applyFunction_sub_le theorem — A one-Lipschitz scalar function obeys the two-diagonalizer, collision-free perturbation bound with the product of the numbers of distinct eigenvalues.
    n :
    ℕ
    f :
    ℝ → ℝ
    hf :
    κA κB :
    ℝ
    hκA :
    DA.conditionNumber ≤ κA
    hκB :
    DB.conditionNumber ≤ κB
    ‖DA.applyFunction f - DB.applyFunction f‖
    ≤ (DA.specCount : ℝ) * (DB.specCount : ℝ) * κA * κB * ‖A - B‖
    Proof (Lean source)
    theorem norm_applyFunction_sub_le {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) (f : ℝ → ℝ) (hf : LipschitzWith 1 f) {κA κB : ℝ} (hκA : DA.conditionNumber ≤ κA) (hκB : DB.conditionNumber ≤ κB) : ‖DA.applyFunction f - DB.applyFunction f‖ ≤ (DA.specCount : ℝ) * (DB.specCount : ℝ) * κA * κB * ‖A - B‖ := by have hκA0 : 0 ≤ κA := le_trans (mul_nonneg (norm_nonneg DA.basis) (norm_nonneg DA.basisInv)) hκA have hκB0 : 0 ≤ κB := le_trans (mul_nonneg (norm_nonneg DB.basis) (norm_nonneg DB.basisInv)) hκB have hsummand (x : ℝ) (hx : x ∈ DA.spectralValues) (y : ℝ) (hy : y ∈ DB.spectralValues) : ‖if x = y then 0 else ((f x - f y) / (x - y)) • (DA.projector x * (A - B) * DB.projector y)‖ ≤ κA * κB * ‖A - B‖ := by by_cases hxy : x = y · rw [if_pos hxy, norm_zero] positivity · rw [if_neg hxy, norm_smul] have hcoef : ‖(f x - f y) / (x - y)‖ ≤ 1 := by rw [norm_div] apply (div_le_one (norm_pos_iff.mpr (sub_ne_zero.mpr hxy))).2 simpa using hf.norm_sub_le x y have htriple : ‖DA.projector x * (A - B) * DB.projector y‖ ≤ κA * κB * ‖A - B‖ := by calc ‖DA.projector x * (A - B) * DB.projector y‖ ≤ ‖DA.projector x * (A - B)‖ * ‖DB.projector y‖ := Matrix.l2_opNorm_mul _ _ _ ≤ (‖DA.projector x‖ * ‖A - B‖) * ‖DB.projector y‖ := by gcongr exact Matrix.l2_opNorm_mul _ _ _ ≤ (κA * ‖A - B‖) * κB := by gcongr · exact le_trans (norm_projector_le_conditionNumber DA x) hκA · exact le_trans (norm_projector_le_conditionNumber DB y) hκB _ = κA * κB * ‖A - B‖ := by ring calc ‖(f x - f y) / (x - y)‖ * ‖DA.projector x * (A - B) * DB.projector y‖ ≤ 1 * (κA * κB * ‖A - B‖) := by gcongr _ = κA * κB * ‖A - B‖ := one_mul _ rw [applyFunction_sub_eq_dividedDifference DA DB f] calc ‖∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, if x = y then 0 else ((f x - f y) / (x - y)) • (DA.projector x * (A - B) * DB.projector y)‖ ≤ ∑ x ∈ DA.spectralValues, ‖∑ y ∈ DB.spectralValues, if x = y then 0 else ((f x - f y) / (x - y)) • (DA.projector x * (A - B) * DB.projector y)‖ := norm_sum_le _ _ _ ≤ ∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, ‖if x = y then 0 else ((f x - f y) / (x - y)) • (DA.projector x * (A - B) * DB.projector y)‖ := by apply Finset.sum_le_sum intro x hx exact norm_sum_le _ _ _ ≤ ∑ x ∈ DA.spectralValues, ∑ y ∈ DB.spectralValues, κA * κB * ‖A - B‖ := by apply Finset.sum_le_sum intro x hx apply Finset.sum_le_sum intro y hy exact hsummand x hx y hy _ = (DA.specCount : ℝ) * (DB.specCount : ℝ) * κA * κB * ‖A - B‖ := by simp [RealDiagonalization.specCount] ring
    Causalean.Mathlib.Analysis.norm_applyFunction_sub_le · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:343
  • norm_applyFunction_le theorem — If f(0)=0, f is one-Lipschitz, and the spectrum lies in [-R,R], then functional calculus has norm at most the diagonalizer condition number times R.
    n :
    ℕ
    f :
    ℝ → ℝ
    hf :
    hf0 :
    f 0 = 0
    κ R :
    ℝ
    hκ :
    D.conditionNumber ≤ κ
    hR0 :
    0 ≤ R
    hR :
    D.SpectrumBound R
    ‖D.applyFunction f‖ ≤ κ * R
    Proof (Lean source)
    theorem norm_applyFunction_le {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) (f : ℝ → ℝ) (hf : LipschitzWith 1 f) (hf0 : f 0 = 0) {κ R : ℝ} (hκ : D.conditionNumber ≤ κ) (hR0 : 0 ≤ R) (hR : D.SpectrumBound R) : ‖D.applyFunction f‖ ≤ κ * R := by have hdiag : ‖Matrix.diagonal (f ∘ D.eigenvalue)‖ ≤ R := by rw [Matrix.l2_opNorm_diagonal, pi_norm_le_iff_of_nonneg hR0] intro i calc ‖(f ∘ D.eigenvalue) i‖ = ‖f (D.eigenvalue i) - f 0‖ := by simp [hf0] _ ≤ ‖D.eigenvalue i - 0‖ := by simpa using hf.norm_sub_le (D.eigenvalue i) 0 _ = |D.eigenvalue i| := by simp [Real.norm_eq_abs] _ ≤ R := hR i unfold RealDiagonalization.applyFunction have hcond0 : 0 ≤ D.conditionNumber := mul_nonneg (norm_nonneg D.basis) (norm_nonneg D.basisInv) calc ‖D.basis * diagonal (f ∘ D.eigenvalue) * D.basisInv‖ ≤ ‖D.basis * diagonal (f ∘ D.eigenvalue)‖ * ‖D.basisInv‖ := Matrix.l2_opNorm_mul _ _ _ ≤ (‖D.basis‖ * ‖Matrix.diagonal (f ∘ D.eigenvalue)‖) * ‖D.basisInv‖ := by gcongr exact Matrix.l2_opNorm_mul _ _ _ ≤ (‖D.basis‖ * R) * ‖D.basisInv‖ := by gcongr _ = D.conditionNumber * R := by unfold RealDiagonalization.conditionNumber ring _ ≤ κ * R := mul_le_mul_of_nonneg_right hκ hR0
    Causalean.Mathlib.Analysis.norm_applyFunction_le · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:451
  • abs_anchorEval_le theorem — A left-right matrix evaluation is bounded by the two anchor norms and the operator norm.
    n :
    ℕ
    a c :
    Euc n
    M :
    |anchorEval a c M| ≤ ‖a‖ * ‖M‖ * ‖c‖
    Proof (Lean source)
    theorem abs_anchorEval_le {n : ℕ} (a c : Euc n) (M : RectMatrix n n) : |anchorEval a c M| ≤ ‖a‖ * ‖M‖ * ‖c‖ := by unfold anchorEval calc |inner ℝ a (matrixCLM M c)| ≤ ‖a‖ * ‖matrixCLM M c‖ := abs_real_inner_le_norm _ _ _ ≤ ‖a‖ * (‖matrixCLM M‖ * ‖c‖) := by gcongr exact (matrixCLM M).le_opNorm c _ = ‖a‖ * ‖M‖ * ‖c‖ := by rw [show matrixCLM M = Matrix.toEuclideanCLM (n := Fin n) (𝕜 := ℝ) M from rfl, Matrix.l2_opNorm_toEuclideanCLM] ring
    Causalean.Mathlib.Analysis.abs_anchorEval_le · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:489
  • abs_anchorEval_applyFunction_sub_le theorem — Normalized one-Lipschitz functional calculus is stable under simultaneous operator and left/right anchor perturbations, without eigenvalue matching or diagonalizer matching.
    n :
    ℕ
    a b c d :
    Euc n
    f :
    ℝ → ℝ
    hf :
    hf0 :
    f 0 = 0
    κA κB R :
    ℝ
    hκA :
    DA.conditionNumber ≤ κA
    hκB :
    DB.conditionNumber ≤ κB
    hR0 :
    0 ≤ R
    hRA :
    DA.SpectrumBound R
    hRB :
    DB.SpectrumBound R
    |anchorEval a c (DA.applyFunction f) - anchorEval b d (DB.applyFunction f)|
    ≤ ‖a - b‖ * (κA * R) * ‖c‖
    + ‖b‖ * ((n : ℝ) ^ 2 * κA * κB * ‖A - B‖) * ‖c‖
    + ‖b‖ * (κB * R) * ‖c - d‖
    Proof (Lean source)
    theorem abs_anchorEval_applyFunction_sub_le {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) (a b c d : Euc n) (f : ℝ → ℝ) (hf : LipschitzWith 1 f) (hf0 : f 0 = 0) {κA κB R : ℝ} (hκA : DA.conditionNumber ≤ κA) (hκB : DB.conditionNumber ≤ κB) (hR0 : 0 ≤ R) (hRA : DA.SpectrumBound R) (hRB : DB.SpectrumBound R) : |anchorEval a c (DA.applyFunction f) - anchorEval b d (DB.applyFunction f)| ≤ ‖a - b‖ * (κA * R) * ‖c‖ + ‖b‖ * ((n : ℝ) ^ 2 * κA * κB * ‖A - B‖) * ‖c‖ + ‖b‖ * (κB * R) * ‖c - d‖ := by have hFA : ‖DA.applyFunction f‖ ≤ κA * R := norm_applyFunction_le DA f hf hf0 hκA hR0 hRA have hFB : ‖DB.applyFunction f‖ ≤ κB * R := norm_applyFunction_le DB f hf hf0 hκB hR0 hRB have hdiff : ‖DA.applyFunction f - DB.applyFunction f‖ ≤ (n : ℝ) ^ 2 * κA * κB * ‖A - B‖ := norm_applyFunction_sub_le_dim_sq DA DB f hf hκA hκB have hdecomp : anchorEval a c (DA.applyFunction f) - anchorEval b d (DB.applyFunction f) = anchorEval (a - b) c (DA.applyFunction f) + anchorEval b c (DA.applyFunction f - DB.applyFunction f) + anchorEval b (c - d) (DB.applyFunction f) := by unfold anchorEval matrixCLM simp only [map_sub, sub_apply, inner_sub_left, inner_sub_right] ring rw [hdecomp] calc |anchorEval (a - b) c (DA.applyFunction f) + anchorEval b c (DA.applyFunction f - DB.applyFunction f) + anchorEval b (c - d) (DB.applyFunction f)| ≤ |anchorEval (a - b) c (DA.applyFunction f)| + |anchorEval b c (DA.applyFunction f - DB.applyFunction f)| + |anchorEval b (c - d) (DB.applyFunction f)| := by calc |anchorEval (a - b) c (DA.applyFunction f) + anchorEval b c (DA.applyFunction f - DB.applyFunction f) + anchorEval b (c - d) (DB.applyFunction f)| ≤ |anchorEval (a - b) c (DA.applyFunction f) + anchorEval b c (DA.applyFunction f - DB.applyFunction f)| + |anchorEval b (c - d) (DB.applyFunction f)| := abs_add_le _ _ _ ≤ _ := by gcongr exact abs_add_le _ _ _ ≤ (‖a - b‖ * ‖DA.applyFunction f‖ * ‖c‖) + (‖b‖ * ‖DA.applyFunction f - DB.applyFunction f‖ * ‖c‖) + (‖b‖ * ‖DB.applyFunction f‖ * ‖c - d‖) := by gcongr · exact abs_anchorEval_le _ _ _ · exact abs_anchorEval_le _ _ _ · exact abs_anchorEval_le _ _ _ _ ≤ ‖a - b‖ * (κA * R) * ‖c‖ + ‖b‖ * ((n : ℝ) ^ 2 * κA * κB * ‖A - B‖) * ‖c‖ + ‖b‖ * (κB * R) * ‖c - d‖ := by gcongr
    Causalean.Mathlib.Analysis.abs_anchorEval_applyFunction_sub_le · Causalean/Mathlib/Analysis/DiagonalizableFunctionalCalculus.lean:505
Two­By­Two­Spectral­Roots 5 core · 12 supporting This module supplies explicit ordered roots, their spectral interpretation for symmetric matrices, and their local continuous differentiability away from a repeated root. ★ eigenvalue_eq_lambda₁_or_lambda₂

Ordered roots of a real two-by-two matrix

This module supplies explicit ordered roots, their spectral interpretation for symmetric matrices, and their local continuous differentiability away from a repeated root. The formulas are defined on all real two-by-two matrices, so the strict-gap region is open without choosing an eigenvector.

def rootDiscriminant reviewed
Causalean.Mathlib.Analysis

Given a real two-by-two matrix, the symmetric-matrix discriminant is the squared diagonal difference plus four times the squared upper off-diagonal entry. The lower off-diagonal entry is ignored, so this is the discriminant of the characteristic polynomial only for a symmetric matrix.

Definition (Lean source)
G :
Matrix (Fin 2) (Fin 2) ℝ
rootDiscriminant G :
ℝ
(G 0 0 - G 1 1) ^ 2 + 4 * (G 0 1) ^ 2
Causalean.Mathlib.Analysis.rootDiscriminant · Causalean/Mathlib/Analysis/TwoByTwoSpectralRoots.lean:20
def lambda₁ reviewed
Causalean.Mathlib.Analysis

Given a real two-by-two matrix, its larger symmetric-formula root is half the trace plus half the nonnegative square root of the symmetric-matrix discriminant. For a symmetric matrix this is the larger eigenvalue; for a nonsymmetric matrix it need not be an eigenvalue.

Definition (Lean source)
G :
Matrix (Fin 2) (Fin 2) ℝ
lambda₁ G :
ℝ
(G 0 0 + G 1 1 + sqrt (rootDiscriminant G)) / 2
Causalean.Mathlib.Analysis.lambda₁ · Causalean/Mathlib/Analysis/TwoByTwoSpectralRoots.lean:24
def lambda₂ reviewed
Causalean.Mathlib.Analysis

Given a real two-by-two matrix, its smaller symmetric-formula root is half the trace minus half the nonnegative square root of the symmetric-matrix discriminant. For a symmetric matrix this is the smaller eigenvalue; for a nonsymmetric matrix it need not be an eigenvalue.

Definition (Lean source)
G :
Matrix (Fin 2) (Fin 2) ℝ
lambda₂ G :
ℝ
(G 0 0 + G 1 1 - sqrt (rootDiscriminant G)) / 2
Causalean.Mathlib.Analysis.lambda₂ · Causalean/Mathlib/Analysis/TwoByTwoSpectralRoots.lean:28
def strictGapSet reviewed
Causalean.Mathlib.Analysis

The strict-gap region consists of real two-by-two matrices whose lower quadratic-formula root is strictly below their upper root.

Definition (Lean source)
strictGapSet :
Set (Matrix (Fin 2) (Fin 2) ℝ)
{G | lambda₂ G < lambda₁ G}
Causalean.Mathlib.Analysis.strictGapSet · Causalean/Mathlib/Analysis/TwoByTwoSpectralRoots.lean:32
theorem eigenvalue_eq_lambda₁_or_lambda₂ reviewed
Causalean.Mathlib.Analysis

Given a real symmetric two-by-two matrix, a real number, a nonzero two-vector, and an eigenvector relation for that number, the number is one of the two explicit ordered roots.

Formal statement
G :
Matrix (Fin 2) (Fin 2) ℝ
hG :
G.IsHermitian
μ :
ℝ
v :
Fin 2 → ℝ
hv :
v ≠ 0
heig :
G.mulVec v = μ • v
μ = lambda₁ G ∨ μ = lambda₂ G
Proof (Lean source)
theorem eigenvalue_eq_lambda₁_or_lambda₂ {G : Matrix (Fin 2) (Fin 2) ℝ} (hG : G.IsHermitian) {μ : ℝ} {v : Fin 2 → ℝ} (hv : v ≠ 0) (heig : G.mulVec v = μ • v) : μ = lambda₁ G ∨ μ = lambda₂ G := by have hsym : G 1 0 = G 0 1 := by simpa using hG.apply 0 1 have h0 := congrFun heig 0 have h1 := congrFun heig 1 simp [mulVec] at h0 h1 rw [hsym] at h1 have hdet : (G 0 0 - μ) * (G 1 1 - μ) - G 0 1 * G 0 1 = 0 := by by_cases hv0 : v 0 = 0 · have hv1 : v 1 ≠ 0 := by intro hv1 apply hv funext i fin_cases i <;> assumption rw [hv0] at h0 h1 simp only [mul_zero, zero_add] at h0 h1 apply (mul_eq_zero.mp ?_).resolve_right hv1 linear_combination (G 0 0 - μ) * h1 - G 0 1 * h0 · apply (mul_eq_zero.mp ?_).resolve_right hv0 linear_combination (G 1 1 - μ) * h0 - G 0 1 * h1 have hsum := lambda₁_add_lambda₂ G have hprod := lambda₁_mul_lambda₂ hG rw [Matrix.det_fin_two, hsym] at hprod have hfactor : (μ - lambda₁ G) * (μ - lambda₂ G) = 0 := by calc _ = μ ^ 2 - μ * (lambda₁ G + lambda₂ G) + lambda₁ G * lambda₂ G := by ring _ = μ ^ 2 - μ * (G 0 0 + G 1 1) + (G 0 0 * G 1 1 - G 0 1 * G 0 1) := by rw [hsum, hprod] _ = 0 := by nlinarith [hdet] rcases mul_eq_zero.mp hfactor with h | h · left linarith · right linarith
Causalean.Mathlib.Analysis.eigenvalue_eq_lambda₁_or_lambda₂ · Causalean/Mathlib/Analysis/TwoByTwoSpectralRoots.lean:93 · uses lambda₁ , lambda₂
12 supporting declarations (lemmas, instances)
Locally­Bounded­Derivative 2 core · 0 supporting This module packages the elementary finite-dimensional consequence that a continuously differentiable function has a bounded Fréchet derivative on some neighborhood of each point. ★ hasLocallyBoundedFDerivAt

Local boundedness of a continuously differentiable derivative

This module packages the elementary finite-dimensional consequence that a continuously differentiable function has a bounded Fréchet derivative on some neighborhood of each point. It is independent of the matrix-specific development.

def HasLocallyBoundedFDerivAt reviewed
Causalean.Mathlib.Analysis

Given a function between real normed vector spaces and a point in its domain, the property of having a locally bounded Fréchet derivative means that one neighborhood of the point has a uniform nonnegative bound on derivative norms.

Definition (Lean source)
f :
E → F
x :
E
HasLocallyBoundedFDerivAt f x :
Prop
∃ U ∈ 𝓝 x, ∃ C : ℝ,
0 ≤ C
clause 1
y ∈ U :
‖fderiv ℝ f y‖ ≤ C
Causalean.Mathlib.Analysis.HasLocallyBoundedFDerivAt · Causalean/Mathlib/Analysis/LocallyBoundedDerivative.lean:17
theorem hasLocallyBoundedFDerivAt reviewed
Causalean.Mathlib.Analysis.ContDiffAt

Given a function between real normed vector spaces, a point in its domain, and continuous differentiability at that point, the function has a locally bounded Fréchet derivative there.

Formal statement
hf :
ContDiffAt ℝ 1 f x
Proof (Lean source)
theorem ContDiffAt.hasLocallyBoundedFDerivAt {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] [NormedAddCommGroup F] [NormedSpace ℝ F] {f : E → F} {x : E} (hf : ContDiffAt ℝ 1 f x) : HasLocallyBoundedFDerivAt f x := by rcases contDiffAt_one_iff.mp hf with ⟨f', U, hU, hf'cont, hfderiv⟩ have hxU : x ∈ U := mem_of_mem_nhds hU have hf'contAt : ContinuousAt f' x := (hf'cont x hxU).continuousAt hU have hnorm : ContinuousAt (fun y => ‖f' y‖) x := hf'contAt.norm have hbound : {y | ‖f' y‖ < ‖f' x‖ + 1} ∈ 𝓝 x := hnorm (Iio_mem_nhds (lt_add_one ‖f' x‖)) refine ⟨U ∩ {y | ‖f' y‖ < ‖f' x‖ + 1}, inter_mem hU hbound, ‖f' x‖ + 1, by positivity, ?_⟩ intro y hy rw [(hfderiv y hy.1).fderiv] exact le_of_lt hy.2
Causalean.Mathlib.Analysis.ContDiffAt.hasLocallyBoundedFDerivAt · Causalean/Mathlib/Analysis/LocallyBoundedDerivative.lean:22 · uses HasLocallyBoundedFDerivAt
Moore­Penrose 4 core · 10 supporting This module gives a paper-independent Moore--Penrose inverse for every finite real rectangular matrix. ★ norm_moorePenrose_sub_le_of_singularMargin

Moore--Penrose inverses and moving-range perturbations

This module gives a paper-independent Moore--Penrose inverse for every finite real rectangular matrix. It exposes the Penrose equations, the two associated orthogonal projections, the exact ambient perturbation identity, and its operator-norm and singular-margin consequences. Neither the row space nor the column space is fixed.

def IsMoorePenroseInverse reviewed
Causalean.Mathlib.Analysis

G is a Moore--Penrose inverse of A when the four real Penrose equations hold.

Definition (Lean source)
rows cols :
ℕ
A :
RectMatrix rows cols
G :
RectMatrix cols rows
IsMoorePenroseInverse A G :
Prop
clause 1
A * G * A = A
clause 2
G * A * G = G
clause 3
(A * G).transpose = A * G
clause 4
(G * A).transpose = G * A
Causalean.Mathlib.Analysis.IsMoorePenroseInverse · Causalean/Mathlib/Analysis/MoorePenrose.lean:204 · uses RectMatrix
def moorePenroseInverse reviewed
Causalean.Mathlib.Analysis

The canonical Moore--Penrose inverse of a finite real rectangular matrix.

Definition (Lean source)
rows cols :
ℕ
A :
RectMatrix rows cols
moorePenroseInverse A :
RectMatrix cols rows
Causalean.Mathlib.Analysis.moorePenroseInverse · Causalean/Mathlib/Analysis/MoorePenrose.lean:298 · uses RectMatrix
def «term_†» reviewed
Causalean.Mathlib.Analysis

The dagger postfix denotes the canonical Moore--Penrose inverse of a finite real matrix.

Definition (Lean source)
postfix:max "†" => moorePenroseInverse
Causalean.Mathlib.Analysis.«term_†» · Causalean/Mathlib/Analysis/MoorePenrose.lean:303
theorem norm_moorePenrose_sub_le_of_singularMargin reviewed
Causalean.Mathlib.Analysis

If two real rectangular matrices A and B both have rank r and their r-th largest singular values are both at least a common positive number s, then the operator norm of the difference of their Moore–Penrose inverses is at most 3/s² times the operator norm of A − B.

Formal statement
rows cols r :
ℕ
A B :
RectMatrix rows cols
s :
ℝ
hrankA :
A.rank = r
hrankB :
B.rank = r
hs :
0 < s
hmarginA :
s ≤ singularValue A (r - 1)
hmarginB :
s ≤ singularValue B (r - 1)
‖A† - B†‖ ≤ 3 * s⁻¹ ^ 2 * ‖A - B‖
Proof (Lean source)
theorem norm_moorePenrose_sub_le_of_singularMargin {rows cols r : ℕ} (A B : RectMatrix rows cols) {s : ℝ} (hrankA : A.rank = r) (hrankB : B.rank = r) (hs : 0 < s) (hmarginA : s ≤ singularValue A (r - 1)) (hmarginB : s ≤ singularValue B (r - 1)) : ‖A† - B†‖ ≤ 3 * s⁻¹ ^ 2 * ‖A - B‖ := by have hAinv := norm_moorePenroseInverse_le_inv A hrankA hs hmarginA have hBinv := norm_moorePenroseInverse_le_inv B hrankB hs hmarginB have hAsq : ‖A†‖ ^ 2 ≤ s⁻¹ ^ 2 := by nlinarith [norm_nonneg A†] have hBsq : ‖B†‖ ^ 2 ≤ s⁻¹ ^ 2 := by nlinarith [norm_nonneg B†] calc ‖A† - B†‖ ≤ 3 * max (‖A†‖ ^ 2) (‖B†‖ ^ 2) * ‖A - B‖ := norm_moorePenrose_sub_le A B _ ≤ 3 * s⁻¹ ^ 2 * ‖A - B‖ := by gcongr exact max_le hAsq hBsq
Causalean.Mathlib.Analysis.norm_moorePenrose_sub_le_of_singularMargin · Causalean/Mathlib/Analysis/MoorePenrose.lean:537 · uses RectMatrix , moorePenroseInverse , singularValue
10 supporting declarations (lemmas, instances)
  • exists_moorePenroseInverse theorem — Every finite real rectangular matrix has a Moore--Penrose inverse.
    rows cols :
    ℕ
    A :
    RectMatrix rows cols
    ∃ G : RectMatrix cols rows, IsMoorePenroseInverse A G
    Proof (Lean source)
    theorem exists_moorePenroseInverse {rows cols : ℕ} (A : RectMatrix rows cols) : ∃ G : RectMatrix cols rows, IsMoorePenroseInverse A G := ⟨constructedMP A, constructedMP_spec A⟩
    Causalean.Mathlib.Analysis.exists_moorePenroseInverse · Causalean/Mathlib/Analysis/MoorePenrose.lean:255
  • isMoorePenroseInverse_unique theorem — A Moore--Penrose inverse of a fixed real matrix is unique.
    rows cols :
    ℕ
    RectMatrix rows cols
    RectMatrix cols rows
    G = H
    Proof (Lean source)
    theorem isMoorePenroseInverse_unique {rows cols : ℕ} {A : RectMatrix rows cols} {G H : RectMatrix cols rows} (hG : IsMoorePenroseInverse A G) (hH : IsMoorePenroseInverse A H) : G = H := by have hGAHA : (G * A) * (H * A) = G * A := by calc (G * A) * (H * A) = G * (A * H * A) := by simp only [Matrix.mul_assoc] _ = G * A := by rw [hH.1] have hHAGA : (H * A) * (G * A) = H * A := by calc (H * A) * (G * A) = H * (A * G * A) := by simp only [Matrix.mul_assoc] _ = H * A := by rw [hG.1] have hGAeqHA : G * A = H * A := by have ht := congr_arg Matrix.transpose hGAHA have ht' : (H * A) * (G * A) = G * A := by simpa only [Matrix.transpose_mul, hH.2.2.2, hG.2.2.2] using ht exact (hHAGA.symm.trans ht').symm have hAGAH : (A * G) * (A * H) = A * H := by calc (A * G) * (A * H) = (A * G * A) * H := by simp only [Matrix.mul_assoc] _ = A * H := by rw [hG.1] have hAHAG : (A * H) * (A * G) = A * G := by calc (A * H) * (A * G) = (A * H * A) * G := by simp only [Matrix.mul_assoc] _ = A * G := by rw [hH.1] have hAGeqAH : A * G = A * H := by have ht := congr_arg Matrix.transpose hAGAH have ht' : (A * H) * (A * G) = A * H := by simpa only [Matrix.transpose_mul, hH.2.2.1, hG.2.2.1] using ht exact hAHAG.symm.trans ht' calc G = G * A * G := hG.2.1.symm _ = H * A * G := by rw [hGAeqHA] _ = H * (A * G) := Matrix.mul_assoc _ _ _ _ = H * (A * H) := by rw [hAGeqAH] _ = H * A * H := (Matrix.mul_assoc _ _ _).symm _ = H := hH.2.1
    Causalean.Mathlib.Analysis.isMoorePenroseInverse_unique · Causalean/Mathlib/Analysis/MoorePenrose.lean:260
  • moorePenroseInverse_spec theorem — The canonical inverse satisfies all four Penrose equations.
    rows cols :
    ℕ
    A :
    RectMatrix rows cols
    Proof (Lean source)
    theorem moorePenroseInverse_spec {rows cols : ℕ} (A : RectMatrix rows cols) : IsMoorePenroseInverse A A† := by exact Classical.choose_spec (exists_moorePenroseInverse A)
    Causalean.Mathlib.Analysis.moorePenroseInverse_spec · Causalean/Mathlib/Analysis/MoorePenrose.lean:306
  • rangeProjection_penrose theorem — The product A A† is the orthogonal projector onto the moving column space of A.
    rows cols :
    ℕ
    A :
    RectMatrix rows cols
    conclusion 1
    (A * A†) * (A * A†) = A * A†
    conclusion 2
    (A * A†).transpose = A * A†
    Proof (Lean source)
    theorem rangeProjection_penrose {rows cols : ℕ} (A : RectMatrix rows cols) : (A * A†) * (A * A†) = A * A† ∧ (A * A†).transpose = A * A† := by have h := moorePenroseInverse_spec A constructor · rw [← Matrix.mul_assoc, h.1] · exact h.2.2.1
    Causalean.Mathlib.Analysis.rangeProjection_penrose · Causalean/Mathlib/Analysis/MoorePenrose.lean:311
  • rowProjection_penrose theorem — The product A† A is the orthogonal projector onto the moving row space of A.
    rows cols :
    ℕ
    A :
    RectMatrix rows cols
    conclusion 1
    (A† * A) * (A† * A) = A† * A
    conclusion 2
    (A† * A).transpose = A† * A
    Proof (Lean source)
    theorem rowProjection_penrose {rows cols : ℕ} (A : RectMatrix rows cols) : (A† * A) * (A† * A) = A† * A ∧ (A† * A).transpose = A† * A := by have h := moorePenroseInverse_spec A constructor · rw [← Matrix.mul_assoc, h.2.1] · exact h.2.2.2
    Causalean.Mathlib.Analysis.rowProjection_penrose · Causalean/Mathlib/Analysis/MoorePenrose.lean:319
  • rangeProjection_norms_le_one theorem — A Penrose range projector and its orthogonal complement both have norm at most one.
    rows cols :
    ℕ
    A :
    RectMatrix rows cols
    conclusion 1
    ‖A * A†‖ ≤ 1
    conclusion 2
    ‖(1 : RectMatrix rows rows) - A * A†‖ ≤ 1
    Proof (Lean source)
    theorem rangeProjection_norms_le_one {rows cols : ℕ} (A : RectMatrix rows cols) : ‖A * A†‖ ≤ 1 ∧ ‖(1 : RectMatrix rows rows) - A * A†‖ ≤ 1 := by exact symmetricIdempotent_norms_le_one (A * A†) (rangeProjection_penrose A).1 (rangeProjection_penrose A).2
    Causalean.Mathlib.Analysis.rangeProjection_norms_le_one · Causalean/Mathlib/Analysis/MoorePenrose.lean:327
  • rowProjection_norms_le_one theorem — A Penrose row projector and its orthogonal complement both have norm at most one.
    rows cols :
    ℕ
    A :
    RectMatrix rows cols
    conclusion 1
    ‖A† * A‖ ≤ 1
    conclusion 2
    ‖(1 : RectMatrix cols cols) - A† * A‖ ≤ 1
    Proof (Lean source)
    theorem rowProjection_norms_le_one {rows cols : ℕ} (A : RectMatrix rows cols) : ‖A† * A‖ ≤ 1 ∧ ‖(1 : RectMatrix cols cols) - A† * A‖ ≤ 1 := by exact symmetricIdempotent_norms_le_one (A† * A) (rowProjection_penrose A).1 (rowProjection_penrose A).2
    Causalean.Mathlib.Analysis.rowProjection_norms_le_one · Causalean/Mathlib/Analysis/MoorePenrose.lean:333
  • moorePenrose_sub_eq theorem — Exact ambient Moore--Penrose difference identity. It permits both ranges to move and holds for every pair of rectangular matrices of the same shape.
    rows cols :
    ℕ
    A B :
    RectMatrix rows cols
    B† - A†
    = -B† * (B - A) * A†
    + B† * B†.transpose * (B - A).transpose * ((1 : RectMatrix rows rows) - A * A†)
    + ((1 : RectMatrix cols cols) - B† * B) * (B - A).transpose * A†.transpose * A†
    Proof (Lean source)
    theorem moorePenrose_sub_eq {rows cols : ℕ} (A B : RectMatrix rows cols) : B† - A† = -B† * (B - A) * A† + B† * B†.transpose * (B - A).transpose * ((1 : RectMatrix rows rows) - A * A†) + ((1 : RectMatrix cols cols) - B† * B) * (B - A).transpose * A†.transpose * A† := by have hA := moorePenroseInverse_spec A have hB := moorePenroseInverse_spec B have hBBtBt : B† * B†.transpose * B.transpose = B† := by calc B† * B†.transpose * B.transpose = B† * (B†.transpose * B.transpose) := Matrix.mul_assoc _ _ _ _ = B† * (B * B†) := by rw [← hB.2.2.1, Matrix.transpose_mul] _ = B† := by rw [← Matrix.mul_assoc, hB.2.1] have hAtAtA : A.transpose * A†.transpose * A† = A† := by calc A.transpose * A†.transpose * A† = (A† * A) * A† := by rw [← hA.2.2.2, Matrix.transpose_mul] _ = A† := hA.2.1 have hAtQ : A.transpose * ((1 : RectMatrix rows rows) - A * A†) = 0 := by have ht := congr_arg Matrix.transpose hA.1 have ht' : A.transpose * (A†.transpose * A.transpose) = A.transpose := by simpa only [Matrix.transpose_mul] using ht have hs : A†.transpose * A.transpose = A * A† := by simpa only [Matrix.transpose_mul] using hA.2.2.1 have hh : A.transpose * (A * A†) = A.transpose := by rw [← hs, ht'] rw [Matrix.mul_sub, Matrix.mul_one, hh, sub_self] have hQB : ((1 : RectMatrix cols cols) - B† * B) * B.transpose = 0 := by have ht := congr_arg Matrix.transpose hB.1 have ht' : B.transpose * (B†.transpose * B.transpose) = B.transpose := by simpa only [Matrix.transpose_mul] using ht have hs : B.transpose * B†.transpose = B† * B := by simpa only [Matrix.transpose_mul] using hB.2.2.2 have hh : (B† * B) * B.transpose = B.transpose := by rw [← hs, Matrix.mul_assoc, ht'] rw [Matrix.sub_mul, Matrix.one_mul, hh, sub_self] rw [Matrix.transpose_sub] have hterm2 : B† * B†.transpose * (B.transpose - A.transpose) * ((1 : RectMatrix rows rows) - A * A†) = B† - B† * A * A† := by let Q : RectMatrix rows rows := 1 - A * A† change B† * B†.transpose * (B.transpose - A.transpose) * Q = B† - B† * A * A† calc _ = (B† * B†.transpose * B.transpose) * Q - B† * B†.transpose * (A.transpose * Q) := by rw [Matrix.mul_assoc (B† * B†.transpose) (B.transpose - A.transpose) Q, Matrix.sub_mul B.transpose A.transpose Q, Matrix.mul_sub (B† * B†.transpose), Matrix.mul_assoc (B† * B†.transpose)] _ = B† * Q := by rw [hBBtBt, show A.transpose * Q = 0 by exact hAtQ]; simp _ = B† - B† * A * A† := by rw [Matrix.mul_sub, Matrix.mul_one, Matrix.mul_assoc] have hterm3 : ((1 : RectMatrix cols cols) - B† * B) * (B.transpose - A.transpose) * A†.transpose * A† = -(A† - B† * B * A.transpose * A†.transpose * A†) := by let Q : RectMatrix cols cols := 1 - B† * B change Q * (B.transpose - A.transpose) * A†.transpose * A† = -(A† - B† * B * A.transpose * A†.transpose * A†) have hAtAtA' : A.transpose * (A†.transpose * A†) = A† := by rw [← Matrix.mul_assoc, hAtAtA] calc _ = (Q * B.transpose) * A†.transpose * A† - (Q * A.transpose) * A†.transpose * A† := by rw [Matrix.mul_sub, Matrix.sub_mul, Matrix.sub_mul] _ = -(Q * A.transpose * A†.transpose * A†) := by rw [show Q * B.transpose = 0 by exact hQB]; simp _ = -(A† - B† * B * A.transpose * A†.transpose * A†) := by congr 1 rw [Matrix.sub_mul (1 : RectMatrix cols cols) (B† * B) A.transpose, Matrix.sub_mul, Matrix.sub_mul, Matrix.one_mul] simp only [Matrix.mul_assoc] rw [hAtAtA'] rw [hterm2, hterm3] have hAtAtA' : A.transpose * (A†.transpose * A†) = A† := by rw [← Matrix.mul_assoc, hAtAtA] have hcross : B† * B * A.transpose * A†.transpose * A† = B† * B * A† := by simp only [Matrix.mul_assoc] rw [hAtAtA'] have hterm1 : -B† * (B - A) * A† = -(B† * B * A†) + B† * A * A† := by rw [Matrix.mul_sub, Matrix.sub_mul] simp only [Matrix.neg_mul] abel rw [hterm1, hcross] abel
    Causalean.Mathlib.Analysis.moorePenrose_sub_eq · Causalean/Mathlib/Analysis/MoorePenrose.lean:339
  • norm_moorePenrose_sub_le theorem — Moore--Penrose inverses are Lipschitz with the explicit symmetric maximum of their squared inverse norms: the inverses differ by at most three times that maximum times the difference of the matrices.
    rows cols :
    ℕ
    A B :
    RectMatrix rows cols
    ‖A† - B†‖ ≤ 3 * max (‖A†‖ ^ 2) (‖B†‖ ^ 2) * ‖A - B‖
    Proof (Lean source)
    theorem norm_moorePenrose_sub_le {rows cols : ℕ} (A B : RectMatrix rows cols) : ‖A† - B†‖ ≤ 3 * max (‖A†‖ ^ 2) (‖B†‖ ^ 2) * ‖A - B‖ := by let M := max (‖A†‖ ^ 2) (‖B†‖ ^ 2) let d := ‖A - B‖ have hAM : ‖A†‖ ^ 2 ≤ M := le_max_left _ _ have hBM : ‖B†‖ ^ 2 ≤ M := le_max_right _ _ have hABM : ‖A†‖ * ‖B†‖ ≤ M := by nlinarith [sq_nonneg (‖A†‖ - ‖B†‖)] have hd : 0 ≤ d := norm_nonneg _ have ht1 : ‖-A† * (A - B) * B†‖ ≤ M * d := by calc ‖-A† * (A - B) * B†‖ = ‖A† * (A - B) * B†‖ := by rw [Matrix.neg_mul, Matrix.neg_mul, norm_neg] _ ≤ ‖A†‖ * ‖A - B‖ * ‖B†‖ := l2_opNorm_mul_three _ _ _ _ = (‖A†‖ * ‖B†‖) * d := by dsimp [d]; ring _ ≤ M * d := mul_le_mul_of_nonneg_right hABM hd have ht2 : ‖A† * A†.transpose * (A - B).transpose * ((1 : RectMatrix rows rows) - B * B†)‖ ≤ M * d := by calc _ ≤ ‖A†‖ * ‖A†.transpose‖ * ‖(A - B).transpose‖ * ‖(1 : RectMatrix rows rows) - B * B†‖ := l2_opNorm_mul_four _ _ _ _ _ = ‖A†‖ * ‖A†‖ * d * ‖(1 : RectMatrix rows rows) - B * B†‖ := by rw [l2_opNorm_transpose, l2_opNorm_transpose] _ ≤ ‖A†‖ * ‖A†‖ * d * 1 := by gcongr exact (rangeProjection_norms_le_one B).2 _ = ‖A†‖ ^ 2 * d := by ring _ ≤ M * d := mul_le_mul_of_nonneg_right hAM hd have ht3 : ‖((1 : RectMatrix cols cols) - A† * A) * (A - B).transpose * B†.transpose * B†‖ ≤ M * d := by calc _ ≤ ‖(1 : RectMatrix cols cols) - A† * A‖ * ‖(A - B).transpose‖ * ‖B†.transpose‖ * ‖B†‖ := l2_opNorm_mul_four _ _ _ _ _ = ‖(1 : RectMatrix cols cols) - A† * A‖ * d * ‖B†‖ * ‖B†‖ := by rw [l2_opNorm_transpose, l2_opNorm_transpose] _ ≤ 1 * d * ‖B†‖ * ‖B†‖ := by gcongr exact (rowProjection_norms_le_one A).2 _ = ‖B†‖ ^ 2 * d := by ring _ ≤ M * d := mul_le_mul_of_nonneg_right hBM hd rw [moorePenrose_sub_eq B A] calc _ ≤ ‖-A† * (A - B) * B† + A† * A†.transpose * (A - B).transpose * ((1 : RectMatrix rows rows) - B * B†)‖ + ‖((1 : RectMatrix cols cols) - A† * A) * (A - B).transpose * B†.transpose * B†‖ := norm_add_le _ _ _ ≤ (‖-A† * (A - B) * B†‖ + ‖A† * A†.transpose * (A - B).transpose * ((1 : RectMatrix rows rows) - B * B†)‖) + ‖((1 : RectMatrix cols cols) - A† * A) * (A - B).transpose * B†.transpose * B†‖ := by gcongr exact norm_add_le _ _ _ ≤ (M * d + M * d) + M * d := add_le_add (add_le_add ht1 ht2) ht3 _ = 3 * M * d := by ring
    Causalean.Mathlib.Analysis.norm_moorePenrose_sub_le · Causalean/Mathlib/Analysis/MoorePenrose.lean:429
  • norm_moorePenroseInverse_le_inv theorem — A positive lower bound on the last nonzero singular value bounds the pseudoinverse norm.
    rows cols r :
    ℕ
    A :
    RectMatrix rows cols
    s :
    ℝ
    hrank :
    A.rank = r
    hs :
    0 < s
    hmargin :
    s ≤ singularValue A (r - 1)
    ‖A†‖ ≤ s⁻¹
    Proof (Lean source)
    theorem norm_moorePenroseInverse_le_inv {rows cols r : ℕ} (A : RectMatrix rows cols) {s : ℝ} (hrank : A.rank = r) (hs : 0 < s) (hmargin : s ≤ singularValue A (r - 1)) : ‖A†‖ ≤ s⁻¹ := by let T := Matrix.toEuclideanLin A have hrT : finrank ℝ T.range = r := by have h := A.rank_eq_finrank_range_toLin (EuclideanSpace.basisFun (Fin rows) ℝ).toBasis (EuclideanSpace.basisFun (Fin cols) ℝ).toBasis rw [hrank] at h exact h.symm have hrpos : 0 < r := by by_contra hr0 have hre : r = 0 := Nat.eq_zero_of_not_pos hr0 have hz : singularValue A (r - 1) = 0 := by unfold singularValue apply T.singularValues_eq_zero_iff_le_finrank_range.mpr rw [hrT, hre] linarith have hcanon : A† = constructedMP A := isMoorePenroseInverse_unique (moorePenroseInverse_spec A) (constructedMP_spec A) have hbound : ‖LinearMap.toContinuousLinearMap (mpLinear T)‖ ≤ s⁻¹ := by apply ContinuousLinearMap.opNorm_le_bound _ (le_of_lt (inv_pos.mpr hs)) intro y have hxmem : mpLinear T y ∈ T.kerᗮ := ((LinearEquiv.ofBijective (restrictKerOrth T) (restrictKerOrth_bijective T)).symm (T.range.orthogonalProjectionOnto y)).property have hlower := singularValues_mul_norm_le_of_mem_ker_orthogonal T hrT hrpos (mpLinear T y) hxmem have hmarginT : s ≤ T.singularValues (r - 1) := hmargin have hsx : s * ‖mpLinear T y‖ ≤ ‖T (mpLinear T y)‖ := (mul_le_mul_of_nonneg_right hmarginT (norm_nonneg _)).trans hlower have hTx : T (mpLinear T y) = T.range.starProjection y := DFunLike.congr_fun (comp_mpLinear T) y have hproj : ‖T.range.starProjection y‖ ≤ ‖y‖ := T.range.norm_starProjection_apply_le y rw [hTx] at hsx have hsy : s * ‖mpLinear T y‖ ≤ ‖y‖ := hsx.trans hproj rw [inv_mul_eq_div, le_div_iff₀ hs] simpa [mul_comm] using hsy change ‖LinearMap.toContinuousLinearMap (Matrix.toEuclideanLin A†)‖ ≤ s⁻¹ rw [hcanon, constructedMP, LinearEquiv.apply_symm_apply] exact hbound
    Causalean.Mathlib.Analysis.norm_moorePenroseInverse_le_inv · Causalean/Mathlib/Analysis/MoorePenrose.lean:492
Bernoulli­KL 2 core · 2 supporting This file proves a scalar upper bound on the Kullback--Leibler divergence between two Bernoulli laws whose success probabilities both lie in the interval $[1/4,3/4]$. ★ bernoulli_kl_le_four_sq_sub_of_mem_quarter_band

Bernoulli KL Band Bound

This file proves a scalar upper bound on the Kullback--Leibler divergence between two Bernoulli laws whose success probabilities both lie in the interval [1/4,3/4][1/4,3/4]. It supplies a Mathlib-adjacent analytic estimate used by finite-sample information arguments elsewhere in the library.

def bernD reviewed
Causalean.Mathlib.Analysis

For a real number, the negative Bernoulli entropy is tlog⁡t+(1−t)log⁡(1−t)t\log t + (1-t)\log(1-t).

Definition (Lean source)
t :
ℝ
bernD t :
ℝ
t * log t + (1 - t) * log (1 - t)
Causalean.Mathlib.Analysis.bernD · Causalean/Mathlib/Analysis/BernoulliKL.lean:64
theorem bernoulli_kl_le_four_sq_sub_of_mem_quarter_band reviewed
Causalean.Mathlib.Analysis

For probabilities p and q both restricted to the band [1/4, 3/4], the Bernoulli Kullback–Leibler divergence p · log(p / q) + (1 - p) · log((1 - p) / (1 - q)) is bounded above by 4 · (p - q) ^ 2.

Formal statement
p q :
ℝ
hp_lo :
(1 : ℝ) / 4 ≤ p
hp_hi :
p ≤ 3 / 4
hq_lo :
(1 : ℝ) / 4 ≤ q
hq_hi :
q ≤ 3 / 4
p * log (p / q) + (1 - p) * log ((1 - p) / (1 - q)) ≤ 4 * (p - q) ^ 2
Proof (Lean source)
theorem bernoulli_kl_le_four_sq_sub_of_mem_quarter_band {p q : ℝ} (hp_lo : (1 : ℝ) / 4 ≤ p) (hp_hi : p ≤ 3 / 4) (hq_lo : (1 : ℝ) / 4 ≤ q) (hq_hi : q ≤ 3 / 4) : p * log (p / q) + (1 - p) * log ((1 - p) / (1 - q)) ≤ 4 * (p - q) ^ 2 := by have hp0 : p ≠ 0 := by nlinarith have hp1 : 1 - p ≠ 0 := by nlinarith have hq0 : q ≠ 0 := by nlinarith have hq1 : 1 - q ≠ 0 := by nlinarith rw [bernoulliKL_eq_bregman hp0 hp1 hq0 hq1] have hnonneg := bernH_nonneg_of_mem_quarter_band hp_lo hp_hi hq_lo hq_hi unfold bernH at hnonneg linarith
Causalean.Mathlib.Analysis.bernoulli_kl_le_four_sq_sub_of_mem_quarter_band · Causalean/Mathlib/Analysis/BernoulliKL.lean:195
2 supporting declarations (lemmas, instances)
  • hasDerivAt_bernEntropy lemma — Away from zero and one, the negative Bernoulli entropy has derivative equal to the log odds of its argument.
    x :
    ℝ
    hx0 :
    x ≠ 0
    hx1 :
    1 - x ≠ 0
    HasDerivAt (fun t : ℝ => t * log t + (1 - t) * log (1 - t)) (log x - log (1 - x)) x
    Proof (Lean source)
    lemma hasDerivAt_bernEntropy (x : ℝ) (hx0 : x ≠ 0) (hx1 : 1 - x ≠ 0) : HasDerivAt (fun t : ℝ => t * log t + (1 - t) * log (1 - t)) (log x - log (1 - x)) x := by have h1 : HasDerivAt (fun t : ℝ => t * log t) (log x + 1) x := Real.hasDerivAt_mul_log hx0 have hsub : HasDerivAt (fun t : ℝ => 1 - t) (0 - 1) x := (hasDerivAt_const x (1 : ℝ)).fun_sub (hasDerivAt_id' (x := x)) have h2log : HasDerivAt (fun t : ℝ => log (1 - t)) (-(1 - x)⁻¹) x := by have h : HasDerivAt (fun t : ℝ => log (1 - t)) ((1 - x)⁻¹ * (0 - 1)) x := (Real.hasDerivAt_log hx1).comp x hsub convert h using 1 ring have h2 : HasDerivAt (fun t : ℝ => (1 - t) * log (1 - t)) (-(log (1 - x)) - 1) x := by have h : HasDerivAt (fun t : ℝ => (1 - t) * log (1 - t)) _ x := hsub.fun_mul h2log convert h using 1 rw [mul_neg, mul_inv_cancel₀ hx1] ring have h : HasDerivAt (fun t : ℝ => t * log t + (1 - t) * log (1 - t)) _ x := h1.fun_add h2 convert h using 1 ring
    Causalean.Mathlib.Analysis.hasDerivAt_bernEntropy · Causalean/Mathlib/Analysis/BernoulliKL.lean:39
  • bernoulliKL_eq_bregman lemma — Bernoulli Kullback–Leibler divergence equals the Bregman remainder of the negative entropy function at the second probability.
    p q :
    ℝ
    hp0 :
    p ≠ 0
    hp1 :
    1 - p ≠ 0
    hq0 :
    q ≠ 0
    hq1 :
    1 - q ≠ 0
    p * log (p / q) + (1 - p) * log ((1 - p) / (1 - q))
    = bernD p - bernD q - (log q - log (1 - q)) * (p - q)
    Proof (Lean source)
    lemma bernoulliKL_eq_bregman {p q : ℝ} (hp0 : p ≠ 0) (hp1 : 1 - p ≠ 0) (hq0 : q ≠ 0) (hq1 : 1 - q ≠ 0) : p * log (p / q) + (1 - p) * log ((1 - p) / (1 - q)) = bernD p - bernD q - (log q - log (1 - q)) * (p - q) := by rw [Real.log_div hp0 hq0, Real.log_div hp1 hq1] unfold bernD ring
    Causalean.Mathlib.Analysis.bernoulliKL_eq_bregman · Causalean/Mathlib/Analysis/BernoulliKL.lean:185
Clip­Interval 3 core · 11 supporting Truncating (clipping, clamping, winsorising) a real number to a closed interval [a, b] is ubiquitous in estimation: propensity scores are clipped away from 0 and 1, outcomes and privatised statistics are clipped to a sym ★ abs_clipIcc_sub_le★ clipIcc_sub_sq_le

Clipping a real number into a closed interval

Truncating (clipping, clamping, winsorising) a real number to a closed interval [a, b] is ubiquitous in estimation: propensity scores are clipped away from 0 and 1, outcomes and privatised statistics are clipped to a symmetric band [-B, B], and so on. Every such argument needs the same four facts — the clipped value lies in the interval, values already inside are untouched, the map is 1-Lipschitz, and clipping never increases the distance (nor the squared distance) to any target that is itself inside the interval.

Mathlib proves the contraction property, but only for the subtype-valued projection Set.projIcc : ℝ → Set.Icc a b, which is awkward to use when the surrounding development works with plain reals. This file provides the real-valued companion clipIcc a b x = max a (min b x) (definitionally the underlying value of Set.projIcc) together with the facts above, so that a symmetric band [-B, B], an asymmetric propensity band [q, 1 - q], and either the max-outside or the min-outside spelling are all instances of one API.

def clipIcc reviewed
Causalean.Mathlib.Analysis

For two real endpoints and a real input, the clipped value is the larger of the first endpoint and the smaller of the second endpoint and the input. When the first endpoint does not exceed the second, it is the input pushed into their closed interval.

Definition (Lean source)
a b x :
ℝ
clipIcc a b x :
ℝ
max a (min b x)
Causalean.Mathlib.Analysis.clipIcc · Causalean/Mathlib/Analysis/ClipInterval.lean:35
lemma abs_clipIcc_sub_le reviewed
Causalean.Mathlib.Analysis

Clipping toward an in-interval target does not increase distance. If a real number lies in the closed interval from a to b, then for any real x, clipping x into that interval moves it no farther from the target than x itself was.

Formal statement
a :
ℝ
shared
b :
ℝ
shared
t :
ℝ
shared
ht :
t ∈ Icc a b
x :
ℝ
|clipIcc a b x - t| ≤ |x - t|
Proof (Lean source)
lemma abs_clipIcc_sub_le (ht : t ∈ Icc a b) (x : ℝ) : |clipIcc a b x - t| ≤ |x - t| := by simpa [clipIcc_eq_self ht] using abs_clipIcc_sub_clipIcc_le a b x t
Causalean.Mathlib.Analysis.abs_clipIcc_sub_le · Causalean/Mathlib/Analysis/ClipInterval.lean:83 · uses clipIcc
lemma clipIcc_sub_sq_le reviewed
Causalean.Mathlib.Analysis

Squared version: clipping toward an in-interval target does not increase squared distance. If a real number lies in the closed interval from a to b, then for any real x, the squared distance from the clipped value of x to the target is at most the squared distance from x itself to the target.

Formal statement
a :
ℝ
shared
b :
ℝ
shared
t :
ℝ
shared
ht :
t ∈ Icc a b
x :
ℝ
(clipIcc a b x - t) ^ 2 ≤ (x - t) ^ 2
Proof (Lean source)
lemma clipIcc_sub_sq_le (ht : t ∈ Icc a b) (x : ℝ) : (clipIcc a b x - t) ^ 2 ≤ (x - t) ^ 2 := by have h := abs_clipIcc_sub_le ht x calc (clipIcc a b x - t) ^ 2 = |clipIcc a b x - t| ^ 2 := (sq_abs _).symm _ ≤ |x - t| ^ 2 := by gcongr _ = (x - t) ^ 2 := sq_abs _
Causalean.Mathlib.Analysis.clipIcc_sub_sq_le · Causalean/Mathlib/Analysis/ClipInterval.lean:93 · uses clipIcc
11 supporting declarations (lemmas, instances)
  • coe_projIcc_eq_clipIcc lemma — Clipping into an interval is exactly Mathlib's projection onto that interval, read as a plain real number instead of as an element of the interval. This is the bridge that makes every fact about the projection available to a development that never leaves the reals.
    a :
    ℝ
    shared
    b :
    ℝ
    shared
    hab :
    a ≤ b
    x :
    ℝ
    (Set.projIcc a b hab x : ℝ) = clipIcc a b x
    Proof (Lean source)
    lemma coe_projIcc_eq_clipIcc (hab : a ≤ b) (x : ℝ) : (Set.projIcc a b hab x : ℝ) = clipIcc a b x := rfl
    Causalean.Mathlib.Analysis.coe_projIcc_eq_clipIcc · Causalean/Mathlib/Analysis/ClipInterval.lean:42
  • clipIcc_mem_Icc lemma — A clipped value always lies in the interval it was clipped to (provided the interval is nonempty, i.e. its left endpoint does not exceed its right endpoint).
    a :
    ℝ
    shared
    b :
    ℝ
    shared
    hab :
    a ≤ b
    x :
    ℝ
    clipIcc a b x ∈ Icc a b
    Proof (Lean source)
    lemma clipIcc_mem_Icc (hab : a ≤ b) (x : ℝ) : clipIcc a b x ∈ Icc a b := (projIcc a b hab x).2
    Causalean.Mathlib.Analysis.clipIcc_mem_Icc · Causalean/Mathlib/Analysis/ClipInterval.lean:48
  • clipIcc_eq_self lemma — Clipping leaves untouched any number that already lies inside the interval.
    a :
    ℝ
    shared
    b :
    ℝ
    shared
    x :
    ℝ
    shared
    hx :
    x ∈ Icc a b
    clipIcc a b x = x
    Proof (Lean source)
    lemma clipIcc_eq_self (hx : x ∈ Icc a b) : clipIcc a b x = x := by rw [clipIcc, min_eq_right hx.2, max_eq_right hx.1]
    Causalean.Mathlib.Analysis.clipIcc_eq_self · Causalean/Mathlib/Analysis/ClipInterval.lean:53
  • clipIcc_eq_min_max lemma — Clipping from below first and then from above gives the same answer as clipping from above first and then from below. This reconciles the two spellings of the same operation that occur in practice, max a (min b x) and min b (max a x).
    a :
    ℝ
    shared
    b :
    ℝ
    shared
    hab :
    a ≤ b
    x :
    ℝ
    clipIcc a b x = min b (max a x)
    Proof (Lean source)
    lemma clipIcc_eq_min_max (hab : a ≤ b) (x : ℝ) : clipIcc a b x = min b (max a x) := by rw [clipIcc, max_min_distrib_left, max_eq_right hab]
    Causalean.Mathlib.Analysis.clipIcc_eq_min_max · Causalean/Mathlib/Analysis/ClipInterval.lean:57
  • lipschitzWith_clipIcc lemma — Clipping is a contraction: two numbers are never pushed further apart by being clipped to a common interval.
    a b :
    ℝ
    Proof (Lean source)
    lemma lipschitzWith_clipIcc (a b : ℝ) : LipschitzWith 1 (clipIcc a b) := (LipschitzWith.id.const_min b).const_max a
    Causalean.Mathlib.Analysis.lipschitzWith_clipIcc · Causalean/Mathlib/Analysis/ClipInterval.lean:63
  • abs_clipIcc_sub_clipIcc_le lemma — Clipping two numbers to the same interval never increases the distance between them.
    a b x y :
    ℝ
    |clipIcc a b x - clipIcc a b y| ≤ |x - y|
    Proof (Lean source)
    lemma abs_clipIcc_sub_clipIcc_le (a b x y : ℝ) : |clipIcc a b x - clipIcc a b y| ≤ |x - y| := by simpa [Real.dist_eq] using (lipschitzWith_clipIcc a b).dist_le_mul x y
    Causalean.Mathlib.Analysis.abs_clipIcc_sub_clipIcc_le · Causalean/Mathlib/Analysis/ClipInterval.lean:68
  • abs_min_max_sub_min_max_le lemma — Capping from above and then flooring from below is a contraction as well: two numbers put through that order of operations are never pushed further apart. Unlike clipIcc_eq_min_max, this needs no assumption on the two thresholds, which is what makes it usable for a propensity band [q, 1 - q] whose definition carries no q ≤ 1/2 hypothesis.
    a b x y :
    ℝ
    |min b (max a x) - min b (max a y)| ≤ |x - y|
    Proof (Lean source)
    lemma abs_min_max_sub_min_max_le (a b x y : ℝ) : |min b (max a x) - min b (max a y)| ≤ |x - y| := by have h : LipschitzWith 1 (fun z : ℝ => min b (max a z)) := (LipschitzWith.id.const_max a).const_min b simpa [Real.dist_eq] using h.dist_le_mul x y
    Causalean.Mathlib.Analysis.abs_min_max_sub_min_max_le · Causalean/Mathlib/Analysis/ClipInterval.lean:73
  • continuous_clipIcc lemma — Clipping to a fixed interval is a continuous operation.
    a b :
    ℝ
    Proof (Lean source)
    @[fun_prop] lemma continuous_clipIcc (a b : ℝ) : Continuous (clipIcc a b) := continuous_const.max (continuous_const.min continuous_id)
    Causalean.Mathlib.Analysis.continuous_clipIcc · Causalean/Mathlib/Analysis/ClipInterval.lean:106
  • measurable_clipIcc lemma — Clipping to a fixed interval is measurable, so clipping a random variable again yields a random variable.
    a b :
    ℝ
    Proof (Lean source)
    @[fun_prop] lemma measurable_clipIcc (a b : ℝ) : Measurable (clipIcc a b) := (continuous_clipIcc a b).measurable
    Causalean.Mathlib.Analysis.measurable_clipIcc · Causalean/Mathlib/Analysis/ClipInterval.lean:111
  • abs_clipIcc_neg_le lemma — Clipping to a symmetric band around zero produces a value whose magnitude is at most the half-width of the band.
    B :
    ℝ
    shared
    hB :
    0 ≤ B
    x :
    ℝ
    |clipIcc (-B) B x| ≤ B
    Proof (Lean source)
    lemma abs_clipIcc_neg_le (hB : 0 ≤ B) (x : ℝ) : |clipIcc (-B) B x| ≤ B := abs_le.mpr (clipIcc_mem_Icc (by linarith) x)
    Causalean.Mathlib.Analysis.abs_clipIcc_neg_le · Causalean/Mathlib/Analysis/ClipInterval.lean:117
  • clipIcc_neg_eq_self lemma — Clipping to a symmetric band around zero leaves untouched any number whose magnitude is already within the half-width of the band.
    x :
    ℝ
    shared
    B :
    ℝ
    shared
    hx :
    |x| ≤ B
    clipIcc (-B) B x = x
    Proof (Lean source)
    lemma clipIcc_neg_eq_self (hx : |x| ≤ B) : clipIcc (-B) B x = x := clipIcc_eq_self (Set.mem_Icc.mpr (abs_le.mp hx))
    Causalean.Mathlib.Analysis.clipIcc_neg_eq_self · Causalean/Mathlib/Analysis/ClipInterval.lean:122
Convex­Projection 8 core · 25 supporting This module provides metric projection onto a nonempty closed convex subset of a real Hilbert space, together with its variational, contraction, continuity, and measurability properties. ★ loewnerProj_frobDist_le

Projection onto closed convex sets

This module provides metric projection onto a nonempty closed convex subset of a real Hilbert space, together with its variational, contraction, continuity, and measurability properties. It also specializes the construction to a Loewner interval of real matrices, using Frobenius distance, and supplies the associated matrix inequalities.

def convexProj reviewed
Causalean.Mathlib.Analysis

For a real Hilbert space and a target subset that is nonempty, closed, and convex, the metric projection assigns each point its nearest point in that target subset.

Definition (Lean source)
E :
Type u_1
shared
K :
Set E
hne :
K.Nonempty
hc :
hconv :
Convex ℝ K
convexProj K hne hc hconv :
E → E
fun x
=> choose (exists_norm_eq_iInf_of_complete_convex hne hc.isComplete hconv x)
Causalean.Mathlib.Analysis.convexProj · Causalean/Mathlib/Analysis/ConvexProjection.lean:39
def loewnerSet reviewed
Causalean.Mathlib.Analysis

Given a square matrix dimension and two real endpoints, the Loewner interval is the set of real square matrices for which (1) the matrix minus the lower endpoint times the identity is positive semidefinite, and (2) the upper endpoint times the identity minus the matrix is positive semidefinite.

Definition (Lean source)
p :
ℕ
c C :
ℝ
loewnerSet p c C :
Set (Matrix (Fin p) (Fin p) ℝ)
{G | (G - c • (1 : Matrix (Fin p) (Fin p) ℝ)).PosSemidef ∧ (C • (1 : Matrix (Fin p) (Fin p) ℝ) - G).PosSemidef}
Causalean.Mathlib.Analysis.loewnerSet · Causalean/Mathlib/Analysis/ConvexProjection.lean:133
def frobDist reviewed
Causalean.Mathlib.Analysis

For a square matrix dimension and two real square matrices, the Frobenius distance is the square root of the sum of squared entrywise differences between the two matrices.

Definition (Lean source)
p :
ℕ
shared
A B :
Matrix (Fin p) (Fin p) ℝ
frobDist A B :
ℝ
sqrt (∑ k : Fin p, ∑ l : Fin p, (A k l - B k l) ^ 2)
Causalean.Mathlib.Analysis.frobDist · Causalean/Mathlib/Analysis/ConvexProjection.lean:138
def mtx reviewed
Causalean.Mathlib.Analysis

For a square matrix dimension, the matrix vectorization linear equivalence identifies real square matrices of that dimension with Euclidean vectors indexed by ordered pairs of row and column coordinates.

Definition (Lean source)
p :
ℕ
mtx p :
Matrix (Fin p) (Fin p) ℝ ≃ₗ[ℝ] EuclideanSpace ℝ (Fin p × Fin p)
(LinearEquiv.curry ℝ ℝ (Fin p) (Fin p)).symm.trans (EuclideanSpace.equiv (Fin p × Fin p) ℝ).symm.toLinearEquiv
def mtxHomeo reviewed
Causalean.Mathlib.Analysis

For a square matrix dimension, the matrix vectorization homeomorphism identifies real square matrices of that dimension, with their usual topology, with Euclidean vectors indexed by ordered pairs of row and column coordinates.

Definition (Lean source)
p :
ℕ
mtxHomeo p :
Matrix (Fin p) (Fin p) ℝ ≃ₜ EuclideanSpace ℝ (Fin p × Fin p)
Homeomorph.piCurry.symm.trans (EuclideanSpace.equiv (Fin p × Fin p) ℝ).symm.toHomeomorph
Causalean.Mathlib.Analysis.mtxHomeo · Causalean/Mathlib/Analysis/ConvexProjection.lean:148
def loewnerProjAux reviewed
Causalean.Mathlib.Analysis

For ordered lower and upper eigenvalue bounds, this auxiliary map sends a real square matrix to its nearest matrix in the associated Loewner interval. It implements the projection through a Euclidean coordinate representation and is used by the total Loewner projection.

Definition (Lean source)
p :
ℕ
c C :
ℝ
hcC :
c ≤ C
loewnerProjAux p c C hcC :
Matrix (Fin p) (Fin p) ℝ → Matrix (Fin p) (Fin p) ℝ
fun G
=> (mtx p).symm (convexProj (mtx p '' loewnerSet p c C) ((loewnerSet_nonempty p c C hcC).image (mtx p)) (mtx_image_isClosed p c C) ((loewnerSet_convex p c C).linear_image (mtx p).toLinearMap) (mtx p G))
Causalean.Mathlib.Analysis.loewnerProjAux · Causalean/Mathlib/Analysis/ConvexProjection.lean:260
def loewnerProj reviewed
Causalean.Mathlib.Analysis

Given a square matrix dimension and two real endpoints, the Loewner projection maps each real square matrix to its nearest point, in Frobenius distance, in the corresponding Loewner interval when the endpoints are ordered; when they are reversed, it is the identity map.

Definition (Lean source)
p :
ℕ
c C :
ℝ
loewnerProj p c C :
Matrix (Fin p) (Fin p) ℝ → Matrix (Fin p) (Fin p) ℝ
if h : c ≤ C then loewnerProjAux p c C h else id
Causalean.Mathlib.Analysis.loewnerProj · Causalean/Mathlib/Analysis/ConvexProjection.lean:270
theorem loewnerProj_frobDist_le reviewed
Causalean.Mathlib.Analysis

Loewner projection decreases distance to each feasible target. For ordered interval endpoints c ≤ C, if a target matrix already lies in the Loewner interval [cI, CI], then projecting an arbitrary matrix onto that interval, in Frobenius geometry, does not increase its Frobenius distance to the in-interval target matrix.

Formal statement
p :
ℕ
shared
c :
ℝ
shared
C :
ℝ
shared
hcC :
c ≤ C
G S :
Matrix (Fin p) (Fin p) ℝ
hS :
S ∈ loewnerSet p c C
frobDist (loewnerProj p c C G) S ≤ frobDist G S
Proof (Lean source)
theorem loewnerProj_frobDist_le (hcC : c ≤ C) (G S : Matrix (Fin p) (Fin p) ℝ) (hS : S ∈ loewnerSet p c C) : frobDist (loewnerProj p c C G) S ≤ frobDist G S := by rw [frobDist_eq_norm, frobDist_eq_norm, loewnerProj, dif_pos hcC, loewnerProjAux] simp only [LinearEquiv.apply_symm_apply] exact convexProj_le_of_mem (mtx p '' loewnerSet p c C) ((loewnerSet_nonempty p c C hcC).image (mtx p)) (mtx_image_isClosed p c C) ((loewnerSet_convex p c C).linear_image (mtx p).toLinearMap) (mtx p G) (mtx p S) ⟨S, hS, rfl⟩
Causalean.Mathlib.Analysis.loewnerProj_frobDist_le · Causalean/Mathlib/Analysis/ConvexProjection.lean:287 · uses frobDist , loewnerProj , loewnerSet
25 supporting declarations (lemmas, instances)
Differential­Comparison 1 core · 0 supporting This file proves the real-analysis comparison underlying the self-bounding form of the Herbst argument. ★ centered_le_of_differential_inequality

A differential comparison below a linear pole

This file proves the real-analysis comparison underlying the self-bounding form of the Herbst argument. The domain is expressed by a * x < 1; unlike x < 1 / a, this also represents the intended unbounded nonnegative domain when a = 0.

theorem centered_le_of_differential_inequality reviewed
Causalean.Mathlib.Analysis

For a real function ψ and nonnegative coefficients a and b, suppose that ψ is differentiable at zero, is differentiable at every positive point below the linear pole, vanishes at zero, the coefficients are nonnegative, and its differential residual is at most b x². Then at a nonnegative point lam below the pole, the centered value of ψ is at most (a ψ'(0) + b) lam² / (1 - a lam).

Formal statement
ψ :
ℝ → ℝ
a b :
ℝ
hψ0 :
hψ :
∀ x
if
0 < x
and
a * x < 1
then
hzero :
ψ 0 = 0
ha :
0 ≤ a
hb :
0 ≤ b
hdiff :
∀ x
if
0 < x
and
a * x < 1
then
x * (1 - a * x) * deriv ψ x - ψ x ≤ b * x ^ 2
lam :
ℝ
hlam0 :
0 ≤ lam
hlam :
a * lam < 1
ψ lam - lam * deriv ψ 0 ≤ (a * deriv ψ 0 + b) * lam ^ 2 / (1 - a * lam)
Proof (Lean source)
theorem centered_le_of_differential_inequality {ψ : ℝ → ℝ} {a b : ℝ} (hψ0 : DifferentiableAt ℝ ψ 0) (hψ : ∀ x, 0 < x → a * x < 1 → DifferentiableAt ℝ ψ x) (hzero : ψ 0 = 0) (ha : 0 ≤ a) (hb : 0 ≤ b) (hdiff : ∀ x, 0 < x → a * x < 1 → x * (1 - a * x) * deriv ψ x - ψ x ≤ b * x ^ 2) {lam : ℝ} (hlam0 : 0 ≤ lam) (hlam : a * lam < 1) : ψ lam - lam * deriv ψ 0 ≤ (a * deriv ψ 0 + b) * lam ^ 2 / (1 - a * lam) := by have _hb : 0 ≤ b := hb by_cases hlamzero : lam = 0 · subst lam simp [hzero] have hlampos : 0 < lam := lt_of_le_of_ne hlam0 (Ne.symm hlamzero) let q : ℝ → ℝ := (fun x => (1 - a * x) * (ψ x / x) - deriv ψ 0) - fun x => b * x have hqdiff : DifferentiableOn ℝ q (Ioc 0 lam) := by intro x hx have hxpos : 0 < x := hx.1 have hax : a * x < 1 := lt_of_le_of_lt (mul_le_mul_of_nonneg_left hx.2 ha) hlam have hx0 : x ≠ 0 := ne_of_gt hxpos have hdiv : DifferentiableAt ℝ (fun y => ψ y / y) x := ((hψ x hxpos hax).hasDerivAt.fun_div (hasDerivAt_id x) hx0).differentiableAt have hfac : DifferentiableAt ℝ (fun y => 1 - a * y) x := by fun_prop have hlin : DifferentiableAt ℝ (fun y => b * y) x := by fun_prop exact ((hfac.mul hdiv).sub_const _).sub hlin |>.differentiableWithinAt have hqderiv : ∀ x ∈ interior (Ioc (0 : ℝ) lam), deriv q x ≤ 0 := by intro x hx have hxmem : x ∈ Ioc (0 : ℝ) lam := interior_subset hx have hxpos : 0 < x := hxmem.1 have hax : a * x < 1 := lt_of_le_of_lt (mul_le_mul_of_nonneg_left hxmem.2 ha) hlam have hx0 : x ≠ 0 := ne_of_gt hxpos have hdiv := (hψ x hxpos hax).hasDerivAt.fun_div (hasDerivAt_id x) hx0 have hfac := (hasDerivAt_const x 1).sub ((hasDerivAt_id x).const_mul a) have hlin := (hasDerivAt_id x).const_mul b have hdq : HasDerivAt q (-a * (ψ x / x) + (1 - a * x) * ((deriv ψ x * x - ψ x) / x ^ 2) - b) x := by have hraw := ((hfac.mul hdiv).sub_const (deriv ψ 0)).sub hlin simpa [q] using hraw have halg : -a * (ψ x / x) + (1 - a * x) * ((deriv ψ x * x - ψ x) / x ^ 2) - b = (x * (1 - a * x) * deriv ψ x - ψ x) / x ^ 2 - b := by field_simp [hx0] ring rw [hdq.deriv, halg] have hx2 : 0 < x ^ 2 := sq_pos_of_pos hxpos apply sub_nonpos.mpr apply (div_le_iff₀ hx2).2 simpa [mul_assoc] using hdiff x hxpos hax have hqanti : AntitoneOn q (Ioc 0 lam) := by apply antitoneOn_of_deriv_nonpos (convex_Ioc 0 lam) · exact hqdiff.continuousOn · exact hqdiff.mono interior_subset · exact hqderiv have hlimSlope : Tendsto (fun x => ψ x / x) (𝓝[>] (0 : ℝ)) (𝓝 (deriv ψ 0)) := by have hslope := hψ0.hasDerivAt.tendsto_slope_zero_right simpa [hzero, div_eq_inv_mul, mul_comm] using hslope have hid : Tendsto (fun x : ℝ => x) (𝓝[>] 0) (𝓝 0) := tendsto_nhdsWithin_of_tendsto_nhds tendsto_id have hfaclim : Tendsto (fun x : ℝ => 1 - a * x) (𝓝[>] 0) (𝓝 1) := by convert tendsto_const_nhds.sub (tendsto_const_nhds.mul hid) using 1 all_goals simp have hlinlim : Tendsto (fun x : ℝ => b * x) (𝓝[>] 0) (𝓝 0) := by convert tendsto_const_nhds.mul hid using 1 all_goals simp have hconstlim : Tendsto (fun _ : ℝ => deriv ψ 0) (𝓝[>] 0) (𝓝 (deriv ψ 0)) := tendsto_const_nhds have hlimQ : Tendsto q (𝓝[>] (0 : ℝ)) (𝓝 0) := by change Tendsto (fun x => (1 - a * x) * (ψ x / x) - deriv ψ 0 - b * x) (𝓝[>] (0 : ℝ)) (𝓝 0) simpa using ((hfaclim.mul hlimSlope).sub hconstlim).sub hlinlim have hevent : ∀ᶠ x in 𝓝[>] (0 : ℝ), q lam ≤ q x := by filter_upwards [self_mem_nhdsWithin, (eventually_lt_nhds hlampos).filter_mono inf_le_left] with x hxpos hxlam exact hqanti ⟨hxpos, le_of_lt hxlam⟩ ⟨hlampos, le_rfl⟩ (le_of_lt hxlam) have hqle : q lam ≤ 0 := ge_of_tendsto hlimQ hevent dsimp [q] at hqle have hden : 0 < 1 - a * lam := sub_pos.mpr hlam apply (le_div_iff₀ hden).2 field_simp [hlamzero] at hqle nlinarith [hb]
Causalean.Mathlib.Analysis.centered_le_of_differential_inequality · Causalean/Mathlib/Analysis/DifferentialComparison.lean:32
Frechet­Functional­Equation 1 core · 0 supporting Fréchet-style finite-difference arguments appear in classical proofs of independence characterization theorems. ★ affine_of_continuous_of_second_diff_zero

Fréchet's functional equation (degree-one case)

Fréchet-style finite-difference arguments appear in classical proofs of independence characterization theorems. This file proves the foundational degree-one case: a continuous function with vanishing second forward difference is affine (affine_of_continuous_of_second_diff_zero).

The argument is classical: a vanishing second difference makes f midpoint-affine; subtracting f 0 yields an additive function; a continuous additive map of real vector spaces is ℝ-linear (AddMonoidHom.toRealLinearMap).

theorem affine_of_continuous_of_second_diff_zero reviewed
Causalean.Mathlib.Analysis

Fréchet functional equation, degree one. If f is a continuous function from the reals into a normed real vector space and its second forward difference vanishes: f(x+2s) + f(x) = 2·f(x+s) for all real x and s, then f is affine — there exist vectors a and b such that f(x) = a + x·b for every real x.

Formal statement
E :
Type u_1
ℝ → E
shared
hf :
h2 :
∀ x s : ℝ, f (x + s + s) + f x = f (x + s) + f (x + s)
∃ a b : E, ∀ x, f x = a + x • b
Proof (Lean source)
theorem affine_of_continuous_of_second_diff_zero {f : ℝ → E} (hf : Continuous f) (h2 : ∀ x s : ℝ, f (x + s + s) + f x = f (x + s) + f (x + s)) : ∃ a b : E, ∀ x, f x = a + x • b := by -- Midpoint identity. have hmid : ∀ p q : ℝ, f p + f q = f ((p + q) / 2) + f ((p + q) / 2) := by intro p q have h := h2 p ((q - p) / 2) rw [show p + (q - p) / 2 + (q - p) / 2 = q from by ring, show p + (q - p) / 2 = (p + q) / 2 from by ring] at h rw [add_comm (f p) (f q)]; exact h -- Doubling identity. have hdouble : ∀ u : ℝ, f (u + u) + f 0 = f u + f u := by intro u; simpa using h2 0 u -- Additivity of `x ↦ f x - f 0`. have hadd : ∀ a b : ℝ, f (a + b) - f 0 = (f a - f 0) + (f b - f 0) := by intro a b have hm := hmid (a + a) (b + b) rw [show (a + a + (b + b)) / 2 = a + b from by ring] at hm have ha := hdouble a have hb := hdouble b -- `(f a + f a) + (f b + f b) = (f (a+b) + f (a+b)) + (f 0 + f 0)` have hsum : (f a + f a) + (f b + f b) = (f (a + b) + f (a + b)) + (f 0 + f 0) := by rw [← ha, ← hb, show (f (a + a) + f 0) + (f (b + b) + f 0) = (f (a + a) + f (b + b)) + (f 0 + f 0) from by abel, hm] -- Cancel the doubling via the `ℝ`-action. have hXY : f a + f b = f (a + b) + f 0 := by have h2s : (2 : ℝ) • (f a + f b) = (2 : ℝ) • (f (a + b) + f 0) := by rw [two_smul, two_smul, show (f a + f b) + (f a + f b) = (f a + f a) + (f b + f b) from by abel, show (f (a + b) + f 0) + (f (a + b) + f 0) = (f (a + b) + f (a + b)) + (f 0 + f 0) from by abel, hsum] exact smul_right_injective E two_ne_zero h2s have hfab : f (a + b) = (f a + f b) - f 0 := eq_sub_of_add_eq hXY.symm rw [hfab]; abel -- Continuous additive ⟹ `ℝ`-linear. have hgcont : Continuous (fun x => f x - f 0) := hf.sub continuous_const let φ : ℝ →+ E := AddMonoidHom.mk' (fun x => f x - f 0) hadd let L : ℝ →L[ℝ] E := φ.toRealLinearMap hgcont have hLx : ∀ x, L x = f x - f 0 := by intro x have : ⇑L = ⇑φ := φ.coe_toRealLinearMap hgcont rw [this]; rfl refine ⟨f 0, L 1, fun x => ?_⟩ have hlin : f x - f 0 = x • L 1 := by rw [← hLx x, show L x = L (x • (1 : ℝ)) from by rw [smul_eq_mul, mul_one], map_smul] rw [← hlin]; abel
Causalean.Mathlib.Analysis.affine_of_continuous_of_second_diff_zero · Causalean/Mathlib/Analysis/FrechetFunctionalEquation.lean:30
Gradient­Coord 1 core · 0 supporting A single bridge lemma: the a-th coordinate of the (Riesz) gradient of a real-valued function on a finite-dimensional Euclidean space equals the ordinary one-variable derivative of the function along the a-th coordinate l ★ gradient_coord_eq_deriv

Coordinates of a Euclidean gradient as directional derivatives

A single bridge lemma: the a-th coordinate of the (Riesz) gradient of a real-valued function on a finite-dimensional Euclidean space equals the ordinary one-variable derivative of the function along the a-th coordinate line. This is the standard tool for computing a gradient coordinate by coordinate — reduce each entry to a deriv of a one-parameter restriction, which the univariate calculus API can then evaluate.

lemma gradient_coord_eq_deriv reviewed
Causalean.Mathlib

Gradient coordinate as a directional derivative. For a real-valued function f on a finite-dimensional Euclidean space that is differentiable at the point x, the a-th coordinate of its gradient at x equals the derivative at 0 of the one-variable restriction t ↦ f(x + t·eₐ) along the a-th standard basis direction.

Formal statement
ι :
f :
EuclideanSpace ℝ ι → ℝ
x :
a :
ι
hf :
(gradient f x) a = deriv (fun t : ℝ => f (x + t • single a (1 : ℝ))) 0
Proof (Lean source)
lemma gradient_coord_eq_deriv {ι : Type*} [Fintype ι] [DecidableEq ι] (f : EuclideanSpace ℝ ι → ℝ) (x : EuclideanSpace ℝ ι) (a : ι) (hf : DifferentiableAt ℝ f x) : (gradient f x) a = deriv (fun t : ℝ => f (x + t • single a (1 : ℝ))) 0 := by have hinner : ⟪EuclideanSpace.single a (1 : ℝ), gradient f x⟫_ℝ = fderiv ℝ f x (single a (1 : ℝ)) := by rw [real_inner_comm] exact inner_gradient_left (𝕜 := ℝ) (f := f) (x := x) (y := single a (1 : ℝ)) have hline : HasDerivAt (fun t : ℝ => x + t • single a (1 : ℝ)) (single a (1 : ℝ)) 0 := by simpa using (((hasDerivAt_id (0 : ℝ)).smul_const (single a (1 : ℝ))).const_add x) have hderiv : HasDerivAt (fun t : ℝ => f (x + t • single a (1 : ℝ))) (fderiv ℝ f x (single a (1 : ℝ))) 0 := by have hf' : HasFDerivAt f (fderiv ℝ f x) (x + (0 : ℝ) • single a (1 : ℝ)) := by simpa using hf.hasFDerivAt exact hf'.comp_hasDerivAt (0 : ℝ) hline calc (gradient f x) a = ⟪EuclideanSpace.single a (1 : ℝ), gradient f x⟫_ℝ := by have hs : ⟪EuclideanSpace.single a (1 : ℝ), gradient f x⟫_ℝ = (gradient f x) a := by simpa using EuclideanSpace.inner_single_left a (1 : ℝ) (gradient f x) exact hs.symm _ = fderiv ℝ f x (single a (1 : ℝ)) := hinner _ = deriv (fun t : ℝ => f (x + t • single a (1 : ℝ))) 0 := hderiv.deriv.symm
Causalean.Mathlib.gradient_coord_eq_deriv · Causalean/Mathlib/Analysis/GradientCoord.lean:30
Half­Disc­Polar 3 core · 14 supporting This module derives weighted polar-integration formulas on upper half-discs, including radial mass identities, odd-angular cancellation, quadratic angular moments, and translation-invariant variants. ★ halfDisc_weighted_polar_integral

Polar integration and cancellation on half-discs

This module derives weighted polar-integration formulas on upper half-discs, including radial mass identities, odd-angular cancellation, quadratic angular moments, and translation-invariant variants.

def planarRadius reviewed
Causalean.Mathlib.Analysis

For a point in the real coordinate plane, the planar radius is its Euclidean distance from the origin, namely x2+y2\sqrt{x^2+y^2} for coordinates (x,y)(x,y).

Definition (Lean source)
z :
ℝ × ℝ
planarRadius z :
ℝ
sqrt (z.1 ^ 2 + z.2 ^ 2)
Causalean.Mathlib.Analysis.planarRadius · Causalean/Mathlib/Analysis/HalfDiscPolar.lean:21
def planarAngle reviewed
Causalean.Mathlib.Analysis

For a point in the real coordinate plane, the planar angle is the angular coordinate assigned by the polar-coordinate chart.

Definition (Lean source)
z :
ℝ × ℝ
planarAngle z :
ℝ
(polarCoord z).2
Causalean.Mathlib.Analysis.planarAngle · Causalean/Mathlib/Analysis/HalfDiscPolar.lean:36
lemma halfDisc_weighted_polar_integral reviewed
Causalean.Mathlib.Analysis

For radial and angular weight functions g and h and a radius r, the integral of the product g(radius)·h(angle) over the open upper half-disc of radius r factors as the product of the radial integral ∫ s·g(s) ds over (0, r] and the angular integral ∫ h(θ) dθ over (0, π).

Formal statement
g h :
ℝ → ℝ
r :
ℝ
(∫ z : ℝ × ℝ in {z | 0 < z.2 ∧ planarRadius z ≤ r}, g (planarRadius z) * h (planarAngle z))
= (∫ s : ℝ in Ioc 0 r, s * g s) * (∫ θ : ℝ in Ioo 0 pi, h θ)
Proof (Lean source)
-- @node: halfDisc_weighted_polar_integral lemma halfDisc_weighted_polar_integral (g h : ℝ → ℝ) (r : ℝ) : (∫ z : ℝ × ℝ in {z | 0 < z.2 ∧ planarRadius z ≤ r}, g (planarRadius z) * h (planarAngle z)) = (∫ s : ℝ in Ioc 0 r, s * g s) * (∫ θ : ℝ in Ioo 0 Real.pi, h θ) := by let D : Set (ℝ × ℝ) := {z | 0 < z.2 ∧ planarRadius z ≤ r} let E : Set (ℝ × ℝ) := Ioc 0 r ×ˢ Ioo 0 Real.pi have hD : MeasurableSet D := by exact (measurableSet_lt measurable_const measurable_snd).inter (measurableSet_le ((measurable_fst.pow_const 2).add (measurable_snd.pow_const 2)).sqrt measurable_const) have hE : MeasurableSet E := measurableSet_Ioc.prod measurableSet_Ioo change (∫ z : ℝ × ℝ in D, g (planarRadius z) * h (planarAngle z)) = _ rw [← integral_indicator hD, ← integral_comp_polarCoord_symm] rw [show (∫ p in polarCoord.target, p.1 • D.indicator (fun z => g (planarRadius z) * h (planarAngle z)) (polarCoord.symm p)) = ∫ p in E, (p.1 * g p.1) * h p.2 by rw [← integral_indicator polarCoord.open_target.measurableSet, ← integral_indicator hE] apply integral_congr_ae filter_upwards with p by_cases hp : p ∈ polarCoord.target · have hptarget := hp simp only [polarCoord_target, mem_prod, mem_Ioi, mem_Ioo] at hp have hinv := polarCoord.right_inv hp have hrs : planarRadius (polarCoord.symm p) = p.1 := congrArg Prod.fst hinv have htheta : planarAngle (polarCoord.symm p) = p.2 := congrArg Prod.snd hinv have hsin : 0 < sin p.2 ↔ 0 < p.2 := by constructor · intro hs by_contra hn exact (not_lt_of_ge (Real.sin_nonpos_of_nonpos_of_neg_pi_le (le_of_not_gt hn) hp.2.1.le)) hs · intro htheta0 exact Real.sin_pos_of_pos_of_lt_pi htheta0 hp.2.2 have hy : 0 < p.1 * sin p.2 ↔ 0 < p.2 := (mul_pos_iff_of_pos_left hp.1).trans hsin have hmem : polarCoord.symm p ∈ D ↔ p ∈ E := by change (0 < (polarCoord.symm p).2 ∧ planarRadius (polarCoord.symm p) ≤ r) ↔ (0 < p.1 ∧ p.1 ≤ r) ∧ 0 < p.2 ∧ p.2 < Real.pi rw [hrs] simp only [polarCoord_symm_apply] rw [hy] constructor · rintro ⟨hptheta, hpr⟩ exact ⟨⟨hp.1, hpr⟩, hptheta, hp.2.2⟩ · rintro ⟨⟨_, hpr⟩, hptheta0, _⟩ exact ⟨hptheta0, hpr⟩ by_cases hmemD : polarCoord.symm p ∈ D · rw [indicator_of_mem hptarget, indicator_of_mem hmemD, indicator_of_mem (hmem.mp hmemD), hrs, htheta] simp [smul_eq_mul] ring · rw [indicator_of_mem hptarget] simp only [indicator] rw [if_neg hmemD, if_neg (mt hmem.mpr hmemD)] simp · have hpE : p ∉ E := by rintro ⟨⟨hp0, _⟩, hptheta0, hpthetapi⟩ apply hp simp only [polarCoord_target, mem_prod, mem_Ioi, mem_Ioo] exact ⟨hp0, lt_trans (neg_lt_zero.mpr Real.pi_pos) hptheta0, hpthetapi⟩ simp only [indicator] rw [if_neg hp, if_neg hpE] ] change (∫ p in Ioc 0 r ×ˢ Ioo 0 Real.pi, (p.1 * g p.1) * h p.2) = _ rw [Measure.volume_eq_prod] exact setIntegral_prod_mul (μ := volume) (ν := volume) (fun s : ℝ => s * g s) h (Ioc 0 r) (Ioo 0 Real.pi)
Causalean.Mathlib.Analysis.halfDisc_weighted_polar_integral · Causalean/Mathlib/Analysis/HalfDiscPolar.lean:60 · uses planarAngle , planarRadius
14 supporting declarations (lemmas, instances)
Line­Second­Deriv 2 core · 6 supporting For f : E → ℝ and a direction d : E, the restriction of f to the line s ↦ f (q + s • d) has first and second derivatives expressible as directional derivatives of f at the moving base point q + t • d: * deriv_line : deri ★ convexOn_deriv2_nonneg

Second directional derivative along an affine line

For f : E → ℝ and a direction d : E, the restriction of f to the line s ↦ f (q + s • d) has first and second derivatives expressible as directional derivatives of f at the moving base point q + t • d:

* deriv_line : deriv (fun s => f (q + s • d)) t = fderiv ℝ f (q + t • d) d * deriv_deriv_line: `deriv (deriv fun s => f (q + s • d)) t = secondDirDeriv f d (q + t • d)`

where secondDirDeriv f d q = fderiv ℝ (fun x => fderiv ℝ f x d) q d. Two consequences make secondDirDeriv usable as a curvature modulus over a constraint set:

* continuous_secondDirDeriv : it is continuous in the base point (so it is bounded on a compact set, giving the BddAbove needed for a ciSup), and * convexOn_deriv2_nonneg : a convex C² function of one variable has nonnegative second derivative at interior points (so such a modulus is nonnegative).

Mathlib has convexOn_of_deriv2_nonneg (sufficiency) but not the converse used here.

The statements are objective-agnostic: callers supply ContDiff ℝ 2 f and read off the directional curvature. This is the substrate behind the dirModulus / EnvelopeLineC2Data discharge for the reciprocal-product variance envelope.

def secondDirDeriv reviewed
Causalean.Mathlib.Analysis

For a real normed vector space, a real-valued function on that space, a direction vector, and a base point, the second directional derivative is the directional derivative at the base point, in the given direction, of the function mapping a point to the directional derivative of the original function in that direction.

Definition (Lean source)
E :
Type u_1
shared
f :
E → ℝ
d :
E
q :
E
secondDirDeriv f d q :
ℝ
fderiv ℝ (fun x => fderiv ℝ f x d) q d
Causalean.Mathlib.Analysis.secondDirDeriv · Causalean/Mathlib/Analysis/LineSecondDeriv.lean:45
lemma convexOn_deriv2_nonneg reviewed
Causalean.Mathlib.Analysis

A convex function of one real variable has nonnegative second derivative at interior points of its domain. If g is convex on the set S, differentiable at every point of S, x lies in the interior of S, and the derivative of g is itself differentiable at x, then the second derivative of g at x is nonnegative.

Formal statement
S :
Set ℝ
g :
ℝ → ℝ
x :
ℝ
hconv :
ConvexOn ℝ S g
hdiff :
∀ y ∈ S, DifferentiableAt ℝ g y
hx :
x ∈ interior S
hdd :
0 ≤ deriv (deriv g) x
Proof (Lean source)
lemma convexOn_deriv2_nonneg {S : Set ℝ} {g : ℝ → ℝ} {x : ℝ} (hconv : ConvexOn ℝ S g) (hdiff : ∀ y ∈ S, DifferentiableAt ℝ g y) (hx : x ∈ interior S) (hdd : DifferentiableAt ℝ (deriv g) x) : 0 ≤ deriv (deriv g) x := by have hacc : AccPt x (𝓟 S) := by have hacc' : AccPt x (𝓟 (interior S)) := by simpa using (PerfectSpace.univ_preperfect.open_inter isOpen_interior x ⟨hx, mem_univ x⟩) exact hacc'.mono (principal_mono.mpr interior_subset) exact hdd.hasDerivAt.hasDerivWithinAt.nonneg_of_monotoneOn hacc (hconv.monotoneOn_deriv hdiff)
Causalean.Mathlib.Analysis.convexOn_deriv2_nonneg · Causalean/Mathlib/Analysis/LineSecondDeriv.lean:101
6 supporting declarations (lemmas, instances)
Log­Ratio­Stability 6 core · 6 supporting This module defines explicit uniform C¹ and C² control on a set. ★ uniformC1On_logRatio★ logRatioDerivative_fixedSign_open_C1

Uniform C1 stability of positive log-ratio derivatives

This module defines explicit uniform C¹ and C² control on a set. It proves continuity of reciprocal, quotient, logarithm, and the within-derivative of a positive log ratio under uniform C¹ convergence, then packages openness of a strict fixed-sign derivative margin on a compact real interval.

def UniformC1On reviewed
Causalean.Mathlib.Analysis

Uniform C¹ convergence on a real set means uniform convergence of both function values and their first within-derivatives.

Definition (Lean source)
K :
Set ℝ
f :
ℕ → ℝ → ℝ
g :
ℝ → ℝ
UniformC1On K f g :
Prop
clause 2
TendstoUniformlyOn (fun n x ↦ derivWithin (f n) K x) (fun x ↦ derivWithin g K x) atTop K
Causalean.Mathlib.Analysis.UniformC1On · Causalean/Mathlib/Analysis/LogRatioStability.lean:40
def C1CloseOn reviewed
Causalean.Mathlib.Analysis

Two real functions are uniformly C¹-close on a set when both values and first within-derivatives differ by less than the same radius everywhere on the set.

Definition (Lean source)
K :
Set ℝ
ε :
ℝ
f g :
ℝ → ℝ
C1CloseOn K ε f g :
Prop
clause 1
x ∈ K :
|f x - g x| < ε
clause 2
x ∈ K :
|derivWithin f K x - derivWithin g K x| < ε
Causalean.Mathlib.Analysis.C1CloseOn · Causalean/Mathlib/Analysis/LogRatioStability.lean:46
def C2CloseOn reviewed
Causalean.Mathlib.Analysis

Two real functions are uniformly C²-close when they are uniformly C¹-close and their second within-derivatives differ by less than the same radius.

Definition (Lean source)
K :
Set ℝ
ε :
ℝ
f g :
ℝ → ℝ
C2CloseOn K ε f g :
Prop
clause 1
C1CloseOn K ε f g
clause 2
x ∈ K :
|derivWithin (fun y ↦ derivWithin f K y) K x
- derivWithin (fun y ↦ derivWithin g K y) K x| < ε
Causalean.Mathlib.Analysis.C2CloseOn · Causalean/Mathlib/Analysis/LogRatioStability.lean:52
def logRatio reviewed
Causalean.Mathlib.Analysis

The log ratio of q to p is the pointwise function x ↦ log (q x / p x).

Definition (Lean source)
q p :
ℝ → ℝ
x :
ℝ
logRatio q p x :
ℝ
log (q x / p x)
Causalean.Mathlib.Analysis.logRatio · Causalean/Mathlib/Analysis/LogRatioStability.lean:60
theorem uniformC1On_logRatio reviewed
Causalean.Mathlib.Analysis

On a nondegenerate compact interval with a positive common lower bound, suppose every approximating numerator and denominator is differentiable, both limiting functions are continuously differentiable, the numerators and denominators converge uniformly in C¹, and the whole families and their limits obey the common lower bound. Then the corresponding log ratios converge uniformly in C¹.

Formal statement
a b m :
ℝ
hab :
a < b
hm :
0 < m
q p :
ℕ → ℝ → ℝ
q₀ p₀ :
ℝ → ℝ
hqdiff :
∀ n, DifferentiableOn ℝ (q n) (Icc a b)
hpdiff :
∀ n, DifferentiableOn ℝ (p n) (Icc a b)
hq₀diff :
ContDiffOn ℝ 1 q₀ (Icc a b)
hp₀diff :
ContDiffOn ℝ 1 p₀ (Icc a b)
hqconv :
UniformC1On (Icc a b) q q₀
hpconv :
UniformC1On (Icc a b) p p₀
hqlower :
∀ n x
if
x ∈ Icc a b
then
m ≤ q n x
hplower :
∀ n x
if
x ∈ Icc a b
then
m ≤ p n x
hq₀lower :
∀ x
if
x ∈ Icc a b
then
m ≤ q₀ x
hp₀lower :
∀ x
if
x ∈ Icc a b
then
m ≤ p₀ x
UniformC1On (Icc a b) (fun n ↦ logRatio (q n) (p n)) (logRatio q₀ p₀)
Proof (Lean source)
theorem uniformC1On_logRatio {a b m : ℝ} (hab : a < b) (hm : 0 < m) {q p : ℕ → ℝ → ℝ} {q₀ p₀ : ℝ → ℝ} (hqdiff : ∀ n, DifferentiableOn ℝ (q n) (Icc a b)) (hpdiff : ∀ n, DifferentiableOn ℝ (p n) (Icc a b)) (hq₀diff : ContDiffOn ℝ 1 q₀ (Icc a b)) (hp₀diff : ContDiffOn ℝ 1 p₀ (Icc a b)) (hqconv : UniformC1On (Icc a b) q q₀) (hpconv : UniformC1On (Icc a b) p p₀) (hqlower : ∀ n x, x ∈ Icc a b → m ≤ q n x) (hplower : ∀ n x, x ∈ Icc a b → m ≤ p n x) (hq₀lower : ∀ x, x ∈ Icc a b → m ≤ q₀ x) (hp₀lower : ∀ x, x ∈ Icc a b → m ≤ p₀ x) : UniformC1On (Icc a b) (fun n ↦ logRatio (q n) (p n)) (logRatio q₀ p₀) := by have hqpos : ∀ n x, x ∈ Icc a b → 0 < q n x := fun n x hx ↦ hm.trans_le (hqlower n x hx) have hppos : ∀ n x, x ∈ Icc a b → 0 < p n x := fun n x hx ↦ hm.trans_le (hplower n x hx) have hq₀pos : ∀ x, x ∈ Icc a b → 0 < q₀ x := fun x hx ↦ hm.trans_le (hq₀lower x hx) have hp₀pos : ∀ x, x ∈ Icc a b → 0 < p₀ x := fun x hx ↦ hm.trans_le (hp₀lower x hx) have hsub : ∀ {u v : ℕ → ℝ → ℝ} {u₀ v₀ : ℝ → ℝ}, TendstoUniformlyOn u u₀ atTop (Icc a b) → TendstoUniformlyOn v v₀ atTop (Icc a b) → TendstoUniformlyOn (fun n x ↦ u n x - v n x) (fun x ↦ u₀ x - v₀ x) atTop (Icc a b) := by intro u v u₀ v₀ hu hv rw [tendstoUniformlyOn_atTop_iff_abs_sub_lt] at hu hv ⊢ intro ε hε obtain ⟨Nu, hNu⟩ := hu (ε / 2) (by positivity) obtain ⟨Nv, hNv⟩ := hv (ε / 2) (by positivity) refine ⟨max Nu Nv, fun n hn x hx ↦ ?_⟩ calc |(u n x - v n x) - (u₀ x - v₀ x)| = |(u n x - u₀ x) - (v n x - v₀ x)| := by ring_nf _ ≤ |u n x - u₀ x| + |v n x - v₀ x| := by simpa only [sub_eq_add_neg, Real.norm_eq_abs, norm_neg] using norm_add_le (u n x - u₀ x) (-(v n x - v₀ x)) _ < ε / 2 + ε / 2 := add_lt_add (hNu n (le_trans (le_max_left _ _) hn) x hx) (hNv n (le_trans (le_max_right _ _) hn) x hx) _ = ε := by ring have hqlog := uniformlyOn_log_of_lowerBound hm hqconv.1 hqlower hq₀lower have hplog := uniformlyOn_log_of_lowerBound hm hpconv.1 hplower hp₀lower have hvalue := hsub hqlog hplog have hqderiv_cont : ContinuousOn (fun x ↦ derivWithin q₀ (Icc a b) x) (Icc a b) := hq₀diff.continuousOn_derivWithin (uniqueDiffOn_Icc hab) (by norm_num) have hpderiv_cont : ContinuousOn (fun x ↦ derivWithin p₀ (Icc a b) x) (Icc a b) := hp₀diff.continuousOn_derivWithin (uniqueDiffOn_Icc hab) (by norm_num) have hqquot := uniformlyOn_div_of_lowerBound isCompact_Icc hm hqconv.2 hqconv.1 hqderiv_cont hqlower hq₀lower have hpquot := uniformlyOn_div_of_lowerBound isCompact_Icc hm hpconv.2 hpconv.1 hpderiv_cont hplower hp₀lower rw [tendstoUniformlyOn_atTop_iff_abs_sub_lt] at hvalue have hderiv := hsub hqquot hpquot rw [tendstoUniformlyOn_atTop_iff_abs_sub_lt] at hderiv refine ⟨(tendstoUniformlyOn_atTop_iff_abs_sub_lt _ _ _).2 ?_, (tendstoUniformlyOn_atTop_iff_abs_sub_lt _ _ _).2 ?_⟩ · intro ε hε obtain ⟨N, hN⟩ := hvalue ε hε refine ⟨N, fun n hn x hx ↦ ?_⟩ change |log (q n x / p n x) - log (q₀ x / p₀ x)| < ε rw [Real.log_div (hqpos n x hx).ne' (hppos n x hx).ne', Real.log_div (hq₀pos x hx).ne' (hp₀pos x hx).ne'] exact hN n hn x hx · intro ε hε obtain ⟨N, hN⟩ := hderiv ε hε refine ⟨N, fun n hn x hx ↦ ?_⟩ change |derivWithin (logRatio (q n) (p n)) (Icc a b) x - derivWithin (logRatio q₀ p₀) (Icc a b) x| < ε rw [derivWithin_logRatio hab (hqdiff n) (hpdiff n) (hqpos n) (hppos n) hx, derivWithin_logRatio hab (hq₀diff.differentiableOn (by norm_num)) (hp₀diff.differentiableOn (by norm_num)) hq₀pos hp₀pos hx] exact hN n hn x hx
Causalean.Mathlib.Analysis.uniformC1On_logRatio · Causalean/Mathlib/Analysis/LogRatioStability.lean:192 · uses UniformC1On , logRatio
theorem logRatioDerivative_fixedSign_open_C1 reviewed
Causalean.Mathlib.Analysis

A nondegenerate compact interval and positive lower and derivative margins, two continuously differentiable center functions, their shared lower bounds, a chosen orientation, and a derivative margin in that orientation ensure a positive uniform C¹ neighborhood in which both perturbed functions stay positive and their log-ratio derivative retains that orientation.

Formal statement
a b m margin :
ℝ
hab :
a < b
hm :
0 < m
hmargin :
0 < margin
q p :
ℝ → ℝ
hq :
ContDiffOn ℝ 1 q (Icc a b)
hp :
ContDiffOn ℝ 1 p (Icc a b)
hqlower :
∀ x ∈ Icc a b, m ≤ q x
hplower :
∀ x ∈ Icc a b, m ≤ p x
sign :
ℝ
hsign :
sign = 1 ∨ sign = -1
hfixed :
∀ x ∈ Icc a b, margin ≤ sign * derivWithin (logRatio q p) (Icc a b) x
∃ ε > 0,
∀ q' p' : ℝ → ℝ,
DifferentiableOn ℝ q' (Icc a b) → DifferentiableOn ℝ p' (Icc a b) → C1CloseOn (Icc a b) ε q' q → C1CloseOn (Icc a b) ε p' p → (∀ x ∈ Icc a b, 0 < q' x ∧ 0 < p' x ∧ 0 < sign * derivWithin (logRatio q' p') (Icc a b) x)
Proof (Lean source)
theorem logRatioDerivative_fixedSign_open_C1 {a b m margin : ℝ} (hab : a < b) (hm : 0 < m) (hmargin : 0 < margin) {q p : ℝ → ℝ} (hq : ContDiffOn ℝ 1 q (Icc a b)) (hp : ContDiffOn ℝ 1 p (Icc a b)) (hqlower : ∀ x ∈ Icc a b, m ≤ q x) (hplower : ∀ x ∈ Icc a b, m ≤ p x) (sign : ℝ) (hsign : sign = 1 ∨ sign = -1) (hfixed : ∀ x ∈ Icc a b, margin ≤ sign * derivWithin (logRatio q p) (Icc a b) x) : ∃ ε > 0, ∀ q' p' : ℝ → ℝ, DifferentiableOn ℝ q' (Icc a b) → DifferentiableOn ℝ p' (Icc a b) → C1CloseOn (Icc a b) ε q' q → C1CloseOn (Icc a b) ε p' p → (∀ x ∈ Icc a b, 0 < q' x ∧ 0 < p' x ∧ 0 < sign * derivWithin (logRatio q' p') (Icc a b) x) := by have hunique := uniqueDiffOn_Icc hab have hqderiv_cont : ContinuousOn (fun x ↦ derivWithin q (Icc a b) x) (Icc a b) := hq.continuousOn_derivWithin hunique (by norm_num) have hpderiv_cont : ContinuousOn (fun x ↦ derivWithin p (Icc a b) x) (Icc a b) := hp.continuousOn_derivWithin hunique (by norm_num) obtain ⟨Cq, hCq⟩ := isCompact_Icc.exists_bound_of_continuousOn hq.continuousOn obtain ⟨Cp, hCp⟩ := isCompact_Icc.exists_bound_of_continuousOn hp.continuousOn obtain ⟨Dq, hDq⟩ := isCompact_Icc.exists_bound_of_continuousOn hqderiv_cont obtain ⟨Dp, hDp⟩ := isCompact_Icc.exists_bound_of_continuousOn hpderiv_cont let B := |Cq| + |Cp| + |Dq| + |Dp| + 1 have hB : 0 < B := by dsimp [B]; positivity have hqB : ∀ x ∈ Icc a b, |q x| ≤ B := by intro x hx calc |q x| ≤ Cq := hCq x hx _ ≤ |Cq| := le_abs_self Cq _ ≤ B := by dsimp [B] linarith [abs_nonneg Cp, abs_nonneg Dq, abs_nonneg Dp] have hpB : ∀ x ∈ Icc a b, |p x| ≤ B := by intro x hx calc |p x| ≤ Cp := hCp x hx _ ≤ |Cp| := le_abs_self Cp _ ≤ B := by dsimp [B] linarith [abs_nonneg Cq, abs_nonneg Dq, abs_nonneg Dp] have hDqB : ∀ x ∈ Icc a b, |derivWithin q (Icc a b) x| ≤ B := by intro x hx calc |derivWithin q (Icc a b) x| ≤ Dq := hDq x hx _ ≤ |Dq| := le_abs_self Dq _ ≤ B := by dsimp [B] linarith [abs_nonneg Cq, abs_nonneg Cp, abs_nonneg Dp] have hDpB : ∀ x ∈ Icc a b, |derivWithin p (Icc a b) x| ≤ B := by intro x hx calc |derivWithin p (Icc a b) x| ≤ Dp := hDp x hx _ ≤ |Dp| := le_abs_self Dp _ ≤ B := by dsimp [B] linarith [abs_nonneg Cq, abs_nonneg Cp, abs_nonneg Dq] let L := (2 * B) / (m ^ 2 / 2) have hL : 0 < L := by dsimp [L]; positivity let ε := min (m / 2) (margin / (4 * L)) have hε : 0 < ε := by dsimp [ε]; positivity have hεm : ε ≤ m / 2 := min_le_left _ _ have hεmargin : 2 * L * ε ≤ margin / 2 := by have hεL : ε ≤ margin / (4 * L) := min_le_right _ _ have hL4 : 0 < 4 * L := by positivity calc 2 * L * ε ≤ 2 * L * (margin / (4 * L)) := by gcongr _ = margin / 2 := by field_simp; ring refine ⟨ε, hε, ?_⟩ intro q' p' hq'diff hp'diff hqclose hpclose x hx have hqpos : 0 < q x := hm.trans_le (hqlower x hx) have hppos : 0 < p x := hm.trans_le (hplower x hx) have hq'pos : 0 < q' x := by have hneg := neg_lt_of_abs_lt (hqclose.1 x hx) linarith [hqlower x hx, hεm, hm] have hp'pos : 0 < p' x := by have hneg := neg_lt_of_abs_lt (hpclose.1 x hx) linarith [hplower x hx, hεm, hm] refine ⟨hq'pos, hp'pos, ?_⟩ have hqfrac := abs_div_sub_div_lt hm hB hε hεm (hqlower x hx) (hqB x hx) (hDqB x hx) (hqclose.1 x hx) (hqclose.2 x hx) have hpfrac := abs_div_sub_div_lt hm hB hε hεm (hplower x hx) (hpB x hx) (hDpB x hx) (hpclose.1 x hx) (hpclose.2 x hx) have hqfrac' : |derivWithin q' (Icc a b) x / q' x - derivWithin q (Icc a b) x / q x| < L * ε := by convert hqfrac using 1 <;> dsimp [L] <;> ring have hpfrac' : |derivWithin p' (Icc a b) x / p' x - derivWithin p (Icc a b) x / p x| < L * ε := by convert hpfrac using 1 <;> dsimp [L] <;> ring have hderivdiff : |derivWithin (logRatio q' p') (Icc a b) x - derivWithin (logRatio q p) (Icc a b) x| < 2 * L * ε := by rw [derivWithin_logRatio hab hq'diff hp'diff (fun y hy ↦ by have hneg := neg_lt_of_abs_lt (hqclose.1 y hy) nlinarith [hqlower y hy]) (fun y hy ↦ by have hneg := neg_lt_of_abs_lt (hpclose.1 y hy) nlinarith [hplower y hy]) hx, derivWithin_logRatio hab (hq.differentiableOn (by norm_num)) (hp.differentiableOn (by norm_num)) (fun y hy ↦ hm.trans_le (hqlower y hy)) (fun y hy ↦ hm.trans_le (hplower y hy)) hx] calc |(derivWithin q' (Icc a b) x / q' x - derivWithin p' (Icc a b) x / p' x) - (derivWithin q (Icc a b) x / q x - derivWithin p (Icc a b) x / p x)| = |(derivWithin q' (Icc a b) x / q' x - derivWithin q (Icc a b) x / q x) - (derivWithin p' (Icc a b) x / p' x - derivWithin p (Icc a b) x / p x)| := by congr 1 <;> ring _ ≤ |derivWithin q' (Icc a b) x / q' x - derivWithin q (Icc a b) x / q x| + |derivWithin p' (Icc a b) x / p' x - derivWithin p (Icc a b) x / p x| := by simpa only [sub_eq_add_neg, Real.norm_eq_abs, norm_neg] using norm_add_le (derivWithin q' (Icc a b) x / q' x - derivWithin q (Icc a b) x / q x) (-(derivWithin p' (Icc a b) x / p' x - derivWithin p (Icc a b) x / p x)) _ < L * ε + L * ε := add_lt_add hqfrac' hpfrac' _ = 2 * L * ε := by ring have hsignabs : |sign| = 1 := by rcases hsign with rfl | rfl <;> norm_num have hsignedDiff : |sign * derivWithin (logRatio q' p') (Icc a b) x - sign * derivWithin (logRatio q p) (Icc a b) x| < margin / 2 := by rw [← mul_sub, abs_mul, hsignabs, one_mul] exact hderivdiff.trans_le hεmargin have hlowerSigned := hfixed x hx have hneg := neg_lt_of_abs_lt hsignedDiff nlinarith
Causalean.Mathlib.Analysis.logRatioDerivative_fixedSign_open_C1 · Causalean/Mathlib/Analysis/LogRatioStability.lean:307 · uses C1CloseOn , logRatio
6 supporting declarations (lemmas, instances)
  • tendstoUniformlyOn_atTop_iff_abs_sub_lt theorem — Uniform convergence of a function sequence on a set holds exactly when every positive error tolerance is eventually met, at every point of the set, by the absolute difference between the sequence and its limit.
    α :
    Type*
    K :
    Set α
    f :
    ℕ → α → ℝ
    g :
    α → ℝ
    TendstoUniformlyOn f g atTop K ↔ ∀ ε > 0, ∃ N, ∀ n ≥ N, ∀ x ∈ K, |f n x - g x| < ε
    Proof (Lean source)
    theorem tendstoUniformlyOn_atTop_iff_abs_sub_lt {α : Type*} (K : Set α) (f : ℕ → α → ℝ) (g : α → ℝ) : TendstoUniformlyOn f g atTop K ↔ ∀ ε > 0, ∃ N, ∀ n ≥ N, ∀ x ∈ K, |f n x - g x| < ε := by rw [Metric.tendstoUniformlyOn_iff] simp only [Real.dist_eq, eventually_atTop] constructor · intro h ε hε obtain ⟨N, hN⟩ := h ε hε exact ⟨N, fun n hn x hx ↦ by simpa [abs_sub_comm] using hN n hn x hx⟩ · intro h ε hε obtain ⟨N, hN⟩ := h ε hε exact ⟨N, fun n hn x hx ↦ by simpa [abs_sub_comm] using hN n hn x hx⟩
    Causalean.Mathlib.Analysis.tendstoUniformlyOn_atTop_iff_abs_sub_lt · Causalean/Mathlib/Analysis/LogRatioStability.lean:24
  • uniformlyOn_inv_of_lowerBound theorem — Uniform convergence is preserved by reciprocals when every approximating denominator and its limit share one strictly positive lower bound.
    α :
    Type*
    Set α
    ℕ → α → ℝ
    α → ℝ
    m :
    ℝ
    hm :
    0 < m
    hconv :
    hlower :
    ∀ n x
    if
    x ∈ K
    then
    m ≤ f n x
    hlower_limit :
    ∀ x
    if
    x ∈ K
    then
    m ≤ g x
    TendstoUniformlyOn (fun n x ↦ (f n x)⁻¹) (fun x ↦ (g x)⁻¹) atTop K
    Proof (Lean source)
    theorem uniformlyOn_inv_of_lowerBound {α : Type*} {K : Set α} {f : ℕ → α → ℝ} {g : α → ℝ} {m : ℝ} (hm : 0 < m) (hconv : TendstoUniformlyOn f g atTop K) (hlower : ∀ n x, x ∈ K → m ≤ f n x) (hlower_limit : ∀ x, x ∈ K → m ≤ g x) : TendstoUniformlyOn (fun n x ↦ (f n x)⁻¹) (fun x ↦ (g x)⁻¹) atTop K := by rw [tendstoUniformlyOn_atTop_iff_abs_sub_lt] at hconv ⊢ intro ε hε obtain ⟨N, hN⟩ := hconv (ε * m ^ 2) (mul_pos hε (sq_pos_of_pos hm)) refine ⟨N, fun n hn x hx ↦ ?_⟩ have hfn : 0 < f n x := hm.trans_le (hlower n x hx) have hg : 0 < g x := hm.trans_le (hlower_limit x hx) rw [inv_sub_inv hfn.ne' hg.ne', abs_div, abs_of_pos (mul_pos hfn hg)] apply (div_lt_iff₀ (mul_pos hfn hg)).2 calc |g x - f n x| = |f n x - g x| := abs_sub_comm _ _ _ < ε * m ^ 2 := hN n hn x hx _ ≤ ε * (f n x * g x) := by gcongr nlinarith [hlower n x hx, hlower_limit x hx]
    Causalean.Mathlib.Analysis.uniformlyOn_inv_of_lowerBound · Causalean/Mathlib/Analysis/LogRatioStability.lean:63
  • uniformlyOn_div_of_lowerBound theorem — Uniform convergence is preserved by quotients on a compact set when numerators converge to a continuous limit and denominators share a strictly positive lower bound.
    α :
    hK :
    u :
    ℕ → α → ℝ
    v :
    ℕ → α → ℝ
    u₀ v₀ :
    α → ℝ
    m :
    ℝ
    hm :
    0 < m
    hu :
    hv :
    hu₀ :
    hlower :
    ∀ n x
    if
    x ∈ K
    then
    m ≤ v n x
    hlower_limit :
    ∀ x
    if
    x ∈ K
    then
    m ≤ v₀ x
    TendstoUniformlyOn (fun n x ↦ u n x / v n x) (fun x ↦ u₀ x / v₀ x) atTop K
    Proof (Lean source)
    theorem uniformlyOn_div_of_lowerBound {α : Type*} [TopologicalSpace α] {K : Set α} (hK : IsCompact K) {u : ℕ → α → ℝ} {v : ℕ → α → ℝ} {u₀ v₀ : α → ℝ} {m : ℝ} (hm : 0 < m) (hu : TendstoUniformlyOn u u₀ atTop K) (hv : TendstoUniformlyOn v v₀ atTop K) (hu₀ : ContinuousOn u₀ K) (hlower : ∀ n x, x ∈ K → m ≤ v n x) (hlower_limit : ∀ x, x ∈ K → m ≤ v₀ x) : TendstoUniformlyOn (fun n x ↦ u n x / v n x) (fun x ↦ u₀ x / v₀ x) atTop K := by obtain ⟨C, hC⟩ := hK.exists_bound_of_continuousOn hu₀ have hinv := uniformlyOn_inv_of_lowerBound hm hv hlower hlower_limit rw [tendstoUniformlyOn_atTop_iff_abs_sub_lt] at hu hinv ⊢ intro ε hε let B := |C| + 1 have hB : 0 < B := add_pos_of_nonneg_of_pos (abs_nonneg C) zero_lt_one obtain ⟨Nu, hNu⟩ := hu (ε * m / 2) (by positivity) obtain ⟨Nv, hNv⟩ := hinv (ε / (2 * B)) (by positivity) refine ⟨max Nu Nv, fun n hn x hx ↦ ?_⟩ have hnu := hNu n (le_trans (le_max_left _ _) hn) x hx have hnv := hNv n (le_trans (le_max_right _ _) hn) x hx have hvpos : 0 < v n x := hm.trans_le (hlower n x hx) have hv_inv : |(v n x)⁻¹| ≤ m⁻¹ := by rw [abs_of_pos (inv_pos.mpr hvpos)] exact (inv_le_inv₀ hvpos hm).2 (hlower n x hx) have hu₀_bound : |u₀ x| < B := (hC x hx).trans_lt (lt_of_le_of_lt (le_abs_self C) (lt_add_one _)) have hfirst : |u n x - u₀ x| * |(v n x)⁻¹| < (ε * m / 2) * m⁻¹ := by calc _ < (ε * m / 2) * |(v n x)⁻¹| := mul_lt_mul_of_pos_right hnu (abs_pos.mpr (inv_ne_zero hvpos.ne')) _ ≤ (ε * m / 2) * m⁻¹ := mul_le_mul_of_nonneg_left hv_inv (by positivity) have hsecond : |u₀ x| * |(v n x)⁻¹ - (v₀ x)⁻¹| < B * (ε / (2 * B)) := by calc _ ≤ B * |(v n x)⁻¹ - (v₀ x)⁻¹| := mul_le_mul_of_nonneg_right hu₀_bound.le (abs_nonneg _) _ < B * (ε / (2 * B)) := mul_lt_mul_of_pos_left hnv hB change |u n x / v n x - u₀ x / v₀ x| < ε rw [div_eq_mul_inv, div_eq_mul_inv] calc |u n x * (v n x)⁻¹ - u₀ x * (v₀ x)⁻¹| = |(u n x - u₀ x) * (v n x)⁻¹ + u₀ x * ((v n x)⁻¹ - (v₀ x)⁻¹)| := by congr 1 ring _ ≤ |u n x - u₀ x| * |(v n x)⁻¹| + |u₀ x| * |(v n x)⁻¹ - (v₀ x)⁻¹| := by simpa only [abs_mul] using abs_add_le ((u n x - u₀ x) * (v n x)⁻¹) (u₀ x * ((v n x)⁻¹ - (v₀ x)⁻¹)) _ < (ε * m / 2) * m⁻¹ + B * (ε / (2 * B)) := add_lt_add hfirst hsecond _ = ε := by field_simp; ring
    Causalean.Mathlib.Analysis.uniformlyOn_div_of_lowerBound · Causalean/Mathlib/Analysis/LogRatioStability.lean:86
  • uniformlyOn_log_of_lowerBound theorem — Uniform convergence is preserved by the real logarithm when all functions share a strictly positive lower bound.
    α :
    Type*
    Set α
    ℕ → α → ℝ
    α → ℝ
    m :
    ℝ
    hm :
    0 < m
    hconv :
    hlower :
    ∀ n x
    if
    x ∈ K
    then
    m ≤ f n x
    hlower_limit :
    ∀ x
    if
    x ∈ K
    then
    m ≤ g x
    TendstoUniformlyOn (fun n x ↦ log (f n x)) (fun x ↦ log (g x)) atTop K
    Proof (Lean source)
    theorem uniformlyOn_log_of_lowerBound {α : Type*} {K : Set α} {f : ℕ → α → ℝ} {g : α → ℝ} {m : ℝ} (hm : 0 < m) (hconv : TendstoUniformlyOn f g atTop K) (hlower : ∀ n x, x ∈ K → m ≤ f n x) (hlower_limit : ∀ x, x ∈ K → m ≤ g x) : TendstoUniformlyOn (fun n x ↦ log (f n x)) (fun x ↦ log (g x)) atTop K := by rw [tendstoUniformlyOn_atTop_iff_abs_sub_lt] at hconv ⊢ have hlog_lip : ∀ {r s : ℝ}, m ≤ r → m ≤ s → |log r - log s| ≤ m⁻¹ * |r - s| := by intro r s hr hs simpa only [Real.norm_eq_abs] using (Convex.norm_image_sub_le_of_norm_hasDerivWithin_le (f := log) (f' := fun y : ℝ ↦ y⁻¹) (C := m⁻¹) (fun y hy ↦ (Real.hasDerivAt_log (hm.trans_le hy).ne').hasDerivWithinAt) (fun y hy ↦ by have hypos : 0 < y := hm.trans_le hy rw [Real.norm_eq_abs, abs_of_pos (inv_pos.mpr hypos)] exact (inv_le_inv₀ hypos hm).2 hy) (convex_Ici m) hs hr) intro ε hε obtain ⟨N, hN⟩ := hconv (ε * m) (mul_pos hε hm) refine ⟨N, fun n hn x hx ↦ ?_⟩ change |log (f n x) - log (g x)| < ε calc _ ≤ m⁻¹ * |f n x - g x| := hlog_lip (hlower n x hx) (hlower_limit x hx) _ < m⁻¹ * (ε * m) := mul_lt_mul_of_pos_left (hN n hn x hx) (inv_pos.mpr hm) _ = ε := by field_simp
    Causalean.Mathlib.Analysis.uniformlyOn_log_of_lowerBound · Causalean/Mathlib/Analysis/LogRatioStability.lean:139
  • derivWithin_logRatio theorem — On a nondegenerate compact interval, the within-derivative of a positive log ratio is the difference of the two logarithmic derivatives.
    a b :
    ℝ
    hab :
    a < b
    q p :
    ℝ → ℝ
    hq :
    DifferentiableOn ℝ q (Icc a b)
    hp :
    DifferentiableOn ℝ p (Icc a b)
    hqpos :
    ∀ x ∈ Icc a b, 0 < q x
    hppos :
    ∀ x ∈ Icc a b, 0 < p x
    x :
    ℝ
    hx :
    x ∈ Icc a b
    derivWithin (logRatio q p) (Icc a b) x
    = derivWithin q (Icc a b) x / q x - derivWithin p (Icc a b) x / p x
    Proof (Lean source)
    theorem derivWithin_logRatio {a b : ℝ} (hab : a < b) {q p : ℝ → ℝ} (hq : DifferentiableOn ℝ q (Icc a b)) (hp : DifferentiableOn ℝ p (Icc a b)) (hqpos : ∀ x ∈ Icc a b, 0 < q x) (hppos : ∀ x ∈ Icc a b, 0 < p x) {x : ℝ} (hx : x ∈ Icc a b) : derivWithin (logRatio q p) (Icc a b) x = derivWithin q (Icc a b) x / q x - derivWithin p (Icc a b) x / p x := by have hq_at := hq x hx have hp_at := hp x hx have hqne : q x ≠ 0 := (hqpos x hx).ne' have hpne : p x ≠ 0 := (hppos x hx).ne' have hunique := (uniqueDiffOn_Icc hab).uniqueDiffWithinAt hx have hdiv : DifferentiableWithinAt ℝ (fun y ↦ q y / p y) (Icc a b) x := hq_at.div hp_at hpne have hdiv_deriv := derivWithin_div hq_at hp_at hpne change derivWithin (fun y ↦ q y / p y) (Icc a b) x = _ at hdiv_deriv change derivWithin (fun y ↦ log (q y / p y)) (Icc a b) x = _ rw [derivWithin.log hdiv (div_ne_zero hqne hpne) hunique] rw [hdiv_deriv] field_simp
    Causalean.Mathlib.Analysis.derivWithin_logRatio · Causalean/Mathlib/Analysis/LogRatioStability.lean:169
  • logRatioDerivative_fixedSign_open_C2 theorem — The same strict fixed-sign derivative property is open under uniform C² perturbations, because uniform C² control includes the required uniform C¹ control.
    a b m margin :
    ℝ
    hab :
    a < b
    hm :
    0 < m
    hmargin :
    0 < margin
    q p :
    ℝ → ℝ
    hq :
    ContDiffOn ℝ 1 q (Icc a b)
    hp :
    ContDiffOn ℝ 1 p (Icc a b)
    hqlower :
    ∀ x ∈ Icc a b, m ≤ q x
    hplower :
    ∀ x ∈ Icc a b, m ≤ p x
    sign :
    ℝ
    hsign :
    sign = 1 ∨ sign = -1
    hfixed :
    ∀ x ∈ Icc a b, margin ≤ sign * derivWithin (logRatio q p) (Icc a b) x
    ∃ ε > 0,
    ∀ q' p' : ℝ → ℝ,
    DifferentiableOn ℝ q' (Icc a b) → DifferentiableOn ℝ p' (Icc a b) → C2CloseOn (Icc a b) ε q' q → C2CloseOn (Icc a b) ε p' p → (∀ x ∈ Icc a b, 0 < q' x ∧ 0 < p' x ∧ 0 < sign * derivWithin (logRatio q' p') (Icc a b) x)
    Proof (Lean source)
    theorem logRatioDerivative_fixedSign_open_C2 {a b m margin : ℝ} (hab : a < b) (hm : 0 < m) (hmargin : 0 < margin) {q p : ℝ → ℝ} (hq : ContDiffOn ℝ 1 q (Icc a b)) (hp : ContDiffOn ℝ 1 p (Icc a b)) (hqlower : ∀ x ∈ Icc a b, m ≤ q x) (hplower : ∀ x ∈ Icc a b, m ≤ p x) (sign : ℝ) (hsign : sign = 1 ∨ sign = -1) (hfixed : ∀ x ∈ Icc a b, margin ≤ sign * derivWithin (logRatio q p) (Icc a b) x) : ∃ ε > 0, ∀ q' p' : ℝ → ℝ, DifferentiableOn ℝ q' (Icc a b) → DifferentiableOn ℝ p' (Icc a b) → C2CloseOn (Icc a b) ε q' q → C2CloseOn (Icc a b) ε p' p → (∀ x ∈ Icc a b, 0 < q' x ∧ 0 < p' x ∧ 0 < sign * derivWithin (logRatio q' p') (Icc a b) x) := by obtain ⟨ε, hε, hopen⟩ := logRatioDerivative_fixedSign_open_C1 hab hm hmargin hq hp hqlower hplower sign hsign hfixed refine ⟨ε, hε, ?_⟩ intro q' p' hq'diff hp'diff hqclose hpclose exact hopen q' p' hq'diff hp'diff hqclose.1 hpclose.1
    Causalean.Mathlib.Analysis.logRatioDerivative_fixedSign_open_C2 · Causalean/Mathlib/Analysis/LogRatioStability.lean:438
Matrix­Measurability 4 core · 8 supporting This module contains topology and measurability facts that do not depend on the proxy model or on a particular statistical construction. ★ singularValue_measurable

Borel prerequisites for finite-dimensional spectral algorithms

This module contains topology and measurability facts that do not depend on the proxy model or on a particular statistical construction.

instance instMeasurableSpaceRectMatrix reviewed
Causalean.Mathlib.Analysis

Finite real rectangular matrices use the Borel measurable-space structure inherited from their Euclidean topology.

Definition (Lean source)
rows cols :
ℕ
instMeasurableSpaceRectMatrix :
borel _
Causalean.Mathlib.Analysis.instMeasurableSpaceRectMatrix · Causalean/Mathlib/Analysis/MatrixMeasurability.lean:23 · uses RectMatrix
lemma singularValue_measurable reviewed
Causalean.Mathlib.Analysis

Finite row and column dimensions and a singular-value index determine a Borel measurable singular-value coordinate.

Formal statement
rows cols j :
ℕ
Measurable (fun A : RectMatrix rows cols => singularValue A j)
Proof (Lean source)
@[fun_prop] lemma singularValue_measurable {rows cols j : ℕ} : Measurable (fun A : RectMatrix rows cols => singularValue A j) := singularValue_continuous.measurable
def singularThresholdMask reviewed
Causalean.Mathlib.Analysis

The finite mask of singular directions retained by a hard threshold: the set of column indices j whose j-th singular value of the matrix (zero-based, in decreasing order) is at least the threshold.

Definition (Lean source)
rows cols :
ℕ
threshold :
ℝ
A :
RectMatrix rows cols
singularThresholdMask threshold A :
Finset (Fin cols)
Finset.univ.filter fun j => threshold ≤ singularValue A j
Causalean.Mathlib.Analysis.singularThresholdMask · Causalean/Mathlib/Analysis/MatrixMeasurability.lean:85 · uses RectMatrix
def rationalThresholdApprox reviewed
Causalean.Mathlib.Analysis

A rational approximation to the hard-thresholded inverse of a real matrix A at a threshold τ: with G = AᵀA and q = m + 1, it is the matrix G^m·(G^q + (τ^(2q)/q)·I)⁻¹·Aᵀ. On a singular direction with singular value σ > 0 it acts as (1/σ)/(1 + (τ/σ)^(2q)/q). The index m represents the positive exponent m + 1; this convention avoids a special zeroth term in the approximating sequence.

Definition (Lean source)
rows cols :
ℕ
threshold :
ℝ
m :
ℕ
A :
RectMatrix rows cols
rationalThresholdApprox threshold m A :
RectMatrix cols rows
G :
A.transpose * A
q :
m + 1
a :
threshold ^ (2 * q) / (q : ℝ)
G ^ m * (G ^ q + a • (1 : RectMatrix cols cols))⁻¹ * A.transpose
Causalean.Mathlib.Analysis.rationalThresholdApprox · Causalean/Mathlib/Analysis/MatrixMeasurability.lean:128 · uses RectMatrix
8 supporting declarations (lemmas, instances)
Monomial­Gram 4 core · 8 supporting This module proves that distinct multivariate monomials have a positive-definite Gram matrix on every nondegenerate real cube. ★ monomialGram_posDef

Multivariate monomial Gram matrices

This module proves that distinct multivariate monomials have a positive-definite Gram matrix on every nondegenerate real cube. It also supplies the resulting uniform quadratic coercivity bound.

def supBall reviewed
Causalean.Mathlib.Analysis

For a coordinate index set, a real-valued center vector, and a real radius, the closed sup-norm ball is the set of real-valued vectors whose every coordinate differs from the corresponding coordinate of the center by at most that radius.

Definition (Lean source)
ι :
Type*
x0 :
ι → ℝ
r :
ℝ
supBall x0 r :
Set (ι → ℝ)
{x | ∀ i, |x i - x0 i| ≤ r}
Causalean.Mathlib.Analysis.supBall · Causalean/Mathlib/Analysis/MonomialGram.lean:24
def monomial reviewed
Causalean.Mathlib.Analysis

For a finite coordinate index set, an assignment of a nonnegative integer exponent to each coordinate, and a real-valued coordinate vector, the multivariate monomial is the product of the coordinates after each has been raised to its assigned exponent.

Definition (Lean source)
ι :
Type*
e :
ι → ℕ
u :
ι → ℝ
monomial e u :
ℝ
∏ j, (u j) ^ (e j)
Causalean.Mathlib.Analysis.monomial · Causalean/Mathlib/Analysis/MonomialGram.lean:30
def monomialGram reviewed
Causalean.Mathlib.Analysis

For a coordinate dimension and a finite family size, an assignment of a multivariate exponent vector to each member of that family, and a real radius, the monomial Gram matrix has as its (k,l)(k,l) entry the integral of the product of the kkth and llth associated monomials over the centered closed coordinate cube of that radius.

Definition (Lean source)
d p :
ℕ
expo :
Fin p → (Fin d → ℕ)
r :
ℝ
monomialGram expo r :
Matrix (Fin p) (Fin p) ℝ
of fun k l
=> ∫ u in {u : Fin d → ℝ | ∀ j, |u j| ≤ r}, monomial (expo k) u * monomial (expo l) u
Causalean.Mathlib.Analysis.monomialGram · Causalean/Mathlib/Analysis/MonomialGram.lean:37
theorem monomialGram_posDef reviewed
Causalean.Mathlib.Analysis

Positive-definiteness of the monomial Gram matrix. For a finite family of multivariate monomials indexed by their exponent vectors, if the cube radius r is strictly positive and the exponent vectors are pairwise distinct, then the Gram matrix of pairwise integrals of the monomials over the cube of radius r is positive-definite.

Formal statement
d p :
ℕ
expo :
Fin p → (Fin d → ℕ)
r :
ℝ
hr :
0 < r
hexpo :
Proof (Lean source)
theorem monomialGram_posDef {d p : ℕ} (expo : Fin p → (Fin d → ℕ)) {r : ℝ} (hr : 0 < r) (hexpo : Injective expo) : (monomialGram expo r).PosDef := by apply Matrix.PosDef.of_dotProduct_mulVec_pos (monomialGram_isHermitian expo r) intro z hz rw [show star z = z by ext k; simp] simp only [dotProduct, mulVec, Finset.mul_sum] simp_rw [← mul_assoc] rw [monomialGram_quadForm expo z] let f : (Fin d → ℝ) → ℝ := fun u => ∑ k, z k * monomial (expo k) u have hfcont : Continuous f := continuous_monomialCombination expo z have hfint : IntegrableOn (fun u => (f u) ^ 2) (cube d r) := (hfcont.pow 2).continuousOn.integrableOn_compact (isCompact_cube d r) have hnonneg : 0 ≤ ∫ u in cube d r, (f u) ^ 2 := MeasureTheory.integral_nonneg_of_ae (Filter.Eventually.of_forall fun _ => sq_nonneg _) by_contra hpos have hintzero : (∫ u in cube d r, (f u) ^ 2) = 0 := le_antisymm (le_of_not_gt hpos) hnonneg have hae_sq : (fun u => (f u) ^ 2) =ᵐ[volume.restrict (cube d r)] 0 := (MeasureTheory.setIntegral_eq_zero_iff_of_nonneg_ae (Filter.Eventually.of_forall fun _ => sq_nonneg _) hfint).mp hintzero have hae_f : f =ᵐ[volume.restrict (cube d r)] 0 := hae_sq.mono fun u hu => by simpa using (sq_eq_zero_iff.mp hu) let U : Set (Fin d → ℝ) := pi univ (fun _ => Ioo (-r) r) have hUopen : IsOpen U := isOpen_set_pi Set.finite_univ (fun _ _ => isOpen_Ioo) have hUcube : U ⊆ cube d r := by intro u hu j rw [abs_le] exact ⟨(hu j (Set.mem_univ j)).1.le, (hu j (Set.mem_univ j)).2.le⟩ have hae_U : f =ᵐ[volume.restrict U] 0 := ae_restrict_of_ae_restrict_of_subset hUcube hae_f have hpoint : EqOn f 0 U := MeasureTheory.Measure.eqOn_open_of_ae_eq hae_U hUopen hfcont.continuousOn continuous_zero.continuousOn apply hz apply monomial_coefficients_eq_zero_of_vanishes_on_openCube hr hexpo z intro u hu exact hpoint (fun j _ => hu j)
Causalean.Mathlib.Analysis.monomialGram_posDef · Causalean/Mathlib/Analysis/MonomialGram.lean:193 · uses monomialGram
8 supporting declarations (lemmas, instances)
  • continuous_monomial lemma — A multivariate real monomial varies continuously with its coordinate vector.
    ι :
    Type*
    e :
    ι → ℕ
    Proof (Lean source)
    @[fun_prop] lemma continuous_monomial {ι : Type*} [Fintype ι] (e : ι → ℕ) : Continuous (monomial e) := by unfold monomial exact continuous_finset_prod _ fun j _ => (continuous_apply j).pow (e j)
    Causalean.Mathlib.Analysis.continuous_monomial · Causalean/Mathlib/Analysis/MonomialGram.lean:59
  • continuous_monomialCombination lemma — A finite linear combination of multivariate real monomials is continuous.
    d p :
    ℕ
    expo :
    Fin p → (Fin d → ℕ)
    z :
    Fin p → ℝ
    Continuous (fun u => ∑ k, z k * monomial (expo k) u)
    Proof (Lean source)
    @[fun_prop] lemma continuous_monomialCombination {d p : ℕ} (expo : Fin p → (Fin d → ℕ)) (z : Fin p → ℝ) : Continuous (fun u => ∑ k, z k * monomial (expo k) u) := by exact continuous_finset_sum _ fun k _ => continuous_const.mul (continuous_monomial (expo k))
    Causalean.Mathlib.Analysis.continuous_monomialCombination · Causalean/Mathlib/Analysis/MonomialGram.lean:66
  • monomial_linearIndependent_on_cube theorem — A linear combination of distinct multivariate monomials that vanishes throughout the interior of a cube with positive radius must have every coefficient equal to zero.
    d p :
    ℕ
    Fin p → (Fin d → ℕ)
    r :
    ℝ
    hr :
    0 < r
    hexpo :
    z :
    Fin p → ℝ
    hz :
    ∀ u
    if
    (∀ j, u j ∈ Ioo (-r) r)
    then
    (∑ k, z k * monomial (expo k) u) = 0
    z = 0
    Proof (Lean source)
    theorem monomial_linearIndependent_on_cube {d p : ℕ} {expo : Fin p → (Fin d → ℕ)} {r : ℝ} (hr : 0 < r) (hexpo : Injective expo) (z : Fin p → ℝ) (hz : ∀ u, (∀ j, u j ∈ Ioo (-r) r) → (∑ k, z k * monomial (expo k) u) = 0) : z = 0 := by exact monomial_coefficients_eq_zero_of_vanishes_on_openCube hr hexpo z hz
    Causalean.Mathlib.Analysis.monomial_linearIndependent_on_cube · Causalean/Mathlib/Analysis/MonomialGram.lean:125
  • monomialGram_quadForm theorem — Evaluating the monomial Gram quadratic form at a coefficient vector equals integrating the square of the corresponding monomial combination over the cube.
    d p :
    ℕ
    expo :
    Fin p → (Fin d → ℕ)
    r :
    ℝ
    z :
    Fin p → ℝ
    ∑ k, ∑ l, z k * monomialGram expo r k l * z l
    = ∫ u in {u : Fin d → ℝ | ∀ j, |u j| ≤ r}, (∑ k, z k * monomial (expo k) u) ^ 2
    Proof (Lean source)
    theorem monomialGram_quadForm {d p : ℕ} (expo : Fin p → (Fin d → ℕ)) {r : ℝ} (z : Fin p → ℝ) : ∑ k, ∑ l, z k * monomialGram expo r k l * z l = ∫ u in {u : Fin d → ℝ | ∀ j, |u j| ≤ r}, (∑ k, z k * monomial (expo k) u) ^ 2 := by change (∑ k, ∑ l, z k * (∫ u in cube d r, monomial (expo k) u * monomial (expo l) u) * z l) = _ have hkl (k l : Fin p) : IntegrableOn (fun u => (z k * monomial (expo k) u) * (z l * monomial (expo l) u)) (cube d r) := (((continuous_const.mul (continuous_monomial (expo k))).mul (continuous_const.mul (continuous_monomial (expo l)))).continuousOn.integrableOn_compact (isCompact_cube d r)) calc _ = ∑ k, ∑ l, ∫ u in cube d r, (z k * monomial (expo k) u) * (z l * monomial (expo l) u) := by apply Finset.sum_congr rfl intro k _ apply Finset.sum_congr rfl intro l _ rw [show (fun u => (z k * monomial (expo k) u) * (z l * monomial (expo l) u)) = fun u => (z k * z l) * (monomial (expo k) u * monomial (expo l) u) by funext u ring, MeasureTheory.integral_const_mul] ring _ = ∫ u in cube d r, ∑ k, ∑ l, (z k * monomial (expo k) u) * (z l * monomial (expo l) u) := by symm rw [MeasureTheory.integral_finset_sum univ (fun k _ => integrable_finset_sum _ fun l _ => hkl k l)] apply Finset.sum_congr rfl intro k _ rw [MeasureTheory.integral_finset_sum univ (fun l _ => hkl k l)] _ = ∫ u in cube d r, (∑ k, z k * monomial (expo k) u) ^ 2 := by congr 1 funext u rw [pow_two, Finset.sum_mul_sum]
    Causalean.Mathlib.Analysis.monomialGram_quadForm · Causalean/Mathlib/Analysis/MonomialGram.lean:133
  • monomialGram_isHermitian theorem — The monomial Gram matrix is symmetric, and hence Hermitian over the real numbers.
    d p :
    ℕ
    expo :
    Fin p → (Fin d → ℕ)
    r :
    ℝ
    Proof (Lean source)
    theorem monomialGram_isHermitian {d p : ℕ} (expo : Fin p → (Fin d → ℕ)) (r : ℝ) : (monomialGram expo r).IsHermitian := by apply Matrix.IsHermitian.ext intro k l simp only [star_id_of_comm] simp [monomialGram, mul_comm]
    Causalean.Mathlib.Analysis.monomialGram_isHermitian · Causalean/Mathlib/Analysis/MonomialGram.lean:173
  • monomialGram_posSemidef theorem — Every coefficient vector gives a nonnegative quadratic form under the monomial Gram matrix.
    d p :
    ℕ
    expo :
    Fin p → (Fin d → ℕ)
    r :
    ℝ
    Proof (Lean source)
    theorem monomialGram_posSemidef {d p : ℕ} (expo : Fin p → (Fin d → ℕ)) {r : ℝ} : (monomialGram expo r).PosSemidef := by apply Matrix.PosSemidef.of_dotProduct_mulVec_nonneg (monomialGram_isHermitian expo r) intro z rw [show star z = z by ext k; simp] simp only [dotProduct, mulVec, Finset.mul_sum] simp_rw [← mul_assoc] rw [monomialGram_quadForm expo z] exact MeasureTheory.integral_nonneg_of_ae (Filter.Eventually.of_forall fun _ => sq_nonneg _)
    Causalean.Mathlib.Analysis.monomialGram_posSemidef · Causalean/Mathlib/Analysis/MonomialGram.lean:181
  • sum_sq_pos lemma — The sum of squared coordinates of a nonzero finite real-valued vector is strictly positive.
    ι :
    Type*
    z :
    ι → ℝ
    hz :
    z ≠ 0
    0 < ∑ k, (z k) ^ 2
    Proof (Lean source)
    lemma sum_sq_pos {ι : Type*} [Fintype ι] (z : ι → ℝ) (hz : z ≠ 0) : 0 < ∑ k, (z k) ^ 2 := by have hnonneg : 0 ≤ ∑ k, (z k) ^ 2 := Finset.sum_nonneg fun _ _ => sq_nonneg _ refine lt_of_le_of_ne hnonneg ?_ intro heq apply hz funext k have hk : (z k) ^ 2 = 0 := (Finset.sum_eq_zero_iff_of_nonneg (fun _ _ => sq_nonneg _)).mp heq.symm k (Finset.mem_univ k) exact sq_eq_zero_iff.mp hk
    Causalean.Mathlib.Analysis.sum_sq_pos · Causalean/Mathlib/Analysis/MonomialGram.lean:238
  • exists_monomialGram_coercive theorem — A fixed family of distinct monomials on a cube with positive radius admits a positive uniform lower bound: its Gram quadratic form dominates the squared Euclidean norm of the coefficients.
    d p :
    ℕ
    expo :
    Fin p → (Fin d → ℕ)
    r :
    ℝ
    hr :
    0 < r
    hexpo :
    ∃ cmin : ℝ,
    0 < cmin
    conclusion 1
    z :
    Fin p → ℝ
    cmin * (∑ k, (z k) ^ 2) ≤ ∑ k, ∑ l, z k * monomialGram expo r k l * z l
    Proof (Lean source)
    theorem exists_monomialGram_coercive {d p : ℕ} (expo : Fin p → (Fin d → ℕ)) {r : ℝ} (hr : 0 < r) (hexpo : Injective expo) : ∃ cmin : ℝ, 0 < cmin ∧ ∀ z : Fin p → ℝ, cmin * (∑ k, (z k) ^ 2) ≤ ∑ k, ∑ l, z k * monomialGram expo r k l * z l := by by_cases hp : p = 0 · subst p refine ⟨1, one_pos, ?_⟩ intro z simp have hp0 : 0 < p := Nat.pos_of_ne_zero hp let q : (Fin p → ℝ) → ℝ := fun z => ∑ k, ∑ l, z k * monomialGram expo r k l * z l let s2 : (Fin p → ℝ) → ℝ := fun z => ∑ k, (z k) ^ 2 let S : Set (Fin p → ℝ) := {z | s2 z = 1} have hqcont : Continuous q := by dsimp [q] fun_prop have hs2cont : Continuous s2 := by dsimp [s2] fun_prop have hSclosed : IsClosed S := by exact isClosed_eq hs2cont continuous_const have hSbounded : Bornology.IsBounded S := by apply (Metric.isBounded_iff_subset_closedBall 0).mpr refine ⟨1, ?_⟩ intro z hz rw [Metric.mem_closedBall, dist_zero_right] apply (pi_norm_le_iff_of_nonneg zero_le_one).mpr intro k rw [Real.norm_eq_abs, ← sq_le_one_iff_abs_le_one] have hk : (z k) ^ 2 ≤ 1 := by rw [← hz] exact Finset.single_le_sum (fun i _ => sq_nonneg (z i)) (Finset.mem_univ k) exact hk have hScompact : IsCompact S := Metric.isCompact_iff_isClosed_bounded.mpr ⟨hSclosed, hSbounded⟩ let e : Fin p := ⟨0, hp0⟩ let zunit : Fin p → ℝ := single e 1 have hzunit : zunit ∈ S := by classical simp [S, s2, zunit, Pi.single_apply] obtain ⟨zmin, hzmin, hmin⟩ := hScompact.exists_isMinOn ⟨zunit, hzunit⟩ hqcont.continuousOn have hPD := monomialGram_posDef expo hr hexpo have hzmin_ne : zmin ≠ 0 := by intro hzero simp [S, s2, hzero] at hzmin have hqmin_pos : 0 < q zmin := by have h := hPD.dotProduct_mulVec_pos hzmin_ne rw [show star zmin = zmin by ext k; simp] at h simpa only [q, dotProduct, mulVec, Finset.mul_sum, ← mul_assoc] using h refine ⟨q zmin, hqmin_pos, ?_⟩ intro z by_cases hz : z = 0 · simp [hz, q] have hspos : 0 < s2 z := by exact sum_sq_pos z hz let a : ℝ := (sqrt (s2 z))⁻¹ let w : Fin p → ℝ := a • z have hsqrt : (sqrt (s2 z)) ^ 2 = s2 z := by exact (Real.sq_sqrt hspos.le) have hsqrt_ne : sqrt (s2 z) ≠ 0 := (Real.sqrt_pos.2 hspos).ne' have hwS : w ∈ S := by simp only [S, Set.mem_setOf_eq, s2, w, Pi.smul_apply, smul_eq_mul] calc ∑ k, (a * z k) ^ 2 = a ^ 2 * ∑ k, (z k) ^ 2 := by simp_rw [mul_pow, Finset.mul_sum] _ = 1 := by dsimp [a] rw [inv_pow, hsqrt] exact inv_mul_cancel₀ hspos.ne' have hscale : q w = a ^ 2 * q z := by dsimp [q, w] symm rw [Finset.mul_sum] apply Finset.sum_congr rfl intro k _ rw [Finset.mul_sum] apply Finset.sum_congr rfl intro l _ ring have hlower : q zmin ≤ q w := hmin hwS rw [hscale] at hlower change q zmin * s2 z ≤ q z calc q zmin * s2 z ≤ (a ^ 2 * q z) * s2 z := mul_le_mul_of_nonneg_right hlower hspos.le _ = q z := by dsimp [a] rw [inv_pow, hsqrt] field_simp
    Causalean.Mathlib.Analysis.exists_monomialGram_coercive · Causalean/Mathlib/Analysis/MonomialGram.lean:251
Offset­Peeling 3 core · 6 supporting This file gives deterministic Young/weighted-AM-GM bounds that control expressions of the form a·t^θ after subtracting a linear offset in t. ★ offset_peeling

Offset peeling inequalities

This file gives deterministic Young/weighted-AM-GM bounds that control expressions of the form a·t^θ after subtracting a linear offset in t. It provides the quarter-offset constant offsetPeelingConstant, its general coefficient version offsetPeelingConstantC, the corresponding peeling bounds offset_peeling and offset_peeling_coeff, endpoint extensions at θ = 0, and max_two_split for splitting a clipped two-term offset across summands.

def offsetPeelingConstant reviewed
Causalean.Mathlib.OffsetPeeling

Given a real number θ\theta, the quarter-offset peeling constant is (1−θ)(4θ)θ/(1−θ)(1-\theta)(4\theta)^{\theta/(1-\theta)}.

Definition (Lean source)
θ :
ℝ
offsetPeelingConstant θ :
ℝ
(1 - θ) * (4 * θ) ^ (θ / (1 - θ))
Causalean.Mathlib.OffsetPeeling.offsetPeelingConstant · Causalean/Mathlib/Analysis/OffsetPeeling.lean:25
def offsetPeelingConstantC reviewed
Causalean.Mathlib.OffsetPeeling

Given a real offset coefficient cc and a real number θ\theta, the general-offset peeling constant is \((1-\theta)(\theta/c)^{\theta/(1-\theta)}).

Definition (Lean source)
c θ :
ℝ
offsetPeelingConstantC c θ :
ℝ
(1 - θ) * (θ / c) ^ (θ / (1 - θ))
Causalean.Mathlib.OffsetPeeling.offsetPeelingConstantC · Causalean/Mathlib/Analysis/OffsetPeeling.lean:30
lemma offset_peeling reviewed
Causalean.Mathlib.OffsetPeeling

Deterministic Young/AM-GM peeling for the quarter-offset. For an exponent strictly between zero and one and nonnegative coefficients a and t, the positive part of a·t^θ − t/4 is at most the offset-peeling constant times a raised to the power 1/(1−θ).

Formal statement
θ a t :
ℝ
hθ_pos :
0 < θ
hθ_lt :
θ < 1
ha :
0 ≤ a
ht :
0 ≤ t
max 0 (a * t ^ θ - (1 / 4 : ℝ) * t) ≤ offsetPeelingConstant θ * a ^ (1 / (1 - θ))
Proof (Lean source)
lemma offset_peeling (θ a t : ℝ) (hθ_pos : 0 < θ) (hθ_lt : θ < 1) (ha : 0 ≤ a) (ht : 0 ≤ t) : max 0 (a * t ^ θ - (1 / 4 : ℝ) * t) ≤ offsetPeelingConstant θ * a ^ (1 / (1 - θ)) := by simpa [offsetPeelingConstant, offsetPeelingConstantC, div_eq_mul_inv, mul_comm] using offset_peeling_coeff (1 / 4) θ a t (by norm_num) hθ_pos hθ_lt ha ht
Causalean.Mathlib.OffsetPeeling.offset_peeling · Causalean/Mathlib/Analysis/OffsetPeeling.lean:131 · uses offsetPeelingConstant
6 supporting declarations (lemmas, instances)
  • offset_peeling_coeff lemma — Generalized offset peeling at coefficient c: for 0 < c, 0 < θ < 1, max 0 (a·t^θ − c·t) ≤ offsetPeelingConstantC c θ · a^{1/(1−θ)} (weighted AM-GM).
    c θ a t :
    ℝ
    hc_pos :
    0 < c
    hθ_pos :
    0 < θ
    hθ_lt :
    θ < 1
    ha :
    0 ≤ a
    ht :
    0 ≤ t
    max 0 (a * t ^ θ - c * t) ≤ offsetPeelingConstantC c θ * a ^ (1 / (1 - θ))
    Proof (Lean source)
    lemma offset_peeling_coeff (c θ a t : ℝ) (hc_pos : 0 < c) (hθ_pos : 0 < θ) (hθ_lt : θ < 1) (ha : 0 ≤ a) (ht : 0 ≤ t) : max 0 (a * t ^ θ - c * t) ≤ offsetPeelingConstantC c θ * a ^ (1 / (1 - θ)) := by have hθ_nonneg : 0 ≤ θ := le_of_lt hθ_pos have hone_sub_nonneg : 0 ≤ 1 - θ := sub_nonneg.mpr (le_of_lt hθ_lt) have hone_sub_pos : 0 < 1 - θ := sub_pos.mpr hθ_lt have hθc_pos : 0 < θ / c := div_pos hθ_pos hc_pos have hθc_nonneg : 0 ≤ θ / c := le_of_lt hθc_pos let p₁ : ℝ := c * t / θ let p₂ : ℝ := (θ / c) ^ (θ / (1 - θ)) * a ^ (1 / (1 - θ)) have hp₁ : 0 ≤ p₁ := div_nonneg (mul_nonneg (le_of_lt hc_pos) ht) hθ_nonneg have hp₂ : 0 ≤ p₂ := mul_nonneg (Real.rpow_nonneg hθc_nonneg _) (Real.rpow_nonneg ha _) have hw : θ + (1 - θ) = 1 := by ring have hamg := Real.geom_mean_le_arith_mean2_weighted hθ_nonneg hone_sub_nonneg hp₁ hp₂ hw have hrhs : θ * p₁ + (1 - θ) * p₂ = c * t + offsetPeelingConstantC c θ * a ^ (1 / (1 - θ)) := by dsimp [p₁, p₂, offsetPeelingConstantC] field_simp [ne_of_gt hθ_pos, ne_of_gt hone_sub_pos, ne_of_gt hc_pos] have hlhs : p₁ ^ θ * p₂ ^ (1 - θ) = a * t ^ θ := by dsimp [p₁, p₂] rw [Real.mul_rpow (Real.rpow_nonneg hθc_nonneg _) (Real.rpow_nonneg ha _)] rw [← Real.rpow_mul hθc_nonneg] rw [← Real.rpow_mul ha] have hpow₁ : θ / (1 - θ) * (1 - θ) = θ := by field_simp [ne_of_gt hone_sub_pos] have hpow₂ : 1 / (1 - θ) * (1 - θ) = 1 := by field_simp [ne_of_gt hone_sub_pos] rw [hpow₁, hpow₂, Real.rpow_one] rw [← mul_assoc] rw [← Real.mul_rpow hp₁ hθc_nonneg] have hdiv : c * t / θ * (θ / c) = t := by field_simp [ne_of_gt hθ_pos, ne_of_gt hc_pos] rw [hdiv] ring have hmain : a * t ^ θ ≤ c * t + offsetPeelingConstantC c θ * a ^ (1 / (1 - θ)) := by rw [← hlhs] simpa [hrhs] using hamg have hR_nonneg : 0 ≤ offsetPeelingConstantC c θ * a ^ (1 / (1 - θ)) := by dsimp [offsetPeelingConstantC] exact mul_nonneg (mul_nonneg hone_sub_nonneg (Real.rpow_nonneg hθc_nonneg _)) (Real.rpow_nonneg ha _) exact max_le (by simpa using hR_nonneg) (by linarith)
    Causalean.Mathlib.OffsetPeeling.offset_peeling_coeff · Causalean/Mathlib/Analysis/OffsetPeeling.lean:38
  • offsetPeelingConstantC_nonneg lemma — The general offset-peeling constant is nonnegative when the offset is positive and the exponent lies between zero and one.
    c θ :
    ℝ
    hc_nonneg :
    0 ≤ c
    hθ_nonneg :
    0 ≤ θ
    hθ_le :
    θ ≤ 1
    Proof (Lean source)
    lemma offsetPeelingConstantC_nonneg (c θ : ℝ) (hc_nonneg : 0 ≤ c) (hθ_nonneg : 0 ≤ θ) (hθ_le : θ ≤ 1) : 0 ≤ offsetPeelingConstantC c θ := by have hsub : 0 ≤ 1 - θ := sub_nonneg.mpr hθ_le have hbase : 0 ≤ θ / c := div_nonneg hθ_nonneg hc_nonneg unfold offsetPeelingConstantC exact mul_nonneg hsub (Real.rpow_nonneg hbase _)
    Causalean.Mathlib.OffsetPeeling.offsetPeelingConstantC_nonneg · Causalean/Mathlib/Analysis/OffsetPeeling.lean:94
  • offset_peeling_coeff_nonneg_theta lemma — The general offset-peeling bound remains valid at exponent zero by the same constant formula.
    c θ a t :
    ℝ
    hc_pos :
    0 < c
    hθ_nonneg :
    0 ≤ θ
    hθ_lt :
    θ < 1
    ha :
    0 ≤ a
    ht :
    0 ≤ t
    max 0 (a * t ^ θ - c * t) ≤ offsetPeelingConstantC c θ * a ^ (1 / (1 - θ))
    Proof (Lean source)
    lemma offset_peeling_coeff_nonneg_theta (c θ a t : ℝ) (hc_pos : 0 < c) (hθ_nonneg : 0 ≤ θ) (hθ_lt : θ < 1) (ha : 0 ≤ a) (ht : 0 ≤ t) : max 0 (a * t ^ θ - c * t) ≤ offsetPeelingConstantC c θ * a ^ (1 / (1 - θ)) := by by_cases hθ_zero : θ = 0 · subst θ have hconst : offsetPeelingConstantC c 0 = 1 := by unfold offsetPeelingConstantC simp have hsub : a * t ^ (0 : ℝ) - c * t ≤ a := by rw [Real.rpow_zero] nlinarith [mul_nonneg (le_of_lt hc_pos) ht] simpa [hconst] using max_le ha hsub · exact offset_peeling_coeff c θ a t hc_pos (lt_of_le_of_ne hθ_nonneg (Ne.symm hθ_zero)) hθ_lt ha ht
    Causalean.Mathlib.OffsetPeeling.offset_peeling_coeff_nonneg_theta · Causalean/Mathlib/Analysis/OffsetPeeling.lean:104
  • offsetPeelingConstant_nonneg lemma — The offset-peeling constant for the quarter-offset case is nonnegative when the exponent lies between zero and one.
    θ :
    ℝ
    hθ_nonneg :
    0 ≤ θ
    hθ_le :
    θ ≤ 1
    Proof (Lean source)
    lemma offsetPeelingConstant_nonneg (θ : ℝ) (hθ_nonneg : 0 ≤ θ) (hθ_le : θ ≤ 1) : 0 ≤ offsetPeelingConstant θ := by simpa [offsetPeelingConstant, offsetPeelingConstantC, div_eq_mul_inv, mul_comm] using offsetPeelingConstantC_nonneg (1 / 4) θ (by norm_num) hθ_nonneg hθ_le
    Causalean.Mathlib.OffsetPeeling.offsetPeelingConstant_nonneg · Causalean/Mathlib/Analysis/OffsetPeeling.lean:123
  • offset_peeling_nonneg_theta lemma — The quarter-offset peeling bound remains valid at exponent zero by continuity of the constant formula.
    θ a t :
    ℝ
    hθ_nonneg :
    0 ≤ θ
    hθ_lt :
    θ < 1
    ha :
    0 ≤ a
    ht :
    0 ≤ t
    max 0 (a * t ^ θ - (1 / 4 : ℝ) * t) ≤ offsetPeelingConstant θ * a ^ (1 / (1 - θ))
    Proof (Lean source)
    lemma offset_peeling_nonneg_theta (θ a t : ℝ) (hθ_nonneg : 0 ≤ θ) (hθ_lt : θ < 1) (ha : 0 ≤ a) (ht : 0 ≤ t) : max 0 (a * t ^ θ - (1 / 4 : ℝ) * t) ≤ offsetPeelingConstant θ * a ^ (1 / (1 - θ)) := by simpa [offsetPeelingConstant, offsetPeelingConstantC, div_eq_mul_inv, mul_comm] using offset_peeling_coeff_nonneg_theta (1 / 4) θ a t (by norm_num) hθ_nonneg hθ_lt ha ht
    Causalean.Mathlib.OffsetPeeling.offset_peeling_nonneg_theta · Causalean/Mathlib/Analysis/OffsetPeeling.lean:143
  • max_two_split lemma — Split a clipped two-term offset across its summands: max 0 (a − 2r) ≤ max 0 (b − r) + max 0 (c − r) when a ≤ b + c.
    a b c r :
    ℝ
    h :
    a ≤ b + c
    max 0 (a - 2 * r) ≤ max 0 (b - r) + max 0 (c - r)
    Proof (Lean source)
    lemma max_two_split (a b c r : ℝ) (h : a ≤ b + c) : max 0 (a - 2 * r) ≤ max 0 (b - r) + max 0 (c - r) := by have hb : b - r ≤ max 0 (b - r) := le_max_right _ _ have hc : c - r ≤ max 0 (c - r) := le_max_right _ _ have hb0 : 0 ≤ max 0 (b - r) := le_max_left _ _ have hc0 : 0 ≤ max 0 (c - r) := le_max_left _ _ apply max_le · linarith · linarith
    Causalean.Mathlib.OffsetPeeling.max_two_split · Causalean/Mathlib/Analysis/OffsetPeeling.lean:154
Piecewise­Lipschitz 1 core · 0 supporting This module turns uniform Lipschitz bounds on consecutive real-valued pieces, together with matching endpoint values, into a bound across the full ordered chain. ★ piecewiseLipschitz_chain_bound

Lipschitz bounds for piecewise profiles

This module turns uniform Lipschitz bounds on consecutive real-valued pieces, together with matching endpoint values, into a bound across the full ordered chain.

theorem piecewiseLipschitz_chain_bound reviewed
Causalean.Mathlib.Analysis

Given a finite number k of pieces, a real-valued profile F_j on each piece, and a common Lipschitz constant C, suppose each of the first k profiles is C-Lipschitz on the unit interval and consecutive profiles among them agree at their shared endpoint, F_j(1) = F_(j+1)(0). For piece indices i and j with i ≤ j and j < k, and local coordinates u and v with u in the unit interval, v in the unit interval, and global positions ordered as i + u ≤ j + v, the profile difference |F_i(u) − F_j(v)| is at most C times the global distance (j + v) − (i + u).

Formal statement
k :
ℕ
F :
ℕ → ℝ → ℝ
C :
ℝ
hlocal :
∀ j < k, ∀ u ∈ Icc (0 : ℝ) 1, ∀ v ∈ Icc (0 : ℝ) 1, |F j u - F j v| ≤ C * |u - v|
hend :
∀ j
if
j + 1 < k
then
F j 1 = F (j + 1) 0
i j :
ℕ
hij :
i ≤ j
hjk :
j < k
u v :
ℝ
hu :
u ∈ Icc (0 : ℝ) 1
hv :
v ∈ Icc (0 : ℝ) 1
horder :
(i : ℝ) + u ≤ (j : ℝ) + v
|F i u - F j v| ≤ C * ((j : ℝ) - (i : ℝ) + v - u)
Proof (Lean source)
theorem piecewiseLipschitz_chain_bound (k : ℕ) (F : ℕ → ℝ → ℝ) (C : ℝ) (hlocal : ∀ j < k, ∀ u ∈ Icc (0 : ℝ) 1, ∀ v ∈ Icc (0 : ℝ) 1, |F j u - F j v| ≤ C * |u - v|) (hend : ∀ j, j + 1 < k → F j 1 = F (j + 1) 0) (i j : ℕ) (hij : i ≤ j) (hjk : j < k) (u v : ℝ) (hu : u ∈ Icc (0 : ℝ) 1) (hv : v ∈ Icc (0 : ℝ) 1) (horder : (i : ℝ) + u ≤ (j : ℝ) + v) : |F i u - F j v| ≤ C * ((j : ℝ) - (i : ℝ) + v - u) := by induction j, hij using Nat.le_induction generalizing v with | base => have huv : u ≤ v := by linarith simpa [abs_of_nonpos (sub_nonpos.mpr huv)] using hlocal i hjk u hu v hv | succ j hij ih => have hjk' : j < k := lt_trans (lt_succ_self j) hjk have hij' : (i : ℝ) ≤ j := by exact_mod_cast hij have hb := ih hjk' 1 (by norm_num) (by linarith [hu.2]) have he := hend j hjk have hl := hlocal (j + 1) hjk 0 (by norm_num) v hv rw [zero_sub, abs_neg, abs_of_nonneg hv.1] at hl calc |F i u - F (j + 1) v| ≤ |F i u - F j 1| + |F j 1 - F (j + 1) v| := abs_sub_le _ _ _ _ ≤ C * ((j : ℝ) - (i : ℝ) + 1 - u) + C * v := by exact add_le_add hb (by simpa only [he] using hl) _ = C * (((j + 1 : ℕ) : ℝ) - (i : ℝ) + v - u) := by push_cast ring
Causalean.Mathlib.Analysis.piecewiseLipschitz_chain_bound · Causalean/Mathlib/Analysis/PiecewiseLipschitz.lean:27
Rank­One­Gram­Pseudoinverse 6 core · 5 supporting This module identifies eigenvector-based rank-one truncation and pseudoinverse formulas with a choice-free algebraic construction from the left Gram matrix. ★ algebraicRankOnePseudoInverse_isMoorePenrose

Rank-one truncation and pseudoinverse from a two-row Gram matrix

This module identifies eigenvector-based rank-one truncation and pseudoinverse formulas with a choice-free algebraic construction from the left Gram matrix. It proves the Moore--Penrose identities and local continuous differentiability on the isolated-positive-root region.

def leftGram reviewed
Causalean.Mathlib.Analysis

Given a real matrix with two rows, its left Gram matrix records all pairwise inner products of those rows.

Definition (Lean source)
E :
Type u_1
shared
H :
Matrix (Fin 2) E ℝ
leftGram H :
Matrix (Fin 2) (Fin 2) ℝ
H * H.transpose
def eigenvectorRankOneTruncation reviewed
Causalean.Mathlib.Analysis

Given a real two-vector and a real matrix with two rows, the eigenvector-selected rank-one truncation multiplies the matrix on the left by the outer product of the vector with itself. No condition is imposed on the vector: this is an orthogonal rank-one projection of the rows only when the vector has unit length (the intended use is a unit upper eigenvector of the left Gram matrix); a non-unit vector rescales the result and the zero vector gives the zero matrix.

Definition (Lean source)
E :
Type u_1
shared
u :
Fin 2 → ℝ
H :
Matrix (Fin 2) E ℝ
eigenvectorRankOneTruncation u H :
Matrix (Fin 2) E ℝ
Causalean.Mathlib.Analysis.eigenvectorRankOneTruncation · Causalean/Mathlib/Analysis/RankOneGramPseudoinverse.lean:57
def eigenvectorRankOnePseudoInverse reviewed
Causalean.Mathlib.Analysis

Given a real two-vector and a real matrix with two rows, the eigenvector-selected rank-one pseudoinverse formula is the transpose of the matrix times the outer product of the vector with itself, divided by the larger root of the left Gram matrix (zero if that root is zero). No condition is imposed on the vector; this is the Moore–Penrose pseudoinverse of the rank-one truncation only when the vector is a unit upper eigenvector of the left Gram matrix.

Definition (Lean source)
E :
Type u_1
shared
u :
Fin 2 → ℝ
H :
Matrix (Fin 2) E ℝ
eigenvectorRankOnePseudoInverse u H :
Matrix E (Fin 2) ℝ
(lambda₁ (leftGram H))⁻¹ • (H.transpose * outerProjector u)
Causalean.Mathlib.Analysis.eigenvectorRankOnePseudoInverse · Causalean/Mathlib/Analysis/RankOneGramPseudoinverse.lean:62
def algebraicRankOneTruncation reviewed
Causalean.Mathlib.Analysis

Given a real matrix with two rows, the choice-free algebraic rank-one truncation applies the algebraic upper projector of its left Gram matrix. It has rank one under a strict gap between the two roots of the left Gram matrix; without a gap the projector's division by the zero gap makes it the zero matrix.

Definition (Lean source)
E :
Type u_1
shared
H :
Matrix (Fin 2) E ℝ
algebraicRankOneTruncation H :
Matrix (Fin 2) E ℝ
Causalean.Mathlib.Analysis.algebraicRankOneTruncation · Causalean/Mathlib/Analysis/RankOneGramPseudoinverse.lean:67
def algebraicRankOnePseudoInverse reviewed
Causalean.Mathlib.Analysis

Given a real matrix with two rows, the choice-free algebraic rank-one pseudoinverse transposes the algebraically projected matrix and divides by the upper Gram root.

Definition (Lean source)
E :
Type u_1
shared
H :
Matrix (Fin 2) E ℝ
algebraicRankOnePseudoInverse H :
Matrix E (Fin 2) ℝ
(lambda₁ (leftGram H))⁻¹ • (H.transpose * topProjector (leftGram H))
Causalean.Mathlib.Analysis.algebraicRankOnePseudoInverse · Causalean/Mathlib/Analysis/RankOneGramPseudoinverse.lean:72
theorem algebraicRankOnePseudoInverse_isMoorePenrose reviewed
Causalean.Mathlib.Analysis

Given a real two-row matrix with a strict positive upper left-Gram root, the algebraic rank-one pseudoinverse satisfies all four Moore--Penrose equations for the algebraic rank-one truncation.

Formal statement
E :
Type u_1
Matrix (Fin 2) E ℝ
shared
hgap :
hpos :
A * Aplus * A = A
Aplus * A * Aplus = Aplus
(A * Aplus).IsHermitian
(Aplus * A).IsHermitian
Proof (Lean source)
theorem algebraicRankOnePseudoInverse_isMoorePenrose {H : Matrix (Fin 2) E ℝ} (hgap : leftGram H ∈ strictGapSet) (hpos : 0 < lambda₁ (leftGram H)) : let A := algebraicRankOneTruncation H let Aplus := algebraicRankOnePseudoInverse H A * Aplus * A = A ∧ Aplus * A * Aplus = Aplus ∧ (A * Aplus).IsHermitian ∧ (Aplus * A).IsHermitian := by let G := leftGram H let P := topProjector G let l := lambda₁ G have hG : G.IsHermitian := leftGram_isHermitian H have hP : P.IsHermitian := topProjector_isHermitian hG have hPP : P * P = P := topProjector_mul_self hG hgap have hl : l ≠ 0 := ne_of_gt hpos have hdecomp : G = (lambda₁ G - lambda₂ G) • P + lambda₂ G • 1 := by have hne : lambda₁ G - lambda₂ G ≠ 0 := ne_of_gt (sub_pos.mpr hgap) ext i j simp [P, topProjector] field_simp [hne] ring have hPG : P * G = l • P := by rw [hdecomp, Matrix.mul_add, Matrix.mul_smul, Matrix.mul_smul, hPP, Matrix.mul_one] ext i j simp [l] ring have hAAplus : algebraicRankOneTruncation H * algebraicRankOnePseudoInverse H = P := by rw [algebraicRankOneTruncation, algebraicRankOnePseudoInverse, Matrix.mul_smul] change (lambda₁ G)⁻¹ • ((P * H) * (H.transpose * P)) = P rw [← Matrix.mul_assoc (P * H) H.transpose P, Matrix.mul_assoc P H H.transpose] change (lambda₁ G)⁻¹ • (P * G * P) = P rw [hPG, Matrix.smul_mul, hPP] simp [l, hl] have hAplusP : algebraicRankOnePseudoInverse H * P = algebraicRankOnePseudoInverse H := by rw [algebraicRankOnePseudoInverse, Matrix.smul_mul, Matrix.mul_assoc, hPP] have hAplusA : algebraicRankOnePseudoInverse H * algebraicRankOneTruncation H = l⁻¹ • (H.transpose * P * H) := by rw [algebraicRankOnePseudoInverse, algebraicRankOneTruncation, Matrix.smul_mul] change (lambda₁ G)⁻¹ • ((H.transpose * P) * (P * H)) = (lambda₁ G)⁻¹ • (H.transpose * P * H) rw [Matrix.mul_assoc, ← Matrix.mul_assoc P P H, hPP] rw [Matrix.mul_assoc] dsimp only refine ⟨?_, ?_, hAAplus ▸ hP, ?_⟩ · rw [hAAplus] change P * (P * H) = P * H rw [← Matrix.mul_assoc, hPP] · rw [Matrix.mul_assoc, hAAplus, hAplusP] · rw [hAplusA] apply (Matrix.isHermitian_conjTranspose_mul_mul H hP).smul simp [isSelfAdjoint_iff]
5 supporting declarations (lemmas, instances)
Rank­One­Wald­Smoothness 4 core · 3 supporting This module composes the algebraic rank-one pseudoinverse with a target direction and an outcome direction. ★ algebraicWaldFunctional_hasLocallyBoundedFDerivAt

Smoothness of the induced rank-one Wald functional

This module composes the algebraic rank-one pseudoinverse with a target direction and an outcome direction. Its regularity condition is solely a positive isolated upper root of the left Gram matrix and makes no continuity assumption about an eigenvector selector.

abbrev WaldInput reviewed
Causalean.Mathlib.Analysis

Given a finite outcome-coordinate type, an input to the rank-one Wald functional consists of a real two-row matrix, an outcome direction, and a two-dimensional target direction.

Definition (Lean source)
E :
Type*
WaldInput E :
Type u_2
Matrix (Fin 2) E ℝ × ((E → ℝ) × (Fin 2 → ℝ))
Causalean.Mathlib.Analysis.WaldInput · Causalean/Mathlib/Analysis/RankOneWaldSmoothness.lean:20
def waldRegularSet reviewed
Causalean.Mathlib.Analysis

The regularity region contains rank-one Wald inputs whose left Gram matrix has distinct roots and a strictly positive upper root.

Definition (Lean source)
E :
Type u_1
shared
waldRegularSet :
{x | leftGram x.1 ∈ strictGapSet ∧ 0 < lambda₁ (leftGram x.1)}
Causalean.Mathlib.Analysis.waldRegularSet · Causalean/Mathlib/Analysis/RankOneWaldSmoothness.lean:24 · uses WaldInput
def algebraicWaldFunctional reviewed
Causalean.Mathlib.Analysis

Given a rank-one Wald input, the choice-free algebraic Wald functional applies the algebraic rank-one pseudoinverse to the target direction and pairs the result with the outcome direction.

Definition (Lean source)
E :
Type u_1
shared
x :
algebraicWaldFunctional x :
ℝ
Causalean.Mathlib.Analysis.algebraicWaldFunctional · Causalean/Mathlib/Analysis/RankOneWaldSmoothness.lean:28 · uses WaldInput
theorem algebraicWaldFunctional_hasLocallyBoundedFDerivAt reviewed
Causalean.Mathlib.Analysis

Given a rank-one Wald input in the regularity region, the algebraic Wald functional has a bounded Fréchet derivative on some neighborhood of that input.

Formal statement
E :
Type u_1
shared
hx :
x ∈ waldRegularSet (E := E)
Proof (Lean source)
theorem algebraicWaldFunctional_hasLocallyBoundedFDerivAt {x : WaldInput E} (hx : x ∈ waldRegularSet (E := E)) : HasLocallyBoundedFDerivAt (algebraicWaldFunctional (E := E)) x := by exact ContDiffAt.hasLocallyBoundedFDerivAt (contDiffAt_algebraicWaldFunctional hx)
3 supporting declarations (lemmas, instances)
Rectangular­Signal­Singular­Values 4 core · 7 supporting This module provides reusable finite-dimensional real singular-value results for rectangular products, orthonormal compression to an adjoint range, and vertical stacking. ★ singularValues_product_adjoint_lower_bound★ singularValues_le_verticalStack_left★ singularValues_comp_linearIsometry_of_range_eq_adjoint_range

Rectangular signal singular values

This module provides reusable finite-dimensional real singular-value results for rectangular products, orthonormal compression to an adjoint range, and vertical stacking. The product bound works on the rank-sized signal subspace rather than assuming an ambient adjoint is injective; all results retain Mathlib's zero-extended singular-value indexing.

theorem singularValues_product_adjoint_lower_bound reviewed
Causalean.Mathlib.Analysis

Given a left rectangular factor, a square core, a right rectangular factor, and a full-column-rank assumption for the right rectangular factor, the last signal singular value of their adjoint product is at least the product of the three least signal singular values.

Formal statement
E :
Type u_1
shared
F :
Type u_2
shared
K :
Type u_3
shared
A :
K →ₗ[ℝ] F
D :
K →ₗ[ℝ] K
B :
K →ₗ[ℝ] E
hB :
A.singularValues (finrank ℝ K - 1) * D.singularValues (finrank ℝ K - 1) * B.singularValues (finrank ℝ K - 1)
≤ (A ∘ₗ D ∘ₗ B.adjoint).singularValues (finrank ℝ K - 1)
Proof (Lean source)
theorem singularValues_product_adjoint_lower_bound [Nontrivial K] (A : K →ₗ[ℝ] F) (D : K →ₗ[ℝ] K) (B : K →ₗ[ℝ] E) (hB : Injective B) : A.singularValues (finrank ℝ K - 1) * D.singularValues (finrank ℝ K - 1) * B.singularValues (finrank ℝ K - 1) ≤ (A ∘ₗ D ∘ₗ B.adjoint).singularValues (finrank ℝ K - 1) := by apply le_singularValues_of_subspace (A ∘ₗ D ∘ₗ B.adjoint) B.range · rw [B.finrank_range_of_inj hB] exact sub_lt (Module.finrank_pos) (by omega) · intro y hy have hBadj := least_singularValue_mul_norm_le_adjoint_on_range B y hy have hDleast := least_singularValue_mul_norm_le D (B.adjoint y) have hAleast := least_singularValue_mul_norm_le A (D (B.adjoint y)) calc (A.singularValues (finrank ℝ K - 1) * D.singularValues (finrank ℝ K - 1) * B.singularValues (finrank ℝ K - 1)) * ‖y‖ = (A.singularValues (finrank ℝ K - 1) * D.singularValues (finrank ℝ K - 1)) * (B.singularValues (finrank ℝ K - 1) * ‖y‖) := by ring _ ≤ (A.singularValues (finrank ℝ K - 1) * D.singularValues (finrank ℝ K - 1)) * ‖B.adjoint y‖ := mul_le_mul_of_nonneg_left hBadj (mul_nonneg (A.singularValues_nonneg _) (D.singularValues_nonneg _)) _ = A.singularValues (finrank ℝ K - 1) * (D.singularValues (finrank ℝ K - 1) * ‖B.adjoint y‖) := by ring _ ≤ A.singularValues (finrank ℝ K - 1) * ‖D (B.adjoint y)‖ := mul_le_mul_of_nonneg_left hDleast (A.singularValues_nonneg _) _ ≤ ‖A (D (B.adjoint y))‖ := hAleast _ = ‖(A ∘ₗ D ∘ₗ B.adjoint) y‖ := rfl
Causalean.Mathlib.Analysis.singularValues_product_adjoint_lower_bound · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:133
def verticalStack reviewed
Causalean.Mathlib.Analysis

For a real inner-product domain space, two real inner-product codomain spaces, and two real linear maps from the common domain into those respective codomains, the vertical stack is the real linear map sending each domain vector to its ordered pair of component outputs, equipped with the Hilbert direct-sum norm.

Definition (Lean source)
E :
Type u_1
shared
F₀ :
Type u_2
shared
F₁ :
Type u_3
shared
M₀ :
E →ₗ[ℝ] F₀
M₁ :
E →ₗ[ℝ] F₁
verticalStack M₀ M₁ :
E →ₗ[ℝ] WithLp 2 (F₀ × F₁)
(WithLp.linearEquiv 2 ℝ (F₀ × F₁)).symm.comp (M₀.prod M₁)
theorem singularValues_le_verticalStack_left reviewed
Causalean.Mathlib.Analysis

Given a first real linear map, a second compatible real linear map, and a singular-value index, the vertical stack's indexed singular value is at least that of the first component.

Formal statement
E :
Type u_1
shared
F₀ :
Type u_2
shared
F₁ :
Type u_3
shared
M₀ :
E →ₗ[ℝ] F₀
M₁ :
E →ₗ[ℝ] F₁
j :
ℕ
M₀.singularValues j ≤ (verticalStack M₀ M₁).singularValues j
Proof (Lean source)
theorem singularValues_le_verticalStack_left (M₀ : E →ₗ[ℝ] F₀) (M₁ : E →ₗ[ℝ] F₁) (j : ℕ) : M₀.singularValues j ≤ (verticalStack M₀ M₁).singularValues j := by apply singularValues_le_of_gram_sub_isPositive M₀ (verticalStack M₀ M₁) rw [verticalStack_adjoint_comp_self] simpa using M₁.isPositive_adjoint_comp_self
Causalean.Mathlib.Analysis.singularValues_le_verticalStack_left · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:263 · uses verticalStack
theorem singularValues_comp_linearIsometry_of_range_eq_adjoint_range reviewed
Causalean.Mathlib.Analysis

Given a real linear map, orthonormal signal coordinates, an equality between the coordinate range and the map's adjoint range, and a singular-value index, compressing to those coordinates preserves the indexed singular value.

Formal statement
E :
Type u_1
shared
F :
Type u_2
shared
K :
Type u_3
shared
M :
E →ₗ[ℝ] F
V :
K →ₗᵢ[ℝ] E
hrange :
V.toLinearMap.range = M.adjoint.range
j :
ℕ
(M ∘ₗ V.toLinearMap).singularValues j = M.singularValues j
Proof (Lean source)
theorem singularValues_comp_linearIsometry_of_range_eq_adjoint_range (M : E →ₗ[ℝ] F) (V : K →ₗᵢ[ℝ] E) (hrange : V.toLinearMap.range = M.adjoint.range) (j : ℕ) : (M ∘ₗ V.toLinearMap).singularValues j = M.singularValues j := by let A := M ∘ₗ V.toLinearMap have hfin : finrank ℝ K = finrank ℝ M.range := by calc finrank ℝ K = finrank ℝ V.toLinearMap.range := V.equivRange.toLinearEquiv.finrank_eq _ = finrank ℝ M.adjoint.range := by rw [hrange] _ = finrank ℝ M.range := M.finrank_range_adjoint have hrangeA : A.range = M.range := by change (M ∘ₗ V.toLinearMap).range = M.range rw [LinearMap.range_comp, hrange, ← LinearMap.range_comp] exact M.range_self_comp_adjoint by_cases hj : j < finrank ℝ M.range · have hjK : j < finrank ℝ K := by omega apply le_antisymm · obtain ⟨S, hdimS, hboundS⟩ := Causalean.Mathlib.Analysis.exists_large_subspace_norm_le_singularValues M (hj.trans_le (LinearMap.finrank_range_le M)) let T : Submodule ℝ K := S.comap V.toLinearMap have hmapT : T.map V.toLinearMap = V.toLinearMap.range ⊓ S := by simpa [T, inf_comm] using Submodule.map_comap_eq V.toLinearMap S have hdim_map (U : Submodule ℝ K) : finrank ℝ (U.map V.toLinearMap) = finrank ℝ U := by let f : U →ₗ[ℝ] E := V.toLinearMap.comp U.subtype have hf : Injective f := V.injective.comp U.injective_subtype have hfrange : f.range = U.map V.toLinearMap := by simp [f, LinearMap.range_comp] rw [← hfrange, f.finrank_range_of_inj hf] have hdimT : finrank ℝ K ≤ finrank ℝ T + j := by have hsum := Submodule.finrank_sup_add_finrank_inf_eq V.toLinearMap.range S have hsup := Submodule.finrank_le (V.toLinearMap.range ⊔ S) have hfinV : finrank ℝ V.toLinearMap.range = finrank ℝ K := by simpa using V.equivRange.toLinearEquiv.finrank_eq.symm rw [← hmapT, hdim_map, hfinV] at hsum omega apply singularValues_le_of_large_subspace A hjK T hdimT intro x hx simpa [A] using hboundS (V x) hx · obtain ⟨T, hdimT, hboundT⟩ := Causalean.Mathlib.Analysis.exists_large_subspace_norm_le_singularValues A hjK let U : Submodule ℝ E := T.map V.toLinearMap let S : Submodule ℝ E := U ⊔ M.ker have hUorth : U ≤ M.kerᗮ := by rw [M.orthogonal_ker, ← hrange] exact LinearMap.map_le_range have hdisjoint : Disjoint U M.ker := M.ker.orthogonal_disjoint.symm.mono hUorth le_rfl have hdimU : finrank ℝ U = finrank ℝ T := by let f : T →ₗ[ℝ] E := V.toLinearMap.comp T.subtype have hf : Injective f := V.injective.comp T.injective_subtype have hfrange : f.range = U := by simp [f, U, LinearMap.range_comp] rw [← hfrange, f.finrank_range_of_inj hf] have hdimS : finrank ℝ E ≤ finrank ℝ S + j := by have hsum := Submodule.finrank_sup_add_finrank_inf_eq U M.ker rw [hdisjoint.eq_bot, finrank_bot, add_zero, hdimU] at hsum have hranknull := M.finrank_range_add_finrank_ker dsimp [S] omega apply singularValues_le_of_large_subspace M (hj.trans_le (LinearMap.finrank_range_le M)) S hdimS intro x hx rcases Submodule.mem_sup.mp hx with ⟨u, hu, k, hk, rfl⟩ rcases hu with ⟨t, ht, rfl⟩ have hvorth : V t ∈ M.kerᗮ := hUorth (by exact ⟨t, ht, rfl⟩) have hinter : inner ℝ (V t) k = 0 := (M.ker.mem_orthogonal' (V t)).mp hvorth k hk have hnormsq : ‖V t + k‖ ^ 2 = ‖V t‖ ^ 2 + ‖k‖ ^ 2 := by simpa [pow_two] using norm_add_sq_eq_norm_sq_add_norm_sq_of_inner_eq_zero (V t) k hinter have hnormle : ‖t‖ ≤ ‖V t + k‖ := by rw [V.norm_map] at hnormsq nlinarith [sq_nonneg ‖k‖, norm_nonneg (V t + k), norm_nonneg t] calc ‖M (V t + k)‖ = ‖A t‖ := by simp [A, LinearMap.mem_ker.mp hk] _ ≤ A.singularValues j * ‖t‖ := hboundT t ht _ ≤ A.singularValues j * ‖V t + k‖ := mul_le_mul_of_nonneg_left hnormle (A.singularValues_nonneg j) · have hle : finrank ℝ M.range ≤ j := Nat.le_of_not_gt hj have hleA : finrank ℝ A.range ≤ j := by rwa [hrangeA] rw [A.singularValues_eq_zero_iff_le_finrank_range.mpr hleA, M.singularValues_eq_zero_iff_le_finrank_range.mpr hle]
Causalean.Mathlib.Analysis.singularValues_comp_linearIsometry_of_range_eq_adjoint_range · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:292
7 supporting declarations (lemmas, instances)
  • le_singularValues_of_subspace theorem — Given a real linear map, a candidate signal subspace, a singular-value index, an expansion factor, a dimension condition putting that index below the signal-subspace dimension, and a lower expansion bound on the signal subspace, the indexed singular value is at least that factor.
    E :
    Type u_1
    shared
    F :
    Type u_2
    shared
    T :
    E →ₗ[ℝ] F
    S :
    Submodule ℝ E
    j :
    ℕ
    c :
    ℝ
    hdim :
    j < finrank ℝ S
    hbound :
    ∀ x : E
    if
    x ∈ S
    then
    c * ‖x‖ ≤ ‖T x‖
    c ≤ T.singularValues j
    Proof (Lean source)
    theorem le_singularValues_of_subspace (T : E →ₗ[ℝ] F) (S : Submodule ℝ E) {j : ℕ} {c : ℝ} (hdim : j < finrank ℝ S) (hbound : ∀ x : E, x ∈ S → c * ‖x‖ ≤ ‖T x‖) : c ≤ T.singularValues j := by have hj : j < finrank ℝ E := lt_of_lt_of_le hdim (Submodule.finrank_le S) obtain ⟨L, hdimL, hTL⟩ := Causalean.Mathlib.Analysis.exists_large_subspace_norm_le_singularValues T hj have hinfne : S ⊓ L ≠ ⊥ := by intro hinf have hformula := S.finrank_sup_add_finrank_inf_eq L have hsup := Submodule.finrank_le (S ⊔ L) rw [hinf, finrank_bot, add_zero] at hformula omega obtain ⟨x, hx, hx0⟩ := Submodule.exists_mem_ne_zero_of_ne_bot hinfne have hlower := hbound x hx.1 have hupper := hTL x hx.2 have hxnorm : 0 < ‖x‖ := norm_pos_iff.mpr hx0 nlinarith
    Causalean.Mathlib.Analysis.le_singularValues_of_subspace · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:32
  • least_singularValue_mul_norm_le theorem — Given a finite-dimensional real linear map and a vector in its domain, the map expands that vector by at least its last domain-indexed singular value.
    E :
    Type u_1
    shared
    F :
    Type u_2
    shared
    T :
    E →ₗ[ℝ] F
    x :
    E
    T.singularValues (finrank ℝ E - 1) * ‖x‖ ≤ ‖T x‖
    Proof (Lean source)
    theorem least_singularValue_mul_norm_le [Nontrivial E] (T : E →ₗ[ℝ] F) (x : E) : T.singularValues (finrank ℝ E - 1) * ‖x‖ ≤ ‖T x‖ := by let hself := T.isSymmetric_adjoint_comp_self let b := hself.eigenvectorBasis rfl have hdimpos : 0 < finrank ℝ E := Module.finrank_pos have hj : finrank ℝ E - 1 < finrank ℝ E := by omega have hof (r : ℝ) : (RCLike.ofReal r : ℝ) = r := by calc (RCLike.ofReal r : ℝ) = RCLike.re (RCLike.ofReal r : ℝ) := (RCLike.re_to_real).symm _ = r := RCLike.ofReal_re r have hnorm_sq : ‖T x‖ ^ 2 = ∑ i : Fin (finrank ℝ E), hself.eigenvalues rfl i * ‖inner ℝ (b i) x‖ ^ 2 := by calc ‖T x‖ ^ 2 = inner ℝ (T x) (T x) := (real_inner_self_eq_norm_sq _).symm _ = inner ℝ x ((T.adjoint ∘ₗ T) x) := by exact (T.adjoint_inner_right x (T x)).symm _ = ∑ i, inner ℝ x (b i) * inner ℝ (b i) ((T.adjoint ∘ₗ T) x) := (b.sum_inner_mul_inner x ((T.adjoint ∘ₗ T) x)).symm _ = ∑ i, hself.eigenvalues rfl i * ‖inner ℝ (b i) x‖ ^ 2 := by apply Finset.sum_congr rfl intro i _ rw [← hself (b i) x, hself.apply_eigenvectorBasis] simp only [real_inner_smul_left, hof] rw [real_inner_comm x (b i)] simp only [Real.norm_eq_abs, sq_abs] ring have hlam (i : Fin (finrank ℝ E)) : T.singularValues (finrank ℝ E - 1) ^ 2 ≤ hself.eigenvalues rfl i := by rw [T.sq_singularValues_fin rfl ⟨finrank ℝ E - 1, hj⟩] exact hself.eigenvalues_antitone rfl (by apply Fin.le_iff_val_le_val.mpr exact Nat.le_sub_one_of_lt i.isLt) apply (sq_le_sq₀ (mul_nonneg (T.singularValues_nonneg _) (norm_nonneg _)) (norm_nonneg _)).mp rw [mul_pow, hnorm_sq, ← b.sum_sq_norm_inner_right x, Finset.mul_sum] exact Finset.sum_le_sum fun i _ => mul_le_mul_of_nonneg_right (hlam i) (sq_nonneg _)
    Causalean.Mathlib.Analysis.least_singularValue_mul_norm_le · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:60
  • least_singularValue_mul_norm_le_adjoint_on_range theorem — Given a real linear map and a vector in its column space, the adjoint expands that signal vector by at least the map's least singular value.
    E :
    Type u_1
    shared
    K :
    Type u_3
    shared
    B :
    K →ₗ[ℝ] E
    y :
    E
    hy :
    y ∈ B.range
    B.singularValues (finrank ℝ K - 1) * ‖y‖ ≤ ‖B.adjoint y‖
    Proof (Lean source)
    theorem least_singularValue_mul_norm_le_adjoint_on_range [Nontrivial K] (B : K →ₗ[ℝ] E) (y : E) (hy : y ∈ B.range) : B.singularValues (finrank ℝ K - 1) * ‖y‖ ≤ ‖B.adjoint y‖ := by rcases hy with ⟨z, rfl⟩ by_cases hz : z = 0 · simp [hz] have hzpos : 0 < ‖z‖ := norm_pos_iff.mpr hz have hleast := least_singularValue_mul_norm_le B z have hcs := real_inner_le_norm z (B.adjoint (B z)) have hadj : inner ℝ z (B.adjoint (B z)) = ‖B z‖ ^ 2 := by calc inner ℝ z (B.adjoint (B z)) = inner ℝ (B z) (B z) := B.adjoint_inner_right z (B z) _ = ‖B z‖ ^ 2 := real_inner_self_eq_norm_sq _ rw [hadj] at hcs have hsv := B.singularValues_nonneg (finrank ℝ K - 1) have hBnorm := norm_nonneg (B z) have hadjnorm := norm_nonneg (B.adjoint (B z)) nlinarith
    Causalean.Mathlib.Analysis.least_singularValue_mul_norm_le_adjoint_on_range · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:107
  • singularValues_mul_mul_transpose_lower_bound theorem — Given finite real left and right matrices, a finite real square core, and a full-column-rank assumption for the right matrix, the last signal singular value of their transpose product is bounded below by the product of the three least signal singular values.
    m n k :
    A :
    Matrix m k ℝ
    D :
    Matrix k k ℝ
    B :
    Matrix n k ℝ
    hB :
    Injective B.toEuclideanLin
    A.toEuclideanLin.singularValues (card k - 1) * D.toEuclideanLin.singularValues (card k - 1) * B.toEuclideanLin.singularValues (card k - 1)
    ≤ (A * D * B.transpose).toEuclideanLin.singularValues (card k - 1)
    Proof (Lean source)
    theorem Matrix.singularValues_mul_mul_transpose_lower_bound {m n k : Type*} [Fintype m] [Fintype n] [Fintype k] [DecidableEq n] [DecidableEq k] [Nonempty k] (A : Matrix m k ℝ) (D : Matrix k k ℝ) (B : Matrix n k ℝ) (hB : Injective B.toEuclideanLin) : A.toEuclideanLin.singularValues (card k - 1) * D.toEuclideanLin.singularValues (card k - 1) * B.toEuclideanLin.singularValues (card k - 1) ≤ (A * D * B.transpose).toEuclideanLin.singularValues (card k - 1) := by have htrans : B.transpose = B.conjTranspose := by ext i j simp [Matrix.conjTranspose_apply] have hlin : (A * D * B.transpose).toEuclideanLin = A.toEuclideanLin ∘ₗ D.toEuclideanLin ∘ₗ B.toEuclideanLin.adjoint := by rw [← Matrix.toEuclideanLin_conjTranspose_eq_adjoint B, ← htrans] apply LinearMap.ext intro x apply PiLp.ext intro i simp only [LinearMap.comp_apply, Matrix.ofLp_toEuclideanLin_apply, Matrix.mulVec_mulVec] rw [Matrix.mul_assoc] have h := singularValues_product_adjoint_lower_bound A.toEuclideanLin D.toEuclideanLin B.toEuclideanLin hB simpa only [finrank_euclideanSpace, ← hlin] using h
    Causalean.Mathlib.Analysis.Matrix.singularValues_mul_mul_transpose_lower_bound · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:174
  • verticalStack_adjoint_comp_self theorem — Given two real linear maps with a common domain, the Gram operator of their vertical stack is the sum of their two component Gram operators.
    E :
    Type u_1
    shared
    F₀ :
    Type u_2
    shared
    F₁ :
    Type u_3
    shared
    M₀ :
    E →ₗ[ℝ] F₀
    M₁ :
    E →ₗ[ℝ] F₁
    (verticalStack M₀ M₁).adjoint ∘ₗ verticalStack M₀ M₁
    = (M₀.adjoint ∘ₗ M₀) + (M₁.adjoint ∘ₗ M₁)
    Proof (Lean source)
    theorem verticalStack_adjoint_comp_self (M₀ : E →ₗ[ℝ] F₀) (M₁ : E →ₗ[ℝ] F₁) : (verticalStack M₀ M₁).adjoint ∘ₗ verticalStack M₀ M₁ = (M₀.adjoint ∘ₗ M₀) + (M₁.adjoint ∘ₗ M₁) := by ext x apply ext_inner_right ℝ intro y simp only [LinearMap.comp_apply, LinearMap.add_apply] rw [(verticalStack M₀ M₁).adjoint_inner_left, inner_add_left, M₀.adjoint_inner_left, M₁.adjoint_inner_left] rfl
    Causalean.Mathlib.Analysis.verticalStack_adjoint_comp_self · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:222
  • singularValues_le_verticalStack_right theorem — Given a first compatible real linear map, a second real linear map, and a singular-value index, the vertical stack's indexed singular value is at least that of the second component.
    E :
    Type u_1
    shared
    F₀ :
    Type u_2
    shared
    F₁ :
    Type u_3
    shared
    M₀ :
    E →ₗ[ℝ] F₀
    M₁ :
    E →ₗ[ℝ] F₁
    j :
    ℕ
    M₁.singularValues j ≤ (verticalStack M₀ M₁).singularValues j
    Proof (Lean source)
    theorem singularValues_le_verticalStack_right (M₀ : E →ₗ[ℝ] F₀) (M₁ : E →ₗ[ℝ] F₁) (j : ℕ) : M₁.singularValues j ≤ (verticalStack M₀ M₁).singularValues j := by apply singularValues_le_of_gram_sub_isPositive M₁ (verticalStack M₀ M₁) rw [verticalStack_adjoint_comp_self] simpa [add_comm] using M₀.isPositive_adjoint_comp_self
    Causalean.Mathlib.Analysis.singularValues_le_verticalStack_right · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:273
  • singularValues_comp_linearIsometry_last theorem — Given a real linear map, orthonormal coordinates for its adjoint range, the last coordinate-indexed singular value after compression equals the corresponding singular value before compression.
    E :
    Type u_1
    shared
    F :
    Type u_2
    shared
    K :
    Type u_3
    shared
    M :
    E →ₗ[ℝ] F
    V :
    K →ₗᵢ[ℝ] E
    hrange :
    V.toLinearMap.range = M.adjoint.range
    (M ∘ₗ V.toLinearMap).singularValues (finrank ℝ K - 1) = M.singularValues (finrank ℝ K - 1)
    Proof (Lean source)
    theorem singularValues_comp_linearIsometry_last (M : E →ₗ[ℝ] F) (V : K →ₗᵢ[ℝ] E) (hrange : V.toLinearMap.range = M.adjoint.range) : (M ∘ₗ V.toLinearMap).singularValues (finrank ℝ K - 1) = M.singularValues (finrank ℝ K - 1) := by exact singularValues_comp_linearIsometry_of_range_eq_adjoint_range M V hrange _
    Causalean.Mathlib.Analysis.singularValues_comp_linearIsometry_last · Causalean/Mathlib/Analysis/RectangularSignalSingularValues.lean:386
Retained­SVD 4 core · 4 supporting A retained singular-value decomposition consists of r strictly positive singular values with orthonormal left and right singular directions; it represents the rank-r matrix U·diag(σ)·V obtained by keeping exactly those d ★ inverse_eq_moorePenroseInverse

Retained finite singular-value decompositions

A retained singular-value decomposition consists of r strictly positive singular values with orthonormal left and right singular directions; it represents the rank-r matrix U·diag(σ)·V obtained by keeping exactly those directions. Replacing each singular value by its reciprocal gives the Moore–Penrose pseudoinverse of that matrix, whose operator norm is at most 1/s when every retained singular value is at least s > 0; the represented matrix has rank exactly r.

Main definitions

* RetainedSVD — positive singular values with orthonormal left columns and right rows. * RetainedSVD.matrix, RetainedSVD.inverse — the represented matrix and its reciprocal expansion Vᵀ·diag(1/σ)·Uᵀ.

Main results

* RetainedSVD.inverse_eq_moorePenroseInverse — the reciprocal expansion is the Moore–Penrose inverse of the represented matrix. * RetainedSVD.norm_inverse_le — its operator norm is at most 1/s under a lower bound s on the singular values. * RetainedSVD.rank_matrix — the represented matrix has rank r.

structure RetainedSVD reviewed
Causalean.Mathlib.Analysis

A retained singular-value decomposition with a given number r of directions and given numbers of rows and columns: r strictly positive singular values, a left factor with r orthonormal columns, and a right factor with r orthonormal rows. It represents the matrix obtained by retaining precisely these directions, independently of how the ambient SVD was chosen.

Definition (Lean source)
r rows cols :
ℕ
sigma :
Fin r → ℝ
left :
RectMatrix rows r
right :
RectMatrix r cols
sigma_pos :
∀ i, 0 < sigma i
left_orthonormal :
left.transpose * left = (1 : RectMatrix r r)
right_orthonormal :
right * right.transpose = (1 : RectMatrix r r)
Causalean.Mathlib.Analysis.RetainedSVD · Causalean/Mathlib/Analysis/RetainedSVD.lean:34
def matrix reviewed
Causalean.Mathlib.Analysis.RetainedSVD

A retained singular-value decomposition determines the reconstructed retained matrix by multiplying its left directions, diagonal singular values, and right directions.

Definition (Lean source)
r rows cols :
ℕ
S :
RetainedSVD r rows cols
matrix S :
RectMatrix rows cols
S.left * diagonal S.sigma * S.right
Causalean.Mathlib.Analysis.RetainedSVD.matrix · Causalean/Mathlib/Analysis/RetainedSVD.lean:47 · uses RectMatrix , RetainedSVD
def inverse reviewed
Causalean.Mathlib.Analysis.RetainedSVD

A retained singular-value decomposition determines its reciprocal retained matrix by replacing each retained singular value by its reciprocal.

Definition (Lean source)
r rows cols :
ℕ
S :
RetainedSVD r rows cols
inverse S :
RectMatrix cols rows
S.right.transpose * diagonal (fun i => (S.sigma i)⁻¹) * S.left.transpose
Causalean.Mathlib.Analysis.RetainedSVD.inverse · Causalean/Mathlib/Analysis/RetainedSVD.lean:52 · uses RectMatrix , RetainedSVD
theorem inverse_eq_moorePenroseInverse reviewed
Causalean.Mathlib.Analysis.RetainedSVD

For a retained singular-value decomposition with positive singular values, its reciprocal retained matrix equals the Moore–Penrose inverse of its reconstructed matrix.

Formal statement
r rows cols :
ℕ
S :
RetainedSVD r rows cols
S.inverse = moorePenroseInverse S.matrix
Proof (Lean source)
theorem RetainedSVD.inverse_eq_moorePenroseInverse {r rows cols : ℕ} (S : RetainedSVD r rows cols) : S.inverse = moorePenroseInverse S.matrix := by let D : RectMatrix r r := Matrix.diagonal S.sigma let E : RectMatrix r r := Matrix.diagonal (fun i => (S.sigma i)⁻¹) have hDE : D * E = 1 := by ext i j by_cases hij : i = j · subst j simp [D, E, Matrix.mul_apply, Matrix.diagonal_apply, mul_inv_cancel₀ (ne_of_gt (S.sigma_pos i))] · simp [D, E, Matrix.mul_apply, Matrix.diagonal_apply, hij] have hED : E * D = 1 := by ext i j by_cases hij : i = j · subst j simp [D, E, Matrix.mul_apply, Matrix.diagonal_apply, inv_mul_cancel₀ (ne_of_gt (S.sigma_pos i))] · simp [D, E, Matrix.mul_apply, Matrix.diagonal_apply, hij] have hspec : IsMoorePenroseInverse S.matrix S.inverse := by change IsMoorePenroseInverse (S.left * D * S.right) (S.right.transpose * E * S.left.transpose) refine ⟨?_, ?_, ?_, ?_⟩ · simp only [Matrix.mul_assoc] rw [← Matrix.mul_assoc S.right S.right.transpose, S.right_orthonormal, Matrix.one_mul, ← Matrix.mul_assoc D E, hDE, Matrix.one_mul, ← Matrix.mul_assoc S.left.transpose S.left, S.left_orthonormal, Matrix.one_mul] · simp only [Matrix.mul_assoc] rw [← Matrix.mul_assoc S.left.transpose S.left, S.left_orthonormal, Matrix.one_mul, ← Matrix.mul_assoc E D, hED, Matrix.one_mul, ← Matrix.mul_assoc S.right S.right.transpose, S.right_orthonormal, Matrix.one_mul] · simp only [Matrix.mul_assoc] rw [← Matrix.mul_assoc S.right S.right.transpose, S.right_orthonormal, Matrix.one_mul, ← Matrix.mul_assoc D E, hDE, Matrix.one_mul] simp [Matrix.transpose_mul] · simp only [Matrix.mul_assoc] rw [← Matrix.mul_assoc S.left.transpose S.left, S.left_orthonormal, Matrix.one_mul, ← Matrix.mul_assoc E D, hED, Matrix.one_mul] simp [Matrix.transpose_mul] exact isMoorePenroseInverse_unique hspec (moorePenroseInverse_spec _)
Causalean.Mathlib.Analysis.RetainedSVD.inverse_eq_moorePenroseInverse · Causalean/Mathlib/Analysis/RetainedSVD.lean:141 · uses RectMatrix , RetainedSVD , inverse , matrix , moorePenroseInverse
4 supporting declarations (lemmas, instances)
  • matrix_apply theorem — For a retained singular-value decomposition, the entry in row i and column j of its reconstructed matrix is the sum over retained directions a of the a-th singular value times the (i, a) left-direction entry times the (a, j) right-direction entry.
    r rows cols :
    ℕ
    S :
    RetainedSVD r rows cols
    i :
    Fin rows
    j :
    Fin cols
    S.matrix i j = ∑ a, S.sigma a * S.left i a * S.right a j
    Proof (Lean source)
    theorem RetainedSVD.matrix_apply {r rows cols : ℕ} (S : RetainedSVD r rows cols) (i : Fin rows) (j : Fin cols) : S.matrix i j = ∑ a, S.sigma a * S.left i a * S.right a j := by rw [RetainedSVD.matrix] simp [Matrix.mul_apply, Matrix.diagonal_apply] apply Finset.sum_congr rfl intro a _ ring
    Causalean.Mathlib.Analysis.RetainedSVD.matrix_apply · Causalean/Mathlib/Analysis/RetainedSVD.lean:57
  • inverse_apply theorem — For a retained singular-value decomposition, the entry in row i and column j of its reciprocal retained matrix is the sum over retained directions a of the reciprocal of the a-th singular value times the (a, i) right-direction entry times the (j, a) left-direction entry.
    r rows cols :
    ℕ
    S :
    RetainedSVD r rows cols
    i :
    Fin cols
    j :
    Fin rows
    S.inverse i j = ∑ a, (S.sigma a)⁻¹ * S.right a i * S.left j a
    Proof (Lean source)
    theorem RetainedSVD.inverse_apply {r rows cols : ℕ} (S : RetainedSVD r rows cols) (i : Fin cols) (j : Fin rows) : S.inverse i j = ∑ a, (S.sigma a)⁻¹ * S.right a i * S.left j a := by rw [RetainedSVD.inverse] simp [Matrix.mul_apply, Matrix.diagonal_apply, Matrix.transpose_apply] apply Finset.sum_congr rfl intro a _ ring
    Causalean.Mathlib.Analysis.RetainedSVD.inverse_apply · Causalean/Mathlib/Analysis/RetainedSVD.lean:67
  • norm_inverse_le theorem — A common lower bound on the retained singular coefficients bounds the reciprocal expansion in operator norm.
    r rows cols :
    ℕ
    S :
    RetainedSVD r rows cols
    s :
    ℝ
    hs :
    0 < s
    hlower :
    ∀ a, s ≤ S.sigma a
    ‖S.inverse‖ ≤ s⁻¹
    Proof (Lean source)
    theorem RetainedSVD.norm_inverse_le {r rows cols : ℕ} (S : RetainedSVD r rows cols) {s : ℝ} (hs : 0 < s) (hlower : ∀ a, s ≤ S.sigma a) : ‖S.inverse‖ ≤ s⁻¹ := by let u : Fin r → Euc rows := fun a => toLp 2 (fun i => S.left i a) let v : Fin r → Euc cols := fun a => toLp 2 (S.right a) have hu : Orthonormal ℝ u := by rw [orthonormal_iff_ite] intro a b have hab := congrFun (congrFun S.left_orthonormal b) a simpa only [u, PiLp.inner_apply, RCLike.inner_apply, conj_trivial, Matrix.mul_apply, Matrix.transpose_apply, Matrix.one_apply, eq_comm] using hab have hv : Orthonormal ℝ v := by rw [orthonormal_iff_ite] intro a b have hab := congrFun (congrFun S.right_orthonormal b) a simpa only [v, PiLp.inner_apply, RCLike.inner_apply, conj_trivial, Matrix.mul_apply, Matrix.transpose_apply, Matrix.one_apply, eq_comm] using hab change ‖matrixCLM S.inverse‖ ≤ s⁻¹ apply ContinuousLinearMap.opNorm_le_bound _ (le_of_lt (inv_pos.mpr hs)) intro x let c : Fin r → ℝ := fun a => (S.sigma a)⁻¹ * inner ℝ (u a) x have haction : matrixCLM S.inverse x = ∑ a, c a • v a := by ext i simp [matrixCLM, Matrix.toEuclideanLin_apply, mulVec, dotProduct, S.inverse_apply, c, u, v, PiLp.inner_apply, RCLike.inner_apply, conj_trivial] simp_rw [Finset.sum_mul] rw [Finset.sum_comm] apply Finset.sum_congr rfl intro a _ rw [Finset.mul_sum, Finset.sum_mul] apply Finset.sum_congr rfl intro j _ ring rw [haction] have hinner := hv.inner_sum c c Finset.univ have hsq : ‖∑ a, c a • v a‖ ^ 2 ≤ s⁻¹ ^ 2 * ‖x‖ ^ 2 := by rw [← real_inner_self_eq_norm_sq, hinner] calc (∑ a, c a * c a) ≤ ∑ a, s⁻¹ ^ 2 * ‖inner ℝ (u a) x‖ ^ 2 := by apply Finset.sum_le_sum (s := Finset.univ) intro a _ have hsig : 0 < S.sigma a := S.sigma_pos a have hinv : (S.sigma a)⁻¹ ≤ s⁻¹ := inv_anti₀ hs (hlower a) have hinv0 : 0 ≤ (S.sigma a)⁻¹ := le_of_lt (inv_pos.mpr hsig) have hinv2 : (S.sigma a)⁻¹ ^ 2 ≤ s⁻¹ ^ 2 := by nlinarith dsimp [c] calc (S.sigma a)⁻¹ * inner ℝ (u a) x * ((S.sigma a)⁻¹ * inner ℝ (u a) x) = (S.sigma a)⁻¹ ^ 2 * inner ℝ (u a) x ^ 2 := by ring _ ≤ s⁻¹ ^ 2 * inner ℝ (u a) x ^ 2 := mul_le_mul_of_nonneg_right hinv2 (sq_nonneg _) _ = s⁻¹ ^ 2 * ‖inner ℝ (u a) x‖ ^ 2 := by rw [Real.norm_eq_abs, sq_abs] _ = s⁻¹ ^ 2 * ∑ a, ‖inner ℝ (u a) x‖ ^ 2 := by rw [Finset.mul_sum] _ ≤ s⁻¹ ^ 2 * ‖x‖ ^ 2 := by gcongr exact hu.sum_inner_products_le x exact (sq_le_sq₀ (norm_nonneg _) (mul_nonneg (inv_nonneg.mpr (le_of_lt hs)) (norm_nonneg _))).mp (by simpa [mul_pow] using hsq)
    Causalean.Mathlib.Analysis.RetainedSVD.norm_inverse_le · Causalean/Mathlib/Analysis/RetainedSVD.lean:77
  • rank_matrix theorem — A retained positive r-frame has matrix rank exactly r.
    r rows cols :
    ℕ
    S :
    RetainedSVD r rows cols
    S.matrix.rank = r
    Proof (Lean source)
    theorem RetainedSVD.rank_matrix {r rows cols : ℕ} (S : RetainedSVD r rows cols) : S.matrix.rank = r := by let D : RectMatrix r r := Matrix.diagonal S.sigma let E : RectMatrix r r := Matrix.diagonal (fun i => (S.sigma i)⁻¹) have hED : E * D = 1 := by ext i j by_cases hij : i = j · subst j simp [D, E, Matrix.mul_apply, Matrix.diagonal_apply, inv_mul_cancel₀ (ne_of_gt (S.sigma_pos i))] · simp [D, E, Matrix.mul_apply, Matrix.diagonal_apply, hij] have hid : (E * S.left.transpose) * S.matrix * S.right.transpose = (1 : RectMatrix r r) := by change (E * S.left.transpose) * (S.left * D * S.right) * S.right.transpose = 1 simp only [Matrix.mul_assoc] rw [← Matrix.mul_assoc S.left.transpose S.left, S.left_orthonormal, Matrix.one_mul, S.right_orthonormal, Matrix.mul_one, hED] apply le_antisymm · change (S.left * D * S.right).rank ≤ r exact (Matrix.rank_mul_le_left (S.left * D) S.right).trans ((Matrix.rank_mul_le_left S.left D).trans (Matrix.rank_le_width S.left)) · calc r = (1 : RectMatrix r r).rank := by simpa only [Fintype.card_fin] using (Matrix.rank_one (n := Fin r) (R := ℝ)).symm _ = ((E * S.left.transpose) * S.matrix * S.right.transpose).rank := congrArg rank hid.symm _ ≤ (S.matrix * S.right.transpose).rank := by simpa only [Matrix.mul_assoc] using Matrix.rank_mul_le_right (E * S.left.transpose) (S.matrix * S.right.transpose) _ ≤ S.matrix.rank := Matrix.rank_mul_le_left S.matrix S.right.transpose
    Causalean.Mathlib.Analysis.RetainedSVD.rank_matrix · Causalean/Mathlib/Analysis/RetainedSVD.lean:185
Rpow­Arith 3 core · 4 supporting This file provides reusable arithmetic identities and inequalities for real powers, logarithms, and square roots, especially for sample-size factors, negative exponents, and multiplicative windows. ★ inv_eq_rpow_neg_one★ div_rpow_of_nonneg_of_pos★ inv_mul_sqrt_eq_rpow_neg_half

Small real-power arithmetic helpers

This file provides reusable arithmetic identities and inequalities for real powers, logarithms, and square roots, especially for sample-size factors, negative exponents, and multiplicative windows. The main lemmas identify reciprocals with real powers (inv_eq_rpow_neg_one), factor (A / n) ^ p into an A part and an n part (div_rpow_of_nonneg_of_pos), bound nonpositive powers of natural casts (rpow_natCast_nonpos_le_one), and rewrite q⁻¹ * sqrt q as q ^ (-1/2) (inv_mul_sqrt_eq_rpow_neg_half). It also controls logarithmic real-power expressions when their positive inputs differ by a fixed multiplicative factor.

lemma inv_eq_rpow_neg_one reviewed
Causalean.Mathlib.RpowArith

For any real number x, its reciprocal equals its real power raised to the exponent −1.

Formal statement
x :
ℝ
x⁻¹ = x ^ (-1 : ℝ)
Proof (Lean source)
lemma inv_eq_rpow_neg_one (x : ℝ) : x⁻¹ = x ^ (-1 : ℝ) := by rw [Real.rpow_neg_one]
Causalean.Mathlib.RpowArith.inv_eq_rpow_neg_one · Causalean/Mathlib/Analysis/RpowArith.lean:29
lemma div_rpow_of_nonneg_of_pos reviewed
Causalean.Mathlib.RpowArith

Factoring a real power of a quotient. For a nonnegative numerator A and a strictly positive denominator n, the real power (A/n)^p equals A^p times n raised to the power −p, for any real exponent p.

Formal statement
A p n :
ℝ
hA :
0 ≤ A
hn :
0 < n
(A / n) ^ p = A ^ p * n ^ (-p)
Proof (Lean source)
lemma div_rpow_of_nonneg_of_pos (A p n : ℝ) (hA : 0 ≤ A) (hn : 0 < n) : (A / n) ^ p = A ^ p * n ^ (-p) := by have hnnonneg : 0 ≤ n := le_of_lt hn have hinv_nonneg : 0 ≤ n⁻¹ := inv_nonneg.mpr hnnonneg have hinv := inv_eq_rpow_neg_one n calc (A / n) ^ p = (A * n⁻¹) ^ p := by rw [div_eq_mul_inv] _ = A ^ p * (n⁻¹) ^ p := by rw [Real.mul_rpow hA hinv_nonneg] _ = A ^ p * (n ^ (-1 : ℝ)) ^ p := by rw [hinv] _ = A ^ p * n ^ ((-1 : ℝ) * p) := by rw [Real.rpow_mul hnnonneg] _ = A ^ p * n ^ (-p) := by congr 1 ring_nf
Causalean.Mathlib.RpowArith.div_rpow_of_nonneg_of_pos · Causalean/Mathlib/Analysis/RpowArith.lean:34
lemma inv_mul_sqrt_eq_rpow_neg_half reviewed
Causalean.Mathlib.RpowArith

Reciprocal times square root as a negative-half power. For a nonnegative real number q, the reciprocal of q times the square root of q equals q raised to the power −1/2.

Formal statement
q :
ℝ
hq :
0 ≤ q
q⁻¹ * sqrt q = q ^ (-(1 / 2 : ℝ))
Proof (Lean source)
lemma inv_mul_sqrt_eq_rpow_neg_half (q : ℝ) (hq : 0 ≤ q) : q⁻¹ * sqrt q = q ^ (-(1 / 2 : ℝ)) := by rcases hq.eq_or_lt with rfl | hq · simp · calc q⁻¹ * sqrt q = q ^ (-1 : ℝ) * q ^ (1 / (2 : ℝ)) := by rw [Real.sqrt_eq_rpow] rw [Real.rpow_neg hq.le, Real.rpow_one] _ = q ^ ((-1 : ℝ) + 1 / (2 : ℝ)) := by rw [← Real.rpow_add hq] _ = q ^ (-(1 / 2 : ℝ)) := by ring_nf
Causalean.Mathlib.RpowArith.inv_mul_sqrt_eq_rpow_neg_half · Causalean/Mathlib/Analysis/RpowArith.lean:71
4 supporting declarations (lemmas, instances)
  • rpow_natCast_nonpos_le_one lemma — Nonpositive real power of a natural number is at most one. For a nonpositive real exponent e, the real power of any natural-number cast raised to e is at most 1.
    n :
    ℕ
    e :
    ℝ
    he :
    e ≤ 0
    (n : ℝ) ^ e ≤ 1
    Proof (Lean source)
    lemma rpow_natCast_nonpos_le_one (n : ℕ) (e : ℝ) (he : e ≤ 0) : (n : ℝ) ^ e ≤ 1 := by cases n with | zero => by_cases he_zero : e = 0 · simp [he_zero] · simp [Real.zero_rpow he_zero] | succ n => have hn_ge_one : 1 ≤ ((n + 1 : ℕ) : ℝ) := by exact_mod_cast (Nat.succ_le_succ (zero_le n)) exact Real.rpow_le_one_of_one_le_of_nonpos hn_ge_one he
    Causalean.Mathlib.RpowArith.rpow_natCast_nonpos_le_one · Causalean/Mathlib/Analysis/RpowArith.lean:56
  • window_log_power_le lemma — For a multiplicative factor K, a nonnegative real exponent d, a nonnegative weight w, and positive inputs a and b, if K is at least one and a is at most K * b, then multiplying the input of w * x ^ d by at most K increases its positive logarithmic transform by at most d * log K.
    K d w a b :
    ℝ
    hK :
    1 ≤ K
    hd :
    0 ≤ d
    hw :
    0 ≤ w
    ha :
    0 < a
    hb :
    0 < b
    hab :
    a ≤ K * b
    log (exp 1 + w * a ^ d) ≤ d * log K + log (exp 1 + w * b ^ d)
    Proof (Lean source)
    lemma window_log_power_le (K d w a b : ℝ) (hK : 1 ≤ K) (hd : 0 ≤ d) (hw : 0 ≤ w) (ha : 0 < a) (hb : 0 < b) (hab : a ≤ K * b) : log (exp 1 + w * a ^ d) ≤ d * log K + log (exp 1 + w * b ^ d) := by have hKpos : 0 < K := lt_of_lt_of_le zero_lt_one hK have hp : 1 ≤ K ^ d := Real.one_le_rpow hK hd have hpow := Real.rpow_le_rpow ha.le hab hd rw [Real.mul_rpow hKpos.le hb.le] at hpow have hm := mul_le_mul_of_nonneg_left hpow hw have he := mul_le_mul_of_nonneg_right hp (Real.exp_pos 1).le have harg : exp 1 + w * a ^ d ≤ K ^ d * (exp 1 + w * b ^ d) := by nlinarith have hl := Real.log_le_log (by positivity : 0 < exp 1 + w * a ^ d) harg rw [Real.log_mul (by positivity) (by positivity), Real.log_rpow hKpos] at hl exact hl
    Causalean.Mathlib.RpowArith.window_log_power_le · Causalean/Mathlib/Analysis/RpowArith.lean:86
  • window_log_power_comparison lemma — For a multiplicative factor K, a nonnegative real exponent d, a nonnegative weight w, and positive inputs a and b, if K is at least one and a is at most K * b, then their positive logarithmic real-power transforms differ by at most the factor 1 + d * log K.
    K d w a b :
    ℝ
    hK :
    1 ≤ K
    hd :
    0 ≤ d
    hw :
    0 ≤ w
    ha :
    0 < a
    hb :
    0 < b
    hab :
    a ≤ K * b
    log (exp 1 + w * a ^ d)
    ≤ (1 + d * log K) * log (exp 1 + w * b ^ d)
    Proof (Lean source)
    lemma window_log_power_comparison (K d w a b : ℝ) (hK : 1 ≤ K) (hd : 0 ≤ d) (hw : 0 ≤ w) (ha : 0 < a) (hb : 0 < b) (hab : a ≤ K * b) : log (exp 1 + w * a ^ d) ≤ (1 + d * log K) * log (exp 1 + w * b ^ d) := by have hl := window_log_power_le K d w a b hK hd hw ha hb hab have h1 : 1 ≤ log (exp 1 + w * b ^ d) := by calc 1 = log (exp 1) := (Real.log_exp 1).symm _ ≤ _ := Real.log_le_log (Real.exp_pos 1) (le_add_of_nonneg_right (by positivity)) have hc : 0 ≤ d * log K := mul_nonneg hd (Real.log_nonneg hK) nlinarith [mul_le_mul_of_nonneg_left h1 hc]
    Causalean.Mathlib.RpowArith.window_log_power_comparison · Causalean/Mathlib/Analysis/RpowArith.lean:107
  • window_sqrt_log_comparison lemma — For a multiplicative factor K, a nonnegative real exponent d, a nonnegative weight w, and positive inputs a and b, if K is at least one and a is at most K * b, then the square roots of their positive logarithmic real-power transforms differ by at most the factor 1 + d * log K.
    K d w a b :
    ℝ
    hK :
    1 ≤ K
    hd :
    0 ≤ d
    hw :
    0 ≤ w
    ha :
    0 < a
    hb :
    0 < b
    hab :
    a ≤ K * b
    sqrt (log (exp 1 + w * a ^ d))
    ≤ (1 + d * log K) * sqrt (log (exp 1 + w * b ^ d))
    Proof (Lean source)
    lemma window_sqrt_log_comparison (K d w a b : ℝ) (hK : 1 ≤ K) (hd : 0 ≤ d) (hw : 0 ≤ w) (ha : 0 < a) (hb : 0 < b) (hab : a ≤ K * b) : sqrt (log (exp 1 + w * a ^ d)) ≤ (1 + d * log K) * sqrt (log (exp 1 + w * b ^ d)) := by have hl := window_log_power_comparison K d w a b hK hd hw ha hb hab have hc : 1 ≤ 1 + d * log K := by have := mul_nonneg hd (Real.log_nonneg hK) linarith have hla : 0 ≤ log (exp 1 + w * a ^ d) := by apply Real.log_nonneg have := Real.one_le_exp (by norm_num : (0 : ℝ) ≤ 1) have : 0 ≤ w * a ^ d := by positivity linarith have hlb : 0 ≤ log (exp 1 + w * b ^ d) := by apply Real.log_nonneg have := Real.one_le_exp (by norm_num : (0 : ℝ) ≤ 1) have : 0 ≤ w * b ^ d := by positivity linarith have hsa := Real.sqrt_nonneg (log (exp 1 + w * a ^ d)) have hsb := Real.sqrt_nonneg (log (exp 1 + w * b ^ d)) have hqa := Real.sq_sqrt hla have hqb := Real.sq_sqrt hlb have hmul := mul_le_mul_of_nonneg_right (show 1 + d * log K ≤ (1 + d * log K) ^ 2 by nlinarith) hlb apply (sq_le_sq₀ hsa (mul_nonneg (by linarith) hsb)).mp calc _ = log (exp 1 + w * a ^ d) := hqa _ ≤ (1 + d * log K) ^ 2 * log (exp 1 + w * b ^ d) := hl.trans hmul _ = _ := by rw [mul_pow, hqb]
    Causalean.Mathlib.RpowArith.window_sqrt_log_comparison · Causalean/Mathlib/Analysis/RpowArith.lean:123
Second­Order­Descent 2 core · 8 supporting This module provides the one-dimensional smooth-optimization descent lemma. ★ second_order_descent_gap

Second-order descent for one real variable

This module provides the one-dimensional smooth-optimization descent lemma. A real function whose second derivative is bounded above in a segment's interior lies below the corresponding quadratic Taylor model, and a negative initial slope gives an explicit positive decrease at the clipped quadratic-model step.

The statements are objective-agnostic. Callers supply the regularity on Set.Icc 0 T and the interior pointwise second-derivative bound; this file only turns those hypotheses into the quadratic upper bound and the optimized descent gap.

def descentStep reviewed
Causalean.Mathlib.Analysis

For a real curvature bound, a real slope margin, and a real available interval length, the quadratic-model step is the available interval length when the curvature bound is zero and otherwise the smaller of that length and the slope margin divided by the curvature bound.

Definition (Lean source)
M c T :
ℝ
descentStep M c T :
ℝ
if M = 0 then T else min T (c / M)
Causalean.Mathlib.Analysis.descentStep · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:28
theorem second_order_descent_gap reviewed
Causalean.Mathlib.Analysis

Quadratic-model descent gap. For a real function f on [0, T] where the interval length T, the slope margin c, and the curvature bound M are all nonnegative, f is twice continuously differentiable on [0, T], f is differentiable at 0, its second derivative is bounded above by M throughout the open interval, and its derivative at 0 is at most −c, then the clipped quadratic-model step lies in [0, T], and the resulting decrease f(0) − f(step) is at least c·step − (M/2)·step².

Formal statement
f :
ℝ → ℝ
M c T :
ℝ
hT :
0 ≤ T
hc :
0 ≤ c
hMnn :
0 ≤ M
hf :
ContDiffOn ℝ 2 f (Icc 0 T)
hf0 :
hM :
∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ M
hslope :
deriv f 0 ≤ -c
conclusion 1
descentStep M c T ∈ Icc 0 T
conclusion 2
f 0 - f (descentStep M c T) ≥ c * descentStep M c T - (M / 2) * descentStep M c T ^ 2
Proof (Lean source)
theorem second_order_descent_gap {f : ℝ → ℝ} {M c T : ℝ} (hT : 0 ≤ T) (hc : 0 ≤ c) (hMnn : 0 ≤ M) (hf : ContDiffOn ℝ 2 f (Icc 0 T)) (hf0 : DifferentiableAt ℝ f 0) (hM : ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ M) (hslope : deriv f 0 ≤ -c) : descentStep M c T ∈ Icc 0 T ∧ f 0 - f (descentStep M c T) ≥ c * descentStep M c T - (M / 2) * descentStep M c T ^ 2 := by let s := descentStep M c T have hs : s ∈ Icc 0 T := descentStep_mem_Icc hMnn hc hT refine ⟨hs, ?_⟩ have hs0 : 0 ≤ s := hs.1 have hub : f s ≤ f 0 + deriv f 0 * s + (M / 2) * s ^ 2 := second_order_upper_bound hf hf0 hM hs have hslope_mul : deriv f 0 * s ≤ -c * s := mul_le_mul_of_nonneg_right hslope hs0 nlinarith
Causalean.Mathlib.Analysis.second_order_descent_gap · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:118 · uses descentStep
8 supporting declarations (lemmas, instances)
  • descentStep_of_eq_zero theorem — With zero curvature bound, the clipped quadratic-model step is the endpoint.
    c T :
    ℝ
    descentStep 0 c T = T
    Proof (Lean source)
    @[simp] theorem descentStep_of_eq_zero (c T : ℝ) : descentStep 0 c T = T := by simp [descentStep]
    Causalean.Mathlib.Analysis.descentStep_of_eq_zero · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:35
  • descentStep_of_pos theorem — With a positive curvature bound, the clipped quadratic-model step is the smaller of the available interval length and the unconstrained quadratic-model optimizer.
    M :
    ℝ
    hM :
    0 < M
    c T :
    ℝ
    descentStep M c T = min T (c / M)
    Proof (Lean source)
    theorem descentStep_of_pos {M : ℝ} (hM : 0 < M) (c T : ℝ) : descentStep M c T = min T (c / M) := by simp [descentStep, hM.ne']
    Causalean.Mathlib.Analysis.descentStep_of_pos · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:40
  • descentStep_mem_Icc theorem — The clipped quadratic-model step is feasible whenever the interval length, slope margin, and curvature bound are nonnegative.
    M c T :
    ℝ
    hM :
    0 ≤ M
    hc :
    0 ≤ c
    hT :
    0 ≤ T
    descentStep M c T ∈ Icc 0 T
    Proof (Lean source)
    theorem descentStep_mem_Icc {M c T : ℝ} (hM : 0 ≤ M) (hc : 0 ≤ c) (hT : 0 ≤ T) : descentStep M c T ∈ Icc 0 T := by unfold descentStep split_ifs with h · exact ⟨hT, le_rfl⟩ · have hMpos : 0 < M := lt_of_le_of_ne hM (Ne.symm h) exact ⟨le_min hT (div_nonneg hc hM), min_le_left _ _⟩
    Causalean.Mathlib.Analysis.descentStep_mem_Icc · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:46
  • second_order_upper_bound theorem — A twice differentiable real function whose second derivative is bounded above on an interval's interior is no larger than its tangent at the left endpoint plus the quadratic curvature allowance.
    f :
    ℝ → ℝ
    M T :
    ℝ
    hf :
    ContDiffOn ℝ 2 f (Icc 0 T)
    hf0 :
    hM :
    ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ M
    t :
    ℝ
    ht :
    t ∈ Icc 0 T
    f t ≤ f 0 + deriv f 0 * t + (M / 2) * t ^ 2
    Proof (Lean source)
    theorem second_order_upper_bound {f : ℝ → ℝ} {M T : ℝ} (hf : ContDiffOn ℝ 2 f (Icc 0 T)) (hf0 : DifferentiableAt ℝ f 0) (hM : ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ M) {t : ℝ} (ht : t ∈ Icc 0 T) : f t ≤ f 0 + deriv f 0 * t + (M / 2) * t ^ 2 := by rcases ht with ⟨ht0, htT⟩ rcases ht0.eq_or_lt with rfl | htpos · simp · have hf' : ContDiffOn ℝ 2 f (Icc 0 t) := hf.mono (Icc_subset_Icc le_rfl htT) have huIcc : uIcc (0 : ℝ) t = Icc 0 t := uIcc_of_le htpos.le have huIoo : uIoo (0 : ℝ) t = Ioo 0 t := uIoo_of_le htpos.le have htay : ∃ x' ∈ Ioo (0 : ℝ) t, f t - taylorWithinEval f 1 (Icc 0 t) 0 t = iteratedDeriv 2 f x' * (t - 0) ^ 2 / (factorial 2) := by have h0 := taylor_mean_remainder_lagrange_iteratedDeriv (f := f) (x := t) (x₀ := 0) (n := 1) htpos.ne (by rw [huIcc] exact_mod_cast hf') rw [huIcc, huIoo] at h0 simpa using h0 have hpoly : taylorWithinEval f 1 (Icc 0 t) 0 t = f 0 + deriv f 0 * t := by rw [taylorWithinEval_succ, taylor_within_zero_eval, iteratedDerivWithin_one] · rw [hf0.derivWithin ((uniqueDiffOn_Icc htpos) 0 ⟨le_rfl, htpos.le⟩)] simp [mul_comm] have hid : iteratedDeriv 2 f = deriv (deriv f) := by rw [iteratedDeriv_succ, iteratedDeriv_one] rcases htay with ⟨ξ, hξ, heq⟩ have hb : deriv (deriv f) ξ ≤ M := hM ξ ⟨hξ.1, hξ.2.trans_le htT⟩ have heq' : f t - (f 0 + deriv f 0 * t) = deriv (deriv f) ξ * t ^ 2 / 2 := by rw [hpoly, hid] at heq simpa [sub_zero, factorial] using heq have hquad : deriv (deriv f) ξ * t ^ 2 / 2 ≤ M * t ^ 2 / 2 := by nlinarith [sq_nonneg t, hb] nlinarith
    Causalean.Mathlib.Analysis.second_order_upper_bound · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:58
  • first_order_upper_bound theorem — A real function with nonpositive second derivative in an interval's interior lies below its tangent line at the left endpoint.
    f :
    ℝ → ℝ
    T :
    ℝ
    hf :
    ContDiffOn ℝ 2 f (Icc 0 T)
    hf0 :
    hM :
    ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ 0
    t :
    ℝ
    ht :
    t ∈ Icc 0 T
    f t ≤ f 0 + deriv f 0 * t
    Proof (Lean source)
    theorem first_order_upper_bound {f : ℝ → ℝ} {T : ℝ} (hf : ContDiffOn ℝ 2 f (Icc 0 T)) (hf0 : DifferentiableAt ℝ f 0) (hM : ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ 0) {t : ℝ} (ht : t ∈ Icc 0 T) : f t ≤ f 0 + deriv f 0 * t := by have h := second_order_upper_bound (M := 0) hf hf0 hM ht simpa using h
    Causalean.Mathlib.Analysis.first_order_upper_bound · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:103
  • second_order_descent_gap_min theorem — With positive curvature, the clipped quadratic-model step gives at least half of the linear descent term.
    f :
    ℝ → ℝ
    M c T :
    ℝ
    hT :
    0 ≤ T
    hc :
    0 ≤ c
    hMpos :
    0 < M
    hf :
    ContDiffOn ℝ 2 f (Icc 0 T)
    hf0 :
    hM :
    ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ M
    hslope :
    deriv f 0 ≤ -c
    f 0 - f (min T (c / M)) ≥ (c / 2) * min T (c / M)
    Proof (Lean source)
    theorem second_order_descent_gap_min {f : ℝ → ℝ} {M c T : ℝ} (hT : 0 ≤ T) (hc : 0 ≤ c) (hMpos : 0 < M) (hf : ContDiffOn ℝ 2 f (Icc 0 T)) (hf0 : DifferentiableAt ℝ f 0) (hM : ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ M) (hslope : deriv f 0 ≤ -c) : f 0 - f (min T (c / M)) ≥ (c / 2) * min T (c / M) := by let s := min T (c / M) have hraw : f 0 - f s ≥ c * s - (M / 2) * s ^ 2 := by simpa [s, descentStep_of_pos hMpos] using (second_order_descent_gap hT hc hMpos.le hf hf0 hM hslope).2 have hsle : s ≤ c / M := min_le_right T (c / M) have hMs : s * M ≤ c := (le_div_iff₀ hMpos).mp hsle have hs0 : 0 ≤ s := le_min hT (div_nonneg hc hMpos.le) nlinarith
    Causalean.Mathlib.Analysis.second_order_descent_gap_min · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:145
  • first_order_descent_gap theorem — With zero curvature, the endpoint step gives the full linear descent guaranteed by the negative initial slope.
    f :
    ℝ → ℝ
    c T :
    ℝ
    hT :
    0 ≤ T
    hf :
    ContDiffOn ℝ 2 f (Icc 0 T)
    hf0 :
    hM :
    ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ 0
    hslope :
    deriv f 0 ≤ -c
    f 0 - f T ≥ c * T
    Proof (Lean source)
    theorem first_order_descent_gap {f : ℝ → ℝ} {c T : ℝ} (hT : 0 ≤ T) (hf : ContDiffOn ℝ 2 f (Icc 0 T)) (hf0 : DifferentiableAt ℝ f 0) (hM : ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ 0) (hslope : deriv f 0 ≤ -c) : f 0 - f T ≥ c * T := by have hub : f T ≤ f 0 + deriv f 0 * T := first_order_upper_bound hf hf0 hM (right_mem_Icc.mpr hT) have hslope_mul : deriv f 0 * T ≤ -c * T := mul_le_mul_of_nonneg_right hslope hT nlinarith
    Causalean.Mathlib.Analysis.first_order_descent_gap · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:165
  • second_order_descent_gap_half theorem — In both zero and positive curvature regimes, the clipped quadratic-model step gives a uniform half-linear decrease.
    f :
    ℝ → ℝ
    M c T :
    ℝ
    hT :
    0 ≤ T
    hc :
    0 ≤ c
    hMnn :
    0 ≤ M
    hf :
    ContDiffOn ℝ 2 f (Icc 0 T)
    hf0 :
    hM :
    ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ M
    hslope :
    deriv f 0 ≤ -c
    conclusion 1
    descentStep M c T ∈ Icc 0 T
    conclusion 2
    f 0 - f (descentStep M c T) ≥ (c / 2) * descentStep M c T
    Proof (Lean source)
    theorem second_order_descent_gap_half {f : ℝ → ℝ} {M c T : ℝ} (hT : 0 ≤ T) (hc : 0 ≤ c) (hMnn : 0 ≤ M) (hf : ContDiffOn ℝ 2 f (Icc 0 T)) (hf0 : DifferentiableAt ℝ f 0) (hM : ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ M) (hslope : deriv f 0 ≤ -c) : descentStep M c T ∈ Icc 0 T ∧ f 0 - f (descentStep M c T) ≥ (c / 2) * descentStep M c T := by refine ⟨descentStep_mem_Icc hMnn hc hT, ?_⟩ rcases hMnn.eq_or_lt with hMzero | hMpos · rw [← hMzero, descentStep_of_eq_zero] have hM0 : ∀ t ∈ Ioo 0 T, deriv (deriv f) t ≤ 0 := by simpa [← hMzero] using hM have hgap : f 0 - f T ≥ c * T := first_order_descent_gap hT hf hf0 hM0 hslope nlinarith · rw [descentStep_of_pos hMpos] exact second_order_descent_gap_min hT hc hMpos hf hf0 hM hslope
    Causalean.Mathlib.Analysis.second_order_descent_gap_half · Causalean/Mathlib/Analysis/SecondOrderDescent.lean:179
Sharp­Functional­Calculus 4 core · 4 supporting For two real n × n matrices A and B, each with a chosen real diagonalization, and a 1-Lipschitz scalar function f, the matrices f(A) and f(B) satisfy ‖f(A) − f(B)‖ ≤ √n·κ_A·κ_B·‖A − B‖ in operator norm, where κ_A and κ_B ★ norm_applyFunction_sub_le_sqrt_dim

Lipschitz perturbation of the functional calculus for two diagonalizable matrices

For two real n × n matrices A and B, each with a chosen real diagonalization, and a 1-Lipschitz scalar function f, the matrices f(A) and f(B) satisfy ‖f(A) − f(B)‖ ≤ √n·κ_A·κ_B·‖A − B‖ in operator norm, where κ_A and κ_B bound the condition numbers of the two diagonalizing bases. The proof writes f(A) − f(B) as a Hadamard product of divided differences of f with the perturbation A − B expressed between the two eigenbases; the divided difference is set to zero where an eigenvalue of A coincides with one of B, so no spectral separation is assumed.

Main definitions

* crossDividedDifference — the matrix of divided differences (f(λ_i) − f(μ_j))/(λ_i − μ_j) between eigenvalues of A and of B, zero where λ_i = μ_j. * crossPerturbation, crossHadamard — A − B written between the two eigenbases, and its entrywise product with the divided differences.

Main results

* applyFunction_sub_eq_crossHadamard — f(A) − f(B) is the cross Hadamard matrix conjugated by the two bases. * norm_applyFunction_sub_le_sqrt_dim — the √n·κ_A·κ_B·‖A − B‖ perturbation bound. * abs_anchorEval_applyFunction_sub_le_sqrt_dim — the resulting bound on the difference of the bilinear evaluations ⟨a, f(A)c⟩ and ⟨b, f(B)d⟩, when f(0) = 0 and both spectra lie in [−R, R]. * matrix_norm_le_sqrt_card_mul_of_column_norm_le — a matrix whose columns have Euclidean norm at most M has operator norm at most √(number of columns)·M.

def crossDividedDifference reviewed
Causalean.Mathlib.Analysis

The collision-safe divided-difference matrix of a scalar function for two real diagonalizations: its (i, j) entry is the divided difference (f(λᵢ) − f(μⱼ))/(λᵢ − μⱼ) of the i-th eigenvalue λᵢ of the first diagonalization and the j-th eigenvalue μⱼ of the second, and is zero when the two eigenvalues coincide.

Definition (Lean source)
n :
ℕ
f :
ℝ → ℝ
crossDividedDifference DA DB f :
fun i j
=> if DA.eigenvalue i = DB.eigenvalue j then 0 else (f (DA.eigenvalue i) - f (DB.eigenvalue j)) / (DA.eigenvalue i - DB.eigenvalue j)
def crossPerturbation reviewed
Causalean.Mathlib.Analysis

The difference A − B of two diagonalized matrices written in cross coordinates: the inverse eigenbasis of the first diagonalization times A − B times the eigenbasis of the second diagonalization.

Definition (Lean source)
crossPerturbation DA DB :
DA.basisInv * (A - B) * DB.basis
def crossHadamard reviewed
Causalean.Mathlib.Analysis

Two real diagonalizations and a scalar function determine their entrywise divided-difference perturbation matrix.

Definition (Lean source)
n :
ℕ
f :
ℝ → ℝ
crossHadamard DA DB f :
fun i j => crossDividedDifference DA DB f i j * crossPerturbation DA DB i j
theorem norm_applyFunction_sub_le_sqrt_dim reviewed
Causalean.Mathlib.Analysis

A matrix dimension and two real matrices, their real diagonalizations, a one-Lipschitz scalar function, and condition-number bounds give the perturbation bound: the operator norm of the difference of the function applied to the two matrices through their diagonalizations is at most √n·κA·κB times the operator norm of A − B.

Formal statement
n :
ℕ
f :
ℝ → ℝ
hf :
κA κB :
ℝ
hκA :
DA.conditionNumber ≤ κA
hκB :
DB.conditionNumber ≤ κB
‖DA.applyFunction f - DB.applyFunction f‖ ≤ sqrt n * κA * κB * ‖A - B‖
Proof (Lean source)
theorem norm_applyFunction_sub_le_sqrt_dim {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) (f : ℝ → ℝ) (hf : LipschitzWith 1 f) {κA κB : ℝ} (hκA : DA.conditionNumber ≤ κA) (hκB : DB.conditionNumber ≤ κB) : ‖DA.applyFunction f - DB.applyFunction f‖ ≤ sqrt n * κA * κB * ‖A - B‖ := by let E := crossPerturbation DA DB let H : RectMatrix n n := fun i j => crossDividedDifference DA DB f i j * E i j have hcoef (i j : Fin n) : |crossDividedDifference DA DB f i j| ≤ 1 := by unfold crossDividedDifference by_cases hij : DA.eigenvalue i = DB.eigenvalue j · simp [hij] · rw [if_neg hij, abs_div] exact (div_le_one (abs_pos.mpr (sub_ne_zero.mpr hij))).2 (by simpa [Real.norm_eq_abs] using hf.norm_sub_le (DA.eigenvalue i) (DB.eigenvalue j)) have hcol (j : Fin n) : ‖(toLp 2 (fun i => H i j) : Euc n)‖ ≤ ‖E‖ := by have hsq : ∑ i, (H i j) ^ 2 ≤ ∑ i, (E i j) ^ 2 := by apply Finset.sum_le_sum intro i _ dsimp [H] have hc2 : (crossDividedDifference DA DB f i j) ^ 2 ≤ 1 := by have hc := abs_le.mp (hcoef i j) nlinarith rw [mul_pow] simpa using mul_le_mul_of_nonneg_right hc2 (sq_nonneg (E i j)) have hcolE := Matrix.l2_opNorm_mulVec E (single j (1 : ℝ)) rw [EuclideanSpace.norm_single, norm_one, mul_one] at hcolE apply (sq_le_sq₀ (norm_nonneg _) (norm_nonneg _)).1 rw [EuclideanSpace.real_norm_sq_eq] calc _ ≤ ∑ i, (E i j) ^ 2 := hsq _ = ‖Matrix.toEuclideanLin E (single j (1 : ℝ))‖ ^ 2 := by rw [EuclideanSpace.real_norm_sq_eq] simp [Matrix.toEuclideanLin_apply, mulVec, dotProduct] _ ≤ ‖E‖ ^ 2 := (sq_le_sq₀ (norm_nonneg _) (norm_nonneg _)).2 hcolE have hH : ‖H‖ ≤ sqrt n * ‖E‖ := matrix_norm_le_sqrt_card_mul_of_column_norm_le H (norm_nonneg _) hcol rw [applyFunction_sub_eq_crossHadamard DA DB f] change ‖DA.basis * H * DB.basisInv‖ ≤ _ have hE : ‖E‖ ≤ ‖DA.basisInv‖ * ‖A - B‖ * ‖DB.basis‖ := by exact (Matrix.l2_opNorm_mul _ _).trans (mul_le_mul_of_nonneg_right (Matrix.l2_opNorm_mul _ _) (norm_nonneg _)) have hκA0 : 0 ≤ κA := (mul_nonneg (norm_nonneg _) (norm_nonneg _)).trans hκA have hκB0 : 0 ≤ κB := (mul_nonneg (norm_nonneg _) (norm_nonneg _)).trans hκB calc ‖DA.basis * H * DB.basisInv‖ ≤ ‖DA.basis‖ * ‖H‖ * ‖DB.basisInv‖ := by exact (Matrix.l2_opNorm_mul _ _).trans (mul_le_mul_of_nonneg_right (Matrix.l2_opNorm_mul _ _) (norm_nonneg _)) _ ≤ ‖DA.basis‖ * (sqrt n * ‖E‖) * ‖DB.basisInv‖ := by gcongr _ ≤ ‖DA.basis‖ * (sqrt n * (‖DA.basisInv‖ * ‖A - B‖ * ‖DB.basis‖)) * ‖DB.basisInv‖ := by gcongr _ = sqrt n * DA.conditionNumber * DB.conditionNumber * ‖A - B‖ := by unfold RealDiagonalization.conditionNumber ring _ ≤ sqrt n * κA * κB * ‖A - B‖ := by have hp : DA.conditionNumber * DB.conditionNumber ≤ κA * κB := mul_le_mul hκA hκB (mul_nonneg (norm_nonneg _) (norm_nonneg _)) hκA0 have := mul_le_mul_of_nonneg_left hp (Real.sqrt_nonneg n) exact mul_le_mul_of_nonneg_right (by simpa [mul_assoc] using this) (norm_nonneg _)
4 supporting declarations (lemmas, instances)
  • matrix_norm_le_sqrt_card_mul_of_column_norm_le lemma — A columnwise Euclidean envelope controls the operator norm with only the square root of the number of columns.
    rows cols :
    ℕ
    A :
    RectMatrix rows cols
    M :
    ℝ
    hM :
    0 ≤ M
    hcol :
    ∀ j, ‖(toLp 2 (fun i => A i j) : Euc rows)‖ ≤ M
    ‖A‖ ≤ sqrt cols * M
    Proof (Lean source)
    lemma matrix_norm_le_sqrt_card_mul_of_column_norm_le {rows cols : ℕ} (A : RectMatrix rows cols) {M : ℝ} (hM : 0 ≤ M) (hcol : ∀ j, ‖(toLp 2 (fun i => A i j) : Euc rows)‖ ≤ M) : ‖A‖ ≤ sqrt cols * M := by apply ContinuousLinearMap.opNorm_le_bound _ (mul_nonneg (Real.sqrt_nonneg _) hM) intro x let c : Fin cols → Euc rows := fun j => toLp 2 (fun i => A i j) have haction : toEuclideanLin A x = ∑ j, x j • c j := by apply PiLp.ext intro i simp [Matrix.toEuclideanLin_apply, mulVec, dotProduct, c, mul_comm] change ‖Matrix.toEuclideanLin A x‖ ≤ _ rw [haction] calc ‖∑ j, x j • c j‖ ≤ ∑ j, ‖x j • c j‖ := norm_sum_le univ _ _ ≤ ∑ j, |x j| * M := by apply Finset.sum_le_sum intro j _ rw [norm_smul, Real.norm_eq_abs] exact mul_le_mul_of_nonneg_left (hcol j) (abs_nonneg _) _ = M * ∑ j, |x j| := by rw [Finset.mul_sum] apply Finset.sum_congr rfl intro j _ ring _ ≤ M * (sqrt cols * ‖x‖) := by gcongr let one : Euc cols := toLp 2 (fun _ => (1 : ℝ)) let ax : Euc cols := toLp 2 (fun j => |x j|) have hinner : ∑ j, |x j| = inner ℝ one ax := by simp [one, ax, PiLp.inner_apply, RCLike.inner_apply, conj_trivial] rw [hinner] calc inner ℝ one ax ≤ |inner ℝ one ax| := le_abs_self _ _ ≤ ‖one‖ * ‖ax‖ := abs_real_inner_le_norm _ _ _ = sqrt cols * ‖x‖ := by congr 1 · rw [EuclideanSpace.norm_eq] simp [one] · rw [EuclideanSpace.norm_eq, EuclideanSpace.norm_eq] simp [ax, Real.norm_eq_abs] _ = (sqrt cols * M) * ‖x‖ := by ring
    Causalean.Mathlib.Analysis.matrix_norm_le_sqrt_card_mul_of_column_norm_le · Causalean/Mathlib/Analysis/SharpFunctionalCalculus.lean:40
  • crossPerturbation_entry lemma — Two real diagonalizations and coordinate indices give the eigenvalue-difference formula for one cross-coordinate perturbation.
    n :
    ℕ
    i j :
    Fin n
    = (DA.eigenvalue i - DB.eigenvalue j) * (DA.basisInv * DB.basis) i j
    Proof (Lean source)
    lemma crossPerturbation_entry {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) (i j : Fin n) : crossPerturbation DA DB i j = (DA.eigenvalue i - DB.eigenvalue j) * (DA.basisInv * DB.basis) i j := by have hA : DA.basisInv * A * DB.basis = diagonal DA.eigenvalue * (DA.basisInv * DB.basis) := by have hr := congrArg (fun X : RectMatrix n n => DA.basisInv * X * DB.basis) DA.reconstruct calc _ = DA.basisInv * (DA.basis * diagonal DA.eigenvalue * DA.basisInv) * DB.basis := hr _ = _ := by simp only [Matrix.mul_assoc] rw [← Matrix.mul_assoc DA.basisInv DA.basis, DA.inv_mul_basis, Matrix.one_mul] have hB : DA.basisInv * B * DB.basis = (DA.basisInv * DB.basis) * diagonal DB.eigenvalue := by have hr := congrArg (fun X : RectMatrix n n => DA.basisInv * X * DB.basis) DB.reconstruct calc _ = DA.basisInv * (DB.basis * diagonal DB.eigenvalue * DB.basisInv) * DB.basis := hr _ = _ := by simp only [Matrix.mul_assoc] rw [DB.inv_mul_basis, Matrix.mul_one] have hE : crossPerturbation DA DB = diagonal DA.eigenvalue * (DA.basisInv * DB.basis) - (DA.basisInv * DB.basis) * diagonal DB.eigenvalue := by unfold crossPerturbation rw [Matrix.mul_sub, Matrix.sub_mul, hA, hB] rw [hE] simp [Matrix.mul_apply, Matrix.diagonal_apply] ring
    Causalean.Mathlib.Analysis.crossPerturbation_entry · Causalean/Mathlib/Analysis/SharpFunctionalCalculus.lean:109
  • applyFunction_sub_eq_crossHadamard lemma — Two real diagonalizations and a scalar function give the factorization of their functional-calculus difference through the cross Hadamard matrix.
    n :
    ℕ
    f :
    ℝ → ℝ
    DA.applyFunction f - DB.applyFunction f = DA.basis * crossHadamard DA DB f * DB.basisInv
    Proof (Lean source)
    lemma applyFunction_sub_eq_crossHadamard {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) (f : ℝ → ℝ) : DA.applyFunction f - DB.applyFunction f = DA.basis * crossHadamard DA DB f * DB.basisInv := by let C := DA.basisInv * DB.basis let H : RectMatrix n n := fun i j => crossDividedDifference DA DB f i j * crossPerturbation DA DB i j have hH (i j : Fin n) : H i j = (f (DA.eigenvalue i) - f (DB.eigenvalue j)) * C i j := by dsimp [H, crossDividedDifference] rw [crossPerturbation_entry DA DB] by_cases hij : DA.eigenvalue i = DB.eigenvalue j · simp [hij] · rw [if_neg hij] field_simp [sub_ne_zero.mpr hij] rfl have hcoord : H = diagonal (f ∘ DA.eigenvalue) * C - C * diagonal (f ∘ DB.eigenvalue) := by ext i j rw [hH] simp [C, Matrix.mul_apply, Matrix.diagonal_apply, Function.comp_apply] ring unfold RealDiagonalization.applyFunction change _ = DA.basis * H * DB.basisInv rw [show DA.basis * H * DB.basisInv = DA.basis * (diagonal (f ∘ DA.eigenvalue) * C) * DB.basisInv - DA.basis * (C * diagonal (f ∘ DB.eigenvalue)) * DB.basisInv by rw [hcoord, Matrix.mul_sub, Matrix.sub_mul]] dsimp [C] simp only [Matrix.mul_assoc] rw [DB.basis_mul_inv, Matrix.mul_one, ← Matrix.mul_assoc DA.basis DA.basisInv, DA.basis_mul_inv, Matrix.one_mul]
    Causalean.Mathlib.Analysis.applyFunction_sub_eq_crossHadamard · Causalean/Mathlib/Analysis/SharpFunctionalCalculus.lean:145
  • abs_anchorEval_applyFunction_sub_le_sqrt_dim theorem — Anchored form of the sharp collision-safe two-diagonalizer estimate.
    n :
    ℕ
    a b c d :
    Euc n
    f :
    ℝ → ℝ
    hf :
    hf0 :
    f 0 = 0
    κA κB R :
    ℝ
    hκA :
    DA.conditionNumber ≤ κA
    hκB :
    DB.conditionNumber ≤ κB
    hR0 :
    0 ≤ R
    hRA :
    DA.SpectrumBound R
    hRB :
    DB.SpectrumBound R
    |anchorEval a c (DA.applyFunction f) - anchorEval b d (DB.applyFunction f)|
    ≤ ‖a - b‖ * (κA * R) * ‖c‖
    + ‖b‖ * (sqrt n * κA * κB * ‖A - B‖) * ‖c‖
    + ‖b‖ * (κB * R) * ‖c - d‖
    Proof (Lean source)
    theorem abs_anchorEval_applyFunction_sub_le_sqrt_dim {n : ℕ} {A B : RectMatrix n n} (DA : RealDiagonalization A) (DB : RealDiagonalization B) (a b c d : Euc n) (f : ℝ → ℝ) (hf : LipschitzWith 1 f) (hf0 : f 0 = 0) {κA κB R : ℝ} (hκA : DA.conditionNumber ≤ κA) (hκB : DB.conditionNumber ≤ κB) (hR0 : 0 ≤ R) (hRA : DA.SpectrumBound R) (hRB : DB.SpectrumBound R) : |anchorEval a c (DA.applyFunction f) - anchorEval b d (DB.applyFunction f)| ≤ ‖a - b‖ * (κA * R) * ‖c‖ + ‖b‖ * (sqrt n * κA * κB * ‖A - B‖) * ‖c‖ + ‖b‖ * (κB * R) * ‖c - d‖ := by have hFA := norm_applyFunction_le DA f hf hf0 hκA hR0 hRA have hFB := norm_applyFunction_le DB f hf hf0 hκB hR0 hRB have hdiff := norm_applyFunction_sub_le_sqrt_dim DA DB f hf hκA hκB have hdecomp : anchorEval a c (DA.applyFunction f) - anchorEval b d (DB.applyFunction f) = anchorEval (a - b) c (DA.applyFunction f) + anchorEval b c (DA.applyFunction f - DB.applyFunction f) + anchorEval b (c - d) (DB.applyFunction f) := by unfold anchorEval matrixCLM simp only [map_sub, sub_apply, inner_sub_left, inner_sub_right] ring rw [hdecomp] calc |_ + _ + _| ≤ |anchorEval (a - b) c (DA.applyFunction f)| + |anchorEval b c (DA.applyFunction f - DB.applyFunction f)| + |anchorEval b (c - d) (DB.applyFunction f)| := by calc |_ + _ + _| ≤ |anchorEval (a - b) c (DA.applyFunction f) + anchorEval b c (DA.applyFunction f - DB.applyFunction f)| + |anchorEval b (c - d) (DB.applyFunction f)| := abs_add_le _ _ _ ≤ _ := by gcongr; exact abs_add_le _ _ _ ≤ (‖a - b‖ * ‖DA.applyFunction f‖ * ‖c‖) + (‖b‖ * ‖DA.applyFunction f - DB.applyFunction f‖ * ‖c‖) + (‖b‖ * ‖DB.applyFunction f‖ * ‖c - d‖) := by gcongr · exact abs_anchorEval_le _ _ _ · exact abs_anchorEval_le _ _ _ · exact abs_anchorEval_le _ _ _ _ ≤ _ := by gcongr
    Causalean.Mathlib.Analysis.abs_anchorEval_applyFunction_sub_le_sqrt_dim · Causalean/Mathlib/Analysis/SharpFunctionalCalculus.lean:245
Signed­Tail­Representation 3 core · 10 supporting The elementary identity behind Hoeffding's covariance formula is that every real number is the Lebesgue integral of a *signed tail indicator*: a = ∫ s, (𝟙{s < a} - 𝟙{s < 0}) ds. ★ integral_signedTail_prod

The signed tail representation of a real number

The elementary identity behind Hoeffding's covariance formula is that every real number is the Lebesgue integral of a signed tail indicator:

a = ∫ s, (𝟙{s < a} - 𝟙{s < 0}) ds.

Indeed the integrand vanishes outside the interval between 0 and a, where it equals +1 (if a ≥ 0) or -1 (if a < 0), so the integral is the signed length a.

This file packages that identity, its integrability, and the corresponding statements for the product signedTail x s * signedTail y t on ℝ × ℝ, which represents the product x * y as a two-dimensional Lebesgue integral:

x * y = ∫∫ (𝟙{s < x} - 𝟙{s < 0})(𝟙{t < y} - 𝟙{t < 0}) ds dt.

Together with the L¹ bound ∫∫ |·| = |x| * |y| (which is what makes the downstream Fubini swap legitimate for L² marginals, via Cauchy–Schwarz), this is the entire analytic input to hoeffding_cov_identity.

def tailInd reviewed
Causalean.Mathlib.Analysis.SignedTailRepresentation

For a real threshold and a real argument, the tail indicator equals one when the argument is strictly below the threshold and zero otherwise.

Definition (Lean source)
a s :
ℝ
tailInd a s :
ℝ
(Iio a).indicator (fun _ => (1 : ℝ)) s
Causalean.Mathlib.Analysis.SignedTailRepresentation.tailInd · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:40
def signedTail reviewed
Causalean.Mathlib.Analysis.SignedTailRepresentation

For a real threshold and a real argument, the signed tail indicator is the indicator that the argument is below the threshold minus the indicator that it is below zero.

Definition (Lean source)
a s :
ℝ
signedTail a s :
ℝ
tailInd a s - tailInd 0 s
Causalean.Mathlib.Analysis.SignedTailRepresentation.signedTail · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:48
lemma integral_signedTail_prod reviewed
Causalean.Mathlib.Analysis.SignedTailRepresentation

Product tail representation. For any two reals x and y, their product x * y equals the two-dimensional Lebesgue integral of the product of their signed tail indicators, ∫∫ (𝟙{s<x} - 𝟙{s<0})(𝟙{t<y} - 𝟙{t<0}) ds dt.

Formal statement
x y :
ℝ
(∫ q : ℝ × ℝ, signedTail x q.1 * signedTail y q.2 ∂(volume.prod volume)) = x * y
Proof (Lean source)
lemma integral_signedTail_prod (x y : ℝ) : (∫ q : ℝ × ℝ, signedTail x q.1 * signedTail y q.2 ∂(volume.prod volume)) = x * y := by rw [integral_prod_mul (fun s => signedTail x s) (fun t => signedTail y t), integral_signedTail, integral_signedTail]
Causalean.Mathlib.Analysis.SignedTailRepresentation.integral_signedTail_prod · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:201 · uses signedTail
10 supporting declarations (lemmas, instances)
  • tailInd_apply lemma — The tail indicator equals one below the threshold and zero at or above it.
    a s :
    ℝ
    tailInd a s = if s < a then 1 else 0
    Proof (Lean source)
    @[simp] lemma tailInd_apply (a s : ℝ) : tailInd a s = if s < a then 1 else 0 := by simp [tailInd, Set.indicator_apply, Set.mem_Iio]
    Causalean.Mathlib.Analysis.SignedTailRepresentation.tailInd_apply · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:57
  • signedTail_eq_indicator_sub lemma — signedTail a is, as a function of s, the difference of the indicators of the two intervals Ico 0 a and Ico a 0 (at most one of which is nonempty). This is the normal form used to compute its integral and to see it is integrable.
    a :
    ℝ
    = (Ico 0 a).indicator (fun _ => (1 : ℝ)) - (Ico a 0).indicator (fun _ => (1 : ℝ))
    Proof (Lean source)
    lemma signedTail_eq_indicator_sub (a : ℝ) : signedTail a = (Ico 0 a).indicator (fun _ => (1 : ℝ)) - (Ico a 0).indicator (fun _ => (1 : ℝ)) := by funext s by_cases hsa : s < a <;> by_cases hs0 : s < 0 <;> simp [signedTail, tailInd_apply, Set.indicator_apply, Set.mem_Ico, hsa, hs0]
    Causalean.Mathlib.Analysis.SignedTailRepresentation.signedTail_eq_indicator_sub · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:61
  • measurable_signedTail lemma — signedTail a is measurable in the tail variable s.
    a :
    ℝ
    Proof (Lean source)
    @[fun_prop] lemma measurable_signedTail (a : ℝ) : Measurable (signedTail a) := by rw [signedTail_eq_indicator_sub] exact (measurable_const.indicator measurableSet_Ico).sub (measurable_const.indicator measurableSet_Ico)
    Causalean.Mathlib.Analysis.SignedTailRepresentation.measurable_signedTail · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:72
  • measurable_signedTail_uncurry lemma — signedTail is jointly measurable in (a, s), since {z | z.2 < z.1} is an open (hence measurable) subset of ℝ × ℝ.
    Measurable (fun z : ℝ × ℝ => signedTail z.1 z.2)
    Proof (Lean source)
    @[fun_prop] lemma measurable_signedTail_uncurry : Measurable (fun z : ℝ × ℝ => signedTail z.1 z.2) := by have hxa : MeasurableSet {z : ℝ × ℝ | z.2 < z.1} := measurableSet_lt measurable_snd measurable_fst have hx0 : MeasurableSet {z : ℝ × ℝ | z.2 < (0 : ℝ)} := measurableSet_lt measurable_snd measurable_const have h1 : Measurable (fun z : ℝ × ℝ => ({z : ℝ × ℝ | z.2 < z.1}.indicator (fun _ => (1 : ℝ)) z)) := measurable_const.indicator hxa have h0 : Measurable (fun z : ℝ × ℝ => ({z : ℝ × ℝ | z.2 < (0 : ℝ)}.indicator (fun _ => (1 : ℝ)) z)) := measurable_const.indicator hx0 simpa [signedTail, tailInd, Set.indicator_apply, Set.mem_Iio] using h1.fun_sub h0
    Causalean.Mathlib.Analysis.SignedTailRepresentation.measurable_signedTail_uncurry · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:79
  • abs_signedTail_le_one lemma — The signed tail indicator is bounded by 1 in absolute value.
    a s :
    ℝ
    |signedTail a s| ≤ 1
    Proof (Lean source)
    lemma abs_signedTail_le_one (a s : ℝ) : |signedTail a s| ≤ 1 := by simp [signedTail, tailInd_apply] split_ifs <;> norm_num
    Causalean.Mathlib.Analysis.SignedTailRepresentation.abs_signedTail_le_one · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:96
  • integrable_signedTail lemma — signedTail a is Lebesgue integrable: it is a bounded function supported on a bounded interval.
    a :
    ℝ
    Proof (Lean source)
    @[fun_prop] lemma integrable_signedTail (a : ℝ) : Integrable (signedTail a) volume := by rw [signedTail_eq_indicator_sub] refine Integrable.sub ?_ ?_ · refine (integrableOn_const (μ := volume) (s := Ico (0 : ℝ) a) (hs := ?_)).integrable_indicator measurableSet_Ico rw [Real.volume_Ico] exact ENNReal.ofReal_ne_top · refine (integrableOn_const (μ := volume) (s := Ico a (0 : ℝ)) (hs := ?_)).integrable_indicator measurableSet_Ico rw [Real.volume_Ico] exact ENNReal.ofReal_ne_top
    Causalean.Mathlib.Analysis.SignedTailRepresentation.integrable_signedTail · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:101
  • integral_signedTail lemma — Signed tail representation. ∫ s, (𝟙{s < a} - 𝟙{s < 0}) ds = a.
    a :
    ℝ
    (∫ s : ℝ, signedTail a s ∂volume) = a
    Proof (Lean source)
    lemma integral_signedTail (a : ℝ) : (∫ s : ℝ, signedTail a s ∂volume) = a := by have hrw : (fun s : ℝ => signedTail a s) = fun s : ℝ => (({s : ℝ | s < a}.indicator (fun _ : ℝ => (1 : ℝ)) s) - ({s : ℝ | s < 0}.indicator (fun _ : ℝ => (1 : ℝ)) s)) := rfl rw [hrw] by_cases ha : 0 ≤ a · have hdiff : (fun s : ℝ => ({s : ℝ | s < a}.indicator (fun _ : ℝ => (1 : ℝ)) s) - ({s : ℝ | s < 0}.indicator (fun _ : ℝ => (1 : ℝ)) s)) = (Ico (0 : ℝ) a).indicator (fun _ : ℝ => (1 : ℝ)) := by funext s by_cases hsa : s < a · by_cases hs0 : s < 0 · have hsI : s ∉ Ico (0 : ℝ) a := by simp [Set.mem_Ico, not_le_of_gt hs0] simp [hsa, hs0, hsI] · have hsI : s ∈ Ico (0 : ℝ) a := ⟨le_of_not_gt hs0, hsa⟩ simp [hsa, hs0, hsI] · have hs0 : ¬ s < 0 := fun hs0 => hsa (lt_of_lt_of_le hs0 ha) have hsI : s ∉ Ico (0 : ℝ) a := fun hsI => hsa hsI.2 simp [hsa, hs0, hsI] rw [hdiff] have hint : (∫ s : ℝ, (Ico (0 : ℝ) a).indicator (fun _ : ℝ => (1 : ℝ)) s ∂volume) = volume.real (Ico (0 : ℝ) a) := by exact integral_indicator_one (μ := volume) (s := Ico (0 : ℝ) a) measurableSet_Ico rw [hint, measureReal_def, Real.volume_Ico, ENNReal.toReal_ofReal] · ring · exact sub_nonneg.mpr ha · have hle : a ≤ 0 := le_of_not_ge ha have hdiff : (fun s : ℝ => ({s : ℝ | s < a}.indicator (fun _ : ℝ => (1 : ℝ)) s) - ({s : ℝ | s < 0}.indicator (fun _ : ℝ => (1 : ℝ)) s)) = (Ico a (0 : ℝ)).indicator (fun _ : ℝ => (-1 : ℝ)) := by funext s by_cases hsa : s < a · have hs0 : s < 0 := lt_of_lt_of_le hsa hle have hsI : s ∉ Ico a (0 : ℝ) := fun hsI => (not_lt_of_ge hsI.1) hsa simp [hsa, hs0, hsI] · by_cases hs0 : s < 0 · have hsI : s ∈ Ico a (0 : ℝ) := ⟨le_of_not_gt hsa, hs0⟩ simp [hsa, hs0, hsI] · have hsI : s ∉ Ico a (0 : ℝ) := fun hsI => hs0 hsI.2 simp [hsa, hs0, hsI] rw [hdiff] calc (∫ s : ℝ, (Ico a (0 : ℝ)).indicator (fun _ : ℝ => (-1 : ℝ)) s ∂volume) = volume.real (Ico a (0 : ℝ)) * (-1 : ℝ) := by rw [integral_indicator_const (-1 : ℝ) measurableSet_Ico] simp [smul_eq_mul] _ = a := by rw [measureReal_def, Real.volume_Ico, ENNReal.toReal_ofReal] · ring · exact sub_nonneg.mpr hle
    Causalean.Mathlib.Analysis.SignedTailRepresentation.integral_signedTail · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:116
  • integral_abs_signedTail lemma — The L¹ norm of the signed tail indicator is |a|: the integrand is ±1 on an interval of length |a|.
    a :
    ℝ
    (∫ s : ℝ, |signedTail a s| ∂volume) = |a|
    Proof (Lean source)
    lemma integral_abs_signedTail (a : ℝ) : (∫ s : ℝ, |signedTail a s| ∂volume) = |a| := by by_cases ha : 0 ≤ a · have hnonneg : ∀ s : ℝ, 0 ≤ signedTail a s := by intro s simp [signedTail, tailInd_apply] split_ifs <;> linarith have habs : (fun s : ℝ => |signedTail a s|) = signedTail a := by funext s exact abs_of_nonneg (hnonneg s) rw [habs, integral_signedTail, abs_of_nonneg ha] · have hlt : a < 0 := lt_of_not_ge ha have hnonpos : ∀ s : ℝ, signedTail a s ≤ 0 := by intro s simp [signedTail, tailInd_apply] split_ifs <;> linarith have habs : (fun s : ℝ => |signedTail a s|) = fun s : ℝ => -signedTail a s := by funext s exact abs_of_nonpos (hnonpos s) rw [habs, integral_neg, integral_signedTail, abs_of_neg hlt]
    Causalean.Mathlib.Analysis.SignedTailRepresentation.integral_abs_signedTail · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:171
  • integrable_signedTail_prod lemma — The tensor product (s, t) ↦ signedTail x s * signedTail y t is integrable on ℝ × ℝ for Lebesgue×Lebesgue.
    x y :
    ℝ
    Integrable (fun q : ℝ × ℝ => signedTail x q.1 * signedTail y q.2) (volume.prod volume)
    Proof (Lean source)
    @[fun_prop] lemma integrable_signedTail_prod (x y : ℝ) : Integrable (fun q : ℝ × ℝ => signedTail x q.1 * signedTail y q.2) (volume.prod volume) := (integrable_signedTail x).mul_prod (integrable_signedTail y)
    Causalean.Mathlib.Analysis.SignedTailRepresentation.integrable_signedTail_prod · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:193
  • integral_norm_signedTail_prod lemma — The L¹ norm of the product tail representation is |x| * |y|. This is the domination bound that makes the Fubini swap against an L² coupling valid: its π-integral is E|XY| < ∞ by Cauchy–Schwarz.
    x y :
    ℝ
    (∫ q : ℝ × ℝ, ‖signedTail x q.1 * signedTail y q.2‖ ∂(volume.prod volume)) = |x| * |y|
    Proof (Lean source)
    lemma integral_norm_signedTail_prod (x y : ℝ) : (∫ q : ℝ × ℝ, ‖signedTail x q.1 * signedTail y q.2‖ ∂(volume.prod volume)) = |x| * |y| := by simp only [norm_mul, Real.norm_eq_abs] rw [integral_prod_mul (fun s : ℝ => |signedTail x s|) (fun t : ℝ => |signedTail y t|), integral_abs_signedTail, integral_abs_signedTail]
    Causalean.Mathlib.Analysis.SignedTailRepresentation.integral_norm_signedTail_prod · Causalean/Mathlib/Analysis/SignedTailRepresentation.lean:209
Singular­Value­Weyl 1 core · 4 supporting This module proves the indexed Weyl--Mirsky perturbation inequality for singular values of finite-dimensional real linear maps. ★ abs_singularValues_add_sub_singularValues_le_opNorm

Weyl perturbation inequality for singular values

This module proves the indexed Weyl--Mirsky perturbation inequality for singular values of finite-dimensional real linear maps. Its support lemmas express the two halves of the singular value min--max argument using subspaces, and the main result shows that each singular value is 1-Lipschitz in the operator norm, including Mathlib's zero-extended indices.

theorem abs_singularValues_add_sub_singularValues_le_opNorm reviewed
Causalean.Mathlib.Analysis

Given a baseline linear map, an additive perturbation, and a singular-value index, the absolute change in the indexed singular value is at most the perturbation's operator norm.

Formal statement
V :
Type u_1
shared
W :
Type u_2
shared
A D :
V →ₗ[ℝ] W
j :
ℕ
|(A + D).singularValues j - A.singularValues j| ≤ ‖D.toContinuousLinearMap‖
Proof (Lean source)
theorem abs_singularValues_add_sub_singularValues_le_opNorm (A D : V →ₗ[ℝ] W) (j : ℕ) : |(A + D).singularValues j - A.singularValues j| ≤ ‖D.toContinuousLinearMap‖ := by rw [abs_le] constructor · have h := singularValues_add_le_add_opNorm (A + D) (-D) j have hnorm : ‖(-D).toContinuousLinearMap‖ = ‖D.toContinuousLinearMap‖ := by simp have hcancel : A + D + -D = A := by abel rw [hcancel, hnorm] at h linarith · have h := singularValues_add_le_add_opNorm A D j linarith
Causalean.Mathlib.Analysis.abs_singularValues_add_sub_singularValues_le_opNorm · Causalean/Mathlib/Analysis/SingularValueWeyl.lean:209
4 supporting declarations (lemmas, instances)
  • singularValues_le_of_large_subspace theorem — Given a linear map, an in-range singular-value index, and a subspace whose codimension is at most that index, if the map is bounded by a scalar multiple of the norm on that subspace, then the indexed singular value is at most that scalar.
    V :
    Type u_1
    shared
    W :
    Type u_2
    shared
    A :
    V →ₗ[ℝ] W
    j :
    ℕ
    hj :
    j < finrank ℝ V
    S :
    Submodule ℝ V
    hdim :
    finrank ℝ V ≤ finrank ℝ S + j
    c :
    ℝ
    hbound :
    ∀ x : V
    if
    x ∈ S
    then
    ‖A x‖ ≤ c * ‖x‖
    A.singularValues j ≤ c
    Proof (Lean source)
    theorem singularValues_le_of_large_subspace (A : V →ₗ[ℝ] W) {j : ℕ} (hj : j < finrank ℝ V) (S : Submodule ℝ V) (hdim : finrank ℝ V ≤ finrank ℝ S + j) {c : ℝ} (hbound : ∀ x : V, x ∈ S → ‖A x‖ ≤ c * ‖x‖) : A.singularValues j ≤ c := by let e : Fin (j + 1) → Fin (finrank ℝ V) := fun i => castLE (Nat.succ_le_iff.mpr hj) i let v : Fin (j + 1) → V := fun i => A.isSymmetric_adjoint_comp_self.eigenvectorBasis rfl (e i) let lam : Fin (j + 1) → ℝ := fun i => A.isSymmetric_adjoint_comp_self.eigenvalues rfl (e i) have hv : Orthonormal ℝ v := A.isSymmetric_adjoint_comp_self.eigenvectorBasis rfl |>.orthonormal.comp e (Fin.castLE_injective _) let U : Submodule ℝ V := span ℝ (range v) have hU : finrank ℝ U = j + 1 := by simpa [U] using finrank_span_eq_card hv.linearIndependent have hinfpos : 0 < finrank ℝ (U ⊓ S : Submodule ℝ V) := by have hformula := U.finrank_sup_add_finrank_inf_eq S have hsup := Submodule.finrank_le (U ⊔ S) rw [hU] at hformula omega have hinfne : U ⊓ S ≠ ⊥ := by intro h rw [h, finrank_bot] at hinfpos omega obtain ⟨x, hxUS, hx0⟩ := Submodule.exists_mem_ne_zero_of_ne_bot hinfne have hxU : x ∈ U := hxUS.1 have hxS : x ∈ S := hxUS.2 obtain ⟨a, ha⟩ := (Submodule.mem_span_range_iff_exists_fun ℝ).mp hxU have hx : (∑ i, a i • v i) = x := ha have hxnorm : ‖x‖ ^ 2 = ∑ i, (a i) ^ 2 := by rw [← hx, @norm_sq_eq_re_inner ℝ V] simpa [pow_two] using hv.inner_sum a a univ have hAe (i : Fin (j + 1)) : A.adjoint (A (v i)) = lam i • v i := by change (A.adjoint ∘ₗ A) _ = _ exact A.isSymmetric_adjoint_comp_self.apply_eigenvectorBasis rfl _ have hTx : A.adjoint (A (∑ i, a i • v i)) = ∑ i, (lam i * a i) • v i := by simp [map_sum, map_smul, hAe, smul_smul, mul_comm] have hAxnorm : ‖A x‖ ^ 2 = ∑ i, lam i * (a i) ^ 2 := by rw [← hx, @norm_sq_eq_re_inner ℝ W, ← A.adjoint_inner_left, hTx] simpa [mul_assoc, mul_left_comm, mul_comm, pow_two] using hv.inner_sum (fun i => lam i * a i) a univ have hlam (i : Fin (j + 1)) : A.singularValues j ^ 2 ≤ lam i := by rw [A.sq_singularValues_fin rfl ⟨j, hj⟩] exact A.isSymmetric_adjoint_comp_self.eigenvalues_antitone rfl (show e i ≤ (⟨j, hj⟩ : Fin (finrank ℝ V)) from Fin.le_iff_val_le_val.mpr (le_of_lt_succ i.isLt)) have hsq : (A.singularValues j * ‖x‖) ^ 2 ≤ ‖A x‖ ^ 2 := by rw [mul_pow, hxnorm, hAxnorm, Finset.mul_sum] exact Finset.sum_le_sum fun i _ => mul_le_mul_of_nonneg_right (hlam i) (sq_nonneg (a i)) have hlower : A.singularValues j * ‖x‖ ≤ ‖A x‖ := by exact (sq_le_sq₀ (mul_nonneg (A.singularValues_nonneg j) (norm_nonneg x)) (norm_nonneg (A x))).mp hsq have hupper := hbound x hxS have hnormpos : 0 < ‖x‖ := norm_pos_iff.mpr hx0 nlinarith
    Causalean.Mathlib.Analysis.singularValues_le_of_large_subspace · Causalean/Mathlib/Analysis/SingularValueWeyl.lean:24
  • exists_large_subspace_norm_le_singularValues theorem — Given a linear map and an in-range singular-value index, there is a subspace whose codimension is at most that index and on which the map is bounded by the indexed singular value.
    V :
    Type u_1
    shared
    W :
    Type u_2
    shared
    A :
    V →ₗ[ℝ] W
    j :
    ℕ
    hj :
    j < finrank ℝ V
    ∃ S : Submodule ℝ V,
    finrank ℝ V ≤ finrank ℝ S + j
    conclusion 1
    x :
    V
    x ∈ S
    ‖A x‖ ≤ A.singularValues j * ‖x‖
    Proof (Lean source)
    theorem exists_large_subspace_norm_le_singularValues (A : V →ₗ[ℝ] W) {j : ℕ} (hj : j < finrank ℝ V) : ∃ S : Submodule ℝ V, finrank ℝ V ≤ finrank ℝ S + j ∧ ∀ x : V, x ∈ S → ‖A x‖ ≤ A.singularValues j * ‖x‖ := by classical let hT := A.isSymmetric_adjoint_comp_self let b := hT.eigenvectorBasis rfl let I := {i : Fin (finrank ℝ V) // j ≤ i.1} let S := span ℝ (range (fun i : I ↦ b i.1)) refine ⟨S, ?_, ?_⟩ · have hli : LinearIndependent ℝ (fun i : I ↦ b i.1) := b.orthonormal.linearIndependent.comp _ Subtype.val_injective have hdim : finrank ℝ S = card I := finrank_span_eq_card hli have hhead : card {i : Fin (finrank ℝ V) // ¬j ≤ i.1} = j := by simpa only [not_le, Fintype.card_fin] using (Fintype.card_congr (Fin.castLEOrderIso (le_of_lt hj)).symm.toEquiv) have hsplit := Fintype.card_subtype_compl (fun i : Fin (finrank ℝ V) ↦ j ≤ i.1) rw [hdim] dsimp [I] have hsplit' : j = finrank ℝ V - card {i : Fin (finrank ℝ V) // j ≤ i.1} := hhead.symm.trans (by simpa only [Fintype.card_fin] using hsplit) omega · intro x hx have hcoord {i : Fin (finrank ℝ V)} (hi : i.1 < j) : ⟪b i, x⟫_ℝ = 0 := by rcases (Submodule.mem_span_range_iff_exists_fun ℝ).mp hx with ⟨c, hc⟩ rw [← hc] simp only [inner_sum, real_inner_smul_right] apply Finset.sum_eq_zero intro k _ have hik : i ≠ k.1 := by intro h subst i omega rw [b.orthonormal.2 hik] simp have hof (r : ℝ) : (RCLike.ofReal r : ℝ) = r := by calc (RCLike.ofReal r : ℝ) = RCLike.re (RCLike.ofReal r : ℝ) := (RCLike.re_to_real).symm _ = r := RCLike.ofReal_re r have hnorm_sq : ‖A x‖ ^ 2 = ∑ i : Fin (finrank ℝ V), hT.eigenvalues rfl i * ‖⟪b i, x⟫_ℝ‖ ^ 2 := by calc ‖A x‖ ^ 2 = inner ℝ (A x) (A x) := (real_inner_self_eq_norm_sq _).symm _ = inner ℝ x ((A.adjoint ∘ₗ A) x) := by change inner ℝ (A x) (A x) = inner ℝ x (A.adjoint (A x)) exact (A.adjoint_inner_right x (A x)).symm _ = ∑ i, inner ℝ x (b i) * inner ℝ (b i) ((A.adjoint ∘ₗ A) x) := (b.sum_inner_mul_inner x ((A.adjoint ∘ₗ A) x)).symm _ = ∑ i, hT.eigenvalues rfl i * ‖inner ℝ (b i) x‖ ^ 2 := by apply Finset.sum_congr rfl intro i _ rw [← hT (b i) x, hT.apply_eigenvectorBasis] simp only [real_inner_smul_left, hof] rw [real_inner_comm x (b i)] simp only [Real.norm_eq_abs, sq_abs] ring apply (sq_le_sq₀ (norm_nonneg _) (mul_nonneg (A.singularValues_nonneg j) (norm_nonneg _))).mp rw [mul_pow] calc ‖A x‖ ^ 2 = ∑ i : Fin (finrank ℝ V), hT.eigenvalues rfl i * ‖inner ℝ (b i) x‖ ^ 2 := hnorm_sq _ ≤ ∑ i : Fin (finrank ℝ V), A.singularValues j ^ 2 * ‖inner ℝ (b i) x‖ ^ 2 := by apply Finset.sum_le_sum intro i _ by_cases hi : j ≤ i.1 · rw [A.sq_singularValues_fin rfl ⟨j, hj⟩] exact mul_le_mul_of_nonneg_right (hT.eigenvalues_antitone rfl hi) (sq_nonneg _) · have hc := hcoord (Nat.lt_of_not_ge hi) rw [hc, norm_zero, zero_pow (by omega : 2 ≠ 0), mul_zero, mul_zero] _ = A.singularValues j ^ 2 * ∑ i : Fin (finrank ℝ V), ‖inner ℝ (b i) x‖ ^ 2 := by rw [Finset.mul_sum] _ = A.singularValues j ^ 2 * ‖x‖ ^ 2 := by rw [b.sum_sq_norm_inner_right]
    Causalean.Mathlib.Analysis.exists_large_subspace_norm_le_singularValues · Causalean/Mathlib/Analysis/SingularValueWeyl.lean:93
  • singularValues_add_le_add_opNorm theorem — Given a baseline linear map, an additive perturbation, and a singular-value index, the perturbation can increase that indexed singular value by no more than its operator norm.
    V :
    Type u_1
    shared
    W :
    Type u_2
    shared
    A D :
    V →ₗ[ℝ] W
    j :
    ℕ
    (A + D).singularValues j ≤ A.singularValues j + ‖D.toContinuousLinearMap‖
    Proof (Lean source)
    theorem singularValues_add_le_add_opNorm (A D : V →ₗ[ℝ] W) (j : ℕ) : (A + D).singularValues j ≤ A.singularValues j + ‖D.toContinuousLinearMap‖ := by by_cases hj : j < finrank ℝ V · obtain ⟨S, hdim, hA⟩ := exists_large_subspace_norm_le_singularValues A hj apply singularValues_le_of_large_subspace (A + D) hj S hdim intro x hx calc ‖(A + D) x‖ ≤ ‖A x‖ + ‖D x‖ := by simpa only [LinearMap.add_apply] using norm_add_le (A x) (D x) _ ≤ A.singularValues j * ‖x‖ + ‖D.toContinuousLinearMap‖ * ‖x‖ := add_le_add (hA x hx) (D.toContinuousLinearMap.le_opNorm x) _ = (A.singularValues j + ‖D.toContinuousLinearMap‖) * ‖x‖ := by ring · have hdim : finrank ℝ V ≤ j := Nat.le_of_not_gt hj simp only [LinearMap.singularValues_of_finrank_le _ hdim, zero_add] exact norm_nonneg _
    Causalean.Mathlib.Analysis.singularValues_add_le_add_opNorm · Causalean/Mathlib/Analysis/SingularValueWeyl.lean:187
  • abs_singularValues_add_sub_singularValues_le theorem — Given a baseline continuous linear map, an additive continuous perturbation, and a singular-value index, the absolute change in the indexed singular value is at most the perturbation's operator norm.
    V :
    Type u_1
    shared
    W :
    Type u_2
    shared
    A D :
    V →L[ℝ] W
    j :
    ℕ
    |(A + D).toLinearMap.singularValues j - A.toLinearMap.singularValues j| ≤ ‖D‖
    Proof (Lean source)
    theorem ContinuousLinearMap.abs_singularValues_add_sub_singularValues_le (A D : V →L[ℝ] W) (j : ℕ) : |(A + D).toLinearMap.singularValues j - A.toLinearMap.singularValues j| ≤ ‖D‖ := by have hD : D.toLinearMap.toContinuousLinearMap = D := by ext x; rfl simpa [hD] using abs_singularValues_add_sub_singularValues_le_opNorm A.toLinearMap D.toLinearMap j
    Causalean.Mathlib.Analysis.ContinuousLinearMap.abs_singularValues_add_sub_singularValues_le · Causalean/Mathlib/Analysis/SingularValueWeyl.lean:228
Smooth­Reciprocal 2 core · 3 supporting The reciprocal x ↦ x⁻¹ is singular at 0. ★ recipC_contDiff

A globally C¹ reciprocal with a floor near the singularity

The reciprocal x ↦ x⁻¹ is singular at 0. recipC ε is a modification that agrees with x⁻¹ on x ≥ ε/2 but is smoothly damped to 0 on the neighbourhood of the singularity, so it is globally C¹ on all of ℝ. This is the reusable core of the "globally C¹ extension of an objective that is singular on the boundary of its feasible box" pattern: multiply the singular part by a Real.smoothTransition cutoff that is 1 on the feasible region and 0 past the boundary.

def recipC reviewed
Causalean.Mathlib

Given a real cutoff scale ε\varepsilon and a real argument xx, the floored reciprocal is x−1x^{-1} multiplied by the smooth transition evaluated at (x−ε/4)/(ε/4)(x-\varepsilon/4)/(\varepsilon/4). This definition applies for every real cutoff scale, including zero and negative values.

Definition (Lean source)
ε :
ℝ
x :
ℝ
recipC ε x :
ℝ
Real.smoothTransition ((x - ε / 4) / (ε / 4)) * x⁻¹
lemma recipC_contDiff reviewed
Causalean.Mathlib

Global continuous differentiability of the floored reciprocal. For a strictly positive threshold ε, the floored reciprocal recipC ε is continuously differentiable on all of the reals.

Formal statement
ε :
ℝ
hε :
0 < ε
ContDiff ℝ 1 (recipC ε)
Proof (Lean source)
@[fun_prop] lemma recipC_contDiff (ε : ℝ) (hε : 0 < ε) : ContDiff ℝ 1 (recipC ε) := recipC_contDiff_of 1 ε hε
Causalean.Mathlib.recipC_contDiff · Causalean/Mathlib/Analysis/SmoothReciprocal.lean:84 · uses recipC
3 supporting declarations (lemmas, instances)
  • recipC_eq_inv lemma — On the region x ≥ ε/2 (with ε > 0) the floored reciprocal is exactly x⁻¹, because the smooth cutoff has already saturated to 1 there.
    ε x :
    ℝ
    hε :
    0 < ε
    hx :
    ε / 2 ≤ x
    recipC ε x = x⁻¹
    Proof (Lean source)
    lemma recipC_eq_inv {ε x : ℝ} (hε : 0 < ε) (hx : ε / 2 ≤ x) : recipC ε x = x⁻¹ := by unfold recipC have hden : 0 < ε / 4 := by positivity have hone : 1 ≤ (x - ε / 4) / (ε / 4) := by rw [le_div_iff₀ hden] linarith rw [Real.smoothTransition.one_of_one_le hone] ring
  • recipC_contDiff_of lemma — The floored reciprocal is globally Cⁿ on all of ℝ, for EVERY smoothness order n: near the singularity the smooth cutoff vanishes to infinite order, absorbing the blow-up of x⁻¹, and away from the singularity it is a product of Cⁿ functions.
    n :
    ℕ∞
    ε :
    ℝ
    hε :
    0 < ε
    ContDiff ℝ n (recipC ε)
    Proof (Lean source)
    lemma recipC_contDiff_of (n : ℕ∞) (ε : ℝ) (hε : 0 < ε) : ContDiff ℝ n (recipC ε) := by rw [contDiff_iff_contDiffAt] intro x unfold recipC by_cases hx : x < ε / 4 · have hev : (fun y : ℝ => Real.smoothTransition ((y - ε / 4) / (ε / 4)) * y⁻¹) =ᶠ[nhds x] fun _ => 0 := by filter_upwards [Iio_mem_nhds hx] with y hy have harg : (y - ε / 4) / (ε / 4) ≤ 0 := by have hden : 0 < ε / 4 := by positivity exact div_nonpos_of_nonpos_of_nonneg (by linarith [show y < ε / 4 from hy]) hden.le rw [Real.smoothTransition.zero_of_nonpos harg] simp exact (contDiffAt_const : ContDiffAt ℝ n (fun _ : ℝ => (0 : ℝ)) x).congr_of_eventuallyEq hev · have hxpos : x ≠ 0 := by have hxge : ε / 4 ≤ x := le_of_not_gt hx have hpos : 0 < x := by linarith exact ne_of_gt hpos have hcut : ContDiffAt ℝ n (fun y : ℝ => Real.smoothTransition ((y - ε / 4) / (ε / 4))) x := by have hlin : ContDiff ℝ n (fun y : ℝ => (y - ε / 4) / (ε / 4)) := by fun_prop exact (Real.smoothTransition.contDiff.comp hlin).contDiffAt have hinv : ContDiffAt ℝ n (fun y : ℝ => y⁻¹) x := contDiffAt_inv ℝ hxpos exact hcut.mul hinv
    Causalean.Mathlib.recipC_contDiff_of · Causalean/Mathlib/Analysis/SmoothReciprocal.lean:47
  • recipC_contDiff_two lemma — recipC ε is globally C². Specialization of recipC_contDiff_of; this is the order the reciprocal-product envelope's directional curvature modulus needs.
    ε :
    ℝ
    hε :
    0 < ε
    ContDiff ℝ 2 (recipC ε)
    Proof (Lean source)
    @[fun_prop] lemma recipC_contDiff_two (ε : ℝ) (hε : 0 < ε) : ContDiff ℝ 2 (recipC ε) := recipC_contDiff_of 2 ε hε
    Causalean.Mathlib.recipC_contDiff_two · Causalean/Mathlib/Analysis/SmoothReciprocal.lean:93
Spectral­Enumeration 4 core · 7 supporting This module turns a real diagonalization into an injective list of its distinct spectral values, padding unused slots by distinct points in a prescribed interval. ★ exists_polynomialSpectralLaw

Collision-safe finite spectral enumeration

This module turns a real diagonalization into an injective list of its distinct spectral values, padding unused slots by distinct points in a prescribed interval. It also identifies the associated Lagrange matrix polynomials with aggregate spectral projectors, so repeated diagonal coordinates contribute once rather than being overcounted.

def ComplexMatrixEigenvalue reviewed
Causalean.Mathlib.Analysis

A complex right eigenvalue of a real square matrix.

Definition (Lean source)
n :
ℕ
A :
z :
ℂ
ComplexMatrixEigenvalue A z :
Prop
∃ v : Fin n → ℂ,
v ≠ 0
clause 1
i :
∑ j, (A i j : ℂ) * v j = z * v i
Causalean.Mathlib.Analysis.ComplexMatrixEigenvalue · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:22 · uses RectMatrix
def polynomialSpectralProjector reviewed
Causalean.Mathlib.Analysis

The Lagrange matrix polynomial attached to slot i of a proposed list of spectral values of a square matrix A: the product, over all slots j whose value differs from the value of slot i, of (A − valueⱼ·I)/(valueᵢ − valueⱼ).

Definition (Lean source)
n :
ℕ
A :
value :
Fin n → ℝ
i :
Fin n
polynomialSpectralProjector A value i :
(Finset.univ.filter (fun j => value j ≠ value i)).toList.foldl (fun E j => E * ((value i - value j)⁻¹ • (A - value j • (1 : RectMatrix n n)))) 1
Causalean.Mathlib.Analysis.polynomialSpectralProjector · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:26 · uses RectMatrix
def scalarLagrange reviewed
Causalean.Mathlib.Analysis

The scalar Lagrange polynomial of slot i of a list of real values, evaluated at a real point x: the product, over all slots j whose value differs from the value of slot i, of (x − valueⱼ)/(valueᵢ − valueⱼ).

Definition (Lean source)
n :
ℕ
value :
Fin n → ℝ
i :
Fin n
x :
ℝ
scalarLagrange value i x :
ℝ
∏ j ∈ Finset.univ.filter (fun j => value j ≠ value i), (value i - value j)⁻¹ * (x - value j)
Causalean.Mathlib.Analysis.scalarLagrange · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:35
theorem exists_polynomialSpectralLaw reviewed
Causalean.Mathlib.Analysis

A real diagonalization of an n×n matrix whose eigenvalues all lie in the interval from −radius to radius for a positive radius, together with nonnegative masses summing to one, a left vector equal to the transposed inverse eigenbasis applied to the masses, and a right vector that the inverse eigenbasis sends to the all-ones vector, yields a list of n pairwise distinct real values in that interval that contains every eigenvalue, such that the weights obtained by pairing the left vector with each slot's Lagrange matrix polynomial applied to the right vector are nonnegative and sum to one.

Formal statement
n :
ℕ
radius :
ℝ
hradius :
0 < radius
mass left right :
Fin n → ℝ
hmass :
(∀ u, 0 ≤ mass u) ∧ ∑ u, mass u = 1
hbound :
∀ u, D.eigenvalue u ∈ Icc (-radius) radius
hleft :
left = mulVec D.basisInv.transpose mass
hright :
mulVec D.basisInv right = fun _ => 1
∃ value : Fin n → ℝ,
Injective value
conclusion 1
u :
∃ i, value i = D.eigenvalue u
conclusion 2
i :
value i ∈ Icc (-radius) radius
conclusion 3
i :
0 ≤ ∑ a, left a * (∑ b, polynomialSpectralProjector A value i a b * right b)
conclusion 4
∑ i, (∑ a, left a * (∑ b, polynomialSpectralProjector A value i a b * right b)) = 1
Proof (Lean source)
theorem exists_polynomialSpectralLaw {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) {radius : ℝ} (hradius : 0 < radius) (mass left right : Fin n → ℝ) (hmass : (∀ u, 0 ≤ mass u) ∧ ∑ u, mass u = 1) (hbound : ∀ u, D.eigenvalue u ∈ Icc (-radius) radius) (hleft : left = mulVec D.basisInv.transpose mass) (hright : mulVec D.basisInv right = fun _ => 1) : ∃ value : Fin n → ℝ, Injective value ∧ (∀ u, ∃ i, value i = D.eigenvalue u) ∧ (∀ i, value i ∈ Icc (-radius) radius) ∧ (∀ i, 0 ≤ ∑ a, left a * (∑ b, polynomialSpectralProjector A value i a b * right b)) ∧ ∑ i, (∑ a, left a * (∑ b, polynomialSpectralProjector A value i a b * right b)) = 1 := by classical obtain ⟨value, hinj, hcomplete, hvalueBound⟩ := exists_injective_spectralEnumeration D hradius hbound refine ⟨value, hinj, hcomplete, hvalueBound, ?_, ?_⟩ · intro i rw [polynomialSpectralProjector_eq_projector_or_zero D value hinj hcomplete i] split_ifs with hi · rw [anchor_projector_eq_clusterMass D mass left right hleft hright] exact Finset.sum_nonneg fun u _ => by split_ifs · exact hmass.1 u · exact le_rfl · simp · have hslot (i : Fin n) : (∑ a, left a * (∑ b, polynomialSpectralProjector A value i a b * right b)) = ∑ u, if D.eigenvalue u = value i then mass u else 0 := by rw [polynomialSpectralProjector_eq_projector_or_zero D value hinj hcomplete i] split_ifs with hi · exact anchor_projector_eq_clusterMass D mass left right hleft hright _ · have hnone (u : Fin n) : D.eigenvalue u ≠ value i := by intro h apply hi simp [RealDiagonalization.spectralValues, ← h] simp [hnone] simp_rw [hslot] rw [Finset.sum_comm] calc ∑ u, ∑ i, (if D.eigenvalue u = value i then mass u else 0) = ∑ u, mass u := by apply Finset.sum_congr rfl intro u _ obtain ⟨i, hi⟩ := hcomplete u rw [Finset.sum_eq_single i] · simp [hi] · intro j _ hji simp only [ite_eq_right_iff] intro h exact (hji (hinj (h.symm.trans hi.symm))).elim · simp _ = 1 := hmass.2
7 supporting declarations (lemmas, instances)
  • polynomialSpectralProjector_eq_projector_or_zero theorem — For an injective enumeration containing every spectral value, a Lagrange matrix polynomial is the aggregate projector at its slot when the slot is spectral, and is zero at every dummy slot.
    n :
    ℕ
    value :
    Fin n → ℝ
    hinj :
    Injective value
    hcomplete :
    ∀ u, ∃ i, value i = D.eigenvalue u
    i :
    Fin n
    = if value i ∈ D.spectralValues then D.projector (value i) else 0
    Proof (Lean source)
    theorem polynomialSpectralProjector_eq_projector_or_zero {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) (value : Fin n → ℝ) (hinj : Injective value) (hcomplete : ∀ u, ∃ i, value i = D.eigenvalue u) (i : Fin n) : polynomialSpectralProjector A value i = if value i ∈ D.spectralValues then D.projector (value i) else 0 := by rw [polynomialSpectralProjector_eq_applyFunction D] unfold RealDiagonalization.applyFunction RealDiagonalization.projector split_ifs with hi · have hscalar (u : Fin n) : scalarLagrange value i (D.eigenvalue u) = if D.eigenvalue u = value i then 1 else 0 := by obtain ⟨j, hj⟩ := hcomplete u rw [← hj, scalarLagrange_on_value value hinj] by_cases hji : j = i · subst j simp · have hne : value j ≠ value i := fun h => hji (hinj h) simp [hji, hne] rw [show diagonal (scalarLagrange value i ∘ D.eigenvalue) = diagonal (fun u => if D.eigenvalue u = value i then 1 else 0) by ext u v by_cases huv : u = v · subst v simp [Matrix.diagonal_apply, Function.comp_apply, hscalar] · simp [Matrix.diagonal_apply, huv]] · have hnone (u : Fin n) : D.eigenvalue u ≠ value i := by intro h apply hi simp [RealDiagonalization.spectralValues, ← h] rw [show diagonal (scalarLagrange value i ∘ D.eigenvalue) = (0 : RectMatrix n n) by ext u v by_cases huv : u = v · subst v obtain ⟨j, hj⟩ := hcomplete u have hji : j ≠ i := fun h => hnone u (hj ▸ congrArg value h) have hscalar := scalarLagrange_on_value value hinj i j rw [if_neg hji] at hscalar simp [Matrix.diagonal_apply, Function.comp_apply, ← hj, hscalar] · simp [Matrix.diagonal_apply, huv]] simp
    Causalean.Mathlib.Analysis.polynomialSpectralProjector_eq_projector_or_zero · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:129
  • polynomialSpectralProjector_eq_projector_or_zero_of_complete theorem — Completeness alone identifies the Lagrange polynomial with the aggregate projector at every listed spectral value. Injectivity is unnecessary here: repeated listed values give the same aggregate projector, while nonspectral dummy values give zero.
    n :
    ℕ
    value :
    Fin n → ℝ
    hcomplete :
    ∀ u, ∃ i, value i = D.eigenvalue u
    i :
    Fin n
    = if value i ∈ D.spectralValues then D.projector (value i) else 0
    Proof (Lean source)
    theorem polynomialSpectralProjector_eq_projector_or_zero_of_complete {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) (value : Fin n → ℝ) (hcomplete : ∀ u, ∃ i, value i = D.eigenvalue u) (i : Fin n) : polynomialSpectralProjector A value i = if value i ∈ D.spectralValues then D.projector (value i) else 0 := by rw [polynomialSpectralProjector_eq_applyFunction D] unfold RealDiagonalization.applyFunction RealDiagonalization.projector split_ifs with hi · have hscalar (u : Fin n) : scalarLagrange value i (D.eigenvalue u) = if D.eigenvalue u = value i then 1 else 0 := by classical unfold scalarLagrange by_cases hu : D.eigenvalue u = value i · rw [if_pos hu] apply Finset.prod_eq_one intro j hj have hne : value j ≠ value i := (Finset.mem_filter.mp hj).2 rw [hu] field_simp · rw [if_neg hu] obtain ⟨j, hj⟩ := hcomplete u apply Finset.prod_eq_zero (Finset.mem_filter.mpr ⟨Finset.mem_univ j, by intro h exact hu (hj.symm.trans h)⟩) simp [hj] rw [show diagonal (scalarLagrange value i ∘ D.eigenvalue) = diagonal (fun u => if D.eigenvalue u = value i then 1 else 0) by ext u v by_cases huv : u = v · subst v simp [Matrix.diagonal_apply, Function.comp_apply, hscalar] · simp [Matrix.diagonal_apply, huv]] · have hnone (u : Fin n) : D.eigenvalue u ≠ value i := by intro h apply hi simp [RealDiagonalization.spectralValues, ← h] rw [show diagonal (scalarLagrange value i ∘ D.eigenvalue) = (0 : RectMatrix n n) by ext u v by_cases huv : u = v · subst v classical obtain ⟨j, hj⟩ := hcomplete u have hz : scalarLagrange value i (D.eigenvalue u) = 0 := by unfold scalarLagrange apply Finset.prod_eq_zero (Finset.mem_filter.mpr ⟨Finset.mem_univ j, by intro h exact hnone u (hj.symm.trans h)⟩) simp [hj] simp [Matrix.diagonal_apply, Function.comp_apply, hz] · simp [Matrix.diagonal_apply, huv]] simp
    Causalean.Mathlib.Analysis.polynomialSpectralProjector_eq_projector_or_zero_of_complete · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:173
  • complete_clusterMass_integral_eq theorem — A complete n-slot enumeration whose cluster masses normalize to one cannot repeat a positive spectral cluster. Consequently it integrates every test function exactly as the underlying diagonal coordinates do; zero-mass dummy slots are harmless.
    n :
    ℕ
    mass eig value :
    Fin n → ℝ
    hmasspos :
    ∀ u, 0 < mass u
    hmasssum :
    ∑ u, mass u = 1
    hcomplete :
    ∀ u, ∃ i, eig u = value i
    houtsum :
    ∑ i, (∑ u, if eig u = value i then mass u else 0) = 1
    f :
    ℝ → ℝ
    ∑ i, (∑ u, if eig u = value i then mass u else 0) * f (value i) = ∑ u, mass u * f (eig u)
    Proof (Lean source)
    theorem complete_clusterMass_integral_eq {n : ℕ} (mass eig value : Fin n → ℝ) (hmasspos : ∀ u, 0 < mass u) (hmasssum : ∑ u, mass u = 1) (hcomplete : ∀ u, ∃ i, eig u = value i) (houtsum : ∑ i, (∑ u, if eig u = value i then mass u else 0) = 1) : ∀ f : ℝ → ℝ, ∑ i, (∑ u, if eig u = value i then mass u else 0) * f (value i) = ∑ u, mass u * f (eig u) := by classical let c : Fin n → ℝ := fun u => ∑ i, if eig u = value i then 1 else 0 have hc1 (u : Fin n) : 1 ≤ c u := by obtain ⟨i, hi⟩ := hcomplete u dsimp [c] calc 1 = (if eig u = value i then 1 else 0 : ℝ) := by simp [hi] _ ≤ ∑ j, (if eig u = value j then 1 else 0 : ℝ) := Finset.single_le_sum (fun j _ => show (0 : ℝ) ≤ (if eig u = value j then 1 else 0) by positivity) (Finset.mem_univ i) have hweighted : ∑ u, mass u * c u = 1 := by rw [← houtsum, Finset.sum_comm] apply Finset.sum_congr rfl intro u _ dsimp [c] rw [Finset.mul_sum] apply Finset.sum_congr rfl intro i _ split_ifs <;> ring have hzero : ∑ u, mass u * (c u - 1) = 0 := by calc _ = ∑ u, (mass u * c u - mass u) := by apply Finset.sum_congr rfl intro u _ ring _ = (∑ u, mass u * c u) - ∑ u, mass u := by rw [Finset.sum_sub_distrib] _ = 0 := by rw [hweighted, hmasssum]; ring have hc (u : Fin n) : c u = 1 := by have hnonneg (v : Fin n) : 0 ≤ mass v * (c v - 1) := mul_nonneg (hmasspos v).le (sub_nonneg.mpr (hc1 v)) have hz := (Finset.sum_eq_zero_iff_of_nonneg (fun v _ => hnonneg v)).mp hzero u (Finset.mem_univ u) rcases mul_eq_zero.mp hz with hm | hh · exact False.elim ((hmasspos u).ne' hm) · linarith intro f simp_rw [Finset.sum_mul] rw [Finset.sum_comm] apply Finset.sum_congr rfl intro u _ calc (∑ i, (if eig u = value i then mass u else 0) * f (value i)) = mass u * f (eig u) * c u := by dsimp [c] rw [Finset.mul_sum] apply Finset.sum_congr rfl intro i _ split_ifs with h · rw [h]; ring · ring _ = mass u * f (eig u) := by rw [hc u, mul_one]
    Causalean.Mathlib.Analysis.complete_clusterMass_integral_eq · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:230
  • diagonal_eigenvalue_is_complexEigenvalue theorem — Every listed diagonal coordinate is an actual complex eigenvalue of the reconstructed real matrix.
    n :
    ℕ
    u :
    Fin n
    ComplexMatrixEigenvalue A (D.eigenvalue u)
    Proof (Lean source)
    theorem RealDiagonalization.diagonal_eigenvalue_is_complexEigenvalue {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) (u : Fin n) : ComplexMatrixEigenvalue A (D.eigenvalue u) := by classical let v : Fin n → ℂ := fun i => D.basis i u refine ⟨v, ?_, ?_⟩ · intro hv have hentry := congrArg (fun M : RectMatrix n n => M u u) D.inv_mul_basis have hzero : ∑ j, D.basisInv u j * D.basis j u = 0 := by apply Finset.sum_eq_zero intro j _ have hj := congrFun hv j change (D.basis j u : ℂ) = 0 at hj have hjR : D.basis j u = 0 := by exact_mod_cast hj simp [hjR] rw [Matrix.mul_apply, hzero] at hentry simpa [Matrix.one_apply] using hentry · intro i have hcol : ∑ j, A i j * D.basis j u = D.eigenvalue u * D.basis i u := by have hmat : A * D.basis = D.basis * diagonal D.eigenvalue := by calc A * D.basis = (D.basis * diagonal D.eigenvalue * D.basisInv) * D.basis := congrArg (fun M => M * D.basis) D.reconstruct _ = D.basis * diagonal D.eigenvalue * (D.basisInv * D.basis) := by simp only [Matrix.mul_assoc] _ = _ := by rw [D.inv_mul_basis, Matrix.mul_one] have h := congrArg (fun M : RectMatrix n n => M i u) hmat simpa [Matrix.mul_apply, Matrix.diagonal_apply, mul_comm] using h change ∑ j, (A i j : ℂ) * (D.basis j u : ℂ) = (D.eigenvalue u : ℂ) * (D.basis i u : ℂ) exact_mod_cast hcol
    Causalean.Mathlib.Analysis.RealDiagonalization.diagonal_eigenvalue_is_complexEigenvalue · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:295
  • exists_injective_spectralEnumeration theorem — If the diagonal values lie in a nondegenerate symmetric interval, their distinct values have an injective Fin n enumeration in that interval; unused slots are necessarily nonspectral.
    n :
    ℕ
    radius :
    ℝ
    hradius :
    0 < radius
    hbound :
    ∀ u, D.eigenvalue u ∈ Icc (-radius) radius
    ∃ value : Fin n → ℝ,
    Injective value
    conclusion 1
    u :
    ∃ i, value i = D.eigenvalue u
    conclusion 2
    i :
    value i ∈ Icc (-radius) radius
    Proof (Lean source)
    theorem exists_injective_spectralEnumeration {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) {radius : ℝ} (hradius : 0 < radius) (hbound : ∀ u, D.eigenvalue u ∈ Icc (-radius) radius) : ∃ value : Fin n → ℝ, Injective value ∧ (∀ u, ∃ i, value i = D.eigenvalue u) ∧ ∀ i, value i ∈ Icc (-radius) radius := by classical let S := D.spectralValues let m := S.card have hmn : m ≤ n := by dsimp [m, S, RealDiagonalization.spectralValues] simpa using (Finset.card_image_le (s := (Finset.univ : Finset (Fin n))) (f := D.eigenvalue)) let specEnum : Fin m ≃ S := (S.orderIsoOfFin (show S.card = m from rfl)).toEquiv let base : Fin m ↪ {x : ℝ // x ∈ Icc (-radius) radius} := ⟨fun j => ⟨(specEnum j).1, by rcases Finset.mem_image.mp (specEnum j).2 with ⟨u, -, hu⟩ rw [← hu] exact hbound u⟩, fun i j h => by apply specEnum.injective apply Subtype.ext exact congrArg (fun q : {x : ℝ // x ∈ Icc (-radius) radius} => q.1) h⟩ have hinfinite : Infinite {x : ℝ // x ∈ Icc (-radius) radius} := Set.Icc.infinite (by linarith) letI := hinfinite obtain ⟨full, hfull⟩ := Fin.Embedding.restrictSurjective_of_le_ENatCard hmn (by rw [ENat.card_eq_top_of_infinite]; simp) base let value : Fin n → ℝ := fun i => full i refine ⟨value, fun i j h => full.injective (Subtype.ext h), ?_, fun i => (full i).2⟩ intro u let x : S := ⟨D.eigenvalue u, by simp [S, RealDiagonalization.spectralValues]⟩ let j : Fin m := (S.orderIsoOfFin rfl).symm x refine ⟨Fin.castLE hmn j, ?_⟩ have hj := congrArg (fun f => f j) hfull have hj' := congrArg Subtype.val hj have hx : (specEnum j).1 = D.eigenvalue u := by simp [j, x, specEnum] have hb : (base j).1 = (specEnum j).1 := rfl have hv : value (castLE hmn j) = (base j).1 := by simpa [value, Function.Embedding.trans_apply] using hj' exact hv.trans (hb.trans hx)
    Causalean.Mathlib.Analysis.exists_injective_spectralEnumeration · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:329
  • anchor_projector_eq_clusterMass theorem — The coordinate functional of an aggregate projector is exactly the total mass in the corresponding repeated-eigenvalue cluster.
    n :
    ℕ
    mass left right :
    Fin n → ℝ
    hleft :
    left = mulVec D.basisInv.transpose mass
    hright :
    mulVec D.basisInv right = fun _ => 1
    x :
    ℝ
    ∑ a, left a * (∑ b, D.projector x a b * right b)
    = ∑ u, if D.eigenvalue u = x then mass u else 0
    Proof (Lean source)
    theorem anchor_projector_eq_clusterMass {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) (mass left right : Fin n → ℝ) (hleft : left = mulVec D.basisInv.transpose mass) (hright : mulVec D.basisInv right = fun _ => 1) (x : ℝ) : ∑ a, left a * (∑ b, D.projector x a b * right b) = ∑ u, if D.eigenvalue u = x then mass u else 0 := by rw [hleft] change dotProduct (mulVec D.basisInv.transpose mass) (mulVec (D.projector x) right) = _ rw [dotProduct_comm, Matrix.dotProduct_transpose_mulVec] unfold RealDiagonalization.projector have hmat : D.basisInv * (D.basis * diagonal (fun i => if D.eigenvalue i = x then 1 else 0) * D.basisInv) = diagonal (fun i => if D.eigenvalue i = x then 1 else 0) * D.basisInv := by calc _ = (D.basisInv * D.basis) * (diagonal (fun i => if D.eigenvalue i = x then 1 else 0) * D.basisInv) := by simp only [Matrix.mul_assoc] _ = _ := by rw [D.inv_mul_basis, Matrix.one_mul] rw [Matrix.mulVec_mulVec, hmat, ← Matrix.mulVec_mulVec, hright] unfold dotProduct simp [Matrix.mulVec_diagonal]
    Causalean.Mathlib.Analysis.anchor_projector_eq_clusterMass · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:376
  • complexEigenvalue_mem_diagonal theorem — Every complex eigenvalue of a real-diagonalized matrix is one of its real diagonal values.
    n :
    ℕ
    z :
    ℂ
    ∃ u, z = D.eigenvalue u
    Proof (Lean source)
    theorem complexEigenvalue_mem_diagonal {n : ℕ} {A : RectMatrix n n} (D : RealDiagonalization A) {z : ℂ} (hz : ComplexMatrixEigenvalue A z) : ∃ u, z = D.eigenvalue u := by classical rcases hz with ⟨v, hv, hev⟩ let w : Fin n → ℂ := fun i => ∑ j, (D.basisInv i j : ℂ) * v j have hw : w ≠ 0 := by intro hw0 apply hv funext i have hrecover : ∑ j, (D.basis i j : ℂ) * w j = v i := by calc ∑ j, (D.basis i j : ℂ) * w j = ∑ j, ∑ r, (D.basis i j : ℂ) * (D.basisInv j r : ℂ) * v r := by simp [w, Finset.mul_sum, mul_assoc] _ = ∑ r, ((D.basis * D.basisInv) i r : ℝ) * v r := by rw [Finset.sum_comm] apply Finset.sum_congr rfl intro r _ simp [Matrix.mul_apply, Finset.sum_mul, mul_assoc] _ = v i := by rw [D.basis_mul_inv] rw [Finset.sum_eq_single i] · simp [Matrix.one_apply] · intro r _ hri simp [Matrix.one_apply, Ne.symm hri] · simp rw [hw0] at hrecover simpa using hrecover.symm obtain ⟨u, hu⟩ : ∃ u, w u ≠ 0 := by by_contra h push_neg at h apply hw funext i exact h i have hsim : D.basisInv * A = diagonal D.eigenvalue * D.basisInv := by calc D.basisInv * A = D.basisInv * (D.basis * diagonal D.eigenvalue * D.basisInv) := congrArg (fun M => D.basisInv * M) D.reconstruct _ = diagonal D.eigenvalue * D.basisInv := by calc _ = (D.basisInv * D.basis) * (diagonal D.eigenvalue * D.basisInv) := by simp only [Matrix.mul_assoc] _ = _ := by rw [D.inv_mul_basis, Matrix.one_mul] have hcoord (j : Fin n) : (D.eigenvalue u : ℂ) * (D.basisInv u j : ℂ) = ∑ r, (D.basisInv u r : ℂ) * (A r j : ℂ) := by have h := congrArg (fun M : RectMatrix n n => M u j) hsim simpa [Matrix.mul_apply, Matrix.diagonal_apply] using congrArg ((↑) : ℝ → ℂ) h.symm have hew : (D.eigenvalue u : ℂ) * w u = z * w u := by calc (D.eigenvalue u : ℂ) * w u = ∑ j, ((D.eigenvalue u : ℂ) * (D.basisInv u j : ℂ)) * v j := by simp [w, Finset.mul_sum, mul_assoc] _ = ∑ j, (∑ r, (D.basisInv u r : ℂ) * (A r j : ℂ)) * v j := by apply Finset.sum_congr rfl intro j _ rw [hcoord] _ = ∑ r, (D.basisInv u r : ℂ) * (∑ j, (A r j : ℂ) * v j) := by simp_rw [Finset.sum_mul, Finset.mul_sum] rw [Finset.sum_comm] apply Finset.sum_congr rfl intro r _ apply Finset.sum_congr rfl intro j _ ring _ = ∑ r, (D.basisInv u r : ℂ) * (z * v r) := by apply Finset.sum_congr rfl intro r _ rw [hev] _ = z * w u := by simp only [w, Finset.mul_sum] apply Finset.sum_congr rfl intro r _ ring exact ⟨u, (mul_right_cancel₀ hu hew.symm)⟩
    Causalean.Mathlib.Analysis.complexEigenvalue_mem_diagonal · Causalean/Mathlib/Analysis/SpectralEnumeration.lean:462
Two­By­Two­Spectral­Projector 4 core · 9 supporting This module turns the two explicit roots into an algebraic projector onto the upper eigenspace of a real symmetric two-by-two matrix. ★ topProjector_isOrthogonalProjectorOntoTop

Choice-free top spectral projector in dimension two

This module turns the two explicit roots into an algebraic projector onto the upper eigenspace of a real symmetric two-by-two matrix. The formula is independent of any sign or basis choice for an eigenvector and is continuously differentiable on the strict-gap region.

def outerProjector reviewed
Causalean.Mathlib.Analysis

Given a real two-vector, its outer-product matrix has entries vivjv_i v_j; it has rank at most one (exactly one for a nonzero vector) and is the orthogonal projector onto the vector's direction when the vector has unit length.

Definition (Lean source)
v :
Fin 2 → ℝ
outerProjector v :
Matrix (Fin 2) (Fin 2) ℝ
fun i j => v i * v j
Causalean.Mathlib.Analysis.outerProjector · Causalean/Mathlib/Analysis/TwoByTwoSpectralProjector.lean:18
def topProjector reviewed
Causalean.Mathlib.Analysis

Given a real two-by-two matrix, the algebraic upper spectral-projector candidate is its lower-root-shifted matrix divided by the gap between its explicit roots.

Definition (Lean source)
G :
Matrix (Fin 2) (Fin 2) ℝ
topProjector G :
Matrix (Fin 2) (Fin 2) ℝ
(lambda₁ G - lambda₂ G)⁻¹ • (G - lambda₂ G • (1 : Matrix (Fin 2) (Fin 2) ℝ))
Causalean.Mathlib.Analysis.topProjector · Causalean/Mathlib/Analysis/TwoByTwoSpectralProjector.lean:22
def IsOrthogonalProjectorOntoTop reviewed
Causalean.Mathlib.Analysis

Given a real two-by-two matrix and a candidate matrix, the property of being the orthogonal projector onto the upper-root eigenspace means that the candidate is symmetric, idempotent, and fixes exactly the upper-root eigenvectors.

Definition (Lean source)
G P :
Matrix (Fin 2) (Fin 2) ℝ
IsOrthogonalProjectorOntoTop G P :
Prop
clause 1
P.IsHermitian
clause 2
P * P = P
clause 3
x :
Fin 2 → ℝ
P.mulVec x = x ↔ G.mulVec x = lambda₁ G • x
Causalean.Mathlib.Analysis.IsOrthogonalProjectorOntoTop · Causalean/Mathlib/Analysis/TwoByTwoSpectralProjector.lean:28
theorem topProjector_isOrthogonalProjectorOntoTop reviewed
Causalean.Mathlib.Analysis

Given a real two-by-two matrix that is symmetric and has distinct explicit roots, its algebraic quotient is the orthogonal projector onto the upper-root eigenspace.

Formal statement
G :
Matrix (Fin 2) (Fin 2) ℝ
hG :
G.IsHermitian
hgap :
Proof (Lean source)
theorem topProjector_isOrthogonalProjectorOntoTop {G : Matrix (Fin 2) (Fin 2) ℝ} (hG : G.IsHermitian) (hgap : G ∈ strictGapSet) : IsOrthogonalProjectorOntoTop G (topProjector G) := by exact ⟨topProjector_isHermitian hG, topProjector_mul_self hG hgap, topProjector_mulVec_eq_iff hgap⟩
Causalean.Mathlib.Analysis.topProjector_isOrthogonalProjectorOntoTop · Causalean/Mathlib/Analysis/TwoByTwoSpectralProjector.lean:102 · uses IsOrthogonalProjectorOntoTop , strictGapSet , topProjector
9 supporting declarations (lemmas, instances)
Weighted­Cauchy­Schwarz 2 core · 2 supporting Mathlib's discrete Cauchy–Schwarz Finset.sum_mul_sq_le_sq_mul_sq is stated for the *unweighted* inner product. ★ weighted_inner_sq_le★ abs_weighted_inner_le

Cauchy–Schwarz against a finite nonnegative weight vector

Mathlib's discrete Cauchy–Schwarz Finset.sum_mul_sq_le_sq_mul_sq is stated for the unweighted inner product. Weighted versions (⟨f, g⟩_w = Σ wᵢ fᵢ gᵢ for a nonnegative weight vector w) get re-derived by hand all over the library, so this module records them once, over an arbitrary finite support.

* weighted_inner_sq_le — squared form (Σ wᵢ fᵢ gᵢ)² ≤ (Σ wᵢ fᵢ²)(Σ wᵢ gᵢ²). * abs_weighted_inner_le — square-root form with an absolute value on the left. * abs_weighted_mean_le_sqrt_weighted_sq — the subprobability-weight (Σ wᵢ ≤ 1) specialization |Σ wᵢ fᵢ| ≤ √(Σ wᵢ fᵢ²), i.e. Jensen for x ↦ x². * weighted_sqrt_le_sqrt_weighted — Jensen for √·: Σ wᵢ √qᵢ ≤ √(Σ wᵢ qᵢ).

All four follow from the unweighted inequality by substituting f ↦ √w · f, g ↦ √w · g and simplifying with Real.sq_sqrt.

lemma weighted_inner_sq_le reviewed
Causalean.Mathlib.Analysis

Weighted Cauchy-Schwarz inequality on a finite support, squared form. Weighting a finite collection of index points by nonnegative weights, the square of the weighted inner product of two real-valued functions is at most the product of their weighted sums of squares.

Formal statement
ι :
Type u_1
shared
s :
w f g :
ι → ℝ
hw :
∀ i ∈ s, 0 ≤ w i
(∑ i ∈ s, w i * (f i * g i)) ^ 2 ≤ (∑ i ∈ s, w i * f i ^ 2) * (∑ i ∈ s, w i * g i ^ 2)
Proof (Lean source)
lemma weighted_inner_sq_le (s : Finset ι) (w f g : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i) : (∑ i ∈ s, w i * (f i * g i)) ^ 2 ≤ (∑ i ∈ s, w i * f i ^ 2) * (∑ i ∈ s, w i * g i ^ 2) := by have hprod : ∀ i ∈ s, sqrt (w i) * f i * (sqrt (w i) * g i) = w i * (f i * g i) := by intro i hi have : sqrt (w i) * sqrt (w i) = w i := Real.mul_self_sqrt (hw i hi) calc sqrt (w i) * f i * (sqrt (w i) * g i) = sqrt (w i) * sqrt (w i) * (f i * g i) := by ring _ = w i * (f i * g i) := by rw [this] have hsq : ∀ (h : ι → ℝ) (i : ι) (_ : i ∈ s), (sqrt (w i) * h i) ^ 2 = w i * h i ^ 2 := by intro h i hi rw [mul_pow, Real.sq_sqrt (hw i hi)] have hsumprod : ∑ i ∈ s, sqrt (w i) * f i * (sqrt (w i) * g i) = ∑ i ∈ s, w i * (f i * g i) := by apply Finset.sum_congr rfl intro i hi exact hprod i hi have hsumsq (h : ι → ℝ) : ∑ i ∈ s, (sqrt (w i) * h i) ^ 2 = ∑ i ∈ s, w i * h i ^ 2 := by apply Finset.sum_congr rfl intro i hi exact hsq h i hi have key := Finset.sum_mul_sq_le_sq_mul_sq s (fun i => sqrt (w i) * f i) (fun i => sqrt (w i) * g i) rw [hsumprod, hsumsq f, hsumsq g] at key exact key
Causalean.Mathlib.Analysis.weighted_inner_sq_le · Causalean/Mathlib/Analysis/WeightedCauchySchwarz.lean:37
lemma abs_weighted_inner_le reviewed
Causalean.Mathlib.Analysis

Weighted Cauchy-Schwarz inequality on a finite support, square-root form. With nonnegative weights, the absolute value of the weighted inner product of two real-valued functions is at most the product of the square roots of their weighted sums of squares.

Formal statement
ι :
Type u_1
shared
s :
w f g :
ι → ℝ
hw :
∀ i ∈ s, 0 ≤ w i
|∑ i ∈ s, w i * (f i * g i)|
≤ sqrt (∑ i ∈ s, w i * f i ^ 2) * sqrt (∑ i ∈ s, w i * g i ^ 2)
Proof (Lean source)
lemma abs_weighted_inner_le (s : Finset ι) (w f g : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i) : |∑ i ∈ s, w i * (f i * g i)| ≤ sqrt (∑ i ∈ s, w i * f i ^ 2) * sqrt (∑ i ∈ s, w i * g i ^ 2) := by have hP : (0 : ℝ) ≤ ∑ i ∈ s, w i * f i ^ 2 := Finset.sum_nonneg fun i hi => mul_nonneg (hw i hi) (sq_nonneg _) have hstep : |∑ i ∈ s, w i * (f i * g i)| ≤ sqrt ((∑ i ∈ s, w i * f i ^ 2) * (∑ i ∈ s, w i * g i ^ 2)) := by rw [← Real.sqrt_sq_eq_abs] exact Real.sqrt_le_sqrt (weighted_inner_sq_le s w f g hw) rwa [Real.sqrt_mul hP] at hstep
Causalean.Mathlib.Analysis.abs_weighted_inner_le · Causalean/Mathlib/Analysis/WeightedCauchySchwarz.lean:71
2 supporting declarations (lemmas, instances)
  • abs_weighted_mean_le_sqrt_weighted_sq lemma — Weighted mean is dominated by the weighted root-mean-square. For weights that are nonnegative and sum to at most one, the absolute value of the weighted average of a real-valued function is at most the square root of the weighted average of its square.
    ι :
    Type u_1
    shared
    s :
    w f :
    ι → ℝ
    hw :
    ∀ i ∈ s, 0 ≤ w i
    c :
    ℝ
    hmass :
    ∑ i ∈ s, w i ≤ c
    |∑ i ∈ s, w i * f i| ≤ sqrt c * sqrt (∑ i ∈ s, w i * f i ^ 2)
    Proof (Lean source)
    lemma abs_weighted_mean_le_sqrt_weighted_sq (s : Finset ι) (w f : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i) (c : ℝ) (hmass : ∑ i ∈ s, w i ≤ c) : |∑ i ∈ s, w i * f i| ≤ sqrt c * sqrt (∑ i ∈ s, w i * f i ^ 2) := by have key := abs_weighted_inner_le s w f (fun _ => 1) hw simp only [mul_one, one_pow] at key have hsqrt : sqrt (∑ i ∈ s, w i) ≤ sqrt c := by have := Real.sqrt_le_sqrt hmass exact this calc _ ≤ sqrt (∑ i ∈ s, w i * f i ^ 2) * sqrt (∑ i ∈ s, w i) := key _ ≤ sqrt (∑ i ∈ s, w i * f i ^ 2) * sqrt c := mul_le_mul_of_nonneg_left hsqrt (Real.sqrt_nonneg _) _ = _ := mul_comm _ _
    Causalean.Mathlib.Analysis.abs_weighted_mean_le_sqrt_weighted_sq · Causalean/Mathlib/Analysis/WeightedCauchySchwarz.lean:86
  • weighted_sqrt_le_sqrt_weighted lemma — Jensen's inequality for the square root. Averaging nonnegative values with weights that are nonnegative and sum to at most one, the weighted average of their square roots is at most the square root of their weighted average.
    ι :
    Type u_1
    shared
    s :
    w q :
    ι → ℝ
    hw :
    ∀ i ∈ s, 0 ≤ w i
    c :
    ℝ
    hmass :
    ∑ i ∈ s, w i ≤ c
    hq :
    ∀ i ∈ s, 0 ≤ q i
    ∑ i ∈ s, w i * sqrt (q i) ≤ sqrt c * sqrt (∑ i ∈ s, w i * q i)
    Proof (Lean source)
    lemma weighted_sqrt_le_sqrt_weighted (s : Finset ι) (w q : ι → ℝ) (hw : ∀ i ∈ s, 0 ≤ w i) (c : ℝ) (hmass : ∑ i ∈ s, w i ≤ c) (hq : ∀ i ∈ s, 0 ≤ q i) : ∑ i ∈ s, w i * sqrt (q i) ≤ sqrt c * sqrt (∑ i ∈ s, w i * q i) := by have key := abs_weighted_mean_le_sqrt_weighted_sq s w (fun i => sqrt (q i)) hw c hmass have hrw : ∀ i ∈ s, w i * sqrt (q i) ^ 2 = w i * q i := by intro i hi; rw [Real.sq_sqrt (hq i hi)] have hsumrw : ∑ i ∈ s, w i * sqrt (q i) ^ 2 = ∑ i ∈ s, w i * q i := by apply Finset.sum_congr rfl intro i hi exact hrw i hi rw [hsumrw] at key exact le_trans (le_abs_self _) key
    Causalean.Mathlib.Analysis.weighted_sqrt_le_sqrt_weighted · Causalean/Mathlib/Analysis/WeightedCauchySchwarz.lean:104