-
Notifications
You must be signed in to change notification settings - Fork 232
Expand file tree
/
Copy pathSection_7_5.lean
More file actions
212 lines (191 loc) · 9.5 KB
/
Section_7_5.lean
File metadata and controls
212 lines (191 loc) · 9.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import Mathlib.Tactic
import Analysis.Section_6_4
import Analysis.Section_7_4
import Mathlib.Topology.Instances.EReal.Lemmas
import Mathlib.Analysis.SpecialFunctions.Pow.Continuity
/-!
# Analysis I, Section 7.5: The root and ratio tests
I have attempted to make the translation as faithful a paraphrasing as possible of the original text. When there is a choice between a more idiomatic Lean solution and a more faithful translation, I have generally chosen the latter. In particular, there will be places where the Lean code could be "golfed" to be more elegant and idiomatic, but I have consciously avoided doing so.
Main constructions and results of this section:
- The root and ratio tests/
A point that is only implicitly stated in the text is that for the root and ratio tests, the lim inf and lim sup should be interpreted within the extended reals. The Lean formalizations below make this point more explicit.
-/
namespace Chapter7
open Filter Real EReal
/-- Theorem 7.5.1(a) (Root test). A technical condition is needed to ensure the limsup is finite. -/
theorem Series.root_test_pos {s : Series}
(h : atTop.limsup (fun n ↦ ((|s.seq n|^(1/(n:ℝ)):ℝ):EReal)) < 1) : s.absConverges := by
-- This proof is written to follow the structure of the original text.
set α':EReal := atTop.limsup (fun n ↦ ↑(|s.seq n|^(1/(n:ℝ)):ℝ))
have hpos : 0 ≤ α' := by
apply le_limsup_of_frequently_le (Frequently.of_forall _) (by isBoundedDefault)
intros; positivity
set α := α'.toReal
have hαα' : α' = α := by
symm; apply coe_toReal
. contrapose! h; simp [h]; exact le_top
contrapose! hpos; simp [hpos]
rw [hαα'] at h hpos; norm_cast at h hpos
set ε := (1-α)/2
have hε : 0 < ε := by simp [ε]; linarith
have hε' : α' < (α+ε:ℝ) := by rw [hαα', EReal.coe_lt_coe_iff]; linarith
have hα : α + ε < 1 := by simp [ε]; linarith
have hα' : 0 < α + ε := by linarith
have := eventually_lt_of_limsup_lt hε' (by isBoundedDefault)
rw [eventually_atTop] at this
choose N' hN using this; set N := max N' (max s.m 1)
have (n:ℤ) (hn: n ≥ N) : |s.seq n| ≤ (α + ε)^n := by
have : n ≥ N' := by omega
have npos : 0 < n := by omega
specialize hN n this
rw [EReal.coe_lt_coe_iff] at hN
calc
_ = (|s.seq n|^(1/(n:ℝ)))^n := by
rw [←rpow_intCast, ←rpow_mul (by positivity)]
symm; convert rpow_one _; field_simp
_ ≤ _ := by
convert pow_le_pow_left₀ (by positivity) (le_of_lt hN) n.toNat
all_goals convert zpow_natCast _ _; omega
set k := (N - s.m).toNat
have hNk : N = s.m + k := by omega
have hgeom : (fun n ↦ (α+ε) ^ n : Series).converges := by
simp [converges_geom_iff, abs_of_pos hα', hα]
rw [converges_from _ N.toNat] at hgeom
have : (s.from N).absConverges := by
apply (converges_of_le _ _ hgeom).1
. simp; omega
intro n hn; simp at hn
have hn' : n ≥ 0 := by omega
simp [hn.1, hn.2, hn']
convert this n hn.2; symm; convert zpow_natCast _ _; omega
unfold absConverges at this ⊢
rw [converges_from _ k]; convert this; simp; refine ⟨ by omega, ?_ ⟩
ext n
by_cases hnm : n ≥ s.m <;> simp [hnm]
by_cases hn: n ≥ N <;> simp [hn] <;> grind
/-- Theorem 7.5.1(b) (Root test) -/
theorem Series.root_test_neg {s : Series}
(h : atTop.limsup (fun n ↦ ((|s.seq n|^(1/(n:ℝ)):ℝ):EReal)) > 1) : s.diverges := by
-- This proof is written to follow the structure of the original text.
apply frequently_lt_of_lt_limsup (by isBoundedDefault) at h
apply diverges_of_nodecay
by_contra this; rw [LinearOrderedAddCommGroup.tendsto_nhds] at this; specialize this 1 (by positivity)
choose n hn hs hs' using (h.and_eventually this).forall_exists_of_atTop 1
simp at hs'; replace hs' := rpow_lt_one ?_ hs' (?_:0 < 1/(n:ℝ)) <;> try positivity
rw [show (1:EReal) = (1:ℝ) by simp, EReal.coe_lt_coe_iff] at hs
linarith
/-- Theorem 7.5.1(c) (Root test) / Exercise 7.5.3 -/
theorem Series.root_test_inconclusive: ∃ s:Series,
atTop.Tendsto (fun n ↦ |s.seq n|^(1/(n:ℝ))) (nhds 1) ∧ s.diverges := by
sorry
/-- Theorem 7.5.1 (Root test) / Exercise 7.5.3 -/
theorem Series.root_test_inconclusive' : ∃ s:Series,
atTop.Tendsto (fun n ↦ |s.seq n|^(1/(n:ℝ))) (nhds 1) ∧ s.absConverges := by
sorry
/-- Lemma 7.5.2 / Exercise 7.5.1 -/
theorem Series.ratio_ineq {c:ℤ → ℝ} (m:ℤ) (hpos: ∀ n ≥ m, c n > 0) :
atTop.liminf (fun n ↦ ((c (n+1) / c n:ℝ):EReal)) ≤
atTop.liminf (fun n ↦ ↑((c n)^(1/(n:ℝ)):ℝ))
∧ atTop.liminf (fun n ↦ (((c n)^(1/(n:ℝ)):ℝ):EReal)) ≤
atTop.limsup (fun n ↦ ↑((c n)^(1/(n:ℝ)):ℝ))
∧ atTop.limsup (fun n ↦ (((c n)^(1/(n:ℝ)):ℝ):EReal)) ≤
atTop.limsup (fun n ↦ ↑(c (n+1) / c n:ℝ))
:= by
-- This proof is written to follow the structure of the original text.
refine ⟨ ?_, liminf_le_limsup ?_ ?_, ?_ ⟩ <;> try isBoundedDefault
. sorry
set L' := limsup (fun n ↦ ((c (n+1) / c n:ℝ):EReal)) .atTop
by_cases hL : L' = ⊤; · rw [hL]; exact le_top
have hL'pos : 0 ≤ L' := by
apply le_limsup_of_frequently_le'
rw [frequently_atTop]
intro N; use max N m, by omega
have hpos1 := hpos (max N m) (by omega)
have hpos2 := hpos ((max N m)+1) (by omega)
positivity
have why : L' ≠ ⊥ := by sorry
set L := L'.toReal
have hL' : L' = L := (coe_toReal hL why).symm
have hLpos : 0 ≤ L := by rw [hL'] at hL'pos; norm_cast at hL'pos
apply le_of_forall_gt_imp_ge_of_dense
intro y hy
by_cases hy' : y = ⊤; · simp [hy']; exact le_top
have : y = y.toReal := by symm; apply coe_toReal hy'; contrapose! hy; simp [hy]
rw [this, hL', EReal.coe_lt_coe_iff] at hy
set ε := y.toReal - L
have hε : 0 < ε := by grind
replace this : y = (L+ε:ℝ) := by convert this; simp [ε]
rw [this]
have hε' : L' < (L+ε:ℝ) := by rw [hL', EReal.coe_lt_coe_iff]; linarith
have := eventually_lt_of_limsup_lt hε' (by isBoundedDefault)
rw [eventually_atTop] at this; choose N' hN using this
set N := max N' (max m 1)
have (n:ℤ) (hn: n ≥ N) : c (n+1) / c n ≤ (L + ε) := by
have : n ≥ N' := by omega
have npos : 0 < n := by omega
specialize hN n this; norm_cast at hN; order
set A := c N * (L+ε)^(-N)
have hA : 0 < A := by specialize hpos N (by omega); positivity
have why2 (n:ℤ) (hn: n ≥ N) : c n ≤ A * (L+ε)^n := by
sorry
have why2_root (n:ℤ) (hn: n ≥ N) : (((c n)^(1/(n:ℝ)):ℝ):EReal) ≤ (A^(1/(n:ℝ)) * (L+ε):ℝ) := by
rw [EReal.coe_le_coe_iff]
have hn' : n > 0 := by omega
calc
_ ≤ (A * (L+ε)^n)^(1/(n:ℝ)) := by
apply_rules [rpow_le_rpow, le_of_lt (hpos n _)]; omega; positivity
_ = A^(1/(n:ℝ)) * ((L+ε)^n)^(1/(n:ℝ)) := mul_rpow (by positivity) (by positivity)
_ = _ := by
congr
rw [←rpow_intCast, ←rpow_mul (by positivity)]
convert rpow_one _
field_simp
calc
_ ≤ atTop.limsup (fun n:ℤ ↦ ((A^(1/(n:ℝ)) * (L+ε):ℝ):EReal)) := by
apply limsup_le_limsup <;> try isBoundedDefault
unfold EventuallyLE; rw [eventually_atTop]
use N
_ ≤ (atTop.limsup (fun n:ℤ ↦ ((A^(1/(n:ℝ)):ℝ):EReal))) * (atTop.limsup (fun n:ℤ ↦ ((L+ε:ℝ):EReal))) := by
convert EReal.limsup_mul_le _ _ _ _ with n
. rfl
. apply Frequently.of_forall; intros; positivity
. apply Eventually.of_forall; simp; positivity
. simp [-coe_add]
simp [-coe_add]; grind
_ = (L+ε:ℝ) := by
simp; convert one_mul _
apply Tendsto.limsup_eq
convert Tendsto.comp (f := fun n:ℤ ↦ (A ^ (n:ℝ)⁻¹)) (g := fun x:ℝ ↦ (x:EReal)) (y := nhds 1) _ _
. apply continuous_coe_real_ereal.tendsto'; norm_num
convert Tendsto.comp (f := fun n:ℤ ↦ (n:ℝ)⁻¹) (g := fun x:ℝ ↦ A^x) (y := nhds 0) _ _
. apply (continuous_const_rpow (by positivity)).tendsto'; simp
exact tendsto_inv_atTop_zero.comp tendsto_intCast_atTop_atTop
/-- Corollary 7.5.3 (Ratio test)-/
theorem Series.ratio_test_pos {s : Series} (hnon: ∀ n ≥ s.m, s.seq n ≠ 0)
(h : atTop.limsup (fun n ↦ ((|s.seq (n+1)| / |s.seq n|:ℝ):EReal)) < 1) : s.absConverges := by
apply Series.root_test_pos (lt_of_le_of_lt _ h)
convert (ratio_ineq s.m _).2.2
convert hnon using 1 with n
simp
/-- Corollary 7.5.3 (Ratio test)-/
theorem Series.ratio_test_neg {s : Series} (hnon: ∀ n ≥ s.m, s.seq n ≠ 0)
(h : atTop.liminf (fun n ↦ ((|s.seq (n+1)| / |s.seq n|:ℝ):EReal)) > 1) : s.diverges := by
apply Series.root_test_neg (lt_of_lt_of_le h _)
convert (ratio_ineq s.m _).1.trans (ratio_ineq s.m _).2.1 with n; rfl
all_goals convert hnon using 1 with n; simp
/-- Corollary 7.5.3 (Ratio test) / Exercise 7.5.3 -/
theorem Series.ratio_test_inconclusive: ∃ s:Series, (∀ n ≥ s.m, s.seq n ≠ 0) ∧
atTop.Tendsto (fun n ↦ |s.seq (n+1)| / |s.seq n|) (nhds 1) ∧ s.diverges := by
sorry
/-- Corollary 7.5.3 (Ratio test) / Exercise 7.5.3 -/
theorem Series.ratio_test_inconclusive' : ∃ s:Series, (∀ n ≥ s.m, s.seq n ≠ 0) ∧
atTop.Tendsto (fun n ↦ |s.seq (n+1)| / |s.seq n|) (nhds 1) ∧ s.absConverges := by
sorry
/-- Proposition 7.5.4 -/
theorem Series.root_self_converges : atTop.Tendsto (fun (n:ℕ) ↦ (n:ℝ)^(1 / (n:ℝ))) (nhds 1) := by
sorry
/-- Exercise 7.5.2 -/
theorem Series.poly_mul_geom_converges {x:ℝ} (hx: |x|<1) (q:ℝ) : (fun n:ℕ ↦ (n:ℝ)^q * x^n : Series).converges
∧ atTop.Tendsto (fun n:ℕ ↦ (n:ℝ)^q * x^n) (nhds 0) := by
sorry
end Chapter7