/- Copyright (c) 2026 Michael R. Douglas. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. # IsGaussian Instance We show that the Gaussian measure constructed by this library satisfies Mathlib's `ProbabilityTheory.IsGaussian` typeclass. ## Main results - `weakDual_clm_eq_eval`: Every continuous linear functional on `WeakDual ℝ E` is evaluation at some `f ∈ E`. This is a standard fact: the continuous dual of the weak-* topology is the original space. - `measure_isGaussian`: `IsGaussian (measure T)` for any CLM `T : E →L[ℝ] H`. ## The bridging argument Mathlib's `IsGaussian μ` requires that `μ.map L` is a real Gaussian for every `L : StrongDual ℝ (Configuration E)`, i.e., every `L : (WeakDual ℝ E) →L[ℝ] ℝ`. Since `Configuration E = WeakDual ℝ E` carries the weak-* (initial) topology, every such `L` is evaluation at some `f ∈ E`: 1. Continuity of `L` w.r.t. the initial topology means `ker L` contains the intersection of finitely many evaluation kernels. 2. By linear algebra (`mem_span_of_iInf_ker_le_ker`), `L` is a finite linear combination of evaluations. 3. By linearity, `L = ev(∑ cᵢ fᵢ)` for `f = ∑ cᵢ fᵢ`. Our existing `pairing_is_gaussian` then immediately gives the result. -/ import GaussianField.Properties import Mathlib.Probability.Distributions.Gaussian.Basic import Mathlib.Topology.Algebra.Module.Spaces.WeakDual import Mathlib.LinearAlgebra.Dual.Lemmas noncomputable section namespace GaussianField open MeasureTheory ProbabilityTheory TopologicalSpace Filter Set Topology open scoped NNReal variable {E : Type*} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [DyninMityaginSpace E] omit [IsTopologicalAddGroup E] [ContinuousSMul ℝ E] [DyninMityaginSpace E] in /-- Every continuous linear functional on `WeakDual ℝ E` is evaluation at some `f ∈ E`. This is the standard fact that the continuous dual of the weak-* topology on E' is canonically isomorphic to E itself. -/ lemma weakDual_clm_eq_eval (L : (WeakDual ℝ E) →L[ℝ] ℝ) : ∃ f : E, ∀ ω : WeakDual ℝ E, L ω = ω f := by -- The evaluation linear map: ev(f)(ω) = ω(f) let ev : E → ((WeakDual ℝ E) →ₗ[ℝ] ℝ) := (topDualPairing ℝ E).flip -- The embedding φ(ω)(f) = ω(f) from WeakDual into E → ℝ (product space) let φ : WeakDual ℝ E → (E → ℝ) := fun ω f => (topDualPairing ℝ E) ω f -- φ is inducing (the WeakDual topology is defined as the induced topology) have h_ind : IsInducing φ := ⟨rfl⟩ -- Step 1: Extract a finite set of test functions from continuity of L -- L⁻¹'(Ioo (-1) 1) is a neighborhood of 0 in the weak-* topology have h_nhd : L ⁻¹' Ioo (-1 : ℝ) 1 ∈ 𝓝 (0 : WeakDual ℝ E) := by apply L.continuous.continuousAt.preimage_mem_nhds simp only [map_zero] exact Ioo_mem_nhds (by norm_num) (by norm_num) -- Rewrite using the inducing characterization: nhds = comap φ (nhds (φ 0)) rw [h_ind.nhds_eq_comap, mem_comap] at h_nhd obtain ⟨V, hV_nhd, hV_sub⟩ := h_nhd -- φ(0) = 0 (since ω ↦ ω(f) is linear, applied to 0 gives 0) have hφ0 : φ 0 = 0 := by funext f show (topDualPairing ℝ E) 0 f = 0 rw [map_zero]; rfl rw [hφ0, nhds_pi] at hV_nhd -- Extract finite set I and neighborhoods t_f from the pi-filter membership obtain ⟨I, t, ht_nhd, hIt_sub⟩ := mem_pi'.mp hV_nhd -- Step 2: Show kernel containment via scaling argument -- If ω(f) = 0 for all f ∈ I, then L(ω) = 0 have h_ker : ∀ ω : WeakDual ℝ E, (∀ f ∈ I, ω f = 0) → L ω = 0 := by intro ω hω by_contra hne have hpos : 0 < |L ω| := abs_pos.mpr hne obtain ⟨n, hn⟩ := exists_nat_gt |L ω|⁻¹ -- n • ω has (n • ω) f = n * ω f = n * 0 = 0 ∈ t_f have h_mem : φ (n • ω) ∈ (I : Set E).pi t := by intro f hf -- φ(n • ω)(f) = (n • ω) f = n • ω(f) = n • 0 = 0 have h0 : φ (n • ω) f = 0 := by show (n • ω) f = 0 show n • (ω f) = 0 rw [hω f hf, smul_zero] rw [h0]; exact mem_of_mem_nhds (by simpa using ht_nhd f) have h_in := hV_sub (hIt_sub h_mem) simp only [mem_preimage, mem_Ioo] at h_in -- L(n • ω) = n * L(ω) have h_Lnω : L (n • ω) = (n : ℝ) * L ω := by rw [← Nat.cast_smul_eq_nsmul ℝ n ω, L.map_smul, smul_eq_mul] rw [h_Lnω] at h_in -- From |L ω|⁻¹ < n and |L ω| > 0, get 1 < n * |L ω| have h1 : 1 < (n : ℝ) * |L ω| := by have := mul_lt_mul_of_pos_right hn hpos simp [inv_mul_cancel₀ (ne_of_gt hpos)] at this linarith -- But -1 < n * L ω < 1, so |n * L ω| < 1 -- We have -1 < n * L ω < 1 and 1 < n * |L ω|, contradiction by_cases h : 0 ≤ L ω · rw [abs_of_nonneg h] at h1; linarith · push Not at h; rw [abs_of_neg h] at h1; linarith -- Step 3: Reformulate as iInf of kernels ≤ kernel of L have h_iInf : ⨅ i : I, LinearMap.ker (ev ↑i) ≤ LinearMap.ker L.toLinearMap := by intro ω hω rw [LinearMap.mem_ker] apply h_ker ω intro f hf rw [Submodule.mem_iInf] at hω exact LinearMap.mem_ker.mp (hω ⟨f, hf⟩) -- Step 4: By linear algebra, L is a linear combination of evaluations have h_span := mem_span_of_iInf_ker_le_ker h_iInf obtain ⟨c, hc⟩ := (Submodule.mem_span_range_iff_exists_fun ℝ).mp h_span -- Step 5: Construct the witness f = ∑ cᵢ • fᵢ refine ⟨∑ i : I, c i • (↑i : E), fun ω => ?_⟩ -- L(ω) = ∑ cᵢ * ev(fᵢ)(ω) = ∑ cᵢ * ω(fᵢ) = ω(∑ cᵢ • fᵢ) -- hc : ∑ i, c i • ev ↑i = ↑L (i.e., L.toLinearMap) -- Goal: L ω = ω (∑ i, c i • ↑i) have h_eq : L.toLinearMap ω = ∑ i : I, c i * (ev ↑i) ω := by have := LinearMap.congr_fun hc ω simp only [LinearMap.coe_sum, Finset.sum_apply, LinearMap.smul_apply, smul_eq_mul] at this linarith show L.toLinearMap ω = ω (∑ i : I, c i • (↑i : E)) rw [h_eq, map_sum] congr 1; ext ⟨i, hi⟩ -- Goal: c ⟨i, hi⟩ * (ev i) ω = ω (c ⟨i, hi⟩ • i) -- ev i ω = (topDualPairing ℝ E).flip i ω = ω i have hev : (ev i) ω = ω i := rfl rw [hev, ← smul_eq_mul, map_smul] variable {H : Type*} [NormedAddCommGroup H] [InnerProductSpace ℝ H] [CompleteSpace H] [SeparableSpace H] /-- The measure constructed from `T` is Gaussian in the Mathlib sense: its pushforward by every continuous linear functional is a real Gaussian. -/ instance measure_isGaussian (T : E →L[ℝ] H) : ProbabilityTheory.IsGaussian (measure T) where map_eq_gaussianReal L := by obtain ⟨f, hf⟩ := weakDual_clm_eq_eval L have h_eq : ⇑L = (fun ω : Configuration E => ω f) := funext hf -- Rewrite map, integral, variance using L = ev_f simp_rw [show ∀ ω : Configuration E, L ω = ω f from hf, h_eq] -- Apply pairing_is_gaussian and centered identity rw [pairing_is_gaussian T f, measure_centered T f] -- Goal: gaussianReal 0 ⟨Tf,Tf⟩.toNNReal = gaussianReal 0 Var[ev_f].toNNReal -- Variance of centered measure = E[X²] congr 1 have h_var : Var[(fun ω : Configuration E => ω f); measure T] = ∫ ω, (ω f) ^ 2 ∂(measure T) := variance_of_integral_eq_zero (configuration_eval_measurable f).aemeasurable (measure_centered T f) rw [h_var, second_moment_eq_covariance T f] end GaussianField