Skip to content

Commit 389ef58

Browse files
committed
feat: compute trailing coefficients of factorized rational functions (leanprover-community#26141)
This PR continues the work from leanprover-community#25523. Original PR: leanprover-community#25523
1 parent 19f4ef2 commit 389ef58

2 files changed

Lines changed: 179 additions & 3 deletions

File tree

Mathlib/Analysis/Meromorphic/FactorizedRational.lean

Lines changed: 137 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Stefan Kebekus
55
-/
66
import Mathlib.Analysis.Meromorphic.Divisor
7+
import Mathlib.Analysis.Meromorphic.IsolatedZeros
78
import Mathlib.Analysis.Meromorphic.NormalForm
9+
import Mathlib.Analysis.Meromorphic.TrailingCoefficient
810
import Mathlib.Analysis.SpecialFunctions.Log.Basic
911

1012
/-!
@@ -31,7 +33,7 @@ variable
3133
{E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E]
3234
{U : Set 𝕜}
3335

34-
open Filter Real Set
36+
open Filter Function Real Set
3537

3638
namespace Function.FactorizedRational
3739

@@ -178,6 +180,95 @@ theorem divisor {U : Set 𝕜} {D : locallyFinsuppWithin U ℤ} (hD : D.support.
178180
by_cases hz : z ∈ U
179181
<;> simp [(meromorphicNFOn D U).meromorphicOn, hz, meromorphicOrderAt_eq D hD]
180182

183+
open Classical in
184+
private lemma mulSupport_update {d : 𝕜 → ℤ} {x : 𝕜}
185+
(h : d.support.Finite) :
186+
(fun u ↦ (x - u) ^ Function.update d x 0 u).mulSupport ⊆ h.toFinset := by
187+
intro u
188+
contrapose
189+
simp only [mem_mulSupport, ne_eq, Decidable.not_not]
190+
by_cases h₁ : u = x
191+
· rw [h₁]
192+
simp
193+
· simp_all
194+
195+
open Classical in
196+
/--
197+
Compute the trailing coefficient of the factorized rational function associated with `d : 𝕜 → ℤ`.
198+
-/
199+
200+
/-
201+
Low-priotity TODO: Using that non-trivially normed fields contain infinitely many elements that are
202+
no roots of unity, it might be possible to drop assumption `h` here and in some of the theorems
203+
below.
204+
-/
205+
theorem meromorphicTrailingCoeffAt_factorizedRational {d : 𝕜 → ℤ} {x : 𝕜} (h : d.support.Finite) :
206+
meromorphicTrailingCoeffAt (∏ᶠ u, (· - u) ^ d u) x = ∏ᶠ u, (x - u) ^ update d x 0 u := by
207+
have : (fun u ↦ (· - u) ^ d u).mulSupport ⊆ h.toFinset := by
208+
simp [Function.FactorizedRational.mulSupport]
209+
rw [finprod_eq_prod_of_mulSupport_subset _ this, meromorphicTrailingCoeffAt_prod
210+
(fun _ ↦ by fun_prop), finprod_eq_prod_of_mulSupport_subset _ (mulSupport_update h)]
211+
apply Finset.prod_congr rfl
212+
intro y hy
213+
rw [MeromorphicAt.meromorphicTrailingCoeffAt_zpow (by fun_prop)]
214+
by_cases hxy : x = y
215+
· rw [hxy, meromorphicTrailingCoeffAt_id_sub_const]
216+
simp_all
217+
· rw [meromorphicTrailingCoeffAt_id_sub_const]
218+
simp only [hxy, reduceIte]
219+
congr
220+
apply (Function.update_of_ne (by tauto) _ _).symm
221+
222+
/--
223+
Variant of `meromorphicTrailingCoeffAt_factorizedRational`: Compute the trailing coefficient of the
224+
factorized rational function associated with `d : 𝕜 → ℤ` at points outside the support of `d`.
225+
-/
226+
theorem meromorphicTrailingCoeffAt_factorizedRational_off_support {d : 𝕜 → ℤ} {x : 𝕜}
227+
(h₁ : d.support.Finite) (h₂ : x ∉ d.support) :
228+
meromorphicTrailingCoeffAt (∏ᶠ u, (· - u) ^ d u) x = ∏ᶠ u, (x - u) ^ d u := by
229+
classical
230+
rw [meromorphicTrailingCoeffAt_factorizedRational h₁,
231+
finprod_eq_prod_of_mulSupport_subset _ (mulSupport_update h₁)]
232+
have : (fun u ↦ (x - u) ^ d u).mulSupport ⊆ h₁.toFinset := by
233+
intro u
234+
contrapose
235+
simp_all
236+
rw [finprod_eq_prod_of_mulSupport_subset _ this, Finset.prod_congr rfl]
237+
intro y hy
238+
congr
239+
apply Function.update_of_ne
240+
by_contra hCon
241+
simp_all
242+
243+
/--
244+
Variant of `meromorphicTrailingCoeffAt_factorizedRational`: Compute log of the norm of the trailing
245+
coefficient. The convention that `log 0 = 0` gives a closed formula easier than the one in
246+
`meromorphicTrailingCoeffAt_factorizedRational`.
247+
-/
248+
theorem log_norm_meromorphicTrailingCoeffAt {d : 𝕜 → ℤ} {x : 𝕜} (h : d.support.Finite) :
249+
log ‖meromorphicTrailingCoeffAt (∏ᶠ u, (· - u) ^ d u) x‖ = ∑ᶠ u, (d u) * log ‖x - u‖ := by
250+
classical
251+
rw [meromorphicTrailingCoeffAt_factorizedRational h,
252+
finprod_eq_prod_of_mulSupport_subset _ (mulSupport_update h)]
253+
have : ∀ y ∈ h.toFinset, ‖(x - y) ^ update d x 0 y‖ ≠ 0 := by
254+
intro y _
255+
by_cases h : x = y
256+
· rw [h]
257+
simp_all
258+
· simp_all [zpow_ne_zero, sub_ne_zero]
259+
rw [norm_prod, log_prod _ _ this]
260+
have : (fun u ↦ (d u) * log ‖x - u‖).support ⊆ h.toFinset := by
261+
intro u
262+
contrapose
263+
simp_all
264+
rw [finsum_eq_sum_of_support_subset _ this]
265+
apply Finset.sum_congr rfl
266+
intro y hy
267+
rw [norm_zpow, Real.log_zpow]
268+
by_cases h : x = y
269+
· simp [h]
270+
· rw [Function.update_of_ne (by tauto)]
271+
181272
end Function.FactorizedRational
182273

183274
open Function.FactorizedRational
@@ -190,7 +281,9 @@ modulo equality on codiscrete sets, to the product of a factorized rational func
190281
function without zeros.
191282
192283
We provide analogous results for functions of the form `log ‖meromorphic‖`.
284+
-/
193285

286+
/-
194287
TODO: Identify some of the terms that appear in the decomposition.
195288
-/
196289

@@ -267,14 +360,15 @@ theorem MeromorphicOn.extract_zeros_poles_log {f g : 𝕜 → E} {D : Function.l
267360
by_cases h₃f : D.support.Finite
268361
case neg =>
269362
rw [finsum_of_infinite_support (by simpa [t₁] using h₃f)]
270-
rw [finprod_of_infinite_mulSupport (by simpa [mulSupport] using h₃f)] at h
363+
rw [finprod_of_infinite_mulSupport (by simpa [FactorizedRational.mulSupport] using h₃f)] at h
271364
filter_upwards [h] with x hx
272365
simp [hx]
273366
-- General case
274367
filter_upwards [h, D.eq_zero_codiscreteWithin, self_mem_codiscreteWithin U] with z hz h₂z h₃z
275368
rw [Pi.zero_apply] at h₂z
276369
rw [hz, finprod_eq_prod_of_mulSupport_subset (s := h₃f.toFinset) _
277-
(by simp_all [mulSupport]), finsum_eq_sum_of_support_subset (s := h₃f.toFinset) _ (by simp_all)]
370+
(by simp_all [FactorizedRational.mulSupport]),
371+
finsum_eq_sum_of_support_subset (s := h₃f.toFinset) _ (by simp_all)]
278372
have : ∀ x ∈ h₃f.toFinset, ‖z - x‖ ^ D x ≠ 0 := by
279373
intro x hx
280374
rw [Finite.mem_toFinset, Function.mem_support] at hx
@@ -284,3 +378,43 @@ theorem MeromorphicOn.extract_zeros_poles_log {f g : 𝕜 → E} {D : Function.l
284378
simp only [Pi.smul_apply', Finset.prod_apply, Pi.pow_apply, norm_smul, norm_prod, norm_zpow]
285379
rw [log_mul (Finset.prod_ne_zero_iff.2 this) (by simp [hg ⟨z, h₃z⟩]), log_prod _ _ this]
286380
simp [log_zpow]
381+
382+
open Classical in
383+
/--
384+
In the setting of `MeromorphicOn.extract_zeros_poles`, compute the trailing
385+
coefficient of `f` in terms of `divisor f U` and `g x`.
386+
-/
387+
theorem MeromorphicOn.meromorphicTrailingCoeffAt_extract_zeros_poles
388+
{x : 𝕜} {f g : 𝕜 → E} {D : 𝕜 → ℤ} (hD : D.support.Finite) (h₁x : x ∈ U) (h₂x : AccPt x (𝓟 U))
389+
(hf : MeromorphicAt f x) (h₁g : AnalyticAt 𝕜 g x) (h₂g : g x ≠ 0)
390+
(h : f =ᶠ[codiscreteWithin U] (∏ᶠ u, (· - u) ^ D u) • g) :
391+
meromorphicTrailingCoeffAt f x = (∏ᶠ u, (x - u) ^ Function.update D x 0 u) • g x := by
392+
have t₀ : MeromorphicAt (∏ᶠ u, (· - u) ^ D u) x :=
393+
(FactorizedRational.meromorphicNFOn D U).meromorphicOn x h₁x
394+
rw [meromorphicTrailingCoeffAt_congr_nhdsNE
395+
(hf.eventuallyEq_nhdsNE_of_eventuallyEq_codiscreteWithin (by fun_prop) h₁x h₂x h),
396+
t₀.meromorphicTrailingCoeffAt_smul h₁g.meromorphicAt,
397+
h₁g.meromorphicTrailingCoeffAt_of_ne_zero h₂g]
398+
simp [meromorphicTrailingCoeffAt_factorizedRational hD]
399+
400+
/--
401+
In the setting of `MeromorphicOn.extract_zeros_poles`, compute the log of the
402+
norm of the trailing coefficient of `f` in terms of `divisor f U` and `g x`.
403+
-/
404+
theorem MeromorphicOn.log_norm_meromorphicTrailingCoeffAt_extract_zeros_poles
405+
{x : 𝕜} {f g : 𝕜 → E} {D : 𝕜 → ℤ} (hD : D.support.Finite) (h₁x : x ∈ U) (h₂x : AccPt x (𝓟 U))
406+
(hf : MeromorphicAt f x) (h₁g : AnalyticAt 𝕜 g x) (h₂g : g x ≠ 0)
407+
(h : f =ᶠ[codiscreteWithin U] (∏ᶠ u, (· - u) ^ D u) • g) :
408+
log ‖meromorphicTrailingCoeffAt f x‖ = ∑ᶠ u, (D u) * log ‖x - u‖ + log ‖g x‖ := by
409+
rw [meromorphicTrailingCoeffAt_congr_nhdsNE
410+
(hf.eventuallyEq_nhdsNE_of_eventuallyEq_codiscreteWithin
411+
(((FactorizedRational.meromorphicNFOn D U).meromorphicOn x h₁x).smul h₁g.meromorphicAt)
412+
h₁x h₂x h),
413+
((FactorizedRational.meromorphicNFOn D U).meromorphicOn x h₁x).meromorphicTrailingCoeffAt_smul
414+
h₁g.meromorphicAt, h₁g.meromorphicTrailingCoeffAt_of_ne_zero h₂g,
415+
norm_smul, log_mul, log_norm_meromorphicTrailingCoeffAt hD]
416+
· simp only [ne_eq, norm_eq_zero]
417+
apply MeromorphicAt.meromorphicTrailingCoeffAt_ne_zero
418+
((FactorizedRational.meromorphicNFOn D U).meromorphicOn x h₁x)
419+
apply FactorizedRational.meromorphicOrderAt_ne_top
420+
· simp_all

Mathlib/Analysis/Meromorphic/TrailingCoefficient.lean

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,34 @@ lemma MeromorphicAt.meromorphicTrailingCoeffAt_ne_zero (h₁ : MeromorphicAt f x
141141
obtain ⟨g, h₁g, h₂g, h₃g⟩ := (meromorphicOrderAt_ne_top_iff h₁).1 h₂
142142
simpa [h₁g.meromorphicTrailingCoeffAt_of_ne_zero_of_eq_nhdsNE h₂g h₃g] using h₂g
143143

144+
/--
145+
The trailing coefficient of a constant function is the constant.
146+
-/
147+
@[simp]
148+
theorem meromorphicTrailingCoeffAt_const {x : 𝕜} {e : 𝕜} :
149+
meromorphicTrailingCoeffAt (fun _ ↦ e) x = e := by
150+
by_cases he : e = 0
151+
· rw [he]
152+
apply MeromorphicAt.meromorphicTrailingCoeffAt_of_order_eq_top
153+
rw [meromorphicOrderAt_eq_top_iff]
154+
simp
155+
· exact analyticAt_const.meromorphicTrailingCoeffAt_of_ne_zero he
156+
157+
/--
158+
The trailing coefficient of `fun z ↦ z - constant` at `z₀` equals one if `z₀ = constant`, or else
159+
`z₀ - constant`.
160+
-/
161+
theorem meromorphicTrailingCoeffAt_id_sub_const [DecidableEq 𝕜] {x y : 𝕜} :
162+
meromorphicTrailingCoeffAt (· - y) x = if x = y then 1 else x - y := by
163+
by_cases h : x = y
164+
· simp_all only [sub_self, ite_true]
165+
apply AnalyticAt.meromorphicTrailingCoeffAt_of_ne_zero_of_eq_nhdsNE (n := 1) (by fun_prop)
166+
(by apply one_ne_zero)
167+
simp
168+
· simp_all only [ite_false]
169+
apply AnalyticAt.meromorphicTrailingCoeffAt_of_ne_zero (by fun_prop)
170+
simp_all [sub_ne_zero]
171+
144172
/-!
145173
## Congruence Lemma
146174
-/
@@ -196,6 +224,20 @@ lemma MeromorphicAt.meromorphicTrailingCoeffAt_mul {f₁ f₂ : 𝕜 → 𝕜} (
196224
(meromorphicTrailingCoeffAt f₁ x) * (meromorphicTrailingCoeffAt f₂ x) :=
197225
meromorphicTrailingCoeffAt_smul hf₁ hf₂
198226

227+
/--
228+
The trailing coefficient of a product is the product of the trailing coefficients.
229+
-/
230+
theorem meromorphicTrailingCoeffAt_prod {ι : Type*} {s : Finset ι} {f : ι → 𝕜 → 𝕜} {x : 𝕜}
231+
(h : ∀ σ, MeromorphicAt (f σ) x) :
232+
meromorphicTrailingCoeffAt (∏ n ∈ s, f n) x = ∏ n ∈ s, meromorphicTrailingCoeffAt (f n) x := by
233+
classical
234+
induction s using Finset.induction with
235+
| empty =>
236+
apply meromorphicTrailingCoeffAt_const
237+
| insert σ s₁ hσ hind =>
238+
rw [Finset.prod_insert hσ, Finset.prod_insert hσ, (h σ).meromorphicTrailingCoeffAt_mul
239+
(MeromorphicAt.prod h), hind]
240+
199241
/--
200242
The trailing coefficient of the inverse function is the inverse of the trailing coefficient.
201243
-/

0 commit comments

Comments
 (0)