Skip to content

Commit 9dd930f

Browse files
urkudb-mehta
authored andcommitted
feat(Complex/RiemannMapping): first step of the proof (leanprover-community#39603)
1 parent 715f3e1 commit 9dd930f

2 files changed

Lines changed: 145 additions & 0 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,6 +1860,7 @@ public import Mathlib.Analysis.Complex.Positivity
18601860
public import Mathlib.Analysis.Complex.ReImTopology
18611861
public import Mathlib.Analysis.Complex.RealDeriv
18621862
public import Mathlib.Analysis.Complex.RemovableSingularity
1863+
public import Mathlib.Analysis.Complex.RiemannMapping
18631864
public import Mathlib.Analysis.Complex.Schwarz
18641865
public import Mathlib.Analysis.Complex.Spectrum
18651866
public import Mathlib.Analysis.Complex.SqrtDeriv
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/-
2+
Copyright (c) 2026 Yury Kudryashov. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Yury Kudryashov
5+
-/
6+
module
7+
8+
public import Mathlib.AlgebraicTopology.FundamentalGroupoid.SimplyConnected
9+
public import Mathlib.Analysis.Calculus.Deriv.Basic
10+
public import Mathlib.Analysis.Complex.Basic
11+
12+
import Mathlib.Analysis.Calculus.Deriv.Inv
13+
import Mathlib.Analysis.Calculus.Deriv.Pow
14+
import Mathlib.Analysis.Calculus.Deriv.Shift
15+
import Mathlib.Analysis.Calculus.InverseFunctionTheorem.Deriv
16+
import Mathlib.Analysis.Complex.BranchLogRoot
17+
18+
/-!
19+
# Riemann mapping theorem
20+
21+
This file contains partial results towards Riemann Mapping Theorem.
22+
A complete proof is available at https://github.com/leanprover-community/mathlib4/pull/33505,
23+
though it may fail to compile with the latest Mathlib.
24+
25+
It is being brought up to Mathlib code standards and merged in a series of smaller PRs.
26+
For now, all lemmas in this file are strictly weaker than the final theorem,
27+
so they're private.
28+
-/
29+
30+
set_option linter.privateModule false -- TODO: remove when we add the main theorem
31+
32+
open Function Filter Metric Set
33+
open scoped Pointwise Topology
34+
35+
namespace Complex
36+
37+
/-- Proof of the Riemann Mapping Theorem, step 1.
38+
39+
If `U` is an open simply connected subset of `ℂ` that is not the whole `ℂ`,
40+
then there exists a function `f : ℂ → ℂ` such that
41+
42+
- `f` is injective;
43+
- the image `f '' U` isn't dense in `ℂ`;
44+
- `f` is complex differentiable on `U` with nonzero derivative.
45+
46+
E.g., one can choose `a ∉ U`, then take `f z` to be the square root of `z - a`.
47+
-/
48+
theorem exists_injective_not_dense_image_deriv_ne_zero {U : Set ℂ} (hUo : IsOpen U)
49+
(hUc : IsSimplyConnected U) (hU : U ≠ univ) :
50+
∃ f : ℂ → ℂ, Injective f ∧ ¬Dense (f '' U) ∧ ∀ z ∈ U, deriv f z ≠ 0 := by
51+
-- WLOG, `0 ∉ U`, otherwise we choose `a ∉ U` and replace `U` with `-a +ᵥ U`
52+
wlog hU₀ : 0 ∉ U
53+
· rw [ne_univ_iff_exists_notMem] at hU
54+
rcases hU with ⟨a, ha⟩
55+
specialize this (hUo.vadd (-a)) (by simpa) (by simp [hU])
56+
(by simpa [mem_vadd_set_iff_neg_vadd_mem])
57+
rcases this with ⟨f, hf_inj, hf_dense, hdf⟩
58+
refine ⟨f ∘ (-a + ·), hf_inj.comp (add_right_injective (-a)), ?_, fun z hz ↦ ?_⟩
59+
· simpa only [← image_vadd, Set.image_image] using hf_dense
60+
· simpa [Function.comp_def, deriv_comp_const_add] using hdf (-a + z) (mapsTo_image _ _ hz)
61+
-- Choose a continuous branch of `√z` on `U`.
62+
-- This is the function we're looking for.
63+
rcases exists_continuousOn_pow_eq hUc hUo continuousOn_id (by rwa [image_id]) two_ne_zero
64+
with ⟨f, hfc, hf_inv⟩
65+
replace hf_inv : LeftInverse (· ^ 2) f := hf_inv
66+
-- Then `0 ∉ f '' U`
67+
have hf₀ : ∀ z ∈ U, f z ≠ 0 := by
68+
intro z hz hfz
69+
simpa [hfz, (ne_of_mem_of_not_mem hz hU₀).symm] using hf_inv z
70+
-- Note that `f` is strictly differentiable at every point of `U`
71+
-- with derivative `1 / (2 * f z)`.
72+
have hdf : ∀ z ∈ U, HasStrictDerivAt f (2 * f z)⁻¹ z := by
73+
intro z hz
74+
apply HasStrictDerivAt.of_local_left_inverse
75+
· exact hfc.continuousAt <| hUo.mem_nhds hz
76+
· simpa using hasStrictDerivAt_pow 2 (f z)
77+
· simpa using hf₀ z hz
78+
· exact .of_forall hf_inv
79+
-- `f` has a left inverse, so it's injective. Let's show that `f '' U` isn't dense in `ℂ`.
80+
refine ⟨f, hf_inv.injective, ?_, fun z hz ↦ ?_⟩
81+
· -- Take a point `x ∈ U`.
82+
simp only [Dense, not_forall, mem_closure_iff_frequently, not_frequently]
83+
rcases hUc.nonempty with ⟨x, hx⟩
84+
-- Show that `-f x` has a neighborhood disjoint with `f '' U`.
85+
use -f x
86+
-- Since `f` is strictly differentiable at `x` with nonzero derivative,
87+
-- `f '' U` is a neighborhood of `f x`.
88+
have : f '' U ∈ 𝓝 (f x) := by
89+
rw [← (hdf x hx).map_nhds_eq (by simpa using hf₀ x hx)]
90+
exact Filter.image_mem_map <| hUo.mem_nhds hx
91+
-- Then `-f '' U` is a neighborhood of `-f x`.
92+
rw [nhds_neg, eventually_neg]
93+
-- This neighborhood has to be disjoint with `f '' U`,
94+
-- because `f a = - f b` implies `a = (f a) ^ 2 = (- f b) ^ 2 = b`, hence `f a = f b = 0`,
95+
-- which is impossible.
96+
filter_upwards [this]
97+
rintro _ ⟨a, ha, rfl⟩ ⟨b, hb, hab⟩
98+
obtain rfl : a = b := by
99+
rw [← hf_inv b, hab]
100+
simp [hf_inv a]
101+
refine hf₀ a ha ?_
102+
linear_combination hab / 2
103+
· simpa [(hdf z hz).hasDerivAt.deriv] using hf₀ z hz
104+
105+
/-- Proof of the Riemann Mapping Theorem, step 2.
106+
107+
If `U` is an open simply connected subset of `ℂ` which is not the whole field,
108+
then there exists a map `f : ℂ → ℂ` such that
109+
110+
- `f` maps `U` to the unit disk;
111+
- `f` is injective on `U`;
112+
- `f` is differentiable on `U` with nonzero derivative.
113+
114+
Once the proof of the Riemann Mapping Theorem gets merged into Mathlib,
115+
this lemma will be made private.
116+
-/
117+
lemma exists_mapsTo_unitBall_injOn_deriv_ne_zero {U : Set ℂ} (hUo : IsOpen U)
118+
(hUc : IsSimplyConnected U) (hU : U ≠ univ) :
119+
∃ f : ℂ → ℂ, MapsTo f U (ball 0 1) ∧ InjOn f U ∧ ∀ z ∈ U, deriv f z ≠ 0 := by
120+
-- Take a continuous branch of the square root on `U`.
121+
-- It is injective, differentiable function on `U`, and `f '' U` isn't dense in `ℂ`.
122+
rcases exists_injective_not_dense_image_deriv_ne_zero hUo hUc hU with ⟨f, hf_inj, hfd, hdf⟩
123+
-- Choose a closed ball `Metric.closedBall x ε`, `ε > 0`, that is disjoint with `f '' U`.
124+
obtain ⟨x, ε, hε₀, hε⟩ : ∃ (x : ℂ) (ε : ℝ), 0 < ε ∧ ∀ a ∈ U, ε < dist (f a) x := by
125+
simpa [Dense, mem_closure_iff_nhds_basis Metric.nhds_basis_closedBall] using hfd
126+
have hfx : ∀ z ∈ U, f z ≠ x := fun z hz ↦ by simpa using hε₀.trans (hε z hz)
127+
-- Then `z ↦ ε / (f z - x)` satisfies all the assertions.
128+
use fun z ↦ ε / (f z - x)
129+
refine ⟨?mapsTo, ?injOn, ?deriv⟩
130+
case mapsTo =>
131+
intro z hz
132+
rw [mem_ball_zero_iff, norm_div, norm_real, Real.norm_of_nonneg hε₀.le, div_lt_one₀]
133+
· simpa [dist_eq_norm] using hε z hz
134+
· simpa [sub_eq_zero] using hfx z hz
135+
case injOn =>
136+
intro z hz w hw heq
137+
simpa [div_eq_mul_inv, hε₀.ne', hf_inj.eq_iff] using heq
138+
case deriv =>
139+
intro z hz
140+
have hdz : DifferentiableAt ℂ f z := differentiableAt_of_deriv_ne_zero (hdf z hz)
141+
rw [(hasDerivAt_const _ _).fun_div (hdz.hasDerivAt.sub_const _) _ |>.deriv] <;>
142+
simp [*, ne_of_gt, sub_eq_zero]
143+
144+
end Complex

0 commit comments

Comments
 (0)