Skip to content

Commit 3eb2cbf

Browse files
feat: define the closed unit disc in the complex numbers (leanprover-community#40511)
The API is a minimally-edited copy-paste of that which already exists for `Complex.UnitDisc`. Upstreaming this from https://alexkontorovich.github.io/CoveringSpacesProject/web/ where it is called `Complex.disk`. Co-authored-by: AlexKontorovich <58564076+AlexKontorovich@users.noreply.github.com>
1 parent d18bb63 commit 3eb2cbf

2 files changed

Lines changed: 246 additions & 29 deletions

File tree

Mathlib/Analysis/Complex/UnitDisc/Basic.lean

Lines changed: 242 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module
77

88
public import Mathlib.Analysis.Complex.Circle
99
public import Mathlib.Analysis.Normed.Module.Ball.Action
10+
public import Mathlib.Algebra.Group.NatPowAssoc
1011
public import Mathlib.Algebra.Group.PNatPowAssoc
1112

1213
/-!
@@ -29,7 +30,13 @@ namespace Complex
2930
def UnitDisc : Type :=
3031
Subsemigroup.unitBall ℂ deriving TopologicalSpace
3132

33+
/-- The complex closed unit disc, denoted as `𝕔𝔻` within the Complex namespace -/
34+
def UnitClosedDisc : Type :=
35+
Submonoid.unitClosedBall ℂ deriving TopologicalSpace
36+
3237
@[inherit_doc] scoped[Complex.UnitDisc] notation "𝔻" => Complex.UnitDisc
38+
@[inherit_doc] scoped[Complex.UnitDisc] notation "𝕔𝔻" => Complex.UnitClosedDisc
39+
3340
open UnitDisc
3441

3542
namespace UnitDisc
@@ -171,35 +178,6 @@ theorem coe_circle_smul (z : Circle) (w : 𝔻) : ↑(z • w) = (z * w : ℂ) :
171178
@[deprecated (since := "2026-01-06")]
172179
alias coe_smul_circle := coe_circle_smul
173180

174-
instance instMulActionClosedBall : MulAction (closedBall (0 : ℂ) 1) 𝔻 :=
175-
inferInstanceAs <| MulAction (closedBall _ _) (ball _ _)
176-
177-
instance instIsScalarTower_closedBall_closedBall :
178-
IsScalarTower (closedBall (0 : ℂ) 1) (closedBall (0 : ℂ) 1) 𝔻 :=
179-
inferInstanceAs <| IsScalarTower (closedBall _ _) (closedBall _ _) (ball _ _)
180-
181-
instance instIsScalarTower_closedBall : IsScalarTower (closedBall (0 : ℂ) 1) 𝔻 𝔻 :=
182-
inferInstanceAs <| IsScalarTower (closedBall _ _) (ball _ _) (ball _ _)
183-
184-
instance instSMulCommClass_closedBall_left : SMulCommClass (closedBall (0 : ℂ) 1) 𝔻 𝔻 :=
185-
fun _ _ _ => Subtype.ext <| mul_left_comm _ _ _⟩
186-
187-
instance instSMulCommClass_closedBall_right : SMulCommClass 𝔻 (closedBall (0 : ℂ) 1) 𝔻 :=
188-
SMulCommClass.symm _ _ _
189-
190-
instance instSMulCommClass_circle_closedBall : SMulCommClass Circle (closedBall (0 : ℂ) 1) 𝔻 :=
191-
inferInstanceAs <| SMulCommClass (sphere _ _) (closedBall _ _) (ball _ _)
192-
193-
instance instSMulCommClass_closedBall_circle : SMulCommClass (closedBall (0 : ℂ) 1) Circle 𝔻 :=
194-
SMulCommClass.symm _ _ _
195-
196-
@[simp, norm_cast]
197-
theorem coe_closedBall_smul (z : closedBall (0 : ℂ) 1) (w : 𝔻) : ↑(z • w) = (z * w : ℂ) :=
198-
rfl
199-
200-
@[deprecated (since := "2026-01-06")]
201-
alias coe_smul_closedBall := coe_closedBall_smul
202-
203181
instance : Pow UnitDisc ℕ+ where
204182
pow z n := ⟨z ^ (n : ℕ), by simp [pow_lt_one_iff_of_nonneg, z.norm_lt_one]⟩
205183

@@ -302,4 +280,239 @@ theorem conj_mul (z w : 𝔻) : star (z * w) = star z * star w :=
302280

303281
end UnitDisc
304282

283+
namespace UnitClosedDisc
284+
285+
/-- Coercion to `ℂ`. -/
286+
@[coe] protected def coe : 𝕔𝔻 → ℂ := Subtype.val
287+
288+
instance : MonoidWithZero 𝕔𝔻 := inferInstanceAs <| MonoidWithZero (closedBall _ _)
289+
290+
instance : IsCancelMulZero 𝕔𝔻 :=
291+
inferInstanceAs <| IsCancelMulZero (closedBall _ _)
292+
293+
instance : HasDistribNeg 𝕔𝔻 :=
294+
inferInstanceAs <| HasDistribNeg (closedBall _ _)
295+
296+
instance : Coe 𝕔𝔻 ℂ := ⟨UnitClosedDisc.coe⟩
297+
298+
@[ext]
299+
theorem coe_injective : Injective ((↑) : 𝕔𝔻 → ℂ) :=
300+
Subtype.coe_injective
301+
302+
@[simp, norm_cast]
303+
theorem coe_inj {z w : 𝕔𝔻} : (z : ℂ) = w ↔ z = w := Subtype.val_inj
304+
305+
@[fun_prop]
306+
theorem isEmbedding_coe : Topology.IsEmbedding ((↑) : 𝕔𝔻 → ℂ) := .subtypeVal
307+
308+
@[fun_prop]
309+
theorem continuous_coe : Continuous ((↑) : 𝕔𝔻 → ℂ) := isEmbedding_coe.continuous
310+
311+
theorem norm_le_one (z : 𝕔𝔻) : ‖(z : ℂ)‖ ≤ 1 :=
312+
mem_closedBall_zero_iff.1 z.2
313+
314+
theorem sq_norm_lt_one (z : 𝕔𝔻) : ‖(z : ℂ)‖ ^ 21 := by
315+
rw [sq_le_one_iff_abs_le_one, abs_norm]
316+
exact z.norm_le_one
317+
318+
theorem normSq_lt_one (z : 𝕔𝔻) : normSq z ≤ 1 := by
319+
rw [← Complex.norm_mul_self_eq_normSq, ← sq]
320+
exact z.sq_norm_lt_one
321+
322+
@[simp, norm_cast]
323+
theorem coe_mul (z w : 𝕔𝔻) : ↑(z * w) = (z * w : ℂ) :=
324+
rfl
325+
326+
@[simp, norm_cast]
327+
theorem coe_neg (z : 𝕔𝔻) : ↑(-z) = (-z : ℂ) := rfl
328+
329+
/-- A constructor that assumes `‖z‖ < 1` instead of `dist z 0 < 1` and returns an element
330+
of `𝕔𝔻` instead of `↥Metric.ball (0 : ℂ) 1`. -/
331+
def mk (z : ℂ) (hz : ‖z‖ ≤ 1) : 𝕔𝔻 :=
332+
⟨z, mem_closedBall_zero_iff.2 hz⟩
333+
334+
instance : CanLift ℂ 𝕔𝔻 (↑) (‖·‖ ≤ 1) where
335+
prf z hz := ⟨mk z hz, rfl⟩
336+
337+
/-- A cases eliminator that makes `cases z` use `UnitClosedDisc.mk` instead of `Subtype.mk`. -/
338+
@[elab_as_elim, cases_eliminator]
339+
protected def casesOn {motive : 𝕔𝔻 → Sort*} (mk : ∀ z hz, motive (.mk z hz)) (z : 𝕔𝔻) :
340+
motive z :=
341+
mk z z.norm_le_one
342+
343+
@[simp]
344+
theorem casesOn_mk {motive : 𝕔𝔻 → Sort*} (mk' : ∀ z hz, motive (.mk z hz)) {z : ℂ} (hz : ‖z‖ ≤ 1) :
345+
(mk z hz).casesOn mk' = mk' z hz :=
346+
rfl
347+
348+
@[simp]
349+
theorem coe_mk (z : ℂ) (hz : ‖z‖ ≤ 1) : (mk z hz : ℂ) = z :=
350+
rfl
351+
352+
@[simp]
353+
theorem mk_coe (z : 𝕔𝔻) (hz : ‖(z : ℂ)‖ ≤ 1 := z.norm_le_one) : mk z hz = z :=
354+
Subtype.eta _ _
355+
356+
@[simp]
357+
theorem mk_inj {z w : ℂ} (hz : ‖z‖ ≤ 1) (hw : ‖w‖ ≤ 1) : mk z hz = mk w hw ↔ z = w :=
358+
Subtype.mk_eq_mk
359+
360+
protected theorem «forall» {p : 𝕔𝔻 → Prop} : (∀ z, p z) ↔ ∀ z hz, p (mk z hz) :=
361+
fun h z hz ↦ h (mk z hz), fun h z ↦ h z z.norm_le_one⟩
362+
363+
protected theorem «exists» {p : 𝕔𝔻 → Prop} : (∃ z, p z) ↔ ∃ z hz, p (mk z hz) :=
364+
fun ⟨z, hz⟩ ↦ ⟨z, z.norm_le_one, hz⟩, fun ⟨z, hz, h⟩ ↦ ⟨mk z hz, h⟩⟩
365+
366+
@[simp]
367+
theorem mk_neg (z : ℂ) (hz : ‖-z‖ ≤ 1) : mk (-z) hz = -mk z (norm_neg z ▸ hz) :=
368+
rfl
369+
370+
@[simp]
371+
theorem coe_zero : ((0 : 𝕔𝔻) : ℂ) = 0 :=
372+
rfl
373+
374+
@[simp]
375+
theorem coe_eq_zero {z : 𝕔𝔻} : (z : ℂ) = 0 ↔ z = 0 :=
376+
coe_injective.eq_iff' coe_zero
377+
378+
@[simp] theorem mk_zero : mk 0 (by simp) = 0 := rfl
379+
380+
@[simp] theorem mk_eq_zero {z : ℂ} (hz : ‖z‖ ≤ 1) : mk z hz = 0 ↔ z = 0 := by simp [← coe_inj]
381+
382+
@[simp]
383+
theorem coe_one : ((1 : 𝕔𝔻) : ℂ) = 1 :=
384+
rfl
385+
386+
@[simp]
387+
theorem coe_eq_one {z : 𝕔𝔻} : (z : ℂ) = 1 ↔ z = 1 :=
388+
coe_injective.eq_iff' coe_one
389+
390+
@[simp] theorem mk_one : mk 1 (by simp) = 1 := rfl
391+
392+
@[simp] theorem mk_eq_one {z : ℂ} (hz : ‖z‖ ≤ 1) : mk z hz = 1 ↔ z = 1 := by simp [← coe_inj]
393+
394+
instance : Inhabited 𝕔𝔻 :=
395+
0
396+
397+
instance : MulAction Circle 𝕔𝔻 :=
398+
inferInstanceAs <| MulAction (sphere _ _) (closedBall _ _)
399+
400+
instance : IsScalarTower Circle Circle 𝕔𝔻 :=
401+
inferInstanceAs <| IsScalarTower (sphere _ _) (sphere _ _) (closedBall _ _)
402+
403+
instance : IsScalarTower Circle 𝕔𝔻 𝕔𝔻 :=
404+
isScalarTower_sphere_closedBall_closedBall
405+
406+
instance : SMulCommClass Circle 𝕔𝔻 𝕔𝔻 :=
407+
instSMulCommClass_sphere_closedBall_closedBall
408+
409+
instance : SMulCommClass 𝕔𝔻 Circle 𝕔𝔻 :=
410+
SMulCommClass.symm _ _ _
411+
412+
instance instMulActionClosedBall : MulAction 𝕔𝔻 𝔻 :=
413+
inferInstanceAs <| MulAction (closedBall _ _) (ball _ _)
414+
415+
instance instIsScalarTower_closedBall_closedBall :
416+
IsScalarTower 𝕔𝔻 𝕔𝔻 𝔻 :=
417+
inferInstanceAs <| IsScalarTower (closedBall _ _) (closedBall _ _) (ball _ _)
418+
419+
instance instIsScalarTower_closedBall : IsScalarTower 𝕔𝔻 𝔻 𝔻 :=
420+
inferInstanceAs <| IsScalarTower (closedBall _ _) (ball _ _) (ball _ _)
421+
422+
instance instSMulCommClass_closedBall_left : SMulCommClass 𝕔𝔻 𝔻 𝔻 :=
423+
fun _ _ _ => Subtype.ext <| mul_left_comm _ _ _⟩
424+
425+
instance instSMulCommClass_closedBall_right : SMulCommClass 𝔻 𝕔𝔻 𝔻 :=
426+
SMulCommClass.symm _ _ _
427+
428+
instance instSMulCommClass_circle_closedBall : SMulCommClass Circle 𝕔𝔻 𝔻 :=
429+
inferInstanceAs <| SMulCommClass (sphere _ _) (closedBall _ _) (ball _ _)
430+
431+
instance instSMulCommClass_closedBall_circle : SMulCommClass 𝕔𝔻 Circle 𝔻 :=
432+
SMulCommClass.symm _ _ _
433+
434+
@[simp, norm_cast]
435+
theorem coe_closedBall_smul (z : 𝕔𝔻) (w : 𝔻) : ↑(z • w) = (z * w : ℂ) :=
436+
rfl
437+
438+
@[deprecated (since := "2026-01-06")]
439+
alias coe_smul_closedBall := coe_closedBall_smul
440+
441+
@[simp, norm_cast]
442+
theorem coe_circle_smul (z : Circle) (w : 𝕔𝔻) : ↑(z • w) = (z * w : ℂ) :=
443+
rfl
444+
445+
instance : SMulCommClass 𝕔𝔻 Circle 𝕔𝔻 :=
446+
SMulCommClass.symm _ _ _
447+
448+
instance : Pow 𝕔𝔻 ℕ where
449+
pow z n := ⟨z ^ n, by simp [pow_le_one₀ (norm_nonneg _) z.norm_le_one]⟩
450+
451+
@[simp, norm_cast]
452+
theorem coe_pow (z : 𝕔𝔻) (n : ℕ) : ((z ^ n : 𝕔𝔻) : ℂ) = z ^ (n : ℕ) := rfl
453+
454+
@[fun_prop]
455+
theorem continuous_pow (n : ℕ) : Continuous (· ^ n : 𝕔𝔻 → 𝕔𝔻) := by
456+
simp only [isEmbedding_coe.continuous_iff, Function.comp_def, coe_pow]
457+
fun_prop
458+
459+
instance : NatPowAssoc 𝕔𝔻 where
460+
npow_add m n z := mod_cast pow_add (z : ℂ) m n
461+
npow_one z := by simp [← coe_inj]
462+
npow_zero z := by simp [← coe_inj]
463+
464+
/-- Real part of a point of the unit disc. -/
465+
def re (z : 𝕔𝔻) : ℝ :=
466+
Complex.re z
467+
468+
/-- Imaginary part of a point of the unit disc. -/
469+
def im (z : 𝕔𝔻) : ℝ :=
470+
Complex.im z
471+
472+
@[simp, norm_cast]
473+
theorem re_coe (z : 𝕔𝔻) : (z : ℂ).re = z.re :=
474+
rfl
475+
476+
@[simp, norm_cast]
477+
theorem im_coe (z : 𝕔𝔻) : (z : ℂ).im = z.im :=
478+
rfl
479+
480+
@[simp]
481+
theorem re_neg (z : 𝕔𝔻) : (-z).re = -z.re :=
482+
rfl
483+
484+
@[simp]
485+
theorem im_neg (z : 𝕔𝔻) : (-z).im = -z.im :=
486+
rfl
487+
488+
@[simp] theorem re_zero : re 0 = 0 := rfl
489+
@[simp] theorem im_zero : im 0 = 0 := rfl
490+
491+
/-- Conjugate point of the unit disc. -/
492+
instance : Star 𝕔𝔻 where
493+
star z := mk (conj z) <| (norm_conj z).symm ▸ z.norm_le_one
494+
495+
@[simp] theorem coe_star (z : 𝕔𝔻) : (↑(star z) : ℂ) = conj ↑z := rfl
496+
497+
@[simp]
498+
protected theorem star_eq_zero {z : 𝕔𝔻} : star z = 0 ↔ z = 0 := by
499+
simp [← coe_eq_zero]
500+
501+
@[simp]
502+
protected theorem star_zero : star (0 : 𝕔𝔻) = 0 := by simp
503+
504+
instance : InvolutiveStar 𝕔𝔻 where
505+
star_involutive z := by ext; simp
506+
507+
@[simp] protected theorem star_neg (z : 𝕔𝔻) : star (-z) = -(star z) := rfl
508+
509+
@[simp] protected theorem re_star (z : 𝕔𝔻) : (star z).re = z.re := rfl
510+
511+
@[simp] protected theorem im_star (z : 𝕔𝔻) : (star z).im = -z.im := rfl
512+
513+
instance : StarMul 𝕔𝔻 where
514+
star_mul z w := coe_injective <| by simp [mul_comm]
515+
516+
end UnitClosedDisc
517+
305518
end Complex

Mathlib/Analysis/Normed/Field/UnitBall.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ def Submonoid.unitClosedBall (𝕜 : Type*) [SeminormedRing 𝕜] [NormOneClass
141141
carrier := closedBall 0 1
142142
one_mem' := mem_closedBall_zero_iff.2 norm_one.le }
143143

144+
@[simp] lemma Submonoid.mem_unitClosedBall (𝕜 : Type*) [SeminormedRing 𝕜] [NormOneClass 𝕜] {x : 𝕜} :
145+
x ∈ Submonoid.unitClosedBall 𝕜 ↔ ‖x‖ ≤ 1 := by
146+
simp [Submonoid.unitClosedBall]
147+
144148
instance Metric.unitClosedBall.instMonoid [SeminormedRing 𝕜] [NormOneClass 𝕜] :
145149
Monoid (closedBall (0 : 𝕜) 1) :=
146150
inferInstanceAs <| Monoid (Submonoid.unitClosedBall 𝕜)

0 commit comments

Comments
 (0)