Convex functions and their tests
Define convex functions and test convexity with the first- and second-order conditions.
A convex function is one whose graph never dips below its chords. This single shape property has an outsized payoff: for a convex objective, every stationary point is a global minimum and gradient descent cannot get trapped. This lesson defines convexity and gives the two practical tests for it.
Definition
A function (with convex domain) is convex if for all and ,
[1]The left side is the function at a point on the segment; the right side is the corresponding point on the chord. Convexity says the function lies on or below every chord. It is strictly convex if the inequality is strict for and . A function is concave if is convex.
A useful equivalent: is convex if and only if its epigraph , the region above the graph, is a convex set. This links function convexity back to the previous lesson's set convexity.
First-order condition
If is differentiable, convexity is equivalent to the graph lying above all its tangent planes:
The right side is the first-order Taylor approximation at . Convexity says this linear underestimate is a global lower bound, never an overestimate.
Why this makes optimization easy. If , the bound becomes for all : the stationary point is a global minimum. For convex functions, the necessary first-order condition is also sufficient, and local minima are global.
Second-order condition
If is twice differentiable, convexity is equivalent to a positive semidefinite Hessian everywhere:
[2]Using the definiteness tests from quadratic forms, this is checkable: all eigenvalues of the Hessian are nonnegative at every point. Strict positive definiteness () gives strict convexity. The Hessian being PSD is the curvature restatement of "curves upward in every direction".
Example. A quadratic has Hessian , so it is convex if and only if . The least-squares objective has Hessian , hence is always convex.
Operations that preserve convexity
Convex functions are built from a small toolbox:
- Nonnegative weighted sums: is convex for .
- Pointwise maximum: is convex (the epigraph is an intersection).
- Affine composition: is convex if is.
These rules certify convexity of composite objectives (a convex loss plus a convex regularizer stays convex) without returning to the definition.
Check it on arrays
import numpy as np
rng = np.random.default_rng(1)
# Chord test: f(theta x + (1-theta) y) <= theta f(x) + (1-theta) f(y)
def chord_holds(f, dim, trials=200_000):
x = rng.normal(size=(trials, dim))
y = rng.normal(size=(trials, dim))
th = rng.random((trials, 1))
lhs = f(th * x + (1 - th) * y)
rhs = th.ravel() * f(x) + (1 - th).ravel() * f(y)
return np.all(lhs <= rhs + 1e-9)
f_quad = lambda X: np.sum(X**2, axis=1) # convex
f_exp = lambda X: np.exp(X[:, 0]) # convex
f_cos = lambda X: np.cos(X[:, 0]) # not convex
print("||x||^2 convex:", chord_holds(f_quad, 3))
print("exp(x) convex: ", chord_holds(f_exp, 1))
print("cos(x) convex: ", chord_holds(f_cos, 1))
# Second-order test on a quadratic: Hessian = A, PSD <-> convex
A = np.array([[2.0, 0.5], [0.5, 1.0]]) # symmetric
print("eig(A):", np.linalg.eigvalsh(A), "-> all >= 0 -> convex")
A_indef = np.array([[1.0, 0.0], [0.0, -1.0]])
print("eig(A_indef):", np.linalg.eigvalsh(A_indef), "-> mixed -> not convex")The chord test confirms the square and exponential are convex while the cosine is not, and the Hessian eigenvalue signs agree.
Exercises
Exercise 1. Use the second-order condition to decide whether is convex. Compute the Hessian and check its eigenvalues by hand.
Solution
Step 1. The Hessian of a quadratic is constant. Here the second partials are , , , so
Step 2. Check positive semidefiniteness by the eigenvalues, the roots of , that is :
Step 3. Both eigenvalues are positive, so everywhere. The function is strictly convex. (A faster route: a symmetric matrix is positive definite when the diagonal entries and the determinant are positive; here , , and .)
Exercise 2. Prove that a nonnegative weighted sum of convex functions is convex: if are convex and , then is convex. Use the chord definition.
Solution
Step 1. Fix and . Apply the convexity inequality to and to separately:
Step 2. Multiply the first by and the second by . The inequality directions are preserved because the multipliers are nonnegative. Add the two:
Step 3. The left side is and the right side is , the chord condition for . So is convex. Nonnegativity of is essential: a negative weight flips an inequality and can destroy convexity.
Exercise 3 (code). The softplus is claimed convex. Verify it two ways in numpy: the chord test on random pairs, and a finite-difference second derivative that stays nonnegative on a grid.
Solution
import numpy as np
rng = np.random.default_rng(0)
softplus = lambda x: np.log1p(np.exp(x))
# Chord test on random scalar pairs
x = rng.normal(size=200_000)
y = rng.normal(size=200_000)
th = rng.random(200_000)
lhs = softplus(th * x + (1 - th) * y)
rhs = th * softplus(x) + (1 - th) * softplus(y)
assert np.all(lhs <= rhs + 1e-9)
# Finite-difference second derivative on a grid: f'' >= 0 means convex
g = np.linspace(-8, 8, 4001)
h = g[1] - g[0]
f2 = (softplus(g[2:]) - 2 * softplus(g[1:-1]) + softplus(g[:-2])) / h**2
assert f2.min() >= -1e-8
print("min finite-diff f'':", round(f2.min(), 8),
" (sigmoid(0) =", round(float(1 / (1 + np.exp(0))) * (1 - 1/(1+np.exp(0))), 4), ")")The chord never rises above the function and the numerical second derivative stays at or above zero, the curvature signature of a convex function. (Its true second derivative is the sigmoid times one minus the sigmoid, peaking at at .)
The next lesson uses these convexity guarantees to analyze the first optimization algorithm: gradient descent.
References
- [1]Boyd, S., & Vandenberghe, L. (2004). Convex Optimization, §3.1. Cambridge University Press. The definition of a convex function and the epigraph characterization.↩
- [2]Boyd, S., & Vandenberghe, L. (2004). Convex Optimization, §3.1.3-3.2. Cambridge University Press. The first- and second-order conditions and convexity-preserving operations.↩