Making multivalued functions single-valued
Every non-zero complex number has two square roots, and no continuous choice of one of them works on all of : follow once round the origin and it comes back as . The logarithm is worse, with infinitely many values. For a century these "multivalued functions" were handled by cutting the plane and keeping track of branches. In his 1851 dissertation Bernhard Riemann proposed a radical alternative: do not change the function, change its domain. Build a surface lying over the plane, with one sheet for each value, glued so that walking round a branch point carries you from one sheet to the next. On that surface the square root is an honest, single-valued holomorphic function.
These Riemann surfaces turned out to be the natural home of an astonishing amount of mathematics. Compact Riemann surfaces are the same thing as complex algebraic curves (solution sets of polynomial equations ); their topology is a single number, the genus; the integrals of algebraic functions — elliptic integrals, which compute the arc length of an ellipse or the period of a pendulum — are integrals of -forms over loops on them; and the same equations studied over the rational numbers are the elliptic curves of number theory.
This lesson builds on complex analysis, the fundamental group and covering spaces, and the classification of surfaces by their Euler characteristic. It uses the language of manifolds, with holomorphic charts in place of smooth ones.
Two sheets glued crosswise
Take two copies of the plane, cut each along the negative real axis, and glue the upper edge of the cut in sheet 1 to the lower edge of the cut in sheet 2, and vice versa. A path going once round starts on sheet 1, crosses the cut and continues on sheet 2, and only after a second turn returns to its starting point. On this two-sheeted surface (completed by one point over and one over ) the function "" takes the value on sheet 1 and on sheet 2, and is continuous. In fact the surface is just another copy of the plane, with coordinate , lying over the -plane by : the "two sheets" are the two preimages of each .
The same recipe for needs two cuts — say from to and from to — because a loop round one of the branch points swaps the sheets while a loop round two of them does not. Two cut spheres glued crosswise along two slits make a torus: the Riemann surface of has genus . Counting branch points to find the genus is the Riemann–Hurwitz formula.
Riemann surfaces and holomorphic maps
Definition— Riemann surface
A Riemann surface is a connected, Hausdorff, second countable space with an atlas of charts whose transition maps are holomorphic (a maximal such atlas is a complex structure). Equivalently, a connected complex manifold of complex dimension . (Second countability is in fact automatic, by Radó's theorem.)
Definition— holomorphic and meromorphic maps
A continuous map of Riemann surfaces is holomorphic if it is holomorphic in local coordinates. A meromorphic function on is a holomorphic map to the Riemann sphere not identically ; equivalently, a function holomorphic outside a discrete set of poles. The meromorphic functions form a field .
Definition— ramification, degree, genus
By the local normal form (Theorem 1), a non-constant holomorphic is near each given in suitable coordinates by with , the ramification index (or multiplicity) of at . Points with are ramification points, and their images branch points. For compact the degree of is (independent of , by Theorem 2). The genus of a compact Riemann surface is the genus of the underlying closed orientable surface, so .
Holomorphic maps preserve orientation (the Jacobian determinant of is ), so every Riemann surface is orientable: the Klein bottle and the projective plane carry no complex structure. Conversely, every orientable surface carries one (for example from a Riemannian metric and isothermal coordinates).
Examples
Example— The plane, the sphere and their quotients
- , the unit disc , and every connected open subset of .
- The Riemann sphere with the two charts on and on ; the transition is holomorphic on . Rational functions are exactly the meromorphic functions on , and a rational function (in lowest terms) has degree .
- Complex tori. Let with linearly independent over . The quotient is a compact Riemann surface of genus : charts are local inverses of the projection on small discs, and transition maps are translations . Holomorphic functions on are -periodic entire functions — hence constant (Liouville; formalised below) — while meromorphic functions on are the elliptic functions, such as the Weierstrass function .
- Quotients of the disc. If is a group of Möbius transformations acting freely and properly discontinuously on or on the upper half-plane , then is a Riemann surface. Modular curves are of this kind (after removing elliptic fixed points or treating them as orbifold points).
Example— Algebraic curves
Let be a polynomial and . At points where the implicit function theorem (holomorphic version) makes a local coordinate; where , is one. So if is smooth (no common zeros of , , ), it is a Riemann surface (if connected), and is a holomorphic map whose ramification points are where . Adding finitely many points at infinity (in , or by gluing in charts) gives a compact Riemann surface.
For with a squarefree polynomial of degree , the projection has degree , ramified exactly over the roots of — and over when is odd. With , , there are four branch points , and the compact curve is a torus (Riemann–Hurwitz, below).
Example— z² as a branched double cover
from to has degree . Every has two preimages ; over and there is one preimage, with . Near angles at the origin are doubled — the conformal map fails to be conformal exactly at its critical point — and the visualization below shows this. The inverse of this map is the Riemann surface of from the intuition section.
Local structure of holomorphic maps
Theorem— Theorem 1 (local normal form)
Let be a non-constant holomorphic map and . There is a unique integer and charts centred at and centred at in which is .
Proof
Choose any charts centred at and , so that becomes a holomorphic function near with . Since is connected and is not constant, is not identically (identity theorem), so with and holomorphic, . On a small disc takes values in a disc not containing , on which a holomorphic logarithm exists; so with holomorphic and . Then has , so by the inverse function theorem it is a new coordinate near , and in it . The integer is determined by : it is the number of preimages near of each point near (but not equal to) . ∎
∎
Consequences: a non-constant holomorphic map is open (since is), its fibres are discrete, and it is a local biholomorphism exactly where , i.e. where its derivative in charts is non-zero. Ramification points are isolated, so on a compact surface there are finitely many.
Theorem— Theorem 2 (maps of compact surfaces are branched coverings)
Let be a non-constant holomorphic map with compact. Then is surjective, is compact, every fibre is finite, and is the same for all . Away from the finitely many branch points, is a -sheeted covering map.
Proof
is open (open mapping) and compact, hence closed; is connected, so , which is compact. Fibres are discrete and closed in the compact , hence finite. Fix with and normal-form charts round each , on disjoint neighbourhoods . Shrink a neighbourhood of so that (possible: is compact and misses ). Then each has exactly preimages in , all with multiplicity , so . Thus the function is locally constant, hence constant on the connected . ∎
∎
Theorem— Corollary 3
On a compact Riemann surface: (a) every holomorphic function is constant; (b) a non-constant meromorphic function has as many zeros as poles, counted with multiplicity; (c) if there is a meromorphic function of degree , then .
Proof
(a) A holomorphic composed with is a holomorphic map to that misses ; by Theorem 2 it must be constant. (b) A meromorphic has . (c) A degree- map is a bijective holomorphic map, hence a biholomorphism (its inverse is holomorphic by the local normal form with ). ∎
∎
The Riemann–Hurwitz formula
Theorem— Theorem 4 (Riemann–Hurwitz)
Let be a non-constant holomorphic map of degree between compact Riemann surfaces of genera and . Then
Proof
The sum is finite (ramification points are isolated). Choose a triangulation of — with geodesic or smooth edges — whose vertices include all branch points, fine enough that each closed triangle lies in a disc over which is a trivial -sheeted covering away from its vertices. Its preimage is a triangulation of : each open face and open edge, avoiding branch points, has exactly preimages, so and . A vertex has preimages, by Theorem 2. Hence , and
Substituting gives the formula. ∎
∎
Example— Genera from branched covers
- on : at and , so . ✓
- Hyperelliptic curves , squarefree of degree : a double cover of with branch points, each with , where for even and for odd. Then , so : genus . For : , . In particular a double cover of the sphere has an even number of branch points.
- Fermat curves (compactified in ): has degree , total ramification over the points (where , ), and is unramified at the points at infinity. So and , in agreement with the genus formula for smooth plane curves of degree .
- Unramified covers of tori are tori: if and is unramified, then . And there is no non-constant holomorphic map from a torus to a surface of genus , or from to a torus: in both cases the right-hand side exceeds the left.
Complex tori: a one-parameter family
All complex tori are homeomorphic (to ) and even diffeomorphic. They are not all biholomorphic.
Theorem— Theorem 5 (classification of tori)
(biholomorphically) if and only if for some . Every lattice is homothetic to with , and , are homothetic exactly when for some .
Proof
If , then descends to a biholomorphism. Conversely, let be a biholomorphism; composing with a translation we may assume . Since is simply connected, lifts through the covering to a holomorphic with . For each , depends continuously on and is discrete, so it is a constant . Hence is -periodic and entire, so constant (Liouville), and . Applying the same to shows and .
For the second part: rotating and scaling, any lattice (ordered so that ) is homothetic to with . Two oriented bases of the same lattice differ by a matrix in , , which changes to . ∎
∎
So the isomorphism classes of tori correspond to points of , whose standard fundamental domain is ; the -invariant is a bijection. Tori form a family with one complex parameter: the square torus (, ) and the hexagonal torus (, ) are different Riemann surfaces, and they have more automorphisms fixing than other tori ( and instead of ). This is the first moduli space; for genus , the moduli space has complex dimension .
Theorem— Theorem 6 (tori are cubic curves; stated)
The Weierstrass function satisfies , with , , and the map (with ) is a biholomorphism from onto the smooth projective cubic . Conversely, every smooth cubic arises this way.
The differential equation is proved by noting that is an elliptic function whose Laurent expansion at has no pole and vanishing constant term, so by Corollary 3(a) it is identically . Mathlib proves exactly this, and we cite it below. One more consequence of Corollary 3: no elliptic function has a single simple pole (per fundamental parallelogram). Indeed, the integral of round the boundary of a fundamental parallelogram (shifted to avoid poles) vanishes, because opposite sides cancel by periodicity; by the residue theorem it equals times the sum of residues in . So the residues of an elliptic function sum to , and a single simple pole is impossible — which also follows from Corollary 3(c), since a function of degree would make the torus a sphere.
Uniformisation and Riemann–Roch
Theorem— Theorem 7 (uniformisation; Koebe and Poincaré, 1907; stated)
Every simply connected Riemann surface is biholomorphic to exactly one of , and the unit disc .
Since the universal cover of a Riemann surface is a simply connected Riemann surface on which acts by biholomorphisms, every Riemann surface is , or , or a torus , or a quotient by a discrete group of Möbius transformations. For compact surfaces this is decided by the genus: gives , gives a torus, gives with a cocompact Fuchsian group. Geometrically: every compact Riemann surface carries a conformal metric of constant curvature , or , matching the sign of — and by Gauss–Bonnet, a hyperbolic surface of genus has area . See Riemannian geometry.
A divisor on a compact Riemann surface is a finite formal sum of points, of degree . Let be the space of meromorphic functions with (poles allowed only where permits) together with , and . Let be the divisor of any non-zero meromorphic -form (a canonical divisor).
Theorem— Theorem 8 (Riemann–Roch; Riemann 1857, Roch 1865; stated)
For every divisor on a compact Riemann surface of genus ,
Example— Riemann–Roch at work
- Consequences for . gives : there are exactly independent holomorphic -forms. then gives , matching Riemann–Hurwitz.
- Genus . On , is the space of polynomials of degree , of dimension (and since ). In general, on a surface of genus , for any point , so there is a meromorphic function with a single simple pole: a degree- map to , and by Corollary 3(c).
- Genus . For , : on , , (no function with one simple pole), , . The seven functions lie in the -dimensional , so they satisfy a linear relation — the Weierstrass cubic. Every compact surface of genus is a cubic curve, hence a torus.
- Genus . and , so the quotient of two holomorphic -forms is a meromorphic function of degree : every surface of genus is hyperelliptic, with or .
Riemann–Roch also shows that every compact Riemann surface has enough meromorphic functions to embed it in some (for , the functions in give an embedding), and Chow's theorem then makes the image algebraic: every compact Riemann surface is a smooth projective algebraic curve. The hard analytic input is the existence of non-constant meromorphic functions, proved via harmonic functions (the Dirichlet principle) or Hodge theory; the proofs are in Forster, Chapters 2–3, and Miranda, Chapter VI.
Riemann surfaces in Lean and Mathlib
Mathlib's complex manifolds are manifolds modelled on with holomorphic transition maps; a Riemann surface is the case . The theory of branched coverings, Riemann–Hurwitz, uniformisation and Riemann–Roch is not yet formalised. What we can do is prove the analytic facts on which the lesson's examples rest.
First, the starting point of the whole subject: there is no continuous square root on . The proof uses connectedness of in the form "two continuous functions with the same square and no zeros agree up to a global sign":
/-- **There is no continuous square root on `ℂ ∖ {0}`.** Suppose `g` were one. Along the circle,
`f(t) = g(e^{it})` and `h(t) = e^{it/2}` are continuous on `[0, 2π]` with `f² = h²` and `h ≠ 0`;
since `[0, 2π]` is connected, `f = h` or `f = -h` throughout. But `f(0) = f(2π) = g(1)`, while
`h(0) = 1` and `h(2π) = e^{iπ} = -1`: contradiction in both cases. The square root becomes a
single-valued continuous (indeed holomorphic) function only on its two-sheeted Riemann surface. -/
theorem no_continuous_sqrt :
¬ ∃ g : ℂ → ℂ, ContinuousOn g {z | z ≠ 0} ∧ ∀ z, z ≠ 0 → g z ^ 2 = z := by
rintro ⟨g, hg, hsq⟩
set S : Set ℝ := Set.Icc 0 (2 * Real.pi)
let f : ℝ → ℂ := fun t => g (exp (t * I))
let h : ℝ → ℂ := fun t => exp (t * I / 2)
have hexp_ne : ∀ t : ℝ, exp (t * I) ≠ 0 := fun t => exp_ne_zero _
have hf : ContinuousOn f S := by
refine hg.comp (Continuous.continuousOn (by fun_prop)) ?_
intro t _
exact hexp_ne t
have hh : ContinuousOn h S := Continuous.continuousOn (by fun_prop)
have hfh : Set.EqOn (f ^ 2) (h ^ 2) S := by
intro t _
simp only [Pi.pow_apply, f, h]
rw [hsq _ (hexp_ne t), ← exp_nat_mul]
congr 1
push_cast
ring
have hne : ∀ {t}, t ∈ S → h t ≠ 0 := fun {t} _ => exp_ne_zero _
have h0 : (0 : ℝ) ∈ S := ⟨le_rfl, by positivity⟩
have h2 : 2 * Real.pi ∈ S := ⟨by positivity, le_rfl⟩
have hf0 : f 0 = g 1 := by simp [f]
have hf2 : f (2 * Real.pi) = g 1 := by
simp only [f]
congr 1
push_cast
exact exp_two_pi_mul_I
have hh0 : h 0 = 1 := by simp [h]
have hh2 : h (2 * Real.pi) = -1 := by
simp only [h]
rw [show ((2 * Real.pi : ℝ) : ℂ) * I / 2 = Real.pi * I by push_cast; ring]
exact exp_pi_mul_I
rcases (isPreconnected_Icc).eq_or_eq_neg_of_sq_eq hf hh hfh hne with heq | heq
· have a := heq h0
have b := heq h2
rw [hf0, hh0] at a
rw [hf2, hh2, a] at b
norm_num at b
· have a := heq h0
have b := heq h2
simp only [Pi.neg_apply] at a b
rw [hf0, hh0] at a
rw [hf2, hh2, a] at b
norm_num at bCorollary 3(a), from Mathlib, for any compact connected complex manifold:
/-- **On a compact connected Riemann surface every holomorphic function is constant** (maximum
modulus). So the interesting functions on a compact Riemann surface are *meromorphic*. Mathlib's
`MDifferentiable.apply_eq_of_compactSpace`, stated for any compact connected complex manifold
without boundary. -/
theorem holomorphic_constant_compact {E : Type*} [NormedAddCommGroup E] [NormedSpace ℂ E]
{H : Type*} [TopologicalSpace H] {I : ModelWithCorners ℂ E H} [I.Boundaryless]
{M : Type*} [TopologicalSpace M] [ChartedSpace H M] [IsManifold I 1 M]
[CompactSpace M] [PreconnectedSpace M] {f : M → ℂ}
(hf : MDifferentiable I (modelWithCornersSelf ℂ ℂ) f) (a b : M) : f a = f b :=
hf.apply_eq_of_compactSpace a bFor complex tori we work with Mathlib's PeriodPair (a pair of -independent periods and the lattice they span). A function with both periods is invariant under the whole lattice; a doubly periodic entire function is constant (Liouville); and — the key step of Theorem 5 — a holomorphic map that commutes with the lattice up to constants is affine:
/-- A function with periods `ω₁` and `ω₂` is invariant under the whole lattice
`Λ = ℤω₁ + ℤω₂`: every `w = mω₁ + nω₂ ∈ Λ` is a period. So it is a function on the torus `ℂ/Λ`. -/
theorem periodic_lattice (L : PeriodPair) {f : ℂ → ℂ} (h₁ : ∀ z, f (z + L.ω₁) = f z)
(h₂ : ∀ z, f (z + L.ω₂) = f z) : ∀ z w, w ∈ L.lattice → f (z + w) = f z := by
intro z w hw
obtain ⟨m, n, rfl⟩ := PeriodPair.mem_lattice.mp hw
have p₁ : Function.Periodic f L.ω₁ := h₁
have p₂ : Function.Periodic f L.ω₂ := h₂
have hm := (p₁.int_mul m) z
have hn := (p₂.int_mul n) (z + m * L.ω₁)
rw [← add_assoc, hn, hm]/-- **A doubly periodic entire function is constant.** It is continuous and invariant under the
lattice, so its range is the image of a compact fundamental parallelogram, hence bounded; by
Liouville's theorem it is constant. Equivalently: every holomorphic function on the compact
Riemann surface `ℂ/Λ` is constant. -/
theorem doubly_periodic_constant (L : PeriodPair) {f : ℂ → ℂ} (hf : Differentiable ℂ f)
(h₁ : ∀ z, f (z + L.ω₁) = f z) (h₂ : ∀ z, f (z + L.ω₂) = f z) (z w : ℂ) : f z = f w := by
have hc : IsCompact (Set.range f) :=
IsZLattice.isCompact_range_of_periodic L.lattice f hf.continuous (periodic_lattice L h₁ h₂)
exact hf.apply_eq_apply_of_bounded hc.isBounded z w/-- **Holomorphic maps between tori lift to affine maps.** Let `F : ℂ → ℂ` be entire and suppose
`F(z + ω₁) - F(z)` and `F(z + ω₂) - F(z)` do not depend on `z` (this holds for a lift of a
holomorphic map `ℂ/Λ → ℂ/Λ'`, the differences lying in the discrete set `Λ'`). Then `F' ` is
doubly periodic, hence constant `= a`, and `F(z) = a z + F(0)`. This is the key step in the
classification of complex tori: `ℂ/Λ ≅ ℂ/Λ'` iff `Λ' = aΛ` for some `a ∈ ℂ^×`. -/
theorem lift_affine (L : PeriodPair) {F : ℂ → ℂ} (hF : Differentiable ℂ F) {c₁ c₂ : ℂ}
(h₁ : ∀ z, F (z + L.ω₁) = F z + c₁) (h₂ : ∀ z, F (z + L.ω₂) = F z + c₂) :
∃ a : ℂ, ∀ z, F z = a * z + F 0 := by
have hd : Differentiable ℂ (deriv F) := fun z =>
((hF.differentiableOn.deriv isOpen_univ) z (Set.mem_univ z)).differentiableAt
(isOpen_univ.mem_nhds (Set.mem_univ z))
have per : ∀ (c ω : ℂ), (∀ z, F (z + ω) = F z + c) → ∀ z, deriv F (z + ω) = deriv F z := by
intro c ω h z
have e1 : deriv (fun z => F (z + ω)) z = deriv F (z + ω) := deriv_comp_add_const _ _ _
have e2 : (fun z => F (z + ω)) = fun z => F z + c := funext h
rw [← e1, e2, deriv_add_const]
obtain ⟨a, ha⟩ : ∃ a, ∀ z, deriv F z = a :=
⟨deriv F 0, fun z => doubly_periodic_constant L hd (per c₁ _ h₁) (per c₂ _ h₂) z 0⟩
refine ⟨a, fun z => ?_⟩
have hG : Differentiable ℂ (fun z => F z - a * z) := hF.sub (differentiable_id.const_mul a)
have hG' : ∀ z, deriv (fun z => F z - a * z) z = 0 := by
intro z
have hz : HasDerivAt (fun z => F z - a * z) (deriv F z - a * 1) z :=
(hF z).hasDerivAt.sub ((hasDerivAt_id' z).const_mul a)
rw [hz.deriv, ha]
ring
have := is_const_of_deriv_eq_zero hG hG' z 0
simp only [mul_zero, sub_zero] at this
linear_combination thisFinally, Theorem 6's differential equation, which Mathlib has recently formalised along with the Weierstrass function itself:
/-- The **Weierstrass function** `℘(z) = 1/z² + Σ_{w ∈ Λ ∖ 0} (1/(z - w)² - 1/w²)` is periodic
for the lattice `Λ`, so it is a meromorphic function on the torus `ℂ/Λ` (with a double pole at
`0`). Mathlib's `PeriodPair.weierstrassP_add_coe`. -/
theorem weierstrass_periodic (L : PeriodPair) (z : ℂ) (w : L.lattice) :
L.weierstrassP (z + w) = L.weierstrassP z :=
L.weierstrassP_add_coe z w/-- **The torus is a cubic curve.** Away from the lattice, `℘'(z)² = 4℘(z)³ - g₂℘(z) - g₃`, so
`z ↦ (℘(z), ℘'(z))` maps `ℂ/Λ` minus a point into the affine curve `y² = 4x³ - g₂x - g₃`; sending
`0` to the point at infinity gives a biholomorphism onto the projective cubic. Mathlib's
`PeriodPair.derivWeierstrassP_sq`. -/
theorem weierstrass_cubic (L : PeriodPair) (z : ℂ) (hz : z ∉ L.lattice) :
L.derivWeierstrassP z ^ 2 = 4 * L.weierstrassP z ^ 3 - L.g₂ * L.weierstrassP z - L.g₃ :=
L.derivWeierstrassP_sq z hzWhat is and is not formalised. Proved here: the non-existence of a continuous square root on , lattice invariance, Liouville for doubly periodic functions, and the affine-lift lemma of Theorem 5. Cited from Mathlib: constancy of holomorphic functions on compact complex manifolds, the periodicity of and the equation . Not formalised: Theorems 1, 2 and 4 (Mathlib has the analytic ingredients — the identity theorem, the open mapping theorem, local inverses — but not holomorphic maps between Riemann surfaces as branched coverings), the full classification of tori (the lifting step uses covering space theory on the quotient ), uniformisation, and Riemann–Roch.
Branch points, genera and the j-invariant
The first program checks Riemann–Hurwitz for rational maps of the sphere, measuring each ramification index numerically (as the number of solutions of near ); computes genera of hyperelliptic and Fermat curves from their branch data; and continues square roots along loops, recording whether they come back with the same sign.
"""Branched covers: Riemann-Hurwitz and the monodromy of square roots.
Part 1 checks the Riemann-Hurwitz formula 2g_X - 2 = n(2g_Y - 2) + sum(e_p - 1)
for rational maps of the Riemann sphere to itself (g_X = g_Y = 0). The
ramification index e_p at each critical point is measured numerically, by
counting how many solutions of f(z) = f(p) + eps lie close to p.
Part 2 computes genera of curves from branched covers of the sphere: the
hyperelliptic curves w^2 = f(z), branched over the roots of f (and over
infinity when deg f is odd), and the Fermat curves x^d + y^d = 1, branched
over the d-th roots of unity.
Part 3 continues a square root along loops numerically: w^2 = z flips sign
round the origin; w^2 = z^3 - z flips sign round a loop enclosing one branch
point but not round a loop enclosing two.
"""
import cmath
import math
import numpy as np
def critical_points(num, den, tol=1e-3):
"""Distinct finite critical points of f = num/den: roots of num' den - num den'."""
p, q = np.poly1d(num), np.poly1d(den)
wronskian = np.polyder(p) * q - p * np.polyder(q)
points = []
for r in np.roots(wronskian.coeffs):
if all(abs(r - c) > tol for c in points):
points.append(complex(r))
return points
def local_degree(num, den, c, eps=1e-12, radius=0.05):
"""e_c: the number of solutions of f(z) = f(c) + eps lying close to c."""
p, q = np.poly1d(num), np.poly1d(den)
target = p(c) / q(c) + eps
roots = np.roots((p - target * q).coeffs)
return sum(1 for r in roots if abs(r - c) < radius)
def total_ramification(num, den):
"""R = sum of (e_p - 1): local degrees counted numerically at the finite
critical points, plus the ramification at infinity, |deg num - deg den| - 1."""
finite = sum(local_degree(num, den, c) - 1 for c in critical_points(num, den))
gap = abs(len(num) - len(den))
return finite + max(gap - 1, 0)
def riemann_hurwitz_genus(degree, genus_y, total_ramification):
"""Solve 2g_X - 2 = n(2g_Y - 2) + R for g_X."""
twice = degree * (2 * genus_y - 2) + total_ramification + 2
if twice % 2:
raise ValueError("Riemann-Hurwitz gives a half-integer genus")
return twice // 2
def hyperelliptic_genus(deg_f):
"""Genus of w^2 = f(z), f squarefree of degree deg_f >= 1."""
branch_points = deg_f if deg_f % 2 == 0 else deg_f + 1
return riemann_hurwitz_genus(2, 0, branch_points)
def fermat_genus(d):
"""Genus of x^d + y^d = 1 via (x, y) -> x: degree d, d points with e = d."""
return riemann_hurwitz_genus(d, 0, d * (d - 1))
def continue_sqrt(f, centre, radius, turns=1, steps=2000):
"""Follow a continuous branch of sqrt(f(z)) round a circle; return end/start."""
z0 = centre + radius
w = cmath.sqrt(f(z0))
start = w
for k in range(1, turns * steps + 1):
z = centre + radius * cmath.exp(2j * math.pi * k / steps)
root = cmath.sqrt(f(z))
w = root if abs(root - w) <= abs(root + w) else -root
return w / start
def main():
print("1. Riemann-Hurwitz for maps P^1 -> P^1: -2 = n(-2) + R")
cases = [("z^3 - 3z", 3, total_ramification([1, 0, -3, 0], [1])),
("z^4", 4, total_ramification([1, 0, 0, 0, 0], [1])),
("(z^2 + 1)/(z - 2)", 2, total_ramification([1, 0, 1], [1, -2])),
("(z^3 - 1)/(z^2 + 3)", 3,
total_ramification([1, 0, 0, -1], [1, 0, 3]))]
for name, n, r in cases:
print(f" {name:<20} degree {n}: R = {r}, n(-2) + R = {-2 * n + r}")
print("2. Genus from branch data")
for deg in [3, 4, 5, 6]:
print(f" w^2 = f(z), deg f = {deg}: genus {hyperelliptic_genus(deg)}")
for d in [2, 3, 4, 5]:
print(f" Fermat x^{d} + y^{d} = 1: genus {fermat_genus(d)}"
f" (plane curve formula (d-1)(d-2)/2 = {(d - 1) * (d - 2) // 2})")
print("3. Continuing a square root once round a loop (end / start):")
loops = [("sqrt(z), circle round 0", lambda z: z, 0, 1.0, 1),
("sqrt(z), twice round 0", lambda z: z, 0, 1.0, 2),
("sqrt(z^3 - z), round 1 only", lambda z: z**3 - z, 1, 0.5, 1),
("sqrt(z^3 - z), round 0 and 1", lambda z: z**3 - z, 0.5, 0.8, 1),
("sqrt(z^3 - z), round all three", lambda z: z**3 - z, 0, 2.0, 1)]
for name, f, c, r, turns in loops:
ratio = continue_sqrt(f, c, r, turns)
print(f" {name:<32} {ratio.real:+.6f}")
print()
print("Epistemic status: numerical root-finding and path-following for a few")
print("maps and loops, plus exact integer arithmetic for the genus formulas.")
print("Evidence for Riemann-Hurwitz and for the monodromy of branch points;")
print("the proofs are in the lesson.")
if __name__ == "__main__":
main()The last block is the intuition section made numerical: changes sign round a loop enclosing one branch point or three (the fourth branch point, , is then also "inside" from the other side), and not round a loop enclosing two.
The second program computes the -invariant of from the -expansions of the Eisenstein series, , and reduces points of the upper half-plane to the fundamental domain.
"""Complex tori and the j-invariant.
Every complex torus is C / (Z + tau Z) with tau in the upper half-plane, and
two tori are biholomorphic exactly when their tau's differ by an element of
SL(2, Z) acting by Mobius transformations. The j-invariant is a complete
invariant. We compute j(tau) = 1728 E4^3 / (E4^3 - E6^2) from the
q-expansions of the Eisenstein series (q = exp(2 pi i tau)), check that
j(tau + 1) = j(-1/tau) = j(tau), compute j(i) = 1728 and j(exp(2 pi i/3)) = 0,
reduce points to the standard fundamental domain, and show that tori of the
same shape but different size have the same j while the square and the
hexagonal tori are different. Numerical evidence from truncated series.
"""
import cmath
import math
def sigma(k, n):
"""Sum of the k-th powers of the divisors of n."""
return sum(d**k for d in range(1, n + 1) if n % d == 0)
def eisenstein(tau, terms=60):
"""(E4, E6) at tau via E4 = 1 + 240 sum s3(n) q^n, E6 = 1 - 504 sum s5(n) q^n."""
q = cmath.exp(2j * math.pi * tau)
e4, e6, qn = 1 + 0j, 1 + 0j, 1 + 0j
for n in range(1, terms + 1):
qn *= q
e4 += 240 * sigma(3, n) * qn
e6 -= 504 * sigma(5, n) * qn
return e4, e6
def j_invariant(tau, terms=60):
"""j(tau) = 1728 E4^3 / (E4^3 - E6^2)."""
e4, e6 = eisenstein(tau, terms)
return 1728 * e4**3 / (e4**3 - e6**2)
def reduce_to_fundamental_domain(tau, max_steps=100):
"""Apply T: tau -> tau + n and S: tau -> -1/tau until |Re| <= 1/2, |tau| >= 1."""
steps = []
for _ in range(max_steps):
n = round(tau.real)
if n:
tau -= n
steps.append(f"T^{-n}")
if abs(tau) < 1 - 1e-12:
tau = -1 / tau
steps.append("S")
else:
return tau, steps
raise RuntimeError("did not converge")
def lattice_tau(w1, w2):
"""The tau of the lattice Z w1 + Z w2, normalised to the upper half-plane."""
tau = w2 / w1
return tau if tau.imag > 0 else -tau
def main():
i = 1j
rho = cmath.exp(2j * math.pi / 3)
print(f"j(i) = {j_invariant(i).real:12.4f} (square torus; exact 1728)")
print(f"j(rho) = {abs(j_invariant(rho + 1)):12.4e} (hexagonal torus; exact 0)")
tau = 0.3 + 1.1j
print(f"j(tau) = {j_invariant(tau):.6f} for tau = 0.3 + 1.1i")
print(f"j(tau + 1) = {j_invariant(tau + 1):.6f}")
print(f"j(-1/tau) = {j_invariant(-1 / tau, terms=120):.6f}")
print()
print("Reducing tau to the fundamental domain |Re tau| <= 1/2, |tau| >= 1:")
for start in [3.7 + 0.2j, -0.45 + 0.05j, 0.1 + 0.6j]:
end, steps = reduce_to_fundamental_domain(start)
moves = " ".join(steps) if steps else "(already reduced)"
x, y = round(end.real, 4) + 0.0, round(end.imag, 4)
print(f" {start}: {moves} -> {x:+.4f}{y:+.4f}i")
print(f" j before {j_invariant(start, 400):.2f}")
print(f" j after {j_invariant(end):.2f}")
print()
t1 = lattice_tau(1 + 0j, 1j)
t2 = lattice_tau(2 + 2j, -2 + 2j)
print("Same shape, different size: lattices Z + iZ and (2+2i)Z + (-2+2i)Z")
print(f" j = {j_invariant(t1).real:.4f} and {j_invariant(t2).real:.4f}")
print()
print("Epistemic status: floating-point evaluation of truncated q-series, so")
print("evidence only. The invariance of j under SL(2, Z) and the fact that j")
print("classifies tori up to biholomorphism are theorems (see the lesson).")
if __name__ == "__main__":
main(), and agree, the reduced point has the same as the original, and homothetic lattices have the same — all numerical evidence for Theorem 5 and the invariance of .
Explore: a branched double cover and a torus
The map is the projection of the Riemann surface of onto the plane. Move the probe: the little right-angled cross stays right-angled (the map is conformal) everywhere except at , the ramification point, where angles are doubled and the cross opens to . Each image point other than is hit twice, by .
w = z²: a branched double cover
Conformal everywhere except at the branch point 0, where angles double.
- horizontal lines and their images
- vertical lines and their images
- small cross at z₀ and its image
Drag the points, or focus one with Tab and use the arrow keys (hold Shift for small steps).
- z₀
- 1 + 0.5i
- w₀ = f(z₀)
- 0.75 + i
- f′(z₀)
- 2 + i
- Local scale factor |f′(z₀)|
- 2.236
- Local rotation arg f′(z₀)
- 26.6°
- Angle between the image curves
- 90°
Conformal at z₀: the little right angle is turned by 26.6° and scaled by 2.236, and it stays a right angle.
Squaring doubles every argument: the right half-plane opens out to the whole plane, and the grid lines become parabolas that still cross at right angles.
A complex torus is the plane modulo a lattice. In the tiling view, copies of a fundamental parallelogram (here a square, ) tile the plane; the plane is the universal cover of the torus, and the deck transformations are the lattice translations. Walking off one edge of the square brings you back on the opposite edge — exactly the identification .
The torus ℂ/(ℤ + iℤ) and its universal cover
Lattice translations are the deck transformations of ℂ → ℂ/Λ.
Keys: ↑ forward, ↓ back, ← and → turn, Space walks or stops. You can also drag it.
- Orientable
- Yes
- Euler characteristic
- χ = 0
Gluing turns the 4 corners into V = 1, the 4 sides into E = 2 and the square into F = 1: V − E + F = 1 − 2 + 1 = 0
Same way round as at the start.
Sides crossed so far: 0
Opposite sides are glued with arrows pointing the same way. Walk off the right side and you come back on the left, the same way round. However it walks, the flatlander is never mirrored: the torus is orientable.
Copies of the square tile the plane, and the trail runs on smoothly from copy to copy. This plane is the universal cover of the torus.
Exercises
1. Riemann surfaces
Warm-upHumanWhat is the genus of the compact Riemann surface of ?
2. Riemann surfaces
CoreHumanA compact Riemann surface of genus admits a holomorphic map of degree onto a torus . What is the total ramification ?
3. Riemann surfaces
CoreHumanA compact Riemann surface of genus is a double cover of the Riemann sphere. How many branch points does the cover have?
4. Riemann surfaces
CoreHumanWhich of these surfaces admit the structure of a Riemann surface? (Choose all that apply.)
5. Riemann surfaces
CoreHumanAre the tori and biholomorphic?
6. Riemann surfaces
CoreHumanOn which of these domains is there a continuous function with for all in the domain? (Choose all that apply.)
7. Riemann surfaces
CoreHumanIn the proof of the local normal form we write with and need a holomorphic near with . Why does exist?
8. Riemann surfaces
StretchFormalWhich Lean statement says exactly that there is no continuous square root on ?
9. Riemann surfaces
StretchComputationalWrite reduce_tau(tau) that takes a complex number with positive imaginary part and returns the equivalent point of the fundamental domain , by repeating: translate by an integer to make ; if , replace by .
Common misconceptions
Misconception
"All tori are biholomorphic." They are all homeomorphic, even diffeomorphic, but the complex structure carries one complex parameter: exactly when , i.e. when the 's are related by , i.e. when the -invariants agree. The square torus () and the hexagonal torus () are different Riemann surfaces, and so are and .
Misconception
"The square root is a function on , if we just choose carefully." Any choice of square roots is discontinuous somewhere on every loop round (formalised above). Continuous branches exist on simply connected regions avoiding , such as , and the square root becomes a single-valued holomorphic function on its Riemann surface , the two-sheeted cover branched at and .
Misconception
"A Riemann surface is a surface in or ." A Riemann surface is an abstract one-dimensional complex manifold; algebraic curves in or are important examples, but tori and quotients are defined intrinsically. It is a theorem (Riemann–Roch plus Chow) that every compact Riemann surface embeds in projective space as an algebraic curve.
Misconception
"Complex dimension one means real dimension one." A Riemann surface is a curve to an algebraic geometer (complex dimension ) and a surface to a topologist (real dimension ). The "complex line" is a real plane, and the "projective line" is a sphere.
Misconception
"Every holomorphic function on a Riemann surface is constant." Only on compact ones (Corollary 3). Non-compact Riemann surfaces have many holomorphic functions — in fact every non-compact Riemann surface is a Stein manifold, with holomorphic functions separating points (Behnke–Stein, 1949). On compact surfaces one works with meromorphic functions and -forms instead.
Many ways of seeing
Topology— Coverings, monodromy and moduli
Away from its branch points, a degree- map is an -sheeted covering of , so it is described by its monodromy: a homomorphism recording how loops permute the sheets. For , every small loop round a branch point maps to the transposition . Conversely (the Riemann existence theorem), any such homomorphism with transitive image comes from a unique compact Riemann surface with a branched cover of — so topology produces algebraic curves. The space of all complex structures on a closed surface of genus , modulo isotopy, is Teichmüller space, a complex manifold of dimension homeomorphic to a ball; dividing by the mapping class group gives the moduli space . See the fundamental group and low-dimensional topology.
Geometry— Conformal structures and constant curvature
On an oriented surface, a complex structure is the same thing as a conformal structure — a Riemannian metric up to multiplication by positive functions — because holomorphic maps are exactly the orientation-preserving conformal maps (and isothermal coordinates exist for every metric). Uniformisation is then a statement in Riemannian geometry: every conformal class contains a metric of constant curvature, spherical, flat or hyperbolic according to the sign of . A compact Riemann surface of genus "is" a closed hyperbolic surface, obtained by gluing the sides of a hyperbolic -gon, and its geodesics and their lengths are a central object of study. See non-Euclidean geometry.
Algebra— Curves and their function fields
For a compact Riemann surface , the field of meromorphic functions is a finitely generated extension of of transcendence degree — for it is — and is an equivalence (contravariant) between compact Riemann surfaces with non-constant holomorphic maps and such fields with -embeddings. A branched cover of degree corresponds to a field extension of degree , and Galois coverings to Galois extensions — the analogue, in geometry, of the Galois correspondence between subgroups and intermediate fields, now with the fundamental group of the punctured surface in the role of the Galois group. See algebraic geometry and Galois theory.
Number theory— Elliptic curves and Belyi's theorem
The torus is the cubic curve , and the group law of (addition of complex numbers) becomes the chord-and-tangent law on the cubic. When the coefficients are rational, the same equation defines an elliptic curve over , whose rational points form a finitely generated abelian group (Mordell, 1922) — the subject of the Birch–Swinnerton-Dyer conjecture and of Wiles's proof of Fermat's Last Theorem, which hinges on the parametrisation of elliptic curves over by modular curves . The -function is itself a modular function, , and its values at imaginary quadratic are algebraic integers (complex multiplication): is within of an integer because . Belyi's theorem (1979) says a compact Riemann surface can be defined by equations with algebraic coefficients exactly when it admits a meromorphic function branched over only three points. See arithmetic geometry.
Analysis— Harmonic functions and Hodge theory
Riemann's own approach was analytic: he constructed meromorphic functions and differentials by solving the Laplace equation with prescribed singularities, using the Dirichlet principle (later made rigorous by Hilbert, 1900). In modern terms, the Hodge decomposition splits the -dimensional cohomology into holomorphic and antiholomorphic -forms, dimensions each — the analytic meaning of the genus. Integrating the holomorphic forms over the loops of a basis of gives the period matrix, and is the Abel–Jacobi construction; Torelli's theorem says the polarised Jacobian determines . For a torus, the period matrix is , recovering Theorem 5.
Physics— Potential flow and worldsheets
Two-dimensional potential theory lives naturally on Riemann surfaces: a steady, irrotational, incompressible planar flow has a holomorphic complex potential, and conformal maps transport flows from one region to another (the Joukowski map turns flow round a cylinder into flow round an aerofoil). In string theory, the trajectory of a string sweeps out a two-dimensional "worldsheet", and perturbative amplitudes are (heuristically) integrals over moduli spaces of Riemann surfaces, one genus at a time; this physical intuition has led to deep, rigorously proved results about the cohomology of (Witten's conjecture, proved by Kontsevich, 1992). The physics is a guide, not a proof.
History and global context
- Elliptic functions. Integrals such as (the lemniscate) were studied by Fagnano and Euler in the eighteenth century. Carl Friedrich Gauss (unpublished, around 1800), Niels Henrik Abel (1827) and Carl Jacobi (1829) inverted elliptic integrals and discovered that the resulting functions are doubly periodic. Karl Weierstrass's lectures in Berlin (from the 1860s) introduced and its differential equation.
- Riemann. Bernhard Riemann's dissertation (1851) introduced Riemann surfaces and conformal mapping; his Theorie der Abel'schen Functionen (1857) used them to study integrals of algebraic functions, introduced the genus, and proved the inequality that his student Gustav Roch completed to the Riemann–Roch theorem (1865). Adolf Hurwitz proved the ramification formula (1891).
- Rigour and uniformisation. Felix Klein popularised Riemann's ideas (1882), and with Henri Poincaré developed the theory of Fuchsian groups in the early 1880s. The uniformisation theorem was proved independently by Paul Koebe and Poincaré in 1907. Hermann Weyl's Die Idee der Riemannschen Fläche (1913) gave the first rigorous definition of a Riemann surface by charts, a model for the definition of manifolds.
- Modern developments. Srinivasa Ramanujan's work on the Eisenstein series , , (1916) and on singular moduli fed into the arithmetic of the -function. Oswald Teichmüller (1930s–1940s), Lars Ahlfors and Lipman Bers founded the theory of moduli of Riemann surfaces; David Mumford and Pierre Deligne studied algebraically (1969). Gennadi Belyi's theorem (1979) inspired Alexander Grothendieck's dessins d'enfants (1984).
Further reading
- Rick Miranda, Algebraic Curves and Riemann Surfaces (1995) — concrete and example-driven: Riemann–Hurwitz, divisors, Riemann–Roch, algebraic curves.
- Otto Forster, Lectures on Riemann Surfaces (1981) — covering spaces, sheaf cohomology, Riemann–Roch, Abel's theorem and uniformisation, in complete detail.
- Simon Donaldson, Riemann Surfaces (2011) — a modern, analytic route to uniformisation and Riemann–Roch.
- Hershel M. Farkas and Irwin Kra, Riemann Surfaces (2nd edition, 1992) — the classical function theory, including Weierstrass points and theta functions.
- Joseph H. Silverman, The Arithmetic of Elliptic Curves (2nd edition, 2009) — Chapter VI for complex tori and the Weierstrass function, then the arithmetic.