1
1
/-
2
2
Copyright (c) 2021 Yury G. Kudryashov. All rights reserved.
3
3
Released under Apache 2.0 license as described in the file LICENSE.
4
- Authors: Yury G. Kudryashov
4
+ Authors: Yury G. Kudryashov, Winston Yin
5
5
-/
6
6
import analysis.special_functions.integrals
7
7
import topology.metric_space.contracting
@@ -11,13 +11,18 @@ import topology.metric_space.contracting
11
11
12
12
In this file we prove that an ordinary differential equation $\dot x=v(t, x)$ such that $v$ is
13
13
Lipschitz continuous in $x$ and continuous in $t$ has a local solution, see
14
- `exists_forall_deriv_within_Icc_eq_of_lipschitz_of_continuous`.
14
+ `exists_forall_deriv_within_Icc_eq_of_is_picard_lindelof`.
15
+
16
+ As a corollary, we prove that a time-independent locally continuously differentiable ODE has a
17
+ local solution.
15
18
16
19
## Implementation notes
17
20
18
21
In order to split the proof into small lemmas, we introduce a structure `picard_lindelof` that holds
19
22
all assumptions of the main theorem. This structure and lemmas in the `picard_lindelof` namespace
20
- should be treated as private implementation details.
23
+ should be treated as private implementation details. This is not to be confused with the `Prop`-
24
+ valued structure `is_picard_lindelof`, which holds the long hypotheses of the Picard-Lindelöf
25
+ theorem for actual use as part of the public API.
21
26
22
27
We only prove existence of a solution in this file. For uniqueness see `ODE_solution_unique` and
23
28
related theorems in `analysis.ODE.gronwall`.
@@ -35,19 +40,35 @@ noncomputable theory
35
40
36
41
variables {E : Type *} [normed_add_comm_group E] [normed_space ℝ E]
37
42
38
- /-- This structure holds arguments of the Picard-Lipschitz (Cauchy-Lipschitz) theorem. Unless you
39
- want to use one of the auxiliary lemmas, use
40
- `exists_forall_deriv_within_Icc_eq_of_lipschitz_of_continuous` instead of using this structure. -/
43
+ /-- `Prop` structure holding the hypotheses of the Picard-Lindelöf theorem.
44
+
45
+ The similarly named `picard_lindelof` structure is part of the internal API for convenience, so as
46
+ not to constantly invoke choice, but is not intended for public use. -/
47
+ structure is_picard_lindelof
48
+ {E : Type *} [normed_add_comm_group E] (v : ℝ → E → E) (t_min t₀ t_max : ℝ) (x₀ : E)
49
+ (L : ℝ≥0 ) (R C : ℝ) : Prop :=
50
+ (ht₀ : t₀ ∈ Icc t_min t_max)
51
+ (hR : 0 ≤ R)
52
+ (lipschitz : ∀ t ∈ Icc t_min t_max, lipschitz_on_with L (v t) (closed_ball x₀ R))
53
+ (cont : ∀ x ∈ closed_ball x₀ R, continuous_on (λ (t : ℝ), v t x) (Icc t_min t_max))
54
+ (norm_le : ∀ (t ∈ Icc t_min t_max) (x ∈ closed_ball x₀ R), ∥v t x∥ ≤ C)
55
+ (C_mul_le_R : (C : ℝ) * linear_order.max (t_max - t₀) (t₀ - t_min) ≤ R)
56
+
57
+ /-- This structure holds arguments of the Picard-Lipschitz (Cauchy-Lipschitz) theorem. It is part of
58
+ the internal API for convenience, so as not to constantly invoke choice. Unless you want to use one
59
+ of the auxiliary lemmas, use `exists_forall_deriv_within_Icc_eq_of_lipschitz_of_continuous` instead
60
+ of using this structure.
61
+
62
+ The similarly named `is_picard_lindelof` is a bundled `Prop` holding the long hypotheses of the
63
+ Picard-Lindelöf theorem as named arguments. It is used as part of the public API.
64
+ -/
41
65
structure picard_lindelof (E : Type *) [normed_add_comm_group E] [normed_space ℝ E] :=
42
66
(to_fun : ℝ → E → E)
43
67
(t_min t_max : ℝ)
44
68
(t₀ : Icc t_min t_max)
45
69
(x₀ : E)
46
70
(C R L : ℝ≥0 )
47
- (lipschitz' : ∀ t ∈ Icc t_min t_max, lipschitz_on_with L (to_fun t) (closed_ball x₀ R))
48
- (cont : ∀ x ∈ closed_ball x₀ R, continuous_on (λ t, to_fun t x) (Icc t_min t_max))
49
- (norm_le' : ∀ (t ∈ Icc t_min t_max) (x ∈ closed_ball x₀ R), ∥to_fun t x∥ ≤ C)
50
- (C_mul_le_R : (C : ℝ) * max (t_max - t₀) (t₀ - t_min) ≤ R)
71
+ (is_pl : is_picard_lindelof to_fun t_min t₀ t_max x₀ L R C)
51
72
52
73
namespace picard_lindelof
53
74
@@ -56,27 +77,31 @@ variables (v : picard_lindelof E)
56
77
instance : has_coe_to_fun (picard_lindelof E) (λ _, ℝ → E → E) := ⟨to_fun⟩
57
78
58
79
instance : inhabited (picard_lindelof E) :=
59
- ⟨⟨0 , 0 , 0 , ⟨0 , le_rfl, le_rfl⟩, 0 , 0 , 0 , 0 , λ t ht, (lipschitz_with.const 0 ).lipschitz_on_with _,
60
- λ _ _, by simpa only [pi.zero_apply] using continuous_on_const, λ t ht x hx, norm_zero.le,
61
- (zero_mul _).le⟩⟩
80
+ ⟨⟨0 , 0 , 0 , ⟨0 , le_rfl, le_rfl⟩, 0 , 0 , 0 , 0 ,
81
+ { ht₀ := by { rw [subtype.coe_mk, Icc_self], exact mem_singleton _ },
82
+ hR := by refl,
83
+ lipschitz := λ t ht, (lipschitz_with.const 0 ).lipschitz_on_with _,
84
+ cont := λ _ _, by simpa only [pi.zero_apply] using continuous_on_const,
85
+ norm_le := λ t ht x hx, norm_zero.le,
86
+ C_mul_le_R := (zero_mul _).le }⟩⟩
62
87
63
88
lemma t_min_le_t_max : v.t_min ≤ v.t_max := v.t₀.2 .1 .trans v.t₀.2 .2
64
89
65
90
protected lemma nonempty_Icc : (Icc v.t_min v.t_max).nonempty := nonempty_Icc.2 v.t_min_le_t_max
66
91
67
92
protected lemma lipschitz_on_with {t} (ht : t ∈ Icc v.t_min v.t_max) :
68
93
lipschitz_on_with v.L (v t) (closed_ball v.x₀ v.R) :=
69
- v.lipschitz' t ht
94
+ v.is_pl. lipschitz t ht
70
95
71
96
protected lemma continuous_on :
72
97
continuous_on (uncurry v) (Icc v.t_min v.t_max ×ˢ closed_ball v.x₀ v.R) :=
73
98
have continuous_on (uncurry (flip v)) (closed_ball v.x₀ v.R ×ˢ Icc v.t_min v.t_max),
74
- from continuous_on_prod_of_continuous_on_lipschitz_on _ v.L v.cont v.lipschitz' ,
99
+ from continuous_on_prod_of_continuous_on_lipschitz_on _ v.L v.is_pl. cont v.is_pl. lipschitz,
75
100
this.comp continuous_swap.continuous_on preimage_swap_prod.symm.subset
76
101
77
102
lemma norm_le {t : ℝ} (ht : t ∈ Icc v.t_min v.t_max) {x : E} (hx : x ∈ closed_ball v.x₀ v.R) :
78
103
∥v t x∥ ≤ v.C :=
79
- v.norm_le' _ ht _ hx
104
+ v.is_pl. norm_le _ ht _ hx
80
105
81
106
/-- The maximum of distances from `t₀` to the endpoints of `[t_min, t_max]`. -/
82
107
def t_dist : ℝ := max (v.t_max - v.t₀) (v.t₀ - v.t_min)
@@ -150,7 +175,7 @@ protected lemma mem_closed_ball (t : Icc v.t_min v.t_max) : f t ∈ closed_ball
150
175
calc dist (f t) v.x₀ = dist (f t) (f.to_fun v.t₀) : by rw f.map_t₀'
151
176
... ≤ v.C * dist t v.t₀ : f.lipschitz.dist_le_mul _ _
152
177
... ≤ v.C * v.t_dist : mul_le_mul_of_nonneg_left (v.dist_t₀_le _) v.C.2
153
- ... ≤ v.R : v.C_mul_le_R
178
+ ... ≤ v.R : v.is_pl. C_mul_le_R
154
179
155
180
/-- Given a curve $γ \colon [t_{\min}, t_{\max}] → E$, `v_comp` is the function
156
181
$F(t)=v(π t, γ(π t))$, where `π` is the projection $ℝ → [t_{\min}, t_{\max}]$. The integral of this
@@ -295,7 +320,8 @@ let ⟨N, K, hK⟩ := exists_contracting_iterate v in ⟨_, hK.is_fixed_pt_fixed
295
320
296
321
end
297
322
298
- /-- Picard-Lindelöf (Cauchy-Lipschitz) theorem. -/
323
+ /-- Picard-Lindelöf (Cauchy-Lipschitz) theorem. Use
324
+ `exists_forall_deriv_within_Icc_eq_of_is_picard_lindelof` instead for the public API. -/
299
325
lemma exists_solution :
300
326
∃ f : ℝ → E, f v.t₀ = v.x₀ ∧ ∀ t ∈ Icc v.t_min v.t_max,
301
327
has_deriv_within_at f (v t (f t)) (Icc v.t_min v.t_max) t :=
@@ -310,21 +336,97 @@ end
310
336
311
337
end picard_lindelof
312
338
339
+ lemma is_picard_lindelof.norm_le₀ {E : Type *} [normed_add_comm_group E]
340
+ {v : ℝ → E → E} {t_min t₀ t_max : ℝ} {x₀ : E} {C R : ℝ} {L : ℝ≥0 }
341
+ (hpl : is_picard_lindelof v t_min t₀ t_max x₀ L R C) : ∥v t₀ x₀∥ ≤ C :=
342
+ hpl.norm_le t₀ hpl.ht₀ x₀ $ mem_closed_ball_self hpl.hR
343
+
313
344
/-- Picard-Lindelöf (Cauchy-Lipschitz) theorem. -/
314
- lemma exists_forall_deriv_within_Icc_eq_of_lipschitz_of_continuous
315
- [complete_space E]
316
- {v : ℝ → E → E} {t_min t₀ t_max : ℝ} (ht₀ : t₀ ∈ Icc t_min t_max)
317
- (x₀ : E) {C R : ℝ} (hR : 0 ≤ R) {L : ℝ≥0 }
318
- (Hlip : ∀ t ∈ Icc t_min t_max, lipschitz_on_with L (v t) (closed_ball x₀ R))
319
- (Hcont : ∀ x ∈ closed_ball x₀ R, continuous_on (λ t, v t x) (Icc t_min t_max))
320
- (Hnorm : ∀ (t ∈ Icc t_min t_max) (x ∈ closed_ball x₀ R), ∥v t x∥ ≤ C)
321
- (Hmul_le : C * max (t_max - t₀) (t₀ - t_min) ≤ R) :
345
+ theorem exists_forall_deriv_within_Icc_eq_of_is_picard_lindelof
346
+ [complete_space E] {v : ℝ → E → E} {t_min t₀ t_max : ℝ} (x₀ : E) {C R : ℝ} {L : ℝ≥0 }
347
+ (hpl : is_picard_lindelof v t_min t₀ t_max x₀ L R C) :
322
348
∃ f : ℝ → E, f t₀ = x₀ ∧ ∀ t ∈ Icc t_min t_max,
323
349
has_deriv_within_at f (v t (f t)) (Icc t_min t_max) t :=
324
350
begin
325
- lift C to ℝ≥0 using ((norm_nonneg _).trans $ Hnorm t₀ ht₀ x₀ (mem_closed_ball_self hR)),
326
- lift R to ℝ≥0 using hR,
327
- lift t₀ to Icc t_min t_max using ht₀,
351
+ lift C to ℝ≥0 using (norm_nonneg _).trans hpl.norm_le₀,
352
+ lift t₀ to Icc t_min t_max using hpl.ht₀,
328
353
exact picard_lindelof.exists_solution
329
- ⟨v, t_min, t_max, t₀, x₀, C, R, L, Hlip, Hcont, Hnorm, Hmul_le ⟩
354
+ ⟨v, t_min, t_max, t₀, x₀, C, ⟨ R, hpl.hR⟩, L, { ht₀ := t₀.property, ..hpl } ⟩
330
355
end
356
+
357
+ variables [proper_space E] {v : E → E} (t₀ : ℝ) (x₀ : E)
358
+
359
+ /-- A time-independent, locally continuously differentiable ODE satisfies the hypotheses of the
360
+ Picard-Lindelöf theorem. -/
361
+ lemma exists_is_picard_lindelof_const_of_cont_diff_on_nhds
362
+ {s : set E} (hv : cont_diff_on ℝ 1 v s) (hs : s ∈ 𝓝 x₀) :
363
+ ∃ (ε > (0 : ℝ)) L R C, is_picard_lindelof (λ t, v) (t₀ - ε) t₀ (t₀ + ε) x₀ L R C :=
364
+ begin
365
+ -- extract Lipschitz constant
366
+ obtain ⟨L, s', hs', hlip⟩ := cont_diff_at.exists_lipschitz_on_with
367
+ ((hv.cont_diff_within_at (mem_of_mem_nhds hs)).cont_diff_at hs),
368
+ -- radius of closed ball in which v is bounded
369
+ obtain ⟨r, hr : 0 < r, hball⟩ := metric.mem_nhds_iff.mp (inter_sets (𝓝 x₀) hs hs'),
370
+ have hr' := (half_pos hr).le,
371
+ obtain ⟨C, hC⟩ := (is_compact_closed_ball x₀ (r / 2 )).bdd_above_image -- uses proper_space E
372
+ (hv.continuous_on.norm.mono (subset_inter_iff.mp
373
+ ((closed_ball_subset_ball (half_lt_self hr)).trans hball)).left),
374
+ have hC' : 0 ≤ C,
375
+ { apply (norm_nonneg (v x₀)).trans,
376
+ apply hC,
377
+ exact ⟨x₀, ⟨mem_closed_ball_self hr', rfl⟩⟩ },
378
+ set ε := if C = 0 then 1 else (r / 2 / C) with hε,
379
+ have hε0 : 0 < ε,
380
+ { rw hε,
381
+ split_ifs,
382
+ { exact zero_lt_one },
383
+ { exact div_pos (half_pos hr) (lt_of_le_of_ne hC' (ne.symm h)) } },
384
+ refine ⟨ε, hε0 , L, r / 2 , C, _⟩,
385
+ exact { ht₀ := by {rw ←real.closed_ball_eq_Icc, exact mem_closed_ball_self hε0 .le},
386
+ hR := (half_pos hr).le,
387
+ lipschitz := λ t ht, hlip.mono (subset_inter_iff.mp
388
+ (subset_trans (closed_ball_subset_ball (half_lt_self hr)) hball)).2 ,
389
+ cont := λ x hx, continuous_on_const,
390
+ norm_le := λ t ht x hx, hC ⟨x, hx, rfl⟩,
391
+ C_mul_le_R := begin
392
+ rw [add_sub_cancel', sub_sub_cancel, max_self, mul_ite, mul_one],
393
+ split_ifs,
394
+ { rwa ← h at hr' },
395
+ { exact (mul_div_cancel' (r / 2 ) h).le }
396
+ end }
397
+ end
398
+
399
+ /-- A time-independent, locally continuously differentiable ODE admits a solution in some open
400
+ interval. -/
401
+ theorem exists_forall_deriv_at_Ioo_eq_of_cont_diff_on_nhds
402
+ {s : set E} (hv : cont_diff_on ℝ 1 v s) (hs : s ∈ 𝓝 x₀) :
403
+ ∃ (ε > (0 : ℝ)) (f : ℝ → E), f t₀ = x₀ ∧
404
+ ∀ t ∈ Ioo (t₀ - ε) (t₀ + ε), f t ∈ s ∧ has_deriv_at f (v (f t)) t :=
405
+ begin
406
+ obtain ⟨ε, hε, L, R, C, hpl⟩ := exists_is_picard_lindelof_const_of_cont_diff_on_nhds t₀ x₀ hv hs,
407
+ obtain ⟨f, hf1, hf2⟩ := exists_forall_deriv_within_Icc_eq_of_is_picard_lindelof x₀ hpl,
408
+ have hf2' : ∀ t ∈ Ioo (t₀ - ε) (t₀ + ε), has_deriv_at f (v (f t)) t :=
409
+ λ t ht, (hf2 t (Ioo_subset_Icc_self ht)).has_deriv_at (Icc_mem_nhds ht.1 ht.2 ),
410
+ have h : (f ⁻¹' s) ∈ 𝓝 t₀,
411
+ { have := (hf2' t₀ (mem_Ioo.mpr ⟨sub_lt_self _ hε, lt_add_of_pos_right _ hε⟩)),
412
+ apply continuous_at.preimage_mem_nhds this.continuous_at,
413
+ rw hf1,
414
+ exact hs },
415
+ rw metric.mem_nhds_iff at h,
416
+ obtain ⟨r, hr1, hr2⟩ := h,
417
+ refine ⟨min r ε, lt_min hr1 hε, f, hf1, λ t ht,
418
+ ⟨_, hf2' t (mem_of_mem_of_subset ht (Ioo_subset_Ioo
419
+ (sub_le_sub_left (min_le_right _ _) _) (add_le_add_left (min_le_right _ _) _)))⟩⟩,
420
+ rw ←set.mem_preimage,
421
+ apply set.mem_of_mem_of_subset _ hr2,
422
+ apply set.mem_of_mem_of_subset ht,
423
+ rw ←real.ball_eq_Ioo,
424
+ exact (metric.ball_subset_ball (min_le_left _ _))
425
+ end
426
+
427
+ /-- A time-independent, continuously differentiable ODE admits a solution in some open interval. -/
428
+ theorem exists_forall_deriv_at_Ioo_eq_of_cont_diff
429
+ (hv : cont_diff ℝ 1 v) : ∃ (ε > (0 : ℝ)) (f : ℝ → E), f t₀ = x₀ ∧
430
+ ∀ t ∈ Ioo (t₀ - ε) (t₀ + ε), has_deriv_at f (v (f t)) t :=
431
+ let ⟨ε, hε, f, hf1, hf2⟩ := exists_forall_deriv_at_Ioo_eq_of_cont_diff_on_nhds t₀ x₀ hv.cont_diff_on
432
+ (is_open.mem_nhds is_open_univ (mem_univ _)) in ⟨ε, hε, f, hf1, λ t ht, (hf2 t ht).2 ⟩
0 commit comments