├── lean-toolchain ├── verso ├── lean-toolchain ├── static_files │ ├── LigaMenlo-Regular.ttf │ ├── scripts.js │ ├── style.css │ └── favicon.svg ├── build_manual.sh ├── lakefile.toml ├── Manual │ ├── Pages │ │ ├── Processes.lean │ │ ├── Extension.lean │ │ ├── Continuity.lean │ │ └── Gaussian.lean │ └── Front.lean ├── Manual.lean └── lake-manifest.json ├── blueprint └── src │ ├── blueprint.sty │ ├── latexmkrc │ ├── macros │ ├── web.tex │ ├── common.tex │ └── print.tex │ ├── plastex.cfg │ ├── extra_styles.css │ ├── print.tex │ ├── web.tex │ ├── chapters │ ├── debut.tex │ ├── process.tex │ └── characteristic_function.tex │ ├── content.tex │ └── bib.bib ├── Manuscript ├── _minted-proof_outline │ ├── 8E09FD9BF8C1518B9C958D85647460E9E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── 50B7A96FD2927B15E1A4BB519D9867B2E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── 8AAC16B7E7807FFCD488803ABF255E72E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── D1B99F57BC75967013DBD7B03CD98C2BE4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── 58757DFEAB5635093A48BDECBC19CF99E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── 8413B9ED51423CE34362958E1EDDE554E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── B1032CF6127DB4CA4A946291E0FC56F0E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── BCF2A702E467ACD2A10E1948F4779A7DE4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── 6ACDE663D7845BA6D5512CB84829B6C4E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── DD2533CBBE32EAA9F671628E17030148E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── A28B20F834BCC4B925421EDB3BFF54B2E4E7D3512B9D2092004B6809BEC27372.pygtex │ ├── DDEB42811F621758018798A6EA876771C965FB8E4A134FA1932D205A4B07554C.pygtex │ ├── 5227DEB661F9065F0A2C434EB500756CC965FB8E4A134FA1932D205A4B07554C.pygtex │ ├── 53020536D603A8FC3AF8CEAB757011C4C965FB8E4A134FA1932D205A4B07554C.pygtex │ └── default-pyg-prefix.pygstyle └── main.bib ├── BrownianMotion ├── Verso │ ├── Processes.lean │ └── Brownian.lean ├── StochasticIntegral │ ├── MathlibImports.lean │ ├── QuadraticVariation.lean │ ├── L2M.lean │ ├── Centering.lean │ ├── DoobLp.lean │ ├── LocalMonad.lean │ ├── DoobMeyer.lean │ ├── LocalMartingale.lean │ ├── Cadlag.lean │ ├── Komlos.lean │ └── SquareIntegrable.lean ├── Auxiliary │ ├── Real.lean │ ├── NNReal.lean │ ├── Nat.lean │ ├── WithLp.lean │ ├── StoppedProcess.lean │ ├── Analysis.lean │ ├── MeanInequalities.lean │ ├── WithTop.lean │ ├── Algebra.lean │ ├── Metric.lean │ ├── ENNReal.lean │ ├── FiniteInf.lean │ ├── Martingale.lean │ ├── LinearAlgebra.lean │ ├── IsStoppingTime.lean │ ├── Topology.lean │ └── HasLaw.lean ├── Gaussian │ ├── Fernique.lean │ ├── StochasticProcesses.lean │ ├── CovMatrix.lean │ └── Moment.lean └── Continuity │ └── HasBoundedInternalCoveringNumber.lean ├── home_page ├── assets │ └── css │ │ └── style.scss ├── 404.html ├── index.md ├── _include │ └── mathjax.html ├── Gemfile ├── _config.yml └── _layouts │ └── default.html ├── .vscode ├── extensions.json └── settings.json ├── .github ├── dependabot.yml └── workflows │ ├── create-release.yml │ ├── update.yml │ ├── blueprint.yml │ ├── 05-pr-comment.yml │ ├── 02-disclaim-issue.yml │ └── 03-propose-pr.yml ├── .gitignore ├── scripts └── nolints.json ├── lakefile.toml ├── README.md ├── BrownianMotion.lean ├── CONTRIBUTING.md ├── lake-manifest.json └── CODE_OF_CONDUCT.md /lean-toolchain: -------------------------------------------------------------------------------- 1 | leanprover/lean4:v4.26.0 -------------------------------------------------------------------------------- /verso/lean-toolchain: -------------------------------------------------------------------------------- 1 | leanprover/lean4:v4.26.0-rc1 -------------------------------------------------------------------------------- /blueprint/src/blueprint.sty: -------------------------------------------------------------------------------- 1 | \DeclareOption*{} 2 | \ProcessOptions 3 | 4 | \newcommand{\graphcolor}[3]{} -------------------------------------------------------------------------------- /verso/static_files/LigaMenlo-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RemyDegenne/brownian-motion/HEAD/verso/static_files/LigaMenlo-Regular.ttf -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/8E09FD9BF8C1518B9C958D85647460E9E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{mathlib} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/50B7A96FD2927B15E1A4BB519D9867B2E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{HolderOnWith} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/8AAC16B7E7807FFCD488803ABF255E72E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{DenseInducing} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/D1B99F57BC75967013DBD7B03CD98C2BE4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{HolderWith} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/58757DFEAB5635093A48BDECBC19CF99E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{Set.SeparatesPoints} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/8413B9ED51423CE34362958E1EDDE554E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{MeasureTheory.TendstoInMeasure} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/B1032CF6127DB4CA4A946291E0FC56F0E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{LipschitzOnWith.extend\PYGZus{}real} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/BCF2A702E467ACD2A10E1948F4779A7DE4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{DenseInducing.continuous\PYGZus{}extend} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /blueprint/src/latexmkrc: -------------------------------------------------------------------------------- 1 | # This file configures the latexmk command you can use to compile 2 | # the pdf version of the blueprint 3 | $pdf_mode = 1; 4 | $pdflatex = 'xelatex -synctex=1'; 5 | @default_files = ('print.tex'); -------------------------------------------------------------------------------- /BrownianMotion/Verso/Processes.lean: -------------------------------------------------------------------------------- 1 | import BrownianMotion.Auxiliary.StoppedProcess 2 | 3 | /-! 4 | # Verso file for stochastic processes 5 | 6 | This file is used to generate the Verso manual pages about stochastic processes. 7 | -/ 8 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/6ACDE663D7845BA6D5512CB84829B6C4E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{continuousAt\PYGZus{}of\PYGZus{}locally\PYGZus{}lipschitz} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/DD2533CBBE32EAA9F671628E17030148E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n}{MeasureTheory.tendstoInMeasure\PYGZus{}of\PYGZus{}tendsto\PYGZus{}ae} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /home_page/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | /* In this file you can add css rules overriding rules defined by your Jekyll theme. */ 5 | 6 | /* Import the CSS from the specified theme */ 7 | @import "{{ site.theme }}"; 8 | 9 | /* Put your rules below this line */ -------------------------------------------------------------------------------- /blueprint/src/macros/web.tex: -------------------------------------------------------------------------------- 1 | % In this file you should put macros to be used only by 2 | % the web version. Of course they should have a corresponding 3 | % version in macros/print.tex. 4 | % Typically the printed version could have more fancy decorations. 5 | % This will probably be a very short file. -------------------------------------------------------------------------------- /verso/build_manual.sh: -------------------------------------------------------------------------------- 1 | set -x -e 2 | 3 | lake build 4 | rm -rf html _out 5 | lake exe manual 6 | mkdir html 7 | mv _out/html-multi/* html/ 8 | rm -rf _out 9 | mkdir -p html/static 10 | cp static_files/* html/static 11 | 12 | cd .. 13 | mkdir -p home_page/verso 14 | cp -r verso/html/* home_page/verso 15 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/MathlibImports.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Probability.Martingale.BorelCantelli 2 | import Mathlib.Probability.Martingale.Convergence 3 | import Mathlib.Topology.EMetricSpace.BoundedVariation 4 | -- the goal of this file is to import statements that are mentioned in the blueprint but are not 5 | -- used yet in the code 6 | -------------------------------------------------------------------------------- /verso/lakefile.toml: -------------------------------------------------------------------------------- 1 | name = "manual" 2 | version = "0.1.0" 3 | keywords = ["math"] 4 | 5 | [leanOptions] 6 | autoImplicit = true 7 | 8 | [[require]] 9 | name = "verso" 10 | git = "https://github.com/leanprover/verso" 11 | 12 | [[lean_lib]] 13 | name = "Manual" 14 | root = "Manual" 15 | 16 | [[lean_exe]] 17 | name = "manual" 18 | root = "Manual" 19 | -------------------------------------------------------------------------------- /blueprint/src/plastex.cfg: -------------------------------------------------------------------------------- 1 | [general] 2 | renderer=HTML5 3 | copy-theme-extras=yes 4 | plugins=plastexdepgraph plastexshowmore leanblueprint 5 | 6 | [document] 7 | toc-depth=3 8 | toc-non-files=True 9 | 10 | [files] 11 | directory=../web/ 12 | split-level= 0 13 | 14 | [html5] 15 | localtoc-level=0 16 | extra-css=extra_styles.css 17 | mathjax-dollars=False -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/Real.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Analysis.SpecialFunctions.Log.Base 2 | 3 | namespace Real 4 | 5 | lemma inv_rpow_logb {b : ℝ} (hb : 0 < b) (hb' : b ≠ 1) {x : ℝ} (hx : 0 < x) : 6 | b⁻¹ ^ Real.logb b x = x⁻¹ := by 7 | rw [inv_eq_one_div, Real.div_rpow (by norm_num) (le_of_lt hb)] 8 | simpa using Real.rpow_logb hb hb' hx 9 | 10 | end Real 11 | -------------------------------------------------------------------------------- /verso/Manual/Pages/Processes.lean: -------------------------------------------------------------------------------- 1 | import VersoManual 2 | 3 | open Verso.Genre Manual Verso.Genre.Manual.InlineLean Verso.Code.External 4 | 5 | set_option pp.rawOnError true 6 | 7 | set_option verso.exampleProject "../" 8 | 9 | set_option verso.exampleModule "BrownianMotion.Verso.Processes" 10 | 11 | #doc (Manual) "Stochastic processes" => 12 | %%% 13 | htmlSplit := .never 14 | %%% 15 | 16 | TODO text 17 | -------------------------------------------------------------------------------- /verso/Manual/Pages/Extension.lean: -------------------------------------------------------------------------------- 1 | import VersoManual 2 | 3 | open Verso.Genre Manual Verso.Genre.Manual.InlineLean Verso.Code.External 4 | 5 | set_option pp.rawOnError true 6 | 7 | set_option verso.exampleProject "../" 8 | 9 | set_option verso.exampleModule "BrownianMotion.Verso.Processes" 10 | 11 | #doc (Manual) "Kolmogorov extension theorem" => 12 | %%% 13 | htmlSplit := .never 14 | %%% 15 | 16 | TODO text 17 | -------------------------------------------------------------------------------- /verso/Manual/Pages/Continuity.lean: -------------------------------------------------------------------------------- 1 | import VersoManual 2 | 3 | open Verso.Genre Manual Verso.Genre.Manual.InlineLean Verso.Code.External 4 | 5 | set_option pp.rawOnError true 6 | 7 | set_option verso.exampleProject "../" 8 | 9 | set_option verso.exampleModule "BrownianMotion.Verso.Processes" 10 | 11 | #doc (Manual) "Kolmogorov-Chentsov continuity theorem" => 12 | %%% 13 | htmlSplit := .never 14 | %%% 15 | 16 | TODO text 17 | -------------------------------------------------------------------------------- /verso/Manual/Pages/Gaussian.lean: -------------------------------------------------------------------------------- 1 | import VersoManual 2 | 3 | open Verso.Genre Manual Verso.Genre.Manual.InlineLean Verso.Code.External 4 | 5 | set_option pp.rawOnError true 6 | 7 | set_option verso.exampleProject "../" 8 | 9 | set_option verso.exampleModule "BrownianMotion.Verso.Processes" 10 | 11 | #doc (Manual) "Gaussian measures and their properties" => 12 | %%% 13 | htmlSplit := .never 14 | %%% 15 | 16 | TODO text 17 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // Learn about workspace recommendations at: 3 | // https://go.microsoft.com/fwlink/?LinkId=827846 4 | 5 | // The extension identifier format is ${publisher}.${name} 6 | // Example: vscode.csharp 7 | 8 | // List of extensions that should be recommended for users of this workspace 9 | "recommendations": [ 10 | "leanprover.lean4" // Extension for Lean 4 support 11 | ] 12 | } -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/NNReal.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Data.NNReal.Basic 2 | 3 | namespace NNReal 4 | 5 | lemma add_sub_two_mul_min_eq_max (s t : ℝ≥0) : s + t - 2 * min s t = max (s - t) (t - s) := by 6 | wlog hst : s ≤ t 7 | · convert this t s (le_of_not_ge hst) using 1 8 | · rw [add_comm, min_comm] 9 | · rw [max_comm] 10 | rw [min_eq_left hst, max_eq_right, two_mul, add_tsub_add_eq_tsub_left] 11 | grw [hst] 12 | 13 | end NNReal 14 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 # Specifies the version of the Dependabot configuration file format 2 | 3 | updates: 4 | # Configuration for dependency updates 5 | - package-ecosystem: "github-actions" # Specifies the ecosystem to check for updates 6 | directory: "/" # Specifies the directory to check for dependencies; "/" means the root directory 7 | schedule: 8 | # Check for updates to GitHub Actions every month 9 | interval: "monthly" 10 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/A28B20F834BCC4B925421EDB3BFF54B2E4E7D3512B9D2092004B6809BEC27372.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\}] 2 | \PYG{n+nb+bp}{∀ᵐ} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{α}\PYG{o}{)} \PYG{n+nb+bp}{∂}\PYG{n}{P}\PYG{o}{,} \PYG{n}{Filter.Tendsto} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{n+nb+bp}{=\PYGZgt{}} \PYG{n}{X} \PYG{n}{n} \PYG{n}{x}\PYG{o}{)} \PYG{n}{Filter.atTop} \PYG{o}{(}\PYG{n}{nhds} \PYG{o}{(}\PYG{n}{X} \PYG{n}{x}\PYG{o}{))} 3 | \end{Verbatim} 4 | -------------------------------------------------------------------------------- /home_page/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /404.html 3 | layout: default 4 | --- 5 | 6 | 19 | 20 |
21 |

404

22 | 23 |

Page not found :(

24 |

The requested page could not be found.

25 |
-------------------------------------------------------------------------------- /blueprint/src/extra_styles.css: -------------------------------------------------------------------------------- 1 | /* This file contains CSS tweaks for this blueprint. 2 | * As an example, we included CSS rules that put 3 | * a vertical line on the left of theorem statements 4 | * and proofs. 5 | * */ 6 | 7 | div.theorem_thmcontent { 8 | border-left: .15rem solid black; 9 | } 10 | 11 | div.proposition_thmcontent { 12 | border-left: .15rem solid black; 13 | } 14 | 15 | div.lemma_thmcontent { 16 | border-left: .1rem solid black; 17 | } 18 | 19 | div.corollary_thmcontent { 20 | border-left: .1rem solid black; 21 | } 22 | 23 | div.proof_content { 24 | border-left: .08rem solid grey; 25 | } 26 | -------------------------------------------------------------------------------- /home_page/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | # Feel free to add content and custom Front Matter to this file. 3 | # To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults 4 | 5 | # layout: home 6 | usemathjax: true 7 | --- 8 | 9 | Useful links: 10 | 11 | * [Zulip chat for Lean](https://leanprover.zulipchat.com/#narrow/channel/509433-Brownian-motion) for coordination 12 | * [Blueprint]({{ site.url }}/blueprint/) 13 | * [Blueprint as pdf]({{ site.url }}/blueprint.pdf) 14 | * [Dependency graph]({{ site.url }}/blueprint/dep_graph_document.html) 15 | * [Doc pages for this repository]({{ site.url }}/docs/) 16 | -------------------------------------------------------------------------------- /home_page/_include/mathjax.html: -------------------------------------------------------------------------------- 1 | 2 | {% if page.usemathjax %} 3 | 4 | 13 | 14 | 17 | {% endif %} -------------------------------------------------------------------------------- /verso/Manual.lean: -------------------------------------------------------------------------------- 1 | import VersoManual 2 | 3 | import Manual.Front 4 | 5 | open Verso.Genre.Manual Verso.Output.Html 6 | 7 | def extraHead : Array Verso.Output.Html := #[ 8 | {{}}, 9 | {{}}, 10 | {{}}, 11 | ] 12 | 13 | def config : Config := { 14 | extraHead := extraHead, 15 | sourceLink := some "https://github.com/RemyDegenne/brownian-motion", 16 | issueLink := some "https://github.com/RemyDegenne/brownian-motion/issues", 17 | } 18 | 19 | def main := manualMain (%doc Manual.Front) (config := config) 20 | -------------------------------------------------------------------------------- /.github/workflows/create-release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - 'lean-toolchain' 9 | 10 | jobs: 11 | lean-release-tag: 12 | name: Add Lean release tag 13 | runs-on: ubuntu-latest 14 | permissions: 15 | contents: write 16 | steps: 17 | - name: lean-release-tag action 18 | uses: leanprover-community/lean-release-tag@92561973391c1d265d18c6d5dfc424079cf5dd13 # 2025-05-22 19 | with: 20 | before: ${{ github.event.before }} 21 | after: ${{ github.event.after }} 22 | do-release: true 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Manuscript/proof_outline.pdf 2 | Manuscript/_minted/* 3 | 4 | ## macOS 5 | .DS_Store 6 | ## Lake 7 | .lake/* 8 | .cache/* 9 | ## Blueprint 10 | /blueprint/print/print.log 11 | /blueprint/web/ 12 | /blueprint/src/print.pdf 13 | /blueprint/src/web.paux 14 | /blueprint/src/web.bbl 15 | /blueprint/src/web.pdf 16 | /blueprint/print/ 17 | ## Verso 18 | /verso/.lake/ 19 | /verso/html/ 20 | /home_page/verso/ 21 | ## TeX 22 | *.aux 23 | *.lof 24 | *.log 25 | *.lot 26 | *.fls 27 | *.out 28 | *.toc 29 | *.fmt 30 | *.fot 31 | *.cb 32 | *.cb2 33 | .*.lb 34 | *.bbl 35 | *.bcf 36 | *.blg 37 | *-blx.aux 38 | *-blx.bib 39 | *.run.xml 40 | *.fdb_latexmk 41 | *.synctex 42 | *.synctex(busy) 43 | *.synctex.gz 44 | *.synctex.gz(busy) 45 | *.pdfsync 46 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/Nat.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Algebra.Order.Floor.Semiring 2 | import Mathlib.Algebra.Order.Ring.Abs 3 | 4 | lemma Nat.self_sub_floor_lt_one {R : Type*} [Ring R] [LinearOrder R] [FloorSemiring R] 5 | [IsStrictOrderedRing R] (x : R) : x - ⌊x⌋₊ < 1 := by 6 | rw [sub_lt_iff_lt_add'] 7 | exact Nat.lt_floor_add_one _ 8 | 9 | lemma Nat.zero_le_self_sub_floor {R : Type*} [Ring R] [LinearOrder R] [FloorSemiring R] 10 | [IsStrictOrderedRing R] {x : R} (hx : 0 ≤ x) : 0 ≤ x - ⌊x⌋₊ := by 11 | rw [sub_nonneg] 12 | exact Nat.floor_le hx 13 | 14 | lemma pow_two_mul_abs {α : Type*} [Ring α] [LinearOrder α] [IsStrictOrderedRing α] (n : ℕ) (a : α) : 15 | |a| ^ (2 * n) = a ^ (2 * n) := 16 | Even.pow_abs ⟨n, two_mul n⟩ a 17 | -------------------------------------------------------------------------------- /scripts/nolints.json: -------------------------------------------------------------------------------- 1 | [["docBlame", "B"], 2 | ["docBlame", "ContinuousBilinForm"], 3 | ["docBlame", "IsCoverWithBoundedCoveringNumber"], 4 | ["docBlame", "chainingSequence"], 5 | ["docBlame", "chainingSequenceReverse"], 6 | ["docBlame", "Ω"], 7 | ["docBlame", "ContinuousBilinForm.ofMatrix"], 8 | ["docBlame", "ProbabilityTheory.Cp"], 9 | ["docBlame", "ProbabilityTheory.brownian"], 10 | ["docBlame", "ProbabilityTheory.brownianCovMatrix"], 11 | ["docBlame", "ProbabilityTheory.constL"], 12 | ["docBlame", "ProbabilityTheory.gaussianLimit"], 13 | ["docBlame", "ProbabilityTheory.gaussianProjectiveFamily"], 14 | ["docBlame", "ProbabilityTheory.preBrownian"], 15 | ["docBlame", "ProbabilityTheory.wienerMeasure"], 16 | ["docBlame", "ProbabilityTheory.wienerMeasureAux"], 17 | ["docBlame", "ProbabilityTheory.MeasurableEquiv.continuousMap"]] 18 | -------------------------------------------------------------------------------- /verso/static_files/scripts.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function () { 2 | document.querySelectorAll('.has-info, .warning').forEach(function (el) { 3 | el.classList.remove('has-info', 'warning'); 4 | 5 | el.querySelectorAll('span.hover-container').forEach(function (hoverSpan) { 6 | hoverSpan.remove(); 7 | }); 8 | }); 9 | 10 | document.querySelectorAll('p').forEach(function (p) { 11 | if (p.querySelector('img')) { 12 | p.setAttribute('align', 'center'); 13 | } 14 | }); 15 | 16 | document.querySelectorAll('a[href]').forEach(function (link) { 17 | const url = new URL(link.href, window.location.href); 18 | if (url.hostname !== window.location.hostname) { 19 | link.setAttribute('target', '_blank'); 20 | link.setAttribute('rel', 'noopener noreferrer'); 21 | } 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // Configure editor to insert spaces when pressing Tab 3 | "editor.insertSpaces": true, 4 | // Set the number of spaces per tab 5 | "editor.tabSize": 2, 6 | // Display vertical rulers at specified character column for readability 7 | "editor.rulers": [100], 8 | // Set the default file encoding to UTF-8 9 | "files.encoding": "utf8", 10 | // Use Unix-style line endings ('\n') by default 11 | "files.eol": "\n", 12 | // Ensure a final newline at the end of files 13 | "files.insertFinalNewline": true, 14 | // Trim final newlines at the end of files 15 | "files.trimFinalNewlines": true, 16 | // Remove any trailing whitespace on save 17 | "files.trimTrailingWhitespace": true, 18 | // Select read-only files 19 | "files.readonlyInclude": { 20 | "**/.elan/**": true, 21 | "**/.lake/**": true 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /home_page/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # To upgrade, run `bundle update github-pages`. 4 | gem "github-pages", group: :jekyll_plugins 5 | # If you have any plugins, put them here! 6 | group :jekyll_plugins do 7 | #gem "jekyll-feed", "~> 0.12" 8 | end 9 | 10 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem 11 | # and associated library. 12 | platforms :mingw, :x64_mingw, :mswin, :jruby do 13 | gem "tzinfo", "~> 1.2" 14 | gem "tzinfo-data" 15 | end 16 | 17 | # Performance-booster for watching directories on Windows. 18 | gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] 19 | 20 | # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem 21 | # do not have a Java counterpart. 22 | gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby] 23 | 24 | # Used for locally serving the website. 25 | gem "webrick", "~> 1.7" -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/DDEB42811F621758018798A6EA876771C965FB8E4A134FA1932D205A4B07554C.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\},codes={\catcode`\$=3\catcode`\^=7\catcode`\_=8\relax}] 2 | \PYG{k+kd}{theorem} \PYG{n}{innerRegular\PYGZus{}isCompact\PYGZus{}isClosed\PYGZus{}measurableSet\PYGZus{}of\PYGZus{}complete\PYGZus{}countable} 3 | \PYG{o}{[}\PYG{n}{PseudoEMetricSpace} \PYG{n}{α}\PYG{o}{]} \PYG{o}{[}\PYG{n}{CompleteSpace} \PYG{n}{α}\PYG{o}{]} \PYG{o}{[}\PYG{n}{SecondCountableTopology} \PYG{n}{α}\PYG{o}{]} \PYG{o}{[}\PYG{n}{BorelSpace} \PYG{n}{α}\PYG{o}{]} 4 | \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{Measure} \PYG{n}{α}\PYG{o}{)} \PYG{o}{[}\PYG{n}{IsFiniteMeasure} \PYG{n}{P}\PYG{o}{]} \PYG{o}{:} 5 | \PYG{n}{P.InnerRegular} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{s} \PYG{n+nb+bp}{=\PYGZgt{}} \PYG{n}{IsCompact} \PYG{n}{s} \PYG{n+nb+bp}{∧} \PYG{n}{IsClosed} \PYG{n}{s}\PYG{o}{)} \PYG{n}{MeasurableSet} 6 | \end{Verbatim} 7 | -------------------------------------------------------------------------------- /blueprint/src/macros/common.tex: -------------------------------------------------------------------------------- 1 | % In this file you should put all LaTeX macros and settings to be used both by 2 | % the pdf version and the web version. 3 | % This should be most of your macros. 4 | 5 | % The theorem-like environments defined below are those that appear by default 6 | % in the dependency graph. See the README of leanblueprint if you need help to 7 | % customize this. 8 | % The configuration below use the theorem counter for all those environments 9 | % (this is what the [theorem] arguments mean) and never resets it. 10 | % If you want for instance to number them within chapters then you can add 11 | % [chapter] at the end of the next line. 12 | \newtheorem{theorem}{Theorem}[chapter] 13 | \newtheorem{proposition}[theorem]{Proposition} 14 | \newtheorem{lemma}[theorem]{Lemma} 15 | \newtheorem{corollary}[theorem]{Corollary} 16 | 17 | \theoremstyle{definition} 18 | \newtheorem{definition}[theorem]{Definition} 19 | -------------------------------------------------------------------------------- /lakefile.toml: -------------------------------------------------------------------------------- 1 | name = "BrownianMotion" 2 | defaultTargets = ["BrownianMotion"] 3 | lintDriver = "batteries/runLinter" 4 | 5 | [leanOptions] 6 | pp.unicode.fun = true 7 | autoImplicit = false 8 | relaxedAutoImplicit = false 9 | weak.linter.flexible = true # no rigid tactic (e.g. `exact`) after a flexible tactic (e.g. `simp`) 10 | # Enable all mathlib linters: automatically matches what mathlib uses. 11 | weak.linter.mathlibStandardSet = true 12 | 13 | [[require]] 14 | name = "mathlib" 15 | git = "https://github.com/leanprover-community/mathlib4.git" 16 | rev = "v4.26.0" 17 | 18 | [[require]] 19 | name = "kolmogorov_extension4" 20 | git = "https://github.com/RemyDegenne/kolmogorov_extension4" 21 | 22 | [[require]] 23 | name = "checkdecls" 24 | git = "https://github.com/PatrickMassot/checkdecls.git" 25 | 26 | [[require]] 27 | name = "subverso" 28 | git = "https://github.com/leanprover/subverso" 29 | 30 | [[lean_lib]] 31 | name = "BrownianMotion" 32 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/WithLp.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Analysis.InnerProductSpace.PiL2 2 | 3 | open WithLp ENNReal 4 | 5 | lemma PiLp.coe_proj (p : ENNReal) {ι : Type*} (𝕜 : Type*) {E : ι → Type*} [Semiring 𝕜] 6 | [∀ i, SeminormedAddCommGroup (E i)] [∀ i, Module 𝕜 (E i)] {i : ι} : 7 | ⇑(proj p (𝕜 := 𝕜) E i) = fun x ↦ x i := rfl 8 | 9 | lemma EuclideanSpace.coe_proj {ι : Type*} (𝕜 : Type*) [RCLike 𝕜] {i : ι} : 10 | ⇑(@proj ι 𝕜 _ i) = fun x ↦ x i := rfl 11 | 12 | @[simp] 13 | lemma EuclideanSpace.proj_apply {ι 𝕜 : Type*} [RCLike 𝕜] {i : ι} (x : EuclideanSpace 𝕜 ι) : 14 | proj i x = x i := rfl 15 | 16 | lemma ContinuousLinearMap.coe_proj' (R : Type*) {ι : Type*} [Semiring R] {φ : ι → Type*} 17 | [∀ i, TopologicalSpace (φ i)] [∀ i, AddCommMonoid (φ i)] [∀ i, Module R (φ i)] (i : ι) : 18 | ⇑(ContinuousLinearMap.proj (R := R) (φ := φ) i) = fun x ↦ x i := rfl 19 | 20 | lemma EuclideanSpace.coe_equiv_symm {ι 𝕜 : Type*} [RCLike 𝕜] : 21 | ⇑(EuclideanSpace.equiv ι 𝕜).symm = toLp 2 := rfl 22 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/5227DEB661F9065F0A2C434EB500756CC965FB8E4A134FA1932D205A4B07554C.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\},codes={\catcode`\$=3\catcode`\^=7\catcode`\_=8\relax}] 2 | \PYG{k+kd}{theorem} \PYG{n}{ContinuousMap.starSubalgebra\PYGZus{}topologicalClosure\PYGZus{}eq\PYGZus{}top\PYGZus{}of\PYGZus{}separatesPoints} 3 | \PYG{o}{\PYGZob{}}\PYG{n+nb+bp}{𝕜} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{n}{u\PYGZus{}2}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{X} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{n}{u\PYGZus{}1}\PYG{o}{\PYGZcb{}} \PYG{o}{[}\PYG{n}{IsROrC} \PYG{n+nb+bp}{𝕜}\PYG{o}{]} \PYG{o}{[}\PYG{n}{TopologicalSpace} \PYG{n}{X}\PYG{o}{]} \PYG{o}{[}\PYG{n}{CompactSpace} \PYG{n}{X}\PYG{o}{]} 4 | \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{n}{StarSubalgebra} \PYG{n+nb+bp}{𝕜} \PYG{n}{C}\PYG{o}{(}\PYG{n}{X}\PYG{o}{,} \PYG{n+nb+bp}{𝕜}\PYG{o}{))} \PYG{o}{(}\PYG{n}{hA} \PYG{o}{:} \PYG{n}{Subalgebra.SeparatesPoints} \PYG{n}{A.toSubalgebra}\PYG{o}{)} \PYG{o}{:} 5 | \PYG{n}{StarSubalgebra.topologicalClosure} \PYG{n}{A} \PYG{n+nb+bp}{=} \PYG{n+nb+bp}{⊤} 6 | \end{Verbatim} 7 | -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | name: Update Dependencies 2 | 3 | on: 4 | # schedule: # Sets a schedule to trigger the workflow 5 | # - cron: "0 8 * * *" # Every day at 08:00 AM UTC (see https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule) 6 | workflow_dispatch: # Allows the workflow to be triggered manually via the GitHub interface 7 | 8 | jobs: 9 | update_lean: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write # Grants permission to push changes to the repository 13 | issues: write # Grants permission to create or update issues 14 | pull-requests: write # Grants permission to create or update pull requests 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v6 18 | - name: Update project 19 | uses: leanprover-community/lean-update@main 20 | with: 21 | on_update_succeeds: pr # Create a pull request if the update succeeds 22 | on_update_fails: issue # Create an issue if the update fails 23 | legacy_update: true # Executes lake -R -Kenv=dev update instead of lake update. 24 | -------------------------------------------------------------------------------- /blueprint/src/macros/print.tex: -------------------------------------------------------------------------------- 1 | % In this file you should put macros to be used only by 2 | % the printed version. Of course they should have a corresponding 3 | % version in macros/web.tex. 4 | % Typically the printed version could have more fancy decorations. 5 | % This should be a very short file. 6 | % 7 | % This file starts with dummy macros that ensure the pdf 8 | % compiler will ignore macros provided by plasTeX that make 9 | % sense only for the web version, such as dependency graph 10 | % macros. 11 | 12 | 13 | % Dummy macros that make sense only for web version. 14 | \newcommand{\lean}[1]{} 15 | \newcommand{\discussion}[1]{} 16 | \newcommand{\leanok}{} 17 | \newcommand{\mathlibok}{} 18 | \newcommand{\notready}{} 19 | % Make sure that arguments of \uses and \proves are real labels, by using invisible refs: 20 | % latex prints a warning if the label is not defined, but nothing is shown in the pdf file. 21 | % It uses LaTeX3 programming, this is why we use the expl3 package. 22 | \ExplSyntaxOn 23 | \NewDocumentCommand{\uses}{m} 24 | {\clist_map_inline:nn{#1}{\vphantom{\ref{##1}}}% 25 | \ignorespaces} 26 | \NewDocumentCommand{\proves}{m} 27 | {\clist_map_inline:nn{#1}{\vphantom{\ref{##1}}}% 28 | \ignorespaces} 29 | \ExplSyntaxOff 30 | -------------------------------------------------------------------------------- /verso/static_files/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --accent: #657ed4; 3 | --accent-compl: #d4bb65; 4 | --background: #eef0f2; 5 | --background-lighter: #fafafa; 6 | } 7 | 8 | @font-face { 9 | font-family: "LigaMenlo"; 10 | src: url("LigaMenlo-Regular.ttf"); 11 | } 12 | 13 | body { 14 | text-align: justify; 15 | background-color: var(--background); 16 | } 17 | 18 | p a:visited, 19 | p a:link { 20 | text-decoration: none; 21 | color: var(--accent); 22 | } 23 | 24 | p a:hover { 25 | text-decoration: underline; 26 | } 27 | 28 | .toc { 29 | background-color: var(--background-lighter); 30 | } 31 | 32 | .keyword { 33 | color: var(--accent) !important; 34 | } 35 | 36 | .hl.lean .token.binding-hl, 37 | .hl.lean .literal.string:hover, 38 | .hl.lean .token.typed:hover { 39 | background-color: var(--accent-compl) !important; 40 | border-radius: 2px !important; 41 | } 42 | 43 | .block { 44 | background-color: var(--background-lighter); 45 | padding: 0.4em; 46 | border: 2px solid black; 47 | border-radius: 0.5em; 48 | } 49 | 50 | .tippy-box[data-theme~='lean'] { 51 | background-color: var(--background-lighter) !important; 52 | } 53 | 54 | code { 55 | font-family: "LigaMenlo"; 56 | font-variant-ligatures: normal; 57 | } -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/QuadraticVariation.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.StochasticIntegral.DoobMeyer 7 | 8 | /-! # Quadratic variation of local martingales 9 | 10 | -/ 11 | 12 | open MeasureTheory Filter 13 | open scoped ENNReal 14 | 15 | namespace ProbabilityTheory 16 | 17 | variable {ι Ω E : Type*} [LinearOrder ι] [OrderBot ι] [TopologicalSpace ι] [OrderTopology ι] 18 | [MeasurableSpace ι] [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] 19 | {mΩ : MeasurableSpace Ω} {P : Measure Ω} {X : ι → Ω → E} {𝓕 : Filtration ι mΩ} 20 | 21 | lemma IsLocalMartingale.isLocalSubmartingale_sq_norm 22 | (hX : IsLocalMartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 23 | IsLocalSubmartingale (fun t ω ↦ ‖X t ω‖ ^ 2) 𝓕 P := by 24 | sorry 25 | 26 | /-- The quadratic variation of a local martingale, defined as the predictable part of the Doob-Meyer 27 | decomposition of its squared norm. -/ 28 | noncomputable 29 | def quadraticVariation (hX : IsLocalMartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 30 | ι → Ω → ℝ := 31 | have hX2_cadlag : ∀ ω, IsCadlag (fun t ↦ ‖X t ω‖ ^ 2) := sorry 32 | (hX.isLocalSubmartingale_sq_norm hX_cadlag).predictablePart (fun t ω ↦ ‖X t ω‖ ^ 2) hX2_cadlag 33 | 34 | end ProbabilityTheory 35 | -------------------------------------------------------------------------------- /BrownianMotion/Gaussian/Fernique.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.Auxiliary.HasLaw 7 | import Mathlib.Probability.Distributions.Gaussian.Fernique 8 | 9 | 10 | /-! 11 | # Gaussian distributions in Banach spaces: Fernique's theorem 12 | -/ 13 | 14 | open MeasureTheory Real NormedSpace 15 | open scoped ENNReal 16 | 17 | namespace ProbabilityTheory 18 | 19 | variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] 20 | [SecondCountableTopology E] [CompleteSpace E] [MeasurableSpace E] [BorelSpace E] 21 | {μ : Measure E} [IsGaussian μ] 22 | 23 | variable {Ω : Type*} {mΩ : MeasurableSpace Ω} {P : Measure Ω} {X : Ω → E} 24 | 25 | /-- A Gaussian random variable has moments of all orders. -/ 26 | lemma HasGaussianLaw.memLp [hX : HasGaussianLaw X P] {p : ℝ≥0∞} (hp : p ≠ ∞) : 27 | MemLp X p P := by 28 | rw [← Function.id_comp X, ← memLp_map_measure_iff] 29 | · exact IsGaussian.memLp_id _ p hp 30 | · exact aestronglyMeasurable_id 31 | · exact hX.aemeasurable 32 | 33 | lemma HasGaussianLaw.memLp_two [HasGaussianLaw X P] : 34 | MemLp X 2 P := HasGaussianLaw.memLp (by norm_num) 35 | 36 | lemma HasGaussianLaw.integrable [HasGaussianLaw X P] : 37 | Integrable X P := memLp_one_iff_integrable.1 <| HasGaussianLaw.memLp (by norm_num) 38 | 39 | end ProbabilityTheory 40 | -------------------------------------------------------------------------------- /blueprint/src/print.tex: -------------------------------------------------------------------------------- 1 | % This file makes a printable version of the blueprint 2 | % It should include all the \usepackage needed for the pdf version. 3 | % The template version assume you want to use a modern TeX compiler 4 | % such as xeLaTeX or luaLaTeX including support for unicode 5 | % and Latin Modern Math font with standard bugfixes applied. 6 | % It also uses expl3 in order to support macros related to the dependency graph. 7 | % It also includes standard AMS packages (and their improved version 8 | % mathtools) as well as support for links with a sober decoration 9 | % (no ugly rectangles around links). 10 | % It is otherwise a very minimal preamble (you should probably at least 11 | % add cleveref and tikz-cd). 12 | 13 | \documentclass[a4paper]{report} 14 | 15 | \usepackage{geometry} 16 | 17 | \usepackage{expl3} 18 | 19 | \usepackage{amssymb, amsthm, mathtools} 20 | \usepackage[unicode,colorlinks=true,linkcolor=blue,urlcolor=magenta, citecolor=blue]{hyperref} 21 | 22 | \usepackage[warnings-off={mathtools-colon,mathtools-overbracket}]{unicode-math} 23 | 24 | \usepackage{bibunits} 25 | \defaultbibliographystyle{amsalpha} 26 | \defaultbibliography{bib} 27 | 28 | \input{macros/common} 29 | \input{macros/print} 30 | 31 | \title{Formalization of a Brownian motion and of stochastic integrals in Lean} 32 | \author{Rémy Degenne \and Peter Pfaffelhuber} 33 | 34 | \begin{document} 35 | 36 | \bibliographyunit[\part] 37 | 38 | \maketitle 39 | \input{content} 40 | \end{document} 41 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/53020536D603A8FC3AF8CEAB757011C4C965FB8E4A134FA1932D205A4B07554C.pygtex: -------------------------------------------------------------------------------- 1 | \begin{Verbatim}[commandchars=\\\{\},codes={\catcode`\$=3\catcode`\^=7\catcode`\_=8\relax}] 2 | \PYG{k+kd}{structure} \PYG{n}{Subalgebra} \PYG{o}{(}\PYG{n}{R} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{n}{u}\PYG{o}{)} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{n}{v}\PYG{o}{)} \PYG{o}{[}\PYG{n}{CommSemiring} \PYG{n}{R}\PYG{o}{]} \PYG{o}{[}\PYG{n}{Semiring} \PYG{n}{A}\PYG{o}{]} 3 | \PYG{o}{[}\PYG{n}{Algebra} \PYG{n}{R} \PYG{n}{A}\PYG{o}{]} \PYG{k+kd}{extends} \PYG{n}{Subsemiring} \PYG{o}{:} 4 | \PYG{k+kt}{Type} \PYG{n}{v} 5 | 6 | \PYG{n}{abbrev} \PYG{n}{Subalgebra.SeparatesPoints} \PYG{o}{\PYGZob{}}\PYG{n}{α} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{n}{u\PYGZus{}1}\PYG{o}{\PYGZcb{}} \PYG{o}{[}\PYG{n}{TopologicalSpace} \PYG{n}{α}\PYG{o}{]} 7 | \PYG{o}{\PYGZob{}}\PYG{n}{R} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{n}{u\PYGZus{}2}\PYG{o}{\PYGZcb{}} \PYG{o}{[}\PYG{n}{CommSemiring} \PYG{n}{R}\PYG{o}{]} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{n}{u\PYGZus{}3}\PYG{o}{\PYGZcb{}} \PYG{o}{[}\PYG{n}{TopologicalSpace} \PYG{n}{A}\PYG{o}{]} 8 | \PYG{o}{[}\PYG{n}{Semiring} \PYG{n}{A}\PYG{o}{]} \PYG{o}{[}\PYG{n}{Algebra} \PYG{n}{R} \PYG{n}{A}\PYG{o}{]} \PYG{o}{[}\PYG{n}{TopologicalSemiring} \PYG{n}{A}\PYG{o}{]} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{Subalgebra} \PYG{n}{R} \PYG{n}{C}\PYG{o}{(}\PYG{n}{α}\PYG{o}{,} \PYG{n}{A}\PYG{o}{))} 9 | \PYG{o}{:} \PYG{k+kt}{Prop} 10 | \end{Verbatim} 11 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/StoppedProcess.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Probability.Process.Stopping 2 | 3 | open MeasureTheory Filter 4 | open scoped ENNReal Topology 5 | 6 | namespace MeasureTheory 7 | 8 | variable {ι Ω E : Type*} {mΩ : MeasurableSpace Ω} {P : Measure Ω} 9 | 10 | variable [Nonempty ι] [LinearOrder ι] 11 | 12 | @[simp] lemma stoppedProcess_const {β : Type*} {u₀ : Ω → β} {τ : Ω → WithTop ι} : 13 | stoppedProcess (fun _ ↦ u₀) τ = fun _ ↦ u₀ := rfl 14 | 15 | @[simp] lemma stoppedProcess_neg {β : Type*} [Neg β] {u : ι → Ω → β} {τ : Ω → WithTop ι} : 16 | stoppedProcess (-u) τ = -stoppedProcess u τ := rfl 17 | 18 | @[simp] lemma stoppedProcess_add {β : Type*} [Add β] {u v : ι → Ω → β} {τ : Ω → WithTop ι} : 19 | stoppedProcess (u + v) τ = stoppedProcess u τ + stoppedProcess v τ := rfl 20 | 21 | @[simp] lemma stoppedProcess_sub {β : Type*} [Sub β] {u v : ι → Ω → β} {τ : Ω → WithTop ι} : 22 | stoppedProcess (u - v) τ = stoppedProcess u τ - stoppedProcess v τ := rfl 23 | 24 | @[simp] lemma stoppedProcess_const_smul {β : Type*} [SMul ℝ β] (c : ℝ) {u : ι → Ω → β} 25 | {τ : Ω → WithTop ι} : stoppedProcess (c • u) τ = c • stoppedProcess u τ := rfl 26 | 27 | @[simp] lemma stoppedProcess_const_bot [OrderBot ι] {E} (X : ι → Ω → E) : 28 | stoppedProcess X (fun _ ↦ ⊥) = fun _ ↦ X ⊥ := by 29 | ext; simp [stoppedProcess, ← WithTop.coe_bot] 30 | 31 | @[simp] lemma stoppedProcess_const_top {E} (X : ι → Ω → E) : 32 | stoppedProcess X (fun _ ↦ ⊤) = X := by ext; simp [stoppedProcess] 33 | 34 | end MeasureTheory 35 | -------------------------------------------------------------------------------- /verso/lake-manifest.json: -------------------------------------------------------------------------------- 1 | {"version": "1.1.0", 2 | "packagesDir": ".lake/packages", 3 | "packages": 4 | [{"url": "https://github.com/leanprover/verso", 5 | "type": "git", 6 | "subDir": null, 7 | "scope": "", 8 | "rev": "e60917322fadb47c4fe940ac380c00914d60b9aa", 9 | "name": "verso", 10 | "manifestFile": "lake-manifest.json", 11 | "inputRev": null, 12 | "inherited": false, 13 | "configFile": "lakefile.lean"}, 14 | {"url": "https://github.com/leanprover-community/plausible", 15 | "type": "git", 16 | "subDir": null, 17 | "scope": "", 18 | "rev": "ec4a54b5308c1f46b4b52a9c62fb67d193aa0972", 19 | "name": "plausible", 20 | "manifestFile": "lake-manifest.json", 21 | "inputRev": "main", 22 | "inherited": true, 23 | "configFile": "lakefile.toml"}, 24 | {"url": "https://github.com/acmepjz/md4lean", 25 | "type": "git", 26 | "subDir": null, 27 | "scope": "", 28 | "rev": "38ac5945d744903ffcc473ce1030223991b11cf6", 29 | "name": "MD4Lean", 30 | "manifestFile": "lake-manifest.json", 31 | "inputRev": "main", 32 | "inherited": true, 33 | "configFile": "lakefile.lean"}, 34 | {"url": "https://github.com/leanprover/subverso", 35 | "type": "git", 36 | "subDir": null, 37 | "scope": "", 38 | "rev": "1d663ae67d8088111bb37c3c526fe2d43e4df01c", 39 | "name": "subverso", 40 | "manifestFile": "lake-manifest.json", 41 | "inputRev": "main", 42 | "inherited": true, 43 | "configFile": "lakefile.lean"}], 44 | "name": "manual", 45 | "lakeDir": ".lake"} 46 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/L2M.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.Auxiliary.Martingale 7 | import BrownianMotion.StochasticIntegral.ApproxSeq 8 | import BrownianMotion.StochasticIntegral.Locally 9 | import BrownianMotion.Auxiliary.Adapted 10 | import BrownianMotion.StochasticIntegral.OptionalSampling 11 | import Mathlib.Probability.Process.HittingTime 12 | import Mathlib.Probability.Process.Predictable 13 | 14 | /-! # L2M space 15 | 16 | -/ 17 | 18 | open MeasureTheory Filter Function TopologicalSpace 19 | open scoped ENNReal 20 | 21 | namespace ProbabilityTheory 22 | 23 | variable {T Ω E : Type*} [LinearOrder T] [TopologicalSpace T] [OrderBot T] 24 | [OrderTopology T] [MeasurableSpace T] [BorelSpace T] 25 | [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] 26 | {mΩ : MeasurableSpace Ω} {P : Measure Ω} 27 | {X Y : T → Ω → E} {𝓕 : Filtration T mΩ} 28 | 29 | lemma _root_.MeasureTheory.Filtration.predictable_le_prod (𝓕 : Filtration T mΩ) : 30 | 𝓕.predictable ≤ Prod.instMeasurableSpace := by 31 | sorry 32 | 33 | -- this will be specialized in a later definition to the measure 34 | -- coming from the quadratic variation of a martingale 35 | /-- L2 space of predictable processes with respect to a product measure. -/ 36 | noncomputable 37 | def L2Predictable (μ : Measure T) (P : Measure Ω) := Lp E 2 ((μ.prod P).trim 𝓕.predictable_le_prod) 38 | 39 | end ProbabilityTheory 40 | -------------------------------------------------------------------------------- /home_page/_config.yml: -------------------------------------------------------------------------------- 1 | # Welcome to Jekyll! 2 | # 3 | # This config file is meant for settings that affect your whole blog, values 4 | # which you are expected to set up once and rarely edit after that. If you find 5 | # yourself editing this file very often, consider using Jekyll's data files 6 | # feature for the data you need to update frequently. 7 | # 8 | # For technical reasons, this file is *NOT* reloaded automatically when you use 9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process. 10 | # 11 | # If you need help with YAML syntax, here are some quick references for you: 12 | # https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml 13 | # https://learnxinyminutes.com/docs/yaml/ 14 | # 15 | # Site settings 16 | # These are used to personalize your new site. If you look in the HTML files, 17 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. 18 | # You can create any custom variable you would like, and they will be accessible 19 | # in the templates via {{ site.myvariable }}. 20 | 21 | title: Brownian Motion 22 | #email: your-email@example.com 23 | description: by Rémy Degenne and Peter Pfaffelhuber 24 | baseurl: "" # the subpath of your site, e.g. /blog 25 | url: "https://RemyDegenne.github.io/brownian-motion" # the base hostname & protocol for your site, e.g. http://example.com 26 | twitter_username: 27 | github_username: RemyDegenne 28 | repository: RemyDegenne/brownian-motion 29 | 30 | # Build settings 31 | remote_theme: pages-themes/cayman@v0.2.0 32 | plugins: 33 | - jekyll-remote-theme 34 | - jekyll-github-metadata -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/Analysis.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Analysis.Convex.SpecificFunctions.Basic 2 | import Mathlib.Analysis.InnerProductSpace.Basic 3 | import Mathlib.Analysis.Normed.Module.Convex 4 | 5 | attribute [simp] convex_empty 6 | attribute [simp] convex_univ 7 | 8 | @[nontriviality] 9 | lemma convexOn_subsingleton {𝕜 E β : Type*} [Semiring 𝕜] [PartialOrder 𝕜] [AddCommMonoid E] 10 | [Subsingleton E] [AddCommMonoid β] [PartialOrder β] [SMul 𝕜 E] [Module 𝕜 β] (s : Set E) 11 | (f : E → β) : ConvexOn 𝕜 s f := by 12 | constructor 13 | · exact Subsingleton.set_cases (by simp) (by simp) s 14 | · intro x hx y hy a b ha hb hab 15 | simp_rw [Subsingleton.eq_zero (α := E), ← add_smul, hab, one_smul] 16 | rfl 17 | 18 | lemma convexOn_rpow_norm {E : Type*} [SeminormedAddCommGroup E] 19 | [NormedSpace ℝ E] {p : ℝ} (hp : 1 ≤ p) : 20 | ConvexOn ℝ Set.univ (fun x : E ↦ ‖x‖ ^ p) := by 21 | nontriviality E 22 | refine ConvexOn.comp (g := fun x ↦ x ^ p) ?_ convexOn_univ_norm ?_ 23 | · refine (convexOn_rpow hp).subset ?_ ?_ 24 | · rintro - ⟨y, -, rfl⟩ 25 | simp 26 | rintro - ⟨x, -, rfl⟩ - ⟨y, -, rfl⟩ a b ha hb hab 27 | obtain hx | hx := eq_or_ne ‖x‖ 0 28 | · refine ⟨b • y, by simp, ?_⟩ 29 | simp [hx, norm_smul, hb] 30 | · refine ⟨((a * ‖x‖ + b * ‖y‖) / ‖x‖) • x, by simp, ?_⟩ 31 | simp only [norm_smul, norm_div, Real.norm_eq_abs, abs_norm, isUnit_iff_ne_zero, ne_eq, hx, 32 | not_false_eq_true, IsUnit.div_mul_cancel, smul_eq_mul, abs_eq_self] 33 | positivity 34 | · apply (Real.monotoneOn_rpow_Ici_of_exponent_nonneg (by linarith)).mono 35 | rintro - ⟨x, -, rfl⟩ 36 | simp 37 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/Centering.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import Mathlib.Probability.Martingale.Centering 7 | 8 | /-! 9 | # Lemmas about the Doob decomposition 10 | 11 | -/ 12 | 13 | open scoped NNReal ENNReal 14 | 15 | namespace MeasureTheory 16 | 17 | variable {Ω E : Type*} {mΩ : MeasurableSpace Ω} {μ : Measure Ω} 18 | [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] 19 | {X : ℕ → Ω → E} {𝓕 : Filtration ℕ mΩ} 20 | 21 | lemma predictablePart_add_one (n : ℕ) : 22 | predictablePart X 𝓕 μ (n + 1) = 23 | predictablePart X 𝓕 μ n + μ[X (n + 1) - X n | 𝓕 n] := by 24 | simp [predictablePart, Finset.sum_range_add] 25 | 26 | variable [SecondCountableTopology E] [MeasurableSpace E] [BorelSpace E] 27 | 28 | lemma isPredictable_predictablePart : IsPredictable 𝓕 (predictablePart X 𝓕 μ) := 29 | isPredictable_of_measurable_add_one (by simp [measurable_const']) 30 | fun n ↦ (adapted_predictablePart n).measurable 31 | 32 | -- todo: feel free to replace `Preorder E` by something stonger if needed 33 | lemma Submartingale.monotone_predictablePart {X : ℕ → Ω → ℝ} (hX : Submartingale X 𝓕 μ) : 34 | ∀ᵐ ω ∂μ, Monotone (predictablePart X 𝓕 μ · ω) := by 35 | have := ae_all_iff.2 <| fun n : ℕ ↦ hX.condExp_sub_nonneg n.le_succ 36 | filter_upwards [this] with ω h 37 | simp only [Pi.zero_apply, Nat.succ_eq_add_one, ← ge_iff_le] at h 38 | refine monotone_nat_of_le_succ fun n ↦ (?_ : _ ≥ _) 39 | grw [predictablePart_add_one, Pi.add_apply, h n, add_zero] 40 | 41 | end MeasureTheory 42 | -------------------------------------------------------------------------------- /blueprint/src/web.tex: -------------------------------------------------------------------------------- 1 | % This file makes a web version of the blueprint 2 | % It should include all the \usepackage needed for this version. 3 | % The template includes standard AMS packages. 4 | % It is otherwise a very minimal preamble (you should probably at least 5 | % add cleveref and tikz-cd). 6 | 7 | \documentclass{report} 8 | 9 | \usepackage{amssymb, amsthm, amsmath} 10 | \usepackage{hyperref} 11 | \usepackage[showmore, dep_graph]{blueprint} 12 | 13 | \newcommand{\putbib}{} % we are using bibunits in print.tex, but not here 14 | 15 | % \bigsqcap is not correctly rendered (https://github.com/mathjax/MathJax/issues/1588) 16 | % so we define a fallback. 17 | \renewcommand{\bigsqcap}{\mathop{\Large\sqcap}} 18 | 19 | \input{macros/common} 20 | \input{macros/web} 21 | 22 | \graphcolor{mathlib}{purple}{Purple} 23 | 24 | \home{https://RemyDegenne.github.io/brownian-motion} 25 | \github{https://github.com/RemyDegenne/brownian-motion} 26 | \dochome{https://RemyDegenne.github.io/brownian-motion/docs} 27 | 28 | \title{Formalization of a Brownian motion and of stochastic integrals in Lean} 29 | \author{Rémy Degenne \and Peter Pfaffelhuber} 30 | 31 | \begin{document} 32 | \maketitle 33 | \input{content} 34 | 35 | \bibliographystyle{amsalpha} 36 | % HACK: bibunits in print.tex generates bu1.bbl and bu2.bbl, but 37 | % `leanblueprint pdf` expects a single print.bbl to be copied to web.bbl, 38 | % which is input by \bibliography. 39 | % We manually input the bbl files instead of using \bibliography. 40 | \part*{Bibliography} 41 | \subsection*{Part 1 Bibliography} 42 | \input{../print/bu1.bbl} 43 | \subsection*{Part 2 Bibliography} 44 | \input{../print/bu2.bbl} 45 | 46 | \end{document} 47 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/MeanInequalities.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.MeasureTheory.Integral.MeanInequalities 2 | import Mathlib.Tactic 3 | 4 | open MeasureTheory 5 | 6 | namespace ENNReal 7 | 8 | theorem lintegral_Lp_finsum_le {α : Type*} [MeasurableSpace α] {μ : Measure α} {p : ℝ} 9 | {ι : Type*} {f : ι → α → ENNReal} {I : Finset ι} 10 | (hf : ∀ i ∈ I, AEMeasurable (f i) μ) (hp : 1 ≤ p) : 11 | (∫⁻ (a : α), (∑ i ∈ I, f i) a ^ p ∂μ) ^ (1 / p) ≤ 12 | ∑ i ∈ I, (∫⁻ (a : α), f i a ^ p ∂μ) ^ (1 / p) := by 13 | classical 14 | induction I using Finset.induction with 15 | | empty => simpa using Or.inl (by bound) 16 | | insert i I hi ih => 17 | simp only [Finset.sum_insert hi] 18 | refine (ENNReal.lintegral_Lp_add_le (hf i (by simp)) 19 | (I.aemeasurable_sum (fun j hj => hf j (by simp [hj]))) hp).trans ?_ 20 | gcongr 21 | exact ih (fun j hj => hf j (by simp [hj])) 22 | 23 | theorem lintegral_Lp_finsum_le' {α : Type*} [MeasurableSpace α] {μ : Measure α} {p : ℝ} 24 | {ι : Type*} {f : ι → α → ENNReal} {I : Finset ι} 25 | (hf : ∀ i ∈ I, AEMeasurable (f i) μ) (hp : 1 ≤ p) : 26 | (∫⁻ (a : α), (∑ i ∈ I, f i a) ^ p ∂μ) ^ (1 / p) ≤ 27 | ∑ i ∈ I, (∫⁻ (a : α), f i a ^ p ∂μ) ^ (1 / p) := by 28 | simpa using ENNReal.lintegral_Lp_finsum_le hf hp 29 | 30 | lemma rpow_finsetSum_le_finsetSum_rpow {p : ℝ} {ι : Type*} {I : Finset ι} {f : ι → ℝ≥0∞} 31 | (hp : 0 < p) (hp1 : p ≤ 1) : (∑ i ∈ I, f i) ^ p ≤ ∑ i ∈ I, f i ^ p := by 32 | classical 33 | induction I using Finset.induction with 34 | | empty => simpa using by bound 35 | | insert i I hi ih => simpa [Finset.sum_insert hi] using 36 | (ENNReal.rpow_add_le_add_rpow _ _ (le_of_lt hp) hp1).trans (by gcongr) 37 | 38 | end ENNReal 39 | -------------------------------------------------------------------------------- /verso/static_files/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/DoobLp.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.Auxiliary.Martingale 7 | import Mathlib.Probability.Martingale.OptionalStopping 8 | 9 | /-! # Doob's Lᵖ inequality 10 | 11 | -/ 12 | 13 | open MeasureTheory Filter Finset 14 | open scoped ENNReal NNReal 15 | 16 | namespace ProbabilityTheory 17 | 18 | variable {ι Ω E : Type*} [LinearOrder ι] [OrderBot ι] [TopologicalSpace ι] [OrderTopology ι] 19 | [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] 20 | {mΩ : MeasurableSpace Ω} {P : Measure Ω} {X : ι → Ω → E} {𝓕 : Filtration ι mΩ} 21 | {Y : ι → Ω → ℝ} 22 | 23 | theorem maximal_ineq_countable [Countable ι] [IsFiniteMeasure P] 24 | (hsub : Submartingale Y 𝓕 P) (hnonneg : 0 ≤ Y) (ε : ℝ≥0) (n : ι) : 25 | ε • P {ω | (ε : ℝ) ≤ ⨆ i ≤ n, Y i ω} ≤ 26 | ENNReal.ofReal (∫ ω in {ω | (ε : ℝ) ≤ ⨆ i ≤ n, Y i ω}, Y n ω ∂P) := by 27 | sorry 28 | 29 | theorem maximal_ineq_norm_countable [Countable ι] [IsFiniteMeasure P] 30 | (hsub : Martingale X 𝓕 P) (ε : ℝ≥0) (n : ι) : 31 | ε • P {ω | (ε : ℝ) ≤ ⨆ i ≤ n, ‖X i ω‖} ≤ 32 | ENNReal.ofReal (∫ ω in {ω | (ε : ℝ) ≤ ⨆ i ≤ n, ‖X i ω‖}, ‖X n ω‖ ∂P) := by 33 | sorry 34 | 35 | theorem maximal_ineq [SecondCountableTopology ι] [IsFiniteMeasure P] 36 | (hsub : Submartingale Y 𝓕 P) (hnonneg : 0 ≤ Y) (ε : ℝ≥0) (n : ι) : 37 | ε • P {ω | (ε : ℝ) ≤ ⨆ i ≤ n, Y i ω} ≤ 38 | ENNReal.ofReal (∫ ω in {ω | (ε : ℝ) ≤ ⨆ i ≤ n, Y i ω}, Y n ω ∂P) := by 39 | obtain ⟨T, hT_countable, hT_dense⟩ := TopologicalSpace.exists_countable_dense ι 40 | sorry 41 | 42 | theorem maximal_ineq_norm [SecondCountableTopology ι] [IsFiniteMeasure P] 43 | (hsub : Martingale X 𝓕 P) (ε : ℝ≥0) (n : ι) : 44 | ε • P {ω | (ε : ℝ) ≤ ⨆ i ≤ n, ‖X i ω‖} ≤ 45 | ENNReal.ofReal (∫ ω in {ω | (ε : ℝ) ≤ ⨆ i ≤ n, ‖X i ω‖}, ‖X n ω‖ ∂P) := by 46 | sorry 47 | 48 | end ProbabilityTheory 49 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/WithTop.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Order.Filter.AtTopBot.Basic 2 | import Mathlib.Topology.Order.WithTop 3 | 4 | open Set 5 | open scoped Topology 6 | 7 | namespace Filter 8 | 9 | variable {ι : Type*} 10 | 11 | theorem Tendsto.min_atTop_atTop {α β : Type*} 12 | [Nonempty β] [LinearOrder β] [LinearOrder α] 13 | {f g : β → α} (hf : Tendsto f atTop atTop) (hg : Tendsto g atTop atTop) : 14 | Tendsto (fun x ↦ f x ⊓ g x) atTop atTop := by 15 | rw [Filter.tendsto_atTop_atTop] at * 16 | exact fun a ↦ let ⟨b₁, hb₁⟩ := hf a; let ⟨b₂, hb₂⟩ := hg a 17 | ⟨max b₁ b₂, fun B hB ↦ le_min (hb₁ _ (max_le_iff.1 hB).1) (hb₂ _ (max_le_iff.1 hB).2)⟩ 18 | 19 | lemma _root_.WithTop.tendsto_nhds_top_iff {α : Type*} 20 | [Nonempty ι] [LinearOrder ι] [TopologicalSpace ι] [OrderTopology ι] {f : Filter α} 21 | (x : α → WithTop ι) : 22 | Tendsto x f (𝓝 ⊤) ↔ ∀ (i : ι), ∀ᶠ (a : α) in f, i < x a := by 23 | refine nhds_top_basis.tendsto_right_iff.trans ?_ 24 | simp only [Set.mem_Ioi] 25 | refine ⟨fun h i ↦ h i (by simp), fun h i hi ↦ ?_⟩ 26 | specialize h (i.untop hi.ne) 27 | filter_upwards [h] with a ha 28 | simpa using ha 29 | 30 | lemma _root_.WithTop.tendsto_atTop_nhds_top_iff {α : Type*} 31 | [Nonempty ι] [LinearOrder ι] [TopologicalSpace ι] [OrderTopology ι] 32 | [Nonempty α] [inst : Preorder α] [IsDirected α fun x1 x2 ↦ x1 ≤ x2] (x : α → WithTop ι) : 33 | Tendsto x atTop (𝓝 ⊤) ↔ ∀ (i : ι), ∃ N, ∀ n ≥ N, i < x n := by 34 | rw [WithTop.tendsto_nhds_top_iff] 35 | simp only [eventually_atTop, ge_iff_le] 36 | 37 | lemma Tendsto.tendsto_withTop_atTop_nhds_top 38 | [Nonempty ι] [LinearOrder ι] [NoMaxOrder ι] [TopologicalSpace ι] [OrderTopology ι] 39 | {a : ℕ → ι} (ha : Tendsto a atTop atTop) : 40 | Tendsto (fun n ↦ (a n : WithTop ι)) atTop (𝓝 ⊤) := by 41 | rw [WithTop.tendsto_atTop_nhds_top_iff] 42 | rw [tendsto_atTop_atTop] at ha 43 | norm_cast 44 | intro i 45 | obtain ⟨i', hi'⟩ := NoMaxOrder.exists_gt i 46 | obtain ⟨j, hj⟩ := ha i' 47 | exact ⟨j, fun n hn ↦ lt_of_lt_of_le hi' <| hj _ hn⟩ 48 | 49 | end Filter 50 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/Algebra.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.LinearAlgebra.Dimension.Finite 2 | 3 | theorem div_left_injective₀ {G₀ : Type*} [CommGroupWithZero G₀] {c : G₀} (hc : c ≠ 0) : 4 | Function.Injective fun x ↦ x / c := by 5 | intro x y hxy 6 | apply mul_eq_mul_of_div_eq_div x y hc hc at hxy 7 | exact mul_left_injective₀ hc hxy 8 | 9 | attribute [simp] Module.finrank_zero_of_subsingleton 10 | 11 | @[simp] 12 | lemma Module.finrank_ne_zero {R M : Type*} [Ring R] [AddCommGroup M] [Module R M] 13 | [StrongRankCondition R] [Module.Finite R M] [NoZeroSMulDivisors R M] [h : Nontrivial M] : 14 | finrank R M ≠ 0 := finrank_pos.ne' 15 | 16 | open Finset 17 | 18 | /-- Telescopic sum when summing over `Fin`. -/ 19 | lemma Fin.sum_Iic_sub {E : Type*} [AddCommGroup E] {n : ℕ} (a : Fin n) (f : Fin (n + 1) → E) : 20 | ∑ i ∈ Iic a, (f i.succ - f i.castSucc) = f a.succ - f 0 := by 21 | let g : Fin n → E := fun i ↦ if i ∈ Iic a then f i.succ - f i.castSucc else 0 22 | let h : ℕ → E := fun i ↦ if hi : i < n then g ⟨i, hi⟩ else 0 23 | calc 24 | _ = ∑ i, g i := by 25 | rw [Finset.sum_ite_mem, univ_inter] 26 | _ = ∑ i : Fin n, h i := by 27 | congr with i 28 | simp_rw [h, dif_pos i.2] 29 | _ = ∑ i ∈ range a.succ, h i := by 30 | rw [Fin.sum_univ_eq_sum_range] 31 | refine Finset.sum_congr_of_eq_on_inter ?_ (by grind) (by grind) 32 | simp only [mem_range, Fin.val_succ, not_lt] 33 | intro i hi1 hi2 34 | simp_rw [h, dif_pos hi1, g] 35 | rw [if_neg (by simpa)] 36 | _ = ∑ i ∈ range a.succ, (f (Fin.ofNat (n + 1) (i + 1)) - f (Fin.ofNat (n + 1) i)) := by 37 | apply Finset.sum_congr rfl 38 | simp only [Fin.val_succ, mem_range, mem_Iic, Fin.succ_mk, Fin.castSucc_mk, Fin.ofNat_eq_cast, h, 39 | g] 40 | intro i hi 41 | rw [dif_pos (by omega), if_pos] 42 | · congr 43 | · rw [Nat.mod_eq_of_lt] 44 | grind 45 | · rw [Nat.mod_eq_of_lt] 46 | grind 47 | rw [Fin.le_def] 48 | grind 49 | _ = f a.succ - f 0 := by 50 | rw [Finset.sum_range_sub (fun i ↦ f (Fin.ofNat (n + 1) i))] 51 | congr 52 | ext 53 | simp 54 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/Metric.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Analysis.Normed.Module.Ball.Pointwise 2 | import Mathlib.Order.CompletePartialOrder 3 | import Mathlib.Topology.MetricSpace.MetricSeparated 4 | 5 | open ENNReal NNReal 6 | 7 | lemma Metric.IsSeparated.disjoint_ball {E : Type*} [PseudoEMetricSpace E] {s : Set E} 8 | {ε : ℝ≥0∞} (hs : IsSeparated ε s) : s.PairwiseDisjoint (EMetric.ball · (ε / 2)) := by 9 | intro x hx y hy hxy 10 | have hxy := hs hx hy hxy 11 | by_contra! 12 | obtain ⟨z, hz1, hz2⟩ := Set.not_disjoint_iff.1 this 13 | refine lt_irrefl (edist x y) ?_ |>.elim 14 | calc 15 | edist x y ≤ edist x z + edist y z := edist_triangle_right x y z 16 | _ ≤ ε / 2 + ε / 2 := by grw [EMetric.mem_ball'.1 hz1 |>.le, EMetric.mem_ball'.1 hz2 |>.le] 17 | _ < edist x y := by rwa [ENNReal.add_halves] 18 | 19 | lemma Metric.IsSeparated.disjoint_closedBall {E : Type*} [PseudoEMetricSpace E] {s : Set E} 20 | {ε : ℝ≥0∞} (hs : IsSeparated ε s) : s.PairwiseDisjoint (EMetric.closedBall · (ε / 2)) := by 21 | intro x hx y hy hxy 22 | have hxy := hs hx hy hxy 23 | by_contra! 24 | obtain ⟨z, hz1, hz2⟩ := Set.not_disjoint_iff.1 this 25 | refine lt_irrefl (edist x y) ?_ |>.elim 26 | calc 27 | edist x y ≤ edist x z + edist y z := edist_triangle_right x y z 28 | _ ≤ ε / 2 + ε / 2 := by grw [EMetric.mem_closedBall'.1 hz1, EMetric.mem_closedBall'.1 hz2] 29 | _ < edist x y := by rwa [ENNReal.add_halves] 30 | 31 | @[simp] 32 | lemma EMetric.nonempty_closedBall {E : Type*} [PseudoEMetricSpace E] {x : E} {r : ℝ≥0∞} : 33 | (closedBall x r).Nonempty := ⟨x, mem_closedBall_self⟩ 34 | 35 | open scoped Pointwise in 36 | lemma EMetric.closedBall_add_closedBall {E : Type*} [SeminormedAddCommGroup E] [NormedSpace ℝ E] 37 | [ProperSpace E] (x y : E) (r s : ℝ≥0∞) : 38 | closedBall x r + closedBall y s = closedBall (x + y) (r + s) := by 39 | by_cases h : r = ⊤ ∨ s = ⊤ 40 | · obtain rfl | rfl := h <;> simp [nonempty_closedBall] 41 | simp only [not_or] at h 42 | lift r to ℝ≥0 using h.1 43 | lift s to ℝ≥0 using h.2 44 | norm_cast 45 | simp_rw [Metric.emetric_closedBall_nnreal] 46 | rw [_root_.closedBall_add_closedBall, NNReal.coe_add] 47 | all_goals simp 48 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/LocalMonad.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Kexing Ying. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Kexing Ying 5 | -/ 6 | import BrownianMotion.StochasticIntegral.Locally 7 | import Mathlib.MeasureTheory.Category.MeasCat 8 | import Mathlib.CategoryTheory.Category.Preorder 9 | 10 | /-! # The Local Monad on Stable Properties 11 | 12 | -/ 13 | 14 | open MeasureTheory Filter CategoryTheory Filtration 15 | open scoped ENNReal Topology 16 | 17 | namespace ProbabilityTheory 18 | 19 | variable {ι Ω E : Type*} {mΩ : MeasurableSpace Ω} {P : Measure Ω} [Zero E] 20 | [ConditionallyCompleteLinearOrderBot ι] [TopologicalSpace ι] [OrderTopology ι] 21 | {𝓕 : Filtration ι mΩ} 22 | 23 | /-- The category of stable properties. -/ 24 | abbrev StableCat (E : Type*) [Zero E] (𝓕 : Filtration ι mΩ) := 25 | ObjectProperty.FullSubcategory <| fun (p : (ι → Ω → E) → Prop) ↦ IsStable 𝓕 p 26 | 27 | /-- Local is a functor from Stable to Stable. -/ 28 | def Local (P : Measure Ω) (p : StableCat E 𝓕) : StableCat E 𝓕 := 29 | ⟨(Locally p.1 𝓕 · P), p.2.isStable_locally⟩ 30 | 31 | /-- The local functor is monotone. -/ 32 | lemma LocalMono (P : Measure Ω) {p q : StableCat E 𝓕} (h : p ⟶ q) (u : ι → Ω → E) : 33 | (Local P p).1 u ≤ (Local P q).1 u := 34 | Locally.mono <| fun v ↦ leOfHom <| h v 35 | 36 | /-- The local functor. -/ 37 | noncomputable 38 | def LocalFunctor (P : Measure Ω) : StableCat E 𝓕 ⥤ StableCat E 𝓕 where 39 | obj X := Local P X 40 | map f _ := homOfLE <| LocalMono P f _ 41 | map_id _ := rfl 42 | map_comp _ _ := rfl 43 | 44 | variable [IsFiniteMeasure P] [DenselyOrdered ι] [FirstCountableTopology ι] [NoMaxOrder ι] 45 | [SecondCountableTopology ι] 46 | 47 | /-- The Stable properties form a monad with the local functor. -/ 48 | noncomputable 49 | def StableMonad (h𝓕 : IsRightContinuous 𝓕) : 50 | Monad (StableCat E 𝓕) where 51 | toFunctor := LocalFunctor P 52 | η := { app _ _ := homOfLE locally_of_prop 53 | naturality _ _ _ := rfl } 54 | μ := { app p _ := homOfLE (locally_locally h𝓕 p.2).1 55 | naturality _ _ _ := rfl } 56 | 57 | end ProbabilityTheory 58 | -------------------------------------------------------------------------------- /home_page/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% seo %} 8 | 9 | 11 | 12 | 13 | 14 | {% if jekyll.environment == "production" %} 15 | 17 | {% else %} 18 | 19 | {% endif %} 20 | {% include head-custom.html %} 21 | 22 | 23 | 24 | Skip to the content. 25 | 26 | 38 | 39 |
40 | {{ content }} 41 | 42 | 48 |
49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /blueprint/src/chapters/debut.tex: -------------------------------------------------------------------------------- 1 | \chapter{Debut Theorem} 2 | \label{chap:debut_theorem} 3 | 4 | 5 | \begin{theorem}\label{thm:hitting_is_stopping_time} 6 | \uses{def:IsStoppingTime, def:hittingAfter, def:ProgMeasurable, def:rightContinuous} 7 | \notready 8 | If $X : T \to \Omega \to E$ is a progressively measurable process with respect to a right-continuous filtration and $B$ is a Borel-measurable subset of $E$, then the hitting time of $X$ in $B$ is a stopping time. 9 | \end{theorem} 10 | 11 | \begin{proof} 12 | \uses{lem:rightContinuous_basic} 13 | 14 | \end{proof} 15 | 16 | 17 | \section{Corollaries} 18 | 19 | TODO: need to generalize the \texttt{leastGE} definition to general index sets that are not necessarily $\mathbb{N}$. 20 | 21 | 22 | \begin{definition}\label{def:leastGE} 23 | \mathlibok 24 | \lean{MeasureTheory.leastGE} 25 | For a process $X : ι \to Ω \to ℝ$ and a real number $a$, define the random time 26 | \begin{align*} 27 | \tau_{X \ge a} = \inf\{t \in ι \mid X_t \ge a\} \: , 28 | \end{align*} 29 | in which the infimum is infinite if the set is empty. 30 | \end{definition} 31 | 32 | 33 | \begin{lemma}\label{lem:isStoppingTime_leastGE} 34 | \uses{def:IsStoppingTime, def:leastGE} 35 | If $X : ι \to Ω \to ℝ$ is a progressively measurable process with respect to a right-continuous filtration, then for any $a \in \mathbb{R}$, the random time $\tau_{X \ge a}$ is a stopping time. 36 | \end{lemma} 37 | 38 | \begin{proof} 39 | \uses{thm:hitting_is_stopping_time} 40 | This is a direct application of Theorem~\ref{thm:hitting_is_stopping_time} with the set $B = [a, +\infty)$. 41 | \end{proof} 42 | 43 | 44 | \begin{corollary}\label{cor:isStoppingTime_leastGE_of_rightContinuous} 45 | \uses{def:IsStoppingTime, def:leastGE, def:rightContinuous, def:adapted, def:RightContinuous} 46 | If $X : ι \to Ω \to ℝ$ is a right-continuous and adapted process with respect to a right-continuous filtration, then for any $a \in \mathbb{R}$, the random time $\tau_{X \ge a}$ is a stopping time. 47 | \end{corollary} 48 | 49 | \begin{proof} 50 | \uses{lem:isStoppingTime_leastGE, lem:Adapted.progMeasurable_of_rightContinuous} 51 | This follows from Lemma~\ref{lem:isStoppingTime_leastGE} since $X$ is progressively measurable by Lemma~\ref{lem:Adapted.progMeasurable_of_rightContinuous}. 52 | \end{proof} 53 | -------------------------------------------------------------------------------- /.github/workflows/blueprint.yml: -------------------------------------------------------------------------------- 1 | name: Compile blueprint 2 | 3 | on: 4 | push: 5 | branches: 6 | - master # Trigger on pushes to the default branch 7 | pull_request: 8 | branches: 9 | - master 10 | workflow_dispatch: # Allow manual triggering of the workflow from the GitHub Actions interface 11 | 12 | # Cancel previous runs if a new commit is pushed to the same PR or branch 13 | concurrency: 14 | group: ${{ github.ref }} # Group runs by the ref (branch or PR) 15 | cancel-in-progress: true # Cancel any ongoing runs in the same group 16 | 17 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 18 | permissions: 19 | contents: read # Read access to repository contents 20 | pages: write # Write access to GitHub Pages 21 | id-token: write # Write access to ID tokens 22 | 23 | jobs: 24 | build_project: 25 | runs-on: ubuntu-latest 26 | name: Build project 27 | steps: 28 | - name: Cleanup to free disk space 29 | uses: jlumbroso/free-disk-space@main 30 | with: 31 | # this might remove tools that are actually needed, 32 | # if set to "true" but frees about 6 GB 33 | tool-cache: false 34 | # all of these default to true, but feel free to set to 35 | # "false" if necessary for your workflow 36 | android: true 37 | dotnet: false 38 | haskell: false 39 | large-packages: false 40 | docker-images: false 41 | swap-storage: false 42 | 43 | - name: Checkout project 44 | uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 45 | with: 46 | fetch-depth: 0 # Fetch all history for all branches and tags 47 | 48 | - name: Build and lint project 49 | uses: leanprover/lean-action@434f25c2f80ded67bba02502ad3a86f25db50709 # 2025-07-02 50 | with: 51 | build: true 52 | lint: true 53 | mk_all-check: true 54 | 55 | - name: Build Verso Documentation 56 | run: | 57 | cd verso 58 | ./build_manual.sh 59 | 60 | - name: Compile blueprint and documentation 61 | uses: leanprover-community/docgen-action@deed0cdc44dd8e5de07a300773eb751d33e32fc8 # 2025-10-26 62 | with: 63 | blueprint: true 64 | homepage: home_page 65 | -------------------------------------------------------------------------------- /BrownianMotion/Gaussian/StochasticProcesses.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.MeasureTheory.Measure.MeasureSpaceDef 2 | 3 | open MeasureTheory 4 | 5 | variable {T Ω E : Type*} {mΩ : MeasurableSpace Ω} {P : Measure Ω} 6 | {X Y : T → Ω → E} 7 | 8 | lemma modification_of_indistinguishable (h : ∀ᵐ ω ∂P, ∀ t, X t ω = Y t ω) : 9 | ∀ t, X t =ᵐ[P] Y t := by 10 | intro t 11 | filter_upwards [h] with ω hω using hω t 12 | 13 | open TopologicalSpace in 14 | lemma indistinguishable_of_modification [TopologicalSpace E] [TopologicalSpace T] 15 | [SeparableSpace T] [T2Space E] 16 | (hX : ∀ᵐ ω ∂P, Continuous fun t ↦ X t ω) (hY : ∀ᵐ ω ∂P, Continuous fun t ↦ Y t ω) 17 | (h : ∀ t, X t =ᵐ[P] Y t) : 18 | ∀ᵐ ω ∂P, ∀ t, X t ω = Y t ω := by 19 | let ⟨D, D_countable, D_dense⟩ := ‹SeparableSpace T› 20 | have eq (ht : ∀ t ∈ D, X t =ᵐ[P] Y t) : ∀ᵐ ω ∂P, ∀ t ∈ D, X t ω = Y t ω := 21 | (ae_ball_iff D_countable).mpr ht 22 | filter_upwards [hX, hY, eq (fun t ht ↦ h t)] with ω hX hY h t 23 | change (fun t ↦ X t ω) t = (fun t ↦ Y t ω) t 24 | rw [Continuous.ext_on D_dense hX hY h] 25 | 26 | open scoped Topology in 27 | lemma subset_closure_dense_inter {α : Type*} [TopologicalSpace α] {T' U : Set α} 28 | (hT'_dense : Dense T') (hU : IsOpen U) : 29 | U ⊆ closure (T' ∩ U) := by 30 | refine fun x hxU ↦ mem_closure_iff_nhds.mpr fun t ht ↦ ?_ 31 | have htU : t ∩ U ∈ 𝓝 x := by simp [ht, hU.mem_nhds hxU] 32 | suffices (T' ∩ (t ∩ U)).Nonempty by grind 33 | exact hT'_dense.inter_nhds_nonempty htU 34 | 35 | open TopologicalSpace in 36 | lemma indistinguishable_of_modification_on [TopologicalSpace E] [TopologicalSpace T] 37 | [SeparableSpace T] [T2Space E] {U : Set T} (hU : IsOpen U) 38 | (hX : ∀ᵐ ω ∂P, ContinuousOn (X · ω) U) (hY : ∀ᵐ ω ∂P, ContinuousOn (Y · ω) U) 39 | (h : ∀ t ∈ U, X t =ᵐ[P] Y t) : 40 | ∀ᵐ ω ∂P, ∀ t ∈ U, X t ω = Y t ω := by 41 | let ⟨D, D_countable, D_dense⟩ := ‹SeparableSpace T› 42 | have DU_countable : (D ∩ U).Countable := D_countable.mono Set.inter_subset_left 43 | have eq (ht : ∀ t ∈ (D ∩ U), X t =ᵐ[P] Y t) : ∀ᵐ ω ∂P, ∀ t ∈ (D ∩ U), X t ω = Y t ω := 44 | (ae_ball_iff DU_countable).mpr ht 45 | filter_upwards [hX, hY, eq (fun t ht ↦ h t ht.2)] with ω hX hY h t htU 46 | suffices Set.EqOn (X · ω) (Y · ω) U from this htU 47 | refine Set.EqOn.of_subset_closure h hX hY Set.inter_subset_right ?_ 48 | exact subset_closure_dense_inter D_dense hU 49 | -------------------------------------------------------------------------------- /blueprint/src/content.tex: -------------------------------------------------------------------------------- 1 | % In this file you should put the actual content of the blueprint. 2 | % It will be used both by the web and the print version. 3 | % It should *not* include the \begin{document} 4 | % 5 | % If you want to split the blueprint content into several files then 6 | % the current file can be a simple sequence of \input. Otherwise It 7 | % can start with a \section or \chapter for instance. 8 | 9 | \part{Brownian motion} 10 | 11 | \textbf{Overview} 12 | 13 | This part of the blueprint is a guide to the formalization of a standard Brownian motion in Lean using Mathlib. There are two main parts to this formalization: 14 | \begin{itemize} 15 | \item a development of the theory of Gaussian distributions, the construction of a projective family of Gaussian distributions and its projective limit by the Kolmogorov extension theorem, 16 | \item a proof of a Kolmogorov-Chentsov continuity theorem, following \cite{kratschmer2023kolmogorov}. 17 | \end{itemize} 18 | 19 | Putting the two sides together, we then build a stochastic process that fits the definition of a Brownian motion on the real line. 20 | 21 | \textbf{Status} The formalization is complete. 22 | 23 | \textbf{Blueprint authors} Rémy Degenne, Peter Pfaffelhuber. 24 | 25 | \textbf{Formalization authors} Rémy Degenne, Markus Himmel, David Ledvinka, Etienne Marion, Peter Pfaffelhuber. 26 | 27 | With additional contributions from Jonas Bayer, Lorenzo Loccioli, Pietro Monticone, Alessio Rondelli and Jérémy Scanvic. 28 | 29 | \input{chapters/characteristic_function.tex} 30 | \input{chapters/process.tex} 31 | \input{chapters/gaussian.tex} 32 | \input{chapters/projective_family.tex} 33 | \input{chapters/kolmogorov_chentsov.tex} 34 | \input{chapters/brownian.tex} 35 | 36 | \putbib 37 | 38 | \part{Stochastic integral} 39 | 40 | \textbf{Overview} 41 | 42 | We describe the construction of a stochastic integral. 43 | 44 | \textbf{Status} The formalization is ongoing. 45 | 46 | \textbf{Blueprint authors} Rémy Degenne, Lorenzo Luccioli, Etienne Marion, Alessio Rondelli, Kexing Ying. Anyone is welcome to contribute! 47 | 48 | \textbf{Formalization authors} Anyone is welcome to contribute! 49 | 50 | \input{chapters/filtration_martingale.tex} 51 | \input{chapters/debut.tex} 52 | \input{chapters/local_martingales.tex} 53 | \input{chapters/elementary.tex} 54 | \input{chapters/cadlag.tex} 55 | \input{chapters/doob_meyer.tex} 56 | \input{chapters/stochastic_integral.tex} 57 | 58 | \putbib 59 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/ENNReal.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Analysis.SpecialFunctions.Pow.NNReal 2 | import Mathlib.Data.ENat.Lattice 3 | import Mathlib.Data.Real.ENatENNReal 4 | import Mathlib.Order.CompletePartialOrder 5 | 6 | open ENNReal NNReal 7 | 8 | namespace ENNReal 9 | 10 | lemma sum_geometric_two_le (n : ℕ) : ∑ i ∈ Finset.range n, ((1 : ENNReal) / 2) ^ i ≤ 2 := by 11 | rw [← ENNReal.toReal_le_toReal (by simp) (by simp), toReal_ofNat, toReal_sum (by simp)] 12 | simpa [-one_div] using _root_.sum_geometric_two_le _ 13 | 14 | lemma ofReal_one_div {x : ℝ} (hx : 0 < x) : 15 | ENNReal.ofReal (1 / x) = 1 / (ENNReal.ofReal x) := by 16 | rwa [ENNReal.ofReal_div_of_pos, ofReal_one] 17 | 18 | lemma le_one_div_iff {x y : ℝ≥0∞} : x ≤ 1 / y ↔ y ≤ 1 / x := by 19 | rw [ENNReal.le_div_iff_mul_le, ENNReal.le_div_iff_mul_le, mul_comm] 20 | all_goals simp 21 | 22 | lemma div_le_one_of_le {x y : ℝ≥0∞} (h : x ≤ y) : x / y ≤ 1 := by 23 | obtain rfl | h1 := eq_or_ne y 0 24 | · simp_all 25 | obtain rfl | h2 := eq_or_ne y ∞ 26 | · simp 27 | rwa [ENNReal.div_le_iff h1 h2, one_mul] 28 | 29 | lemma one_le_toReal {p : ℝ≥0∞} (hp1 : 1 ≤ p) (hp2 : p ≠ ⊤) : 1 ≤ p.toReal := by 30 | calc 31 | 1 = (1 : ℝ≥0∞).toReal := rfl 32 | _ ≤ p.toReal := by rwa [ENNReal.toReal_le_toReal (by simp) hp2] 33 | 34 | lemma toReal_pos_of_one_le {p : ℝ≥0∞} (hp1 : 1 ≤ p) (hp2 : p ≠ ⊤) : 0 < p.toReal := 35 | LT.lt.trans_le (by simp) (one_le_toReal hp1 hp2) 36 | 37 | end ENNReal 38 | 39 | @[norm_cast] 40 | lemma ENat.toENNReal_iSup {ι : Sort*} (f : ι → ℕ∞) : ⨆ i, f i = ⨆ i, (f i : ℝ≥0∞) := by 41 | refine eq_of_forall_ge_iff fun c ↦ ⟨fun h ↦ ?_, fun h ↦ ?_⟩ 42 | · exact iSup_le fun i ↦ le_trans (ENat.toENNReal_le.2 (le_iSup f i)) h 43 | · obtain rfl | hc := eq_or_ne c ⊤ 44 | · exact le_top 45 | lift c to ℝ≥0 using hc 46 | have (i : ι) : f i ≤ Nat.floor c := by 47 | have := (le_iSup _ i).trans h 48 | have h' : f i ≠ ⊤ := by 49 | rw [← ENat.toENNReal_ne_top] 50 | exact this.trans_lt ENNReal.coe_lt_top |>.ne 51 | lift f i to ℕ using h' with k 52 | norm_cast 53 | change ((k : ℝ≥0) : ℝ≥0∞) ≤ c at this 54 | exact Nat.le_floor_iff (zero_le _) |>.2 <| ENNReal.coe_le_coe.1 this 55 | calc 56 | (↑(⨆ i, f i) : ℝ≥0∞) ≤ Nat.floor c := by 57 | change (↑(⨆ i, f i) : ℝ≥0∞) ≤ ((Nat.floor c : ENat) : ℝ≥0∞) 58 | exact ENat.toENNReal_le.2 (iSup_le this) 59 | _ ≤ c := by norm_cast; exact Nat.floor_le (zero_le _) 60 | 61 | @[gcongr] 62 | alias ⟨_, ENat.toENNReal_le'⟩ := ENat.toENNReal_le 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lean formalization of Brownian motion and stochastic integrals 2 | 3 | This is an open, collaborative project with the goal of formalizing stochastic processes and stochastic integration in Lean. 4 | There are currently two main parts: 5 | 6 | * A formalization of Brownian motion, which is now complete. That task needed a development of the theory of Gaussian distributions, the construction of a projective family of Gaussian distributions and its projective limit by the Kolmogorov extension theorem, and a proof of a Kolmogorov-Chentsov continuity theorem. 7 | 8 | * A definition of stochastic integrals and proof of Ito's lemma. This is in progress. 9 | 10 | For more information, see [the project home page](https://remydegenne.github.io/brownian-motion/), in particular the [blueprint](https://remydegenne.github.io/brownian-motion/blueprint/). 11 | 12 | 13 | ### Brownian motion 14 | 15 | We now have a full implementation of a Brownian motion on the positive real half line, and are in the process of migrating our results to Mathlib. 16 | See [that page](https://remydegenne.github.io/brownian-motion/verso/) for a brief overview of the results. 17 | 18 | We also have a preprint, available at [https://arxiv.org/pdf/2511.20118](https://arxiv.org/pdf/2511.20118). To cite our work on Brownian motion, please use the following BibTex entry: 19 | ``` 20 | @article{degenne2025formalization, 21 | title={Formalization of Brownian motion in Lean}, 22 | author={Degenne, R{\'e}my and Ledvinka, David and Marion, Etienne and Pfaffelhuber, Peter}, 23 | journal={arXiv preprint arXiv:2511.20118}, 24 | year={2025} 25 | } 26 | ``` 27 | 28 | 29 | ### Stochastic integrals 30 | 31 | We are now building the necessary theory to define the integral against a semi-martingale, with the goal to then prove Ito's lemma. 32 | See this Zulip channel for discussion: [zulip link](https://leanprover.zulipchat.com/#narrow/channel/509433-Brownian-motion) 33 | 34 | If you want to get involved, you can look at [the open issues](https://github.com/RemyDegenne/brownian-motion/issues). Please read the CONTRIBUTING file to learn how to claim an issue. 35 | To see what we will need and where we are going, you can refer to the [blueprint](https://remydegenne.github.io/brownian-motion/blueprint/index.html), which we gradually refine alongside the Lean code. 36 | 37 | 38 | ### Acknowledgements 39 | 40 | Our github project uses the [Leanblueprint](https://github.com/PatrickMassot/leanblueprint) tool by Patrick Massot and a lot of code from the [LeanProject](https://github.com/pitmonticone/LeanProject) template by Pietro Monticone. 41 | -------------------------------------------------------------------------------- /BrownianMotion.lean: -------------------------------------------------------------------------------- 1 | import BrownianMotion.Auxiliary.Adapted 2 | import BrownianMotion.Auxiliary.Algebra 3 | import BrownianMotion.Auxiliary.Analysis 4 | import BrownianMotion.Auxiliary.ContinuousBilinForm 5 | import BrownianMotion.Auxiliary.ENNReal 6 | import BrownianMotion.Auxiliary.FiniteInf 7 | import BrownianMotion.Auxiliary.HasGaussianLaw 8 | import BrownianMotion.Auxiliary.HasLaw 9 | import BrownianMotion.Auxiliary.IsStoppingTime 10 | import BrownianMotion.Auxiliary.Jensen 11 | import BrownianMotion.Auxiliary.LinearAlgebra 12 | import BrownianMotion.Auxiliary.Martingale 13 | import BrownianMotion.Auxiliary.MeanInequalities 14 | import BrownianMotion.Auxiliary.MeasureTheory 15 | import BrownianMotion.Auxiliary.Metric 16 | import BrownianMotion.Auxiliary.NNReal 17 | import BrownianMotion.Auxiliary.Nat 18 | import BrownianMotion.Auxiliary.Real 19 | import BrownianMotion.Auxiliary.StoppedProcess 20 | import BrownianMotion.Auxiliary.Topology 21 | import BrownianMotion.Auxiliary.WithLp 22 | import BrownianMotion.Auxiliary.WithTop 23 | import BrownianMotion.Continuity.Chaining 24 | import BrownianMotion.Continuity.CoveringNumber 25 | import BrownianMotion.Continuity.HasBoundedInternalCoveringNumber 26 | import BrownianMotion.Continuity.IsKolmogorovProcess 27 | import BrownianMotion.Continuity.KolmogorovChentsov 28 | import BrownianMotion.Continuity.KolmogorovChentsovInequality 29 | import BrownianMotion.Gaussian.BrownianMotion 30 | import BrownianMotion.Gaussian.CovMatrix 31 | import BrownianMotion.Gaussian.Fernique 32 | import BrownianMotion.Gaussian.Gaussian 33 | import BrownianMotion.Gaussian.GaussianProcess 34 | import BrownianMotion.Gaussian.Moment 35 | import BrownianMotion.Gaussian.MultivariateGaussian 36 | import BrownianMotion.Gaussian.ProjectiveLimit 37 | import BrownianMotion.Gaussian.StochasticProcesses 38 | import BrownianMotion.StochasticIntegral.ApproxSeq 39 | import BrownianMotion.StochasticIntegral.Cadlag 40 | import BrownianMotion.StochasticIntegral.Centering 41 | import BrownianMotion.StochasticIntegral.ClassD 42 | import BrownianMotion.StochasticIntegral.DoobLp 43 | import BrownianMotion.StochasticIntegral.DoobMeyer 44 | import BrownianMotion.StochasticIntegral.Komlos 45 | import BrownianMotion.StochasticIntegral.L2M 46 | import BrownianMotion.StochasticIntegral.LocalMartingale 47 | import BrownianMotion.StochasticIntegral.LocalMonad 48 | import BrownianMotion.StochasticIntegral.Locally 49 | import BrownianMotion.StochasticIntegral.MathlibImports 50 | import BrownianMotion.StochasticIntegral.OptionalSampling 51 | import BrownianMotion.StochasticIntegral.Predictable 52 | import BrownianMotion.StochasticIntegral.QuadraticVariation 53 | import BrownianMotion.StochasticIntegral.SimpleProcess 54 | import BrownianMotion.StochasticIntegral.SquareIntegrable 55 | import BrownianMotion.StochasticIntegral.UniformIntegrable 56 | import BrownianMotion.Verso.Brownian 57 | import BrownianMotion.Verso.Processes 58 | -------------------------------------------------------------------------------- /blueprint/src/bib.bib: -------------------------------------------------------------------------------- 1 | @Article{ hairer2009introduction, 2 | title = {An introduction to stochastic PDEs}, 3 | author = {Hairer, Martin}, 4 | journal = {arXiv preprint arXiv:0907.4178}, 5 | year = {2009} 6 | } 7 | 8 | @article{kratschmer2023kolmogorov, 9 | title={A Kolmogorov--Chentsov type theorem on general metric spaces with applications to limit theorems for Banach-valued processes}, 10 | author={Kr{\"a}tschmer, Volker and Urusov, Mikhail}, 11 | journal={Journal of Theoretical Probability}, 12 | volume={36}, 13 | number={3}, 14 | pages={1454--1486}, 15 | year={2023}, 16 | publisher={Springer} 17 | } 18 | 19 | @book{talagrand2022upper, 20 | title={Upper and lower bounds for stochastic processes: decomposition theorems}, 21 | author={Talagrand, Michel}, 22 | volume={60}, 23 | year={2022}, 24 | publisher={Springer Nature} 25 | } 26 | 27 | @Book{ kallenberg2021, 28 | author = {Kallenberg, Olav}, 29 | title = {Foundations of modern probability}, 30 | series = {Probability Theory and Stochastic Modelling}, 31 | volume = {99}, 32 | publisher = {Springer Nature Switzerland}, 33 | edition = {Third Edition}, 34 | year = {2021}, 35 | pages = {193}, 36 | isbn = {978-3-030-61870-4; 978-3-030-61871-1}, 37 | doi = {10.1007/978-3-030-61871-1}, 38 | url = {https://doi.org/10.1007/978-3-030-61871-1} 39 | } 40 | 41 | @article{Beiglböck_Schachermayer_Veliyev_2012, 42 | title={A short proof of the Doob–Meyer theorem}, 43 | volume={122}, 44 | ISSN={0304-4149}, 45 | DOI={10.1016/j.spa.2011.12.001}, 46 | abstractNote={Every submartingale S of class D has a unique Doob–Meyer decomposition S=M+A, where M is a martingale and A is a predictable increasing process starting at 0. We provide a short proof of the Doob–Meyer decomposition theorem. Several previously known arguments are included to keep the paper self-contained.}, 47 | number={4}, 48 | journal={Stochastic Processes and their Applications}, 49 | author={Beiglböck, Mathias and Schachermayer, Walter and Veliyev, Bezirgen}, 50 | year={2012}, month=apr, pages={1204–1209} } 51 | 52 | @book{pascucci2024, 53 | address={Cham}, 54 | series={UNITEXT}, 55 | title={Probability Theory II: Stochastic Calculus}, 56 | volume={166}, 57 | rights={https://www.springernature.com/gp/researchers/text-and-data-mining}, 58 | ISBN={978-3-031-63192-4}, 59 | url={https://link.springer.com/10.1007/978-3-031-63193-1}, 60 | DOI={10.1007/978-3-031-63193-1}, 61 | publisher={Springer Nature Switzerland}, 62 | author={Pascucci, Andrea}, 63 | year={2024}, 64 | collection={UNITEXT}, 65 | language={en} } 66 | 67 | @misc{almostsuremath, 68 | author = {Lowther, George}, 69 | title = {Almost Sure - A random mathematical blog}, 70 | url = {https://almostsuremath.com}, 71 | note = {Accessed: 2025-09-14} 72 | } 73 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/FiniteInf.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Data.Finset.Max 2 | import Mathlib.Data.Set.Finite.Lattice 3 | import Mathlib.Order.CompletePartialOrder 4 | import Mathlib.Order.ConditionallyCompleteLattice.Indexed 5 | 6 | variable {α ι : Type*} [CompleteLinearOrder α] 7 | 8 | -- Move those next to the ciInf/ciSup versions 9 | 10 | theorem Finset.Nonempty.sSup_eq_max' {s : Finset α} (h : s.Nonempty) : sSup ↑s = s.max' h := 11 | eq_of_forall_ge_iff fun _ => (csSup_le_iff s.bddAbove h.to_set).trans (s.max'_le_iff h).symm 12 | 13 | theorem Finset.iSup_eq_max'_image (f : ι → α) {s : Finset ι} (h : s.Nonempty) 14 | (h' : (s.image f).Nonempty := by simpa using h) : 15 | ⨆ i ∈ s, f i = (s.image f).max' h' := by 16 | classical 17 | rw [iSup, ← h'.sSup_eq_max', coe_image] 18 | refine csSup_eq_csSup_of_forall_exists_le ?_ ?_ 19 | · simp only [Set.mem_range, Set.mem_image, mem_coe, exists_exists_and_eq_and, 20 | forall_exists_index, forall_apply_eq_imp_iff, iSup_le_iff] 21 | intro i 22 | by_cases his : i ∈ s 23 | · exact ⟨i, by assumption, fun _ ↦ le_rfl⟩ 24 | · simpa [his] using h 25 | · simp only [Set.mem_image, mem_coe, Set.mem_range, exists_exists_eq_and, forall_exists_index, 26 | and_imp, forall_apply_eq_imp_iff₂] 27 | intro i hi 28 | refine ⟨i, ?_⟩ 29 | simp [hi] 30 | 31 | theorem Finset.iInf_eq_min'_image (f : ι → α) {s : Finset ι} (h : s.Nonempty) 32 | (h' : (s.image f).Nonempty := by simpa using h) : 33 | ⨅ i ∈ s, f i = (s.image f).min' h' := by 34 | classical 35 | rw [← OrderDual.toDual_inj, toDual_min', toDual_iInf] 36 | simp only [toDual_iInf] 37 | rw [iSup_eq_max'_image _ h] 38 | simp only [image_image] 39 | congr 40 | 41 | theorem Finset.iInf_mem_image (f : ι → α) {s : Finset ι} (h : s.Nonempty) : 42 | ⨅ i ∈ s, f i ∈ s.image f := by 43 | rw [iInf_eq_min'_image _ h] 44 | exact min'_mem (image f s) _ 45 | 46 | theorem Set.Finite.iInf_mem_image (f : ι → α) {s : Set ι} (h : s.Nonempty) (hs : s.Finite) : 47 | ⨅ i ∈ s, f i ∈ f '' s := by 48 | lift s to Finset ι using hs 49 | simpa using Finset.iInf_mem_image f h 50 | 51 | theorem Set.Finite.lt_iInf_iff {s : Set ι} {f : ι → α} (h : s.Nonempty) (hs : s.Finite) {a : α} : 52 | a < ⨅ i ∈ s, f i ↔ ∀ x ∈ s, a < f x := by 53 | constructor 54 | · intro h x hx 55 | refine h.trans_le (csInf_le ?_ ?_) 56 | · classical 57 | refine (((hs.image f).union (finite_singleton (sInf ∅))).subset ?_).bddBelow 58 | intro 59 | simp only [ciInf_eq_ite, dite_eq_ite, mem_range, union_singleton, mem_insert_iff, mem_image, 60 | forall_exists_index] 61 | intro x hx 62 | split_ifs at hx 63 | · exact Or.inr ⟨_, by assumption, hx⟩ 64 | · simp_all 65 | · simp only [mem_range] 66 | refine ⟨x, ?_⟩ 67 | simp [hx] 68 | · intro H 69 | have := hs.iInf_mem_image f h 70 | simp only [mem_image] at this 71 | obtain ⟨_, hmem, hx⟩ := this 72 | rw [← hx] 73 | exact H _ hmem 74 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/Martingale.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne, Thomas Zhu 5 | -/ 6 | import BrownianMotion.Auxiliary.Jensen 7 | import Mathlib.Probability.Martingale.Basic 8 | 9 | /-! # Properties of martingales and submartingales 10 | -/ 11 | 12 | namespace MeasureTheory 13 | 14 | section 15 | 16 | variable {ι Ω E : Type*} [Preorder ι] [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] 17 | {mΩ : MeasurableSpace Ω} {P : Measure Ω} {X Y : ι → Ω → E} {𝓕 : Filtration ι mΩ} 18 | 19 | lemma Martingale.congr (hX : Martingale X 𝓕 P) (hY : Adapted 𝓕 Y) (h_eq : ∀ t, X t =ᵐ[P] Y t) : 20 | Martingale Y 𝓕 P := by 21 | refine ⟨hY, fun i j hij ↦ ?_⟩ 22 | calc 23 | P[Y j | 𝓕 i] =ᵐ[P] P[X j | 𝓕 i] := (condExp_congr_ae (h_eq j)).symm 24 | _ =ᵐ[P] Y i := (hX.2 i j hij).trans (h_eq i) 25 | 26 | lemma Submartingale.congr [LE E] (hX : Submartingale X 𝓕 P) (hY : Adapted 𝓕 Y) 27 | (h_eq : ∀ t, X t =ᵐ[P] Y t) : 28 | Submartingale Y 𝓕 P := by 29 | refine ⟨hY, ?_, ?_⟩ 30 | · intro i j hij 31 | have hcond : P[X j | 𝓕 i] =ᵐ[P] P[Y j | 𝓕 i] := condExp_congr_ae (h_eq j) 32 | exact (Filter.eventuallyLE_congr (h_eq i) hcond).mp (ae_le_condExp hX hij) 33 | · exact fun i ↦ (integrable_congr (h_eq i)).mp (hX.integrable i) 34 | 35 | lemma Martingale.indicator [OrderBot ι] {s : Set Ω} 36 | (hX : Martingale X 𝓕 P) (hs : MeasurableSet[𝓕 ⊥] s) : 37 | Martingale (fun t ↦ s.indicator (X t)) 𝓕 P := 38 | ⟨fun i ↦ (hX.adapted i).indicator (𝓕.mono bot_le _ hs), fun i j hij ↦ 39 | (condExp_indicator (hX.integrable _) (𝓕.mono bot_le _ hs)).trans (hX.2 i j hij).indicator⟩ 40 | 41 | end 42 | 43 | variable {ι Ω E : Type*} [LinearOrder ι] [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] 44 | {mΩ : MeasurableSpace Ω} {P : Measure Ω} [SigmaFinite P] {X Y : ι → Ω → E} {𝓕 : Filtration ι mΩ} 45 | 46 | lemma Martingale.submartingale_convex_comp (hX : Martingale X 𝓕 P) {φ : E → ℝ} 47 | (hφ_cvx : ConvexOn ℝ Set.univ φ) (hφ_cont : Continuous φ) 48 | (hφ_int : ∀ t, Integrable (fun ω ↦ φ (X t ω)) P) : 49 | Submartingale (fun t ω ↦ φ (X t ω)) 𝓕 P := by 50 | refine ⟨fun i ↦ hφ_cont.comp_stronglyMeasurable (hX.adapted i), fun i j hij ↦ ?_, hφ_int⟩ 51 | calc 52 | _ =ᵐ[P] fun ω ↦ φ (P[X j | 𝓕 i] ω) := hX.condExp_ae_eq hij |>.fun_comp φ |>.symm 53 | _ ≤ᵐ[P] P[fun ω ↦ φ (X j ω) | 𝓕 i] := 54 | conditional_jensen (𝓕.le i) hφ_cvx hφ_cont.lowerSemicontinuous (hX.integrable j) (hφ_int j) 55 | 56 | lemma Martingale.submartingale_norm (hX : Martingale X 𝓕 P) : 57 | Submartingale (fun t ω ↦ ‖X t ω‖) 𝓕 P := 58 | hX.submartingale_convex_comp convexOn_univ_norm continuous_norm fun i ↦ (hX.integrable i).norm 59 | 60 | lemma Submartingale.monotone_convex_comp [Preorder E] (hX : Submartingale X 𝓕 P) {φ : E → ℝ} 61 | (hφ_mono : Monotone φ) (hφ_cvx : ConvexOn ℝ Set.univ φ) (hφ_cont : Continuous φ) 62 | (hφ_int : ∀ t, Integrable (fun ω ↦ φ (X t ω)) P) : 63 | Submartingale (fun t ω ↦ φ (X t ω)) 𝓕 P := by 64 | refine ⟨fun i ↦ hφ_cont.comp_stronglyMeasurable (hX.adapted i), fun i j hij ↦ ?_, hφ_int⟩ 65 | calc 66 | _ ≤ᵐ[P] fun ω ↦ φ (P[X j | 𝓕 i] ω) := (hX.ae_le_condExp hij).mono fun ω hω ↦ hφ_mono hω 67 | _ ≤ᵐ[P] P[fun ω ↦ φ (X j ω) | 𝓕 i] := 68 | conditional_jensen (𝓕.le i) hφ_cvx hφ_cont.lowerSemicontinuous (hX.integrable j) (hφ_int j) 69 | 70 | end MeasureTheory 71 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/DoobMeyer.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.StochasticIntegral.Cadlag 7 | import BrownianMotion.StochasticIntegral.ClassD 8 | import BrownianMotion.StochasticIntegral.LocalMartingale 9 | 10 | /-! # Doob-Meyer decomposition theorem 11 | 12 | -/ 13 | 14 | open MeasureTheory Filter 15 | open scoped ENNReal 16 | 17 | namespace ProbabilityTheory 18 | 19 | variable {ι Ω : Type*} [LinearOrder ι] [OrderBot ι] [TopologicalSpace ι] [OrderTopology ι] 20 | {mΩ : MeasurableSpace Ω} {P : Measure Ω} {X : ι → Ω → ℝ} {𝓕 : Filtration ι mΩ} 21 | [MeasurableSpace ι] 22 | namespace IsLocalSubmartingale 23 | 24 | -- the sorry is locally integrable 25 | theorem doob_meyer (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 26 | ∃ (M A : ι → Ω → ℝ), X = M + A ∧ IsLocalMartingale M 𝓕 P ∧ (∀ ω, IsCadlag (M · ω)) ∧ 27 | IsPredictable 𝓕 A ∧ (∀ ω, IsCadlag (A · ω)) ∧ (HasLocallyIntegrableSup A 𝓕 P) 28 | ∧ (∀ ω, Monotone (A · ω)) := by 29 | sorry 30 | 31 | /-- The local martingale part of the Doob-Meyer decomposition of the local submartingale. -/ 32 | noncomputable 33 | def martingalePart (X : ι → Ω → ℝ) 34 | (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 35 | ι → Ω → ℝ := 36 | (hX.doob_meyer hX_cadlag).choose 37 | 38 | /-- The predictable part of the Doob-Meyer decomposition of the local submartingale. -/ 39 | noncomputable 40 | def predictablePart (X : ι → Ω → ℝ) 41 | (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 42 | ι → Ω → ℝ := 43 | (hX.doob_meyer hX_cadlag).choose_spec.choose 44 | 45 | lemma martingalePart_add_predictablePart 46 | (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 47 | X = hX.martingalePart X hX_cadlag + hX.predictablePart X hX_cadlag := 48 | (hX.doob_meyer hX_cadlag).choose_spec.choose_spec.1 49 | 50 | lemma isLocalMartingale_martingalePart 51 | (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 52 | IsLocalMartingale (hX.martingalePart X hX_cadlag) 𝓕 P := 53 | (hX.doob_meyer hX_cadlag).choose_spec.choose_spec.2.1 54 | 55 | lemma cadlag_martingalePart (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 56 | ∀ ω, IsCadlag (hX.martingalePart X hX_cadlag · ω) := 57 | (hX.doob_meyer hX_cadlag).choose_spec.choose_spec.2.2.1 58 | 59 | lemma isPredictable_predictablePart 60 | (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 61 | IsPredictable 𝓕 (hX.predictablePart X hX_cadlag) := 62 | (hX.doob_meyer hX_cadlag).choose_spec.choose_spec.2.2.2.1 63 | 64 | lemma cadlag_predictablePart (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 65 | ∀ ω, IsCadlag (hX.predictablePart X hX_cadlag · ω) := 66 | (hX.doob_meyer hX_cadlag).choose_spec.choose_spec.2.2.2.2.1 67 | 68 | lemma hasLocallyIntegrableSup_predictablePart 69 | (hX : IsLocalSubmartingale X 𝓕 P) (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 70 | HasLocallyIntegrableSup (hX.predictablePart X hX_cadlag) 𝓕 P := 71 | (hX.doob_meyer hX_cadlag).choose_spec.choose_spec.2.2.2.2.2.1 72 | 73 | lemma monotone_predictablePart (hX : IsLocalSubmartingale X 𝓕 P) 74 | (hX_cadlag : ∀ ω, IsCadlag (X · ω)) : 75 | ∀ ω, Monotone (hX.predictablePart X hX_cadlag · ω) := 76 | (hX.doob_meyer hX_cadlag).choose_spec.choose_spec.2.2.2.2.2.2 77 | 78 | end IsLocalSubmartingale 79 | 80 | end ProbabilityTheory 81 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/LocalMartingale.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.StochasticIntegral.Locally 7 | import BrownianMotion.StochasticIntegral.OptionalSampling 8 | import Mathlib.Probability.Martingale.Basic 9 | import BrownianMotion.Auxiliary.Martingale 10 | 11 | /-! # Local (sub)martingales 12 | 13 | -/ 14 | 15 | open MeasureTheory Filter TopologicalSpace Function 16 | open scoped ENNReal 17 | 18 | namespace ProbabilityTheory 19 | 20 | variable {ι Ω E : Type*} [LinearOrder ι] [OrderBot ι] [TopologicalSpace ι] [OrderTopology ι] 21 | [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] 22 | {mΩ : MeasurableSpace Ω} {P : Measure Ω} {X : ι → Ω → E} {𝓕 : Filtration ι mΩ} 23 | 24 | /-- A stochastic process is a local martingale if it satisfies the martingale property locally. -/ 25 | def IsLocalMartingale (X : ι → Ω → E) (𝓕 : Filtration ι mΩ) (P : Measure Ω := by volume_tac) : 26 | Prop := 27 | Locally (fun X ↦ Martingale X 𝓕 P ∧ ∀ ω, IsCadlag (X · ω)) 𝓕 X P 28 | 29 | /-- A stochastic process is a local submartingale if it satisfies the submartingale property 30 | locally. -/ 31 | def IsLocalSubmartingale [LE E] (X : ι → Ω → E) (𝓕 : Filtration ι mΩ) 32 | (P : Measure Ω := by volume_tac) : Prop := 33 | Locally (fun X ↦ Submartingale X 𝓕 P ∧ ∀ ω, IsCadlag (X · ω)) 𝓕 X P 34 | 35 | lemma Martingale.IsLocalMartingale (hX : Martingale X 𝓕 P) (hC : ∀ ω, IsCadlag (X · ω)) : 36 | IsLocalMartingale X 𝓕 P := 37 | locally_of_prop ⟨hX, hC⟩ 38 | 39 | lemma Submartingale.IsLocalSubmartingale [LE E] 40 | (hX : Submartingale X 𝓕 P) (hC : ∀ ω, IsCadlag (X · ω)) : 41 | IsLocalSubmartingale X 𝓕 P := 42 | locally_of_prop ⟨hX, hC⟩ 43 | 44 | variable [MeasurableSpace ι] [SecondCountableTopology ι] [BorelSpace ι] [PseudoMetrizableSpace ι] 45 | [MeasurableSpace E] [BorelSpace E] [SecondCountableTopology E] [IsFiniteMeasure P] 46 | [Approximable 𝓕 P] 47 | 48 | /-- Martingales are a stable class. -/ 49 | lemma isStable_martingale : 50 | IsStable 𝓕 (fun (X : ι → Ω → E) ↦ Martingale X 𝓕 P ∧ ∀ ω, IsCadlag (X · ω)) := by 51 | intro X ⟨hX, hC⟩ τ hτ 52 | refine ⟨⟨ProgMeasurable.adapted_stoppedProcess ?_ hτ, fun i j hij ↦ ?_⟩, 53 | isStable_isCadlag X hC τ hτ⟩ 54 | · refine Adapted.progMeasurable_of_rightContinuous 55 | (fun i ↦ (hX.adapted i).indicator <| 𝓕.mono bot_le _ <| hτ.measurableSet_gt _) (fun ω ↦ ?_) 56 | by_cases hω : ω ∈ {ω | ⊥ < τ ω} 57 | · simp_rw [Set.indicator_of_mem hω] 58 | exact (hC ω).right_continuous 59 | · simp [Set.indicator_of_notMem hω, RightContinuous, continuousWithinAt_const] 60 | · have : Martingale (fun i ↦ {ω | ⊥ < τ ω}.indicator (X i)) 𝓕 P := 61 | hX.indicator (hτ.measurableSet_gt _) 62 | conv_rhs => rw [← stoppedProcess_min_eq_stoppedProcess _ τ hij] 63 | refine EventuallyEq.trans ?_ (Martingale.condExp_stoppedValue_ae_eq_stoppedProcess 64 | (μ := P) (n := j) this (fun ω ↦ ?_) ((isStoppingTime_const 𝓕 j).min hτ) 65 | (fun ω ↦ min_le_left _ _) i) 66 | · rw [stoppedProcess_eq_stoppedValue] 67 | · by_cases hω : ω ∈ {ω | ⊥ < τ ω} 68 | · simp_rw [Set.indicator_of_mem hω] 69 | exact (hC ω).right_continuous 70 | · simp [Set.indicator_of_notMem hω, RightContinuous, continuousWithinAt_const] 71 | 72 | /-- Submartingales are a stable class. -/ 73 | lemma isStable_submartingale : 74 | IsStable 𝓕 (fun (X : ι → Ω → ℝ) ↦ Submartingale X 𝓕 P ∧ ∀ ω, IsCadlag (X · ω)) := by 75 | sorry 76 | 77 | end ProbabilityTheory 78 | -------------------------------------------------------------------------------- /BrownianMotion/Verso/Brownian.lean: -------------------------------------------------------------------------------- 1 | import BrownianMotion.Gaussian.BrownianMotion 2 | 3 | /-! 4 | # Verso file for the Brownian motion process 5 | 6 | This file is used to generate the Verso manual page about Brownian motion. 7 | -/ 8 | 9 | open MeasureTheory ProbabilityTheory 10 | open scoped NNReal Topology 11 | noncomputable section 12 | 13 | abbrev Ω := ℝ≥0 → ℝ 14 | 15 | variable {I : Finset ℝ≥0} {s t : ℝ≥0} {ω : Ω} 16 | 17 | /- Projective family and limit -/ 18 | 19 | -- ANCHOR: Measures 20 | example (I : Finset ℝ≥0) : 21 | brownianCovMatrix I = Matrix.of fun s t ↦ min s.1 t.1 := rfl 22 | 23 | example (I : Finset ℝ≥0) : 24 | gaussianProjectiveFamily I = 25 | (multivariateGaussian 0 (brownianCovMatrix I)).map 26 | (MeasurableEquiv.toLp 2 (I → ℝ)).symm := 27 | rfl 28 | 29 | example : (gaussianLimit : Measure Ω) = 30 | projectiveLimit gaussianProjectiveFamily 31 | isProjectiveMeasureFamily_gaussianProjectiveFamily := rfl 32 | -- ANCHOR_END: Measures 33 | 34 | instance : MeasureSpace Ω := ⟨gaussianLimit⟩ 35 | 36 | /- Brownian and its law. -/ 37 | 38 | -- ANCHOR: Brownian 39 | def B : ℝ≥0 → Ω → ℝ := brownian 40 | 41 | example (t : ℝ≥0) : HasLaw (B t) (gaussianReal 0 t) := 42 | hasLaw_brownian_eval 43 | 44 | example (s t : ℝ≥0) : cov[B s, B t] = min s t := 45 | covariance_brownian s t 46 | 47 | example (s t : ℝ≥0) : 48 | HasLaw (B s - B t) (gaussianReal 0 (max (s - t) (t - s))) := 49 | hasLaw_brownian_sub 50 | 51 | example (I : Finset ℝ≥0) : 52 | HasLaw (fun ω ↦ I.restrict (B · ω)) (gaussianProjectiveFamily I) := 53 | hasLaw_restrict_brownian 54 | -- ANCHOR_END: Brownian 55 | 56 | /- Continuity. -/ 57 | 58 | -- ANCHOR: Continuity 59 | example (ω : Ω) (t β : ℝ≥0) (hβ_pos : 0 < β) (hβ_lt : β < 2⁻¹) : 60 | ∃ U ∈ 𝓝 t, ∃ C, HolderOnWith C β (B · ω) U := 61 | memHolder_brownian ω t β hβ_pos hβ_lt 62 | 63 | example (ω : Ω) : Continuous (B · ω) := continuous_brownian ω 64 | -- ANCHOR_END: Continuity 65 | 66 | /- Conclution: IsBrownian. In particular, IsGaussianProcess. -/ 67 | 68 | --ANCHOR: IsBrownian 69 | example : IsBrownian B := IsBrownian_brownian 70 | 71 | example : IsGaussianProcess B := isGaussianProcess_brownian 72 | 73 | example : HasLaw (fun ω ↦ (B · ω)) gaussianLimit := hasLaw_brownian 74 | -- ANCHOR_END: IsBrownian 75 | 76 | /- Independent increments. -/ 77 | 78 | -- ANCHOR: HasIndepIncrements 79 | example : HasIndepIncrements B := hasIndepIncrements_brownian 80 | 81 | example (X : ℝ≥0 → Ω → ℝ) (hX : AEMeasurable (fun ω ↦ (X · ω))) 82 | (law : ∀ t, HasLaw (X t) (gaussianReal 0 t)) (incr : HasIndepIncrements X) : 83 | HasLaw (fun ω ↦ (X · ω)) gaussianLimit := 84 | (incr.isPreBrownian_of_hasLaw law).hasLaw_gaussianLimit hX 85 | -- ANCHOR_END: HasIndepIncrements 86 | 87 | /- Other. -/ 88 | 89 | example {n : ℕ} (hn : 0 < n) : 90 | IsKolmogorovProcess B gaussianLimit (2 * n) n (Nat.doubleFactorial (2 * n - 1)) := 91 | isKolmogorovProcess_brownian hn 92 | 93 | -- ANCHOR: Transformations 94 | variable {X : ℝ≥0 → Ω → ℝ} 95 | 96 | example [IsBrownian X] {c : ℝ≥0} (hc : c ≠ 0) : 97 | IsBrownian (fun t ω ↦ (X (c * t) ω) / √c) := 98 | IsBrownian.smul hc 99 | 100 | example [IsBrownian X] (t₀ : ℝ≥0) : 101 | IsBrownian (fun t ω ↦ X (t₀ + t) ω - X t₀ ω) := 102 | IsBrownian.shift t₀ 103 | 104 | example [IsBrownian X] : 105 | IsBrownian (fun t ω ↦ t * (X (1 / t) ω)) := 106 | IsBrownian.inv 107 | 108 | example [IsBrownian X] : 109 | ∀ᵐ ω, Filter.Tendsto (X · ω) (𝓝 0) (𝓝 0) := 110 | IsBrownian.tendsto_nhds_zero 111 | -- ANCHOR_END: Transformations 112 | 113 | end 114 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/LinearAlgebra.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Analysis.InnerProductSpace.Dual 2 | import Mathlib.Analysis.InnerProductSpace.PiL2 3 | import Mathlib.LinearAlgebra.Matrix.PosDef 4 | 5 | lemma sum_single_apply {ι : Type*} (φ : ι → Type*) [∀ i, AddCommMonoid (φ i)] [Fintype ι] 6 | [DecidableEq ι] (v : (i : ι) → φ i) : 7 | ∑ i, Pi.single i (v i) = v := by 8 | ext i 9 | simp 10 | 11 | lemma Matrix.PosSemidef.nonneg_apply_self {n R : Type*} [CommRing R] [PartialOrder R] 12 | [StarRing R] {M : Matrix n n R} (hM : M.PosSemidef) (i : n) : 0 ≤ M i i := by 13 | classical 14 | convert hM.2 (Finsupp.single i 1) 15 | simp 16 | 17 | section mkContinuous₂ 18 | 19 | namespace LinearMap 20 | 21 | variable {E F G 𝕜 : Type*} [NormedAddCommGroup E] 22 | [NormedAddCommGroup F] [NormedAddCommGroup G] [NontriviallyNormedField 𝕜] [CompleteSpace 𝕜] 23 | [NormedSpace 𝕜 E] [NormedSpace 𝕜 F] [NormedSpace 𝕜 G] [FiniteDimensional 𝕜 E] 24 | [FiniteDimensional 𝕜 F] (f : E →ₗ[𝕜] F →ₗ[𝕜] G) 25 | 26 | /-- Given a bilinear map whose codomains are finite dimensional, outputs the continuous 27 | version. -/ 28 | def mkContinuous₂OfFiniteDimensional : E →L[𝕜] F →L[𝕜] G := 29 | letI g x : F →L[𝕜] G := (f x).toContinuousLinearMap 30 | letI h : E →ₗ[𝕜] F →L[𝕜] G := 31 | { toFun := g 32 | map_add' x y := by ext z; simp [g] 33 | map_smul' m x := by ext y; simp [g] } 34 | h.toContinuousLinearMap 35 | 36 | @[simp] 37 | lemma mkContinuous₂OfFiniteDimensional_apply (x : E) (y : F) : 38 | f.mkContinuous₂OfFiniteDimensional x y = f x y := rfl 39 | 40 | end LinearMap 41 | 42 | end mkContinuous₂ 43 | 44 | section InnerProductSpace 45 | 46 | open scoped InnerProductSpace 47 | 48 | lemma OrthonormalBasis.inner_eq {𝕜 E ι : Type*} [NormedAddCommGroup E] [RCLike 𝕜] 49 | [InnerProductSpace 𝕜 E] [Fintype ι] [DecidableEq ι] (b : OrthonormalBasis ι 𝕜 E) {i j : ι} : 50 | ⟪b i, b j⟫_𝕜 = if i = j then 1 else 0 := by 51 | by_cases h : i = j 52 | · simp only [h, ↓reduceIte] 53 | apply RCLike.ext 54 | · simp 55 | · simp 56 | · simp [h] 57 | 58 | theorem OrthonormalBasis.norm_sq_eq_sum_sq_inner_right {ι E : Type*} [NormedAddCommGroup E] 59 | [InnerProductSpace ℝ E] [Fintype ι] (b : OrthonormalBasis ι ℝ E) (x : E) : 60 | ‖x‖ ^ 2 = ∑ i, ⟪b i, x⟫_ℝ ^ 2 := by 61 | rw [← b.sum_sq_norm_inner_right] 62 | simp 63 | 64 | theorem OrthonormalBasis.norm_sq_eq_sum_sq_inner_left {ι E : Type*} [NormedAddCommGroup E] 65 | [InnerProductSpace ℝ E] [Fintype ι] (b : OrthonormalBasis ι ℝ E) (x : E) : 66 | ‖x‖ ^ 2 = ∑ i, ⟪x, b i⟫_ℝ ^ 2 := by 67 | simp_rw [b.norm_sq_eq_sum_sq_inner_right, real_inner_comm] 68 | 69 | theorem EuclideanSpace.real_norm_sq_eq {n : Type*} [Fintype n] (x : EuclideanSpace ℝ n) : 70 | ‖x‖ ^ 2 = ∑ i, (x i) ^ 2 := by 71 | rw [PiLp.norm_sq_eq_of_L2] 72 | congr with i; simp 73 | 74 | lemma EuclideanSpace.real_inner_eq {ι : Type*} [Fintype ι] (x y : EuclideanSpace ℝ ι) : 75 | ⟪x, y⟫_ℝ = ∑ i, x i * y i := by 76 | nth_rw 1 [← (EuclideanSpace.basisFun ι ℝ).sum_repr' x, sum_inner] 77 | simp_rw [real_inner_smul_left, basisFun_inner] 78 | 79 | @[simp] 80 | lemma inner_toDual_symm_eq_self {𝕜 E : Type*} [RCLike 𝕜] [NormedAddCommGroup E] 81 | [InnerProductSpace 𝕜 E] [CompleteSpace E] (L : StrongDual 𝕜 E) : 82 | inner 𝕜 ((InnerProductSpace.toDual 𝕜 E).symm L) = L := by ext; simp 83 | 84 | theorem OrthonormalBasis.norm_dual {ι E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] 85 | [Fintype ι] (b : OrthonormalBasis ι ℝ E) (L : StrongDual ℝ E) : 86 | ‖L‖ ^ 2 = ∑ i, L (b i) ^ 2 := by 87 | have := Module.Basis.finiteDimensional_of_finite b.toBasis 88 | simp_rw [← (InnerProductSpace.toDual ℝ E).symm.norm_map, b.norm_sq_eq_sum_sq_inner_left, 89 | InnerProductSpace.toDual_symm_apply] 90 | 91 | @[simp] 92 | lemma LinearIsometryEquiv.coe_coe_eq_coe {𝕜 E F : Type*} [RCLike 𝕜] [NormedAddCommGroup E] 93 | [NormedAddCommGroup F] [InnerProductSpace 𝕜 E] [InnerProductSpace 𝕜 F] (f : E ≃ₗᵢ[𝕜] F) : 94 | ⇑f.toLinearIsometry.toContinuousLinearMap = ⇑f := rfl 95 | 96 | end InnerProductSpace 97 | -------------------------------------------------------------------------------- /blueprint/src/chapters/process.tex: -------------------------------------------------------------------------------- 1 | \chapter{Stochastic processes} 2 | \label{chap:process} 3 | 4 | Let $T$ be an index set and $\Omega$ a measurable space, with measure $\mathbb{P}$. 5 | A stochastic process is a function $X : T \to \Omega \to E$, where $E$ is another measurable space, such that for all $t \in T$, $X_t : \Omega \to E$ is $\mathbb{P}$-a.e. measurable. 6 | 7 | 8 | \begin{definition}[Law of a stochastic process]\label{def:processLaw} 9 | \leanok 10 | The law of a stochastic process $X$ is the measure on the measurable space $E^T$ obtained by pushing forward the measure $\mathbb{P}$ by the map $\omega \mapsto X(\cdot, \omega)$. 11 | \end{definition} 12 | 13 | \textbf{Lean remark}: we don't use a Lean definition for the law, but write the map in full. 14 | 15 | \begin{definition}[Modification]\label{def:modification} 16 | \leanok 17 | We say that a stochastic process $Y$ is a \emph{modification} of another stochastic process $X$ if for all $t \in T$, $Y_t =_{\mathbb{P}\text{-a.e.}} X_t$. 18 | \end{definition} 19 | 20 | \textbf{Lean remark}: we don't use a Lean definition for being a modification, but write explicitly the condition $\forall t \in T,\ Y_t =_{\mathbb{P}\text{-a.e.}} X_t$~. 21 | 22 | \begin{definition}[Indistinguishable]\label{def:indistinguishable} 23 | \leanok 24 | We say that a stochastic processes $Y$ is a \emph{indistinguishable} from $X$ if $\mathbb{P}$-a.e., for all $t \in T$, $X_t = Y_t$. 25 | \end{definition} 26 | 27 | A summary of the next few lemmas is this: 28 | \begin{itemize} 29 | \item indistinguishable $\implies$ modification $\implies$ same law, 30 | \item modification and continuous with $T$ separable $\implies$ indistinguishable. 31 | \end{itemize} 32 | 33 | 34 | \begin{lemma}\label{lem:Indistinguishable.Modification} 35 | \uses{def:indistinguishable, def:modification} 36 | \leanok 37 | \lean{modification_of_indistinguishable} 38 | If $Y$ is indistinguishable from $X$, then $Y$ is a modification of $X$. 39 | \end{lemma} 40 | 41 | \begin{proof}\leanok 42 | Obvious. 43 | \end{proof} 44 | 45 | 46 | \begin{lemma}\label{lem:map_eq_of_modification} 47 | \uses{def:modification} 48 | \mathlibok 49 | \lean{ProbabilityTheory.map_eq_of_forall_ae_eq} 50 | Let $X, Y : T \to \Omega \to E$ be two stochastic processes that are modifications of each other. 51 | Then for all $t_1, \ldots, t_n \in T$, the random vector $(X_{t_1}, \ldots, X_{t_n})$ has the same distribution as the random vector $(Y_{t_1}, \ldots, Y_{t_n})$. 52 | That is, $X$ and $Y$ have same finite-dimensional distributions. 53 | \end{lemma} 54 | 55 | \begin{proof}\leanok 56 | By the modification property, almost surely $X_{t_i} = Y_{t_i}$ for all $i \in [n]$. 57 | Thus the function $\omega \mapsto (X_{t_1}(\omega), \ldots, X_{t_n}(\omega))$ is equal to $\omega \mapsto (Y_{t_1}(\omega), \ldots, Y_{t_n}(\omega))$ almost surely, hence the maps of $\mathbb{P}$ by these two functions are equal. 58 | \end{proof} 59 | 60 | 61 | \begin{lemma}\label{lem:map_eq_iff} 62 | \uses{def:processLaw} 63 | \mathlibok 64 | \lean{ProbabilityTheory.map_eq_iff_forall_finset_map_restrict_eq} 65 | Let $X, Y : T \to \Omega \to E$ be two stochastic processes. 66 | Then $X$ and $Y$ have same finite-dimensional distributions if and only if they have the same law. 67 | \end{lemma} 68 | 69 | \begin{proof}\leanok 70 | TODO: consider the $\pi$-system of cylinder sets. 71 | \end{proof} 72 | 73 | 74 | \begin{lemma}\label{lem:indistinguishable_of_modification_of_continuous} 75 | \uses{def:modification, def:indistinguishable} 76 | \leanok 77 | \lean{indistinguishable_of_modification} 78 | Let $T$ and $E$ be topological spaces and suppose that $T$ is separable Hausdorff. 79 | Let $X, Y : T \to \Omega \to E$ be two stochastic processes that are modifications of each other and are almost surely continuous. 80 | Then $X$ and $Y$ are indistinguishable. 81 | \end{lemma} 82 | 83 | \begin{proof}\leanok 84 | Since $T$ is separable, it has a countable dense subset $D$. 85 | Since $D$ is countable, 86 | \begin{align*} 87 | (\forall t \in D, \mathbb{P}\text{-a.e.}, X_t = Y_t) 88 | \iff (\mathbb{P}\text{-a.e.}, \forall t \in D, X_t = Y_t) 89 | \end{align*} 90 | Hence by the modification property we have that almost surely, for all $t \in D$, $X_t = Y_t$. 91 | Then almost surely $X$ and $Y$ are continuous functions which are equal on a dense subset of $T$: those two functions are equal everywhere. 92 | \end{proof} 93 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Brownian Motion Project 2 | 3 | Thank you for your interest in contributing to the Brownian Motion Project! 4 | This guide provides detailed instructions on how to effectively and efficiently contribute to the project. 5 | 6 | ## Project Coordination 7 | 8 | The project is managed using a [GitHub project dashboard](https://github.com/users/RemyDegenne/projects/1), which tracks tasks through various stages, from assignment to completion. 9 | 10 | ## How to Contribute 11 | 12 | Contributions to the project are made through GitHub pull requests (PRs) from forks. PRs correspond to specific tasks outlined in the project's issues. The following instructions detail the process for claiming and completing tasks. 13 | 14 | ### 1. Task Identification 15 | 16 | - Tasks are posted as GitHub issues and can be found in the `Unclaimed` column of the project dashboard. 17 | - Each issue represents a specific task to be completed. The issue title and description contain relevant details and requirements. 18 | 19 | ### 2. Claiming a Task 20 | 21 | - To claim a task, comment the single word `claim` on the relevant GitHub issue. 22 | - If no other user is assigned, you will automatically be assigned to the task, and the issue will move to the `Claimed` column. 23 | - If you decide not to work on a task after claiming it, comment the single word `disclaim` on the issue. This will unassign you and return the issue to the `Unclaimed` column, making it available for others to claim. 24 | 25 | ### 3. Working on the Task 26 | 27 | Once you are assigned to an issue, begin working on the corresponding task. You should fork the project and also create a new branch from the `master` branch to develop your solution. Please try and avoid making PRs from `master` as for technical reasons this makes them slightly harder to review. 28 | 29 | ### 4. Submitting a Pull Request 30 | 31 | - When you are ready to submit your solution, create a PR from the working branch of your fork to the project’s `master` branch. 32 | - After submitting the PR, comment `propose #PR_NUMBER` on the original issue. This links your PR to the task, and the task will move to the `In Progress` column on the dashboard. 33 | - A task can only move to `In Progress` if it has been claimed by the user proposing the PR. 34 | 35 | ### 5. Withdrawing or Updating a PR 36 | 37 | - If you need to withdraw your PR, comment the single phrase `withdraw #PR_NUMBER` on the issue. The task will return to the `Claimed` column, but you will remain assigned to the issue. 38 | - To submit an updated PR after withdrawal, comment `propose #NEW_PR_NUMBER` following the same process outlined in step 4. 39 | 40 | ### 6. Review Process 41 | 42 | - After finishing the task and ensuring your PR is ready for review, comment `awaiting-review` on the PR. This will add the `awaiting-review` label to your PR and move the task from `In Progress` to the `In Review` column of the dashboard. 43 | The project maintainers will review the PR. They may request changes, approve the PR, or provide feedback. If they comment `awaiting-author`, this will add the `awaiting-author` label to your PR. 44 | When you've responded, comment `awaiting-review` again to remove it and add the `awaiting-review` tag again. 45 | 46 | ### 7. Task Completion 47 | 48 | - Once the PR is approved and merged, the task will automatically move to the `Completed` column. 49 | - If further adjustments are needed after merging, a new issue will be created to track additional work. 50 | 51 | ### Additional Guidelines and Notes 52 | 53 | 1. Please adhere to the issue claiming process. If an issue is already assigned to another contributor, refrain from working on it without prior communication with the current claimant. This ensures a collaborative and respectful workflow that values each contributor’s efforts. 54 | 2. Be aware that this contribution process is still in an experimental phase. As a result, occasional issues and inefficiencies may arise. We are committed to continuously refining the process, and your constructive feedback is highly appreciated. You can share your thoughts and suggestions on the [Lean Zulip chat channel](https://leanprover.zulipchat.com/#narrow/channel/509433-Brownian-motion). 55 | 3. Until the integration of sufficient CI automation, the management of the project dashboard is handled manually by the maintainers. We ask for your patience and understanding as we work to keep the process running smoothly. 56 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/Cadlag.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import Mathlib.Analysis.SpecificLimits.Basic 7 | import Mathlib.Data.Nat.Nth 8 | import Mathlib.Topology.Bases 9 | import Mathlib.Topology.MetricSpace.Basic 10 | import Mathlib.Topology.MetricSpace.Pseudo.Defs 11 | import Mathlib.Topology.MetricSpace.Bounded 12 | import Mathlib.Topology.Sequences 13 | import Mathlib.Topology.Order.Basic 14 | 15 | /-! # cadlag functions 16 | 17 | -/ 18 | 19 | open Filter TopologicalSpace Bornology 20 | open scoped Topology 21 | 22 | variable {ι E : Type*} [TopologicalSpace ι] [TopologicalSpace E] 23 | 24 | /-- The predicate that a function is right continuous. -/ 25 | abbrev Function.RightContinuous [PartialOrder ι] (f : ι → E) := 26 | ∀ a, ContinuousWithinAt f (Set.Ioi a) a 27 | 28 | /-- A function is cadlag if it is right-continuous and has left limits. -/ 29 | structure IsCadlag [PartialOrder ι] (f : ι → E) : Prop where 30 | right_continuous : Function.RightContinuous f 31 | left_limit : ∀ x, ∃ l, Tendsto f (𝓝[<] x) (𝓝 l) 32 | 33 | /-- A càdlàg function maps compact sets to bounded sets. -/ 34 | lemma isBounded_image_of_isCadlag_of_isCompact {E : Type*} [LinearOrder ι] [PseudoMetricSpace E] 35 | {f : ι → E} (hf : IsCadlag f) {s : Set ι} (hs : IsCompact s) : 36 | IsBounded (f '' s) := by 37 | by_contra h_nb 38 | let x := (nonempty_of_not_isBounded h_nb).some 39 | have h_distx : ∀ n : ℕ, ∃ t_n ∈ s, n ≤ dist (f t_n) x := fun n ↦ by 40 | rw [Metric.isBounded_iff_subset_ball x] at h_nb 41 | dsimp [Metric.ball] at h_nb 42 | push_neg at h_nb 43 | replace h_nb := h_nb n 44 | rw [Set.not_subset] at h_nb 45 | rcases h_nb with ⟨y, ⟨t, ht_in, ht_y⟩, hy_dist⟩ 46 | use t, ht_in 47 | simpa [Set.mem_setOf_eq, not_lt, ht_y] using hy_dist 48 | choose t ht_in ht_eq using h_distx 49 | let V := Ultrafilter.of (map t atTop) 50 | have h_map_le_V : V ≤ map t atTop := Ultrafilter.of_le (map t atTop) 51 | have hs_in_V : s ∈ V := by 52 | apply h_map_le_V 53 | rw [mem_map] 54 | filter_upwards [Filter.univ_mem] with n _ using ht_in n 55 | rcases IsCompact.ultrafilter_le_nhds' hs V hs_in_V with ⟨c, _, hV_le_nhds⟩ 56 | have h_loc_bdd : ∃ W ∈ 𝓝 c, Bornology.IsBounded (f '' W) := by 57 | obtain ⟨l, hl⟩ := hf.left_limit c 58 | rcases Metric.exists_isBounded_image_of_tendsto hl with ⟨U_left, hU_mem, hU_bdd⟩ 59 | rcases Metric.exists_isBounded_image_of_tendsto (hf.right_continuous c).tendsto 60 | with ⟨_, hV_mem, hV_bdd⟩ 61 | rw [mem_nhdsWithin_iff_exists_mem_nhds_inter] at hU_mem hV_mem 62 | rcases hU_mem with ⟨G_left, hGl_nhds, hGl_sub⟩ 63 | rcases hV_mem with ⟨G_right, hGr_nhds, hGr_sub⟩ 64 | let W := G_left ∩ G_right 65 | have hW_nhds : W ∈ 𝓝 c := Filter.inter_mem hGl_nhds hGr_nhds 66 | use W, hW_nhds 67 | apply Bornology.IsBounded.subset ((hU_bdd.union hV_bdd).union 68 | (isBounded_induced.mp isBounded_singleton : Bornology.IsBounded (f '' {c}))) 69 | rintro _ ⟨y, ⟨hyL, hyR⟩ , rfl⟩ 70 | rcases lt_trichotomy y c with (hlt | heq | hgt) 71 | · apply Or.inl ∘ Or.inl 72 | simp_all only [inter_mem_iff, and_self, Set.mem_image, x, V, W] 73 | refine ⟨y, hGl_sub ?_, rfl⟩ 74 | simp_all only [Set.mem_inter_iff, Set.mem_Iio, and_self] 75 | · apply Or.inr 76 | rw [heq] 77 | exact Set.mem_image_of_mem f rfl 78 | · apply Or.inl ∘ Or.inr 79 | apply (Set.mem_image _ _ _).mpr ⟨y, hGr_sub ?_, rfl⟩ 80 | simp_all only [Set.mem_inter_iff, Set.mem_Ioi, and_self] 81 | rcases h_loc_bdd with ⟨W, hW_nhds, hW_bdd⟩ 82 | rcases hW_bdd.subset_ball (f c) with ⟨R, h_subset⟩ 83 | have h_far : ∀ᶠ n in atTop, dist (f (t n)) x > R + dist (f c) x := by 84 | have h_dist_infty : Tendsto (fun n ↦ dist (f (t n)) x) atTop atTop := 85 | tendsto_atTop_mono (ht_eq ·) tendsto_natCast_atTop_atTop 86 | rw [tendsto_atTop_atTop] at h_dist_infty 87 | rcases h_dist_infty (R + dist (f c) x + 1) with ⟨N, hN⟩ 88 | apply eventually_atTop.2 ⟨N, fun n hn ↦ ?_ ⟩ 89 | specialize hN n hn 90 | linarith 91 | have h_inter : (t '' {n | dist (f (t n)) x > R + dist (f c) x} ∩ W).Nonempty := 92 | Ultrafilter.nonempty_of_mem (inter_mem (h_map_le_V (image_mem_map h_far)) (hV_le_nhds hW_nhds)) 93 | rcases h_inter with ⟨z, ⟨n, hn_far, rfl⟩, hz_in_W⟩ 94 | have h_close : dist (f (t n)) (f c) < R := h_subset (Set.mem_image_of_mem f hz_in_W) 95 | have h_tri : dist (f (t n)) x ≤ dist (f (t n)) (f c) + dist (f c) x := dist_triangle _ _ _ 96 | dsimp at hn_far 97 | linarith 98 | -------------------------------------------------------------------------------- /lake-manifest.json: -------------------------------------------------------------------------------- 1 | {"version": "1.1.0", 2 | "packagesDir": ".lake/packages", 3 | "packages": 4 | [{"url": "https://github.com/leanprover/subverso", 5 | "type": "git", 6 | "subDir": null, 7 | "scope": "", 8 | "rev": "eb77622e97e942ba2cfe02f60637705fc2d9481b", 9 | "name": "subverso", 10 | "manifestFile": "lake-manifest.json", 11 | "inputRev": null, 12 | "inherited": false, 13 | "configFile": "lakefile.lean"}, 14 | {"url": "https://github.com/PatrickMassot/checkdecls.git", 15 | "type": "git", 16 | "subDir": null, 17 | "scope": "", 18 | "rev": "3d425859e73fcfbef85b9638c2a91708ef4a22d4", 19 | "name": "checkdecls", 20 | "manifestFile": "lake-manifest.json", 21 | "inputRev": null, 22 | "inherited": false, 23 | "configFile": "lakefile.lean"}, 24 | {"url": "https://github.com/RemyDegenne/kolmogorov_extension4", 25 | "type": "git", 26 | "subDir": null, 27 | "scope": "", 28 | "rev": "907c4a2273a7fcc90b62f67772ede3b3ab1da141", 29 | "name": "kolmogorov_extension4", 30 | "manifestFile": "lake-manifest.json", 31 | "inputRev": null, 32 | "inherited": false, 33 | "configFile": "lakefile.toml"}, 34 | {"url": "https://github.com/leanprover-community/mathlib4.git", 35 | "type": "git", 36 | "subDir": null, 37 | "scope": "", 38 | "rev": "2df2f0150c275ad53cb3c90f7c98ec15a56a1a67", 39 | "name": "mathlib", 40 | "manifestFile": "lake-manifest.json", 41 | "inputRev": "v4.26.0", 42 | "inherited": false, 43 | "configFile": "lakefile.lean"}, 44 | {"url": "https://github.com/leanprover-community/plausible", 45 | "type": "git", 46 | "subDir": null, 47 | "scope": "leanprover-community", 48 | "rev": "160af9e8e7d4ae448f3c92edcc5b6a8522453f11", 49 | "name": "plausible", 50 | "manifestFile": "lake-manifest.json", 51 | "inputRev": "main", 52 | "inherited": true, 53 | "configFile": "lakefile.toml"}, 54 | {"url": "https://github.com/leanprover-community/LeanSearchClient", 55 | "type": "git", 56 | "subDir": null, 57 | "scope": "leanprover-community", 58 | "rev": "3591c3f664ac3719c4c86e4483e21e228707bfa2", 59 | "name": "LeanSearchClient", 60 | "manifestFile": "lake-manifest.json", 61 | "inputRev": "main", 62 | "inherited": true, 63 | "configFile": "lakefile.toml"}, 64 | {"url": "https://github.com/leanprover-community/import-graph", 65 | "type": "git", 66 | "subDir": null, 67 | "scope": "leanprover-community", 68 | "rev": "e9f31324f15ead11048b1443e62c5deaddd055d2", 69 | "name": "importGraph", 70 | "manifestFile": "lake-manifest.json", 71 | "inputRev": "main", 72 | "inherited": true, 73 | "configFile": "lakefile.toml"}, 74 | {"url": "https://github.com/leanprover-community/ProofWidgets4", 75 | "type": "git", 76 | "subDir": null, 77 | "scope": "leanprover-community", 78 | "rev": "b4fb2aa5290ebf61bc5f80a5375ba642f0a49192", 79 | "name": "proofwidgets", 80 | "manifestFile": "lake-manifest.json", 81 | "inputRev": "v0.0.83", 82 | "inherited": true, 83 | "configFile": "lakefile.lean"}, 84 | {"url": "https://github.com/leanprover-community/aesop", 85 | "type": "git", 86 | "subDir": null, 87 | "scope": "leanprover-community", 88 | "rev": "2f6d238744c4cb07fdc91240feaf5d4221a27931", 89 | "name": "aesop", 90 | "manifestFile": "lake-manifest.json", 91 | "inputRev": "master", 92 | "inherited": true, 93 | "configFile": "lakefile.toml"}, 94 | {"url": "https://github.com/leanprover-community/quote4", 95 | "type": "git", 96 | "subDir": null, 97 | "scope": "leanprover-community", 98 | "rev": "9312503909aa8e8bb392530145cc1677a6298574", 99 | "name": "Qq", 100 | "manifestFile": "lake-manifest.json", 101 | "inputRev": "master", 102 | "inherited": true, 103 | "configFile": "lakefile.toml"}, 104 | {"url": "https://github.com/leanprover-community/batteries", 105 | "type": "git", 106 | "subDir": null, 107 | "scope": "leanprover-community", 108 | "rev": "24241822ef9d3e7f6a3bcc53ad136e12663db8f3", 109 | "name": "batteries", 110 | "manifestFile": "lake-manifest.json", 111 | "inputRev": "main", 112 | "inherited": true, 113 | "configFile": "lakefile.toml"}, 114 | {"url": "https://github.com/leanprover/lean4-cli", 115 | "type": "git", 116 | "subDir": null, 117 | "scope": "leanprover", 118 | "rev": "933fce7e893f65969714c60cdb4bd8376786044e", 119 | "name": "Cli", 120 | "manifestFile": "lake-manifest.json", 121 | "inputRev": "v4.26.0", 122 | "inherited": true, 123 | "configFile": "lakefile.toml"}], 124 | "name": "BrownianMotion", 125 | "lakeDir": ".lake"} 126 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/Komlos.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import Mathlib.Probability.Moments.Basic 7 | 8 | /-! 9 | # Komlos lemmas 10 | 11 | -/ 12 | 13 | variable {E Ω : Type*} {mΩ : MeasurableSpace Ω} 14 | 15 | open Filter MeasureTheory 16 | open scoped Topology NNReal ENNReal 17 | 18 | lemma komlos_convex [AddCommMonoid E] [Module ℝ≥0 E] 19 | {f : ℕ → E} {φ : E → ℝ} (hφ_nonneg : 0 ≤ φ) 20 | (hφ_bdd : ∃ M : ℝ, ∀ n, φ (f n) ≤ M) : 21 | ∃ g : ℕ → E, (∀ n, g n ∈ convexHull ℝ≥0 (Set.range fun m ↦ f (n + m))) ∧ 22 | ∀ δ > 0, ∃ N, ∀ n m, N ≤ n → N ≤ m → 23 | 2⁻¹ * φ (g n) + 2⁻¹ * φ (g m) - φ ((2 : ℝ≥0)⁻¹ • (g n + g m)) < δ := by 24 | obtain ⟨M, hM⟩ := hφ_bdd 25 | let r : ℕ → ℝ := fun n ↦ sInf (Set.image φ (convexHull ℝ≥0 (Set.range (fun m ↦ f (n + m))))) 26 | have hr_nondec n : r n ≤ r (n + 1) := by 27 | apply_rules [csInf_le_csInf] 28 | · exact ⟨0, Set.forall_mem_image.2 fun x hx ↦ hφ_nonneg x⟩ 29 | · exact ⟨_, ⟨ _, subset_convexHull ℝ≥0 _ ⟨0, rfl⟩, rfl⟩⟩ 30 | · refine Set.image_mono <| convexHull_min ?_ (convex_convexHull ℝ≥0 _) 31 | rintro _ ⟨m, rfl⟩; exact subset_convexHull ℝ≥0 _ ⟨m + 1, by simp [add_comm, add_left_comm]⟩ 32 | obtain ⟨A, hA⟩ : ∃ A, Filter.Tendsto r Filter.atTop (nhds A) := by 33 | refine ⟨_, tendsto_atTop_ciSup (monotone_nat_of_le_succ hr_nondec) ?_⟩ 34 | exact ⟨M, Set.forall_mem_range.mpr fun n ↦ csInf_le 35 | ⟨0, Set.forall_mem_image.mpr fun x hx ↦ hφ_nonneg x⟩ 36 | (Set.mem_image_of_mem _ <| subset_convexHull ℝ≥0 _ 37 | <| Set.mem_range_self 0) |> le_trans <| by simpa using hM n⟩ 38 | obtain ⟨g, hg⟩ : 39 | ∃ g : ℕ → E, (∀ n, g n ∈ convexHull ℝ≥0 (Set.range (fun m ↦ f (n + m)))) 40 | ∧ (∀ n, φ (g n) ≤ A + 1 / (n + 1)) := by 41 | have h_exists_g : 42 | ∀ n, ∃ g ∈ convexHull ℝ≥0 (Set.range (fun m ↦ f (n + m))), φ g ≤ A + 1 / (n + 1) := by 43 | intro n 44 | have h_exists_g : 45 | ∃ g ∈ convexHull ℝ≥0 (Set.range (fun m ↦ f (n + m))), φ g < A + 1 / (n + 1) := by 46 | have h_exists_g : r n < A + 1 / (n + 1) := by 47 | exact lt_add_of_le_of_pos (le_of_tendsto_of_tendsto tendsto_const_nhds hA 48 | (Filter.eventually_atTop.2 ⟨n, fun m hm ↦ by 49 | induction hm <;> [tauto; linarith [hr_nondec ‹_›]]⟩)) (by positivity) 50 | contrapose! h_exists_g 51 | exact le_csInf ⟨ _, Set.mem_image_of_mem _ <| subset_convexHull ℝ≥0 _ 52 | <| Set.mem_range_self 0 ⟩ fun x hx ↦ by 53 | rcases hx with ⟨ g, hg, rfl ⟩; exact h_exists_g g hg 54 | exact ⟨h_exists_g.choose, h_exists_g.choose_spec.1, le_of_lt h_exists_g.choose_spec.2⟩ 55 | exact ⟨fun n ↦ Classical.choose (h_exists_g n), 56 | fun n ↦ Classical.choose_spec (h_exists_g n) |>.1, 57 | fun n ↦ Classical.choose_spec (h_exists_g n) |>.2⟩ 58 | refine ⟨g, hg.1, fun δ δpos ↦ ?_⟩ 59 | obtain ⟨ε, εpos, hε⟩ := exists_between (div_pos δpos zero_lt_four) 60 | obtain ⟨N, hN⟩ : ∃ N, r N ≥ A - ε ∧ 1 / (N + 1) ≤ ε := by 61 | rcases Metric.tendsto_atTop.mp hA ε εpos with ⟨N, hN⟩ 62 | exact ⟨N + ⌈ε⁻¹⌉₊, by linarith [abs_lt.mp (hN (N + ⌈ε⁻¹⌉₊) (by grind))], by 63 | simpa using inv_le_of_inv_le₀ εpos (by linarith [Nat.le_ceil (ε⁻¹)])⟩ 64 | refine ⟨N, fun n m hn hm ↦ ?_⟩ 65 | have h_convex : φ ((1 / 2 : ℝ≥0) • (g n + g m)) ≥ A - ε := by 66 | have h_convex : 67 | (1 / 2 : ℝ≥0) • (g n + g m) ∈ convexHull ℝ≥0 (Set.range (fun m ↦ f (N + m))) := by 68 | simp only [one_div, gt_iff_lt, ge_iff_le, tsub_le_iff_right, smul_add] at * 69 | refine convex_convexHull ℝ≥0 _ ?_ ?_ ?_ ?_ ?_ <;> norm_num 70 | · refine convexHull_mono (Set.range_subset_iff.2 fun m ↦ ?_) (hg.1 n) 71 | exact ⟨m + (n - N), by grind⟩ 72 | · refine convexHull_mono ?_ (hg.1 m) 73 | exact Set.range_subset_iff.2 fun k ↦ ⟨k + (m - N), by 74 | simp [show N + (k + (m - N)) = m + k by grind]⟩ 75 | refine le_trans hN.1 ?_ 76 | exact csInf_le ⟨0, Set.forall_mem_image.2 fun x hx ↦ hφ_nonneg _⟩ ⟨_, h_convex, rfl⟩ 77 | norm_num at * 78 | linarith [hg.2 n, hg.2 m, inv_anti₀ 79 | (by positivity) (by norm_cast; grind : (n : ℝ) + 1 ≥ N + 1), inv_anti₀ 80 | (by positivity) (by norm_cast; grind : (m : ℝ) + 1 ≥ N + 1)] 81 | 82 | lemma komlos_norm [NormedAddCommGroup E] [InnerProductSpace ℝ E] 83 | {f : ℕ → E} (h_bdd : ∃ M : ℝ, ∀ n, ‖f n‖ ≤ M) : 84 | ∃ (g : ℕ → E) (x : E), (∀ n, g n ∈ convexHull ℝ (Set.range fun m ↦ f (n + m))) ∧ 85 | Tendsto g atTop (𝓝 x) := 86 | sorry 87 | 88 | -- todo: check measurability hypothesis/conclusion 89 | lemma komlos_ennreal (X : ℕ → Ω → ℝ≥0∞) (hX : ∀ n, Measurable (X n)) 90 | {P : Measure Ω} [IsProbabilityMeasure P] : 91 | ∃ (Y : ℕ → Ω → ℝ≥0∞) (Y_lim : Ω → ℝ≥0∞), 92 | (∀ n, Y n ∈ convexHull ℝ≥0∞ (Set.range fun m ↦ X (n + m))) ∧ Measurable Y_lim ∧ 93 | ∀ᵐ ω ∂P, Tendsto (Y · ω) atTop (𝓝 (Y_lim ω)) := 94 | sorry 95 | -------------------------------------------------------------------------------- /BrownianMotion/StochasticIntegral/SquareIntegrable.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.Auxiliary.Martingale 7 | import BrownianMotion.StochasticIntegral.ApproxSeq 8 | import BrownianMotion.StochasticIntegral.Locally 9 | import BrownianMotion.Auxiliary.Adapted 10 | import BrownianMotion.StochasticIntegral.OptionalSampling 11 | import Mathlib.Probability.Process.HittingTime 12 | 13 | /-! # Square integrable martingales 14 | 15 | -/ 16 | 17 | open MeasureTheory Filter Function TopologicalSpace 18 | open scoped ENNReal 19 | 20 | namespace ProbabilityTheory 21 | 22 | variable {ι Ω E : Type*} [LinearOrder ι] [TopologicalSpace ι] 23 | [NormedAddCommGroup E] [NormedSpace ℝ E] [CompleteSpace E] 24 | {mΩ : MeasurableSpace Ω} {P : Measure Ω} 25 | {X Y : ι → Ω → E} {𝓕 : Filtration ι mΩ} 26 | 27 | /-- A square integrable martingale is a martingale with cadlag paths and uniformly bounded 28 | second moments. -/ 29 | structure IsSquareIntegrable (X : ι → Ω → E) (𝓕 : Filtration ι mΩ) (P : Measure Ω) : Prop where 30 | martingale : Martingale X 𝓕 P 31 | cadlag : ∀ ω, IsCadlag (X · ω) 32 | bounded : ⨆ i, eLpNorm (X i) 2 P < ∞ 33 | 34 | lemma IsSquareIntegrable.integrable_sq (hX : IsSquareIntegrable X 𝓕 P) (i : ι) : 35 | Integrable (fun ω ↦ ‖X i ω‖ ^ 2) P := by 36 | constructor 37 | · have hX_meas := (hX.martingale.adapted i).mono (𝓕.le i) 38 | fun_prop 39 | · have hX_bound : eLpNorm (X i) 2 P < ∞ := by 40 | calc eLpNorm (X i) 2 P 41 | _ ≤ ⨆ j, eLpNorm (X j) 2 P := le_iSup (fun j ↦ eLpNorm (X j) 2 P) i 42 | _ < ∞ := hX.bounded 43 | simpa [HasFiniteIntegral, eLpNorm_lt_top_iff_lintegral_rpow_enorm_lt_top] using hX_bound 44 | 45 | lemma IsSquareIntegrable.add (hX : IsSquareIntegrable X 𝓕 P) 46 | (hY : IsSquareIntegrable Y 𝓕 P) : 47 | IsSquareIntegrable (fun i ω ↦ X i ω + Y i ω) 𝓕 P := by 48 | refine ⟨hX.martingale.add hY.martingale, fun ω ↦ ⟨fun i => ?_, fun i => ?_⟩, ?_⟩ 49 | · exact ContinuousWithinAt.add ((hX.2 ω).1 i) ((hY.2 ω).1 i) 50 | · obtain ⟨r, hr⟩ := (hX.2 ω).2 i 51 | obtain ⟨s, hs⟩ := (hY.2 ω).2 i 52 | exact ⟨r + s, Tendsto.add hr hs⟩ 53 | · have hX_bound : ⨆ i, eLpNorm (X i) 2 P < ∞ := hX.bounded 54 | have hY_bound : ⨆ i, eLpNorm (Y i) 2 P < ∞ := hY.bounded 55 | calc ⨆ i, eLpNorm (fun ω ↦ X i ω + Y i ω) 2 P 56 | ≤ ⨆ i, (eLpNorm (X i) 2 P + eLpNorm (Y i) 2 P) := by 57 | refine iSup_mono fun i ↦ ?_ 58 | exact eLpNorm_add_le ((hX.martingale.adapted i).mono (𝓕.le i)).aestronglyMeasurable 59 | ((hY.martingale.adapted i).mono (𝓕.le i)).aestronglyMeasurable (by simp) 60 | _ ≤ (⨆ i, eLpNorm (X i) 2 P) + ⨆ i, eLpNorm (Y i) 2 P := by 61 | refine iSup_le fun i => ?_ 62 | gcongr 63 | · exact le_iSup (fun i => eLpNorm (X i) 2 P) i 64 | · exact le_iSup (fun i => eLpNorm (Y i) 2 P) i 65 | _ < ∞ := ENNReal.add_lt_top.mpr ⟨hX_bound, hY_bound⟩ 66 | 67 | variable [SigmaFinite P] 68 | 69 | lemma IsSquareIntegrable.submartingale_sq_norm (hX : IsSquareIntegrable X 𝓕 P) : 70 | Submartingale (fun i ω ↦ ‖X i ω‖ ^ 2) 𝓕 P := by 71 | refine hX.1.submartingale_convex_comp (φ := fun x => ‖x‖ ^ 2) ?_ (by fun_prop) fun i => ?_ 72 | · have s : (fun x : E => ‖x‖)'' (Set.univ : Set E) ⊆ Set.Ici 0 := by intro; aesop 73 | have ic : Convex ℝ ((fun x : E => ‖x‖)'' (Set.univ : Set E)) := by 74 | by_cases Nontrivial E 75 | · simp [convex_Ici] 76 | · refine Set.Subsingleton.convex (Set.Subsingleton.image ?_ fun x => ‖x‖) 77 | simp_all [not_nontrivial_iff_subsingleton] 78 | simpa using ((convexOn_rpow (p := 2) (by linarith)).subset s ic).comp convexOn_univ_norm 79 | ((Real.monotoneOn_rpow_Ici_of_exponent_nonneg (r := 2) (by linarith)).mono s) 80 | · refine MemLp.integrable_norm_pow ⟨?_, ?_⟩ (by linarith) 81 | · exact hX.1.1.stronglyMeasurable.aestronglyMeasurable 82 | · exact lt_of_le_of_lt (le_iSup (fun i => eLpNorm (X i) 2 P) i) hX.3 83 | 84 | variable [SigmaFiniteFiltration P 𝓕] 85 | 86 | lemma IsSquareIntegrable.eLpNorm_mono (hX : IsSquareIntegrable X 𝓕 P) {i j : ι} (hij : i ≤ j) : 87 | eLpNorm (X i) 2 P ≤ eLpNorm (X j) 2 P := by 88 | have : ∫ ω, ‖X i ω‖ ^ 2 ∂P ≤ ∫ ω, ‖X j ω‖ ^ 2 ∂P := by 89 | simpa using hX.submartingale_sq_norm.setIntegral_le hij MeasurableSet.univ 90 | calc 91 | _ = (∫⁻ ω, ‖X i ω‖ₑ ^ ((2 : ℝ≥0∞).toReal) ∂P) ^ (1 / (2 : ℝ≥0∞).toReal) := by 92 | simp [eLpNorm_eq_lintegral_rpow_enorm] 93 | _ = (ENNReal.ofReal (∫ ω, ‖X i ω‖ ^ 2 ∂P)) ^ (1 / (2 : ℝ≥0∞).toReal) := by 94 | congr 95 | simpa using (ofReal_integral_norm_eq_lintegral_enorm (hX.integrable_sq i)).symm 96 | _ ≤ (ENNReal.ofReal (∫ ω, ‖X j ω‖ ^ 2 ∂P)) ^ (1 / (2 : ℝ≥0∞).toReal) := by gcongr 97 | _ = (∫⁻ ω, ‖X j ω‖ₑ ^ ((2 : ℝ≥0∞).toReal) ∂P) ^ (1 / (2 : ℝ≥0∞).toReal) := by 98 | congr 99 | simpa using (ofReal_integral_norm_eq_lintegral_enorm (hX.integrable_sq j)) 100 | _ = eLpNorm (X j) 2 P := by 101 | simp [eLpNorm_eq_lintegral_rpow_enorm] 102 | 103 | end ProbabilityTheory 104 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/IsStoppingTime.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Probability.Process.Stopping 2 | import BrownianMotion.StochasticIntegral.Predictable 3 | import BrownianMotion.Auxiliary.WithTop 4 | 5 | open MeasureTheory Filter Filtration 6 | open scoped ENNReal Topology 7 | 8 | namespace MeasureTheory 9 | 10 | variable {ι Ω E : Type*} {mΩ : MeasurableSpace Ω} {P : Measure Ω} 11 | [ConditionallyCompleteLinearOrderBot ι] [TopologicalSpace ι] [OrderTopology ι] 12 | [DenselyOrdered ι] [FirstCountableTopology ι] {𝓕 : Filtration ι mΩ} 13 | 14 | lemma isStoppingTime_of_measurableSet_lt_of_isRightContinuous [NoMaxOrder ι] 15 | {τ : Ω → WithTop ι} (h𝓕 : IsRightContinuous 𝓕) (hτ : ∀ i, MeasurableSet[𝓕 i] {ω | τ ω < i}) : 16 | IsStoppingTime 𝓕 τ := by 17 | intro i 18 | obtain ⟨u, hu₁, hu₂, hu₃⟩ := exists_seq_strictAnti_tendsto i 19 | refine MeasurableSet.of_compl ?_ 20 | rw [(_ : {ω | τ ω ≤ i}ᶜ = ⋃ n, {ω | u n ≤ τ ω})] 21 | · refine h𝓕.measurableSet ?_ 22 | simp_rw [𝓕.rightCont_eq, MeasurableSpace.measurableSet_iInf] 23 | intros j hj 24 | obtain ⟨N, hN⟩ := (hu₃.eventually_le_const hj).exists 25 | rw [(_ : ⋃ n, {ω | u n ≤ τ ω} = ⋃ n ≥ N, {ω | u n ≤ τ ω})] 26 | · refine MeasurableSet.iUnion <| fun n ↦ MeasurableSet.iUnion <| fun hn ↦ 27 | 𝓕.mono ((hu₁.antitone hn).trans hN) _ <| MeasurableSet.of_compl ?_ 28 | rw [(by ext; simp : {ω | u n ≤ τ ω}ᶜ = {ω | τ ω < u n})] 29 | exact hτ (u n) 30 | · ext ω 31 | simp only [Set.mem_iUnion, Set.mem_setOf_eq, ge_iff_le, exists_prop] 32 | constructor 33 | · rintro ⟨i, hle⟩ 34 | refine ⟨i + N, N.le_add_left i, le_trans ?_ hle⟩ 35 | norm_cast 36 | exact hu₁.antitone <| i.le_add_right N 37 | · rintro ⟨i, -, hi⟩ 38 | exact ⟨i, hi⟩ 39 | · ext ω 40 | simp only [Set.mem_compl_iff, Set.mem_setOf_eq, not_le, Set.mem_iUnion] 41 | constructor 42 | · intro h 43 | by_cases hτ : τ ω = ⊤ 44 | · exact ⟨0, hτ ▸ le_top⟩ 45 | · have hlt : i < (τ ω).untop hτ := by 46 | rwa [WithTop.lt_untop_iff] 47 | obtain ⟨N, hN⟩ := (hu₃.eventually_le_const hlt).exists 48 | refine ⟨N, WithTop.coe_le_iff.2 <| fun n hn ↦ hN.trans ?_⟩ 49 | simp only [hn, WithTop.untop_coe, le_refl] 50 | · rintro ⟨j, hj⟩ 51 | refine lt_of_lt_of_le ?_ hj 52 | norm_cast 53 | exact hu₂ _ 54 | 55 | -- This lemma will change when we decide on the correct definition of `IsRightContinuous` 56 | lemma isStoppingTime_of_measurableSet_lt_of_isRightContinuous' 57 | {τ : Ω → WithTop ι} (h𝓕 : IsRightContinuous 𝓕) 58 | (hτ1 : ∀ i, ¬ IsMax i → MeasurableSet[𝓕 i] {ω | τ ω < i}) 59 | (hτ2 : ∀ i, IsMax i → MeasurableSet[𝓕 i] {ω | τ ω ≤ i}) : 60 | IsStoppingTime 𝓕 τ := by 61 | intro i 62 | by_cases hmax : IsMax i 63 | · rw [h𝓕.eq, 𝓕.rightCont_eq_of_isMax hmax] 64 | exact hτ2 i hmax 65 | rw [h𝓕.eq, 𝓕.rightCont_eq_of_not_isMax hmax] 66 | rw [not_isMax_iff] at hmax 67 | obtain ⟨j, hj⟩ := hmax 68 | obtain ⟨u, hu₁, hu₂, hu₃⟩ := exists_seq_strictAnti_tendsto' hj 69 | refine MeasurableSet.of_compl ?_ 70 | rw [(_ : {ω | τ ω ≤ i}ᶜ = ⋃ n, {ω | u n ≤ τ ω})] 71 | · simp_rw [MeasurableSpace.measurableSet_iInf] 72 | intros j hj 73 | obtain ⟨N, hN⟩ := (hu₃.eventually_le_const hj).exists 74 | rw [(_ : ⋃ n, {ω | u n ≤ τ ω} = ⋃ n > N, {ω | u n ≤ τ ω})] 75 | · refine MeasurableSet.iUnion <| fun n ↦ MeasurableSet.iUnion <| fun hn ↦ 76 | 𝓕.mono ((hu₁ hn).le.trans hN) _ <| MeasurableSet.of_compl ?_ 77 | rw [(by ext; simp : {ω | u n ≤ τ ω}ᶜ = {ω | τ ω < u n})] 78 | refine hτ1 (u n) <| not_isMax_iff.2 ⟨u N, hu₁ hn⟩ 79 | · ext ω 80 | simp only [Set.mem_iUnion, Set.mem_setOf_eq, gt_iff_lt, exists_prop] 81 | constructor 82 | · rintro ⟨i, hle⟩ 83 | refine ⟨i + N + 1, by linarith, le_trans ?_ hle⟩ 84 | norm_cast 85 | exact hu₁.antitone (by linarith) 86 | · rintro ⟨i, -, hi⟩ 87 | exact ⟨i, hi⟩ 88 | · ext ω 89 | simp only [Set.mem_compl_iff, Set.mem_setOf_eq, not_le, Set.mem_iUnion] 90 | constructor 91 | · intro h 92 | by_cases hτ : τ ω = ⊤ 93 | · exact ⟨0, hτ ▸ le_top⟩ 94 | · have hlt : i < (τ ω).untop hτ := by 95 | rwa [WithTop.lt_untop_iff] 96 | obtain ⟨N, hN⟩ := (hu₃.eventually_le_const hlt).exists 97 | refine ⟨N, WithTop.coe_le_iff.2 <| fun n hn ↦ hN.trans ?_⟩ 98 | simp only [hn, WithTop.untop_coe, le_refl] 99 | · rintro ⟨j, hj⟩ 100 | refine lt_of_lt_of_le ?_ hj 101 | norm_cast 102 | exact (hu₂ j).1 103 | 104 | variable [NoMaxOrder ι] 105 | 106 | lemma IsStoppingTime.iInf {𝓕 : Filtration ι mΩ} {τ : ℕ → Ω → WithTop ι} 107 | (s : Set ℕ) (h𝓕 : IsRightContinuous 𝓕) (hτ : ∀ n, IsStoppingTime 𝓕 (τ n)) : 108 | IsStoppingTime 𝓕 (fun ω ↦ ⨅ (n) (_ : n ∈ s), τ n ω) := by 109 | refine isStoppingTime_of_measurableSet_lt_of_isRightContinuous h𝓕 <| fun i ↦ ?_ 110 | refine MeasurableSet.of_compl ?_ 111 | rw [(_ : {ω | ⨅ n ∈ s, τ n ω < i}ᶜ = ⋂ n ∈ s, {ω | i ≤ τ n ω})] 112 | · exact MeasurableSet.iInter <| fun n ↦ MeasurableSet.iInter <| fun hn ↦ (hτ n).measurableSet_ge i 113 | · ext ω 114 | simp only [Set.mem_compl_iff, Set.mem_setOf_eq, not_lt, le_iInf_iff, Set.mem_iInter] 115 | 116 | lemma stoppedProcess_min_eq_stoppedProcess {ι Ω E : Type*} [Nonempty ι] [LinearOrder ι] 117 | (X : ι → Ω → E) (τ : Ω → WithTop ι) {i j : ι} (hij : i ≤ j) : 118 | stoppedProcess X (fun ω ↦ min j (τ ω)) i = stoppedProcess X τ i := by 119 | simp [stoppedProcess_eq_stoppedValue, ← min_assoc, min_eq_left (WithTop.coe_le_coe.2 hij)] 120 | 121 | end MeasureTheory 122 | -------------------------------------------------------------------------------- /BrownianMotion/Gaussian/CovMatrix.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.Auxiliary.ContinuousBilinForm 7 | import BrownianMotion.Auxiliary.MeasureTheory 8 | import Mathlib.Analysis.InnerProductSpace.Adjoint 9 | import Mathlib.MeasureTheory.SpecificCodomains.WithLp 10 | import Mathlib.Probability.Distributions.Gaussian.Fernique 11 | import Mathlib.Probability.Moments.CovarianceBilinDual 12 | import Mathlib.Probability.Moments.CovarianceBilin 13 | import Mathlib.LinearAlgebra.BilinearForm.Properties 14 | 15 | /-! 16 | # Covariance matrix 17 | 18 | -/ 19 | 20 | open MeasureTheory InnerProductSpace NormedSpace WithLp 21 | open scoped ENNReal NNReal Matrix 22 | 23 | namespace ProbabilityTheory 24 | 25 | lemma isPosSemidef_covarianceBilinDual {E : Type*} [NormedAddCommGroup E] 26 | [NormedSpace ℝ E] [MeasurableSpace E] [BorelSpace E] {μ : Measure E} : 27 | ContinuousBilinForm.IsPosSemidef (covarianceBilinDual μ) where 28 | map_symm := covarianceBilinDual_comm 29 | nonneg_re_apply_self := covarianceBilinDual_self_nonneg 30 | 31 | variable {E : Type*} [NormedAddCommGroup E] [InnerProductSpace ℝ E] 32 | [MeasurableSpace E] [BorelSpace E] {μ : Measure E} 33 | 34 | nonrec 35 | lemma IsGaussian.covarianceBilin_apply [IsGaussian μ] [SecondCountableTopology E] [CompleteSpace E] 36 | (x y : E) : 37 | covarianceBilin μ x y = ∫ z, ⟪x, z - μ[id]⟫_ℝ * ⟪y, z - μ[id]⟫_ℝ ∂μ := 38 | covarianceBilin_apply IsGaussian.memLp_two_id x y 39 | 40 | lemma covarianceBilin_apply_prod {Ω : Type*} {mΩ : MeasurableSpace Ω} 41 | {μ : Measure Ω} [IsFiniteMeasure μ] {X Y : Ω → ℝ} 42 | (hX : MemLp X 2 μ) (hY : MemLp Y 2 μ) (x y : WithLp 2 (ℝ × ℝ)) : 43 | covarianceBilin (μ.map (fun ω ↦ toLp 2 (X ω, Y ω))) x y = 44 | x.fst * y.fst * Var[X; μ] + (x.fst * y.snd + x.snd * y.fst) * cov[X, Y; μ] + 45 | x.snd * y.snd * Var[Y; μ] := by 46 | have := hX.aemeasurable 47 | have := hY.aemeasurable 48 | nth_rw 1 [covarianceBilin_apply_eq_cov, covariance_map_fun] 49 | · simp only [prod_inner_apply, ofLp_fst, RCLike.inner_apply', conj_trivial, ofLp_snd] 50 | rw [covariance_fun_add_left, covariance_fun_add_right, covariance_fun_add_right] 51 | · simp_rw [covariance_const_mul_left, covariance_const_mul_right] 52 | rw [covariance_comm X Y, covariance_self, covariance_self] 53 | · ring 54 | · exact hY.aemeasurable 55 | · exact hX.aemeasurable 56 | any_goals exact MemLp.const_mul (by assumption) _ 57 | exact hX.const_mul _ |>.add <| hY.const_mul _ 58 | any_goals exact Measurable.aestronglyMeasurable (by fun_prop) 59 | · fun_prop 60 | · exact (memLp_map_measure_iff aestronglyMeasurable_id (by fun_prop)).2 61 | (MemLp.of_fst_of_snd_prodLp ⟨hX, hY⟩) 62 | 63 | lemma isPosSemidef_covarianceBilin' : 64 | LinearMap.BilinForm.IsPosSemidef (covarianceBilin μ).toBilinForm := by 65 | rw [LinearMap.BilinForm.isPosSemidef_iff] 66 | exact isPosSemidef_covarianceBilin 67 | 68 | lemma isSymm_covarianceBilin : 69 | LinearMap.BilinForm.IsSymm (covarianceBilin μ).toBilinForm := 70 | isPosSemidef_covarianceBilin'.1 71 | 72 | variable [FiniteDimensional ℝ E] 73 | 74 | /-- Covariance matrix of a measure on a finite dimensional inner product space. -/ 75 | noncomputable 76 | def covMatrix (μ : Measure E) : Matrix (Fin (Module.finrank ℝ E)) (Fin (Module.finrank ℝ E)) ℝ := 77 | BilinForm.toMatrix (stdOrthonormalBasis ℝ E).toBasis (covarianceBilin μ).toBilinForm 78 | 79 | lemma covMatrix_apply (μ : Measure E) (i j : Fin (Module.finrank ℝ E)) : 80 | covMatrix μ i j = 81 | covarianceBilin μ (stdOrthonormalBasis ℝ E i) (stdOrthonormalBasis ℝ E j) := by 82 | simp [covMatrix] 83 | 84 | lemma covMatrix_mulVec (x : Fin (Module.finrank ℝ E) → ℝ) : 85 | (covMatrix μ).mulVec x = fun i ↦ 86 | covarianceBilin μ (stdOrthonormalBasis ℝ E i) (∑ j, x j • stdOrthonormalBasis ℝ E j) := by 87 | ext 88 | simp [covMatrix, Matrix.mulVec_eq_sum] 89 | 90 | lemma dotProduct_covMatrix_mulVec (x y : Fin (Module.finrank ℝ E) → ℝ) : 91 | x ⬝ᵥ (covMatrix μ).mulVec y = 92 | covarianceBilin μ (∑ j, x j • stdOrthonormalBasis ℝ E j) 93 | (∑ j, y j • stdOrthonormalBasis ℝ E j) := by 94 | simp_rw [covMatrix, BilinForm.dotProduct_toMatrix_mulVec, 95 | Module.Basis.equivFun_symm_apply, OrthonormalBasis.coe_toBasis] 96 | simp 97 | 98 | lemma covarianceBilin_eq_dotProduct_covMatrix_mulVec (x y : E) : 99 | covarianceBilin μ x y = 100 | ((stdOrthonormalBasis ℝ E).repr x) ⬝ᵥ 101 | ((covMatrix μ).mulVec ((stdOrthonormalBasis ℝ E).repr y)) := by 102 | rw [ContinuousBilinForm.apply_eq_dotProduct_toMatrix_mulVec _ (stdOrthonormalBasis ℝ E).toBasis] 103 | rfl 104 | 105 | lemma covMatrix_map {F : Type*} [NormedAddCommGroup F] [InnerProductSpace ℝ F] 106 | [MeasurableSpace F] [BorelSpace F] [FiniteDimensional ℝ F] 107 | [IsFiniteMeasure μ] (h : MemLp id 2 μ) (L : E →L[ℝ] F) (i j : Fin (Module.finrank ℝ F)) : 108 | covMatrix (μ.map L) i j = 109 | (stdOrthonormalBasis ℝ E).repr (L.adjoint (stdOrthonormalBasis ℝ F i)) ⬝ᵥ ((covMatrix μ) *ᵥ 110 | (stdOrthonormalBasis ℝ E).repr (L.adjoint (stdOrthonormalBasis ℝ F j))) := by 111 | rw [covMatrix_apply, covarianceBilin_map h, covarianceBilin_eq_dotProduct_covMatrix_mulVec] 112 | 113 | lemma posSemidef_covMatrix : (covMatrix μ).PosSemidef := by 114 | rw [covMatrix, ← LinearMap.BilinForm.isPosSemidef_iff_posSemidef_toMatrix, 115 | LinearMap.BilinForm.isPosSemidef_iff] 116 | exact isPosSemidef_covarianceBilin 117 | 118 | end ProbabilityTheory 119 | -------------------------------------------------------------------------------- /BrownianMotion/Auxiliary/Topology.lean: -------------------------------------------------------------------------------- 1 | import Mathlib.Topology.MetricSpace.HolderNorm 2 | 3 | open Bornology Filter 4 | 5 | open scoped NNReal ENNReal Topology 6 | 7 | lemma eventually_nhdsGT {α : Type*} [TopologicalSpace α] [LinearOrder α] [ClosedIciTopology α] 8 | {a b : α} (hab : a < b) {p : α → Prop} (h : ∀ x ∈ Set.Ioc a b, p x) : 9 | ∀ᶠ x in 𝓝[>] a, p x := 10 | sets_of_superset (x := Set.Ioo a b) _ (Ioo_mem_nhdsGT hab) (by grind) 11 | 12 | variable {X Y : Type*} [PseudoEMetricSpace X] [PseudoEMetricSpace Y] [CompleteSpace Y] 13 | {C r : ℝ≥0} {s : Set X} {f : s → Y} 14 | 15 | lemma neBot_comap_nhds (hs : Dense s) (x : X) : ((𝓝 x).comap ((↑) : s → X)).NeBot := 16 | hs.isDenseInducing_val.comap_nhds_neBot _ 17 | 18 | lemma Dense.holderWith_extend (hs : Dense s) (hf : HolderWith C r f) (hr : 0 < r) : 19 | HolderWith C r (hs.extend f) := by 20 | intro x y 21 | have hf' := hf.uniformContinuous hr 22 | have := neBot_comap_nhds hs 23 | have hx := hs.extend_spec hf' x 24 | have hy := hs.extend_spec hf' y 25 | refine le_of_tendsto_of_tendsto' 26 | (b := ((𝓝 x).comap ((↑) : s → X)) ×ˢ ((𝓝 y).comap ((↑) : s → X))) ?_ ?_ 27 | fun z : s × s ↦ hf z.1 z.2 28 | · change Tendsto (edist.uncurry ∘ (fun z : s × s ↦ (f z.1, f z.2))) _ _ 29 | refine (Continuous.tendsto (by fun_prop) (hs.extend f x, hs.extend f y)).comp ?_ 30 | exact Tendsto.prodMk_nhds (hx.comp tendsto_fst) (hy.comp tendsto_snd) 31 | · simp_rw [Subtype.edist_eq] 32 | change Tendsto ((fun z ↦ C * edist z.1 z.2 ^ r.toReal) ∘ (fun z : s × s ↦ (z.1.1, z.2.1))) _ _ 33 | refine (Continuous.tendsto ?_ (x, y)).comp ?_ 34 | · fun_prop (disch := exact ENNReal.coe_ne_top) 35 | exact Tendsto.prodMk_nhds (tendsto_comap.comp tendsto_fst) (tendsto_comap.comp tendsto_snd) 36 | 37 | lemma PseudoEMetricSpace.boundedSpace_toPseudoMetricSpace {C : ℝ≥0} 38 | (hX : ∀ x y : X, edist x y ≤ C) : 39 | letI := PseudoEMetricSpace.toPseudoMetricSpace 40 | fun x y ↦ ne_top_of_le_ne_top ENNReal.coe_ne_top (hX x y) 41 | BoundedSpace X := by 42 | letI := PseudoEMetricSpace.toPseudoMetricSpace 43 | fun x y ↦ ne_top_of_le_ne_top ENNReal.coe_ne_top (hX x y) 44 | rw [Metric.boundedSpace_iff] 45 | refine ⟨C, fun x y ↦ ?_⟩ 46 | grw [dist_edist, hX, ENNReal.coe_toReal] 47 | exact ENNReal.coe_ne_top 48 | 49 | lemma MemHolder.mono {X Y : Type*} [PseudoMetricSpace X] [hX : BoundedSpace X] 50 | [PseudoEMetricSpace Y] {f : X → Y} {r s : ℝ≥0} (hf : MemHolder r f) (hs : s ≤ r) : 51 | MemHolder s f := by 52 | obtain ⟨C, hf⟩ := hf 53 | obtain rfl | hr := eq_zero_or_pos r 54 | · rw [nonpos_iff_eq_zero.1 hs] 55 | exact ⟨C, hf⟩ 56 | obtain ⟨C', hC'⟩ := Metric.boundedSpace_iff_nndist.1 hX 57 | refine ⟨C * C' ^ (r - s : ℝ), fun x y ↦ ?_⟩ 58 | obtain h | h := eq_or_ne (edist x y) 0 59 | · have := hf x y 60 | simp_all 61 | nth_grw 1 [hf x y, ← sub_add_cancel r.toReal s, ENNReal.rpow_add _ _ h (edist_ne_top _ _), 62 | edist_nndist, edist_nndist, edist_nndist, hC', ENNReal.coe_mul, mul_assoc, 63 | ENNReal.coe_rpow_of_nonneg] 64 | all_goals simpa 65 | 66 | lemma MemHolder.mono' {X Y : Type*} [PseudoEMetricSpace X] [PseudoEMetricSpace Y] 67 | {f : X → Y} {r s : ℝ≥0} (hf : MemHolder r f) (hs : s ≤ r) {C' : ℝ≥0} 68 | (hX : ∀ x y : X, edist x y ≤ C') : 69 | MemHolder s f := by 70 | letI := PseudoEMetricSpace.toPseudoMetricSpace 71 | fun x y ↦ ne_top_of_le_ne_top ENNReal.coe_ne_top (hX x y) 72 | have := PseudoEMetricSpace.boundedSpace_toPseudoMetricSpace hX 73 | exact hf.mono hs 74 | 75 | lemma HolderOnWith.mono_right {X Y : Type*} [PseudoMetricSpace X] [PseudoEMetricSpace Y] 76 | {f : X → Y} {C r s : ℝ≥0} {t : Set X} (hf : HolderOnWith C r f t) (hs : s ≤ r) 77 | (ht : IsBounded t) : ∃ C', HolderOnWith C' s f t := by 78 | simp_rw [← HolderWith.restrict_iff] at * 79 | have : BoundedSpace t := boundedSpace_val_set_iff.2 ht 80 | exact MemHolder.mono ⟨C, hf⟩ hs 81 | 82 | lemma HolderOnWith.mono_right' {X Y : Type*} [PseudoEMetricSpace X] [PseudoEMetricSpace Y] 83 | {f : X → Y} {C r s : ℝ≥0} {t : Set X} (hf : HolderOnWith C r f t) (hs : s ≤ r) 84 | {C' : ℝ≥0} (ht : ∀ ⦃x⦄, x ∈ t → ∀ ⦃y⦄, y ∈ t → edist x y ≤ C') : 85 | ∃ C', HolderOnWith C' s f t := by 86 | simp_rw [← HolderWith.restrict_iff] at * 87 | letI := PseudoEMetricSpace.toPseudoMetricSpace 88 | fun x y : t ↦ ne_top_of_le_ne_top ENNReal.coe_ne_top (ht x.2 y.2) 89 | have : BoundedSpace t := 90 | PseudoEMetricSpace.boundedSpace_toPseudoMetricSpace fun x y : t ↦ ht x.2 y.2 91 | exact MemHolder.mono ⟨C, hf⟩ hs 92 | 93 | lemma HolderWith.HolderWith_of_le_of_le {X Y : Type*} [PseudoEMetricSpace X] [PseudoEMetricSpace Y] 94 | {f : X → Y} {C₁ C₂ r s t : ℝ≥0} (hf₁ : HolderWith C₁ r f) (hf₂ : HolderWith C₂ t f) 95 | (hrs : r ≤ s) (hst : s ≤ t) : HolderWith (max C₁ C₂) s f := by 96 | intro x y 97 | obtain h | h := le_total (edist x y) 1 98 | · grw [hf₂ x y] 99 | refine mul_le_mul ?_ ?_ ?_ ?_ 100 | · gcongr 101 | exact le_max_right _ _ 102 | · exact ENNReal.rpow_le_rpow_of_exponent_ge h (by norm_cast) 103 | all_goals simp 104 | · grw [hf₁ x y] 105 | refine mul_le_mul ?_ ?_ ?_ ?_ 106 | · gcongr 107 | exact le_max_left _ _ 108 | · exact ENNReal.rpow_le_rpow_of_exponent_le h (by norm_cast) 109 | all_goals simp 110 | 111 | lemma HolderOnWith.holderOnWith_of_le_of_le {X Y : Type*} [PseudoEMetricSpace X] 112 | [PseudoEMetricSpace Y] {f : X → Y} {C₁ C₂ r s t : ℝ≥0} {u : Set X} 113 | (hf₁ : HolderOnWith C₁ r f u) (hf₂ : HolderOnWith C₂ t f u) 114 | (hrs : r ≤ s) (hst : s ≤ t) : HolderOnWith (max C₁ C₂) s f u := by 115 | simp_rw [← HolderWith.restrict_iff] at * 116 | exact hf₁.HolderWith_of_le_of_le hf₂ hrs hst 117 | -------------------------------------------------------------------------------- /Manuscript/main.bib: -------------------------------------------------------------------------------- 1 | @book{karatzas1991brownian, 2 | title={Brownian motion and stochastic calculus}, 3 | author={Karatzas, Ioannis and Shreve, Steven}, 4 | volume={113}, 5 | year={1991}, 6 | publisher={Springer Science \& Business Media} 7 | } 8 | 9 | @inproceedings{ying2023formalization, 10 | title={A Formalization of {D}oob’s Martingale Convergence Theorems in mathlib}, 11 | author={K. Ying and R. Degenne}, 12 | booktitle={Proceedings of the 12th ACM SIGPLAN International Conference on Certified Programs and Proofs}, 13 | pages={334--347}, 14 | year={2023} 15 | } 16 | 17 | @Book{EthierKurtz1986, 18 | Author = {S.N. Ethier and T.G. Kurtz}, 19 | Title = {Markov {P}rocesses. {C}haracterization and 20 | {C}onvergence}, 21 | Publisher = {John Wiley, New York}, 22 | year = 1986, 23 | } 24 | 25 | @article{sheffield2007gaussian, 26 | title={Gaussian free fields for mathematicians}, 27 | author={Sheffield, S.}, 28 | journal={Probability theory and related fields}, 29 | volume={139}, 30 | number={3-4}, 31 | pages={521--541}, 32 | year={2007}, 33 | publisher={Springer} 34 | } 35 | 36 | @article{chin2019new, 37 | title={New simple proofs of the Kolmogorov extension theorem and {P}rokhorov's theorem}, 38 | author={Chin, W.}, 39 | journal={arXiv preprint arXiv:1911.12979}, 40 | year={2019} 41 | } 42 | 43 | @book{guide2006infinite, 44 | title={Infinite dimensional analysis. A Hitchhiker’s Guide}, 45 | author={C. D. Aliprantis}, 46 | year={2006}, 47 | publisher={Springer} 48 | } 49 | 50 | @article{rao1971projective, 51 | title={Projective limits of probability spaces}, 52 | author={Rao, M. M.}, 53 | journal={Journal of multivariate analysis}, 54 | volume={1}, 55 | number={1}, 56 | pages={28--57}, 57 | year={1971}, 58 | publisher={Elsevier} 59 | } 60 | 61 | @misc{border1998expository, 62 | title={Expository Notes on the {K}olmogorov Extension Problem}, 63 | author={Border, K. C.}, 64 | year={1998}, 65 | publisher={Caltech Pasadena} 66 | } 67 | 68 | @book{bogachev2007measure, 69 | title={Measure theory}, 70 | author={V. I. Bogachev and M. A. S. Ruas}, 71 | volume={1}, 72 | year={2007}, 73 | publisher={Springer} 74 | } 75 | @article{melikhov2011metrizable, 76 | title={Metrizable uniform spaces}, 77 | author={Melikhov, S. A}, 78 | journal={arXiv preprint arXiv:1106.3249}, 79 | year={2011} 80 | } 81 | 82 | @book{james2013topologies, 83 | title={Topologies and uniformities}, 84 | author={James, I. M}, 85 | year={2013}, 86 | publisher={Springer Science \& Business Media} 87 | } 88 | @book{Kallenberg2020, 89 | author="Kallenberg, O.", 90 | title="{Foundations of Modern Probability. 3rd ed.}", 91 | publisher="{Probability and Its Applications. New York, NY: Springer.}", 92 | year=2020, 93 | keywords="{measure theory; probability theory; stochastic processes}", 94 | } 95 | 96 | @article{avigad2017formally, 97 | title={A formally verified proof of the central limit theorem}, 98 | author={J. Avigad and J. H{\"o}lzl and L. Serafin}, 99 | journal={Journal of Automated Reasoning}, 100 | volume={59}, 101 | pages={389--423}, 102 | year={2017}, 103 | publisher={Springer} 104 | } 105 | 106 | @inproceedings{mathlib2020lean, 107 | title={The Lean mathematical library}, 108 | author={mathlib Community.}, 109 | booktitle={Proceedings of the 9th ACM SIGPLAN International Conference on Certified Programs and Proofs (CPP 2020)}, 110 | pages={367--381}, 111 | year={2020} 112 | } 113 | 114 | @book{kolmogoroff1933grundbegriffe, 115 | title={Grundbegriffe der wahrscheinlichkeitsrechnung}, 116 | author={A. Kolmogoroff}, 117 | year={1933}, 118 | publisher={Springer} 119 | } 120 | 121 | @article{holzl2017markov, 122 | title={Markov chains and Markov decision processes in Isabelle/HOL}, 123 | author={H{\"o}lzl, J.}, 124 | journal={Journal of Automated Reasoning}, 125 | volume={59}, 126 | number={3}, 127 | pages={345--387}, 128 | year={2017}, 129 | publisher={Springer} 130 | } 131 | 132 | @inproceedings{holzl2017markov, 133 | title={Markov processes in {Isabelle/HOL}}, 134 | author={H{\"o}lzl, J.}, 135 | booktitle={Proceedings of the 6th ACM SIGPLAN Conference on Certified Programs and Proofs}, 136 | pages={100--111}, 137 | year={2017} 138 | } 139 | 140 | @article{aldrich2007but, 141 | title={But you have to remember {PJ D}aniell of {S}heffield}, 142 | author={Aldrich, John}, 143 | journal={Electronic Journal for History of Probability and Statistics (www. jehps. net)}, 144 | volume={3}, 145 | number={2}, 146 | year={2007} 147 | } 148 | 149 | @book{Billingsley1995, 150 | author="Billingsley, P.", 151 | title="{Probability and Measure. 3rd ed.}", 152 | publisher="{Wiley Series in 153 | Probability and Statistics}", 154 | year=1995, 155 | keywords="{measure theory; probability theory; stochastic processes}", 156 | } 157 | 158 | @misc{Immler2012, 159 | author = "Immler, F.", 160 | title = "Generic 161 | Construction of Probability Spaces for Paths of Stochastic Processes in Isabelle/HOL", 162 | journal = "Master’s Thesis in Informatik, TU Munich", 163 | year = "2012", 164 | URL ="https://saloranta.de/immler/fabian/mastersthesis/thesis.pdf" 165 | } 166 | 167 | @book{Klenke2013, 168 | author = "Klenke, A.", 169 | title = "Probability Theory. A Comprehensive Course. 2nd ed.", 170 | publisher = {Springer}, 171 | year = "2013", 172 | } 173 | 174 | @inproceedings{moura2021lean, 175 | title={The lean 4 theorem prover and programming language}, 176 | author={Moura, L. de and Ullrich, S.}, 177 | booktitle={Automated Deduction--CADE 28: 28th International Conference on Automated Deduction, Virtual Event, July 12--15, 2021, Proceedings 28}, 178 | pages={625--635}, 179 | year={2021}, 180 | organization={Springer} 181 | } 182 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at https://leanprover.zulipchat.com/#narrow/channel/509433-Brownian-motion or directly to Rémy Degenne via Zulip DM. 63 | All complaints will be reviewed and investigated promptly and fairly. 64 | 65 | All community leaders are obligated to respect the privacy and security of the 66 | reporter of any incident. 67 | 68 | ## Enforcement Guidelines 69 | 70 | Community leaders will follow these Community Impact Guidelines in determining 71 | the consequences for any action they deem in violation of this Code of Conduct: 72 | 73 | ### 1. Correction 74 | 75 | **Community Impact**: Use of inappropriate language or other behavior deemed 76 | unprofessional or unwelcome in the community. 77 | 78 | **Consequence**: A private, written warning from community leaders, providing 79 | clarity around the nature of the violation and an explanation of why the 80 | behavior was inappropriate. A public apology may be requested. 81 | 82 | ### 2. Warning 83 | 84 | **Community Impact**: A violation through a single incident or series 85 | of actions. 86 | 87 | **Consequence**: A warning with consequences for continued behavior. No 88 | interaction with the people involved, including unsolicited interaction with 89 | those enforcing the Code of Conduct, for a specified period of time. This 90 | includes avoiding interactions in community spaces as well as external channels 91 | like social media. Violating these terms may lead to a temporary or 92 | permanent ban. 93 | 94 | ### 3. Temporary Ban 95 | 96 | **Community Impact**: A serious violation of community standards, including 97 | sustained inappropriate behavior. 98 | 99 | **Consequence**: A temporary ban from any sort of interaction or public 100 | communication with the community for a specified period of time. No public or 101 | private interaction with the people involved, including unsolicited interaction 102 | with those enforcing the Code of Conduct, is allowed during this period. 103 | Violating these terms may lead to a permanent ban. 104 | 105 | ### 4. Permanent Ban 106 | 107 | **Community Impact**: Demonstrating a pattern of violation of community 108 | standards, including sustained inappropriate behavior, harassment of an 109 | individual, or aggression toward or disparagement of classes of individuals. 110 | 111 | **Consequence**: A permanent ban from any sort of public interaction within 112 | the community. 113 | 114 | ## Attribution 115 | 116 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 117 | version 2.0, available at 118 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 119 | 120 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 121 | enforcement ladder](https://github.com/mozilla/diversity). 122 | 123 | [homepage]: https://www.contributor-covenant.org 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | https://www.contributor-covenant.org/faq. Translations are available at 127 | https://www.contributor-covenant.org/translations. 128 | -------------------------------------------------------------------------------- /verso/Manual/Front.lean: -------------------------------------------------------------------------------- 1 | import Manual.Pages.Processes 2 | import Manual.Pages.Extension 3 | import Manual.Pages.Gaussian 4 | import Manual.Pages.Continuity 5 | import VersoManual 6 | 7 | open Verso.Genre Manual Verso.Genre.Manual.InlineLean Verso.Code.External 8 | 9 | set_option pp.rawOnError true 10 | 11 | set_option verso.exampleProject "../" 12 | 13 | set_option verso.exampleModule "BrownianMotion.Verso.Brownian" 14 | 15 | #doc (Manual) "Formalization of Brownian motion" => 16 | %%% 17 | authors := ["Rémy Degenne, David Ledvinka, Etienne Marion, Peter Pfaffelhuber"] 18 | shortTitle := "Formalization of Brownian motion" 19 | %%% 20 | 21 | *The Brownian motion project* 22 | 23 | This is a collaborative formalization project, in which we formalized the following results: 24 | - Kolmogorov extension theorem 25 | - Gaussian measures and their properties 26 | - Kolmogorov-Chentsov continuity theorem 27 | - Putting everything together: construction of a Brownian motion on the nonnegative reals. 28 | 29 | Besides the main authors, contributions were made by Markus Himmel, Jonas Bayer, Lorenzo Luccioli, Alessio Rondelli and Jérémy Scanvic, with technical support from Pietro Monticone. 30 | 31 | *Main result: construction of a Brownian motion* 32 | 33 | A stochastic process `ℝ≥0 → Ω → ℝ` is called *Brownian* if its finite-dimensional law for points $`t_1, ..., t_n` is a multivariate Gaussian with mean zero and covariance matrix given by $`min(t_i, t_j)`, and if it has almost-sure continuous paths. 34 | 35 | We formalize the finite dimensional laws and the law of Brownian motion by constructing a projective family of finite-dimensional Gaussian measures with the correct covariance structure, and then taking its projective limit. 36 | 37 | For a finite set `(I : Finset ℝ≥0)`, we define the covariance matrix {anchorTerm Measures}`brownianCovMatrix I` with entries `min s t` for `(s t : I)`. 38 | Then, we define a family of multivaliate Gaussian measures, with mean zero and that covariance matrix. 39 | Finally, we take the projective limit of this family, `gaussianLimit`. 40 | 41 | ```anchor Measures 42 | example (I : Finset ℝ≥0) : 43 | brownianCovMatrix I = Matrix.of fun s t ↦ min s.1 t.1 := rfl 44 | 45 | example (I : Finset ℝ≥0) : 46 | gaussianProjectiveFamily I = 47 | (multivariateGaussian 0 (brownianCovMatrix I)).map 48 | (MeasurableEquiv.toLp 2 (I → ℝ)).symm := 49 | rfl 50 | 51 | example : (gaussianLimit : Measure Ω) = 52 | projectiveLimit gaussianProjectiveFamily 53 | isProjectiveMeasureFamily_gaussianProjectiveFamily := rfl 54 | ``` 55 | 56 | The main result of the Brownian motion project is the construction of a process with that law and continuous paths. 57 | Let's build one now, and first check that it has the right laws. 58 | We write `Ω` for the probability space `ℝ≥0 → ℝ` endowed with the probability measure `gaussianLimit`. 59 | 60 | ```anchor Brownian 61 | def B : ℝ≥0 → Ω → ℝ := brownian 62 | 63 | example (t : ℝ≥0) : HasLaw (B t) (gaussianReal 0 t) := 64 | hasLaw_brownian_eval 65 | 66 | example (s t : ℝ≥0) : cov[B s, B t] = min s t := 67 | covariance_brownian s t 68 | 69 | example (s t : ℝ≥0) : 70 | HasLaw (B s - B t) (gaussianReal 0 (max (s - t) (t - s))) := 71 | hasLaw_brownian_sub 72 | 73 | example (I : Finset ℝ≥0) : 74 | HasLaw (fun ω ↦ I.restrict (B · ω)) (gaussianProjectiveFamily I) := 75 | hasLaw_restrict_brownian 76 | ``` 77 | 78 | The stochastic process {anchorTerm Brownian}`B` is such that {anchorTerm Brownian}`B t` has law {anchorTerm Brownian}`gaussianReal 0 t` for every `t : ℝ≥0`, with covariance structure given by {anchorTerm Brownian}`cov[B s, B t] = min s t`. 79 | We also derived the law of its increments, and importantly to check that it has the right law, we checked that its finite-dimensional distributions match the projective family we constructed before. 80 | 81 | Finally, we can check that {anchorTerm Brownian}`B` has continuous paths. 82 | It even satisfies a stronger regularity property: local Hölder continuity. 83 | 84 | ```anchor Continuity 85 | example (ω : Ω) (t β : ℝ≥0) (hβ_pos : 0 < β) (hβ_lt : β < 2⁻¹) : 86 | ∃ U ∈ 𝓝 t, ∃ C, HolderOnWith C β (B · ω) U := 87 | memHolder_brownian ω t β hβ_pos hβ_lt 88 | 89 | example (ω : Ω) : Continuous (B · ω) := continuous_brownian ω 90 | ``` 91 | 92 | *Other properties of Brownian motion* 93 | 94 | First, we check that {anchorTerm Brownian}`B` has independent increments, and we prove that any process with the same one-dimensional marginals and independent increments has the same law as {anchorTerm Brownian}`B` (but it might not be continuous). 95 | 96 | ```anchor HasIndepIncrements 97 | example : HasIndepIncrements B := hasIndepIncrements_brownian 98 | 99 | example (X : ℝ≥0 → Ω → ℝ) (hX : AEMeasurable (fun ω ↦ (X · ω))) 100 | (law : ∀ t, HasLaw (X t) (gaussianReal 0 t)) (incr : HasIndepIncrements X) : 101 | HasLaw (fun ω ↦ (X · ω)) gaussianLimit := 102 | (incr.isPreBrownian_of_hasLaw law).hasLaw_gaussianLimit hX 103 | ``` 104 | 105 | Finally, we prove some classical transformations of Brownian motion: scaling, time shift, inversion. 106 | Note that we use the typeclass {anchorTerm Transformations}`IsBrownian` to state that a process is a Brownian motion (it has the right law and has almost surely continuous paths). 107 | 108 | ```anchor Transformations 109 | variable {X : ℝ≥0 → Ω → ℝ} 110 | 111 | example [IsBrownian X] {c : ℝ≥0} (hc : c ≠ 0) : 112 | IsBrownian (fun t ω ↦ (X (c * t) ω) / √c) := 113 | IsBrownian.smul hc 114 | 115 | example [IsBrownian X] (t₀ : ℝ≥0) : 116 | IsBrownian (fun t ω ↦ X (t₀ + t) ω - X t₀ ω) := 117 | IsBrownian.shift t₀ 118 | 119 | example [IsBrownian X] : 120 | IsBrownian (fun t ω ↦ t * (X (1 / t) ω)) := 121 | IsBrownian.inv 122 | 123 | example [IsBrownian X] : 124 | ∀ᵐ ω, Filter.Tendsto (X · ω) (𝓝 0) (𝓝 0) := 125 | IsBrownian.tendsto_nhds_zero 126 | ``` 127 | 128 | If you want to learn more about the formalization of the definitions and theorems that led to this Brownian motion construction, you can check the other pages of this manual. 129 | 130 | {include 0 Manual.Pages.Processes} 131 | 132 | {include 0 Manual.Pages.Extension} 133 | 134 | {include 0 Manual.Pages.Gaussian} 135 | 136 | {include 0 Manual.Pages.Continuity} 137 | -------------------------------------------------------------------------------- /Manuscript/_minted-proof_outline/default-pyg-prefix.pygstyle: -------------------------------------------------------------------------------- 1 | 2 | \makeatletter 3 | \def\PYG@reset{\let\PYG@it=\relax \let\PYG@bf=\relax% 4 | \let\PYG@ul=\relax \let\PYG@tc=\relax% 5 | \let\PYG@bc=\relax \let\PYG@ff=\relax} 6 | \def\PYG@tok#1{\csname PYG@tok@#1\endcsname} 7 | \def\PYG@toks#1+{\ifx\relax#1\empty\else% 8 | \PYG@tok{#1}\expandafter\PYG@toks\fi} 9 | \def\PYG@do#1{\PYG@bc{\PYG@tc{\PYG@ul{% 10 | \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}} 11 | \def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}} 12 | 13 | \@namedef{PYG@tok@w}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}} 14 | \@namedef{PYG@tok@c}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.24,0.48,0.48}{##1}}} 15 | \@namedef{PYG@tok@cp}{\def\PYG@tc##1{\textcolor[rgb]{0.61,0.40,0.00}{##1}}} 16 | \@namedef{PYG@tok@k}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 17 | \@namedef{PYG@tok@kp}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 18 | \@namedef{PYG@tok@kt}{\def\PYG@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}} 19 | \@namedef{PYG@tok@o}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 20 | \@namedef{PYG@tok@ow}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}} 21 | \@namedef{PYG@tok@nb}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 22 | \@namedef{PYG@tok@nf}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}} 23 | \@namedef{PYG@tok@nc}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}} 24 | \@namedef{PYG@tok@nn}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}} 25 | \@namedef{PYG@tok@ne}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.80,0.25,0.22}{##1}}} 26 | \@namedef{PYG@tok@nv}{\def\PYG@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 27 | \@namedef{PYG@tok@no}{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}} 28 | \@namedef{PYG@tok@nl}{\def\PYG@tc##1{\textcolor[rgb]{0.46,0.46,0.00}{##1}}} 29 | \@namedef{PYG@tok@ni}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.44,0.44,0.44}{##1}}} 30 | \@namedef{PYG@tok@na}{\def\PYG@tc##1{\textcolor[rgb]{0.41,0.47,0.13}{##1}}} 31 | \@namedef{PYG@tok@nt}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 32 | \@namedef{PYG@tok@nd}{\def\PYG@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}} 33 | \@namedef{PYG@tok@s}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 34 | \@namedef{PYG@tok@sd}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 35 | \@namedef{PYG@tok@si}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.64,0.35,0.47}{##1}}} 36 | \@namedef{PYG@tok@se}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.67,0.36,0.12}{##1}}} 37 | \@namedef{PYG@tok@sr}{\def\PYG@tc##1{\textcolor[rgb]{0.64,0.35,0.47}{##1}}} 38 | \@namedef{PYG@tok@ss}{\def\PYG@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 39 | \@namedef{PYG@tok@sx}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 40 | \@namedef{PYG@tok@m}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 41 | \@namedef{PYG@tok@gh}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} 42 | \@namedef{PYG@tok@gu}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}} 43 | \@namedef{PYG@tok@gd}{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}} 44 | \@namedef{PYG@tok@gi}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.52,0.00}{##1}}} 45 | \@namedef{PYG@tok@gr}{\def\PYG@tc##1{\textcolor[rgb]{0.89,0.00,0.00}{##1}}} 46 | \@namedef{PYG@tok@ge}{\let\PYG@it=\textit} 47 | \@namedef{PYG@tok@gs}{\let\PYG@bf=\textbf} 48 | \@namedef{PYG@tok@gp}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} 49 | \@namedef{PYG@tok@go}{\def\PYG@tc##1{\textcolor[rgb]{0.44,0.44,0.44}{##1}}} 50 | \@namedef{PYG@tok@gt}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}} 51 | \@namedef{PYG@tok@err}{\def\PYG@bc##1{{\setlength{\fboxsep}{\string -\fboxrule}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}} 52 | \@namedef{PYG@tok@kc}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 53 | \@namedef{PYG@tok@kd}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 54 | \@namedef{PYG@tok@kn}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 55 | \@namedef{PYG@tok@kr}{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 56 | \@namedef{PYG@tok@bp}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}} 57 | \@namedef{PYG@tok@fm}{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}} 58 | \@namedef{PYG@tok@vc}{\def\PYG@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 59 | \@namedef{PYG@tok@vg}{\def\PYG@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 60 | \@namedef{PYG@tok@vi}{\def\PYG@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 61 | \@namedef{PYG@tok@vm}{\def\PYG@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}} 62 | \@namedef{PYG@tok@sa}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 63 | \@namedef{PYG@tok@sb}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 64 | \@namedef{PYG@tok@sc}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 65 | \@namedef{PYG@tok@dl}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 66 | \@namedef{PYG@tok@s2}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 67 | \@namedef{PYG@tok@sh}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 68 | \@namedef{PYG@tok@s1}{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}} 69 | \@namedef{PYG@tok@mb}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 70 | \@namedef{PYG@tok@mf}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 71 | \@namedef{PYG@tok@mh}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 72 | \@namedef{PYG@tok@mi}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 73 | \@namedef{PYG@tok@il}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 74 | \@namedef{PYG@tok@mo}{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 75 | \@namedef{PYG@tok@ch}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.24,0.48,0.48}{##1}}} 76 | \@namedef{PYG@tok@cm}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.24,0.48,0.48}{##1}}} 77 | \@namedef{PYG@tok@cpf}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.24,0.48,0.48}{##1}}} 78 | \@namedef{PYG@tok@c1}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.24,0.48,0.48}{##1}}} 79 | \@namedef{PYG@tok@cs}{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.24,0.48,0.48}{##1}}} 80 | 81 | \def\PYGZbs{\char`\\} 82 | \def\PYGZus{\char`\_} 83 | \def\PYGZob{\char`\{} 84 | \def\PYGZcb{\char`\}} 85 | \def\PYGZca{\char`\^} 86 | \def\PYGZam{\char`\&} 87 | \def\PYGZlt{\char`\<} 88 | \def\PYGZgt{\char`\>} 89 | \def\PYGZsh{\char`\#} 90 | \def\PYGZpc{\char`\%} 91 | \def\PYGZdl{\char`\$} 92 | \def\PYGZhy{\char`\-} 93 | \def\PYGZsq{\char`\'} 94 | \def\PYGZdq{\char`\"} 95 | \def\PYGZti{\char`\~} 96 | % for compatibility with earlier versions 97 | \def\PYGZat{@} 98 | \def\PYGZlb{[} 99 | \def\PYGZrb{]} 100 | \makeatother 101 | 102 | -------------------------------------------------------------------------------- /BrownianMotion/Continuity/HasBoundedInternalCoveringNumber.lean: -------------------------------------------------------------------------------- 1 | /- 2 | Copyright (c) 2025 Rémy Degenne. All rights reserved. 3 | Released under Apache 2.0 license as described in the file LICENSE. 4 | Authors: Rémy Degenne 5 | -/ 6 | import BrownianMotion.Continuity.CoveringNumber 7 | 8 | /-! 9 | # HasBoundedCoveringNumber 10 | 11 | -/ 12 | 13 | open MeasureTheory Metric 14 | open scoped ENNReal NNReal 15 | 16 | variable {T : Type*} [PseudoEMetricSpace T] {A : Set T} {c : ℝ≥0∞} {ε : ℝ≥0} {d : ℝ} 17 | 18 | /-- A set `A` in a pseudoemetric space has bounded covering number with constant `c` and exponent 19 | `d` if it has finite diameter and for all `ε ∈ (0, diam(A)]`, the covering number of `A` 20 | at scale `ε` is bounded by `c * ε^{-d}`. -/ 21 | structure HasBoundedCoveringNumber (A : Set T) (c : ℝ≥0∞) (d : ℝ) : Prop where 22 | ediam_lt_top : EMetric.diam A < ∞ 23 | coveringNumber_le : ∀ ε : ℝ≥0, ε ≤ EMetric.diam A → coveringNumber ε A ≤ c * (ε : ℝ≥0∞)⁻¹ ^ d 24 | 25 | lemma HasBoundedCoveringNumber.coveringNumber_lt_top 26 | (h : HasBoundedCoveringNumber A c d) (hε_ne : ε ≠ 0) 27 | (hc : c ≠ ∞) (hd : 0 ≤ d) : 28 | coveringNumber ε A < ⊤ := by 29 | by_cases hε_le : ε ≤ EMetric.diam A 30 | · suffices (coveringNumber ε A : ℝ≥0∞) < ∞ by norm_cast at this 31 | calc (coveringNumber ε A : ℝ≥0∞) 32 | _ ≤ c * (ε : ℝ≥0∞)⁻¹ ^ d := h.coveringNumber_le _ hε_le 33 | _ < ∞ := by 34 | refine ENNReal.mul_lt_top hc.lt_top ?_ 35 | exact ENNReal.rpow_lt_top_of_nonneg hd (by simp [hε_ne]) 36 | · calc coveringNumber ε A 37 | _ ≤ 1 := coveringNumber_le_one_of_ediam_le (not_le.mp hε_le).le 38 | _ < ⊤ := by simp 39 | 40 | lemma HasBoundedCoveringNumber.subset {B : Set T} 41 | (h : HasBoundedCoveringNumber A c d) (hBA : B ⊆ A) (hd : 0 ≤ d) : 42 | HasBoundedCoveringNumber B (2 ^ d * c) d := by 43 | constructor 44 | · exact lt_of_le_of_lt (EMetric.diam_mono hBA) h.ediam_lt_top 45 | intro ε hε_le 46 | by_cases hdA : d = 0 ∧ EMetric.diam A = ∞ 47 | · simp only [hdA.1, ENNReal.rpow_zero, one_mul, mul_one] 48 | replace h := h.coveringNumber_le 0 zero_le' 49 | simp only [hdA.1, ENNReal.rpow_zero, mul_one] at h 50 | calc (coveringNumber ε B : ℝ≥0∞) 51 | _ ≤ coveringNumber 0 B := mod_cast coveringNumber_anti zero_le' 52 | _ ≤ coveringNumber (0 / 2) A := mod_cast coveringNumber_subset_le hBA 53 | _ = coveringNumber 0 A := by simp 54 | _ ≤ c := h 55 | push_neg at hdA 56 | calc (coveringNumber ε B : ℝ≥0∞) 57 | _ ≤ coveringNumber (ε / 2) A := mod_cast coveringNumber_subset_le hBA 58 | _ ≤ c * (ε / 2 : ℝ≥0∞)⁻¹ ^ d := by 59 | replace h := h.coveringNumber_le (ε / 2) ?_ 60 | · simpa using h 61 | · simp only [ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, ENNReal.coe_div, ENNReal.coe_ofNat] 62 | calc (ε / 2 : ℝ≥0∞) ≤ ε := ENNReal.half_le_self 63 | _ ≤ EMetric.diam B := hε_le 64 | _ ≤ EMetric.diam A := EMetric.diam_mono hBA 65 | _ = 2 ^ d * c * (ε : ℝ≥0∞)⁻¹ ^ d := by 66 | rw [div_eq_mul_inv, ENNReal.mul_inv (by simp) (by simp), inv_inv, 67 | ENNReal.mul_rpow_of_nonneg _ _ hd] 68 | ring 69 | 70 | structure IsCoverWithBoundedCoveringNumber (C : ℕ → Set T) (A : Set T) (c : ℕ → ℝ≥0∞) (d : ℕ → ℝ) 71 | where 72 | c_ne_top : ∀ n, c n ≠ ∞ 73 | d_pos : ∀ n, 0 < d n 74 | isOpen : ∀ n, IsOpen (C n) 75 | totallyBounded : ∀ n, TotallyBounded (C n) 76 | hasBoundedCoveringNumber : ∀ n, HasBoundedCoveringNumber (C n) (c n) (d n) 77 | mono : ∀ n m, n ≤ m → C n ⊆ C m 78 | subset_iUnion : A ⊆ ⋃ i, C i 79 | 80 | open scoped Pointwise in 81 | lemma isCoverWithBoundedCoveringNumber_Ico_nnreal : 82 | IsCoverWithBoundedCoveringNumber (fun n ↦ Set.Ico (0 : ℝ≥0) (n + 1)) Set.univ 83 | (fun n ↦ 3 * (n + 1)) (fun _ ↦ 1) where 84 | c_ne_top n := by finiteness 85 | d_pos := by simp 86 | isOpen n := NNReal.isOpen_Ico_zero 87 | totallyBounded n := totallyBounded_Ico _ _ 88 | hasBoundedCoveringNumber n := by 89 | have h_iso : Isometry ((↑) : ℝ≥0 → ℝ) := fun x y ↦ rfl 90 | have h_image : ((↑) : ℝ≥0 → ℝ) '' (Set.Ico (0 : ℝ≥0) (n + 1)) = Set.Ico (0 : ℝ) (n + 1) := by 91 | ext x 92 | simp only [Set.mem_image, Set.mem_Ico, zero_le, true_and] 93 | refine ⟨fun ⟨y, hy, hy_eq⟩ ↦ ?_, fun h ↦ ?_⟩ 94 | · rw [← hy_eq] 95 | exact ⟨y.2, hy⟩ 96 | · exact ⟨⟨x, h.1⟩, h.2, rfl⟩ 97 | -- todo : extract that have as a lemma 98 | have h_diam : EMetric.diam (Set.Ico (0 : ℝ≥0) (n + 1)) = n + 1 := by 99 | rw [← h_iso.ediam_image, h_image] 100 | simp only [Real.ediam_Ico, sub_zero] 101 | norm_cast 102 | constructor 103 | · simp [h_diam] 104 | intro ε hε_le 105 | simp only [ENNReal.rpow_one] 106 | rw [← h_iso.coveringNumber_image, h_image] 107 | rw [h_diam] at hε_le 108 | have : Set.Ico (0 : ℝ) (n + 1) ⊆ EMetric.closedBall (((n : ℝ) + 1) / 2) ((n + 1) / 2) := by 109 | intro x hx 110 | simp only [Set.mem_Ico, EMetric.mem_closedBall, edist_dist, dist] at hx ⊢ 111 | refine ENNReal.ofReal_le_of_le_toReal ?_ 112 | simp only [ENNReal.toReal_div, ENNReal.toReal_ofNat] 113 | norm_cast 114 | refine abs_le.mpr ⟨?_, ?_⟩ 115 | · linarith 116 | · simp [hx.2.le] 117 | calc (coveringNumber ε (Set.Ico (0 : ℝ) (n + 1)) : ℝ≥0∞) 118 | _ ≤ coveringNumber (ε / 2) (EMetric.closedBall (((n : ℝ) + 1) / 2) ((n + 1) / 2)) := by 119 | gcongr 120 | exact coveringNumber_subset_le this 121 | _ ≤ 3 * ((n + 1) / 2 : ℝ≥0) / (ε / 2 : ℝ≥0) := by 122 | have h := coveringNumber_closedBall_le_three_mul (r := (n + 1) / 2) (ε := ε / 2) 123 | (x := ((n : ℝ) + 1) / 2) ?_ ?_ 124 | · simp only [ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, ENNReal.coe_div, ENNReal.coe_add, 125 | ENNReal.coe_natCast, ENNReal.coe_one, ENNReal.coe_ofNat, Module.finrank_self, pow_one] 126 | at h 127 | rwa [ENNReal.coe_div (by simp), ENNReal.coe_div (by simp)] 128 | · simp 129 | · gcongr 130 | exact mod_cast hε_le 131 | _ = 3 * (n + 1) / ε := by 132 | conv_lhs => rw [mul_div_assoc] 133 | conv_rhs => rw [mul_div_assoc] 134 | congr 1 135 | simp only [ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, ENNReal.coe_div, ENNReal.coe_add, 136 | ENNReal.coe_natCast, ENNReal.coe_one, ENNReal.coe_ofNat] 137 | simp_rw [div_eq_mul_inv] 138 | rw [ENNReal.mul_inv (by simp) (by simp), inv_inv, mul_assoc, mul_comm _ (2 : ℝ≥0∞), 139 | ← mul_assoc _ (2 : ℝ≥0∞), ENNReal.inv_mul_cancel (by simp) (by simp), one_mul] 140 | _ ≤ 3 * (n + 1) * (ε : ℝ≥0∞)⁻¹ := by rw [div_eq_mul_inv] 141 | mono n m hnm x hx := by 142 | simp only [Set.mem_Ico, zero_le, true_and] at hx ⊢ 143 | exact hx.trans_le (mod_cast (by gcongr)) 144 | subset_iUnion x hx := by 145 | simp only [Set.mem_iUnion, Set.mem_Ico, zero_le, true_and] 146 | obtain ⟨i, hi⟩ := exists_nat_gt x 147 | exact ⟨i, hi.trans (by simp)⟩ 148 | -------------------------------------------------------------------------------- /.github/workflows/05-pr-comment.yml: -------------------------------------------------------------------------------- 1 | name: Awaiting Review 2 | 3 | on: 4 | issue_comment: 5 | types: [created] 6 | 7 | jobs: 8 | awaiting_author: 9 | if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'awaiting-author') 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Add 'awaiting-author; and remove any 'awaiting-review' 13 | uses: actions/github-script@v8 14 | with: 15 | github-token: ${{ secrets.GITHUB_TOKEN }} 16 | script: | 17 | const { owner, repo, number: issue_number } = context.issue; 18 | await github.rest.issues.addLabels({ owner, repo, issue_number, labels: ['awaiting-author'] }); 19 | await github.rest.issues.removeLabel({ owner, repo, issue_number, name: 'awaiting-review' }).catch(() => {}); 20 | 21 | awaiting_review: 22 | if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'awaiting-review') 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - name: Add 'awaiting-review; and remove any 'awaiting-author' 27 | uses: actions/github-script@v8 28 | with: 29 | github-token: ${{ secrets.GITHUB_TOKEN }} 30 | script: | 31 | const { owner, repo, number: issue_number } = context.issue; 32 | await github.rest.issues.addLabels({ owner, repo, issue_number, labels: ['awaiting-review'] }); 33 | await github.rest.issues.removeLabel({ owner, repo, issue_number, name: 'awaiting-author' }).catch(() => {}); 34 | 35 | - name: Retrieve project ID 36 | id: get_project_id 37 | run: | 38 | QUERY=$(cat <> $GITHUB_ENV 55 | fi 56 | 57 | - name: Get PR details 58 | id: get_pr 59 | run: | 60 | curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 61 | https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.issue.number }} > pr.json 62 | cat pr.json 63 | 64 | - name: Extract related issue number 65 | id: extract_issue 66 | run: | 67 | ISSUE_NUMBER=$(jq -r '.body | capture("Closes #(?[0-9]+)") | .num' pr.json) 68 | echo "issue_number=$ISSUE_NUMBER" >> $GITHUB_ENV 69 | 70 | - name: Fail if no related issue is found 71 | if: ${{ env.issue_number == '' }} 72 | run: | 73 | echo "No related issue found in PR body. Exiting..." 74 | exit 1 75 | 76 | - name: Retrieve the project ITEM_ID for the related issue 77 | id: get_item_id 78 | run: | 79 | QUERY=$(cat <> $GITHUB_ENV 97 | fi 98 | 99 | - name: Retrieve the project FIELD_ID for "Status" 100 | id: get_field_id 101 | run: | 102 | QUERY=$(cat <> $GITHUB_ENV 120 | fi 121 | 122 | - name: Retrieve the "In Review" option ID 123 | id: find_in_review_tasks_id 124 | run: | 125 | QUERY=$(cat <> $GITHUB_ENV 143 | fi 144 | 145 | - name: Move task to "In Review" column 146 | run: | 147 | QUERY=$(cat <> $GITHUB_ENV 45 | fi 46 | 47 | - name: Get issue details 48 | id: issue 49 | run: | 50 | curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 51 | https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }} > issue.json 52 | cat issue.json 53 | continue-on-error: true 54 | 55 | - name: Check if the commenter is assigned to the issue 56 | id: check_assignee 57 | run: | 58 | COMMENTER="${{ github.event.comment.user.login }}" 59 | ASSIGNED=$(jq --arg user "$COMMENTER" '.assignees[]?.login | select(. == $user)' issue.json) 60 | if [ -z "$ASSIGNED" ]; then 61 | echo "not_assigned=true" >> $GITHUB_ENV 62 | else 63 | echo "not_assigned=false" >> $GITHUB_ENV 64 | fi 65 | 66 | - name: Remove the user from the assignees 67 | if: env.not_assigned == 'false' 68 | run: | 69 | curl -X DELETE -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 70 | -d '{"assignees":["${{ github.event.comment.user.login }}"]}' \ 71 | https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/assignees 72 | 73 | - name: Log the unassignment result 74 | if: env.not_assigned == 'false' 75 | run: echo "User ${{ github.event.comment.user.login }} has been unassigned from the issue." 76 | 77 | - name: Retrieve the project ITEM_ID 78 | id: get_item_id 79 | run: | 80 | QUERY=$(cat <> $GITHUB_ENV 100 | fi 101 | 102 | - name: Retrieve the project FIELD_ID for "Status" 103 | id: get_field_id 104 | run: | 105 | QUERY=$(cat <> $GITHUB_ENV 125 | fi 126 | 127 | - name: Retrieve the "Unclaimed" option ID 128 | id: find_unclaimed_tasks_id 129 | run: | 130 | QUERY=$(cat <> $GITHUB_ENV 150 | fi 151 | 152 | - name: Move task to "Unclaimed" column 153 | run: | 154 | QUERY=$(cat < 74 | rhs 75 | ext x 76 | rw [show x ^ (2 * n) / √(2 * Real.pi * ↑σ ^ 2) * Real.exp (-x ^ 2 77 | / (2 * ↑σ ^ 2)) = (fun u => u ^ (2 * n) / √(2 * Real.pi * ↑σ ^ 2) 78 | * Real.exp (-u ^ 2 / (2 * ↑σ ^ 2))) |x| by 79 | simp only [NNReal.zero_le_coe, pow_nonneg, Real.sqrt_mul', Nat.ofNat_nonneg, 80 | Real.sqrt_mul, Real.sqrt_sq, sq_abs, mul_eq_mul_right_iff, Real.exp_ne_zero, 81 | or_false] 82 | rw [pow_mul, ← sq_abs] 83 | ring_nf] 84 | rw [integral_comp_abs 85 | (f := (fun u => u ^ (2 * n) / √(2 * Real.pi * σ ^ 2) * Real.exp (-u ^ 2 / (2 * σ ^ 2))))] 86 | -- 6. ... = 2 ∫_(0, ∞) φ(x)^(2n) / √(2πσ²) e^(- φ(x)² / 2σ^2) |φ'(x)| dx 87 | -- where φ(x) = σ √(2x) and φ'(x) = σ / (√2 * √x), i.e., 88 | -- u sub with y = x^2 / (2σ²) or x = σ √(2y). 89 | _ = 2 * ∫ x in Set.Ioi 0, φ x ^ (2 * n) / (Real.sqrt (2 * Real.pi * σ ^ 2)) 90 | * Real.exp (-φ x ^ 2 / (2 * σ ^ 2)) * |deriv φ x| := by 91 | conv_lhs => rw [hφ_Ioi] 92 | rw [integral_image_eq_integral_abs_deriv_smul (f' := deriv φ) measurableSet_Ioi] 93 | · congr with x 94 | simp only [NNReal.zero_le_coe, pow_nonneg, Real.sqrt_mul', Nat.ofNat_nonneg, Real.sqrt_mul, 95 | Real.sqrt_sq, smul_eq_mul] 96 | group 97 | · exact fun x hx ↦ (h_diff (by simpa using hx)).hasDerivAt.hasDerivWithinAt 98 | · exact h_inj 99 | _ = 2 * ∫ x in Set.Ioi 0, φ x ^ (2 * n) / (Real.sqrt (2 * Real.pi * σ ^ 2)) 100 | * Real.exp (-x) * |deriv φ x| := by 101 | congr 1 102 | refine setIntegral_congr_fun measurableSet_Ioi fun x hx ↦ ?_ 103 | simp only [Set.mem_Ioi] at hx 104 | congr 105 | simp only [Nat.ofNat_nonneg, Real.sqrt_mul, φ] 106 | ring_nf 107 | field_simp 108 | rw [Real.sq_sqrt (by positivity), Real.sq_sqrt (by positivity)] 109 | -- 7. ... = σ^(2n) 2^n / √π Γ(n + 1/2) 110 | _ = σ ^ (2 * n) * 2 ^ n / √Real.pi * Real.Gamma (n + 1/2) := by 111 | rw [Real.Gamma_eq_integral (by positivity)] 112 | simp only [← integral_const_mul] 113 | refine setIntegral_congr_fun measurableSet_Ioi fun x hx ↦ ?_ 114 | simp only [Set.mem_Ioi] at hx 115 | rw [h_deriv hx, hφ_pow hx] 116 | simp only [NNReal.zero_le_coe, pow_nonneg, Real.sqrt_mul', Nat.ofNat_nonneg, Real.sqrt_mul, 117 | Real.sqrt_sq, one_div] 118 | rw [abs_of_nonneg (by positivity)] 119 | field_simp 120 | ring_nf 121 | have : x ^ n = x ^ (-(1 : ℝ) / 2 + n) * √x := by 122 | rw [Real.sqrt_eq_rpow, ← Real.rpow_add_of_nonneg (by positivity) _ (by positivity)] 123 | · ring_nf 124 | rw [Real.rpow_natCast] 125 | · rw [add_comm, neg_div, ← sub_eq_add_neg] 126 | simp only [one_div, sub_nonneg] 127 | calc (2 : ℝ)⁻¹ 128 | _ ≤ 1 := by norm_num 129 | _ ≤ n := by norm_cast; omega 130 | rw [this, Real.sq_sqrt zero_le_two] 131 | ring 132 | -- 8. ... = σ^(2n) (2n - 1)!! 133 | _ = σ ^ (2 * n) * Nat.doubleFactorial (2 * n - 1) := by 134 | rw [Real.Gamma_nat_add_half, ← sub_eq_zero] 135 | field_simp 136 | ring 137 | 138 | lemma centralMoment_fun_two_mul_gaussianReal (μ : ℝ) (σ : ℝ≥0) (n : ℕ) : 139 | centralMoment (fun x ↦ x) (2 * n) (gaussianReal μ (σ^2)) 140 | = σ ^ (2 * n) * Nat.doubleFactorial (2 * n - 1) := 141 | centralMoment_two_mul_gaussianReal .. 142 | 143 | end ProbabilityTheory 144 | -------------------------------------------------------------------------------- /blueprint/src/chapters/characteristic_function.tex: -------------------------------------------------------------------------------- 1 | \chapter{Characteristic function and covariance} 2 | 3 | \section{Characteristic functions} 4 | \label{sec:characteristic_function} 5 | 6 | 7 | \begin{definition}[Characteristic function]\label{def:charFunDual} 8 | \mathlibok 9 | \lean{MeasureTheory.charFunDual} 10 | The characteristic function of a measure $\mu$ on a normed space $E$ is the function $E^* \to \mathbb{C}$ defined by 11 | \begin{align*} 12 | \hat{\mu}(L) = \int_E e^{i L(x)} \: d\mu(x) \: . 13 | \end{align*} 14 | \end{definition} 15 | 16 | 17 | \begin{theorem}\label{thm:ext_of_charFunDual} 18 | \uses{def:charFunDual} 19 | \mathlibok 20 | \lean{MeasureTheory.Measure.ext_of_charFunDual} 21 | In a separable Banach space, if two finite measures have same characteristic function, they are equal. 22 | \end{theorem} 23 | 24 | \begin{proof}\leanok 25 | 26 | \end{proof} 27 | 28 | 29 | \begin{definition}[Characteristic function]\label{def:charFun} 30 | \mathlibok 31 | \lean{MeasureTheory.charFun} 32 | The characteristic function of a measure $\mu$ on an inner product space $E$ is the function $E \to \mathbb{C}$ defined by 33 | \begin{align*} 34 | \hat{\mu}(t) = \int_E e^{i \langle t, x \rangle} \: d\mu(x) \: . 35 | \end{align*} 36 | This is equal to the normed space version of the characteristic function applied to the linear map $x \mapsto \langle t, x \rangle$. 37 | \end{definition} 38 | 39 | 40 | \begin{theorem}\label{thm:ext_of_charFun} 41 | \uses{def:charFun} 42 | \mathlibok 43 | \lean{MeasureTheory.Measure.ext_of_charFun} 44 | In a separable Hilbert space, if two finite measures have same characteristic function, they are equal. 45 | \end{theorem} 46 | 47 | \begin{proof}\leanok 48 | 49 | \end{proof} 50 | 51 | 52 | \begin{lemma}\label{lem:charFun_map_eq_charFunDual_smul} 53 | \uses{def:charFun, def:charFunDual} 54 | \mathlibok 55 | \lean{MeasureTheory.charFun_map_eq_charFunDual_smul} 56 | Let $\mu$ be a measure on $F$ and let $L \in F^*$. Then 57 | \begin{align*} 58 | \widehat{L_*\mu}(x) &= \hat{\mu}(x \cdot L) \: . 59 | \end{align*} 60 | \end{lemma} 61 | 62 | \begin{proof}\leanok 63 | 64 | \end{proof} 65 | 66 | 67 | \begin{lemma}\label{lem:charFunDual_map} 68 | \uses{def:charFunDual} 69 | \mathlibok 70 | \lean{MeasureTheory.charFunDual_map} 71 | Let $\mu$ be a measure on a normed space $E$ and let $L$ be a continuous linear map from $E$ to $F$. 72 | Then for all $L' \in F^*$, 73 | \begin{align*} 74 | \widehat{L_*\mu}(L') = \hat{\mu}(L' \circ L) \: . 75 | \end{align*} 76 | \end{lemma} 77 | 78 | \begin{proof}\leanok 79 | 80 | \end{proof} 81 | 82 | 83 | 84 | \section{Covariance} 85 | \label{sec:covariance} 86 | 87 | Let $F$ be a Banach space and $E$ be a Hilbert space. 88 | 89 | \begin{definition}[Covariance]\label{def:covarianceBilin} 90 | \mathlibok 91 | \lean{ProbabilityTheory.covarianceBilinDual, ProbabilityTheory.covarianceBilinDual_apply, ProbabilityTheory.covarianceBilinDual_apply'} 92 | The covariance bilinear form of a measure $\mu$ on $F$ with finite second moment is the continuous bilinear form $C_\mu : F^* \times F^* \to \mathbb{R}$ with 93 | \begin{align*} 94 | C_\mu(L_1, L_2) 95 | &= \int_x (L_1(x) - L_1(m_\mu)) (L_2(x) - L_2(m_\mu)) \: d\mu(x) 96 | \\ 97 | &= \int_x L_1(x - m_\mu) L_2(x- m_\mu) \: d\mu(x) 98 | \: . 99 | \end{align*} 100 | \end{definition} 101 | 102 | \begin{lemma}\label{lem:covarianceBilin_same_eq_variance} 103 | \uses{def:covarianceBilin} 104 | \mathlibok 105 | \lean{ProbabilityTheory.covarianceBilinDual_self_eq_variance} 106 | For $\mu$ a measure on $F$ with finite second moment and $L \in F^*$, $C_\mu(L, L) = \mathbb{V}_\mu[L]$. 107 | \end{lemma} 108 | 109 | \begin{proof}\leanok 110 | 111 | \end{proof} 112 | 113 | 114 | \begin{definition}[Covariance in a Hilbert space]\label{def:covInnerBilin} 115 | \mathlibok 116 | \lean{ProbabilityTheory.covarianceBilin} 117 | The covariance bilinear form of a finite measure $\mu$ with finite second moment on a Hilbert space $E$ is the continuous bilinear form $C_\mu : E \times E \to \mathbb{R}$ with 118 | \begin{align*} 119 | C'_\mu(x, y) = \int_z \langle x, z - m_\mu \rangle \langle y, z - m_\mu \rangle \: d\mu(z) \: . 120 | \end{align*} 121 | This is $C_\mu$ applied to the linear maps $L_x, L_y \in E^*$ defined by $L_x(z) = \langle x, z \rangle$ and $L_y(z) = \langle y, z \rangle$. 122 | \end{definition} 123 | 124 | 125 | \begin{lemma}\label{lem:covInnerBilin_map} 126 | \uses{def:covInnerBilin} 127 | \mathlibok 128 | \lean{ProbabilityTheory.covarianceBilin_map} 129 | Let $E$ and $F$ be two Hilbert spaces with $F$ finite dimensional, $\mu$ a finite measure on $E$ with finite second moment, and $L : E \to F$ a continuous linear map. 130 | Then the covariance bilinear form of the measure $L_*\mu$ is given by 131 | \begin{align*} 132 | C'_{L_*\mu}(u, v) 133 | &= C'_\mu(L^\dagger(u), L^\dagger(v)) 134 | \: , 135 | \end{align*} 136 | in which $L^\dagger : F \to E$ is the adjoint of $L$. 137 | \end{lemma} 138 | 139 | \begin{proof}\leanok 140 | \begin{align*} 141 | C'_{L_*\mu}(u, v) 142 | &= (L_*\mu)\left[\langle u, x - m_{L_*\mu}\rangle \langle x - m_{L_*\mu}, v \rangle\right] 143 | \\ 144 | &= \mu\left[\langle u, L(x) - L(m_\mu)\rangle \langle L(x) - L(m_\mu), v \rangle \right] 145 | \\ 146 | &= \mu\left[\langle L^\dagger(u), x - m_\mu\rangle \langle x - m_\mu, L^\dagger(v) \rangle \right] 147 | \\ 148 | &= C'_\mu(L^\dagger(u), L^\dagger(v)) 149 | \: . 150 | \end{align*} 151 | \end{proof} 152 | 153 | 154 | \begin{definition}[Covariance matrix]\label{def:covMatrix} 155 | \uses{def:IsGaussian, lem:covarianceBilin_same_eq_variance} 156 | \leanok 157 | \lean{ProbabilityTheory.covMatrix, ProbabilityTheory.posSemidef_covMatrix} 158 | The covariance matrix of a finite measure $\mu$ with finite second moment on a finite dimensional inner product space $E$ is the positive semidefinite matrix $\Sigma_\mu$ such that for $u, v \in E$, 159 | \begin{align*} 160 | \langle u, \Sigma_\mu v\rangle = \mu[\langle u, x - m_\mu \rangle \langle x - m_\mu, v \rangle] \: . 161 | \end{align*} 162 | This is the covariance bilinear form $C'_\mu(u, v)$, as a matrix. 163 | \end{definition} 164 | 165 | 166 | \begin{lemma}\label{lem:covMatrix_map} 167 | \uses{def:covMatrix} 168 | \leanok 169 | \lean{ProbabilityTheory.covMatrix_map} 170 | Let $E$ and $F$ be two finite dimensional inner product spaces, $\mu$ a measure on $E$ with finite second moment, and $L : E \to F$ a continuous linear map. 171 | Then the covariance matrix of the measure $L_*\mu$ has entries 172 | \begin{align*} 173 | \langle e_i, \Sigma_{L_*\mu} e_j\rangle 174 | &= \langle L^\dagger(e_i), \Sigma_\mu L^\dagger(e_j)\rangle 175 | \: , 176 | \end{align*} 177 | in which $L^\dagger : F \to E$ is the adjoint of $L$. 178 | \end{lemma} 179 | 180 | \begin{proof}\leanok 181 | \uses{lem:covInnerBilin_map} 182 | On the left-hand side we have 183 | $$\langle e_i, \Sigma_{L_*\mu} e_j\rangle = C'_{L_*\mu}(e_i, e_j) = C'_\mu(L^\dagger(e_i), L^\dagger(e_j)),$$ 184 | where the last equality comes from Lemma~\ref{lem:covInnerBilin_map}. On the right-hand side we have 185 | $$\langle L^\dagger(e_i), \Sigma_{L_*\mu} L^\dagger(e_j)\rangle = C'_\mu(L^\dagger(e_i), L^\dagger(e_j)),$$ 186 | which concludes the proof. 187 | \end{proof} 188 | -------------------------------------------------------------------------------- /.github/workflows/03-propose-pr.yml: -------------------------------------------------------------------------------- 1 | name: Propose PR 2 | 3 | on: 4 | issue_comment: 5 | types: [created] 6 | 7 | jobs: 8 | propose_pr: 9 | if: github.event.issue.pull_request == null && contains(github.event.comment.body, 'propose') 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Check if the comment contains "propose #PR_NUMBER" 14 | id: check_propose 15 | env: 16 | COMMENT: ${{ github.event.comment.body }} 17 | run: | 18 | COMMENT_LOWER=$(echo "$COMMENT" | tr '[:upper:]' '[:lower:]') 19 | 20 | # Use a refined regex with [[:space:]] to match any whitespace 21 | if [[ "$COMMENT_LOWER" =~ propose[[:space:]]*(pr[[:space:]]*)?\#([0-9]+)[[:space:]]* ]]; then 22 | PR_NUMBER="${BASH_REMATCH[2]}" 23 | echo "pr_number=$PR_NUMBER" >> $GITHUB_ENV 24 | else 25 | echo "The comment does not contain a valid 'propose #PR_NUMBER' format." 26 | exit 1 27 | fi 28 | 29 | - name: Retrieve project ID 30 | id: get_project_id 31 | run: | 32 | QUERY=$(cat <> $GITHUB_ENV 49 | fi 50 | 51 | - name: Get issue details 52 | run: | 53 | curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 54 | https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.issue.number }} > issue.json 55 | 56 | - name: Check if the commenter is assigned to the issue 57 | run: | 58 | COMMENTER="${{ github.event.comment.user.login }}" 59 | ASSIGNED=$(jq --arg user "$COMMENTER" '.assignees[]?.login | select(. == $user)' issue.json) 60 | if [ -z "$ASSIGNED" ]; then 61 | echo "not_assigned=true" >> $GITHUB_ENV 62 | else 63 | echo "not_assigned=false" >> $GITHUB_ENV 64 | fi 65 | 66 | - name: Notify the user if they are not assigned 67 | if: env.not_assigned == 'true' 68 | run: | 69 | echo "User ${{ github.event.comment.user.login }} is not assigned to this issue, exiting." 70 | exit 0 71 | 72 | - name: Link PR to the issue 73 | if: env.not_assigned == 'false' 74 | run: | 75 | PR_NUMBER="${{ env.pr_number }}" 76 | if [ -z "$PR_NUMBER" ]; then 77 | echo "Error: PR number is not set. Exiting." 78 | exit 1 79 | fi 80 | 81 | # Get the current PR body (ensure newlines are treated properly) 82 | PR_BODY=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 83 | https://api.github.com/repos/${{ github.repository }}/pulls/${PR_NUMBER} | jq -r '.body') 84 | 85 | # Remove unnecessary carriage returns 86 | PR_BODY_CLEAN=$(echo "$PR_BODY" | sed 's/\r//g') 87 | 88 | # Append the issue closing reference 89 | NEW_PR_BODY=$(echo -e "${PR_BODY_CLEAN}\n\nCloses #${{ github.event.issue.number }}") 90 | 91 | # Prepare the JSON payload (properly escaped for newlines) 92 | PAYLOAD=$(jq -n --arg body "$NEW_PR_BODY" '{body: $body}') 93 | 94 | # Update the PR body with the properly formatted content 95 | curl -s -X PATCH -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ 96 | -H "Content-Type: application/json" \ 97 | -d "$PAYLOAD" \ 98 | https://api.github.com/repos/${{ github.repository }}/pulls/${PR_NUMBER} 99 | 100 | - name: Retrieve the project ITEM_ID 101 | id: get_item_id 102 | run: | 103 | QUERY=$(cat <> $GITHUB_ENV 121 | fi 122 | 123 | - name: Retrieve the project FIELD_ID for "Status" 124 | id: get_field_id 125 | run: | 126 | QUERY=$(cat <> $GITHUB_ENV 144 | fi 145 | 146 | - name: Retrieve the "In Progress" option ID 147 | id: find_in_progress_tasks_id 148 | run: | 149 | QUERY=$(cat <> $GITHUB_ENV 167 | fi 168 | 169 | - name: Move task to "In Progress" column 170 | run: | 171 | QUERY=$(cat < enter [1, ω]; change (WithLp.prodContinuousLinearEquiv p ℝ E F).symm _ 134 | infer_instance 135 | 136 | lemma HasGaussianLaw.fst [HasGaussianLaw (fun ω ↦ (X ω, Y ω)) P] : 137 | HasGaussianLaw X P := by 138 | have : X = (ContinuousLinearMap.fst ℝ E F) ∘ (fun ω ↦ (X ω, Y ω)) := by ext; simp 139 | rw [this] 140 | infer_instance 141 | 142 | lemma HasGaussianLaw.snd [HasGaussianLaw (fun ω ↦ (X ω, Y ω)) P] : 143 | HasGaussianLaw Y P := by 144 | have : Y = (ContinuousLinearMap.snd ℝ E F) ∘ (fun ω ↦ (X ω, Y ω)) := by ext; simp 145 | rw [this] 146 | infer_instance 147 | 148 | end Prod 149 | 150 | section Pi 151 | 152 | variable [SecondCountableTopology E] {ι : Type*} [Fintype ι] {X : ι → Ω → E} 153 | 154 | section Nondependent 155 | 156 | instance HasGaussianLaw.sub [h : HasGaussianLaw (fun ω ↦ (X · ω)) P] (i j : ι) : 157 | HasGaussianLaw (X i - X j) P := by 158 | have : X i - X j = (ContinuousLinearMap.proj (R := ℝ) (φ := fun _ ↦ E) i - 159 | ContinuousLinearMap.proj (R := ℝ) (φ := fun _ ↦ E) j) ∘ (fun ω ↦ (X · ω)) := by ext; simp 160 | rw [this] 161 | infer_instance 162 | 163 | instance IsGaussian.hasGaussianLaw_sub_eval {μ : Measure (ι → E)} [IsGaussian μ] (i j : ι) : 164 | HasGaussianLaw (fun x ↦ x i - x j) μ := 165 | HasGaussianLaw.sub (h := IsGaussian.hasGaussianLaw_id) i j 166 | 167 | instance IsGaussian.hasGaussianLaw_sub_eval_piLp (p : ℝ≥0∞) [Fact (1 ≤ p)] 168 | {μ : Measure (PiLp p (fun _ ↦ E))} [IsGaussian μ] (i j : ι) : 169 | HasGaussianLaw (fun x ↦ x i - x j) μ := 170 | HasGaussianLaw.sub 171 | (h := IsGaussian.hasGaussianLaw_id.map_equiv (PiLp.continuousLinearEquiv p ℝ (fun _ : ι ↦ E))) 172 | i j 173 | 174 | end Nondependent 175 | 176 | variable {E : ι → Type*} [∀ i, NormedAddCommGroup (E i)] 177 | [∀ i, NormedSpace ℝ (E i)] [∀ i, MeasurableSpace (E i)] [∀ i, BorelSpace (E i)] 178 | [∀ i, SecondCountableTopology (E i)] {X : (i : ι) → Ω → E i} 179 | 180 | instance HasGaussianLaw.eval [∀ i, SecondCountableTopology (E i)] {X : (i : ι) → Ω → E i} 181 | [h : HasGaussianLaw (fun ω ↦ (X · ω)) P] (i : ι) : 182 | HasGaussianLaw (X i) P := by 183 | have : X i = (ContinuousLinearMap.proj (R := ℝ) (φ := E) i) ∘ (fun ω ↦ (X · ω)) := by ext; simp 184 | rw [this] 185 | infer_instance 186 | 187 | instance HasGaussianLaw.toLp_comp_pi (p : ℝ≥0∞) [Fact (1 ≤ p)] 188 | [hX : HasGaussianLaw (fun ω ↦ (X · ω)) P] : 189 | HasGaussianLaw (fun ω ↦ toLp p (X · ω)) P := 190 | hX.map_equiv (PiLp.continuousLinearEquiv p ℝ E).symm 191 | 192 | instance IsGaussian.hasGaussianLaw_eval {μ : Measure (Π i, E i)} [IsGaussian μ] (i : ι) : 193 | HasGaussianLaw (fun x ↦ x i) μ := 194 | HasGaussianLaw.eval (h := IsGaussian.hasGaussianLaw_id) i 195 | 196 | instance IsGaussian.hasGaussianLaw_eval_piLp (p : ℝ≥0∞) [Fact (1 ≤ p)] 197 | {μ : Measure (PiLp p E)} [IsGaussian μ] (i : ι) : HasGaussianLaw (fun x ↦ x i) μ := 198 | HasGaussianLaw.eval 199 | (h := IsGaussian.hasGaussianLaw_id.map_equiv (PiLp.continuousLinearEquiv p ℝ E)) i 200 | 201 | end Pi 202 | 203 | end SpecificMaps 204 | 205 | end NormedSpace 206 | 207 | end HasGaussianLaw 208 | 209 | end ProbabilityTheory 210 | --------------------------------------------------------------------------------