III.8 · Calculus
Which way is uphill — and how steep is every other way?
Place a point on a contour map and aim a direction. The gradient gives the rate in that direction by a dot product, points along steepest increase and stands perpendicular to the level curve.
Measure the rate of change in any direction
Gradient (drawn ×0.25) on the contours of f = 0.5x² + 2y²
Contours of f = 0.5x² + 2y². At (1, 0.5) the gradient is (1, 2), drawn at scale 0.25; the dashed line is tangent to the level curve and perpendicular to it. The blue arrow is the unit direction of d = (1, 0).
Directional derivative versus direction angle θ (radians)
The directional derivative ∇f·u = |∇f| cos(θ − θ∇) peaks at θ∇ ≈ 1.107 with value |∇f| ≈ 2.236068 and is 0 along the level curve.
- Point
- (1, 0.5)
- Gradient (exact)
- (1, 2)
- Steepest rate of increase
- 2.236068
- Direction vector
- (1, 0)
- Unnormalised rate (exact)
- 1
- Directional derivative
- 1
- Gradient · level tangent
- 0
Exact values use =; binary64 approximations use ≈. Undefined values state their reason.
Moving in direction u changes f at rate 1, between −|∇f| and |∇f|. The maximum ≈ 2.236068 occurs along ∇f itself.
Compute the gradient
The partial derivatives at the point form ∇f = (1, 2).
from −2.5 to 2.5, up to 2 decimal places
from −2.5 to 2.5, up to 2 decimal places
from −2 to 2, up to 2 decimal places
from −2 to 2, up to 2 decimal places
At on the valley , the gradient is . In the direction the height changes at rate . Choose Along the gradient: the rate rises to , the largest possible. Choose Along the level curve: the rate is exactly .
Intuition: one vector answers every direction
Walking from a point in a direction , the height changes at some rate. You might expect a different calculation for every direction. For a differentiable function there is a single vector — the gradient — and the rate in direction is just its component along . The profile plot shows the consequence: as the direction turns, the rate traces a cosine wave.
Definition
The gradient of at is the vector of partial derivatives,
For a unit vector , the directional derivative is
When is differentiable, . A nonzero direction vector is normalised first: . The zero vector has no direction.
Mechanics: what the explorer computes
The gradient is exact at rational points. The unnormalised product is exact; dividing by is exact when is the square of a rational and is otherwise shown with . The gradient arrow is drawn at the scale stated in the title, so its direction is faithful and its length is proportional. The level-curve tangent is perpendicular to the gradient, and the inspector checks exactly.
Derivation: why the dot product appears
Differentiability means . Put and divide by :
Letting gives , where is the angle between and . The rate is largest when (steepest ascent, value ), smallest when , and zero when . Along a level curve is constant, so its tangent direction has zero rate: the gradient is perpendicular to regular level curves.
Worked example
For at : . With , , so
The steepest rate is , and the tangent to the level curve is , for which .
Replay the worked derivation
Compute the gradient
The partial derivatives at the point form ∇f = (1, 2).
Stationary points and undefined cases
Where (the Stationary point preset), every directional derivative is and there is no direction of steepest ascent; the stage draws no gradient arrow rather than an arbitrary one. A zero direction vector cannot be normalised, so the directional derivative is reported as undefined. At points where is not differentiable, the formula is not guaranteed even when the partials exist; the surfaces here are polynomials, which are differentiable everywhere.
Executable reference code
The reference computes exact gradients and directional derivatives with Fraction, and confirms against the limit definition along rational unit directions such as . The NumPy version maximises the directional derivative over many angles and finds the gradient direction.
"""Gradient and directional derivatives, exact; the limit definition agrees with grad . u (III.8)."""
from fractions import Fraction as F
f = lambda x, y: x * x / 2 + 2 * y * y
grad = lambda x, y: (x, 4 * y)
p = (F(1), F(1, 2))
g = grad(*p)
assert g == (1, 2)
def directional(d):
if d == (0, 0):
raise ValueError("the zero vector has no direction")
n2 = d[0] ** 2 + d[1] ** 2
return (g[0] * d[0] + g[1] * d[1]), n2 # rate = numerator / sqrt(n2)
num, n2 = directional((F(3), F(4)))
assert (num, n2) == (11, 25) # rate 11/5
# Limit definition along the unit direction u = (3/5, 4/5): m(h) is a polynomial of degree 1 in h.
u = (F(3, 5), F(4, 5))
m = lambda h: (f(p[0] + h * u[0], p[1] + h * u[1]) - f(*p)) / h
assert 2 * m(F(1, 4)) - m(F(1, 2)) == F(11, 5)
# The gradient is perpendicular to the level-curve tangent t = (-g_y, g_x).
t = (-g[1], g[0])
assert g[0] * t[0] + g[1] * t[1] == 0"""The steepest direction maximises grad . u over all unit vectors (III.8)."""
import numpy as np
g = np.array([1.0, 2.0])
theta = np.linspace(-np.pi, np.pi, 3601)
U = np.stack([np.cos(theta), np.sin(theta)], axis=1)
rates = U @ g
best = U[np.argmax(rates)]
assert abs(rates.max() - np.linalg.norm(g)) < 1e-6
assert np.allclose(best, g / np.linalg.norm(g), atol=1e-3)
assert abs(rates.min() + np.linalg.norm(g)) < 1e-6Explore
On Saddle, find two directions with rate zero: they are the two arms of the level curve through the point. On Tilted plane, the gradient is the same everywhere and the contours are parallel lines perpendicular to it. Shorten without changing its direction: the directional derivative does not change, because is normalised.
Common mistakes
Using an unnormalised direction, which scales the “rate” by . Drawing the gradient tangent to the contour instead of perpendicular to it. Assuming the gradient points toward a minimum: it points toward the steepest increase; the steepest decrease is .
Numerical considerations
Normalising a tiny direction vector divides by a tiny number and amplifies rounding; the zero vector must be rejected explicitly, not left to produce NaN. When is nearly zero its direction is numerically unreliable even if its components are accurate: steepest-ascent directions near stationary points are ill-conditioned.
Engineering and ML connections
Gradient descent (VI.4) steps along because it is locally the steepest decrease. Directional derivatives appear in line searches and in Jacobian–vector products, which automatic differentiation (III.10) computes without forming the whole gradient. Level-set geometry also underlies constraints in optimisation (VI.9).
Exercises
Summary and checkpoints
The gradient collects the partial derivatives; for a unit direction , . It points along steepest increase with rate and is perpendicular to regular level curves. At stationary points it vanishes, and zero directions have no rate. Next, III.9 differentiates maps with several outputs: the Jacobian.