These are personal study and translation notes for reference only; the original course materials belong to MIT OpenCourseWare and their respective rights holders.
The Gram-Schmidt algorithm takes a set of n independent vectors a1,a2,…,an (the columns of A) and produces a set of n orthonormal vectors q1,q2,…,qn (the columns of Q).
For each column j:
Start with aj.
Subtract off its projections onto all previously computed qi (for i<j). The result is a vector v that is orthogonal to all earlier qi.
Normalize v by its length to produce the unit vector qj.
The inner products qiTaj are collected into the upper-triangular matrix R, satisfying A=QR. R is upper triangular because qiTaj=0 when i>j (later q's are orthogonal to earlier 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, Q contains orthonormal columns and R is upper triangular such that A=QR.
If you "undo" the last step and the intermediate steps, column j is:
R(j,j)qj=aj−i=1∑j−1R(i,j)qi
Moving the sum to the left gives column j of the matrix multiplication A=QR:
aj=i=1∑jR(i,j)qi
3. Modified Gram-Schmidt
The crucial change from aj to v in line 4 of the code gives modified Gram-Schmidt.
In exact arithmetic, R(i,j)=qiTaj is the same as qiTv (where v has already had its projections onto earlier q1,…,qi−1 subtracted). This is because the new qi is orthogonal to those earlier directions.
In floating-point arithmetic, however, orthogonality is not perfect. Computing R(i,j) from the currentv (which has already been partially orthogonalized) rather than from the original aj gives significantly better numerical stability. Everybody uses v at that step in the code. This is the standard modified Gram-Schmidt algorithm.
The length of the first column of A. When we normalize a1 to get q1, this length becomes the first diagonal entry of R.
R(2,2)=2
∥v∥
The length of the orthogonalized vector v after subtracting the projection of a2 onto q1. This is the second diagonal entry of R.
R(1,2)=−1
q1Ta2
The inner product between q1 and a2. This is the projection coefficient -- how much of a2 lies in the direction of q1. It appears in the upper-triangular part of R because q1 comes before q2 in the ordering.
R(2,1)=0
q2Ta1
Zero because q2 is orthogonal to a1 by construction (equivalently, a1 has no component in the q2 direction). This is what makes R upper triangular.