JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

The Geometry: Orthogonal Projection

An overdetermined system has no exact solution, so we settle for the closest one. This guide reveals the picture behind that choice: the best fit is the shadow of your data cast straight down onto the subspace your model can reach, and 'best' means the leftover error points perfectly at right angles.

What the previous guide left on the table

In the previous guide you met the overdetermined system A x = b: a tall, skinny matrix A with more rows (measurements) than columns (unknowns), and a right-hand side b that almost never lies exactly where A x can reach. There is no x that makes A x equal b, so we redefined the goal — find the x that makes the residual r = b - A x as small as possible in length, i.e. minimize ||A x - b||_2. That is the least-squares problem. We named the target and even computed a tiny example. What we did not yet do is explain why the minimizer has the clean form it has. This guide supplies the missing reason, and the reason is pure geometry.

The trick to seeing it is to stop staring at the equations and start looking at vectors living in a space. The vector b is a single point in R^m (m is the number of measurements). The quantity A x, as x ranges over all possible coefficient vectors, traces out not all of R^m but only a flat slice of it: every reachable A x is some combination of the columns of A. That slice — the set of all vectors you can build as a weighted sum of A's columns — is the column space of A, written col(A). Least squares is the question: of all the points in this flat slice, which one sits closest to b?

The closest point is a foot of perpendicular

Here is a picture you already trust from everyday life. Stand a flashlight directly above a tabletop and hold a small ball somewhere in the air. The point on the table closest to the ball is the spot directly beneath it — the ball's shadow when the light shines straight down, not at an angle. Every other point on the table is farther away. The line from the ball to that nearest spot is exactly vertical: it meets the tabletop at a right angle. That right angle is not a coincidence; it is what makes the point closest. Slant the line even a little and you could shorten it by sliding toward the foot of the perpendicular.

Now translate the toy back to least squares, word for word. The tabletop is the column space col(A). The ball is your data vector b, floating above (it does not lie in the slice — that is exactly why the system is overdetermined). The closest point on the slice is some A x*, the best fit. And the line from b down to A x* is the residual r = b - A x*. The whole content of least squares is this single sentence: the best fit is the point of col(A) directly under b, and the residual that connects them is perpendicular to col(A). This is the orthogonal projection of b onto the column space, and it is the geometric heart of the entire rung.

Perpendicular to the slice means perpendicular to every column

The geometric statement is satisfying, but we want to turn it into something we can compute with. The key move is to make 'the residual is perpendicular to col(A)' concrete. The column space is spanned by the columns of A, call them a_1, a_2, ..., a_n. A vector is perpendicular to the whole slice exactly when it is perpendicular to each spanning column — if it were tilted toward even one column, it would not be square-on to the slice. Perpendicularity of two vectors u and v is measured by their dot product: u and v are orthogonal precisely when u . v = 0. So the residual being perpendicular to the slice unpacks into n separate dot-product equations, one per column.

Orthogonality conditions, one per column of A:

   a_1 . r = 0          (residual square-on to column 1)
   a_2 . r = 0          (residual square-on to column 2)
      ...                 with   r = b - A x*
   a_n . r = 0          (residual square-on to column n)

Stack all n of these:   A^T r = 0
                        A^T (b - A x*) = 0
   rearrange       ->   A^T A x* = A^T b      (the normal equations)
Demanding the residual be orthogonal to each column of A, then stacking the conditions, collapses into a single square n-by-n system A^T A x = A^T b.

Look at what just happened. Each row of A^T is one of the columns of A, so the matrix product A^T r is exactly the column of dot products a_1 . r, a_2 . r, ..., a_n . r stacked up. Setting that whole vector to zero is the compact way of writing all n orthogonality conditions at once: A^T r = 0, that is, A^T (b - A x*) = 0. Move the b term across and you arrive at A^T A x* = A^T b — a square n-by-n system in the n unknowns. These are the famous normal equations, and the word 'normal' here is just the old geometry word for 'perpendicular'. They are not an arbitrary algebraic recipe; they are perpendicularity, written in matrix shorthand.

The projection matrix, and a guarantee about the residual

Once we have x*, the best fit itself — the shadow point in the slice — is p = A x*. If the columns of A are independent, A^T A is invertible, and substituting x* = (A^T A)^{-1} A^T b gives p = A (A^T A)^{-1} A^T b. The matrix that turns b into its shadow, P = A (A^T A)^{-1} A^T, is called the projection matrix. It has two properties that exactly match the geometry, and they are worth seeing because they are how you check that something really is a projection. First, P is idempotent: P P = P. Projecting a point that is already on the table does nothing — its shadow is itself. Second, applying P twice or once lands you in the same place, because once you are flat on the slice, dropping straight down again moves you nowhere.

The residual r = b - p = (I - P) b carries a guarantee that is genuinely useful in practice: it is orthogonal to every vector in the column space, which means in particular it is orthogonal to the fit p itself. That gives a Pythagorean identity, ||b||_2^2 = ||p||_2^2 + ||r||_2^2 — the data vector is the hypotenuse, the fit and the residual are the two perpendicular legs. It also gives you a cheap, honest sanity check on any least-squares solution you compute: form A^T r and confirm it is essentially zero (to within rounding). This is the residual check, and it is the first thing to reach for when you suspect your solver misbehaved.

One honest caveat about that formula P = A (A^T A)^{-1} A^T. It is the right picture, but it is a poor recipe for computation, for the same reason we never literally invert a matrix to solve A x = b. Forming A^T A explicitly, then inverting it, throws away accuracy: as a later guide in this rung will show, A^T A squares the condition number of A, so a fit that was merely awkward becomes genuinely fragile. Read P as a definition that explains the geometry, not as an instruction to your computer. The stable ways to actually land on the projection use a QR factorization or the SVD, and they are coming.

The orthonormal shortcut, and a worked shadow

The whole reason QR is the right next tool is hidden in a special case worth seeing now. Suppose the columns of A were already orthonormal — mutually perpendicular and each of length one. Then A^T A is just the identity matrix I, the messy (A^T A)^{-1} vanishes, and the projection collapses to p = A A^T b. Even better, the coefficient on each column is simply the dot product of b with that column: you find how much of b points along each direction independently, with no cross-talk. Projecting onto a single unit vector q is the familiar (q . b) q from your first linear-algebra rung. Orthonormal columns turn the whole least-squares problem into n of those independent one-direction projections.

That is exactly the payoff QR will buy us: Gram-Schmidt orthogonalization (and its more stable cousins) rebuilds the same column space out of an orthonormal set, so the hard tilted geometry becomes n easy independent shadows. But hold the honesty flag here too: naive Gram-Schmidt is itself numerically delicate — when columns are nearly parallel it can lose orthogonality badly to rounding — which is why production code uses Householder reflections or a modified scheme instead. The idea is clean; the careful implementation is the subject of guide four.

Make it concrete with the simplest possible shadow, one you can check by eye. Take A whose two columns are (1,0,0) and (0,1,0) — already orthonormal — so col(A) is the flat xy-plane sitting inside R^3, and take the data b = (1, 2, 4). Each coefficient is just a dot product: x* = (a_1 . b, a_2 . b) = (1, 2). The fit is p = A x* = (1, 2, 0) — exactly b with its z-component knocked off. The residual is r = b - p = (0, 0, 4), pointing straight up out of the plane. Confirm the geometry: A^T r = (0, 0), so the residual really is orthogonal to both columns, and Pythagoras holds — ||b||_2^2 = 21 equals ||p||_2^2 + ||r||_2^2 = 5 + 16. Projection onto a coordinate plane is just 'forget the perpendicular coordinate', and every harder least-squares fit is this same move dressed in a tilted basis.

Why this picture is worth carrying forward

Step back and notice how much the geometry bought. We never had to manipulate ||A x - b||_2 with brute-force algebra; one picture — drop a perpendicular onto the slice you can reach — told us that the minimizer exists, that it is unique when the columns are independent, and that it satisfies a clean square system. The same projection idea reappears everywhere downstream: it is why the normal equations have their form (next guide), why QR and the SVD are the stable ways to compute the same shadow without inverting anything (the guide after), and ultimately why regularization works — it gently tilts which slice you project onto. Carry the flashlight-and-tabletop image with you; it explains nearly everything that follows.

A final caution to keep you honest, in the spirit of this whole subject. The geometry is exact mathematics, but the moment you compute a projection on a real machine, every number is an approximation — floating-point arithmetic is not exact real arithmetic, A^T r will come out as a tiny nonzero vector rather than precisely zero, and how tiny it is depends on conditioning and on which algorithm you chose. A perpendicular drawn in idealized R^m and a perpendicular computed in double precision are close cousins, not identical twins. Knowing the clean geometry is what lets you recognize when the computed answer has drifted from it — and that recognition is the whole point of the rung.