Skip to content
AI360XpertBeta

Orthogonality and Projections

Perpendicular means zero dot product. Projection splits any vector into a parallel part plus a perpendicular leftover, which is how clean bases get built.

Vector v equals (4, 3) splits into projection (4, 0) along u plus residual (0, 3) perpendicular to u, so u dot r equals 0
Vector v equals (4, 3) splits into projection (4, 0) along u plus residual (0, 3) perpendicular to u, so u dot r equals 0

Why Does This Exist?

Least squares, Fourier series, PCA, and attention all throw away the part they cannot use and keep the part they can. Without a clean split, the leftover leaks into the kept part: correlated features double count evidence, non-orthogonal bases entangle coefficients, and denoising removes signal with the noise.

Orthogonality makes the split clean. Two vectors are orthogonal when their dot product is zero, meaning they share no direction. Projection drops one vector onto another (or onto a subspace), leaving a residual that is orthogonal to everything kept. Lengths come from norms, and the full basis-building payoff is PCA derivation. This page covers the split, the formula, and the 3-4-5 check.

The one idea you need first

For unit direction u^\hat{u} with u^⋅u^=1\hat{u} \cdot \hat{u} = 1, the projection of vv along u^\hat{u} is (v⋅u^)u^(v \cdot \hat{u})\hat{u}: how far vv reaches in that direction, laid back along it. The residual r=v−projr = v - \text{proj} is perpendicular by construction. For general uu, divide by the squared length: proju(v)=((v⋅u)/(u⋅u))u\text{proj}_u(v) = ((v \cdot u)/(u \cdot u))u.

Think of It Like This

Noon shadow on a straight road

Sun directly overhead throws your shadow straight onto the road centerline. Your full height is the vector vv; the shadow on the road is the projection; the vertical drop from your head to the shadow tip is the residual, perpendicular to the road.

The shadow length tells how far along the road you reach, nothing about height. Where it stops: shadows collapse a dimension, so many heights share one shadow. Projection likewise keeps one part and parks the rest in the residual, recoverable only by adding it back.

How It Actually Works

Orthogonal means u⋅r=0u \cdot r = 0. Projection keeps the parallel part and parks the rest: v=proju(v)+rv = \text{proj}_u(v) + r with u⋅r=0u \cdot r = 0. Only the parallel part survives a second projection, which is why orthogonal bases decouple coefficients. Gram-Schmidt repeats this: take the next vector, subtract its projections onto every kept direction, keep the residual. Each residual is orthogonal to all previous ones by construction.

Worked example

Take v=(4,3)v = (4, 3) and unit direction u^=(1,0)\hat{u} = (1, 0) along the x-axis. Dot: v⋅u^=4×1+3×0=4v \cdot \hat{u} = 4 \times 1 + 3 \times 0 = 4. Projection: proj=4u^=(4,0)\text{proj} = 4\hat{u} = (4, 0). Residual: r=(4,3)−(4,0)=(0,3)r = (4, 3) - (4, 0) = (0, 3). Check: u^⋅r=1×0+0×3=0\hat{u} \cdot r = 1 \times 0 + 0 \times 3 = 0, so perpendicular. Lengths: ∥v∥=16+9=5\lVert v \rVert = \sqrt{16 + 9} = 5, ∥proj∥=4\lVert \text{proj} \rVert = 4, ∥r∥=3\lVert r \rVert = 3, and 42+32=25=524^2 + 3^2 = 25 = 5^2. The diagram draws exactly this right triangle.

Code

import numpy as np

def project(v: np.ndarray, u: np.ndarray) -> np.ndarray:    return ((v @ u) / (u @ u)) * u  # scale by overlap over squared length

v = np.array([4.0, 3.0])u = np.array([1.0, 0.0])p = project(v, u)print(p.tolist())  # -> [4.0, 0.0]print((v - p).tolist())  # -> [0.0, 3.0]print(float(u @ (v - p)))  # -> 0.0

Parallel part plus perpendicular leftover, with zero dot product confirming the split.

Watch Out For

Using the unit formula on a non-unit direction

(v⋅u)u(v \cdot u)u without dividing by u⋅uu \cdot u scales the answer by ∥u∥2\lVert u \rVert^2. With u=(2,0)u = (2, 0), it reports (8,0)(8, 0) instead of (4,0)(4, 0), and the residual (−4,3)(-4, 3) is not perpendicular: u⋅r=−8u \cdot r = -8.

Symptom: residual dot product nonzero, lengths violating Pythagoras. Fix: always use ((v⋅u)/(u⋅u))u((v \cdot u)/(u \cdot u))u, or normalize first and use (v⋅u^)u^(v \cdot \hat{u})\hat{u}. Test on (4,3)(4, 3) against (1,0)(1, 0) where the answer must be (4,0)(4, 0).

Projecting onto correlated axes one at a time

Subtracting the projection onto u1u_1 then onto u2u_2 works only when u1⋅u2=0u_1 \cdot u_2 = 0. When axes correlate, the second subtraction reintroduces a u1u_1 component, so coefficients entangle and the residual still points along kept directions.

Symptom: residual dot products against kept axes are nonzero, and refitting changes earlier coefficients. Fix: orthogonalize first (Gram-Schmidt), or solve the joint normal equations instead of projecting sequentially.

The Quick Version

  • Orthogonal means zero dot product: no shared direction.
  • Projection splits vv into parallel (v⋅u^)u^(v \cdot \hat{u})\hat{u} plus residual perpendicular to uu.
  • Example (4,3)(4, 3) along (1,0)(1, 0) gives (4,0)(4, 0) plus (0,3)(0, 3) with dot zero and lengths 3 4 5.
  • General formula divides by squared length: ((v⋅u)/(u⋅u))u((v \cdot u)/(u \cdot u))u.
  • Gram-Schmidt repeats the split to build orthogonal bases; PCA lives on the same split.
  • Unit formula on non-unit vectors and sequential projection onto correlated axes both silently fail.