Four theorems, or one?
A course in multivariable calculus ends with a list of theorems that look different:
- the fundamental theorem of calculus: ;
- Green's theorem: ;
- Stokes' theorem: ;
- the divergence theorem: .
Each says that integrating some kind of derivative over a region equals integrating the original quantity over the region's boundary. With the right language — differential forms — they become literally one statement,
valid in every dimension. The same language turns Maxwell's four equations of electromagnetism into two, and , valid in any coordinates and on curved spacetime.
There is a puzzle hiding here too. The vector field has zero curl everywhere it is defined. Yet its circulation around the unit circle is , not . Green's theorem has not failed: the field is undefined at the origin, which is inside the circle. The surprise is that calculus noticed the hole. Making that precise leads to de Rham cohomology, where calculus detects topology.
Things you integrate
A differential form is something you integrate. A 1-form such as is integrated along oriented curves: think of the work done by a force along a path. Reversing the path reverses the sign. A 2-form is integrated over oriented surfaces: think of the flux of a fluid through a membrane, which depends on which side counts as "out". A 0-form is a function, "integrated" over points by evaluating it, with signs for orientation.
Orientation is why forms are alternating. The 2-form assigns to a pair of vectors the signed area of the parallelogram they span, so swapping the vectors changes the sign: , and . That one rule replaces the right-hand rules, cross products and Jacobian determinants of vector calculus.
The exterior derivative measures "how much there is around the boundary of a tiny piece". For a 1-form in the plane, at a point is the circulation of around a tiny square there, divided by its area. Stokes' theorem then follows from a picture: cut the region into tiny squares and add up their circulations. Each interior edge is traversed twice in opposite directions and cancels, leaving only the outer boundary.
Forms, wedge, d and pullback
Throughout, is open, with coordinates .
Definition— alternating forms and the wedge product
An alternating -form on is a multilinear map that changes sign when two arguments are swapped (equivalently, vanishes when two arguments are equal). They form a vector space of dimension , with basis for . Here is the -th coordinate functional and
The wedge product of a -form and an -form is the -form determined by bilinearity and written in order, with the sign of the permutation that sorts , or if and share an index. For two 1-forms, .
Definition— differential form
A differential -form on is a smooth assignment of an alternating -form to each point:
We write for the space of -forms. A 0-form is a smooth function.
Definition— exterior derivative
The exterior derivative is defined on functions by , and on -forms by
Definition— pullback
If is smooth ( open), the pullback is . On functions , and , .
Definition— integration over cubes and chains
For a -form on , set . A singular -cube in is a smooth map , and . A -chain is a formal sum with integer coefficients, integrated linearly. The boundary of the standard cube is the -chain
and . For , , and a 0-form is integrated over it as .
Definition— closed, exact, de Rham cohomology
A form is closed if and exact if for some form . Since (Theorem 2), exact forms are closed, and the de Rham cohomology groups
measure how far closed forms are from being exact.
Worked examples
Example— Vector calculus is exterior calculus in R³
On , identify a vector field with the 1-form and with the 2-form . Then
The identities and are both . For example, .
Example— Polar coordinates
Pull back along . Then and . So
The factor in is the Jacobian determinant, produced automatically by the alternating rule.
Example— The angle form
On , let
In polar coordinates is literally , as the computation above shows. But the notation is misleading: there is no smooth (or even continuous) function on all of — the polar angle jumps by somewhere on every circle around the origin. is closed (Theorem 5), and its integral over the unit circle is .
Example— A form that measures area
has . So by Green's theorem is the area of . This is the principle of the planimeter, an instrument that measures areas on maps and drawings by tracing their boundaries.
The wedge product and the exterior derivative
Theorem— Proposition 1 (graded commutativity)
The wedge product is bilinear and associative, and for a -form and an -form ,
In particular for every 1-form (indeed every form of odd degree).
Proof
Bilinearity and associativity hold on basis elements, where concatenating index lists is associative and signs of sorting permutations multiply. By bilinearity it suffices to check graded commutativity on with , . To turn the list into , move each of the indices of to the front past the indices of : transpositions in all, each changing the sign. For a 1-form, forces .
∎
So 1-forms anticommute, but a 1-form and a 2-form commute: .
Theorem— Theorem 2 (properties of d)
(a) for a -form . (b) . (c) commutes with pullback: .
Proof
(a) By linearity take and . Then , and by the product rule
where moving the 1-form past the -form costs (Proposition 1). This is .
(b) For a function, . The coefficients are symmetric in (mixed partials of smooth functions commute) while is antisymmetric, so the terms cancel in pairs and the diagonal terms vanish. For , , and by (a), , since .
(c) For functions this is the chain rule: . In particular . For , . By (a) and (b), .
∎
Property (c) means that does not depend on coordinates: the same operator works on any manifold, and it is why the definition of through a coordinate formula is legitimate.
Stokes' theorem
Theorem— Theorem 3 (Stokes' theorem for chains)
For every -form on and every -chain in ,
Proof
Step 1: the standard cube. By linearity it suffices to take (with omitted) on . Only the term of survives in , and moving into position costs :
By Fubini and the fundamental theorem of calculus in the variable ,
with and in the -th slot. On the other side, for , because along that face is constant, so pulls back to , and contains . For , . Hence
which is the same.
Step 2: singular cubes and chains. For a singular cube , by the definition of the integral, Theorem 2(c) and Step 1,
where the last equality holds because . Chains follow by linearity.
∎
Theorem— Theorem 4 (Stokes' theorem for manifolds; stated, proof referenced)
Let be a compact oriented smooth -manifold with boundary in (or abstractly), with given the induced orientation, and let be a smooth -form on a neighbourhood of . Then .
The proof reduces to Theorem 3 with a partition of unity and orientation-preserving charts (Spivak 1965, chapter 5; Lee, Introduction to Smooth Manifolds, chapter 16). The classical theorems are its special cases:
| is | |||
|---|---|---|---|
| 1 | interval | function | (fundamental theorem of calculus) |
| 1 | curve in | function | |
| 2 | region | Green's theorem | |
| 2 | surface | Stokes' (Kelvin–Stokes) theorem | |
| 3 | solid | divergence (Gauss–Ostrogradsky) theorem |
Closed versus exact: the Poincaré lemma and the angle form
Theorem— Theorem 5 (dθ is closed but not exact)
The form on is closed, but it is not for any smooth function on .
Proof
Closed. With and , , and
Not exact. If , Stokes' theorem for the 1-cube , whose boundary is zero, would give . But the example above computed .
∎
The Lean proof of non-exactness is the same argument in calculus form. If , then has , so is constant, while . Whether closed forms are exact depends on the shape of the domain:
Theorem— Theorem 6 (Poincaré lemma)
Let be open and star-shaped with respect to (for every , the segment from to lies in ). Then every closed -form on with is exact. We prove the case .
Proof
Let be closed, so for all . Define by integrating along the segment from to :
The integrand is smooth in , so we may differentiate under the integral sign:
using closedness. The integrand is exactly , so the integral is . Hence .
∎
For general , the same idea gives a linear operator with on forms of degree . If , then (Spivak 1965, Theorem 4-11). The punctured plane is not star-shaped, and Theorem 5 shows that the conclusion fails there.
Theorem— Corollary 7 (first de Rham cohomology of the punctured plane)
, spanned by the class of . A closed 1-form is exact if and only if .
Proof
by Theorem 5. Let be closed and . Then is closed with . We show is exact. On the slit plane minus the closed negative -axis, which is star-shaped (with respect to ), the Poincaré lemma gives . On minus the closed positive -axis, it gives . On , the union of the open upper and lower half-planes, , so is a constant on each half-plane: on the upper one and on the lower one. Split the unit circle at , , and . The two arcs touching lie in and the two touching lie in , so integrating or arc by arc gives
So , and on , on is a well-defined smooth function on with . Hence .
∎
De Rham's theorem (1931) generalises this. For any smooth manifold , is isomorphic to the singular cohomology , a purely topological invariant. Calculus detects holes: of the plane with points removed is , of the torus , of the sphere .
Differential forms in Lean and Mathlib
Mathlib represents a differential -form on a normed space as a map into continuous alternating maps, and defines the exterior derivative extDeriv. It proves and that commutes with pullback, and it has the exterior algebra and the divergence theorem on boxes. It does not (yet) have integration of forms over manifolds or the general Stokes theorem.
First the wedge product of two 1-forms, its antisymmetry, and as signed area, alongside Mathlib's exterior algebra:
/-- The **wedge product** of two 1-forms (linear functionals) `α, β` on a real vector space: the
alternating bilinear form `(α ∧ β)(u, v) = α(u) β(v) - α(v) β(u)`. -/
def wedge {E : Type*} [AddCommGroup E] [Module ℝ E] (α β : E →ₗ[ℝ] ℝ) (u v : E) : ℝ :=
α u * β v - α v * β u/-- **The wedge product of 1-forms is anticommutative**: `α ∧ β = -(β ∧ α)`. (For a `k`-form and an
`l`-form the rule is `α ∧ β = (-1)^(kl) β ∧ α`.) -/
theorem wedge_antisymm {E : Type*} [AddCommGroup E] [Module ℝ E] (α β : E →ₗ[ℝ] ℝ) (u v : E) :
wedge α β u v = -wedge β α u v := by
unfold wedge
ring/-- Consequently `α ∧ α = 0` for every 1-form `α`. -/
theorem wedge_self {E : Type*} [AddCommGroup E] [Module ℝ E] (α : E →ₗ[ℝ] ℝ) (u v : E) :
wedge α α u v = 0 := by
unfold wedge
ring/-- `α ∧ β` is **alternating**: it vanishes when both arguments are equal. -/
theorem wedge_alternating {E : Type*} [AddCommGroup E] [Module ℝ E] (α β : E →ₗ[ℝ] ℝ) (u : E) :
wedge α β u u = 0 := by
unfold wedge
ring/-- On `ℝ²`, `dx ∧ dy` evaluated on two vectors is the determinant `u₁ v₂ - u₂ v₁`: the **signed
area** of the parallelogram they span. Here `dx` and `dy` are the coordinate projections. -/
theorem dx_wedge_dy (u v : ℝ × ℝ) :
wedge (LinearMap.fst ℝ ℝ ℝ) (LinearMap.snd ℝ ℝ ℝ) u v = u.1 * v.2 - u.2 * v.1 := by
simp only [wedge, LinearMap.fst_apply, LinearMap.snd_apply]
ring/-- In Mathlib's **exterior algebra** of a module `M`, vectors anticommute: `x ∧ y + y ∧ x = 0`.
This applies Mathlib's `ExteriorAlgebra.ι_add_mul_swap`. -/
theorem exterior_anticomm {M : Type*} [AddCommGroup M] [Module ℝ M] (x y : M) :
ExteriorAlgebra.ι ℝ x * ExteriorAlgebra.ι ℝ y + ExteriorAlgebra.ι ℝ y * ExteriorAlgebra.ι ℝ x
= 0 :=
ExteriorAlgebra.ι_add_mul_swap x yThen , both as the symmetry of mixed partials (the heart of Theorem 2(b)) and as Mathlib's general theorem about extDeriv:
/-- **Mixed partial derivatives commute** for a `C²` function on `ℝ²` (Schwarz–Clairaut). In
coordinates `d(df) = (∂²f/∂x∂y - ∂²f/∂y∂x) dx ∧ dy`, so this is `d(df) = 0` for functions. This
applies Mathlib's `ContDiffAt.isSymmSndFDerivAt`. -/
theorem mixed_partials_commute (f : ℝ × ℝ → ℝ) (p : ℝ × ℝ) (hf : ContDiffAt ℝ 2 f p) :
fderiv ℝ (fderiv ℝ f) p (1, 0) (0, 1) = fderiv ℝ (fderiv ℝ f) p (0, 1) (1, 0) :=
hf.isSymmSndFDerivAt (by simp) _ _/-- **`d ∘ d = 0`** for every `C²` differential `n`-form `ω` on a normed space (with values in a
normed space). Mathlib represents an `n`-form as a map `E → E [⋀^Fin n]→L[ℝ] F` to continuous
alternating `n`-linear maps. This applies Mathlib's `extDeriv_extDeriv`. -/
theorem d_squared_zero {E F : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
[NormedAddCommGroup F] [NormedSpace ℝ F] {n : ℕ} (ω : E → E [⋀^Fin n]→L[ℝ] F)
(hω : ContDiff ℝ 2 ω) : extDeriv (extDeriv ω) = 0 :=
extDeriv_extDeriv hω (by simp)Stokes' theorem in dimension one (the fundamental theorem of calculus) and on a rectangle (Green's theorem in divergence form), cited from Mathlib:
/-- **Stokes' theorem on an interval is the fundamental theorem of calculus**: `∫_[a,b] df =
f(b) - f(a)`, the integral of `df` over `[a, b]` equals the "integral" of `f` over the oriented
boundary `{b} - {a}`. This applies Mathlib's `intervalIntegral.integral_eq_sub_of_hasDerivAt`. -/
theorem stokes_interval (f f' : ℝ → ℝ) (a b : ℝ)
(hderiv : ∀ x ∈ Set.uIcc a b, HasDerivAt f (f' x) x)
(hint : IntervalIntegrable f' MeasureTheory.volume a b) :
∫ x in a..b, f' x = f b - f a :=
intervalIntegral.integral_eq_sub_of_hasDerivAt hderiv hint/-- **Stokes' theorem on a rectangle** (Green's theorem in divergence form): for the 1-form
`ω = f dy - g dx`, `dω = (∂f/∂x + ∂g/∂y) dx ∧ dy`, and `∬_R dω = ∮_∂R ω` becomes the identity
below — the integral of `f' (1, 0) + g' (0, 1)` over the rectangle equals the boundary terms. This
applies Mathlib's `MeasureTheory.integral2_divergence_prod_of_hasFDerivAt`. -/
theorem stokes_rectangle (f g : ℝ × ℝ → ℝ) (f' g' : ℝ × ℝ → ℝ × ℝ →L[ℝ] ℝ)
(a₁ a₂ b₁ b₂ : ℝ)
(Hcf : ContinuousOn f (Set.uIcc a₁ b₁ ×ˢ Set.uIcc a₂ b₂))
(Hcg : ContinuousOn g (Set.uIcc a₁ b₁ ×ˢ Set.uIcc a₂ b₂))
(Hdf : ∀ x ∈ Set.Ioo (min a₁ b₁) (max a₁ b₁) ×ˢ Set.Ioo (min a₂ b₂) (max a₂ b₂),
HasFDerivAt f (f' x) x)
(Hdg : ∀ x ∈ Set.Ioo (min a₁ b₁) (max a₁ b₁) ×ˢ Set.Ioo (min a₂ b₂) (max a₂ b₂),
HasFDerivAt g (g' x) x)
(Hi : MeasureTheory.IntegrableOn (fun x => f' x (1, 0) + g' x (0, 1))
(Set.uIcc a₁ b₁ ×ˢ Set.uIcc a₂ b₂)) :
(∫ x in a₁..b₁, ∫ y in a₂..b₂, f' (x, y) (1, 0) + g' (x, y) (0, 1)) =
(((∫ x in a₁..b₁, g (x, b₂)) - ∫ x in a₁..b₁, g (x, a₂)) + ∫ y in a₂..b₂, f (b₁, y)) -
∫ y in a₂..b₂, f (a₁, y) :=
MeasureTheory.integral2_divergence_prod_of_hasFDerivAt f g f' g' a₁ a₂ b₁ b₂ Hcf Hcg Hdf Hdg HiFinally the main independent result, Theorem 5. The angle form is defined pointwise as a continuous linear functional; it is closed; it pulls back to on the circle, so its integral is ; and it is not the derivative of any function on the punctured plane:
/-- The **angle form** `dθ = (x dy - y dx) / (x² + y²)` on `ℝ² ∖ {0}`: at each point `p = (x, y)`,
a linear functional on vectors. (It is not the differential of a global function `θ` — that is
the point of `dTheta_not_exact`.) -/
noncomputable def dTheta (p : ℝ × ℝ) : ℝ × ℝ →L[ℝ] ℝ :=
(p.1 / (p.1 ^ 2 + p.2 ^ 2)) • ContinuousLinearMap.snd ℝ ℝ ℝ -
(p.2 / (p.1 ^ 2 + p.2 ^ 2)) • ContinuousLinearMap.fst ℝ ℝ ℝ/-- **`dθ` is closed.** Writing `dθ = P dx + Q dy` with `P = -y/(x² + y²)` and `Q = x/(x² + y²)`,
we have `dθ' = (∂Q/∂x - ∂P/∂y) dx ∧ dy`, and both partial derivatives equal
`(y² - x²)/(x² + y²)²` away from the origin. -/
theorem dTheta_closed (x y : ℝ) (h : x ^ 2 + y ^ 2 ≠ 0) :
HasDerivAt (fun x => x / (x ^ 2 + y ^ 2)) ((y ^ 2 - x ^ 2) / (x ^ 2 + y ^ 2) ^ 2) x ∧
HasDerivAt (fun y => -y / (x ^ 2 + y ^ 2)) ((y ^ 2 - x ^ 2) / (x ^ 2 + y ^ 2) ^ 2) y := by
constructor
· have hd : HasDerivAt (fun x => x ^ 2 + y ^ 2) (2 * x) x := by
simpa using (hasDerivAt_pow 2 x).add_const (y ^ 2)
convert (hasDerivAt_id' x).div hd h using 1
field_simp
ring
· have hd : HasDerivAt (fun y => x ^ 2 + y ^ 2) (2 * y) y := by
simpa using (hasDerivAt_pow 2 y).const_add (x ^ 2)
convert (hasDerivAt_neg y).div hd h using 1
field_simp
ring/-- The unit circle `γ(t) = (cos t, sin t)` has velocity `γ'(t) = (-sin t, cos t)`. -/
theorem circle_path (t : ℝ) : HasDerivAt (fun t => (cos t, sin t)) (-sin t, cos t) t :=
(hasDerivAt_cos t).prodMk (hasDerivAt_sin t)/-- **The pullback of `dθ` to the circle is `dt`**: `dθ_{γ(t)}(γ'(t)) = cos t · cos t - sin t · (-sin t)
= 1`, using `cos² t + sin² t = 1`. -/
theorem dTheta_on_circle (t : ℝ) : dTheta (cos t, sin t) (-sin t, cos t) = 1 := by
have h := cos_sq_add_sin_sq t
simp only [dTheta, h, div_one]
simp
linear_combination h/-- **`∮ dθ = 2π` around the unit circle**: pull back along `γ(t) = (cos t, sin t)` and integrate
the constant `1` over `[0, 2π]`. -/
theorem dTheta_circle_integral :
∫ t in (0 : ℝ)..2 * π, dTheta (cos t, sin t) (-sin t, cos t) = 2 * π := by
simp only [dTheta_on_circle, intervalIntegral.integral_const, smul_eq_mul, mul_one, sub_zero]/-- **`dθ` is closed but not exact.** There is no differentiable function `f` on the punctured plane
with `df = dθ`. If there were, `g(t) = f(cos t, sin t)` would satisfy `g'(t) = dθ(γ'(t)) = 1` by
the chain rule, so `g(t) - t` would be constant; but `g(2π) = g(0)` because the circle closes up,
which would force `2π = 0`. -/
theorem dTheta_not_exact :
¬ ∃ f : ℝ × ℝ → ℝ, ∀ p : ℝ × ℝ, p ≠ 0 → HasFDerivAt f (dTheta p) p := by
rintro ⟨f, hf⟩
have hne : ∀ t : ℝ, ((cos t, sin t) : ℝ × ℝ) ≠ 0 := by
intro t h0
have h1 : cos t = 0 := congrArg Prod.fst h0
have h2 : sin t = 0 := congrArg Prod.snd h0
have := cos_sq_add_sin_sq t
rw [h1, h2] at this
norm_num at this
-- `g(t) - t` has derivative `0` everywhere.
have hderiv : ∀ t : ℝ,
HasDerivAt (fun t => f (cos t, sin t) - t) 0 t := by
intro t
have hg := (hf _ (hne t)).comp_hasDerivAt t (circle_path t)
rw [dTheta_on_circle] at hg
have h2 := hg.sub (hasDerivAt_id' t)
rw [sub_self] at h2
exact h2
have hconst := is_const_of_deriv_eq_zero
(fun t => (hderiv t).differentiableAt) (fun t => (hderiv t).deriv) (2 * π) 0
simp only [cos_two_pi, sin_two_pi, cos_zero, sin_zero, sub_zero] at hconst
have : (2 : ℝ) * π = 0 := by linarith
exact (mul_ne_zero two_ne_zero pi_ne_zero) thisWhat is and is not formalised. Independent: the algebra of the wedge product of two 1-forms, the closedness of (as an equality of partial derivatives), its circle integral and its non-exactness. Cited from Mathlib: anticommutativity in the exterior algebra, symmetry of second derivatives, , the fundamental theorem of calculus and the divergence theorem on rectangles. Not formalised: Theorem 3 for general chains, Theorem 4, the Poincaré lemma and Corollary 7. In dTheta_not_exact, is only assumed differentiable on the punctured plane, which makes the theorem stronger than Theorem 5.
Exterior calculus and line integrals by computer
The first program implements forms on as dictionaries of SymPy coefficients, with the wedge product and . It verifies , graded commutativity and the Leibniz rule for forms with arbitrary coefficient functions, and it displays grad, curl and div inside . It also checks Stokes' theorem exactly on the unit cube for one vector field.
"""Exterior calculus on R^3, symbolically.
A differential form on R^3 is stored as a dictionary from increasing index
tuples to SymPy expressions: {(0,): P, (1,): Q, (2,): R} is P dx + Q dy + R dz.
We implement the wedge product (with the sign of the sorting permutation) and
the exterior derivative d, and let SymPy check, for forms with arbitrary
smooth coefficient functions: d(d w) = 0 in every degree, the graded rule
a ^ b = (-1)^(kl) b ^ a, the Leibniz rule for d, and the dictionary between
d and grad, curl, div (so curl grad = 0 and div curl = 0 are d d = 0). Finally
we check Stokes' theorem (the divergence theorem) exactly on the unit cube for
one vector field. Evidence: symbolic verification, relying on SymPy's
equality of mixed partial derivatives.
"""
import re
from itertools import product
import sympy
X = sympy.symbols("x y z")
NAMES = ("dx", "dy", "dz")
def sort_sign(indices):
"""(sign, sorted tuple) of a tuple of indices; sign 0 if one repeats."""
if len(set(indices)) < len(indices):
return 0, ()
sign, idx = 1, list(indices)
for i in range(len(idx)):
for j in range(len(idx) - 1 - i):
if idx[j] > idx[j + 1]:
idx[j], idx[j + 1] = idx[j + 1], idx[j]
sign = -sign
return sign, tuple(idx)
def clean(form):
"""Drop zero coefficients after expanding."""
out = {}
for key, c in form.items():
c = sympy.expand(c)
if c != 0:
out[key] = c
return out
def add(*forms):
"""Sum of forms."""
out = {}
for f in forms:
for key, c in f.items():
out[key] = out.get(key, 0) + c
return clean(out)
def scale(c, form):
"""Multiply a form by a function or number."""
return clean({key: c * v for key, v in form.items()})
def wedge(a, b):
"""The wedge product of two forms."""
out = {}
for (ka, ca), (kb, cb) in product(a.items(), b.items()):
sign, key = sort_sign(ka + kb)
if sign:
out[key] = out.get(key, 0) + sign * ca * cb
return clean(out)
def d(form):
"""The exterior derivative: d(c dx_I) = sum_i (dc/dx_i) dx_i ^ dx_I."""
out = {}
for key, c in form.items():
for i, xi in enumerate(X):
sign, new = sort_sign((i,) + key)
if sign:
out[new] = out.get(new, 0) + sign * sympy.diff(c, xi)
return clean(out)
def generic(degree, name):
"""A k-form whose coefficients are arbitrary functions of x, y, z."""
keys = [k for k in product(range(3), repeat=degree) if list(k) == sorted(set(k))]
return {k: sympy.Function(f"{name}{''.join(map(str, k))}")(*X) for k in keys}
def short(expr):
"""Write Derivative(f(x, y, z), x) as f_x and f(x, y, z) as f."""
text = str(expr)
text = re.sub(r"Derivative\((\w+)\(x, y, z\), (\w)\)", r"\1_\2", text)
return re.sub(r"(\w+)\(x, y, z\)", r"\1", text)
def show(form):
"""Readable text for a form."""
if not form:
return "0"
parts = []
for key in sorted(form, key=lambda k: (len(k), k)):
basis = "^".join(NAMES[i] for i in key)
parts.append(f"({short(form[key])}){' ' + basis if basis else ''}")
return " + ".join(parts)
def main():
print(f"Exterior calculus on R^3 (SymPy {sympy.__version__})")
for k in range(3):
w = generic(k, "w")
print(f" d(d w) = {show(d(d(w)))} for a general {k}-form w")
a, b, c = generic(1, "a"), generic(1, "b"), generic(2, "c")
print(" a^b + b^a = 0 for 1-forms:", add(wedge(a, b), wedge(b, a)) == {})
print(" a^c - c^a = 0 for a 1-form a and a 2-form c:",
add(wedge(a, c), scale(-1, wedge(c, a))) == {})
leibniz = add(d(wedge(a, b)), scale(-1, wedge(d(a), b)), wedge(a, d(b)))
print(" d(a^b) = da^b - a^db for 1-forms:", leibniz == {})
print()
f = sympy.Function("f")(*X)
P, Q, R = (sympy.Function(n)(*X) for n in "PQR")
A, B, C = (sympy.Function(n)(*X) for n in "ABC")
print("Vector calculus inside d:")
print(" d f =", show(d({(): f})), " (grad)")
curl = d({(0,): P, (1,): Q, (2,): R})
print(" d(P dx + Q dy + R dz): dy^dz:", short(curl[(1, 2)]),
" dz^dx:", short(-curl[(0, 2)]))
print(" dx^dy:", short(curl[(0, 1)]), " (curl)")
div = d({(1, 2): A, (0, 2): -B, (0, 1): C})
print(" d(A dy^dz + B dz^dx + C dx^dy) =", show(div), " (div)")
print(" so curl(grad f) = 0 and div(curl F) = 0 are both d(d w) = 0")
print()
x, y, z = X
field = {(1, 2): x * y ** 2, (0, 2): -(y * z), (0, 1): x * z ** 2}
volume = sympy.integrate(d(field)[(0, 1, 2)], (x, 0, 1), (y, 0, 1),
(z, 0, 1))
P, Q, R = field[(1, 2)], -field[(0, 2)], field[(0, 1)]
flux = sum(
sympy.integrate(F_comp.subs(v, 1) - F_comp.subs(v, 0), *lim)
for F_comp, v, lim in [(P, x, [(y, 0, 1), (z, 0, 1)]),
(Q, y, [(x, 0, 1), (z, 0, 1)]),
(R, z, [(x, 0, 1), (y, 0, 1)])])
print("Stokes on the unit cube for F = (x y^2, y z, x z^2):")
print(f" integral of d(omega) = {volume}, flux through boundary = {flux}")
print()
print("Epistemic status: symbolic verification. The identities hold for")
print("arbitrary coefficient functions because SymPy treats mixed partials")
print("as equal (true for C^2 functions); the cube check is one example of")
print("Stokes' theorem, which is proved in the lesson, not here.")
if __name__ == "__main__":
main()The second program integrates 1-forms numerically along paths by pulling them back to . An exact form gives around every loop. The angle form gives times the winding number, and it gives different answers along two paths with the same endpoints — the computational face of Theorem 5.
"""Line integrals of 1-forms: closed, exact, and the angle form.
We integrate 1-forms P dx + Q dy along sampled paths by pulling them back:
the integral of w over gamma is the integral of P(gamma) x' + Q(gamma) y' dt,
computed with the midpoint rule and exact derivatives of the paths. An exact
form df integrates to f(end) - f(start) along every path, so to 0 around
every loop. The angle form d theta = (x dy - y dx)/(x^2 + y^2) is closed, yet
its integral around a loop is 2 pi times the winding number about the origin,
and from (1, 0) to (-1, 0) it gives +pi along the upper half circle and -pi
along the lower one: path dependence, so d theta is not exact on the punctured
plane. A non-closed form, x dy - y dx, measures twice the enclosed area, as
Green's theorem says. Evidence: numerical.
"""
import math
STEPS = 4000
def line_integral(form, path, velocity, steps=STEPS):
"""Midpoint rule for the integral of form = (P, Q) along a path on [0, 1]."""
total = 0.0
for k in range(steps):
t = (k + 0.5) / steps
x, y = path(t)
dx, dy = velocity(t)
p, q = form(x, y)
total += (p * dx + q * dy) / steps
return total
def dtheta(x, y):
"""The angle form (-y dx + x dy) / (x^2 + y^2)."""
r2 = x * x + y * y
return -y / r2, x / r2
def exact_form(x, y):
"""d f for f(x, y) = x^2 y + sin(x y)."""
return 2 * x * y + y * math.cos(x * y), x * x + x * math.cos(x * y)
def area_form(x, y):
"""x dy - y dx, with d(x dy - y dx) = 2 dx ^ dy."""
return -y, x
def circle(cx, cy, r, turns=1):
"""Loop around a circle (path, velocity), parametrised on [0, 1]."""
w = 2 * math.pi * turns
def path(t):
return cx + r * math.cos(w * t), cy + r * math.sin(w * t)
def velocity(t):
return -r * w * math.sin(w * t), r * w * math.cos(w * t)
return path, velocity
def half_circle(upper=True):
"""From (1, 0) to (-1, 0) along the upper or lower unit half circle."""
s = 1 if upper else -1
def path(t):
return math.cos(math.pi * t), s * math.sin(math.pi * t)
def velocity(t):
return -math.pi * math.sin(math.pi * t), s * math.pi * math.cos(math.pi * t)
return path, velocity
def square_loop():
"""The boundary of the square [-1, 2] x [-1, 2], anticlockwise."""
corners = [(-1, -1), (2, -1), (2, 2), (-1, 2), (-1, -1)]
def side(t):
k = min(int(4 * t), 3)
return k, 4 * t - k
def path(t):
k, u = side(t)
(x0, y0), (x1, y1) = corners[k], corners[k + 1]
return x0 + u * (x1 - x0), y0 + u * (y1 - y0)
def velocity(t):
k, _ = side(t)
(x0, y0), (x1, y1) = corners[k], corners[k + 1]
return 4 * (x1 - x0), 4 * (y1 - y0)
return path, velocity
def main():
loops = [
("unit circle", circle(0, 0, 1)),
("circle twice round", circle(0, 0, 1, turns=2)),
("circle centre (3, 0)", circle(3, 0, 1)),
("square [-1, 2]^2", square_loop()),
]
print("Loop d theta / 2 pi exact df x dy - y dx")
for name, (p, v) in loops:
a = line_integral(dtheta, p, v) / (2 * math.pi)
b = line_integral(exact_form, p, v)
c = line_integral(area_form, p, v)
a, b, c = (round(val, 6) + 0.0 for val in (a, b, c))
print(f" {name:<22} {a:12.6f} {b:12.6f} {c:12.6f}")
print(" (x dy - y dx gives twice the area swept: 2 pi, 2 x 2 pi for the")
print(" doubled loop, 2 pi, and 2 x 9 for the square)")
print()
up = line_integral(dtheta, *half_circle(True))
down = line_integral(dtheta, *half_circle(False))
print("From (1, 0) to (-1, 0):")
print(f" d theta along the upper half circle: {up / math.pi:9.6f} pi")
print(f" d theta along the lower half circle: {down / math.pi:9.6f} pi")
print(" The integral depends on the path, so d theta = df is impossible:")
print(" an exact form would give f(-1, 0) - f(1, 0) both times.")
print()
print("Epistemic status: numerical (4000-point midpoint rule on each path).")
print("That d theta is closed but not exact, and Green's and Stokes'")
print("theorems, are proved in the lesson (and the non-exactness in Lean).")
if __name__ == "__main__":
main()The symbolic checks hold for all coefficient functions, but only because SymPy treats mixed partial derivatives as equal, which is true for functions. The numerical integrals are evidence on particular paths. The theorems are proved above.
Explore: circulation, curl and the hole
The first field is the rotation , the vector field of . Drag the loop anywhere: the circulation always equals , as Green's theorem says.
Circulation equals the integral of curl
Move the loop through the field: how much does the field circulate around it, flow out of it, and turn along it?
F(x, y) = (−y, x)
Drag the gold centre (or click anywhere) to move the loop. With the keyboard, focus the centre and use the arrow keys.
Turns so far: 0.09
- Circulation
- ∮ F·dr ≈ 14.1372 | ∬ curl F dA ≈ 14.1372
- Flux out
- ∮ F·n ds ≈ 0 | ∬ div F dA ≈ 0
- At the centre
- curl F ≈ 2, div F ≈ 0, πr² ≈ 7.069
- Index
- 1
All values are numerical approximations (sums around the loop and over the disc).
Green’s theorem checks out: circulation = total curl inside, and flux = total divergence inside (up to numerical error).
Index 1 ≠ 0: walking once around the loop, the arrow makes 1 net full turns (negative means clockwise). A non-zero index forces the field to vanish somewhere inside the loop.
The second field is the vortex , the field of . Its curl is zero wherever it is defined. Move the loop so that it does not enclose the origin: the circulation is . Now let it enclose the origin: the circulation jumps to , while over the region away from the singularity is still . Green's theorem does not apply, because the field is undefined at a point inside — and that defect is exactly the non-zero class .
A vortex: circulation without curl
Move the loop through the field: how much does the field circulate around it, flow out of it, and turn along it?
F(x, y) = (−y/(x² + y²), x/(x² + y²))
Drag the gold centre (or click anywhere) to move the loop. With the keyboard, focus the centre and use the arrow keys.
Turns so far: 0.09
- Circulation
- ∮ F·dr ≈ 6.2832 | ∬ curl F dA ≈ −0.0322
- Flux out
- ∮ F·n ds ≈ 0 | ∬ div F dA ≈ 0.1043
- At the centre
- curl F ≈ 0, div F ≈ 0, πr² ≈ 8.042
- Index
- 1
All values are numerical approximations (sums around the loop and over the disc).
The two sides differ: the field must fail to be smooth (or be undefined) somewhere inside the loop, so Green’s theorem does not apply to this loop.
Index 1 ≠ 0: walking once around the loop, the arrow makes 1 net full turns (negative means clockwise). A field that is continuous on the whole disc would have to vanish inside; this one is not (see above), and the point where it breaks down carries the index instead.
Exercises
1. Differential forms and Stokes' theorem
Warm-upHumanEvaluate the 2-form on the pair of vectors , , in that order.
2. Differential forms and Stokes' theorem
Warm-upHumanWhich of these forms on are equal to ? (Choose all that apply.)
3. Differential forms and Stokes' theorem
CoreHumanCompute on .
4. Differential forms and Stokes' theorem
CoreHumanLet be the rectangle with its boundary oriented anticlockwise. Use Stokes' theorem to compute .
5. Differential forms and Stokes' theorem
CoreHumanGreen's theorem is the general Stokes theorem with which choice of and ?
6. Differential forms and Stokes' theorem
CoreHumanAway from the -axis, . Why does this not show that is exact on ?
7. Differential forms and Stokes' theorem
CoreFormalWhich Lean statement correctly says that is not exact on the punctured plane? (dTheta p is the linear functional at the point p.)
8. Differential forms and Stokes' theorem
CoreComputationalA 1-form on is a triple meaning , and a 2-form is a triple meaning . Write wedge(a, b) returning the 2-form as such a triple. What familiar operation do you get?
9. Differential forms and Stokes' theorem
StretchHumanOn which of these open sets is every closed 1-form exact? (Choose all that apply.)
Common misconceptions
Misconception
" is exact, because it is written as of something." The notation is a convenient name, not a theorem. There is no continuous function on whose differential is : any choice of polar angle jumps by somewhere. Locally, on a slit plane, is exact — exactness is a global question.
Misconception
"The wedge product is commutative." For 1-forms it is anticommutative: and . In general , so it is commutative only when is even, for example a 1-form and a 2-form, or anything with a function.
Misconception
"Closed forms are always exact." Exact implies closed everywhere. Closed implies exact on star-shaped (more generally, contractible) domains, but not in general. The failure is measured by de Rham cohomology, a topological invariant: on the punctured plane is the basic example.
Misconception
" is the gradient vector." is a 1-form — at each point a linear functional that eats a vector and returns the directional derivative . Turning it into a vector needs an inner product: in other coordinates, or on a curved surface, the components of and of differ. Forms need no metric. That is why Stokes' theorem holds in any coordinates.
Misconception
"Stokes' theorem holds for any region and any form." It needs a compact oriented region (with the induced orientation on the boundary) and a form that is smooth on all of it. Drop smoothness at one point — on the unit disc — and "". The theorem is not wrong; its hypothesis fails at the origin.
Many ways of seeing
Topology— Calculus detects holes: de Rham's theorem
The de Rham complex is a cochain complex because , and its cohomology is defined by calculus alone. De Rham's theorem says it equals the singular cohomology , defined by triangulating and counting. The pairing is integration: a closed -form integrated over -cycles, which by Stokes depends only on cohomology and homology classes. So is the -th Betti number. Homotopy invariance and the Mayer–Vietoris sequence make these groups computable. The proof of Corollary 7 is a small Mayer–Vietoris argument. See algebraic topology and the winding numbers of the fundamental group: is the degree of .
Geometry— Orientation, volume and symplectic forms
On an oriented -manifold a nowhere-vanishing -form is a volume form, and integration of -forms is how manifolds are measured. A Riemannian metric gives a canonical one, ; on a surface it is the of Gauss–Bonnet. A symplectic form, a closed non-degenerate 2-form such as on phase space, is the geometry of classical mechanics. Hamiltonian flows preserve it, hence also its top power , the phase-space volume (Liouville's theorem); see symplectic geometry. Curvature itself becomes a 2-form, and Chern's proof of the higher-dimensional Gauss–Bonnet theorem integrates a polynomial in curvature forms; see curves and surfaces.
Analysis— Harmonic forms and the Hodge theorem
Given a Riemannian metric, there is a Hodge star , an adjoint , and a Laplacian on forms. The Hodge theorem (Hodge, 1930s; made rigorous with elliptic PDE methods by Weyl, Kodaira and others) says that on a compact oriented Riemannian manifold every de Rham class contains exactly one harmonic form (). Hence is the space of harmonic -forms, a finite-dimensional solution space of an elliptic PDE. For the flat torus , and are harmonic and span . Analysis, geometry and topology meet here; see Hodge theory.
Physics— Maxwell's equations in two lines
In spacetime , the electric and magnetic fields combine into one 2-form, the Faraday form . Maxwell's four equations become
with the Hodge star of the Minkowski metric and the current 3-form (in suitable units). The first packages Faraday's law and "no magnetic monopoles"; the second, Gauss's and Ampère's laws. Charge conservation is . On a contractible region, gives a potential, , by the Poincaré lemma. Around a solenoid or a hypothetical monopole the region has topology, and need not be exact. Physically this shows up in the Aharonov–Bohm effect and in Dirac's argument (1931) that magnetic monopoles would force electric charge to be quantised — a physical argument whose mathematics is the cohomology class of . See relativity.
Algebra— The exterior algebra
Pointwise, forms live in the exterior algebra , the quotient of the tensor algebra by . It is graded-commutative, with and total dimension . Its top piece is one-dimensional, and a linear map acts on it by multiplication by — a basis-free definition of the determinant; see advanced linear algebra. Globally, is a differential graded algebra, so de Rham cohomology is a graded ring under the wedge product. On the torus, , which detects that the two circles intersect. Rational homotopy theory (Sullivan, 1977) recovers much of the homotopy type of a simply connected space from this algebra.
Category theory— Naturality
Theorem 2(c), , says that is a natural transformation. Forms are contravariant functors from smooth manifolds to vector spaces, and commutes with every pullback. Hence de Rham cohomology is a functor , and smoothly homotopic maps induce the same map on cohomology. Stokes' theorem says that integration is a natural pairing between this functor and (smooth) homology. In sheaf language, the Poincaré lemma says the de Rham complex is a resolution of the constant sheaf — the structural reason behind de Rham's theorem.
History and global context
- The integral theorems. Gauss treated special cases of the divergence theorem in his work on attraction (1813). Mikhail Ostrogradsky, in Paris and later St Petersburg, proved it in general (1826, published 1831). George Green, a largely self-taught miller from Nottingham, published his theorem in an essay printed by subscription in 1828. William Thomson (Lord Kelvin) stated the theorem now called Stokes' in a letter to George Gabriel Stokes in 1850, and Stokes set it as a question in the Cambridge Smith's Prize examination of 1854.
- The algebra. Hermann Grassmann's Ausdehnungslehre (1844) introduced the exterior algebra, decades ahead of its time and long neglected.
- Forms. Henri Poincaré used integral invariants in celestial mechanics (1890s) and stated the lemma now named after him. Élie Cartan introduced differential forms with the exterior derivative in 1899 and made them a working tool in geometry and Lie theory. Vito Volterra worked on related "functions of lines" in the 1880s.
- Cohomology. Georges de Rham proved his theorem in his 1931 thesis in Paris, connecting Cartan's forms to Poincaré's topology. W. V. D. Hodge developed harmonic forms in the 1930s (The Theory and Applications of Harmonic Integrals, 1941). Physicists adopted forms for Maxwell's equations and gauge theory in the twentieth century.
Further reading
- Michael Spivak, Calculus on Manifolds (1965) — short and rigorous; chapters 4–5 prove Stokes' theorem as above.
- Manfredo P. do Carmo, Differential Forms and Applications (1994).
- Harold M. Edwards, Advanced Calculus: A Differential Forms Approach (1969) — forms from the start, with motivation.
- Raoul Bott and Loring W. Tu, Differential Forms in Algebraic Topology (1982) — de Rham cohomology, Mayer–Vietoris and much more.
- Vladimir I. Arnold, Mathematical Methods of Classical Mechanics (1978), chapter 7 — forms in mechanics.