Skip to content

Commit 49a6376

Browse files
committed
uniqueness of variational gradient
1 parent 813f864 commit 49a6376

File tree

4 files changed

+216
-9
lines changed

4 files changed

+216
-9
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/-
2+
Copyright (c) 2025 Tomas Skrivan. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Tomas Skrivan, Joseph Tooby-Smith
5+
-/
6+
import Mathlib.MeasureTheory.Integral.Bochner.Basic
7+
import PhysLean.Mathematics.VariationalCalculus.IsTestFunction
8+
/-!
9+
10+
# Fundamental lemma of the calculus of variations
11+
12+
The key took in variational calculus is:
13+
```
14+
∀ h, ∫ x, f x * h x = 0 → f = 0
15+
```
16+
which allows use to go from reasoning about integrals to reasoning about functions. There are
17+
18+
-/
19+
20+
open MeasureTheory InnerProductSpace
21+
22+
variable
23+
{X} [NormedAddCommGroup X] [NormedSpace ℝ X] [MeasurableSpace X]
24+
{V} [NormedAddCommGroup V] [InnerProductSpace ℝ V]
25+
26+
lemma fundamental_theorem_of_variational_calculus {f : X → V}
27+
(μ : Measure X) [IsFiniteMeasureOnCompacts μ] [μ.IsOpenPosMeasure]
28+
[OpensMeasurableSpace X]
29+
(hf : IsTestFunction f) (hg : ∀ g, IsTestFunction g → ∫ x, ⟪f x, g x⟫_ℝ ∂μ = 0) :
30+
f = 0 := by
31+
have hf' := hg f hf
32+
rw [MeasureTheory.integral_eq_zero_iff_of_nonneg] at hf'
33+
· rw [Continuous.ae_eq_iff_eq] at hf'
34+
· funext x
35+
have hf'' := congrFun hf' x
36+
simpa using hf''
37+
· have hf : Continuous f := hf.smooth.continuous
38+
fun_prop
39+
· fun_prop
40+
· intro x
41+
simp
42+
exact real_inner_self_nonneg
43+
· apply IsTestFunction.integrable
44+
exact IsTestFunction.inner hf hf
45+
46+
47+
-- The assumption `IsTestFunction f` can be weakened to `Continuous f`
48+
proof_wanted fundamental_theorem_of_variational_calculus' {f : X → V}
49+
(μ : Measure X) [IsFiniteMeasureOnCompacts μ] [μ.IsOpenPosMeasure]
50+
[OpensMeasurableSpace X]
51+
(hf : Continuous f) (hg : ∀ g, IsTestFunction g → ∫ x, ⟪f x, g x⟫_ℝ ∂μ = 0) :
52+
f = 0

PhysLean/Mathematics/VariationalCalculus/HasVarAdjoint.lean

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ Copyright (c) 2025 Tomas Skrivan. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Tomas Skrivan, Joseph Tooby-Smith
55
-/
6-
import Mathlib.Algebra.Lie.OfAssociative
76
import Mathlib.MeasureTheory.Integral.IntegralEqImproper
8-
import PhysLean.Mathematics.VariationalCalculus.IsTestFunction
7+
import PhysLean.Mathematics.VariationalCalculus.Basic
98
/-!
9+
1010
# Variational adjoint
1111
1212
Definition of adjoint of linear function between function spaces. It is inspired by the definition
@@ -15,6 +15,7 @@ https://en.wikipedia.org/wiki/Distribution_(mathematics) under 'Preliminaries: T
1515
operator' but we require that the adjoint is function between test functions too.
1616
1717
The key results are:
18+
- variational adjoint is unique on test functions
1819
- variational adjoint of identity is identity, `HasVarAdjoint.id`
1920
- variational adjoint of composition is composition of adjoint in reverse order,
2021
`HasVarAdjoint.comp`
@@ -55,6 +56,16 @@ structure HasVarAdjoint
5556
adjoint : ∀ φ ψ, IsTestFunction φ → IsTestFunction ψ →
5657
∫ x, ⟪F φ x, ψ x⟫_ℝ ∂μ = ∫ x, ⟪φ x, F' ψ x⟫_ℝ ∂μ
5758

59+
structure HasVarDual
60+
(F : (X → U) → ℝ) (F' : X → U) (μ : Measure X := by volume_tac) where
61+
adjoint : ∀ φ, IsTestFunction φ →
62+
F φ = ∫ x, ⟪F' x, φ x⟫_ℝ ∂μ
63+
64+
structure HasVarDual'
65+
(F : X → U) (F' : (X → U) → ℝ) (μ : Measure X := by volume_tac) where
66+
adjoint : ∀ φ, IsTestFunction φ →
67+
∫ x, ⟪F x, φ x⟫_ℝ ∂μ = F' φ
68+
5869
namespace HasVarAdjoint
5970

6071
variable {μ : Measure X}
@@ -74,16 +85,16 @@ lemma comp {F : (X → V) → (X → W)} {G : (X → U) → (X → V)} {F' G'}
7485
rw [hG.adjoint _ _ hφ (hF.test_fun_preserving' _ hψ)]
7586

7687
protected lemma deriv :
77-
HasVarAdjoint (fun φ : ℝ → ℝ => deriv φ) (fun φ => - deriv φ) where
78-
test_fun_preserving _ hφ := by
88+
HasVarAdjoint (fun φ : ℝ → ℝ => deriv φ) (fun φ x => - deriv φ x) where
89+
test_fun_preserving _ hφ := by
7990
have ⟨h,h'⟩ := hφ
8091
constructor
8192
· fun_prop
8293
· exact HasCompactSupport.deriv h'
8394
test_fun_preserving' _ hφ := by
8495
have ⟨h,h'⟩ := hφ
8596
constructor
86-
· eta_expand; dsimp; fun_prop
97+
· fun_prop
8798
· apply HasCompactSupport.neg'
8899
apply HasCompactSupport.deriv h'
89100
adjoint φ ψ hφ hψ := by
@@ -131,6 +142,44 @@ lemma congr_adjoint {F : (X → U) → (X → V)} {G' : (X → V) → (X → U)}
131142
rw [h' ψ hψ]
132143
exact h.adjoint φ ψ hφ hψ
133144

145+
/-- Variational adjoint is unique only when applied to test functions. -/
146+
lemma unique {F : (X → U) → (X → V)} {F' G' : (X → V) → (X → U)}
147+
{μ : Measure X} [IsFiniteMeasureOnCompacts μ] [μ.IsOpenPosMeasure]
148+
[OpensMeasurableSpace X] (hF' : HasVarAdjoint F F' μ) (hG' : HasVarAdjoint F G' μ) :
149+
∀ φ, IsTestFunction φ → F' φ = G' φ := by
150+
obtain ⟨F_preserve_test, F'_preserve_test, F'_adjoint⟩ := hF'
151+
obtain ⟨F_preserve_test, G'_preserve_test, G'_adjoint⟩ := hG'
152+
intro φ hφ
153+
rw [← zero_add (G' φ)]
154+
rw [← sub_eq_iff_eq_add]
155+
change (F' - G') φ = 0
156+
apply fundamental_theorem_of_variational_calculus μ
157+
· simp
158+
apply IsTestFunction.sub
159+
· exact F'_preserve_test φ hφ
160+
· exact G'_preserve_test φ hφ
161+
· intro ψ hψ
162+
simp [inner_sub_left]
163+
rw [MeasureTheory.integral_sub]
164+
· conv_lhs =>
165+
enter [2, 2, a]
166+
rw [← inner_conj_symm]
167+
conv_lhs =>
168+
enter [1, 2, a]
169+
rw [← inner_conj_symm]
170+
simp
171+
rw [← F'_adjoint ψ φ hψ hφ]
172+
rw [G'_adjoint ψ φ hψ hφ]
173+
simp
174+
· apply IsTestFunction.integrable
175+
apply IsTestFunction.inner
176+
· exact F'_preserve_test φ hφ
177+
· exact hψ
178+
· apply IsTestFunction.integrable
179+
apply IsTestFunction.inner
180+
· exact G'_preserve_test φ hφ
181+
· exact hψ
182+
134183
lemma neg {F : (X → U) → (X → V)} {F' : (X → V) → (X → U)}
135184
{μ : Measure X}
136185
(hF : HasVarAdjoint F F' μ) :

PhysLean/Mathematics/VariationalCalculus/HasVarGradient.lean

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: Tomas Skrivan, Joseph Tooby-Smith
55
-/
66
import PhysLean.Mathematics.VariationalCalculus.HasVarAdjoint
77
import Mathlib.Tactic.FunProp.Differentiable
8+
import Mathlib.Analysis.Calculus.BumpFunction.InnerProduct
89
/-!
910
1011
# Variational gradient
@@ -61,16 +62,84 @@ HasVarGradientAt
6162
inductive HasVarGradientAt (S' : (X → U) → (X → ℝ)) (grad : X → U) (u : X → U)
6263
(μ : Measure X := by volume_tac) : Prop
6364
| intro (F')
64-
(adjoint : HasVarAdjoint (fun δu t => deriv (fun s : ℝ => S' (u + s • δu) t) 0) F' μ)
65-
(eq : F' (fun _ => 1) = grad)
65+
(diff : ∀ δu x, IsTestFunction δu →
66+
Differentiable ℝ (fun s : ℝ => S' (fun x' => u x' + s • δu x') x))
67+
(adjoint : HasVarAdjoint (fun δu x => deriv (fun s : ℝ => S' (u + s • δu) x) 0) F' μ)
68+
/- This condition is effectivelly saying that `F' (fun _ => 1) = grad` but `F'` is not
69+
guaranteed to produce meaningful result for `fun _ => 1` as it is not test function.
70+
Therefore we require that it is possible to glue `grad` together by -/
71+
(eq : ∀ (x : X), ∃ D : Set X,
72+
x ∈ D ∧ IsCompact D
73+
74+
∀ (φ : X → ℝ), IsTestFunction φ → (∀ x ∈ D, φ x = 1) → F' φ x = grad x)
75+
76+
77+
lemma HasVarGradientAt.unique
78+
{X : Type*} [NormedAddCommGroup X] [InnerProductSpace ℝ X]
79+
[FiniteDimensional ℝ X] [MeasurableSpace X]
80+
{S' : (X → U) → (X → ℝ)} {grad grad' : X → U} {u : X → U} {μ : Measure X}
81+
[IsFiniteMeasureOnCompacts μ] [μ.IsOpenPosMeasure] [OpensMeasurableSpace X]
82+
(h : HasVarGradientAt S' grad u μ) (h' : HasVarGradientAt S' grad' u μ) :
83+
grad = grad' := by
84+
85+
obtain ⟨F,_,hF,eq⟩ := h
86+
obtain ⟨G,_,hG,eq'⟩ := h'
87+
funext x
88+
obtain ⟨D,hm,hD,hgrad⟩ := eq x
89+
obtain ⟨D',_,hD',hgrad'⟩ := eq' x
90+
91+
-- prepare test function that is one on `D ∪ D'`
92+
let r := sSup ((fun x => ‖x‖) '' (D ∪ D'))
93+
have : 0 ≤ r := by
94+
obtain ⟨x, h1, h2, h3⟩ := IsCompact.exists_sSup_image_eq_and_ge (s := D ∪ D')
95+
(IsCompact.union hD hD') (Set.Nonempty.inl (Set.nonempty_of_mem hm))
96+
(f := fun x => ‖x‖) (by fun_prop)
97+
unfold r
98+
apply le_of_le_of_eq (b := ‖x‖)
99+
· exact norm_nonneg x
100+
· rw [← h2]
101+
102+
let φ : ContDiffBump (0 : X) := {
103+
rIn := r + 1,
104+
rOut := r + 2,
105+
rIn_pos := by linarith,
106+
rIn_lt_rOut := by linarith}
107+
108+
-- few properties about `φ`
109+
let f := fun x => φ.toFun x
110+
have hφ : IsTestFunction (fun x : X => φ x) := by
111+
constructor
112+
apply ContDiffBump.contDiff
113+
apply ContDiffBump.hasCompactSupport
114+
have hφ' : ∀ x, x ∈ D ∪ D' → x ∈ Metric.closedBall 0 φ.rIn := by
115+
intro x hx
116+
simp [φ, r]
117+
obtain ⟨y, h1, h2, h3⟩ := IsCompact.exists_sSup_image_eq_and_ge (s := D ∪ D')
118+
(IsCompact.union hD hD') (Set.Nonempty.inl (Set.nonempty_of_mem hm))
119+
(f := fun x => ‖x‖) (by fun_prop)
120+
rw [h2]
121+
have h3' := h3 x hx
122+
apply le_trans h3'
123+
simp
124+
have h := hgrad φ hφ
125+
(by intros _ hx; unfold φ; rw[φ.one_of_mem_closedBall]; apply hφ'; simp[hx])
126+
have h' := hgrad' φ hφ
127+
(by intros _ hx; unfold φ; rw[φ.one_of_mem_closedBall]; apply hφ'; simp[hx])
128+
rw[← h, ← h',hF.unique hG φ hφ]
66129

67130
/-- Variation of `S(x) = ∫ 1/2*m*‖ẋ‖² - V(x)` gives Newton's law of motion `δS(x) = - m*ẍ - V'(x)`-/
68-
example (m : ℝ) (u V : ℝ → ℝ) (hu : ContDiff ℝ ∞ u) (hV : ContDiff ℝ ∞ V) :
131+
lemma euler_lagrange_particle_1d (m : ℝ) (u V : ℝ → ℝ)
132+
(hu : ContDiff ℝ ∞ u) (hV : ContDiff ℝ ∞ V) :
69133
HasVarGradientAt
70134
(fun (u : ℝ → ℝ) (t : ℝ) => 1/2 * m * deriv u t ^ 2 - V (u t))
71135
(fun t => - m * deriv (deriv u) t - deriv V (u t))
72136
u := by
73137
apply HasVarGradientAt.intro
138+
case diff =>
139+
intro _ _ hδu
140+
have := hδu.1
141+
have : (2:WithTop ℕ∞) ≤ ∞ := ENat.LEInfty.out
142+
fun_prop (config:={maxTransitionDepth:=2}) (disch:=aesop) [deriv]
74143
case adjoint =>
75144
eta_expand
76145
have := hu.differentiable ENat.LEInfty.out
@@ -96,4 +165,15 @@ example (m : ℝ) (u V : ℝ → ℝ) (hu : ContDiff ℝ ∞ u) (hV : ContDiff
96165
· apply HasVarAdjoint.mul_left (hψ := by fun_prop)
97166
apply HasVarAdjoint.id
98167
case eq =>
99-
simp only [mul_one, deriv_const_mul_field', Pi.neg_apply, neg_mul]
168+
intro x
169+
use (Metric.closedBall x 1)
170+
constructor
171+
· simp
172+
· constructor
173+
· exact isCompact_closedBall x 1
174+
· intro φ hφ hφ'
175+
simp[hφ',hφ]
176+
have h : (fun x => m * deriv u x * φ x) =ᶠ[nhds x] (fun x => m * deriv u x) :=
177+
Filter.eventuallyEq_of_mem (Metric.closedBall_mem_nhds x Real.zero_lt_one)
178+
(by intro x' hx'; simp[hφ' x' hx'])
179+
simp[h.deriv_eq]

PhysLean/Mathematics/VariationalCalculus/IsTestFunction.lean

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,32 @@ lemma IsTestFunction.deriv {f : ℝ → U} (hf : IsTestFunction f) :
4848
smooth := deriv' hf.smooth
4949
supp := HasCompactSupport.deriv hf.supp
5050

51+
@[fun_prop]
52+
lemma IsTestFunction.add {f g : X → V} (hf : IsTestFunction f) (hg : IsTestFunction g) :
53+
IsTestFunction (fun x => f x + g x) where
54+
smooth := ContDiff.add hf.smooth hg.smooth
55+
supp := by
56+
apply HasCompactSupport.add
57+
· exact hf.supp
58+
· exact hg.supp
59+
60+
@[fun_prop]
61+
lemma IsTestFunction.neg {f : X → V} (hf : IsTestFunction f) :
62+
IsTestFunction (fun x => - f x) where
63+
smooth := ContDiff.neg hf.smooth
64+
supp := by
65+
apply HasCompactSupport.neg' hf.supp
66+
67+
@[fun_prop]
68+
lemma IsTestFunction.sub {f g : X → V} (hf : IsTestFunction f) (hg : IsTestFunction g) :
69+
IsTestFunction (f - g) where
70+
smooth := ContDiff.sub hf.smooth hg.smooth
71+
supp := by
72+
rw [SubNegMonoid.sub_eq_add_neg]
73+
apply HasCompactSupport.add
74+
· exact hf.supp
75+
· exact HasCompactSupport.neg' hg.supp
76+
5177
@[fun_prop]
5278
lemma IsTestFunction.mul {f g : X → ℝ} (hf : IsTestFunction f) (hg : IsTestFunction g) :
5379
IsTestFunction (fun x => f x * g x) where

0 commit comments

Comments
 (0)