|
| 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