/- Copyright (c) 2026 Michael R. Douglas. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. # Heat Kernel Bilinear Form and Green's Function Defines the heat kernel and Green's function on any DyninMityaginSpace equipped with Laplacian eigenvalues. These are the universal analytic objects that drive the continuum limit construction. ## Main definitions - `HasLaplacianEigenvalues` — typeclass providing eigenvalues μ_m ≥ 0 of -Δ - `heatKernelBilinear` — K_t(f,g) = Σ_m e^{-tμ_m} coeff_m(f) coeff_m(g) - `l2InnerProduct` — ⟨f,g⟩_{L²} = Σ_m coeff_m(f) coeff_m(g) - `greenFunctionBilinear` — G_mass(f,g) = Σ_m coeff_m(f) coeff_m(g) / (μ_m + mass²) ## Key properties - `heatKernelBilinear_tensorProduct` — K_t factors under ⊗ - `heatKernelBilinear_tendsto_l2` — K_t(f,g) → ⟨f,g⟩_{L²} as t → 0⁺ - `greenFunctionBilinear_pos` — G_mass(f,f) > 0 for f ≠ 0 ## Design: mass separated from eigenvalues The eigenvalues are of -Δ alone (nonneg, not strictly positive). Mass enters only through the Green's function. This ensures: - Tensor product correctness: μ_{E₁⊗E₂} = μ_{E₁} + μ_{E₂} (not +2m²) - Heat kernel factorization: K_t factors multiplicatively - Identity at t=0: K_t → L² inner product (not mass-dependent) ## References - Glimm-Jaffe, *Quantum Physics*, §6.1 - Simon, *The P(φ)₂ Euclidean QFT*, Ch. I -/ import Nuclear.NuclearTensorProduct import Mathlib.Analysis.Normed.Group.Tannery import Mathlib.Analysis.Normed.Group.FunctionSeries import Mathlib.Analysis.LocallyConvex.SeparatingDual import Mathlib.Analysis.Normed.Ring.InfiniteSum noncomputable section open scoped BigOperators namespace GaussianField /-! ## Laplacian eigenvalues -/ /-- **Laplacian eigenvalues on a DyninMityaginSpace.** Each DyninMityaginSpace can be equipped with eigenvalues of the Laplacian -Δ associated to its geometry. The eigenvalues are nonneg (the zero mode on the circle has μ₀ = 0). Mass is NOT included — it enters only through the Green's function. The basis `{e_m}` of the DMS is assumed orthonormal w.r.t. the L² inner product, and the eigenvalues satisfy `-Δ e_m = μ_m e_m`. -/ class HasLaplacianEigenvalues (E : Type*) [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [DyninMityaginSpace E] where eigenvalue : ℕ → ℝ eigenvalue_nonneg : ∀ m, 0 ≤ eigenvalue m /-! ## L² inner product -/ variable {E : Type*} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [DyninMityaginSpace E] /-- Helper: the m-th term of the L² inner product series. -/ private def l2Term (f g : E) (m : ℕ) : ℝ := DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g /-- **L² inner product via Schauder coefficients.** `⟨f, g⟩_{L²} = Σ_m coeff_m(f) · coeff_m(g)` This is the Parseval identity for the orthonormal Schauder basis. -/ def l2InnerProduct (f g : E) : ℝ := ∑' m, l2Term f g m /-- Summability of the L² inner product series. -/ theorem l2InnerProduct_summable (f g : E) : Summable (l2Term f g) := by -- Use coeff_decay at exponent 2 for f and g to bound |c_m(f) * c_m(g)| ≤ const/(1+m)^4 obtain ⟨Cf, hCf, sf, hdf⟩ := DyninMityaginSpace.coeff_decay (E := E) 2 obtain ⟨Cg, hCg, sg, hdg⟩ := DyninMityaginSpace.coeff_decay (E := E) 2 set Bf := Cf * (sf.sup DyninMityaginSpace.p) f set Bg := Cg * (sg.sup DyninMityaginSpace.p) g -- Summability of 1/(m+1)^2 have h1sq : Summable (fun m : ℕ => (1 : ℝ) / ((m : ℝ) + 1) ^ 2) := by have := (summable_nat_add_iff 1).mpr (Real.summable_one_div_nat_pow.mpr (by norm_num : 1 < 2)) exact this.congr (fun m => by push_cast; ring_nf) -- Bound: ‖l2Term f g m‖ ≤ Bf * Bg / (1+m)^4 set bound : ℕ → ℝ := fun m => Bf * Bg * (1 / ((m : ℝ) + 1) ^ 2) ^ 2 have hbound_summable : Summable bound := by apply Summable.of_nonneg_of_le (fun m => by positivity : ∀ m, 0 ≤ bound m) · intro m show bound m ≤ Bf * Bg * (1 / ((m : ℝ) + 1) ^ 2) have h1 : (1 : ℝ) / ((m : ℝ) + 1) ^ 2 ≤ 1 := by rw [div_le_one (by positivity)] exact one_le_pow₀ (by linarith [Nat.cast_nonneg' (α := ℝ) m] : (1 : ℝ) ≤ (m : ℝ) + 1) show Bf * Bg * (1 / ((m : ℝ) + 1) ^ 2) ^ 2 ≤ Bf * Bg * (1 / ((m : ℝ) + 1) ^ 2) apply mul_le_mul_of_nonneg_left _ (by positivity) calc (1 / ((m : ℝ) + 1) ^ 2) ^ 2 = (1 / ((m : ℝ) + 1) ^ 2) * (1 / ((m : ℝ) + 1) ^ 2) := sq _ _ ≤ 1 * (1 / ((m : ℝ) + 1) ^ 2) := mul_le_mul_of_nonneg_right h1 (by positivity) _ = 1 / ((m : ℝ) + 1) ^ 2 := one_mul _ · exact h1sq.mul_left (Bf * Bg) exact Summable.of_norm_bounded hbound_summable (fun m => by show ‖l2Term f g m‖ ≤ bound m simp only [l2Term, bound, Real.norm_eq_abs, abs_mul] have hf_bound : |DyninMityaginSpace.coeff m f| ≤ Bf / (1 + (m : ℝ)) ^ 2 := by rw [le_div_iff₀ (by positivity)]; exact hdf f m have hg_bound : |DyninMityaginSpace.coeff m g| ≤ Bg / (1 + (m : ℝ)) ^ 2 := by rw [le_div_iff₀ (by positivity)]; exact hdg g m calc |DyninMityaginSpace.coeff m f| * |DyninMityaginSpace.coeff m g| ≤ (Bf / (1 + (m : ℝ)) ^ 2) * (Bg / (1 + (m : ℝ)) ^ 2) := mul_le_mul hf_bound hg_bound (abs_nonneg _) (by positivity) _ = Bf * Bg * (1 / ((m : ℝ) + 1) ^ 2) ^ 2 := by field_simp; ring) /-! ## Heat kernel bilinear form -/ /-- Helper: the m-th term of the heat kernel series. -/ private def heatKernelTerm [HasLaplacianEigenvalues E] (t : ℝ) (f g : E) (m : ℕ) : ℝ := Real.exp (-t * HasLaplacianEigenvalues.eigenvalue (E := E) m) * DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g /-- **Heat kernel bilinear form.** `K_t(f, g) = Σ_m e^{-tμ_m} · coeff_m(f) · coeff_m(g)` The sum converges absolutely because `coeff_m(f)` and `coeff_m(g)` are rapidly decreasing and `e^{-tμ_m} ≤ 1` for t ≥ 0. -/ def heatKernelBilinear [HasLaplacianEigenvalues E] (t : ℝ) (f g : E) : ℝ := ∑' m, heatKernelTerm (E := E) t f g m /-- Summability of the heat kernel series for t > 0. -/ theorem heatKernelBilinear_summable [HasLaplacianEigenvalues E] (t : ℝ) (ht : 0 < t) (f g : E) : Summable (heatKernelTerm (E := E) t f g) := by -- Bound: |e^{-tμ_m} c_m(f) c_m(g)| ≤ |c_m(f) c_m(g)| since e^{-tμ_m} ∈ [0,1] apply (l2InnerProduct_summable f g).abs.of_norm_bounded_eventually apply Filter.Eventually.of_forall intro m simp only [heatKernelTerm, l2Term, Real.norm_eq_abs] rw [show Real.exp (-t * HasLaplacianEigenvalues.eigenvalue (E := E) m) * DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g = Real.exp (-t * HasLaplacianEigenvalues.eigenvalue (E := E) m) * (DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g) from by ring] rw [abs_mul] apply mul_le_of_le_one_left (abs_nonneg _) rw [abs_of_pos (Real.exp_pos _)] exact Real.exp_le_one_iff.mpr (by nlinarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m]) /-! ## Heat kernel properties -/ /-- **Heat kernel converges to L² inner product as t → 0⁺.** `lim_{t→0⁺} K_t(f,g) = ⟨f,g⟩_{L²}` Proof: dominated convergence. Each term `e^{-tμ_m} → 1` as `t → 0⁺`, and `|e^{-tμ_m} c_m(f) c_m(g)| ≤ |c_m(f) c_m(g)|` which is summable. -/ theorem heatKernelBilinear_tendsto_l2 [HasLaplacianEigenvalues E] (f g : E) : Filter.Tendsto (fun t : ℝ => heatKernelBilinear (E := E) t f g) (nhdsWithin 0 (Set.Ioi 0)) (nhds (l2InnerProduct f g)) := by unfold heatKernelBilinear l2InnerProduct apply tendsto_tsum_of_dominated_convergence (l2InnerProduct_summable f g).abs · -- Pointwise convergence: heatKernelTerm t f g m → l2Term f g m intro m simp only [heatKernelTerm] have hcfg : l2Term f g m = 1 * DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g := by simp [l2Term] rw [hcfg] apply Filter.Tendsto.mul (Filter.Tendsto.mul _ tendsto_const_nhds) tendsto_const_nhds rw [show (1 : ℝ) = Real.exp 0 from Real.exp_zero.symm] apply (Real.continuous_exp.tendsto 0).comp apply tendsto_nhdsWithin_of_tendsto_nhds have hca : ContinuousAt (fun t : ℝ => -t * HasLaplacianEigenvalues.eigenvalue (E := E) m) 0 := by fun_prop simp only [ContinuousAt, neg_zero, zero_mul] at hca exact hca · -- Norm bound: ‖heatKernelTerm t f g m‖ ≤ |l2Term f g m| for t > 0 apply Filter.eventually_of_mem self_mem_nhdsWithin intro t (ht : 0 < t) m simp only [heatKernelTerm, l2Term, Real.norm_eq_abs] rw [show Real.exp (-t * HasLaplacianEigenvalues.eigenvalue (E := E) m) * DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g = Real.exp (-t * HasLaplacianEigenvalues.eigenvalue (E := E) m) * (DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g) from by ring] rw [abs_mul, abs_mul] apply mul_le_of_le_one_left (mul_nonneg (abs_nonneg _) (abs_nonneg _)) rw [abs_of_pos (Real.exp_pos _)] exact Real.exp_le_one_iff.mpr (by nlinarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m]) /-- **Heat kernel is nonneg on the diagonal:** `K_t(f,f) ≥ 0`. -/ theorem heatKernelBilinear_nonneg [HasLaplacianEigenvalues E] (t : ℝ) (f : E) : 0 ≤ heatKernelBilinear (E := E) t f f := by unfold heatKernelBilinear heatKernelTerm apply tsum_nonneg intro m nlinarith [Real.exp_pos (-t * HasLaplacianEigenvalues.eigenvalue (E := E) m), sq_nonneg (DyninMityaginSpace.coeff m f)] /-- **Heat kernel bounded by L² inner product:** `K_t(f,f) ≤ ⟨f,f⟩_{L²}`. Since `e^{-tμ_m} ≤ 1` for t > 0 and μ_m ≥ 0. -/ theorem heatKernelBilinear_le_l2 [HasLaplacianEigenvalues E] (t : ℝ) (ht : 0 < t) (f : E) : heatKernelBilinear (E := E) t f f ≤ l2InnerProduct f f := by unfold heatKernelBilinear l2InnerProduct apply Summable.tsum_le_tsum · intro m unfold heatKernelTerm l2Term have hexp : Real.exp (-t * HasLaplacianEigenvalues.eigenvalue (E := E) m) ≤ 1 := Real.exp_le_one_iff.mpr (by nlinarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m]) nlinarith [sq_nonneg (DyninMityaginSpace.coeff m f), Real.exp_pos (-t * HasLaplacianEigenvalues.eigenvalue (E := E) m)] · exact heatKernelBilinear_summable t ht f f · exact l2InnerProduct_summable f f /-! ## Green's function -/ /-- Helper: the m-th term of the Green's function series. -/ private def greenTerm [HasLaplacianEigenvalues E] (mass : ℝ) (f g : E) (m : ℕ) : ℝ := DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g / (HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2) /-- **Green's function bilinear form.** `G_mass(f, g) = Σ_m coeff_m(f) · coeff_m(g) / (μ_m + mass²)` This is the spectral representation of `(-Δ + mass²)⁻¹`. Equivalently, it is the Laplace transform of the heat kernel: `G_mass(f, g) = ∫₀^∞ e^{-t·mass²} K_t(f, g) dt` The sum converges because `1/(μ_m + mass²) ≤ 1/mass²` is bounded and coefficients are rapidly decreasing. -/ def greenFunctionBilinear [HasLaplacianEigenvalues E] (mass : ℝ) (_hmass : 0 < mass) (f g : E) : ℝ := ∑' m, greenTerm (E := E) mass f g m /-- Summability of the Green's function series. -/ theorem greenFunctionBilinear_summable [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f g : E) : Summable (greenTerm (E := E) mass f g) := by have hmass_sq_pos : (0 : ℝ) < mass ^ 2 := sq_pos_of_pos hmass apply (Summable.mul_left (1 / mass ^ 2) (l2InnerProduct_summable f g).abs).of_norm_bounded_eventually apply Filter.Eventually.of_forall intro m simp only [greenTerm, Real.norm_eq_abs] rw [abs_div, abs_mul] have hden_pos : 0 < HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2 := by linarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m, hmass_sq_pos] rw [abs_of_pos hden_pos] have hmass_le : mass ^ 2 ≤ HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2 := le_add_of_nonneg_left (HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m) calc |DyninMityaginSpace.coeff m f| * |DyninMityaginSpace.coeff m g| / (HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2) ≤ |DyninMityaginSpace.coeff m f| * |DyninMityaginSpace.coeff m g| / mass ^ 2 := div_le_div_of_nonneg_left (mul_nonneg (abs_nonneg _) (abs_nonneg _)) hmass_sq_pos hmass_le _ = 1 / mass ^ 2 * (|DyninMityaginSpace.coeff m f| * |DyninMityaginSpace.coeff m g|) := by ring _ = 1 / mass ^ 2 * |DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g| := by rw [abs_mul] /-- **Green's function equals the Laplace transform of the heat kernel.** Informally: `G_mass(f, g) = ∫₀^∞ e^{-t·mass²} K_t(f, g) dt`. This is obtained by exchanging sum and integral (Fubini-Tonelli), then evaluating `∫₀^∞ e^{-t(μ_m + mass²)} dt = 1/(μ_m + mass²)`. The spectral sum definition is primary; this is a derived identity. -/ theorem greenFunctionBilinear_eq_heatKernel [HasLaplacianEigenvalues E] (mass : ℝ) (_hmass : 0 < mass) (f g : E) (m : ℕ) : greenTerm (E := E) mass f g m = DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m g / (HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2) := by rfl /-- **Green's function is nonneg on the diagonal.** `G_mass(f, f) ≥ 0` for all `f` Each term `coeff_m(f)² / (μ_m + mass²) ≥ 0` since the numerator is a square and the denominator is positive (`μ_m ≥ 0`, `mass² > 0`). The tsum of nonneg terms is nonneg. -/ theorem greenFunctionBilinear_nonneg [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f : E) : 0 ≤ greenFunctionBilinear mass hmass f f := by apply tsum_nonneg intro m apply div_nonneg (mul_self_nonneg _) linarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m, sq_pos_of_pos hmass] /-- **Green's function is positive definite.** `G_mass(f, f) > 0` for nonzero `f` Since `coeff_m(f)² / (μ_m + mass²) ≥ 0` for all m, and at least one coefficient is nonzero (by the expansion property of DMS), so the sum is strictly positive. -/ theorem greenFunctionBilinear_pos [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f : E) (hf : f ≠ 0) : 0 < greenFunctionBilinear mass hmass f f := by -- Step 1: f ≠ 0 implies some coefficient is nonzero have hcoeff : ∃ m, DyninMityaginSpace.coeff m f ≠ 0 := by by_contra hall push Not at hall haveI : LocallyConvexSpace ℝ E := DyninMityaginSpace.h_with.toLocallyConvexSpace obtain ⟨φ, hφ⟩ := SeparatingDual.exists_ne_zero (R := ℝ) hf exact hφ (by rw [DyninMityaginSpace.expansion φ f]; simp [hall]) obtain ⟨m₀, hm₀⟩ := hcoeff -- Step 2: Use tsum_pos with the witness m₀ unfold greenFunctionBilinear exact (greenFunctionBilinear_summable mass hmass f f).tsum_pos (fun m => div_nonneg (mul_self_nonneg _) (by linarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m, sq_pos_of_pos hmass])) m₀ (div_pos (mul_self_pos.mpr hm₀) (by linarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m₀, sq_pos_of_pos hmass])) /-- **Green's function is bounded by `1/mass² · ⟨f,f⟩_{L²}`.** Since `1/(μ_m + mass²) ≤ 1/mass²`, we have `G_mass(f,f) ≤ (1/mass²) · ⟨f,f⟩_{L²}`. -/ theorem greenFunctionBilinear_le [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f : E) : greenFunctionBilinear mass hmass f f ≤ (1 / mass ^ 2) * l2InnerProduct f f := by unfold greenFunctionBilinear l2InnerProduct rw [← tsum_mul_left] apply Summable.tsum_le_tsum · intro m unfold greenTerm l2Term have hmass_sq_pos : (0 : ℝ) < mass ^ 2 := sq_pos_of_pos hmass have hden_pos : 0 < HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2 := by linarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m] have hmass_le : mass ^ 2 ≤ HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2 := le_add_of_nonneg_left (HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m) have hsq : 0 ≤ DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m f := mul_self_nonneg _ calc DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m f / (HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2) ≤ DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m f / mass ^ 2 := div_le_div_of_nonneg_left hsq hmass_sq_pos hmass_le _ = 1 / mass ^ 2 * (DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m f) := by ring · exact greenFunctionBilinear_summable mass hmass f f · exact Summable.mul_left _ (l2InnerProduct_summable f f) /-! ## Continuity of Green's function on diagonal -/ /-- **Continuity of `f ↦ G_mass(f, f)` on the diagonal.** The Green's function `G_mass(f, f) = Σ_m (coeff_m f)² / (μ_m + mass²)` is continuous as a function of `f`. The proof shows that the partial sums converge locally uniformly: - `coeff_decay` at `k = 1` gives `|coeff_m f| ≤ C · q(f) / (1+m)` for a continuous seminorm `q`. - Each term satisfies `|term_m(f)| ≤ C² · q(f)² / ((1+m)² · mass²)`. - On the seminorm ball `{f | q(f) < R}`, this is bounded by the `m`-independent summable sequence `C² R² / ((1+m)² · mass²)`. - By the Weierstrass M-test (`tendstoUniformlyOn_tsum`), partial sums converge uniformly on each such ball. - Since these balls cover `E`, convergence is locally uniform (`tendstoLocallyUniformly_of_forall_exists_nhds`). - A locally uniform limit of continuous functions is continuous (`TendstoLocallyUniformly.continuous`). -/ theorem greenFunctionBilinear_continuous_diag [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) : Continuous (fun f : E => greenFunctionBilinear mass hmass f f) := by -- Step 0: Setup — get coeff_decay bound and continuous seminorm obtain ⟨C, hC, s, hbound⟩ := DyninMityaginSpace.coeff_decay (E := E) 1 set q : Seminorm ℝ E := s.sup DyninMityaginSpace.p with hq_def have hq_cont : Continuous q := by -- sup of continuous seminorms is continuous: sup ≤ sum, and sum is continuous refine Seminorm.continuous_of_le ?_ (Seminorm.finset_sup_le_sum _ _) exact Seminorm.continuous_finsetSum fun i _ => DyninMityaginSpace.h_with.continuous_seminorm i have hmass_sq_pos : (0 : ℝ) < mass ^ 2 := sq_pos_of_pos hmass -- Summability of 1/(1+m)^2 have h1sq : Summable (fun m : ℕ => (1 : ℝ) / ((m : ℝ) + 1) ^ 2) := by have := (summable_nat_add_iff 1).mpr (Real.summable_one_div_nat_pow.mpr (by norm_num : 1 < 2)) exact this.congr (fun m => by push_cast; ring_nf) -- Step 1: Show locally uniform convergence of partial sums apply TendstoLocallyUniformly.continuous (F := fun (t : Finset ℕ) (f : E) => ∑ m ∈ t, greenTerm (E := E) mass f f m) · -- Locally uniform convergence apply tendstoLocallyUniformly_of_forall_exists_nhds intro f₀ set R := q f₀ + 1 with hR_def have hR_pos : (0 : ℝ) < R := by positivity -- The neighborhood: {f | q(f) < R} refine ⟨{f : E | q f < R}, ?_, ?_⟩ · -- {f | q(f) < R} ∈ nhds f₀ exact hq_cont.isOpen_preimage _ isOpen_Iio |>.mem_nhds (by linarith : q f₀ < R) · -- TendstoUniformlyOn on this set set bound := fun m : ℕ => C ^ 2 * R ^ 2 / (mass ^ 2) * (1 / ((m : ℝ) + 1) ^ 2) apply tendstoUniformlyOn_tsum (u := bound) · -- Summability of the bound exact (h1sq.mul_left (C ^ 2 * R ^ 2 / mass ^ 2)) · -- Pointwise bound: ‖greenTerm mass f f m‖ ≤ bound m for f in the neighborhood intro m f (hf : q f < R) show ‖greenTerm (E := E) mass f f m‖ ≤ bound m simp only [greenTerm, Real.norm_eq_abs] -- The term is nonneg (square over positive), so abs = value have hden_pos : 0 < HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2 := by linarith [HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m] rw [abs_of_nonneg (div_nonneg (mul_self_nonneg _) (le_of_lt hden_pos))] -- Bound: (coeff m f)² / denom ≤ (coeff m f)² / mass² have hcoeff_bound : |DyninMityaginSpace.coeff m f| ≤ C * q f / (1 + (m : ℝ)) := by have h1m : (0 : ℝ) < 1 + (m : ℝ) := by positivity rw [le_div_iff₀ h1m] have := hbound f m; simp only [pow_one] at this; exact this calc DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m f / (HasLaplacianEigenvalues.eigenvalue (E := E) m + mass ^ 2) ≤ DyninMityaginSpace.coeff m f * DyninMityaginSpace.coeff m f / mass ^ 2 := by apply div_le_div_of_nonneg_left (mul_self_nonneg _) hmass_sq_pos exact le_add_of_nonneg_left (HasLaplacianEigenvalues.eigenvalue_nonneg (E := E) m) _ = |DyninMityaginSpace.coeff m f| ^ 2 / mass ^ 2 := by rw [sq_abs]; ring_nf _ ≤ (C * q f / (1 + (m : ℝ))) ^ 2 / mass ^ 2 := by apply div_le_div_of_nonneg_right _ (le_of_lt hmass_sq_pos) exact pow_le_pow_left₀ (abs_nonneg _) hcoeff_bound 2 _ ≤ (C * R / (1 + (m : ℝ))) ^ 2 / mass ^ 2 := by apply div_le_div_of_nonneg_right _ (le_of_lt hmass_sq_pos) exact pow_le_pow_left₀ (by positivity) (div_le_div_of_nonneg_right (mul_le_mul_of_nonneg_left (le_of_lt hf) (le_of_lt hC)) (by positivity : (0 : ℝ) ≤ 1 + (m : ℝ))) 2 _ = bound m := by simp only [bound]; field_simp; ring · -- Step 2: Partial sums are continuous (they are finite sums of continuous functions) apply Filter.Frequently.of_forall intro t apply continuous_finsetSum intro m _ show Continuous (fun f : E => greenTerm (E := E) mass f f m) simp only [greenTerm] apply Continuous.div_const exact Continuous.mul (DyninMityaginSpace.coeff m).continuous (DyninMityaginSpace.coeff m).continuous /-! ## Bilinearity of Green's function -/ /-- **Green's function is symmetric.** `G_mass(f, g) = G_mass(g, f)` -/ theorem greenFunctionBilinear_symm [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f g : E) : greenFunctionBilinear mass hmass f g = greenFunctionBilinear mass hmass g f := by unfold greenFunctionBilinear greenTerm congr 1; ext m; ring /-- **Green's function is additive in the first argument.** -/ theorem greenFunctionBilinear_add_left [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f₁ f₂ g : E) : greenFunctionBilinear mass hmass (f₁ + f₂) g = greenFunctionBilinear mass hmass f₁ g + greenFunctionBilinear mass hmass f₂ g := by unfold greenFunctionBilinear rw [← Summable.tsum_add (greenFunctionBilinear_summable mass hmass f₁ g) (greenFunctionBilinear_summable mass hmass f₂ g)] congr 1; ext m simp only [greenTerm, map_add]; ring /-- **Green's function is ℝ-homogeneous in the first argument.** -/ theorem greenFunctionBilinear_smul_left [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (c : ℝ) (f g : E) : greenFunctionBilinear mass hmass (c • f) g = c * greenFunctionBilinear mass hmass f g := by unfold greenFunctionBilinear rw [← tsum_mul_left] congr 1; ext m simp only [greenTerm, map_smul, smul_eq_mul]; ring /-- **Green's function is additive in the second argument.** -/ theorem greenFunctionBilinear_add_right [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f g₁ g₂ : E) : greenFunctionBilinear mass hmass f (g₁ + g₂) = greenFunctionBilinear mass hmass f g₁ + greenFunctionBilinear mass hmass f g₂ := by rw [greenFunctionBilinear_symm, greenFunctionBilinear_add_left, greenFunctionBilinear_symm mass hmass g₁, greenFunctionBilinear_symm mass hmass g₂] /-- **Green's function is ℝ-homogeneous in the second argument.** -/ theorem greenFunctionBilinear_smul_right [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f : E) (c : ℝ) (g : E) : greenFunctionBilinear mass hmass f (c • g) = c * greenFunctionBilinear mass hmass f g := by rw [greenFunctionBilinear_symm, greenFunctionBilinear_smul_left, greenFunctionBilinear_symm] /-- **Green's function negation in first argument.** -/ theorem greenFunctionBilinear_neg_left [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f g : E) : greenFunctionBilinear mass hmass (-f) g = -greenFunctionBilinear mass hmass f g := by rw [show -f = (-1 : ℝ) • f from (neg_one_smul ℝ f).symm, greenFunctionBilinear_smul_left]; ring /-- **Green's function subtraction in first argument.** -/ theorem greenFunctionBilinear_sub_left [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (f₁ f₂ g : E) : greenFunctionBilinear mass hmass (f₁ - f₂) g = greenFunctionBilinear mass hmass f₁ g - greenFunctionBilinear mass hmass f₂ g := by rw [sub_eq_add_neg, greenFunctionBilinear_add_left, greenFunctionBilinear_neg_left, sub_eq_add_neg] /-- **Green's function at zero.** -/ theorem greenFunctionBilinear_zero_left [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (g : E) : greenFunctionBilinear mass hmass 0 g = 0 := by have := greenFunctionBilinear_smul_left mass hmass (0 : ℝ) (0 : E) g simp at this; exact this /-- **Green's function distributes over finite sums in the first argument.** -/ theorem greenFunctionBilinear_finset_sum_left {ι : Type*} [DecidableEq ι] [HasLaplacianEigenvalues E] (mass : ℝ) (hmass : 0 < mass) (s : Finset ι) (a : ι → ℝ) (f : ι → E) (g : E) : greenFunctionBilinear mass hmass (∑ i ∈ s, a i • f i) g = ∑ i ∈ s, a i * greenFunctionBilinear mass hmass (f i) g := by induction s using Finset.induction with | empty => simp [greenFunctionBilinear_zero_left] | @insert a s ha ih => rw [Finset.sum_insert ha, greenFunctionBilinear_add_left, greenFunctionBilinear_smul_left, ih, Finset.sum_insert ha] /-- **Green's function distributes over finite sums in both arguments.** -/ theorem greenFunctionBilinear_finset_sum [HasLaplacianEigenvalues E] {ι₁ ι₂ : Type*} [DecidableEq ι₁] [DecidableEq ι₂] (mass : ℝ) (hmass : 0 < mass) (s₁ : Finset ι₁) (s₂ : Finset ι₂) (a : ι₁ → ℝ) (b : ι₂ → ℝ) (f : ι₁ → E) (g : ι₂ → E) : greenFunctionBilinear mass hmass (∑ i ∈ s₁, a i • f i) (∑ j ∈ s₂, b j • g j) = ∑ i ∈ s₁, ∑ j ∈ s₂, a i * b j * greenFunctionBilinear mass hmass (f i) (g j) := by rw [greenFunctionBilinear_finset_sum_left] congr 1; ext i rw [greenFunctionBilinear_symm, greenFunctionBilinear_finset_sum_left] rw [Finset.mul_sum] congr 1; ext j rw [greenFunctionBilinear_symm]; ring /-! ## Tensor product eigenvalues -/ variable {E₁ : Type*} [AddCommGroup E₁] [Module ℝ E₁] [TopologicalSpace E₁] [IsTopologicalAddGroup E₁] [ContinuousSMul ℝ E₁] [DyninMityaginSpace E₁] {E₂ : Type*} [AddCommGroup E₂] [Module ℝ E₂] [TopologicalSpace E₂] [IsTopologicalAddGroup E₂] [ContinuousSMul ℝ E₂] [DyninMityaginSpace E₂] /-- **Tensor product Laplacian eigenvalues are sums.** For `E₁ ⊗̂ E₂`, the eigenvalue at Cantor-paired index `m = pair(n₁, n₂)` is `μ₁(n₁) + μ₂(n₂)`, corresponding to `-Δ_{E₁} ⊗ I + I ⊗ (-Δ_{E₂})`. -/ instance tensorProductHasLaplacianEigenvalues [HasLaplacianEigenvalues E₁] [HasLaplacianEigenvalues E₂] : HasLaplacianEigenvalues (NuclearTensorProduct E₁ E₂) where eigenvalue m := let p := Nat.unpair m HasLaplacianEigenvalues.eigenvalue (E := E₁) p.1 + HasLaplacianEigenvalues.eigenvalue (E := E₂) p.2 eigenvalue_nonneg m := add_nonneg (HasLaplacianEigenvalues.eigenvalue_nonneg (Nat.unpair m).1) (HasLaplacianEigenvalues.eigenvalue_nonneg (Nat.unpair m).2) /-! ## Heat kernel factorization -/ /-- Summability of the heat kernel series for `0 ≤ t` (extending `heatKernelBilinear_summable` to include `t = 0`). -/ private theorem heatKernelTerm_summable_nonneg [HasLaplacianEigenvalues E] (t : ℝ) (ht : 0 ≤ t) (f g : E) : Summable (heatKernelTerm (E := E) t f g) := by rcases eq_or_lt_of_le ht with rfl | hpos · -- t = 0: heatKernelTerm 0 f g m = 1 * c_f(m) * c_g(m) = l2Term f g m exact (l2InnerProduct_summable f g).congr (fun m => by simp only [heatKernelTerm, l2Term, neg_zero, zero_mul, Real.exp_zero, one_mul]) · exact heatKernelBilinear_summable t hpos f g /-- The m-th heat kernel term for the tensor product factors as a product of individual terms. -/ private theorem heatKernelTerm_tensorProduct [HasLaplacianEigenvalues E₁] [HasLaplacianEigenvalues E₂] (t : ℝ) (f₁ g₁ : E₁) (f₂ g₂ : E₂) (m : ℕ) : heatKernelTerm (E := NuclearTensorProduct E₁ E₂) t (NuclearTensorProduct.pure f₁ f₂) (NuclearTensorProduct.pure g₁ g₂) m = heatKernelTerm (E := E₁) t f₁ g₁ (Nat.unpair m).1 * heatKernelTerm (E := E₂) t f₂ g₂ (Nat.unpair m).2 := by set i := (Nat.unpair m).1 set j := (Nat.unpair m).2 set μ₁ := HasLaplacianEigenvalues.eigenvalue (E := E₁) i set μ₂ := HasLaplacianEigenvalues.eigenvalue (E := E₂) j set c₁f := DyninMityaginSpace.coeff i f₁ set c₁g := DyninMityaginSpace.coeff i g₁ set c₂f := DyninMityaginSpace.coeff j f₂ set c₂g := DyninMityaginSpace.coeff j g₂ -- LHS: heatKernelTerm for NTP unfolds to: -- exp(-t * (μ₁ + μ₂)) * coeff_NTP(m, pure f₁ f₂) * coeff_NTP(m, pure g₁ g₂) -- The NTP eigenvalue is μ₁ + μ₂ (from tensorProductHasLaplacianEigenvalues). -- The NTP coeff is .val access (from NTP.dyninMityaginSpace = rapidDecay_dyninMityaginSpace, -- where coeff := coeffCLM, and coeffCLM m x = x.val m). -- pure_val says (pure f₁ f₂).val m = c₁f * c₂f (and similarly for g). -- RHS: (exp(-t*μ₁) * c₁f * c₁g) * (exp(-t*μ₂) * c₂f * c₂g) -- The key algebraic step: exp(-t*(μ₁+μ₂)) = exp(-t*μ₁) * exp(-t*μ₂) have h_eq : heatKernelTerm (E := NuclearTensorProduct E₁ E₂) t (NuclearTensorProduct.pure f₁ f₂) (NuclearTensorProduct.pure g₁ g₂) m = Real.exp (-t * (μ₁ + μ₂)) * (c₁f * c₂f) * (c₁g * c₂g) := by simp only [heatKernelTerm] rfl rw [h_eq] simp only [heatKernelTerm] rw [show -t * (μ₁ + μ₂) = (-t * μ₁) + (-t * μ₂) from by ring, Real.exp_add] ring /-- Norm-summability of heat kernel terms for `0 ≤ t`. -/ private theorem heatKernelTerm_summable_norm [HasLaplacianEigenvalues E] (t : ℝ) (ht : 0 ≤ t) (f g : E) : Summable (fun m => ‖heatKernelTerm (E := E) t f g m‖) := (heatKernelTerm_summable_nonneg t ht f g).abs.congr (fun _ => (Real.norm_eq_abs _).symm) /-- **Heat kernel is multiplicative under tensor product.** `K_t^{E₁⊗E₂}(f₁⊗f₂, g₁⊗g₂) = K_t^{E₁}(f₁,g₁) · K_t^{E₂}(f₂,g₂)` This follows from: - `e^{-t(μ₁+μ₂)} = e^{-tμ₁} · e^{-tμ₂}` - `coeff_{pair(n₁,n₂)}(f₁⊗f₂) = coeff_{n₁}(f₁) · coeff_{n₂}(f₂)` - Fubini (absolute convergence of double series) This is THE KEY THEOREM that makes the 1D → 2D construction work. -/ theorem heatKernelBilinear_tensorProduct [HasLaplacianEigenvalues E₁] [HasLaplacianEigenvalues E₂] (t : ℝ) (f₁ g₁ : E₁) (f₂ g₂ : E₂) : heatKernelBilinear (E := NuclearTensorProduct E₁ E₂) t (NuclearTensorProduct.pure f₁ f₂) (NuclearTensorProduct.pure g₁ g₂) = heatKernelBilinear (E := E₁) t f₁ g₁ * heatKernelBilinear (E := E₂) t f₂ g₂ := by -- Abbreviations set a := heatKernelTerm (E := E₁) t f₁ g₁ set b := heatKernelTerm (E := E₂) t f₂ g₂ unfold heatKernelBilinear -- Step 1: Rewrite each term using the factorization conv_lhs => arg 1; ext m; rw [heatKernelTerm_tensorProduct t f₁ g₁ f₂ g₂ m] -- Step 2: Reindex from ℕ to ℕ × ℕ via Cantor pairing -- Nat.pairEquiv_symm_apply : ⇑Nat.pairEquiv.symm = Nat.unpair simp_rw [show Nat.unpair = ⇑Nat.pairEquiv.symm from Nat.pairEquiv_symm_apply.symm] rw [Nat.pairEquiv.symm.tsum_eq (fun p : ℕ × ℕ => a p.1 * b p.2)] -- Step 3: Factor the double sum ∑' (i,j), a_i * b_j = (∑' i, a_i) * (∑' j, b_j) -- For 0 ≤ t, both factors are norm-summable. -- For t < 0, we case-split on summability and handle each case. by_cases ht : 0 ≤ t · exact (tsum_mul_tsum_of_summable_norm (heatKernelTerm_summable_norm t ht f₁ g₁) (heatKernelTerm_summable_norm t ht f₂ g₂)).symm · -- t < 0: case split on summability of each factor push Not at ht by_cases h1 : Summable a <;> by_cases h2 : Summable b · -- Both summable have h1n : Summable (fun m => ‖a m‖) := h1.abs.congr (fun m => (Real.norm_eq_abs _).symm) have h2n : Summable (fun m => ‖b m‖) := h2.abs.congr (fun m => (Real.norm_eq_abs _).symm) exact (h1.tsum_mul_tsum h2 (summable_mul_of_summable_norm h1n h2n)).symm · -- a summable, b not: RHS = tsum_a * 0 = 0 rw [tsum_eq_zero_of_not_summable h2, mul_zero] -- LHS: product series not summable (or identically zero), so tsum = 0 by_cases ha : ∀ i, a i = 0 · -- All a_i = 0 → product terms all 0 → tsum = 0 simp only [show ∀ p : ℕ × ℕ, a p.1 * b p.2 = 0 from fun p => by rw [ha p.1, zero_mul], tsum_zero] · -- ∃ nonzero a_{i₀} → product summable would imply b summable → contradiction push Not at ha; obtain ⟨i₀, hi₀⟩ := ha exact tsum_eq_zero_of_not_summable (fun hprod => h2 ((summable_mul_left_iff hi₀).mp (hprod.prod_factor i₀))) · -- a not summable, b summable: RHS = 0 * tsum_b = 0 rw [tsum_eq_zero_of_not_summable h1, zero_mul] by_cases hb : ∀ j, b j = 0 · simp only [show ∀ p : ℕ × ℕ, a p.1 * b p.2 = 0 from fun p => by rw [hb p.2, mul_zero], tsum_zero] · push Not at hb; obtain ⟨j₀, hj₀⟩ := hb apply tsum_eq_zero_of_not_summable intro hprod -- Fix second index j₀: use prod_symm then prod_factor -- prod_symm swaps (i,j) ↦ (j,i), then prod_factor fixes first to j₀ exact h1 ((summable_mul_right_iff hj₀).mp ((hprod.prod_symm.prod_factor j₀).congr (fun _ => rfl))) · -- Neither summable: RHS = 0 * 0 = 0 rw [tsum_eq_zero_of_not_summable h1, zero_mul] by_cases hb : ∀ j, b j = 0 · simp only [show ∀ p : ℕ × ℕ, a p.1 * b p.2 = 0 from fun p => by rw [hb p.2, mul_zero], tsum_zero] · push Not at hb; obtain ⟨j₀, hj₀⟩ := hb apply tsum_eq_zero_of_not_summable intro hprod exact h1 ((summable_mul_right_iff hj₀).mp ((hprod.prod_symm.prod_factor j₀).congr (fun _ => rfl))) end GaussianField