Week 7 showed that when b does not lie in the column space C(A), the equation Ax=b has no exact solution. The closest you can get is the orthogonal projection of b onto C(A): find x^ so that
p=Ax^
minimizes the residual length ∥b−Ax∥ over all x. That is the least-squares problem
xmin∥b−Ax∥2.
The geometry is the same as last week: the residual e=b−Ax^ must be orthogonal to every column of A, which forces the normal equations
A⊤Ax^=A⊤b.
When A is m×n with m>n and full column rank n, the Gram matrix A⊤A is n×n, symmetric, and invertible, so a unique least-squares solution exists:
x^=(A⊤A)−1A⊤b.
The fitted values are p=Ax^; the residual e=b−p lives in the left null space N(A⊤).
When this shows up. Overdetermined systems are the everyday case: more measurements than parameters. Fitting a line through noisy sensor readings, estimating robot pose from many landmarks, regressing a policy on a batch of trajectories — all are least squares.
Worked example: fit a line. Suppose we want y=c+dt for three data points
(t,y):(0,1),(1,2),(2,2).
Stack the model as Ax=b with x=(d,c)⊤ (slope first, then intercept):
A=012111,b=122.
The first column is the t-values; the second is the constant column of ones. No exact line hits all three points (check: the slopes between consecutive pairs differ). Form the normal equations:
A⊤A=(011121)012111=(5333),A⊤b=(65).
Solve A⊤Ax^=A⊤b:
(5333)(d^c^)=(65).
Subtract the second row from the first after scaling: from 3d^+3c^=5 we get d^+c^=5/3. From 5d^+3c^=6, eliminate c^ to find d^=1/2, then c^=5/3−1/2=7/6. So
x^=(1/27/6)⟹y^(t)=21t+67.
The fitted values are Ax^=(7/6,5/3,13/6)⊤, and the residual b−Ax^=(−1/6,1/3,−1/6)⊤ is orthogonal to both columns of A (dot products zero). Among all lines, this one minimizes the sum of squared vertical errors.
Connection to Week 7. The normal equations are exactly the subspace-projection equations A⊤(b−Ax^)=0. Least squares is projection of b onto C(A), rephrased as “best fit in the 2-norm.”
Projections become cleanest when the basis is orthonormal: vectors q1,…,qn with
qi⊤qj=δij
(unit length, pairwise orthogonal). The projection of b onto span{q1,…,qn} collapses to a sum of line projections:
p=(q1⊤b)q1+⋯+(qn⊤b)qn,
with no matrix inverse. Gram-Schmidt turns any independent set a1,…,an into such an orthonormal set.
Algorithm. Start with independent vectors a1,…,an∈Rm.
v1=a1, then q1=v1/∥v1∥.
For j=2,…,n:
Subtract projections onto the previous qi's:
vj=aj−i=1∑j−1(qi⊤aj)qi.
Normalize: qj=vj/∥vj∥.
Each vj is the component of aj orthogonal to span{q1,…,qj−1}=span{a1,…,aj−1}. Independence of the ai's guarantees vj=0, so normalization is always defined.
Check: q1⊤q2=(1/12)(1−1+0)=0, and both have unit length. The pair {q1,q2} is an orthonormal basis for span{a1,a2}.
Failure mode. If the input vectors are linearly dependent, some vj is zero and you cannot normalize — Gram-Schmidt is ill-defined (or you drop that vector and reduce rank). Orthogonal or already unit-length independent vectors are fine; the algorithm simply skips the “subtract” step when coefficients are zero.
Exercise · Fill in the blank
Apply the first step of Gram-Schmidt to a1 = (1, 1, 0): normalize it to get q1. What is the first (x) component of q1, rounded to 3 decimals?
Pack the independent columns of A as a1,…,an and the Gram-Schmidt outputs as q1,…,qn. By construction, each aj is a linear combination of q1,…,qj only (earlier qi's appear with coefficient qi⊤aj; later ones do not appear). In matrix form that is the QROrthogonal-Upper (matrix factorization) factorization
A=QR,
where
Q is m×n with orthonormal columns (Q⊤Q=In),
R is n×nupper triangular.
Explicitly, the entries of R are the Gram-Schmidt coefficients:
Rij=⎩⎨⎧qi⊤aj∥vj∥0i<j,i=j,i>j.
Column j of A=QR reads aj=r1jq1+⋯+rjjqj, which is exactly the reverse of the Gram-Schmidt subtractions.
Example continued. With a1,a2 from above,
Q=1/21/201/6−1/62/6,R=(201/26/2).
Check R11=∥a1∥=2, R12=q1⊤a2=1/2, R22=∥v2∥=6/2, and R21=0. Multiplying QR recovers A=[a1a2].
Full vs thin QR. When A is m×n with m≥n and full column rank, the form above is the thin (or reduced) QR: Q is m×n, R is n×n. A full QR extends Q to an m×m orthogonal matrix by adding an orthonormal basis for the left null space; the extra rows of R are zero. For least squares the thin form is enough.
Why care.QR is a stable way to encode “orthonormal basis for the column space” plus “change-of-basis coefficients.” Week 13 reuses orthonormal columns in the SVD construction; Gram-Schmidt is the constructive prototype for that idea.
Substitute A=QR into the normal equations A⊤Ax^=A⊤b:
(QR)⊤(QR)x^=(QR)⊤b⟹R⊤Q⊤QRx^=R⊤Q⊤b.
Since Q⊤Q=I and R is invertible (upper triangular with positive diagonal entries from full column rank), multiply both sides by (R⊤)−1:
Rx^=Q⊤b.
That is a triangular system. Solve it by back-substitution — no need to form A⊤A or invert it.
Why this is better numerically. Forming A⊤Asquares the condition number: κ(A⊤A)=κ(A)2. If A is already moderately ill-conditioned, A⊤A can lose all accurate digits before you solve. Working with Rx^=Q⊤b keeps the condition number of order κ(A), not κ(A)2. Library routines (numpy.linalg.lstsq, np.linalg.qr followed by a triangular solve) use QR or related orthogonal factorizations for this reason.
Algorithm summary.
Compute thin QR: A=QR.
Form the projected right-hand side c=Q⊤b.
Solve Rx^=c by back-substitution.
Fitted values: p=Ax^=Q(Q⊤b); residual e=b−p is orthogonal to C(A).
For the line-fit design matrix from the first section, the same x^ appears whether you solve normal equations or use QR; the QR path is the one you should prefer on real data.