Purpose

Orthogonality, projection, and least squares are one idea seen three ways: the best approximation to from a subspace is the point where the error is perpendicular to the subspace. This note derives that chain, states the normal equations, and explains the numerical reason libraries solve least squares with QR or SVD instead. Matrix background is in Matrix Theory.

Orthogonality and orthonormal bases

Vectors are orthogonal when . A set of vectors is orthonormal when the vectors are pairwise orthogonal and unit length. Orthonormal bases are the convenient ones: if has orthonormal columns then , and coordinates in that basis are just inner products, no linear system to solve.

The orthogonal complement of a subspace is . The instance that matters for least squares is

vectors perpendicular to every column of are exactly the vectors kills (ILA §6.2). Every splits uniquely as with and .

Projections

The projection of onto is that component , the closest point in to . With an orthonormal basis for ,

per ILA §6.3. For a general full-column-rank matrix whose columns span , project by solving for the coefficient vector: the projection is where makes the residual perpendicular to every column, and the projection matrix is

Projection matrices satisfy (projecting twice changes nothing) and . Strang’s 18.06 lectures 15-16 build the whole least-squares story from this matrix.

Least squares and the normal equations

An overdetermined system with , , usually has no solution because is not in . Least squares asks for the minimizing . Geometrically, must be the projection of onto , so the residual lies in :

These are the normal equations (ILA §6.5). The same equation drops out of calculus, since . is invertible exactly when has full column rank, and then is unique.

The normal equations are an orthogonality statement

is nothing but rearranged: the residual is perpendicular to every column of . If you remember one thing, remember the geometry, “the best fit is the one whose error the model cannot see,” and the algebra reconstructs itself. It also gives free sanity checks on any fitted model: compute and confirm it is numerically zero, as the worked example below does.

The residual orthogonality is worth internalizing. The error the fit cannot remove is perpendicular to everything the model can express. In a regression with an intercept column of ones, orthogonality against that column forces the residuals to sum to zero. Orthogonality against a feature column means the residual is uncorrelated with that feature; whatever structure remains in the residual is structure the column space cannot represent.

Worked example

Fit a line through the points , , , the example Strang uses in 18.06 lecture 16:

Solving gives , the line . The fitted values are and the residual is . Check both orthogonality conditions: sums to zero (intercept column) and (slope column), so as derived.

import numpy as np
 
A = np.array([[1.0, 0.0], [1.0, 1.0], [1.0, 2.0]])
b = np.array([6.0, 0.0, 0.0])
 
xhat, res, rank, sv = np.linalg.lstsq(A, b, rcond=None)
print(xhat)                    # [ 5. -3.]
r = b - A @ xhat
print(A.T @ r)                 # ~[0. 0.], residual orthogonal to columns
 
P = A @ np.linalg.inv(A.T @ A) @ A.T   # projection onto col(A)
print(np.allclose(P @ b, A @ xhat))    # True
print(np.allclose(P @ P, P))           # True, projecting twice is a no-op

Why QR instead of the normal equations

Forming squares the conditioning of the problem: for full-column-rank , (Trefethen and Bau, lecture 19; Golub and Van Loan, ch. 5). A matrix with is unpleasant; its normal equations have and can lose all useful digits in double precision. The QR route factors with orthonormal and triangular , then solves by back substitution. Orthogonal transformations preserve norms and hence conditioning, and Householder QR is backward stable (Trefethen and Bau, lecture 16), so the accuracy tracks rather than .

Derive with the normal equations, solve with QR or SVD

The normal equations are the right tool for understanding least squares and the wrong tool for computing it. Explicitly forming squares the condition number, so a problem that is merely ill-conditioned becomes numerically hopeless. In double precision, already puts at the edge of machine epsilon. Library solvers (lstsq, R’s lm, LAPACK drivers) use QR or SVD for exactly this reason.

numpy.linalg.lstsq goes one step further and uses an SVD-based LAPACK driver (gelsd). SVD costs more than QR but handles rank deficiency: singular values below rcond times the largest are treated as zero, and among all minimizers lstsq returns the minimum-norm one. That pseudoinverse story continues in SVD and the Pseudoinverse.

Sources