/- Copyright (c) 2026 Raphael Coelho. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Raphael Coelho -/ module public import MathFin.Foundations.DriftProcessPredictable /-! # SDE existence/uniqueness via Picard on `E` (build) The strong solution of `dX = b(X)dt + σ(X)dB`, `X₀ = η` is the fixed point of the Picard iterate `Φ(X)_t = η + ∫₀ᵗ b(X_s) ds + ∫₀ᵗ σ(X_s) dB_s`, built as a self-map of the predictable `L²` space `E := Lp ℝ 2 (trimMeasure_T T)`. Both analytic terms already land back in `E` — the drift as a genuine CLM `driftProcessAssembled : E →L[ℝ] E`, the Itô term as the element-valued linear map `itoProcessAssembled : E → E` (built from a continuous modification, so *not* a CLM — its linearity is re-established a.e.). This file wires them into the Picard map, proves the contraction estimate `‖Φ(X) − Φ(Y)‖ ≤ (T·L_b + √T·L_σ)·‖X − Y‖`, and — when that constant is `< 1` — obtains the **unique fixed point** (`picardSolution`) via Banach's theorem: existence and uniqueness of the strong solution in `E`. The `T` vs `√T` asymmetry is structural: both terms integrate a `[0,t]` quantity over `t ∈ [0,T]`, but Cauchy–Schwarz already spends a factor of time inside each drift slice (leaving the full `T`), whereas the Itô isometry bounds each `[0,t]` energy flatly by the total energy (so only `√T` survives the outer time-integral). The `driftProcessAssembled_norm_le` (`≤ T‖·‖`) and `itoProcessAssembled_norm_le` (`≤ √T‖·‖`) bounds live with their operators in `DriftProcessPredictable` / `ItoProcessPredictable`. * `lipComp` — the coefficient composition `f ∘ X ∈ E` (centered via `lipschitz_sub_const`); `lipComp_sub_norm_le` — its `L`-Lipschitz bound. * `picardMap` — the Picard iterate `Φ : E → E`. * `picardMap_contraction` — the contraction estimate; `picardMap_contractingWith` — as `ContractingWith`. * `picardSolution` — the strong solution (the fixed point); `picardMap_exists_unique_fixedPoint` — `∃!`. The remaining bridge to the benchmark `sc-thm-8.2.5` (its `ℝ`-time, pointwise-per-`t`, `intervalIntegral`-drift, opaque-`Iσ` shape) and the all-`T` extension (a Bielecki weighted norm) are the next steps. -/ @[expose] public section open MeasureTheory ProbabilityTheory Filter Topology open scoped NNReal ENNReal namespace MathFin namespace SDEExistence open ItoIntegralL2 ItoIntegralCLM ItoIntegralProcess ItoIntegralProcessGeneral ItoIntegralProcessContinuousModification variable {Ω : Type*} {mΩ : MeasurableSpace Ω} {μ : Measure Ω} [IsProbabilityMeasure μ] {B : ℝ≥0 → Ω → ℝ} /-- Centering a Lipschitz coefficient at `0`: `x ↦ f x − f 0` is `L`-Lipschitz and sends `0 ↦ 0`, so it composes with an `L²` process via `LipschitzWith.compLp`. -/ theorem lipschitz_sub_const {f : ℝ → ℝ} {L : ℝ≥0} (hf : LipschitzWith L f) : LipschitzWith L (fun x ↦ f x - f 0) := LipschitzWith.of_dist_le_mul fun x y ↦ by simpa only [Real.dist_eq, sub_sub_sub_cancel_right] using hf.dist_le_mul x y /-- **The coefficient composition** `f ∘ X ∈ E` for a Lipschitz `f : ℝ → ℝ` and a predictable process `X ∈ E`: `f(0)·1 + (f − f 0)∘X`. The centered part lands in `E` by `compLp` (predictability is inherited from `E`'s trim measure); the constant `f 0` is added back as a genuine element of `E` (finite measure). -/ noncomputable def lipComp (T : ℝ≥0) (hBmeas : ∀ t, Measurable (B t)) (f : ℝ → ℝ) (L : ℝ≥0) (hf : LipschitzWith L f) (X : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas)) : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas) := Lp.const 2 _ (f 0) + (lipschitz_sub_const hf).compLp (by simp) X /-- **The composition is `L`-Lipschitz in `X`** — the constant `f 0` cancels in the difference, and `LipschitzWith.norm_compLp_sub_le` bounds the centered part. This is the per-coefficient Lipschitz factor of the Picard contraction. -/ theorem lipComp_sub_norm_le (T : ℝ≥0) (hBmeas : ∀ t, Measurable (B t)) {f : ℝ → ℝ} {L : ℝ≥0} (hf : LipschitzWith L f) (X Y : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas)) : ‖lipComp T hBmeas f L hf X - lipComp T hBmeas f L hf Y‖ ≤ (L : ℝ) * ‖X - Y‖ := by rw [lipComp, lipComp, add_sub_add_left_eq_sub] exact (lipschitz_sub_const hf).norm_compLp_sub_le (by simp) X Y /-- **The Picard iterate** `Φ(X) = η + driftProcessAssembled(b∘X) + itoProcessAssembled(σ∘X)`, a self-map of `E`. Its fixed point is the strong solution of the SDE. -/ noncomputable def picardMap (hB : IsPreBrownianReal B μ) (T : ℝ≥0) (hBmeas : ∀ t, Measurable (B t)) (hBcont : ∀ ω, Continuous fun t : ℝ≥0 ↦ B t ω) {b σ : ℝ → ℝ} {Lb Lσ : ℝ≥0} (hb : LipschitzWith Lb b) (hσ : LipschitzWith Lσ σ) (η_E : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas)) (X : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas)) : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas) := η_E + driftProcessAssembled T hBmeas (lipComp T hBmeas b Lb hb X) + itoProcessAssembled hB T hBmeas hBcont (lipComp T hBmeas σ Lσ hσ X) /-- **The Picard contraction estimate** `‖Φ(X) − Φ(Y)‖ ≤ (T·L_b + √T·L_σ)·‖X − Y‖`. The initial condition cancels in the difference; the drift term contributes `T·L_b` (operator bound `T` × Lipschitz `L_b`), the Itô term `√T·L_σ` (operator bound `√T` × Lipschitz `L_σ`). For `T` small this constant is `< 1`, giving a contraction. -/ theorem picardMap_contraction (hB : IsPreBrownianReal B μ) (T : ℝ≥0) (hBmeas : ∀ t, Measurable (B t)) (hBcont : ∀ ω, Continuous fun t : ℝ≥0 ↦ B t ω) {b σ : ℝ → ℝ} {Lb Lσ : ℝ≥0} (hb : LipschitzWith Lb b) (hσ : LipschitzWith Lσ σ) (η_E X Y : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas)) : ‖picardMap hB T hBmeas hBcont hb hσ η_E X - picardMap hB T hBmeas hBcont hb hσ η_E Y‖ ≤ ((T : ℝ) * Lb + Real.sqrt (T : ℝ) * Lσ) * ‖X - Y‖ := by have hdrift : driftProcessAssembled (μ := μ) T hBmeas (lipComp T hBmeas b Lb hb X) - driftProcessAssembled (μ := μ) T hBmeas (lipComp T hBmeas b Lb hb Y) = driftProcessAssembled (μ := μ) T hBmeas (lipComp T hBmeas b Lb hb X - lipComp T hBmeas b Lb hb Y) := (map_sub (driftProcessAssembled (μ := μ) T hBmeas) _ _).symm have hito : itoProcessAssembled hB T hBmeas hBcont (lipComp T hBmeas σ Lσ hσ X) - itoProcessAssembled hB T hBmeas hBcont (lipComp T hBmeas σ Lσ hσ Y) = itoProcessAssembled hB T hBmeas hBcont (lipComp T hBmeas σ Lσ hσ X - lipComp T hBmeas σ Lσ hσ Y) := (itoProcessAssembled_sub hB T hBmeas hBcont _ _).symm have hdecomp : picardMap hB T hBmeas hBcont hb hσ η_E X - picardMap hB T hBmeas hBcont hb hσ η_E Y = driftProcessAssembled (μ := μ) T hBmeas (lipComp T hBmeas b Lb hb X - lipComp T hBmeas b Lb hb Y) + itoProcessAssembled hB T hBmeas hBcont (lipComp T hBmeas σ Lσ hσ X - lipComp T hBmeas σ Lσ hσ Y) := by rw [picardMap, picardMap, ← hdrift, ← hito]; abel rw [hdecomp] calc ‖driftProcessAssembled (μ := μ) T hBmeas (lipComp T hBmeas b Lb hb X - lipComp T hBmeas b Lb hb Y) + itoProcessAssembled hB T hBmeas hBcont (lipComp T hBmeas σ Lσ hσ X - lipComp T hBmeas σ Lσ hσ Y)‖ ≤ ‖driftProcessAssembled (μ := μ) T hBmeas (lipComp T hBmeas b Lb hb X - lipComp T hBmeas b Lb hb Y)‖ + ‖itoProcessAssembled hB T hBmeas hBcont (lipComp T hBmeas σ Lσ hσ X - lipComp T hBmeas σ Lσ hσ Y)‖ := norm_add_le _ _ _ ≤ (T : ℝ) * ‖lipComp T hBmeas b Lb hb X - lipComp T hBmeas b Lb hb Y‖ + Real.sqrt (T : ℝ) * ‖lipComp T hBmeas σ Lσ hσ X - lipComp T hBmeas σ Lσ hσ Y‖ := add_le_add (driftProcessAssembled_norm_le T hBmeas _) (itoProcessAssembled_norm_le hB T hBmeas hBcont _) _ ≤ (T : ℝ) * ((Lb : ℝ) * ‖X - Y‖) + Real.sqrt (T : ℝ) * ((Lσ : ℝ) * ‖X - Y‖) := add_le_add (mul_le_mul_of_nonneg_left (lipComp_sub_norm_le T hBmeas hb X Y) T.coe_nonneg) (mul_le_mul_of_nonneg_left (lipComp_sub_norm_le T hBmeas hσ X Y) (Real.sqrt_nonneg _)) _ = ((T : ℝ) * Lb + Real.sqrt (T : ℝ) * Lσ) * ‖X - Y‖ := by ring /-- **The Picard map is a contraction** on `E` once `T·L_b + √T·L_σ < 1` (a smallness condition on the horizon `T` given the Lipschitz constants). Packages `picardMap_contraction` as Mathlib's `ContractingWith`. -/ theorem picardMap_contractingWith (hB : IsPreBrownianReal B μ) (T : ℝ≥0) (hBmeas : ∀ t, Measurable (B t)) (hBcont : ∀ ω, Continuous fun t : ℝ≥0 ↦ B t ω) {b σ : ℝ → ℝ} {Lb Lσ : ℝ≥0} (hb : LipschitzWith Lb b) (hσ : LipschitzWith Lσ σ) (η_E : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas)) (hc : (T : ℝ) * Lb + Real.sqrt (T : ℝ) * Lσ < 1) : ContractingWith (Real.toNNReal ((T : ℝ) * Lb + Real.sqrt (T : ℝ) * Lσ)) (picardMap hB T hBmeas hBcont hb hσ η_E) := by have hc0 : (0 : ℝ) ≤ (T : ℝ) * Lb + Real.sqrt (T : ℝ) * Lσ := by positivity refine ⟨?_, LipschitzWith.of_dist_le_mul fun X Y ↦ ?_⟩ · rw [← NNReal.coe_lt_coe, Real.coe_toNNReal _ hc0, NNReal.coe_one]; exact hc · rw [dist_eq_norm, dist_eq_norm, Real.coe_toNNReal _ hc0] exact picardMap_contraction hB T hBmeas hBcont hb hσ η_E X Y /-- **The strong solution** of the SDE (contraction regime): the unique fixed point of the Picard map in `E`, from Banach's fixed-point theorem (`ContractingWith.fixedPoint`; `E` is a complete, nonempty metric space). -/ noncomputable def picardSolution (hB : IsPreBrownianReal B μ) (T : ℝ≥0) (hBmeas : ∀ t, Measurable (B t)) (hBcont : ∀ ω, Continuous fun t : ℝ≥0 ↦ B t ω) {b σ : ℝ → ℝ} {Lb Lσ : ℝ≥0} (hb : LipschitzWith Lb b) (hσ : LipschitzWith Lσ σ) (η_E : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas)) (hc : (T : ℝ) * Lb + Real.sqrt (T : ℝ) * Lσ < 1) : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas) := (picardMap_contractingWith hB T hBmeas hBcont hb hσ η_E hc).fixedPoint _ /-- **Existence + uniqueness** of the strong solution: `picardSolution` is a fixed point of the Picard map, and it is the *only* one — the SDE `dX = b(X)dt + σ(X)dB` has a unique strong solution in `E` under the contraction condition. -/ theorem picardMap_exists_unique_fixedPoint (hB : IsPreBrownianReal B μ) (T : ℝ≥0) (hBmeas : ∀ t, Measurable (B t)) (hBcont : ∀ ω, Continuous fun t : ℝ≥0 ↦ B t ω) {b σ : ℝ → ℝ} {Lb Lσ : ℝ≥0} (hb : LipschitzWith Lb b) (hσ : LipschitzWith Lσ σ) (η_E : Lp ℝ 2 (trimMeasure_T (μ := μ) T hBmeas)) (hc : (T : ℝ) * Lb + Real.sqrt (T : ℝ) * Lσ < 1) : ∃! X, picardMap hB T hBmeas hBcont hb hσ η_E X = X := by refine ⟨picardSolution hB T hBmeas hBcont hb hσ η_E hc, ?_, fun Y hY ↦ ?_⟩ · exact (picardMap_contractingWith hB T hBmeas hBcont hb hσ η_E hc).fixedPoint_isFixedPt · exact (picardMap_contractingWith hB T hBmeas hBcont hb hσ η_E hc).fixedPoint_unique hY end SDEExistence end MathFin