Three equations that run the world
Heat a metal rod at its middle and hold its ends in ice water. How does the temperature evolve? Pluck a string on a kora in Bamako, a sitar in Varanasi or a guitar in Seville: why does it sound a note and its overtones, and nothing in between? Dip a bent wire loop into soapy water: what shape does the film take? Each question is answered by a partial differential equation (PDE) — an equation linking the rates of change of a function of several variables:
In 1807 Joseph Fourier claimed something outrageous about the first one. Every initial temperature profile, he said, even one with corners and jumps, can be written as a sum of sine waves, and each sine wave simply decays at its own rate. The leading analysts of the day, Lagrange among them, did not believe that a discontinuous function could be a sum of smooth ones. Making sense of Fourier's claim took a century and created much of modern analysis: the Riemann and Lebesgue integrals, uniform convergence, set theory (Cantor began with the uniqueness of trigonometric series), and Hilbert spaces.
Today Fourier's idea is everywhere. MP3 audio and JPEG images store a signal by its frequency content, an MRI scanner measures the Fourier transform of your body's tissue directly, and quantum mechanics computes atomic energy levels as the frequencies of a wave equation. This lesson solves the three classical equations on an interval and develops the theory of Fourier series that makes the solutions rigorous. It also proves that the solutions are unique.
Pure tones, and averages
Heat flows from hot to cold at a rate proportional to the temperature gradient (Fourier's law). In a thin rod, the heat in a small piece changes by the flux in at one end minus the flux out at the other. Dividing by and letting gives . The sign tells the story: where the temperature profile is curved upwards (, a cold dip), the temperature rises. Heat flattens bumps.
Sine waves are the natural modes. If the initial profile is , the solution keeps its shape and just shrinks: . The decay rate grows like , so wiggly components die almost instantly and the profile quickly smooths out. If the initial profile is a sum of sines, each one decays independently, because the equation is linear. So everything hinges on Fourier's claim that every reasonable profile is such a sum.
Waves keep their shape and travel. A string's displacement satisfies (Newton's law for each small piece, with tension and density , ). Any shape moving right at speed , , is a solution, and so is any shape moving left.
Harmonic functions — solutions of Laplace's equation — are steady states of heat flow. They have no bumps at all: the value at each point equals the average over any circle around it. So a harmonic function cannot have a maximum inside its domain.
Definitions
Definition— the three classical equations
For (or ) and constants : the heat equation , the wave equation , and Laplace's equation . A solution of Laplace's equation is harmonic. All three are linear: sums and multiples of solutions are solutions (the superposition principle).
A problem consists of an equation plus side conditions. On a rod we impose initial conditions — for heat, and also for waves — and boundary conditions such as the Dirichlet conditions . Following Hadamard (1902), a problem is well posed if a solution exists, is unique, and depends continuously on the data.
Definition— Fourier series
Let be -periodic and Riemann integrable on . Its Fourier coefficients are
and its Fourier series is , with partial sums . For real this is with and .
Definition— Fourier sine series on [0, L]
For integrable on , the sine coefficients are and the sine series is . It is the full Fourier series of the odd -periodic extension of .
Definition— inner product and L² norm
For complex-valued integrable functions on , put and . The functions are orthonormal: if and otherwise, and .
A function on is piecewise if it is continuously differentiable except at finitely many points, where and have one-sided limits.
Worked examples
Example— The square wave
Let : on and on . It is odd, so , and
So . At this gives Leibniz's series .
Example— The sawtooth and the triangle
For on , integration by parts gives , so . The coefficients decay like : the periodic extension jumps at . For the continuous triangle wave , and for odd (zero for even ). The coefficients decay like , one power faster, because one more derivative is continuous. Smoothness of is decay of .
Example— The heat equation with initial profile x(π − x)
On , has sine coefficients , that is for odd . So
By the second term is times the first: the profile is essentially .
Example— An ill-posed problem (Hadamard)
Pose Laplace's equation as an initial-value problem: for with and . The solution is . As the data tend to uniformly, but at the solution has size . Tiny changes in the data cause enormous changes in the solution, so the problem is not well posed — even though a solution exists and is unique. Laplace's equation wants boundary data, not initial data.
Separation of variables
We solve the heat equation on with and . (Rescaling handles any interval .)
Step 1: separated solutions. Look for . Then , so wherever these are defined. The left side depends only on and the right only on , so both equal a constant . The problem with has a non-zero solution only when , , with . (For the solutions are or combinations of , and the boundary conditions force them to vanish; for , , and , force and .) Then .
Step 2: superposition. Formally, with the sine coefficients of , so that .
Theorem— Theorem 1 (the series solves the heat equation)
Let be integrable on with sine coefficients . Then converges for , together with all its derivatives, uniformly on for each . The function is infinitely differentiable for , satisfies and , and if is continuous and piecewise with , then uniformly as .
Proof
. A derivative of the -th term is bounded by for , and . By the Weierstrass M-test every differentiated series converges uniformly, so (by the theorem on derivatives of uniform limits in real analysis) we may differentiate term by term. Each term solves the equation and the boundary conditions, so does too. For the last claim, the hypotheses give (Theorem 4 below, applied to the odd extension of , which is continuous and piecewise ). Then , which tends to uniformly by dominated convergence for series (or directly: split the sum at a large ).
∎
Theorem 1 shows the smoothing effect of the heat equation. Even a discontinuous initial profile becomes infinitely differentiable instantly. Running time backwards is the opposite. The backward heat equation multiplies the -th mode by , which explodes, so it is ill posed: you cannot un-mix milk from coffee.
The vibrating string. The same method for on with fixed ends gives , so
with the sine coefficients of and those of . The -th mode vibrates at frequency times the fundamental: the harmonic series of overtones that gives a string its timbre. Here nothing decays, so convergence requires smoother data, and on the whole line d'Alembert's formula below is cleaner.
Fourier series: Bessel, Parseval and convergence
Theorem— Theorem 2 (Bessel's inequality; best approximation)
For integrable on and every : . Hence , and in particular (the Riemann–Lebesgue lemma for square-integrable ). Moreover is the closest trigonometric polynomial of degree to in the norm.
Proof
By orthonormality, for , so is orthogonal to every trigonometric polynomial of degree . Pythagoras gives (best approximation). Taking : , and .
∎
Theorem— Theorem 3 (Parseval; stated)
For every square-integrable on , , and therefore
By Theorem 2, Parseval is equivalent to the density of trigonometric polynomials in . For continuous , density follows from Fejér's theorem: the averages converge to uniformly, because they are convolutions with the positive kernel , which concentrates at . Continuous functions are in turn dense in . Full proofs are in Stein and Shakarchi (2003), chapters 2–3, and Mathlib proves the Hilbert-space version (see the formal section).
Example— Basel from Parseval
For , for , and . Parseval gives , that is, , Euler's 1734 answer to the Basel problem.
convergence says nothing about any particular point. Pointwise convergence needs the Dirichlet kernel: substituting the coefficients into and summing the geometric series gives
with .
Theorem— Theorem 4 (Dirichlet; uniform convergence)
Let be -periodic and integrable.
(a) If is differentiable at (or merely Lipschitz near ), then .
(b) If is piecewise , then at every .
(c) If is continuous and piecewise , then , and uniformly.
Proof
(a) Since ,
Near , and , so is bounded, hence square integrable. Expand . The integral becomes a combination of Fourier coefficients of the square-integrable functions and , which tend to by the Riemann–Lebesgue lemma (Theorem 2).
(b) Split the integral into and . Since is even, . Repeat (a) on each half with in place of , using the one-sided Lipschitz bounds that piecewise provides.
(c) Integration by parts (valid because is continuous and periodic) gives . By Cauchy–Schwarz and Bessel for ,
By the M-test, converges uniformly to some continuous , and by (a) .
∎
The Gibbs phenomenon. Near a jump, convergence cannot be uniform: a uniform limit of continuous functions is continuous. But the failure has a precise, universal size. For the square wave, (with non-zero terms) has derivative . So its first maximum to the right of is at , where, with ,
because the middle sum is a midpoint Riemann sum. The partial sums overshoot the value by about of the jump , ever closer to the discontinuity, and the overshoot never shrinks. Every jump discontinuity of a piecewise function shows the same proportional overshoot.
What can go wrong. Continuity alone is not enough for pointwise convergence. Paul du Bois-Reymond (1873) constructed a continuous periodic function whose Fourier series diverges at a point, and Kolmogorov (1926) found an integrable function whose Fourier series diverges everywhere. In the positive direction, Lennart Carleson (1966) proved that the Fourier series of every square-integrable function converges almost everywhere — one of the deepest theorems of twentieth-century analysis.
Term-by-term differentiation can fail. Differentiating term by term gives , whose terms do not even tend to . The problem is the jump of the periodic sawtooth at . For a continuous, piecewise periodic function, , so the differentiated series is the Fourier series of . That series converges to wherever Theorem 4 applies to .
d'Alembert's formula
Theorem— Theorem 5 (d'Alembert)
Every solution of on has the form with . The solution with and (, ) is unique and given by
Proof
Change to characteristic coordinates , , and write . The chain rule gives , , and
So . Then does not depend on , say , and has zero -derivative, so it is a function . Conversely, every such sum solves the equation (proved in Lean below).
For the initial values: and . Integrating the second, . Solving, and . Substituting gives the formula, and since were forced, the solution is unique.
∎
The formula shows two physical facts. Finite speed of propagation: depends only on the data in , the domain of dependence, so disturbances travel at speed exactly . And no smoothing: a corner in travels along the lines forever, unlike for the heat equation.
Maximum principles and energy
Theorem— Theorem 6 (weak maximum principle for the heat equation)
Let be continuous on the rectangle , with continuous for , , and there. Then the maximum of over is attained on the parabolic boundary : the bottom or the sides , .
Proof
Let , and for put , so that inside. Suppose attains its maximum over at a point not on , so and . In the -direction this is an interior maximum, so . In the -direction it is a maximum at an interior point or at the top edge , so . Then , a contradiction. So , hence on . Let .
∎
(Without the trick the argument fails: at an interior maximum of we only get , which is consistent with .)
Theorem— Corollary 7 (uniqueness and stability for the heat equation)
The Dirichlet problem on , , , has at most one solution continuous on . If solve it with initial data and the same boundary data, then .
Proof
solves the heat equation with zero boundary data. Apply Theorem 6 to and to .
∎
The energy method gives uniqueness by integration instead.
Theorem— Theorem 8 (energy identities)
(a) If is a smooth solution of on with , then is non-increasing. (b) If is a smooth solution of with the same boundary conditions, then is constant. Consequently both Dirichlet problems have at most one smooth solution.
Proof
(a) . The boundary term vanishes because at both ends.
(b) , because at the fixed ends.
For uniqueness, the difference of two solutions has zero initial data, so . In (a) this gives and . In (b) it gives , so is constant, hence .
∎
For Laplace's equation the corresponding facts are the mean value property and the maximum principle.
Theorem— Theorem 9 (harmonic functions)
Let be harmonic ( with ) on an open set . (a) If the closed disc lies in , then . (b) If is connected and attains its maximum at a point of , then is constant. Hence on a bounded domain, a harmonic function continuous up to the boundary attains its maximum and minimum on the boundary, and the Dirichlet problem for has at most one solution.
Proof
(a) Let . Differentiating under the integral, . By the divergence theorem this equals . So is constant, and as by continuity.
(b) The set where equals its maximum is closed in . It is also open: if , the mean value property on every small circle around forces on those circles (an average of values equals only if all are , by continuity). By connectedness it is all of . For uniqueness, apply this to the difference of two solutions and its negative.
∎
PDEs and Fourier series in Lean and Mathlib
Mathlib has a substantial theory of Fourier series on the circle (the type AddCircle T) but, at this version, no library of partial differential equations. So the PDE results below are proved directly, by computing derivatives with the chain rule. Partial derivatives are written as ordinary derivatives of one-variable slices: at is deriv (fun s => u s x) t.
The separated solutions really solve their equations, and satisfy the boundary conditions:
/-- **A separated solution of the heat equation.** `u(t, x) = e^{-k n² t} sin(n x)` satisfies
`u_t = k u_xx`: differentiating in `t` brings down `-k n²`, and differentiating twice in `x`
brings down `-n²`. Both sides equal `-k n² e^{-k n² t} sin(n x)`. -/
theorem heat_mode (k n t x : ℝ) :
deriv (fun s => exp (-k * n ^ 2 * s) * sin (n * x)) t =
k * deriv (fun y => deriv (fun z => exp (-k * n ^ 2 * t) * sin (n * z)) y) x := by
-- First and second derivatives in `x`.
have hx1 : ∀ y, HasDerivAt (fun z => exp (-k * n ^ 2 * t) * sin (n * z))
(exp (-k * n ^ 2 * t) * (cos (n * y) * n)) y := fun y =>
(((hasDerivAt_id' y).const_mul n).sin.congr_deriv (by simp)).const_mul _
have hfun : deriv (fun z => exp (-k * n ^ 2 * t) * sin (n * z)) =
fun y => exp (-k * n ^ 2 * t) * (cos (n * y) * n) := funext fun y => (hx1 y).deriv
have hx2 : HasDerivAt (fun y => exp (-k * n ^ 2 * t) * (cos (n * y) * n))
(exp (-k * n ^ 2 * t) * (-sin (n * x) * n * n)) x := by
have := ((((hasDerivAt_id' x).const_mul n).cos).mul_const n).const_mul (exp (-k * n ^ 2 * t))
convert this using 1; ring
-- The derivative in `t`.
have ht : HasDerivAt (fun s => exp (-k * n ^ 2 * s) * sin (n * x))
(exp (-k * n ^ 2 * t) * (-k * n ^ 2) * sin (n * x)) t := by
have := (((hasDerivAt_id' t).const_mul (-k * n ^ 2)).exp).mul_const (sin (n * x))
convert this using 1; ring
rw [ht.deriv, hfun, hx2.deriv]
ring/-- The heat mode `e^{-k n² t} sin(n x)` with `n` a natural number vanishes at both ends of
`[0, π]`, so it satisfies the Dirichlet boundary conditions `u(t, 0) = u(t, π) = 0` for all `t`.
(This is why the separation constants are `n²` with `n = 1, 2, 3, …`.) -/
theorem heat_mode_boundary (k t : ℝ) (n : ℕ) :
exp (-k * (n : ℝ) ^ 2 * t) * sin (n * 0) = 0 ∧
exp (-k * (n : ℝ) ^ 2 * t) * sin (n * π) = 0 := by
constructor
· simp
· rw [sin_nat_mul_pi, mul_zero]/-- **A separated solution of Laplace's equation.** `u(x, y) = e^{n y} sin(n x)` is harmonic:
`u_xx = -n² u` and `u_yy = n² u`, so `u_xx + u_yy = 0`. -/
theorem laplace_mode (n x y : ℝ) :
deriv (fun a => deriv (fun b => exp (n * y) * sin (n * b)) a) x +
deriv (fun a => deriv (fun b => exp (n * b) * sin (n * x)) a) y = 0 := by
have h1 : deriv (fun b => exp (n * y) * sin (n * b)) = fun a => exp (n * y) * (cos (n * a) * n) :=
funext fun a => ((((hasDerivAt_id' a).const_mul n).sin.congr_deriv (by simp)).const_mul _).deriv
have h2 : deriv (fun b => exp (n * b) * sin (n * x)) = fun a => exp (n * a) * n * sin (n * x) := by
funext a
have := (((hasDerivAt_id' a).const_mul n).exp).mul_const (sin (n * x))
rw [this.deriv]; ring
have h3 : HasDerivAt (fun a => exp (n * y) * (cos (n * a) * n))
(exp (n * y) * (-sin (n * x) * n * n)) x := by
have := ((((hasDerivAt_id' x).const_mul n).cos).mul_const n).const_mul (exp (n * y))
convert this using 1; ring
have h4 : HasDerivAt (fun a => exp (n * a) * n * sin (n * x))
(exp (n * y) * n * n * sin (n * x)) y := by
have := ((((hasDerivAt_id' y).const_mul n).exp).mul_const n).mul_const (sin (n * x))
convert this using 1; ring
rw [h1, h2, h3.deriv, h4.deriv]
ringd'Alembert's travelling waves solve the wave equation (the easy half of Theorem 5):
/-- **d'Alembert's travelling waves solve the wave equation.** If `f` and `g` are twice
differentiable, then `u(t, x) = f(x - c t) + g(x + c t)` satisfies `u_tt = c² u_xx`. By the chain
rule `u_t = -c f'(x - c t) + c g'(x + c t)` and `u_tt = c² f''(x - c t) + c² g''(x + c t)`, while
`u_xx = f''(x - c t) + g''(x + c t)`. (The converse — every C² solution has this form — is proved
in the lesson by changing to the characteristic coordinates `x ± c t`.) -/
theorem dalembert_solves {f g : ℝ → ℝ} (hf : Differentiable ℝ f) (hf' : Differentiable ℝ (deriv f))
(hg : Differentiable ℝ g) (hg' : Differentiable ℝ (deriv g)) (c t x : ℝ) :
deriv (fun s => deriv (fun r => f (x - c * r) + g (x + c * r)) s) t =
c ^ 2 * deriv (fun y => deriv (fun z => f (z - c * t) + g (z + c * t)) y) x := by
-- Inner derivatives.
have hin : ∀ s : ℝ, HasDerivAt (fun r => x - c * r) (-c) s := fun s => by
simpa using ((hasDerivAt_id' s).const_mul c).const_sub x
have hin' : ∀ s : ℝ, HasDerivAt (fun r => x + c * r) c s := fun s => by
simpa using ((hasDerivAt_id' s).const_mul c).const_add x
have ht1 : deriv (fun r => f (x - c * r) + g (x + c * r)) =
fun s => deriv f (x - c * s) * (-c) + deriv g (x + c * s) * c := by
funext s
exact (((hf _).hasDerivAt.comp s (hin s)).add ((hg _).hasDerivAt.comp s (hin' s))).deriv
have ht2 : HasDerivAt (fun s => deriv f (x - c * s) * (-c) + deriv g (x + c * s) * c)
(deriv (deriv f) (x - c * t) * (-c) * (-c) + deriv (deriv g) (x + c * t) * c * c) t :=
(((hf' _).hasDerivAt.comp t (hin t)).mul_const (-c)).add
(((hg' _).hasDerivAt.comp t (hin' t)).mul_const c)
have hsh : ∀ y : ℝ, HasDerivAt (fun z => z - c * t) 1 y := fun y => (hasDerivAt_id' y).sub_const _
have hsh' : ∀ y : ℝ, HasDerivAt (fun z => z + c * t) 1 y := fun y => (hasDerivAt_id' y).add_const _
have hx1 : deriv (fun z => f (z - c * t) + g (z + c * t)) =
fun y => deriv f (y - c * t) + deriv g (y + c * t) := by
funext y
have := ((hf _).hasDerivAt.comp y (hsh y)).add ((hg _).hasDerivAt.comp y (hsh' y))
rw [mul_one, mul_one] at this
exact this.deriv
have hx2 : HasDerivAt (fun y => deriv f (y - c * t) + deriv g (y + c * t))
(deriv (deriv f) (x - c * t) + deriv (deriv g) (x + c * t)) x := by
have := ((hf' _).hasDerivAt.comp x (hsh x)).add ((hg' _).hasDerivAt.comp x (hsh' x))
rw [mul_one, mul_one] at this
exact this
rw [ht1, ht2.deriv, hx1, hx2.deriv]
ringOrthogonality of the sine modes, from an explicit antiderivative and the second fundamental theorem of calculus:
/-- **Orthogonality of sines on `[0, π]`.** For distinct natural numbers `m ≠ n`,
`∫₀^π sin(m x) sin(n x) dx = 0`. Proof: `sin a sin b = (cos(a - b) - cos(a + b))/2`, which has the
antiderivative `sin((m - n)x)/(2(m - n)) - sin((m + n)x)/(2(m + n))`; this vanishes at `0` and at
`π` because `sin(k π) = 0` for every integer `k`. This is what lets us read off Fourier sine
coefficients by integrating against `sin(n x)`. -/
theorem sin_orthogonal {m n : ℕ} (hmn : m ≠ n) :
∫ x in (0 : ℝ)..π, sin (m * x) * sin (n * x) = 0 := by
have hd : (m : ℝ) - n ≠ 0 := sub_ne_zero.mpr (by exact_mod_cast hmn)
have hs : (m : ℝ) + n ≠ 0 := by
have : (0 : ℝ) < m + n := by
rcases Nat.eq_zero_or_pos m with h | h
· subst h; have : 0 < n := Nat.pos_of_ne_zero (Ne.symm hmn); simp; exact_mod_cast this
· have : (0 : ℝ) < m := by exact_mod_cast h
positivity
exact this.ne'
have hderiv : ∀ x ∈ Set.uIcc (0 : ℝ) π, HasDerivAt
(fun x => sin ((m - n) * x) / (2 * (m - n)) - sin ((m + n) * x) / (2 * (m + n)))
(sin (m * x) * sin (n * x)) x := by
intro x _
have h1 := (((hasDerivAt_id' x).const_mul ((m : ℝ) - n)).sin).div_const (2 * ((m : ℝ) - n))
have h2 := (((hasDerivAt_id' x).const_mul ((m : ℝ) + n)).sin).div_const (2 * ((m : ℝ) + n))
refine (h1.sub h2).congr_deriv ?_
rw [show ((m : ℝ) - n) * x = (m * x) - (n * x) by ring,
show ((m : ℝ) + n) * x = (m * x) + (n * x) by ring, cos_sub, cos_add]
field_simp
ring
have hcont : Continuous fun x : ℝ => sin (m * x) * sin (n * x) := by fun_prop
rw [intervalIntegral.integral_eq_sub_of_hasDerivAt hderiv (hcont.intervalIntegrable _ _)]
have hk1 : sin (((m : ℝ) - n) * π) = 0 := by
have := sin_int_mul_pi ((m : ℤ) - n); push_cast at this; exact this
have hk2 : sin (((m : ℝ) + n) * π) = 0 := by
have := sin_nat_mul_pi (m + n); push_cast at this; exact this
simp [hk1, hk2]A discrete analogue of the maximum principle (Theorem 6): the explicit finite-difference scheme, its convex-combination property when , the resulting stability for all time, and the explosion of the sawtooth mode when . These are the facts behind the computation section.
/-- One step of the explicit scheme for `u_t = k u_xx` on a grid of spacing `Δx` with time step
`Δt`: the new value at site `j` is `r u_{j-1} + (1 - 2r) u_j + r u_{j+1}`, where
`r = k Δt / Δx²`. (Sites are indexed by `ℤ`, an unbounded rod; boundary conditions are treated in
the lesson.) -/
def heatStep (r : ℝ) (u : ℤ → ℝ) : ℤ → ℝ :=
fun j => r * u (j - 1) + (1 - 2 * r) * u j + r * u (j + 1)/-- **Discrete maximum principle, one step.** If `0 ≤ r ≤ 1/2`, the new value is a *convex
combination* of three old values (the weights `r, 1 - 2r, r` are non-negative and sum to `1`), so
if all old values lie in `[m, M]`, so do all new ones. -/
theorem heatStep_bounded {r m M : ℝ} (hr0 : 0 ≤ r) (hr1 : r ≤ 1 / 2) {u : ℤ → ℝ}
(hu : ∀ j, m ≤ u j ∧ u j ≤ M) (j : ℤ) : m ≤ heatStep r u j ∧ heatStep r u j ≤ M := by
have hw : 0 ≤ 1 - 2 * r := by linarith
obtain ⟨a1, a2⟩ := hu (j - 1)
obtain ⟨b1, b2⟩ := hu j
obtain ⟨c1, c2⟩ := hu (j + 1)
simp only [heatStep]
constructor
· nlinarith [mul_le_mul_of_nonneg_left a1 hr0, mul_le_mul_of_nonneg_left b1 hw,
mul_le_mul_of_nonneg_left c1 hr0]
· nlinarith [mul_le_mul_of_nonneg_left a2 hr0, mul_le_mul_of_nonneg_left b2 hw,
mul_le_mul_of_nonneg_left c2 hr0]/-- **Discrete maximum principle, all time.** With `0 ≤ r ≤ 1/2`, after any number of steps the
solution stays between the minimum and maximum of the initial data. In particular the scheme is
*stable* in the maximum norm: errors in the data are never amplified. Induction on the number of
steps, using `heatStep_bounded`. -/
theorem heat_iterate_bounded {r m M : ℝ} (hr0 : 0 ≤ r) (hr1 : r ≤ 1 / 2) {u : ℤ → ℝ}
(hu : ∀ j, m ≤ u j ∧ u j ≤ M) (steps : ℕ) (j : ℤ) :
m ≤ (heatStep r)^[steps] u j ∧ (heatStep r)^[steps] u j ≤ M := by
induction steps generalizing j with
| zero => exact hu j
| succ s ih =>
rw [Function.iterate_succ_apply']
exact heatStep_bounded hr0 hr1 ih j/-- **Instability when `r > 1/2`.** With `r = 1`, the sawtooth `u_j = (-1)^j` is multiplied by
`1 - 4r = -3` at every step, so after `N` steps it has grown by `3^N`: rounding errors of this
shape explode. In general this mode is multiplied by `1 - 4r`, which has absolute value at most
`1` exactly when `0 ≤ r ≤ 1/2` (von Neumann's stability condition). -/
theorem heat_step_unstable (j : ℤ) :
heatStep 1 (fun i => (-1 : ℝ) ^ i) j = -3 * (-1 : ℝ) ^ j := by
simp only [heatStep]
rw [zpow_sub_one₀ (by norm_num), zpow_add_one₀ (by norm_num)]
ringMathlib's Fourier theory, for the circle with normalised Haar measure (for this is the measure of the lesson). It covers the orthonormal exponentials, convergence (the exponentials form a Hilbert basis), Parseval's identity (Theorem 3), uniform convergence for absolutely summable coefficients (the mechanism of Theorem 4(c)), and the Basel sum:
/-- **The exponentials `e_n(x) = e^{2π i n x / T}` are orthonormal in `L²` of the circle
`ℝ/Tℤ`** (with normalised Haar measure). This applies Mathlib's `orthonormal_fourier`. -/
theorem fourier_orthonormal (T : ℝ) [Fact (0 < T)] :
Orthonormal ℂ (@fourierLp T _ 2 _) :=
orthonormal_fourier/-- **Fourier series converge in `L²`.** For every square-integrable `f` on the circle,
`∑ₙ f̂(n) eₙ = f` with convergence in the `L²` norm: the exponentials form a Hilbert basis.
This applies Mathlib's `hasSum_fourier_series_L2`. -/
theorem fourier_series_l2 (T : ℝ) [Fact (0 < T)] (f : Lp ℂ 2 (@AddCircle.haarAddCircle T _)) :
HasSum (fun i => fourierCoeff f i • fourierLp 2 i) f :=
hasSum_fourier_series_L2 f/-- **Parseval's identity**: `∑ₙ |f̂(n)|² = ∫ |f|²` (normalised measure on the circle). This
applies Mathlib's `tsum_sq_fourierCoeff`. -/
theorem parseval (T : ℝ) [Fact (0 < T)] (f : Lp ℂ 2 (@AddCircle.haarAddCircle T _)) :
∑' i : ℤ, ‖fourierCoeff f i‖ ^ 2 = ∫ t, ‖f t‖ ^ 2 ∂AddCircle.haarAddCircle :=
tsum_sq_fourierCoeff f/-- **Absolutely summable coefficients give uniform convergence.** If `f` is continuous on the
circle and `∑ |f̂(n)| < ∞` (summability in `ℂ`), then the Fourier series converges to `f` in the
sup norm of `C(ℝ/Tℤ, ℂ)`, hence uniformly and at every point. This applies Mathlib's
`hasSum_fourier_series_of_summable`. -/
theorem fourier_uniform (T : ℝ) [Fact (0 < T)] (f : C(AddCircle T, ℂ))
(h : Summable (fourierCoeff f)) :
HasSum (fun i => fourierCoeff f i • fourier i) f :=
hasSum_fourier_series_of_summable h/-- **Basel problem**: `∑_{n ≥ 1} 1/n² = π²/6`. The lesson derives it from Parseval's identity for
the sawtooth `f(x) = x` on `(-π, π)`; Mathlib proves it (`hasSum_zeta_two`) via Bernoulli
polynomials and Fourier series. (The `n = 0` term is `1/0 = 0` in Lean's conventions.) -/
theorem basel : HasSum (fun n : ℕ => (1 : ℝ) / (n : ℝ) ^ 2) (π ^ 2 / 6) :=
hasSum_zeta_twoWhat is and is not formalised. Proved here: that the heat, Laplace and d'Alembert solutions satisfy their equations and boundary conditions, the orthogonality of sines on , and the discrete maximum principle with its stability threshold. Cited from Mathlib: orthonormality, convergence, Parseval, uniform convergence for summable coefficients, and Basel. Not formalised: Theorem 1's term-by-term differentiation, Dirichlet's pointwise theorem, the Gibbs constant, the converse half of d'Alembert's theorem, the continuous maximum principles, the energy identities and the mean value property.
Overshoots, sums and schemes
The first program measures the two faces of Fourier convergence. On one side, the partial sums of the square wave, evaluated exactly at their first peak , settle at rather than . On the other, Parseval's identity for the sawtooth produces , whose partial sums approach with error almost exactly .
"""Fourier series: the Gibbs overshoot and Parseval's identity, measured.
The square wave sign(sin x) has Fourier series (4/pi) * sum over odd k of
sin(kx)/k. Its partial sum with n non-zero terms, S_n, has derivative
(2/pi) sin(2nx)/sin(x), so its first maximum to the right of the jump at 0 is
at x = pi/(2n), exactly. We evaluate S_n there: the peak does not shrink to 1
but tends to (2/pi) Si(pi) = 1.17898..., an overshoot of about 9% of the jump.
At x = 0 every partial sum is 0, the average of the one-sided limits, as
Dirichlet's theorem predicts. Then Parseval's identity for the sawtooth
f(x) = x on (-pi, pi), whose sine coefficients are 2(-1)^(n+1)/n, gives
sum 1/n^2 = pi^2/6; we watch the partial sums close in, with error ~ 1/N.
Evidence: numerical (floating point, Simpson's rule for Si(pi)), with the
locations of the maxima and the Parseval formula derived exactly.
"""
import math
def square_partial(x, n):
"""S_n(x) = (4/pi) * sum_{j=1..n} sin((2j-1)x)/(2j-1)."""
return 4 / math.pi * sum(math.sin((2 * j - 1) * x) / (2 * j - 1)
for j in range(1, n + 1))
def first_peak(n):
"""Value of S_n at its first maximum to the right of 0, x = pi/(2n)."""
return square_partial(math.pi / (2 * n), n)
def sine_integral(x, steps=2000):
"""Si(x) = integral of sin(t)/t from 0 to x, by Simpson's rule."""
if steps % 2:
raise ValueError("steps must be even")
f = lambda t: 1.0 if t == 0 else math.sin(t) / t
h = x / steps
s = f(0) + f(x)
s += 4 * sum(f((2 * i - 1) * h) for i in range(1, steps // 2 + 1))
s += 2 * sum(f(2 * i * h) for i in range(1, steps // 2))
return s * h / 3
def gibbs_limit():
"""(2/pi) Si(pi), the limit of the first peaks."""
return 2 / math.pi * sine_integral(math.pi)
def sawtooth_coefficient(n):
"""b_n = (1/pi) * integral of x sin(nx) over (-pi, pi) = 2(-1)^(n+1)/n."""
return 2 * (-1) ** (n + 1) / n
def parseval_partial(N):
"""(1/4) * sum_{n<=N} b_n^2, which Parseval says tends to pi^2/6."""
return sum(sawtooth_coefficient(n) ** 2 for n in range(1, N + 1)) / 4
def main():
g = gibbs_limit()
print("Square wave sign(sin x): peak of S_n at x = pi/(2n)")
print(" n peak S_n(0) S_n(pi/2)")
for n in [1, 5, 10, 50, 200, 1000]:
print(f"{n:6d} {first_peak(n):.5f} {square_partial(0.0, n):+.1f}"
f" {square_partial(math.pi / 2, n):.5f}")
print(f"limit (2/pi) Si(pi) = {g:.5f}: overshoot {100 * (g - 1) / 2:.2f}%"
" of the jump")
print("The peak moves towards the jump but never shrinks: the convergence")
print("is pointwise, not uniform, near a discontinuity.")
print()
print("Parseval for f(x) = x on (-pi, pi): sum 1/n^2 = pi^2/6")
print(" N partial sum error N * error")
for N in [10, 100, 1000, 10000]:
err = math.pi ** 2 / 6 - parseval_partial(N)
print(f"{N:7d} {parseval_partial(N):.9f} {err:.2e} {N * err:.4f}")
print()
print("Epistemic status: numerical evidence. The peak locations and the")
print("coefficients are derived exactly; the values are floating-point")
print("and Si(pi) comes from Simpson's rule. Finitely many n cannot prove")
print("the limits; the Gibbs constant and Parseval's identity are proved")
print("in the lesson and its references.")
if __name__ == "__main__":
main()Notice that for every , the average of the one-sided limits , as Theorem 4(b) predicts. The values at converge to , slowly and with oscillation, because the coefficients only decay like . All of this is numerical evidence about finitely many . The limits are theorems.
The second program solves the heat equation twice: by the Fourier sine series of the third example, and by the explicit finite-difference scheme, which replaces and by difference quotients on a grid. With every new value is a weighted average of old ones, and the scheme obeys a discrete maximum principle — proved in Lean above. With the grid's most oscillatory mode is multiplied by about per step, and the computation explodes.
"""The heat equation on a computer: series solution versus finite differences.
We solve u_t = u_xx on [0, pi] with u = 0 at both ends and u(0, x) = x(pi - x).
Separation of variables gives the exact solution
u(t, x) = sum over odd n of (8 / (pi n^3)) exp(-n^2 t) sin(n x).
The explicit scheme replaces u_t and u_xx by difference quotients:
u_j <- r u_(j-1) + (1 - 2r) u_j + r u_(j+1), r = dt / dx^2.
For r <= 1/2 each new value is an average of old ones (discrete maximum
principle), the scheme is stable, and its error shrinks like dx^2. For
r > 1/2 the highest grid mode is multiplied by about 1 - 4r < -1 per step and
the computation explodes. Evidence: numerical; the series is summed to 200
terms (truncation error below 1e-6).
"""
import math
def exact(t, x, terms=200):
"""Fourier sine series solution for initial data x(pi - x)."""
return sum(8 / (math.pi * n ** 3) * math.exp(-n * n * t) * math.sin(n * x)
for n in range(1, 2 * terms, 2))
def step(u, r):
"""One explicit step with fixed zero boundary values u[0] = u[-1] = 0."""
new = [0.0] * len(u)
for j in range(1, len(u) - 1):
new[j] = r * u[j - 1] + (1 - 2 * r) * u[j] + r * u[j + 1]
return new
def solve(intervals, r, t_end):
"""Run the scheme to (about) t_end; return (grid, values, t, max seen)."""
dx = math.pi / intervals
dt = r * dx * dx
steps = max(1, round(t_end / dt))
xs = [j * dx for j in range(intervals + 1)]
u = [x * (math.pi - x) for x in xs]
u[-1] = 0.0
top = max(u)
for _ in range(steps):
u = step(u, r)
top = max(top, max(u))
return xs, u, steps * dt, top
def max_error(intervals, r, t_end):
"""Largest |scheme - exact| over the grid at the final time."""
xs, u, t, _ = solve(intervals, r, t_end)
return max(abs(a - exact(t, x)) for x, a in zip(xs, u))
def main():
peak0 = (math.pi / 2) ** 2
print("u_t = u_xx on [0, pi], u(0, x) = x(pi - x), compared at t = 0.5")
print(" r max error (20 intervals) largest value ever / initial max")
for r in [0.25, 0.4, 0.5, 0.6]:
_, _, _, top = solve(20, r, 0.5)
print(f" {r:4.2f} {max_error(20, r, 0.5):24.3e} {top / peak0:18.3g}")
print()
print("Refining the grid with r = 0.4 fixed (error should fall ~ dx^2):")
prev = None
for n in [10, 20, 40]:
e = max_error(n, 0.4, 0.5)
ratio = "" if prev is None else f" ratio {prev / e:.2f}"
print(f" {n:3d} intervals: max error {e:.3e}{ratio}")
prev = e
print()
print("Epistemic status: numerical experiment. The series solution and the")
print("stability threshold r = 1/2 are proved in the lesson (the discrete")
print("maximum principle is also checked in Lean); the table only shows")
print("them at work for one initial condition and a few grids.")
if __name__ == "__main__":
main()With fixed, halving divides the error by about : the scheme is second-order accurate in space. The stability condition is severe — halving forces four times as many time steps. That is why implicit schemes, which have no such restriction, are used in practice, as discussed in numerical analysis.
Explore: heat, harmonics and travelling waves
Heat smooths. The curve is the initial temperature ; the other is the first four terms of the series solution at time . Move : the higher modes, with decay rates , vanish almost at once, and the profile becomes a pure, shrinking sine.
The heat equation on [0, π]
Move the sliders and trace along the curves to read off values.
- u(0, x) = x(π − x)
- u(t, x), four terms
- u(0, x) = x(π − x): y = 2.1416
- u(t, x), four terms: y = 1.9427
Fourier series and the Gibbs overshoot. Add terms to the square-wave series. The partial sums converge at every point, but the spike next to each jump only gets narrower, never shorter: about of the jump, for ever.
Fourier series
Add sine waves one at a time to build a square, sawtooth or triangle wave.
- target wave f(x)
- partial sum with N terms
- highest peak of the partial sum
SN(x) = (4/π) NΣk=1 sin((2k − 1)x) / (2k − 1)
f(x) = 1 for 0 < x < π and −1 for −π < x < 0, repeating with period 2π.
Highest peak of the partial sum ≈ 1.1798: an overshoot of 0.1798, which is 9.0 % of the jump 2.
As N grows the overshoot does not shrink to 0: it tends to about 8.95 % of the jump, while the wiggle gets narrower and closer to the jump. This is the Gibbs phenomenon.
Travelling waves. d'Alembert's solution with initial bump and zero initial velocity splits into two half-height bumps moving apart at speed . Corners would travel just the same — there is no smoothing.
d'Alembert: u = ½φ(x − t) + ½φ(x + t)
Move the sliders and trace along the curves to read off values.
- u(t, x)
- u(t, x): y = 0.3679
Modes of a string. The -th standing wave on : points (nodes) never move, and the time period is .
Standing waves on a string
Move the sliders and trace along the curves to read off values.
- y = sin(n·x)·cos(n·t)
- y = 0.9093
Exercises
1. Partial differential equations and Fourier series
Warm-upHumanWhich function solves the heat equation ?
2. Partial differential equations and Fourier series
Warm-upHumanLet on . What is its Fourier sine coefficient ?
3. Partial differential equations and Fourier series
CoreHumanSolve on with and . What is ?
4. Partial differential equations and Fourier series
CoreHumanLet be the partial sums of the Fourier series of the square wave . Which statements are true? Choose all that apply.
5. Partial differential equations and Fourier series
CoreHumanIn the proof of the weak maximum principle (Theorem 6), why do we work with rather than with itself?
6. Partial differential equations and Fourier series
CoreFormalLet u : ℝ → ℝ → ℝ take time first, u t x. Which Lean statement says that u satisfies the heat equation u_t = k u_xx at the point (t, x)?
7. Partial differential equations and Fourier series
CoreHumanApply Parseval's identity to the square wave , whose sine coefficients are for odd and for even . In the real form, Parseval reads . You get . What is ?
8. Partial differential equations and Fourier series
CoreComputationalWrite sine_coefficients(f, N, M) returning the list [b_1, ..., b_N] of Fourier sine coefficients of f on , each computed by the midpoint rule with M subintervals.
9. Partial differential equations and Fourier series
StretchHumanOn , and . Which statements are true? Choose all that apply.
10. Partial differential equations and Fourier series
StretchHumanFor , solves Laplace's equation with and . Which conclusion is correct?
Common misconceptions
Misconception
"The Fourier series of a continuous function converges to it at every point." False: du Bois-Reymond (1873) found a continuous periodic function whose Fourier series diverges at a point, and later constructions make it diverge on any prescribed set of measure zero. What is true: convergence at every point where is differentiable, or Lipschitz, or where Dini's condition holds (Theorem 4); uniform convergence for continuous piecewise functions; uniform convergence of the Fejér averages for every continuous function; and almost-everywhere convergence for square-integrable functions (Carleson).
Misconception
"A Fourier series can always be differentiated term by term." The sawtooth differentiates to a series whose terms do not tend to . Term-by-term differentiation is justified when the function is continuous and piecewise as a periodic function (no jump where the period wraps around), or when the differentiated series converges uniformly. In Theorem 1 the factor provides exactly that.
Misconception
"Convergence in means convergence at each point." convergence controls an average of . It allows small sets of bad points, such as the Gibbs spikes, whose width shrinks while their height does not. Conversely, pointwise convergence does not imply convergence for general sequences of functions.
Misconception
"If a solution exists and is unique, the problem is fine." Hadamard's example — Laplace's equation with initial data — has unique solutions that do not depend continuously on the data. The backward heat equation is another example. In a computation, data always carry small errors, so continuous dependence is not optional.
Misconception
"Separation of variables finds all solutions." It finds the separated ones. That their superpositions give every solution needs two more facts: the completeness of the sine functions (Parseval) and the uniqueness theorems of the last section.
Many ways of seeing
Analysis— An orthonormal basis of a Hilbert space
The space of square-integrable functions, with , is a Hilbert space: an inner product space that is complete (the Riesz–Fischer theorem, which needs the Lebesgue integral). The exponentials form an orthonormal basis, and the map is an isometric isomorphism onto — Parseval's identity. Separation of variables is the spectral theorem in disguise: are the eigenfunctions of the self-adjoint operator with Dirichlet conditions, with eigenvalues , and the heat equation is solved by . See functional analysis and harmonic analysis.
Physics— Heat, strings and quantum energy levels
Fourier derived the heat equation from conservation of energy and his law of conduction, and the wave equation comes from Newton's second law for a string. The eigenvalue problem reappears as the time-independent Schrödinger equation for a particle in a box . Its energy levels are the separation constants of this lesson, and quantisation is the boundary condition. Physical intuition also suggests theorems: conservation of energy for the string is Theorem 8(b), and "heat never makes a new hot spot" is Theorem 6. See quantum mechanics.
Geometry— Can one hear the shape of a drum?
On a bounded domain (a drum), the Dirichlet eigenvalues of are the squares of the frequencies the drum can sound. Weyl's law (1911) says that the number of eigenvalues below is asymptotic to , so the sound determines the area. Mark Kac asked in 1966 whether it determines the shape. The answer is no: Gordon, Webb and Wolpert (1992) found two different polygons with exactly the same eigenvalues. On a Riemannian manifold the same questions lead to the heat kernel, whose short-time expansion encodes curvature, and to the heat-equation proof of the Atiyah–Singer index theorem.
Probability— Heat is the average of random walks
With , the explicit scheme reads : the new temperature is the expected old temperature seen by a walker who steps left or right with probability . In the limit, the solution of on is , with a Brownian motion. The heat kernel is the normal density of variance . Harmonic functions become exit probabilities: the solution of the Dirichlet problem on at is the expected boundary value at the point where a Brownian path from first leaves (Kakutani, 1944). The mean value property is the symmetry of Brownian motion. See stochastic processes.
Algebra— Characters of the circle group
The functions are exactly the continuous homomorphisms from the circle group to the unit circle in : . They are its characters, and Fourier analysis is the representation theory of this abelian group. Translation multiplies by , and differentiation multiplies it by . So every translation-invariant linear operator — differential operators with constant coefficients, convolutions — becomes diagonal, and that is why Fourier series solve constant-coefficient PDEs. Replacing the circle by a finite cyclic group gives the discrete Fourier transform, computed by the fast Fourier transform. A compact non-abelian group gives the Peter–Weyl theorem.
History and global context
- Vibrating strings. Jean le Rond d'Alembert derived and solved the wave equation in 1747. Leonhard Euler and Daniel Bernoulli (1753) argued over whether every solution is a superposition of sine modes, a debate that turned on what a "function" is.
- Heat. Joseph Fourier submitted his memoir on heat conduction to the Paris Academy in 1807 and published Théorie analytique de la chaleur in 1822. His claim that arbitrary functions are sums of sines was resisted, but his solutions worked.
- Rigour. Peter Gustav Lejeune Dirichlet proved the first convergence theorem in 1829. Bernhard Riemann's 1854 habilitation on trigonometric series introduced the Riemann integral and the localisation principle. Georg Cantor's work on the uniqueness of trigonometric series (1870s) led him to set theory. Paul du Bois-Reymond published his divergent example in 1873.
- Gibbs. The overshoot was found by Henry Wilbraham in 1848, rediscovered by J. Willard Gibbs in 1898–1899 after the physicist Albert Michelson's harmonic analyser showed it, and named after Gibbs by Maxime Bôcher (1906).
- The twentieth century. Lipót Fejér proved his theorem in 1900, aged twenty. Andrey Kolmogorov found divergent Fourier series of integrable functions (1923, 1926), and Lennart Carleson proved almost-everywhere convergence for (1966). On the PDE side, Sofia Kovalevskaya's 1875 thesis gave the Cauchy–Kovalevskaya existence theorem for analytic data, and Jacques Hadamard (1902) introduced well-posedness. Modern PDE theory builds on Sobolev spaces and weak solutions (Sergei Sobolev and Laurent Schwartz in the 1930s–1950s, Olga Ladyzhenskaya and many others); see the modern theory of PDEs.
Further reading
- Walter A. Strauss, Partial Differential Equations: An Introduction (1992; 2nd edition 2008) — the standard first course; separation of variables, maximum principles and energy methods as here.
- Elias M. Stein and Rami Shakarchi, Fourier Analysis: An Introduction (2003) — rigorous Fourier series, Fejér, Parseval and applications to PDEs.
- T. W. Körner, Fourier Analysis (1988) — a wonderful collection of short chapters on the mathematics and its history.
- Lawrence C. Evans, Partial Differential Equations (1998; 2nd edition 2010) — the next step: weak solutions and Sobolev spaces.