@@ -25,9 +25,16 @@ analytic functions are analytic.
2525open Complex (exp log)
2626open Filter (atTop)
2727open Metric (ball closedBall sphere)
28+ open Set
2829open scoped Classical Real NNReal ENNReal Topology
2930noncomputable 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`) -/
3239def 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
5158theorem 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 0 ≠ 0 ) (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 0 ≠ 0 ) (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` -/
101216theorem 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 0 ≠ 0 ) (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 0 ≠ 0 ) (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