A square root that would not go away
In 1545 Gerolamo Cardano published a formula for solving cubic equations. For an equation it reads
Rafael Bombelli tried it on , which obviously has the solution (since ). The formula gives
A square root of a negative number! Bombelli did not give up. In his Algebra (1572) he calculated boldly with a "number" obeying the usual rules plus , and noticed that . So the two cube roots are and , and their sum is . The "impossible" numbers were needed to reach a perfectly real answer.
Today these numbers are indispensable: electrical engineers use them for alternating currents, physicists write quantum mechanics with them, and the images of the Mandelbrot set are pictures of complex arithmetic. In this lesson we build them carefully, see what they look like, and prove their main properties.
Numbers you can turn
Think of multiplication by as a motion of the number line: it swaps and , and — it is a half turn about . Doing it twice is a full turn: .
Now ask for a number with : "multiplying by twice is a half turn". On the line that is impossible. But in the plane there is an obvious candidate: a quarter turn about . Two quarter turns make a half turn. So we let numbers live in a plane: the real numbers along the horizontal axis, and one unit up. Then walks around a square.
Definitions
Definition— complex number
A complex number is an expression with . The number is its real part and its imaginary part; two complex numbers are equal when their real parts are equal and their imaginary parts are equal. The set of complex numbers is . We identify the real number with , so .
Arithmetic follows the usual rules of algebra together with :
(Expand the product and replace by .) Formally one can define as the set of pairs of reals with these two operations and check every law of arithmetic — commutativity, associativity, distributivity — directly. That is how Hamilton defined complex numbers in 1837, and how Mathlib defines them.
Definition— complex plane
The complex number is drawn as the point — or the arrow from to it — in the complex plane (also called an Argand diagram). The horizontal axis is the real axis, the vertical axis the imaginary axis.
Definition— conjugate, modulus and argument
For :
- the conjugate is , the mirror image of in the real axis;
- the modulus is , the distance from to (Pythagoras);
- for , an argument is an angle from the positive real axis to the arrow , measured anticlockwise in radians. It is defined only up to adding multiples of ; the principal argument is the one in . The number has no argument.
Definition— polar form
If and is an argument of , then and , so
This is the polar form of . The number is the point at angle on the unit circle .
You need the trigonometry of the unit circle and the addition formulas from Trigonometry, and the quadratic formula from Quadratic equations.
Worked examples
Example— Arithmetic
- .
- .
- Powers of repeat with period : , , , , So .
Example— Division with the conjugate
To divide, multiply the top and bottom by the conjugate of the bottom, which makes the bottom real:
In general , so for every . Every non-zero complex number has an inverse: is a field.
Example— Polar forms
- : modulus , argument , so .
- , and .
- : modulus ; the point is in the second quadrant with , , so and .
- Careful: alone does not determine . For , , but the point is in the third quadrant: its principal argument is , not .
Explore: arithmetic as geometry
Drag and . Addition is the parallelogram rule — complex numbers add like arrows (vectors). Then switch to the product: watch the lengths multiply and the angles add.
Multiplying complex numbers
Compare |zw| with |z||w|, and arg(zw) with arg z + arg w. Then try the quotient and the conjugate.
Drag the points, or focus one with Tab and use the arrow keys (hold Shift for small steps).
| Number | Modulus | Argument | |
|---|---|---|---|
| z | 1.5 + 0.5i | 1.581 | 18.4°0.322 rad |
| w | 0.5 + i | 1.118 | 63.4°1.107 rad |
| zw | 0.25 + 1.75i | 1.768 | 81.9°1.429 rad |
Lengths multiply: 1.581 × 1.118 = 1.768
Angles add: 18.4° + 63.4° = 81.9°
Multiplying by w stretches by |w| and turns by arg w: lengths multiply and angles add.
Multiplication by a fixed number moves the whole plane: it rotates by and scales by . As a map of the plane it is the matrix . Here is multiplication by : a rotation by and a stretch by .
Multiplication by 1 + i
The determinant is a² + b² = |w|². Which matrices of the form [[a, −b], [b, a]] are pure rotations?
- image of the grid
- image of the unit square
- image of the flag
- before the transformation
The columns of A are the images of e₁ = (1, 0) and e₂ = (0, 1): Ae₁ = (1, 1), Ae₂ = (−1, 1)
det A = ad − bc = 2
The unit square (area 1) becomes a parallelogram of area |det A| = 2. Since det A > 0, orientation is preserved.
Invariant lines (real eigenvectors)
λ = 1 ± 1i
No real eigenvectors: A turns every direction, so no line through 0 stays put. The eigenvalues are complex.
Theorems and proofs
Theorem— Theorem 1 (moduli multiply)
For all complex numbers : .
Proof
Write , , so . Expanding both sides shows the two-squares identity
since both sides equal (the cross terms cancel on the right). That says . Taking non-negative square roots gives .
∎
Theorem— Theorem 2 (multiplication in polar form)
For all real : . Consequently
to multiply complex numbers, multiply the moduli and add the arguments.
Proof
By the multiplication rule,
By the addition formulas of trigonometry the real part is and the imaginary part is . The second statement follows by multiplying by .
∎
So the addition formulas for sine and cosine are "really" the statement that angles add when complex numbers multiply. In particular , so ; it is also the conjugate .
Theorem— Theorem 3 (De Moivre)
For every real and every integer :
Proof
First let ; we use induction on . For both sides are . If , then by Theorem 2
For negative with : , using the remark after Theorem 2.
∎
De Moivre's theorem turns powers into multiplication of angles. Expanding with the binomial theorem and comparing real parts gives — a trigonometric identity obtained by pure algebra (the experiment below lets SymPy do it).
Theorem— Theorem 4 (roots of unity)
Let . The equation has exactly complex solutions,
the -th roots of unity. They are the vertices of a regular -gon inscribed in the unit circle, with one vertex at . For they add up to .
Proof
Each is a solution: by De Moivre, .
There are no others: if then by Theorem 1, so and for some . De Moivre gives , so , which forces for an integer , i.e. . Since repeats with period , only give different numbers, and these angles all lie in , so they give distinct points.
Regular polygon: consecutive are at angles differing by on the unit circle.
Sum: let (as ), so . The geometric sum satisfies , and , so .
∎
The same idea finds all -th roots of any non-zero : they are for , again a regular -gon. For example the square roots of are .
The sixth roots of unity
Change n, then move c away from 1 to see the n-th roots of other numbers.
Drag the points, or focus one with Tab and use the arrow keys (hold Shift for small steps).
Solutions of wⁿ = c for n = 6:
- w₀ = 1
- w₁ = 0.5 + 0.866i
- w₂ = −0.5 + 0.866i
- w₃ = −1
- w₄ = −0.5 − 0.866i
- w₅ = 0.5 − 0.866i
All roots lie on the circle of radius |c|^(1/n) ≈ 1.
Neighbouring roots are 60° apart: 360° ÷ 6.
w₀ is the principal root, at the angle (arg c)/n; the others follow by equal turns.
Because c = 1, these are the roots of unity of order 6.
The roots add up to 0, so the regular polygon is balanced around the origin.
Theorem— Theorem 5 (quadratics with negative discriminant)
Let be real, , and . Then has the two complex solutions
which are conjugates of each other.
Proof
Let , a positive real number, and . Put . Multiplying the equation by ,
Now and , so , because . As , . The other root is obtained by replacing with , which conjugates .
∎
For example has , so . Check: .
Quadratics are only the beginning:
Theorem— Fundamental theorem of algebra (statement)
Every non-constant polynomial with complex coefficients has at least one complex root. Consequently a polynomial of degree factors into linear factors over .
We do not prove it here: every proof needs a substantial idea from analysis or topology (a sketch of one appears among the viewpoints below). It is why the complex numbers are the natural home of algebra: inventing to solve turns out to make every polynomial equation solvable.
Finally, one thing is lost. The real numbers are ordered compatibly with arithmetic: positive times positive is positive, and every non-zero number is positive or negative, but not both. Not so for .
Theorem— Theorem 6 (ℂ cannot be ordered)
There is no set ("the positive numbers") such that products of elements of lie in and every satisfies exactly one of , .
Proof
Suppose were such a set. Since , either or . In the first case ; in the second . Either way . Then too. But then both and are in , which is forbidden.
∎
So statements like "" or "" have no meaning in . We can compare moduli — — because those are real numbers.
Complex numbers in Lean
Mathlib defines ℂ as pairs of real numbers ⟨re, im⟩, with I = ⟨0, 1⟩, and proves that it is a field. So is a theorem, not an assumption:
/-- The defining property of `i`: `i² = -1`. This applies Mathlib's `Complex.I_sq`; in Mathlib,
`I` is the pair `⟨0, 1⟩` and the equation is a computation with the multiplication rule for
pairs. -/
theorem i_sq : I ^ 2 = -1 := Complex.I_sqThe multiplication rule and our division example. The tactic linear_combination checks that two sides differ by a multiple of , which is exactly "replace by ":
/-- **The multiplication rule.** `(a + bi)(c + di) = (ac − bd) + (ad + bc)i`: expand with the
distributive law and replace `i²` by `-1`. The `linear_combination` step says precisely that
the two sides differ by `bd (i² + 1)`, which is `0`. -/
theorem mul_rule (a b c d : ℝ) :
((a : ℂ) + b * I) * (c + d * I) = (a * c - b * d) + (a * d + b * c) * I := by
linear_combination ((b : ℂ) * d) * I_sq/-- **Division by the conjugate trick.** `(3 + 4i)/(1 + 2i) = 11/5 − (2/5) i`, because
`(3 + 4i)(1 − 2i) = 11 − 2i` and `(1 + 2i)(1 − 2i) = 5`. Lean checks the equivalent statement
`3 + 4i = (11/5 − (2/5)i)(1 + 2i)`. -/
theorem div_example : (3 + 4 * I) / (1 + 2 * I) = 11 / 5 - 2 / 5 * I := by
have h : (1 + 2 * I) ≠ 0 := by
intro h
have := congrArg Complex.re h
simp at this
rw [div_eq_iff h]
linear_combination (4 / 5 : ℂ) * I_sq/-- `z · z̄ = |z|²`, a real number: this is why multiplying by the conjugate clears
denominators. Mathlib's `Complex.mul_conj` states it with `normSq z = a² + b²`. -/
theorem mul_conj (z : ℂ) : z * (starRingEnd ℂ) z = (normSq z : ℂ) := Complex.mul_conj zTheorem 1, via the two-squares identity. Mathlib writes normSq z for and ‖z‖ for the modulus :
/-- **The two-squares identity** (Brahmagupta; Fibonacci's *Liber Quadratorum*):
`(a² + b²)(c² + d²) = (ac − bd)² + (ad + bc)²`. A product of two sums of two squares is again a
sum of two squares. It holds in every commutative ring; `ring` checks it. -/
theorem two_squares_identity {R : Type*} [CommRing R] (a b c d : R) :
(a ^ 2 + b ^ 2) * (c ^ 2 + d ^ 2) = (a * c - b * d) ^ 2 + (a * d + b * c) ^ 2 := by
ring/-- **`|zw|² = |z|² |w|²`.** With `z = a + bi` and `w = c + di`, `zw = (ac − bd) + (ad + bc)i`,
so this *is* the two-squares identity. (Mathlib: `Complex.normSq_mul`.) -/
theorem normSq_mul (z w : ℂ) : normSq (z * w) = normSq z * normSq w := by
simp only [normSq_apply, mul_re, mul_im]
ring/-- **Moduli multiply:** `|zw| = |z| |w|` (Mathlib writes `‖z‖` for the modulus). This applies
Mathlib's `Complex.norm_mul`; it follows from `normSq_mul` by taking square roots. -/
theorem norm_mul (z w : ℂ) : ‖z * w‖ = ‖z‖ * ‖w‖ := Complex.norm_mul z wMathlib has no cis, so we define it, prove that it lies on the unit circle and that it turns multiplication into addition of angles (Theorem 2), and prove De Moivre's theorem by induction for natural numbers (the extension to negative is not formalised here):
/-- `cis θ = cos θ + i sin θ`, the point at angle `θ` on the unit circle. A number with modulus
`r` and argument `θ` is `r · cis θ`. (Mathlib has no `cis`; it uses `exp (θ * I)`, see
`cis_eq_exp`.) -/
noncomputable def cis (θ : ℝ) : ℂ := Real.cos θ + Real.sin θ * I/-- `cis θ` lies on the unit circle: `|cis θ| = √(cos² θ + sin² θ) = 1`. -/
theorem norm_cis (θ : ℝ) : ‖cis θ‖ = 1 := by
rw [cis, Complex.norm_add_mul_I]
simp [Real.cos_sq_add_sin_sq]/-- **Multiplying adds angles:** `cis (α + β) = cis α · cis β`. Expand the right side with the
multiplication rule: its real part is `cos α cos β − sin α sin β = cos (α + β)` and its
imaginary part is `sin α cos β + cos α sin β = sin (α + β)` — the addition formulas of
trigonometry. -/
theorem cis_add (α β : ℝ) : cis (α + β) = cis α * cis β := by
simp only [cis, Real.cos_add, Real.sin_add, Complex.ofReal_add, Complex.ofReal_mul,
Complex.ofReal_sub]
linear_combination (-(Real.sin α : ℂ) * Real.sin β) * I_sq/-- **Multiplication in polar form:** `(r cis α)(s cis β) = (rs) cis (α + β)`. Moduli multiply
and arguments add: a rotation combined with a scaling. -/
theorem polar_mul (r s α β : ℝ) :
((r : ℂ) * cis α) * ((s : ℂ) * cis β) = ((r * s : ℝ) : ℂ) * cis (α + β) := by
rw [cis_add]
push_cast
ring/-- **De Moivre's theorem:** `(cos θ + i sin θ)ⁿ = cos nθ + i sin nθ` for every natural number
`n`. Induction on `n`: the case `0` is `1 = cis 0`, and
`cis θ ^ (k + 1) = cis θ ^ k · cis θ = cis (kθ) · cis θ = cis (kθ + θ)` by `cis_add`.
(Mathlib: `Complex.cos_add_sin_mul_I_pow`.) -/
theorem de_moivre (θ : ℝ) (n : ℕ) : cis θ ^ n = cis (n * θ) := by
induction n with
| zero => simp [cis]
| succ k ih =>
rw [pow_succ, ih, ← cis_add]
congr 1
push_cast
ring/-- **Euler's formula** `e^{iθ} = cos θ + i sin θ`: our `cis θ` is Mathlib's `exp (θ * I)`.
This applies `Complex.exp_mul_I` and the fact that `cos` and `sin` of a real number are real. -/
theorem cis_eq_exp (θ : ℝ) : cis θ = Complex.exp (θ * I) := by
rw [Complex.exp_mul_I, cis, Complex.ofReal_cos, Complex.ofReal_sin]Roots of unity. We prove that each is an -th root of unity and that roots of unity other than sum to ; that there are exactly of them we take from Mathlib, whose rootsOfUnity n ℂ is the group of all with :
/-- **`cis (2πk/n)` is an `n`-th root of unity.** By De Moivre,
`cis (2πk/n) ^ n = cis (2πk) = cos 2πk + i sin 2πk = 1`. Together with `norm_cis`, the `n`
numbers `cis (2πk/n)`, `k = 0, …, n − 1`, sit on the unit circle at equal angles `2π/n`:
the vertices of a regular `n`-gon. -/
theorem cis_root_of_unity (n k : ℕ) (hn : n ≠ 0) : cis (2 * Real.pi * k / n) ^ n = 1 := by
rw [de_moivre]
have h : (n : ℝ) * (2 * Real.pi * k / n) = k * (2 * Real.pi) := by
field_simp
have hsin : Real.sin (k * (2 * Real.pi)) = 0 := by
rw [show (k : ℝ) * (2 * Real.pi) = ((2 * k : ℕ) : ℝ) * Real.pi by push_cast; ring]
exact Real.sin_nat_mul_pi _
rw [h, cis, Real.cos_nat_mul_two_pi, hsin]
simp/-- **The `n`-th roots of unity add up to `0`.** If `ω ^ n = 1` and `ω ≠ 1`, then
`1 + ω + ⋯ + ω^(n−1) = 0`: multiplying the sum by `ω − 1` telescopes to `ωⁿ − 1 = 0`
(Mathlib's `geom_sum_mul`), and `ω − 1 ≠ 0`. With `ω = cis (2π/n)` this says the vertices of a
regular `n`-gon centred at `0` balance at the centre. -/
theorem sum_roots_of_unity {ω : ℂ} {n : ℕ} (hω : ω ^ n = 1) (h1 : ω ≠ 1) :
∑ k ∈ Finset.range n, ω ^ k = 0 := by
have h := geom_sum_mul ω n
rw [hω, sub_self] at h
exact (mul_eq_zero.mp h).resolve_right (sub_ne_zero.mpr h1)/-- **There are exactly `n` complex `n`-th roots of unity** (for `n ≥ 1`). This applies
Mathlib's `Complex.card_rootsOfUnity`; `rootsOfUnity n ℂ` is the group of units `ζ` with
`ζ ^ n = 1`. -/
theorem card_roots_of_unity (n : ℕ) [NeZero n] : Nat.card (rootsOfUnity n ℂ) = n :=
Complex.card_rootsOfUnity nQuadratics with negative discriminant (Theorem 5), and the fundamental theorem of algebra, which Mathlib proves using complex analysis:
/-- `z² + 2z + 5 = 0` has discriminant `4 − 20 = −16 < 0`, so no real roots — but
`z = −1 + 2i` is a complex root: `(−1 + 2i)² + 2(−1 + 2i) + 5 = 4 + 4i² = 0`. -/
theorem quadratic_example : (-1 + 2 * I) ^ 2 + 2 * (-1 + 2 * I) + 5 = 0 := by
linear_combination (4 : ℂ) * I_sq/-- **The quadratic formula when `Δ = b² − 4ac < 0`.** With `s = √(4ac − b²)` (a real number),
`z = (−b + s i)/(2a)` solves `az² + bz + c = 0`. Proof: put `w = 2az = −b + si`; then
`4a(az² + bz + c) = w² + 2bw + 4ac = −b² + s² i² + 4ac = −b² − s² + 4ac = 0`. -/
theorem quadratic_formula_neg_disc (a b c : ℝ) (ha : a ≠ 0) (hΔ : b ^ 2 - 4 * a * c < 0)
(z : ℂ) (hz : z = (-b + Real.sqrt (4 * a * c - b ^ 2) * I) / (2 * a)) :
a * z ^ 2 + b * z + c = 0 := by
set s := Real.sqrt (4 * a * c - b ^ 2) with hsdef
have hs : s ^ 2 = 4 * a * c - b ^ 2 := Real.sq_sqrt (by linarith)
have hs' : (s : ℂ) ^ 2 = 4 * a * c - b ^ 2 := by exact_mod_cast hs
have ha' : (a : ℂ) ≠ 0 := by exact_mod_cast ha
have hw : 2 * (a : ℂ) * z = -b + s * I := by
rw [hz]
field_simp
have h4 : 4 * (a : ℂ) * (a * z ^ 2 + b * z + c) = 0 := by
linear_combination (2 * a * z + (-b + s * I) + 2 * b) * hw + (s : ℂ) ^ 2 * I_sq - hs'
have h4a : (4 * (a : ℂ)) ≠ 0 := mul_ne_zero (by norm_num) ha'
exact (mul_eq_zero.mp h4).resolve_left h4a/-- **The fundamental theorem of algebra:** every non-constant polynomial with complex
coefficients has a complex root. This applies Mathlib's `Complex.exists_root`, whose proof
uses analysis (Liouville's theorem), well beyond this lesson. -/
theorem fundamental_theorem_of_algebra {f : Polynomial ℂ} (hf : 0 < f.degree) :
∃ z : ℂ, f.IsRoot z :=
Complex.exists_root hfAnd Theorem 6. An ordering compatible with arithmetic is described by its set P of positive elements, so "no such P" is the formal content of "ℂ cannot be ordered":
/-- **ℂ cannot be made into an ordered field.** An ordering compatible with arithmetic is the
same as a set `P` of "positive" numbers closed under multiplication, such that every `z ≠ 0`
has `z ∈ P` or `-z ∈ P`, but never both. No such `P` exists in `ℂ`: whether `i ∈ P` or
`-i ∈ P`, the product of that number with itself is `i² = (-i)² = -1`, so `-1 ∈ P`; then
`1 = (-1)(-1) ∈ P` as well — but `1` and `-1` cannot both be positive. -/
theorem no_positive_cone (P : Set ℂ) (mul_mem : ∀ a b, a ∈ P → b ∈ P → a * b ∈ P)
(total : ∀ z : ℂ, z ≠ 0 → z ∈ P ∨ -z ∈ P) (not_both : ∀ z : ℂ, z ∈ P → -z ∉ P) :
False := by
have hm1 : (-1 : ℂ) ∈ P := by
rcases total I I_ne_zero with h | h
· have := mul_mem _ _ h h
rwa [← sq, I_sq] at this
· have := mul_mem _ _ h h
rwa [neg_mul_neg, ← sq, I_sq] at this
have h1 : (1 : ℂ) ∈ P := by
have := mul_mem _ _ hm1 hm1
rwa [neg_mul_neg, one_mul] at this
exact not_both 1 h1 hm1(Mathlib does put a partial order on ℂ, available after open scoped ComplexOrder: means and . It is useful, but most pairs, such as and , are incomparable — consistent with Theorem 6.)
Computing with complex numbers
"""Roots of unity, De Moivre's theorem and a square-root trap.
Numerically: the n numbers cos(2 pi k/n) + i sin(2 pi k/n) satisfy z^n = 1
up to rounding, add up to 0, multiply to (-1)^(n+1), and are spaced 2 sin(pi/n)
apart (a regular n-gon). Symbolically (SymPy): the exact cube roots of 1, and
the triple-angle formula cos 3t = 4 cos^3 t - 3 cos t read off from De
Moivre's theorem. Finally the trap: with principal square roots,
sqrt(-1) * sqrt(-1) = -1 while sqrt((-1) * (-1)) = 1.
"""
import cmath
import math
import sympy
def roots_of_unity(n):
"""The n complex numbers cis(2 pi k / n), k = 0, ..., n - 1."""
if n < 1:
raise ValueError("n must be at least 1")
return [cmath.rect(1.0, 2 * math.pi * k / n) for k in range(n)]
def max_error_power(n):
"""max |z^n - 1| over the computed n-th roots of unity (rounding only)."""
return max(abs(z ** n - 1) for z in roots_of_unity(n))
def root_sum(n):
"""Sum of the n-th roots of unity (exactly 0 for n >= 2)."""
return sum(roots_of_unity(n))
def root_product(n):
"""Product of the n-th roots of unity (exactly (-1)^(n+1))."""
product = 1
for z in roots_of_unity(n):
product *= z
return product
def side_length(n):
"""Distance between neighbouring n-th roots of unity."""
zs = roots_of_unity(n)
return abs(zs[1 % n] - zs[0])
def exact_cube_roots():
"""The roots of z^3 - 1 as exact SymPy expressions, sorted by argument."""
z = sympy.symbols("z")
roots = sympy.solve(z ** 3 - 1, z)
return sorted(roots, key=lambda r: float(sympy.arg(r)) % (2 * math.pi))
def triple_angle():
"""Real and imaginary parts of (cos t + i sin t)^3, in terms of cos, sin."""
t = sympy.symbols("t", real=True)
c, s = sympy.cos(t), sympy.sin(t)
w = sympy.expand((c + sympy.I * s) ** 3)
re_part = sympy.re(w).subs(s ** 2, 1 - c ** 2)
im_part = sympy.im(w).subs(c ** 2, 1 - s ** 2)
return sympy.expand(re_part), sympy.expand(im_part)
def main():
print(" n max|z^n - 1| |sum| |prod - (-1)^(n+1)| side 2 sin(pi/n)")
for n in range(3, 9):
prod_err = abs(root_product(n) - (-1) ** (n + 1))
print(
f"{n:2d} {max_error_power(n):.1e} {abs(root_sum(n)):.1e}"
f" {prod_err:.1e} {side_length(n):.6f}"
f" {2 * math.sin(math.pi / n):.6f}"
)
print("Errors of about 1e-15 are floating-point rounding, not mathematics.")
print()
roots = ", ".join(str(r) for r in exact_cube_roots())
print(f"Exact cube roots of 1 (SymPy): {roots}")
re_part, im_part = triple_angle()
print("De Moivre, n = 3: (cos t + i sin t)^3 = cos 3t + i sin 3t, so")
print(f" cos 3t = {re_part}")
print(f" sin 3t = {im_part}")
print()
a = cmath.sqrt(-1) * cmath.sqrt(-1)
b = cmath.sqrt((-1) * (-1))
print(f"sqrt(-1) * sqrt(-1) = {a.real:+.0f} but sqrt((-1)(-1)) = {b.real:+.0f}")
print("So sqrt(ab) = sqrt(a) sqrt(b) fails when a and b are negative.")
print()
print("Epistemic status: the table is numerical evidence for n = 3..8 only;")
print("the lesson proves z^n = 1, the sum and the spacing for every n. The")
print("SymPy results are exact symbolic computations, as trustworthy as")
print("SymPy's algebra; De Moivre's theorem itself is proved by induction.")
if __name__ == "__main__":
main()The tiny errors in the table, around , come from rounding in floating-point arithmetic, not from the mathematics: Theorem 4 says the true errors are exactly . The table is evidence for six values of ; the theorem covers all of them.
Theorem 1 has a beautiful consequence for whole numbers. If are integers, the two-squares identity says that a product of two sums of two squares is again a sum of two squares — and complex multiplication tells you which squares:
"""Multiplying complex numbers multiplies sums of two squares.
For Gaussian integers z = a + bi (a, b whole numbers) the squared modulus
N(z) = a^2 + b^2 is a sum of two squares, and |zw|^2 = |z|^2 |w|^2 says that
(a^2 + b^2)(c^2 + d^2) = (ac - bd)^2 + (ad + bc)^2. The experiment checks this
exhaustively on a grid of Gaussian integers (exact integer arithmetic), then
uses complex multiplication to *produce* new sums of two squares, e.g.
65 = 5 * 13 = 1^2 + 8^2 = 4^2 + 7^2 from (1 + 2i)(2 + 3i) and (1 + 2i)(2 - 3i).
"""
import math
def gauss_mul(z, w):
"""Product of Gaussian integers given as pairs (a, b) meaning a + bi."""
(a, b), (c, d) = z, w
return (a * c - b * d, a * d + b * c)
def norm(z):
"""N(a + bi) = a^2 + b^2, the squared modulus."""
a, b = z
return a * a + b * b
def grid(radius):
"""All Gaussian integers a + bi with |a|, |b| <= radius."""
if radius < 0:
raise ValueError("radius must be non-negative")
values = range(-radius, radius + 1)
return [(a, b) for a in values for b in values]
def check_multiplicative(radius):
"""Return (pairs checked, failures) for N(zw) == N(z) N(w) on the grid."""
points = grid(radius)
failures = [
(z, w)
for z in points
for w in points
if norm(gauss_mul(z, w)) != norm(z) * norm(w)
]
return len(points) ** 2, failures
def two_square_reps(n):
"""All (a, b) with 0 <= a <= b and a^2 + b^2 = n."""
reps = []
for a in range(math.isqrt(n // 2) + 1):
b2 = n - a * a
b = math.isqrt(b2)
if b * b == b2 and a <= b:
reps.append((a, b))
return reps
def normalise(z):
"""Sort |real|, |imag| so a representation reads (small, large)."""
a, b = abs(z[0]), abs(z[1])
return (min(a, b), max(a, b))
def show(z):
"""Write the pair (a, b) as the text a + bi (or a - bi)."""
a, b = z
sign = "-" if b < 0 else "+"
return f"{a} {sign} {abs(b)}i"
def square(x):
"""x^2 as text, with brackets around negative x."""
return f"({x})^2" if x < 0 else f"{x}^2"
def main():
cases, failures = check_multiplicative(6)
print("N(zw) = N(z)N(w) for all z, w with coordinates in -6..6:")
print(f" {cases} pairs checked, {len(failures)} failures")
print()
z, w = (1, 2), (2, 3)
w_bar = (2, -3)
for v in (w, w_bar):
p = gauss_mul(z, v)
print(f"({show(z)})({show(v)}) = {show(p)}, "
f"N = {square(p[0])} + {square(p[1])} = {norm(p)}")
print("So 5 * 13 = 65 has two representations:", two_square_reps(65))
print()
print("n = a^2 + b^2 (all representations with 0 <= a <= b)")
for n in [5, 13, 25, 65, 85, 325, 1105]:
reps = two_square_reps(n)
shown = ", ".join(f"{a}^2+{b}^2" for a, b in reps)
print(f"{n:<5} {shown}")
print("3, 7, 21 have none:", [two_square_reps(n) for n in (3, 7, 21)])
print()
print("Epistemic status: the grid check is exhaustive but finite; the")
print("identity (a^2+b^2)(c^2+d^2) = (ac-bd)^2+(ad+bc)^2 is proved for all")
print("numbers by expanding both sides (and in Lean). Which n are sums of")
print("two squares is a theorem of Fermat and Euler, not shown here.")
if __name__ == "__main__":
main()Exercises
1. Complex numbers
Warm-upHumanCompute and enter its real part.
2. Complex numbers
Warm-upHumanWhat is ?
3. Complex numbers
Warm-upHumanCompute — ideally without multiplying out first.
4. Complex numbers
CoreHumanWhich is the polar form of ?
5. Complex numbers
CoreHumanSolve .
6. Complex numbers
CoreHumanWhich of the following are sixth roots of unity, i.e. solutions of ? (Choose all that apply.)
7. Complex numbers
StretchHumanWhat is wrong with this "proof" that ?
8. Complex numbers
CoreFormalIn the Lean module, cis θ means and n : ℕ. Which Lean statement is De Moivre's theorem?
9. Complex numbers
StretchComputationalWrite nth_roots(w, n) that returns a list of the complex -th roots of a non-zero complex number w, using polar form: if , the roots are for . Python's cmath.polar(w) returns and cmath.rect(r, theta) returns .
Common misconceptions
Misconception
"Imaginary numbers are fake." The word "imaginary" (Descartes' term, meant dismissively) is a historical accident. Complex numbers are as legitimate as negative numbers or : they can be constructed from real numbers (as pairs), they obey precise laws, and they describe real phenomena — alternating currents, waves, quantum amplitudes.
Misconception
" always." It holds for , but not for negative numbers: with , we get , while . Every non-zero complex number has two square roots, and no choice of "the" square root can make the product rule work everywhere. Treat as , and simplify before multiplying.
Misconception
" can be ordered like ." Theorem 6 shows no ordering is compatible with multiplication. Inequalities between complex numbers are meaningless; inequalities between their moduli, real parts or imaginary parts (all real numbers) are fine.
Misconception
"" or "". The modulus is a distance in the plane: . For example .
Misconception
"The argument is ." That gives an angle in only, so it is wrong for points with , and undefined when . Always check the quadrant: , not .
Other ways of seeing
Geometry— Similarities of the plane
Multiplication by is a rotation by combined with a scaling by , and is a similarity of the plane fixing orientation; is a reflection. Every rigid motion of the plane is or with . Geometry problems about rotations become algebra: for instance, form an equilateral triangle (or all coincide) exactly when for or , the two choices corresponding to the two orientations.
Algebra— Adjoining a root
Algebraically, is what you get by adjoining to a root of : the quotient ring , where polynomials are computed modulo , so plays the role of . Conjugation respects addition and multiplication and fixes — it is a field automorphism, and the two automorphisms of fixing form the first example of a Galois group. The matrices give yet another model of , inside real matrices. See Fields and Galois theory.
Number theory— Gaussian integers
The numbers with form the Gaussian integers , where factorisation behaves differently: and , while cannot be split. Since is multiplicative (Theorem 1), a prime factors in exactly when for some integers . Fermat's theorem that odd primes of the form are sums of two squares (proved by Euler) is the starting point of algebraic number theory.
Topology— Why every polynomial has a root: a winding argument
Here is the idea of one proof of the fundamental theorem of algebra — a sketch, not a proof. Let with , and suppose had no root. For a huge circle , the term dominates, so as goes once around the circle, winds times around . Now shrink the circle continuously to the point : the image curve deforms continuously, never passing through (no roots!), so its winding number cannot jump — yet at the end the curve is the single point , which winds times. Since , contradiction. Making "winding number" and "cannot jump" precise is a job for the fundamental group or complex analysis.
Counting how often a curve winds around a point
How many times does the curve wind around the point p? Count the turns of an arrow, or the signed crossings of a ray.
- winding number 1
Drag the points, or focus one with Tab and use the arrow keys (hold Shift for small steps).
Winding number around p: 1
By the angle: as the gold point goes once around the curve, the arrow from p turns 1 full turns (counter-clockwise counts as positive).
By the ray: signed crossings (+1) = 1
Each crossing of the dashed ray counts +1 where the curve passes upwards (counter-clockwise around p) and −1 where it passes downwards (clockwise).
Both counts are computed on the curve sampled at 720 points.
Physics— Rotating arrows for waves
An alternating voltage is the real part of the rotating complex number (a "phasor"). Adding waves of the same frequency becomes adding complex numbers, and the effect of a capacitor or inductor becomes multiplication by a complex impedance. In quantum mechanics complex numbers are not a convenience but part of the theory: states are described by complex amplitudes whose squared moduli give probabilities.
Wonder Trails
Optional, and never graded: a question that leads somewhere further.
Wonder Trail · Optional · never gradedLoops around a holeWalk around a tree and come back to where you started. How many times did you go around it? Can you change that number by wandering differently — without ever walking through the tree?Follow the trailHistory and global context
- Early encounters. Heron of Alexandria (1st century CE) met the square root of a negative number in a calculation about a truncated pyramid and passed over it. The Indian mathematician Mahāvīra (9th century) stated that a negative number has no square root, since it is not a square.
- Renaissance Italy. Gerolamo Cardano's Ars Magna (1545) contains the cubic formula and, in another problem, the "sophisticated" numbers , which have sum and product . Rafael Bombelli's Algebra (1572) gave the first systematic rules for calculating with them, motivated by .
- Names and symbols. René Descartes called such roots "imaginary" in La Géométrie (1637). Abraham de Moivre found formulas equivalent to his theorem in the early 18th century; Leonhard Euler stated in his Introductio (1748) and introduced the symbol (1777).
- The plane. The surveyor Caspar Wessel (1799, in Danish), Jean-Robert Argand (1806) and Carl Friedrich Gauss (1831) described complex numbers as points of a plane. Gauss's doctoral thesis (1799) was devoted to the fundamental theorem of algebra; its proof was later seen to leave a topological point unproved, and Gauss gave further proofs. William Rowan Hamilton defined complex numbers as pairs of reals (1837).
Further reading
- Tristan Needham, Visual Complex Analysis (1997) — complex numbers as geometry, beautifully illustrated; chapter 1 suits this lesson.
- Paul J. Nahin, An Imaginary Tale: The Story of √−1 (1998) — the history, from Cardano to modern physics.
- Richard Courant and Herbert Robbins, What Is Mathematics? (1941), chapter II, §5 on complex numbers.
- John Stillwell, Mathematics and Its History (1989), the chapters on complex numbers in algebra and geometry.
- Lars Ahlfors, Complex Analysis (1953), chapter 1 — for the next step.