Skip to content

Commit 38a7a53

Browse files
committed
feat(Analysis/SpecialFunctions/Complex/Circle): expMapCircle as a PartialHomeomorph and prove IsLocalHomeomorph (#11334)
This PR proves `IsLocalHomeomorph expMapCircle` (eventually this should be upgraded to `IsCoveringMap`, but that's a good deal harder and is probably best done via general theory such as in #7596).
1 parent d4be533 commit 38a7a53

File tree

2 files changed

+89
-8
lines changed

2 files changed

+89
-8
lines changed

Mathlib/Analysis/SpecialFunctions/Complex/Circle.lean

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,14 @@ noncomputable def toCircle : AddCircle T → circle :=
170170
(@scaled_exp_map_periodic T).lift
171171
#align add_circle.to_circle AddCircle.toCircle
172172

173+
theorem toCircle_apply_mk (x : ℝ) : @toCircle T x = expMapCircle (2 * π / T * x) :=
174+
rfl
175+
173176
theorem toCircle_add (x : AddCircle T) (y : AddCircle T) :
174177
@toCircle T (x + y) = toCircle x * toCircle y := by
175178
induction x using QuotientAddGroup.induction_on'
176179
induction y using QuotientAddGroup.induction_on'
177-
rw [← QuotientAddGroup.mk_add]
178-
simp_rw [toCircle, Function.Periodic.lift_coe, mul_add, expMapCircle_add]
180+
simp_rw [← coe_add, toCircle_apply_mk, mul_add, expMapCircle_add]
179181
#align add_circle.to_circle_add AddCircle.toCircle_add
180182

181183
theorem continuous_toCircle : Continuous (@toCircle T) :=
@@ -186,7 +188,7 @@ theorem injective_toCircle (hT : T ≠ 0) : Function.Injective (@toCircle T) :=
186188
intro a b h
187189
induction a using QuotientAddGroup.induction_on'
188190
induction b using QuotientAddGroup.induction_on'
189-
simp_rw [toCircle, Function.Periodic.lift_coe] at h
191+
simp_rw [toCircle_apply_mk] at h
190192
obtain ⟨m, hm⟩ := expMapCircle_eq_expMapCircle.mp h.symm
191193
rw [QuotientAddGroup.eq]; simp_rw [AddSubgroup.mem_zmultiples_iff, zsmul_eq_mul]
192194
use m
@@ -195,4 +197,38 @@ theorem injective_toCircle (hT : T ≠ 0) : Function.Injective (@toCircle T) :=
195197
linarith
196198
#align add_circle.injective_to_circle AddCircle.injective_toCircle
197199

200+
/-- The homeomorphism between `AddCircle (2 * π)` and `circle`. -/
201+
@[simps] noncomputable def homeomorphCircle' : AddCircle (2 * π) ≃ₜ circle where
202+
toFun := Angle.expMapCircle
203+
invFun := fun x ↦ arg x
204+
left_inv := Angle.arg_expMapCircle
205+
right_inv := expMapCircle_arg
206+
continuous_toFun := continuous_coinduced_dom.mpr expMapCircle.continuous
207+
continuous_invFun := by
208+
rw [continuous_iff_continuousAt]
209+
intro x
210+
apply (continuousAt_arg_coe_angle (ne_zero_of_mem_circle x)).comp
211+
continuousAt_subtype_val
212+
213+
theorem homeomorphCircle'_apply_mk (x : ℝ) : homeomorphCircle' x = expMapCircle x :=
214+
rfl
215+
216+
/-- The homeomorphism between `AddCircle` and `circle`. -/
217+
noncomputable def homeomorphCircle (hT : T ≠ 0) : AddCircle T ≃ₜ circle :=
218+
(homeomorphAddCircle T (2 * π) hT (by positivity)).trans homeomorphCircle'
219+
220+
theorem homeomorphCircle_apply (hT : T ≠ 0) (x : AddCircle T) :
221+
homeomorphCircle hT x = toCircle x := by
222+
induction' x using QuotientAddGroup.induction_on' with x
223+
rw [homeomorphCircle, Homeomorph.trans_apply,
224+
homeomorphAddCircle_apply_mk, homeomorphCircle'_apply_mk, toCircle_apply_mk]
225+
ring_nf
226+
198227
end AddCircle
228+
229+
open AddCircle
230+
231+
-- todo: upgrade this to `IsCoveringMap expMapCircle`.
232+
lemma isLocalHomeomorph_expMapCircle : IsLocalHomeomorph expMapCircle := by
233+
have : Fact (0 < 2 * π) := ⟨by positivity⟩
234+
exact homeomorphCircle'.isLocalHomeomorph.comp (isLocalHomeomorph_coe (2 * π))

Mathlib/Topology/Instances/AddCircle.lean

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ Copyright (c) 2022 Oliver Nash. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Oliver Nash
55
-/
6-
import Mathlib.Data.Nat.Totient
6+
import Mathlib.Algebra.Order.ToIntervalMod
77
import Mathlib.Algebra.Ring.AddAut
8+
import Mathlib.Data.Nat.Totient
89
import Mathlib.GroupTheory.Divisible
9-
import Mathlib.GroupTheory.OrderOfElement
10-
import Mathlib.Algebra.Order.Floor
11-
import Mathlib.Algebra.Order.ToIntervalMod
12-
import Mathlib.Topology.Instances.Real
1310
import Mathlib.Topology.Connected.PathConnected
11+
import Mathlib.Topology.IsLocalHomeomorph
1412

1513
#align_import topology.instances.add_circle from "leanprover-community/mathlib"@"213b0cff7bc5ab6696ee07cceec80829ce42efec"
1614

@@ -278,6 +276,37 @@ theorem continuousAt_equivIoc : ContinuousAt (equivIoc p a) x := by
278276
exact (continuousAt_toIocMod hp.out a hx).codRestrict _
279277
#align add_circle.continuous_at_equiv_Ioc AddCircle.continuousAt_equivIoc
280278

279+
/-- The quotient map `𝕜 → AddCircle p` as a partial homeomorphism. -/
280+
@[simps] def partialHomeomorphCoe [DiscreteTopology (zmultiples p)] :
281+
PartialHomeomorph 𝕜 (AddCircle p) where
282+
toFun := (↑)
283+
invFun := fun x ↦ equivIco p a x
284+
source := Ioo a (a + p)
285+
target := {↑a}ᶜ
286+
map_source' := by
287+
intro x hx hx'
288+
exact hx.1.ne' ((coe_eq_coe_iff_of_mem_Ico (Ioo_subset_Ico_self hx)
289+
(left_mem_Ico.mpr (lt_add_of_pos_right a hp.out))).mp hx')
290+
map_target' := by
291+
intro x hx
292+
exact (eq_left_or_mem_Ioo_of_mem_Ico (equivIco p a x).2).resolve_left
293+
(hx ∘ ((equivIco p a).symm_apply_apply x).symm.trans ∘ congrArg _)
294+
left_inv' :=
295+
fun x hx ↦ congrArg _ ((equivIco p a).apply_symm_apply ⟨x, Ioo_subset_Ico_self hx⟩)
296+
right_inv' := fun x _ ↦ (equivIco p a).symm_apply_apply x
297+
open_source := isOpen_Ioo
298+
open_target := isOpen_compl_singleton
299+
continuousOn_toFun := (AddCircle.continuous_mk' p).continuousOn
300+
continuousOn_invFun := by
301+
exact ContinuousAt.continuousOn
302+
(fun _ ↦ continuousAt_subtype_val.comp ∘ continuousAt_equivIco p a)
303+
304+
lemma isLocalHomeomorph_coe [DiscreteTopology (zmultiples p)] [DenselyOrdered 𝕜] :
305+
IsLocalHomeomorph ((↑) : 𝕜 → AddCircle p) := by
306+
intro a
307+
obtain ⟨b, hb1, hb2⟩ := exists_between (sub_lt_self a hp.out)
308+
exact ⟨partialHomeomorphCoe p b, ⟨hb2, lt_add_of_sub_right_lt hb1⟩, rfl⟩
309+
281310
end Continuity
282311

283312
/-- The image of the closed-open interval `[a, a + p)` under the quotient map `𝕜 → AddCircle p` is
@@ -328,6 +357,22 @@ theorem equivAddCircle_symm_apply_mk (hp : p ≠ 0) (hq : q ≠ 0) (x : 𝕜) :
328357
rfl
329358
#align add_circle.equiv_add_circle_symm_apply_mk AddCircle.equivAddCircle_symm_apply_mk
330359

360+
/-- The rescaling homeomorphism between additive circles with different periods. -/
361+
def homeomorphAddCircle (hp : p ≠ 0) (hq : q ≠ 0) : AddCircle p ≃ₜ AddCircle q :=
362+
⟨equivAddCircle p q hp hq,
363+
(continuous_quotient_mk'.comp (continuous_mul_right (p⁻¹ * q))).quotient_lift _,
364+
(continuous_quotient_mk'.comp (continuous_mul_right (q⁻¹ * p))).quotient_lift _⟩
365+
366+
@[simp]
367+
theorem homeomorphAddCircle_apply_mk (hp : p ≠ 0) (hq : q ≠ 0) (x : 𝕜) :
368+
homeomorphAddCircle p q hp hq (x : 𝕜) = (x * (p⁻¹ * q) : 𝕜) :=
369+
rfl
370+
371+
@[simp]
372+
theorem homeomorphAddCircle_symm_apply_mk (hp : p ≠ 0) (hq : q ≠ 0) (x : 𝕜) :
373+
(homeomorphAddCircle p q hp hq).symm (x : 𝕜) = (x * (q⁻¹ * p) : 𝕜) :=
374+
rfl
375+
331376
variable [hp : Fact (0 < p)]
332377

333378
section FloorRing

0 commit comments

Comments
 (0)