Skip to content

Commit 0d0b1e4

Browse files
committed
Tighten multibrot bounds
Most importantly, `bottcher_approx_z` does from ‖s.bottcher c z - z⁻¹‖ ≤ 16 * ‖z‖⁻¹ ^ 2 for `16 < ‖c‖ ≤ ‖z‖` to ‖s.bottcher c z - z⁻¹‖ ≤ 0.943 * ‖z‖⁻¹ ^ 2 := by for `4 ≤ ‖c‖ ≤ ‖z‖`, which is already nontrivial at radius 4.
1 parent 54f8824 commit 0d0b1e4

16 files changed

Lines changed: 1281 additions & 445 deletions

Ray/Analytic/Products.lean

Lines changed: 185 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,16 @@ analytic functions are analytic.
2525
open Complex (exp log)
2626
open Filter (atTop)
2727
open Metric (ball closedBall sphere)
28+
open Set
2829
open scoped Classical Real NNReal ENNReal Topology
2930
noncomputable section
3031

32+
variable {ι : Type}
33+
34+
/-!
35+
### Definitions
36+
-/
37+
3138
/-- For all z, `Πₙ f n z` converges absolutely to `g z` (analogous to `HasSumOn`) -/
3239
def HasProdOn (f : ℕ → ℂ → ℂ) (g : ℂ → ℂ) (s : Set ℂ) :=
3340
∀ z, z ∈ s → HasProd (fun n ↦ f n z) (g z)
@@ -51,6 +58,73 @@ theorem HasProd.prodExists {f : ℕ → ℂ} {g : ℂ} (h : HasProd f g) : ProdE
5158
theorem HasProdOn.tprodOn_eq {f : ℕ → ℂ → ℂ} {g : ℂ → ℂ} {s : Set ℂ} :
5259
HasProdOn f g s → ∀ z, z ∈ s → tprodOn f z = g z := fun h z zs ↦ (h z zs).tprod_eq
5360

61+
/-!
62+
### Basics about products of sequences
63+
-/
64+
65+
/-- Powers commute with products -/
66+
theorem product_pow {f : ℕ → ℂ} {g : ℂ} (p : ℕ) (h : HasProd f g) :
67+
HasProd (fun n ↦ f n ^ p) (g ^ p) := by
68+
rw [HasProd]; simp_rw [Finset.prod_pow]
69+
exact Filter.Tendsto.comp (Continuous.tendsto (continuous_pow p) g) h
70+
71+
/-- Powers commute with products (`tprod` version) -/
72+
theorem product_pow' {f : ℕ → ℂ} {p : ℕ} (h : ProdExists f) :
73+
tprod f ^ p = tprod fun n ↦ f n ^ p := by
74+
rcases h with ⟨g, h⟩; rw [HasProd.tprod_eq h]; rw [HasProd.tprod_eq _]; exact product_pow p h
75+
76+
/-- Adding one more term to a product multiplies by it -/
77+
theorem product_cons {a g : ℂ} {f : ℕ → ℂ} (h : HasProd f g) :
78+
HasProd (Stream'.cons a f) (a * g) := by
79+
rw [HasProd] at h ⊢
80+
have ha := Filter.Tendsto.comp (Continuous.tendsto (continuous_mul_left a) g) h
81+
have s : ((fun z ↦ a * z) ∘ fun N : Finset ℕ ↦ N.prod f) =
82+
(fun N : Finset ℕ ↦ N.prod (Stream'.cons a f)) ∘ push := by
83+
apply funext; intro N; simp; exact push_prod
84+
rw [s] at ha
85+
exact tendsto_comp_push.mp ha
86+
87+
/-- Adding one more term to a product multiplies by it (`tprod` version) -/
88+
theorem product_cons' {a : ℂ} {f : ℕ → ℂ} (h : ProdExists f) :
89+
tprod (Stream'.cons a f) = a * tprod f := by
90+
rcases h with ⟨g, h⟩; rw [HasProd.tprod_eq h]; rw [HasProd.tprod_eq _]; exact product_cons h
91+
92+
/-- Dropping a nonzero term divides by it -/
93+
theorem product_drop {f : ℕ → ℂ} {g : ℂ} (f0 : f 00) (h : HasProd f g) :
94+
HasProd (fun n ↦ f (n + 1)) (g / f 0) := by
95+
have c := @product_cons (f 0)⁻¹ _ _ h
96+
rw [HasProd]
97+
rw [inv_mul_eq_div, HasProd, SummationFilter.unconditional_filter, ← tendsto_comp_push,
98+
← tendsto_comp_push] at c
99+
have s : ((fun N : Finset ℕ ↦ N.prod fun n ↦ (Stream'.cons (f 0)⁻¹ f) n) ∘ push) ∘ push =
100+
fun N : Finset ℕ ↦ N.prod fun n ↦ f (n + 1) := by
101+
clear c h g; apply funext; intro N; simp
102+
nth_rw 2 [← Stream'.eta f]
103+
simp only [←push_prod, Stream'.head, Stream'.tail, Stream'.get, ←mul_assoc, inv_mul_cancel₀ f0,
104+
one_mul]
105+
rw [s] at c; assumption
106+
107+
/-- Dropping a nonzero term divides by it (`tprod` version) -/
108+
theorem product_drop' {f : ℕ → ℂ} (f0 : f 00) (h : ProdExists f) :
109+
(tprod fun n ↦ f (n + 1)) = tprod f / f 0 := by
110+
rcases h with ⟨g, h⟩; rw [HasProd.tprod_eq h]; rw [HasProd.tprod_eq _]; exact product_drop f0 h
111+
112+
/-- Products that start with zero are zero -/
113+
theorem product_head_zero {f : ℕ → ℂ} (f0 : f 0 = 0) : HasProd f 0 := by
114+
rw [HasProd, SummationFilter.unconditional_filter, Metric.tendsto_atTop]; intro e ep
115+
use Finset.range 1; intro N N1
116+
simp at N1; rw [Finset.prod_eq_zero N1 f0]; simpa
117+
118+
/-- Separate out head and tail in a product -/
119+
theorem product_split {f : ℕ → ℂ} (h : ProdExists f) : tprod f = f 0 * tprod fun n ↦ f (n + 1) := by
120+
by_cases f0 : f 0 = 0; · rw [f0, (product_head_zero f0).tprod_eq]; simp
121+
rw [product_drop' f0 h]; field_simp
122+
123+
124+
/-!
125+
### Infinite products of analytic functions
126+
-/
127+
54128
/-- Analytic products that converge exponentially converge to analytic functions.
55129
For now, we require the constant to be `≤ 1/2` so that we can take logs without
56130
care, and get nonzero results. -/
@@ -72,7 +146,6 @@ theorem fast_products_converge {f : ℕ → ℂ → ℂ} {s : Set ℂ} {a c :
72146
exact near_one_avoids_zero (near1' n z zs)
73147
have hl : ∀ n, AnalyticOnNhd ℂ (fl n) s := fun n ↦
74148
(h n).clog (fun z m ↦ mem_slitPlane_of_near_one (near1' n z m))
75-
--fun n ↦ log_analytic_near_one o (h n) (near1' n)
76149
set c2 := 2 * c
77150
have hfl : ∀ n z, z ∈ s → ‖fl n z‖ ≤ c2 * a ^ n := by
78151
intro n z zs
@@ -97,7 +170,49 @@ theorem fast_products_converge {f : ℕ → ℂ → ℂ} {s : Set ℂ} {a c :
97170
· rw [← hg]; exact fun z zs ↦ analyticAt_cexp.comp (gla z zs)
98171
· simp only [Complex.exp_ne_zero, Ne, not_false_iff, imp_true_iff, ← hg]
99172

100-
/-- Same as above, but converge to `tprodOn` -/
173+
/-- Same as above, but remove the requirement that `c ≤ 1/2` by peeling off the first few terms -/
174+
theorem fast_products_converge_eventually {f : ℕ → ℂ → ℂ} {s : Set ℂ} {c a : ℝ} (o : IsOpen s)
175+
(a0 : 0 ≤ a) (a1 : a < 1) (fa : ∀ n, AnalyticOnNhd ℂ (f n) s)
176+
(fb : ∀ᶠ n in atTop, ∀ z ∈ s, ‖f n z - 1‖ ≤ c * a ^ n) :
177+
∃ g : ℂ → ℂ, HasProdOn f g s ∧ AnalyticOnNhd ℂ g s ∧
178+
∀ z, z ∈ s → (∀ n, f n z ≠ 0) → g z ≠ 0 := by
179+
-- We need `c * a ^ n0 ≤ 1 / 2`, or `a ^ n0 ≤ 1 / (2 * c)`.
180+
have ta := (tendsto_const_nhds (x := c)).mul (tendsto_pow_atTop_nhds_zero_of_lt_one a0 a1)
181+
simp only [mul_zero] at ta
182+
have low := ta.eventually_le_const (u := 1/2) (by norm_num)
183+
obtain ⟨N, h⟩ := Filter.eventually_atTop.mp (fb.and low)
184+
have fa' := fun n ↦ fa (N + n)
185+
have fb' : ∀ n z, z ∈ s → ‖f (N + n) z - 1‖ ≤ c * a ^ N * a ^ n := by
186+
intro n z zs
187+
exact le_trans ((h (N + n) (by omega)).1 z zs) (by simp only [pow_add, mul_assoc, le_refl])
188+
obtain ⟨g, fg, ga, g0⟩ := fast_products_converge o (h N (le_refl _)).2 a0 a1 fa' fb'
189+
refine ⟨fun z ↦ (∏ n ∈ Finset.range N, f n z) * g z, ?_, ?_, ?_⟩
190+
· intro z zs
191+
specialize fg z zs
192+
simp only at fg ⊢
193+
clear zs g0 ga fb' fa' h low ta fb fa a1 a0 o c a s
194+
suffices P : ∀ M, M ≤ N → HasProd (fun n ↦ f (N - M + n) z)
195+
((∏ n ∈ Finset.range M, f (N - M + n) z) * g z) by
196+
simpa only [tsub_self, zero_add] using P N (le_refl _)
197+
intro M MN
198+
induction' M with M H
199+
· simpa using fg
200+
· specialize H (by omega)
201+
have e : ∀ k, (N - (M + 1) + (k + 1)) = (N - M + k) := by grind
202+
have ec : (Stream'.cons (f (N - (M + 1)) z) fun n ↦ f (N - M + n) z) =
203+
fun n ↦ f (N - (M + 1) + n) z := by
204+
ext n
205+
induction' n with n h
206+
· simp only [Stream'.get, Stream'.cons, add_zero]
207+
· simp only [Stream'.get, Stream'.cons]
208+
grind
209+
simpa only [Finset.prod_range_succ', e, add_zero, mul_comm _ (f _ _), mul_assoc (f _ _),
210+
ec] using product_cons (a := f (N - (M + 1)) z) H
211+
· exact (Finset.analyticOnNhd_fun_prod _ fun n _ ↦ fa n).mul ga
212+
· intro z zs f0
213+
simp [g0 z zs, Finset.prod_eq_zero_iff, f0]
214+
215+
/-- Same as `fast_products_converge`, but converge to `tprodOn` -/
101216
theorem fast_products_converge' {f : ℕ → ℂ → ℂ} {s : Set ℂ} {c a : ℝ} (o : IsOpen s)
102217
(c12 : c ≤ 1 / 2) (a0 : 0 ≤ a) (a1 : a < 1) (h : ∀ n, AnalyticOnNhd ℂ (f n) s)
103218
(hf : ∀ n z, z ∈ s → ‖f n z - 1‖ ≤ c * a ^ n) :
@@ -108,60 +223,75 @@ theorem fast_products_converge' {f : ℕ → ℂ → ℂ} {s : Set ℂ} {c a :
108223
· rwa [← analyticOnNhd_congr o fun z zs ↦ (gp.tprodOn_eq z zs).symm]
109224
· intro z zs; rw [gp.tprodOn_eq z zs]; exact g0 z zs
110225

111-
/-- Powers commute with products -/
112-
theorem product_pow {f : ℕ → ℂ} {g : ℂ} (p : ℕ) (h : HasProd f g) :
113-
HasProd (fun n ↦ f n ^ p) (g ^ p) := by
114-
rw [HasProd]; simp_rw [Finset.prod_pow]
115-
exact Filter.Tendsto.comp (Continuous.tendsto (continuous_pow p) g) h
116-
117-
/-- Powers commute with products (`tprod` version) -/
118-
theorem product_pow' {f : ℕ → ℂ} {p : ℕ} (h : ProdExists f) :
119-
tprod f ^ p = tprod fun n ↦ f n ^ p := by
120-
rcases h with ⟨g, h⟩; rw [HasProd.tprod_eq h]; rw [HasProd.tprod_eq _]; exact product_pow p h
121-
122-
/-- Adding one more term to a product multiplies by it -/
123-
theorem product_cons {a g : ℂ} {f : ℕ → ℂ} (h : HasProd f g) :
124-
HasProd (Stream'.cons a f) (a * g) := by
125-
rw [HasProd] at h ⊢
126-
have ha := Filter.Tendsto.comp (Continuous.tendsto (continuous_mul_left a) g) h
127-
have s : ((fun z ↦ a * z) ∘ fun N : Finset ℕ ↦ N.prod f) =
128-
(fun N : Finset ℕ ↦ N.prod (Stream'.cons a f)) ∘ push := by
129-
apply funext; intro N; simp; exact push_prod
130-
rw [s] at ha
131-
exact tendsto_comp_push.mp ha
132-
133-
/-- Adding one more term to a product multiplies by it (`tprod` version) -/
134-
theorem product_cons' {a : ℂ} {f : ℕ → ℂ} (h : ProdExists f) :
135-
tprod (Stream'.cons a f) = a * tprod f := by
136-
rcases h with ⟨g, h⟩; rw [HasProd.tprod_eq h]; rw [HasProd.tprod_eq _]; exact product_cons h
226+
/-- Same as `fast_products_converge_eventually`, but converge to `tprodOn` -/
227+
theorem fast_products_converge_eventually' {f : ℕ → ℂ → ℂ} {s : Set ℂ} {c a : ℝ} (o : IsOpen s)
228+
(a0 : 0 ≤ a) (a1 : a < 1) (h : ∀ n, AnalyticOnNhd ℂ (f n) s)
229+
(hf : ∀ᶠ n in atTop, ∀ z ∈ s, ‖f n z - 1‖ ≤ c * a ^ n) :
230+
ProdExistsOn f s ∧ AnalyticOnNhd ℂ (tprodOn f) s ∧
231+
∀ z, z ∈ s → (∀ n, f n z ≠ 0) → tprodOn f z ≠ 0 := by
232+
rcases fast_products_converge_eventually o a0 a1 h hf with ⟨g, gp, ga, g0⟩
233+
refine ⟨?_, ?_, ?_⟩
234+
· exact fun z zs ↦ ⟨g z, gp z zs⟩
235+
· rwa [← analyticOnNhd_congr o fun z zs ↦ (gp.tprodOn_eq z zs).symm]
236+
· intro z zs; rw [gp.tprodOn_eq z zs]; exact g0 z zs
137237

138-
/-- Dropping a nonzero term divides by it -/
139-
theorem product_drop {f : ℕ → ℂ} {g : ℂ} (f0 : f 00) (h : HasProd f g) :
140-
HasProd (fun n ↦ f (n + 1)) (g / f 0) := by
141-
have c := @product_cons (f 0)⁻¹ _ _ h
142-
rw [HasProd]
143-
rw [inv_mul_eq_div, HasProd, SummationFilter.unconditional_filter, ← tendsto_comp_push,
144-
← tendsto_comp_push] at c
145-
have s : ((fun N : Finset ℕ ↦ N.prod fun n ↦ (Stream'.cons (f 0)⁻¹ f) n) ∘ push) ∘ push =
146-
fun N : Finset ℕ ↦ N.prod fun n ↦ f (n + 1) := by
147-
clear c h g; apply funext; intro N; simp
148-
nth_rw 2 [← Stream'.eta f]
149-
simp only [←push_prod, Stream'.head, Stream'.tail, Stream'.get, ←mul_assoc, inv_mul_cancel₀ f0,
150-
one_mul]
151-
rw [s] at c; assumption
238+
/-!
239+
### Reasonably tight bounds on products
240+
-/
152241

153-
/-- Dropping a nonzero term divides by it (`tprod` version) -/
154-
theorem product_drop' {f : ℕ → ℂ} (f0 : f 00) (h : ProdExists f) :
155-
(tprod fun n ↦ f (n + 1)) = tprod f / f 0 := by
156-
rcases h with ⟨g, h⟩; rw [HasProd.tprod_eq h]; rw [HasProd.tprod_eq _]; exact product_drop f0 h
242+
lemma norm_mul_sub_one_le {a b : ℂ} :
243+
‖a * b - 1‖ ≤ (1 + ‖a - 1‖) * (1 + ‖b - 1‖) - 1 := by
244+
-- Ugly semi-GPT 5.1 proof, but meh, it works.
245+
have h1 : a * b - 1 = (a - 1) * (b - 1) + (a - 1) + (b - 1) := by ring_nf
246+
have h2 : ‖a * b - 1‖ ≤ ‖(a - 1) * (b - 1) + (a - 1)‖ + ‖b - 1‖ := by
247+
simpa [h1, add_assoc] using (norm_add_le ((a - 1) * (b - 1) + (a - 1)) (b - 1))
248+
have h3 : ‖(a - 1) * (b - 1) + (a - 1)‖ ≤ ‖(a - 1) * (b - 1)‖ + ‖a - 1‖ := by bound
249+
have h4 : ‖a * b - 1‖ ≤ ‖(a - 1) * (b - 1)‖ + ‖a - 1‖ + ‖b - 1‖ :=
250+
le_trans h2 (by simpa [add_assoc, add_comm, add_left_comm] using add_le_add_right h3 ‖b - 1‖)
251+
have h5 : ‖a * b - 1‖ ≤ ‖a - 1‖ * ‖b - 1‖ + ‖a - 1‖ + ‖b - 1‖ := by
252+
simpa [norm_mul, add_comm, add_left_comm, add_assoc] using h4
253+
grind
157254

158-
/-- Products that start with zero are zero -/
159-
theorem product_head_zero {f : ℕ → ℂ} (f0 : f 0 = 0) : HasProd f 0 := by
160-
rw [HasProd, SummationFilter.unconditional_filter, Metric.tendsto_atTop]; intro e ep
161-
use Finset.range 1; intro N N1
162-
simp at N1; rw [Finset.prod_eq_zero N1 f0]; simpa
255+
lemma Finset.norm_prod_sub_one_le {f : ι → ℂ} {s : Finset ι} :
256+
‖∏ i ∈ s, f i - 1‖ ≤ ∏ i ∈ s, (1 + ‖f i - 1‖) - 1 := by
257+
induction' s using Finset.induction with i s is h
258+
· simp only [prod_empty, sub_self, norm_zero, le_refl]
259+
· simp only [Finset.prod_insert is]
260+
exact le_trans norm_mul_sub_one_le (by bound)
163261

164-
/-- Separate out head and tail in a product -/
165-
theorem product_split {f : ℕ → ℂ} (h : ProdExists f) : tprod f = f 0 * tprod fun n ↦ f (n + 1) := by
166-
by_cases f0 : f 0 = 0; · rw [f0, (product_head_zero f0).tprod_eq]; simp
167-
rw [product_drop' f0 h]; field_simp
262+
/-- Bound a product in terms of bounds on the first few terms, and a geometric tail bound -/
263+
lemma HasProd.norm_sub_one_le {f : ℕ → ℂ} {g : ℂ} (fg : HasProd f g)
264+
{n : ℕ} {b : Fin n → ℝ} (lo : ∀ k : Fin n, ‖f k - 1‖ ≤ b k)
265+
{c a : ℝ} (hi : ∀ k ≥ n, ‖f k - 1‖ ≤ c * a ^ k)
266+
(b0 : ∀ k, 0 ≤ b k) (c0 : 0 ≤ c) (a0 : 0 ≤ a) (a1 : a < 1) (ca : c * a ^ n / (1 - a) ≤ 1 / 2) :
267+
‖g - 1‖ ≤ (∏ k, (1 + b k)) * (1 + 4 * c * a ^ n / (1 - a)) - 1 := by
268+
have le1 : ‖∏ i ∈ .range n, f i - 1‖ ≤ ∏ i, (1 + b i) - 1 := by
269+
refine le_trans Finset.norm_prod_sub_one_le ?_
270+
simp only [Finset.prod_fin_eq_prod_range]
271+
refine tsub_le_tsub_right (Finset.prod_le_prod (by bound) fun i m ↦ ?_) _
272+
specialize lo ⟨i, by simpa using m⟩
273+
grind
274+
rw [le_sub_iff_add_le, add_comm] at le1
275+
simp only [HasProd] at fg
276+
apply le_of_tendsto (Filter.Tendsto.comp continuous_norm.continuousAt (fg.sub_const 1))
277+
simp only [Function.comp_apply, SummationFilter.unconditional_filter, Filter.eventually_atTop]
278+
refine ⟨Finset.range n, fun s ns ↦ ?_⟩
279+
have le2 : ‖∏ i ∈ s \ .range n, f i - 1‖ ≤ 4 * c * a ^ n / (1 - a) := by
280+
simp only [mul_assoc, div_eq_mul_inv]
281+
set t := (s \ .range n).image fun k ↦ k - n
282+
have st : s \ .range n = t.image fun k ↦ k + n := by
283+
simp only [t, Finset.image_image, Function.comp_def]
284+
rw [Finset.image_congr (g := id), Finset.image_id]
285+
intro k m
286+
simp at m ⊢
287+
omega
288+
have inj : InjOn (fun k ↦ k + n) t := by intro a _ b _; simp
289+
simp only [st, Finset.prod_image inj, ← mul_assoc c]
290+
refine dist_prod_one_le_abs_sum ?_ ca
291+
refine le_trans ?_ (mul_le_mul_of_nonneg_left (partial_geometric_bound t a0 a1) (by bound))
292+
simp only [Finset.mul_sum, mul_assoc, ← pow_add, add_comm n]
293+
exact Finset.sum_le_sum fun i m ↦ hi _ (by omega)
294+
have d : Disjoint (Finset.range n) (s \ Finset.range n) := Finset.disjoint_sdiff
295+
have e : s = (Finset.range n).disjUnion (s \ Finset.range n) d := by simpa using ns
296+
rw [e, Finset.prod_disjUnion]
297+
exact le_trans norm_mul_sub_one_le (by bound)

0 commit comments

Comments
 (0)