The Stable Solution: The Gram-Schmidt Process

The constructive algorithm that takes a 'bad' basis and straightens it out into a perfect orthonormal basis.

In our last lesson, we discovered the potential dangers of the Normal Equations. The act of computing `AᵀA` can lead to numerical instability, especially when the columns of our matrix `A` are nearly parallel.

The root of the problem is that the columns of `A` can be "badly behaved." They can point in similar directions, creating a skewed and unstable coordinate system.

What if we could fix this? What if we could take any set of basis vectors (like the columns of `A`) and convert them into a perfect basis—one where every vector is orthogonal to every other vector, and every vector has a length of 1?

This is the goal of the Gram-Schmidt Process. It is a beautiful, constructive algorithm that takes a "bad" basis and systematically straightens it out into a "good" orthonormal basis.

The Goal: Orthonormal Bases
A set of vectors {q1,q2,...,qn}\{q_1, q_2, ..., q_n\} is orthonormal if they are mutually orthogonal (dot product is 0) and all have a length of 1.

Working with an orthonormal basis is a dream. Projections become trivial, and matrices whose columns are orthonormal (our **Orthogonal Matrices, `Q`**) are numerically perfect, with a condition number of 1.

The Algorithm: Step-by-Step Purification
The process takes a set of independent vectors {v1,v2,...}\{v_1, v_2, ...\} and generates an orthonormal set {q1,q2,...}\{q_1, q_2, ...\} that spans the same space.

Step 1: The First Vector (The Anchor)

Take the first vector v1v_1, which becomes our first orthogonal vector u1u_1. Then, normalize it.

q1=v1v1q_1 = \frac{v_1}{\|v_1\|}

Step 2: The Second Vector (The Subtraction Trick)

Take the second vector v2v_2 and subtract its projection onto the first new vector q1q_1. This removes any component of v2v_2 that is parallel to q1q_1, leaving only the orthogonal part u2u_2.

u2=v2(q1Tv2)q1u_2 = v_2 - (q_1^T v_2) q_1

Then normalize u2u_2 to get q2q_2.

q2=u2u2q_2 = \frac{u_2}{\|u_2\|}

Step 3: The Third Vector and Beyond...

The pattern continues. To find u3u_3, take v3v_3 and subtract its projections onto *all* previously found orthonormal vectors (q1q_1 and q2q_2).

u3=v3(q1Tv3)q1(q2Tv3)q2u_3 = v_3 - (q_1^T v_3) q_1 - (q_2^T v_3) q_2

Then normalize.

A Concrete Example
Let's orthonormalize the basis v1=[3,4]v_1 = [3, 4] and v2=[1,5]v_2 = [1, 5].

Step 1: Process v1v_1

v1=32+42=5\|v_1\| = \sqrt{3^2 + 4^2} = 5

q1=15[3,4]=[0.6,0.8]q_1 = \frac{1}{5}[3, 4] = [0.6, 0.8]

Step 2: Process v2v_2

Subtract the projection of v2v_2 onto q1q_1:

q1Tv2=(0.6)(1)+(0.8)(5)=4.6q_1^T v_2 = (0.6)(1) + (0.8)(5) = 4.6

u2=[1,5]4.6[0.6,0.8]=[1,5][2.76,3.68]=[1.76,1.32]u_2 = [1, 5] - 4.6 \cdot [0.6, 0.8] = [1, 5] - [2.76, 3.68] = [-1.76, 1.32]

Normalize u2u_2:

u2=(1.76)2+(1.32)2=3.0976+1.7424=4.84=2.2\|u_2\| = \sqrt{(-1.76)^2 + (1.32)^2} = \sqrt{3.0976 + 1.7424} = \sqrt{4.84} = 2.2

q2=12.2[1.76,1.32]=[0.8,0.6]q_2 = \frac{1}{2.2}[-1.76, 1.32] = [-0.8, 0.6]

Result

Our new orthonormal basis is {q1=[0.6,0.8],q2=[0.8,0.6]}\{ q_1=[0.6, 0.8], q_2=[-0.8, 0.6] \}.

**Up Next:** We will assemble these new orthonormal vectors into a matrix `Q` to form the QR Decomposition.