AoZai
AoZai

Reading Notice

These are personal study and translation notes for reference only; the original course materials belong to MIT OpenCourseWare and their respective rights holders.

Gram-Schmidt in 9 Lines of MATLAB

QR factorization — MIT 18.06 · Ch.1 / 1

Gram-Schmidt Orthogonalization -- MIT 18.06 Notes

1. The Gram-Schmidt Algorithm

The Gram-Schmidt algorithm takes a set of nn independent vectors a1,a2,,an\mathbf{a}_1, \mathbf{a}_2, \dots, \mathbf{a}_n (the columns of AA) and produces a set of nn orthonormal vectors q1,q2,,qn\mathbf{q}_1, \mathbf{q}_2, \dots, \mathbf{q}_n (the columns of QQ).

For each column jj:

  1. Start with aj\mathbf{a}_j.
  2. Subtract off its projections onto all previously computed qi\mathbf{q}_i (for i<ji < j). The result is a vector v\mathbf{v} that is orthogonal to all earlier qi\mathbf{q}_i.
  3. Normalize v\mathbf{v} by its length to produce the unit vector qj\mathbf{q}_j.

The inner products qiTaj\mathbf{q}_i^T \mathbf{a}_j are collected into the upper-triangular matrix RR, satisfying A=QRA = QR. RR is upper triangular because qiTaj=0\mathbf{q}_i^T \mathbf{a}_j = 0 when i>ji > j (later q\mathbf{q}'s are orthogonal to earlier a\mathbf{a}'s -- that is the whole point of the algorithm).


2. The Complete 9-Line MATLAB Code

[m,n] = size(A);
Q = zeros(m,n); R = zeros(n,n);
for j = 1:n
    % Gram-Schmidt orthogonalization
    v = A(:,j);                 % begins as column j of A
    for i = 1:j-1
        R(i,j) = Q(:,i)' * A(:,j);
        % modify A(j) to v for more accuracy
        v = v - R(i,j) * Q(:,i);
        % subtract the projection (qi^T aj) qi
    end
    % v is now perpendicular to all of q1,...,qj-1
    R(j,j) = norm(v);
    Q(:,j) = v / R(j,j);        % normalize v to be the next unit vector qj
end

After the loop, QQ contains orthonormal columns and RR is upper triangular such that A=QRA = QR.

If you "undo" the last step and the intermediate steps, column jj is:

R(j,j)qj=aji=1j1R(i,j)qiR(j,j)\,\mathbf{q}_j = \mathbf{a}_j - \sum_{i=1}^{j-1} R(i,j)\,\mathbf{q}_i

Moving the sum to the left gives column jj of the matrix multiplication A=QRA = QR:

aj=i=1jR(i,j)qi\mathbf{a}_j = \sum_{i=1}^{j} R(i,j)\,\mathbf{q}_i

3. Modified Gram-Schmidt

The crucial change from aj\mathbf{a}_j to v\mathbf{v} in line 4 of the code gives modified Gram-Schmidt.

In exact arithmetic, R(i,j)=qiTajR(i,j) = \mathbf{q}_i^T \mathbf{a}_j is the same as qiTv\mathbf{q}_i^T \mathbf{v} (where v\mathbf{v} has already had its projections onto earlier q1,,qi1\mathbf{q}_1, \dots, \mathbf{q}_{i-1} subtracted). This is because the new qi\mathbf{q}_i is orthogonal to those earlier directions.

In floating-point arithmetic, however, orthogonality is not perfect. Computing R(i,j)R(i,j) from the current v\mathbf{v} (which has already been partially orthogonalized) rather than from the original aj\mathbf{a}_j gives significantly better numerical stability. Everybody uses v\mathbf{v} at that step in the code. This is the standard modified Gram-Schmidt algorithm.


4. A 2x2 Example

A=[4231]A = \begin{bmatrix} 4 & -2 \\ 3 & 1 \end{bmatrix}

The Gram-Schmidt process factors AA into QRQR:

A=QR=15[4334][5102]A = QR = \frac{1}{5}\begin{bmatrix} 4 & -3 \\ 3 & 4 \end{bmatrix} \begin{bmatrix} 5 & -1 \\ 0 & 2 \end{bmatrix}

Step 1: Normalize a1\mathbf{a}_1 to q1\mathbf{q}_1

a1=[43],a1=42+32=25=5\mathbf{a}_1 = \begin{bmatrix} 4 \\ 3 \end{bmatrix}, \qquad \|\mathbf{a}_1\| = \sqrt{4^2 + 3^2} = \sqrt{25} = 5 q1=a1a1=15[43]\mathbf{q}_1 = \frac{\mathbf{a}_1}{\|\mathbf{a}_1\|} = \frac{1}{5}\begin{bmatrix} 4 \\ 3 \end{bmatrix}

The diagonal entry R(1,1)=a1=5R(1,1) = \|\mathbf{a}_1\| = 5.


Step 2: Subtract the projection of a2\mathbf{a}_2 onto q1\mathbf{q}_1

a2=[21]\mathbf{a}_2 = \begin{bmatrix} -2 \\ 1 \end{bmatrix}

First compute the inner product (this becomes R(1,2)R(1,2)):

R(1,2)=q1Ta2=15(4)(2)+15(3)(1)=85+35=1R(1,2) = \mathbf{q}_1^T \mathbf{a}_2 = \frac{1}{5}(4)(-2) + \frac{1}{5}(3)(1) = -\frac{8}{5} + \frac{3}{5} = -1

Now subtract the projection of a2\mathbf{a}_2 onto q1\mathbf{q}_1:

v=a2R(1,2)q1=[21](1)15[43]=[21]+[4/53/5]=[6/58/5]=25[34]\mathbf{v} = \mathbf{a}_2 - R(1,2)\,\mathbf{q}_1 = \begin{bmatrix} -2 \\ 1 \end{bmatrix} - (-1)\frac{1}{5}\begin{bmatrix} 4 \\ 3 \end{bmatrix} = \begin{bmatrix} -2 \\ 1 \end{bmatrix} + \begin{bmatrix} 4/5 \\ 3/5 \end{bmatrix} = \begin{bmatrix} -6/5 \\ 8/5 \end{bmatrix} = \frac{2}{5}\begin{bmatrix} -3 \\ 4 \end{bmatrix}

Step 3: Normalize v\mathbf{v} to q2\mathbf{q}_2

v=(65)2+(85)2=3625+6425=10025=4=2\|\mathbf{v}\| = \sqrt{\left(-\frac{6}{5}\right)^2 + \left(\frac{8}{5}\right)^2} = \sqrt{\frac{36}{25} + \frac{64}{25}} = \sqrt{\frac{100}{25}} = \sqrt{4} = 2

This is R(2,2)=2R(2,2) = 2.

q2=vv=12[6/58/5]=15[34]\mathbf{q}_2 = \frac{\mathbf{v}}{\|\mathbf{v}\|} = \frac{1}{2}\begin{bmatrix} -6/5 \\ 8/5 \end{bmatrix} = \frac{1}{5}\begin{bmatrix} -3 \\ 4 \end{bmatrix}

Verification

Q=[4/53/53/54/5],R=[5102]Q = \begin{bmatrix} 4/5 & -3/5 \\ 3/5 & 4/5 \end{bmatrix}, \qquad R = \begin{bmatrix} 5 & -1 \\ 0 & 2 \end{bmatrix} QR=15[4334][5102]=15[4(5)+(3)(0)4(1)+(3)(2)3(5)+4(0)3(1)+4(2)]=15[2010155]=[4231]=AQR = \frac{1}{5}\begin{bmatrix} 4 & -3 \\ 3 & 4 \end{bmatrix} \begin{bmatrix} 5 & -1 \\ 0 & 2 \end{bmatrix} = \frac{1}{5}\begin{bmatrix} 4(5)+(-3)(0) & 4(-1)+(-3)(2) \\ 3(5)+4(0) & 3(-1)+4(2) \end{bmatrix} = \frac{1}{5}\begin{bmatrix} 20 & -10 \\ 15 & 5 \end{bmatrix} = \begin{bmatrix} 4 & -2 \\ 3 & 1 \end{bmatrix} = A

5. Explanation of the Entries in RR

Entry Value Meaning
R(1,1)=5R(1,1) = 5 a1\|\mathbf{a}_1\| The length of the first column of AA. When we normalize a1\mathbf{a}_1 to get q1\mathbf{q}_1, this length becomes the first diagonal entry of RR.
R(2,2)=2R(2,2) = 2 v\|\mathbf{v}\| The length of the orthogonalized vector v\mathbf{v} after subtracting the projection of a2\mathbf{a}_2 onto q1\mathbf{q}_1. This is the second diagonal entry of RR.
R(1,2)=1R(1,2) = -1 q1Ta2\mathbf{q}_1^T \mathbf{a}_2 The inner product between q1\mathbf{q}_1 and a2\mathbf{a}_2. This is the projection coefficient -- how much of a2\mathbf{a}_2 lies in the direction of q1\mathbf{q}_1. It appears in the upper-triangular part of RR because q1\mathbf{q}_1 comes before q2\mathbf{q}_2 in the ordering.
R(2,1)=0R(2,1) = 0 q2Ta1\mathbf{q}_2^T \mathbf{a}_1 Zero because q2\mathbf{q}_2 is orthogonal to a1\mathbf{a}_1 by construction (equivalently, a1\mathbf{a}_1 has no component in the q2\mathbf{q}_2 direction). This is what makes RR upper triangular.
Previous
© MIT OpenCourseWare  |  18.06 Linear Algebra  |  Gilbert Strang  |  Spring 2010
ocw.mit.edu  ·  CC BY-NC-SA 4.0