AI Knowledge Tree

Convex sets

Define convex sets, recognize them, and use the separating-hyperplane idea.

⏱ 28 min

Convexity is the property that makes optimization tractable: on a convex problem, any local minimum is global and there are no saddles to escape. The geometry starts with convex sets, the shapes a feasible region can take before the objective is even introduced.

Definition

A set C⊆RnC \subseteq \mathbb{R}^n is convex if the line segment between any two of its points stays inside it: for all x,y∈Cx, y \in C and θ∈[0,1]\theta \in [0, 1],

θx+(1−θ)y∈C.\theta x + (1 - \theta) y \in C.

The point θx+(1−θ)y\theta x + (1-\theta)y is a convex combination of xx and yy, tracing the segment from yy (θ=0\theta = 0) to xx (θ=1\theta = 1). A disk, a solid ball, a half-space, and the whole space are convex; a ring, a crescent, and a pair of separated blobs are not[1].

The definition extends to any number of points: a convex set contains every convex combination ∑iθixi\sum_i \theta_i x_i with θi≥0\theta_i \ge 0 and ∑iθi=1\sum_i \theta_i = 1.

Building blocks

Hyperplanes and half-spaces. A hyperplane {x:a⊤x=b}\{x : a^\top x = b\} and a half-space {x:a⊤x≤b}\{x : a^\top x \le b\} are convex. A half-space is the basic ingredient of linear constraints: each inequality a⊤x≤ba^\top x \le b carves out one.

Norm balls. {x:∥x−x0∥≤r}\{x : \lVert x - x_0\rVert \le r\} is convex for any norm, by the triangle inequality. The ℓ1\ell_1, ℓ2\ell_2, and ℓ∞\ell_\infty balls are all convex, which is why their unit balls were the feasible regions in the norms lesson.

Operations that preserve convexity

Convexity survives the operations used to assemble feasible regions:

  • Intersection. If C1,C2C_1, C_2 are convex, so is C1∩C2C_1 \cap C_2. A segment lying in both sets lies in their intersection. This extends to arbitrary intersections, so a polyhedron {x:Ax≤b}\{x : Ax \le b\}, an intersection of half-spaces, is convex.
  • Affine images. If CC is convex, so is {Ax+b:x∈C}\{Ax + b : x \in C\}. Scaling, rotating, projecting, and translating a convex set keep it convex.

These rules let you certify convexity of a feasible region by construction, without checking the segment condition directly.

The separating hyperplane theorem

Theorem. If CC and DD are disjoint convex sets, there exists a hyperplane separating them: a nonzero aa and scalar bb with a⊤x≤ba^\top x \le b for all x∈Cx \in C and a⊤x≥ba^\top x \ge b for all x∈Dx \in D[2].

The picture is that two non-overlapping convex shapes can always be split by a flat wall. This is the geometric root of duality (a separating hyperplane becomes a dual certificate) and of support vector machines (the separating hyperplane is the classifier). The disjointness and convexity are both essential; non-convex sets can interlock so that no flat wall separates them.

A set is convex if the segment between any two of its points stays inside: the disk passes, the crescent fails.
A set is convex if the segment between any two of its points stays inside: the disk passes, the crescent fails.

Check it on arrays

python · numpy
import numpy as np

rng = np.random.default_rng(0)

# Test convexity empirically: sample pairs, check midpoints stay inside.
def is_convex_region(inside, sampler, trials=100_000):
    P = sampler(trials)
    Q = sampler(trials)
    P, Q = P[inside(P)], Q[inside(Q)]
    m = min(len(P), len(Q))
    theta = rng.random((m, 1))
    mid = theta * P[:m] + (1 - theta) * Q[:m]
    return np.all(inside(mid))

box = lambda n: rng.uniform(-2, 2, size=(n, 2))

# L2 ball: convex
in_ball = lambda X: np.linalg.norm(X, axis=1) <= 1.5
print("L2 ball convex:", is_convex_region(in_ball, box))

# Annulus (ring): NOT convex
in_ring = lambda X: (np.linalg.norm(X, axis=1) >= 0.8) & (np.linalg.norm(X, axis=1) <= 1.5)
print("annulus convex:", is_convex_region(in_ring, box))

# Polyhedron {x : A x <= b} is convex (intersection of half-spaces)
A = np.array([[1, 0], [0, 1], [-1, -1]]); b = np.array([1.0, 1.0, 1.0])
in_poly = lambda X: np.all(X @ A.T <= b, axis=1)
print("polyhedron convex:", is_convex_region(in_poly, box))

The midpoint test confirms the ball and polyhedron are convex and flags the ring as non-convex.

Exercises

Exercise 1. Show directly from the definition that the half-space H={x:a⊤x≤b}H = \{x : a^\top x \le b\} is convex, for any nonzero aa and scalar bb.

Solution

Step 1. Take any x,y∈Hx, y \in H, so a⊤x≤ba^\top x \le b and a⊤y≤ba^\top y \le b. Pick θ∈[0,1]\theta \in [0, 1] and form the convex combination z=θx+(1−θ)yz = \theta x + (1-\theta) y.

Step 2. Apply a⊤a^\top and use linearity:

a⊤z=θ a⊤x+(1−θ) a⊤y.a^\top z = \theta\, a^\top x + (1-\theta)\, a^\top y.

Step 3. Both θ≥0\theta \ge 0 and 1−θ≥01-\theta \ge 0, so each term is bounded by the same coefficient times bb:

a⊤z≤θb+(1−θ)b=b.a^\top z \le \theta b + (1-\theta) b = b.

So z∈Hz \in H, and the segment stays inside. The half-space is convex.

Exercise 2. Prove the intersection rule: if C1C_1 and C2C_2 are convex, then C1∩C2C_1 \cap C_2 is convex. Then explain in one sentence why this makes the polyhedron {x:Ax≤b}\{x : Ax \le b\} convex.

Solution

Step 1. Take x,y∈C1∩C2x, y \in C_1 \cap C_2, so xx and yy lie in both sets. Pick θ∈[0,1]\theta \in [0,1] and let z=θx+(1−θ)yz = \theta x + (1-\theta) y.

Step 2. Since x,y∈C1x, y \in C_1 and C1C_1 is convex, z∈C1z \in C_1. The identical argument with C2C_2 gives z∈C2z \in C_2.

Step 3. A point in both sets is in the intersection, so z∈C1∩C2z \in C_1 \cap C_2. The segment stays inside, so the intersection is convex.

The polyhedron is the intersection of the half-spaces {x:ai⊤x≤bi}\{x : a_i^\top x \le b_i\}, one per row of AA; each is convex by Exercise 1, so their intersection is convex.

Exercise 3 (code). A convex set contains every convex combination of its points, not only midpoints. For the polyhedron with rows (1,0),(0,1),(−1,−1)(1,0), (0,1), (-1,-1) and b=(1,1,1)b = (1, 1, 1), sample triples of interior points and random barycentric weights θ1,θ2,θ3≥0\theta_1, \theta_2, \theta_3 \ge 0 summing to one, and check the weighted combination stays inside.

Solution
python · numpy
import numpy as np

rng = np.random.default_rng(0)
A = np.array([[1, 0], [0, 1], [-1, -1]])
b = np.array([1.0, 1.0, 1.0])
inside = lambda X: np.all(X @ A.T <= b + 1e-12, axis=1)

# Draw points in the box, keep those inside the polyhedron.
box = rng.uniform(-2, 2, size=(300_000, 2))
pts = box[inside(box)]
P, Q, R = pts[0::3], pts[1::3], pts[2::3]
m = min(len(P), len(Q), len(R))
P, Q, R = P[:m], Q[:m], R[:m]

# Random convex weights on the simplex via the sort trick.
u = np.sort(rng.random((m, 2)), axis=1)
t1 = u[:, 0]
t2 = u[:, 1] - u[:, 0]
t3 = 1.0 - u[:, 1]
comb = t1[:, None] * P + t2[:, None] * Q + t3[:, None] * R

assert np.all(inside(comb))
print("all", m, "three-point convex combinations stayed inside")

Every weighted combination of three interior points lands inside, confirming the definition extends from segments to arbitrary convex combinations.

With convex feasible regions defined, the next lesson puts a convex function on top of them.


References

  1. [1]Boyd, S., & Vandenberghe, L. (2004). Convex Optimization, §2.1-2.3. Cambridge University Press. Convex sets and the operations that preserve convexity.↩
  2. [2]Boyd, S., & Vandenberghe, L. (2004). Convex Optimization, §2.5. Cambridge University Press. The separating and supporting hyperplane theorems.↩