function [Q,R] = mgs2(A); % MGS2 computes QR reduced factors by modified Gram-Schmidt, but it completes % Q in the rank-deficient case, and it estimates rank(A) % demonstration/testing: % >> m=17; n=7; A=randn(m,n); A(:,n)=A(:,2); A(:,n-1)=A(:,n-2)+A(:,n-3); % >> [Q,R]=mgs2(A); norm(A-Q*R,1), norm(Q'*Q-eye(n,n),1), rank(A) [m n] = size(A); rank = n; % reduces this if it finds very small vectors R = zeros(n,n); scal = max(max(abs(A))); tol = (max([m n]) + 10) * eps; if scal == 0 Q = eye(m,n); return, end Q = A; for i = 1:n r = norm(Q(:,i),2); R(i,i) = r; if abs(r)/scal < tol warning(['column ' num2str(i) ' gives nearly zero internal vector']) rank = rank - 1; w = randn(m,1); for j = 1:i-1 w = w - (Q(:,j)' * w) * Q(:,j); end w = w / norm(w,2); else w = Q(:,i)/r; end Q(:,i) = w; for j = i+1:n r = w'*Q(:,j); R(i,j) = r; Q(:,j) = Q(:,j)-r*w; end end if rank < n warning(['input essentially rank-deficient: rank = ' num2str(rank) '?']) end