i asked question in math stackexchange, seems didn't enough attention there asking here. https://math.stackexchange.com/questions/1729946/why-do-we-say-svd-can-handle-singular-matrx-when-doing-least-square-comparison?noredirect=1#comment3530971_1729946
i learned tutorials svd should more stable qr decomposition when solving least square problem, , able handle singular matrix. following example wrote in matlab seems support opposite conclusion. don't have deep understanding of svd, if @ questions in old post in math stackexchange , explain me, appreciate lot.
i use matrix have large condition number(e+13). result shows svd larger error(0.8) qr(e-27)
% linear regression between y , x data= [ 47.667483331 -122.1070832; 47.667483331001 -122.1070832 ]; x = data(:,1); y = data(:,2); x_1 = [ones(length(x),1),x]; %% %svd method [u,d,v] = svd(x_1,'econ'); beta_svd = v*diag(1./diag(d))*u'*y; %% qr method(here 1 can use "\" operator, same result tested. wrote down backward substitution educate myself) [q,r] = qr(x_1) %now backward substitution [nr nc] = size(r) beta_qr=[] y_1 = q'*y = nc:-1:1 s = y_1(i) j = m:-1:i+1 s = s - r(i,j)*beta_qr(j) end beta_qr(i) = s/r(i,i) end svd_error = 0; qr_error = 0; i=1:length(x) svd_error = svd_error + (y(i) - beta_svd(1) - beta_svd(2) * x(i))^2; qr_error = qr_error + (y(i) - beta_qr(1) - beta_qr(2) * x(i))^2; end
you svd-based approach same pinv function in matlab (see pseudo-inverse , svd). missing though (for numerical reasons) using tolerance value such singular values less tolerance treated zero.
if refer edit pinv.m, can see following (i won't post exact code here because file copyrighted mathworks):
[u,s,v] = svd(a,'econ'); s = diag(s); tol = max(size(a)) * eps(norm(s,inf)); % .. use above tolerance truncate singular values invs = diag(1./s); out = v*invs*u'; in fact pinv has second syntax can explicitly specify tolerance value pinv(a,tol) if default 1 not suitable...
so when solving least-squares problem of form minimize norm(a*x-b), should understand pinv , mldivide solutions have different properties:
x = pinv(a)*bcharacterized factnorm(x)smaller norm of other solution.x = a\bhas fewest possible nonzero components (i.e sparse).
using example (note rcond(a) small near machine epsilon):
data = [ 47.667483331 -122.1070832; 47.667483331001 -122.1070832 ]; = [ones(size(data,1),1), data(:,1)]; b = data(:,2); let's compare 2 solutions:
x1 = a\b; x2 = pinv(a)*b; first can see how mldivide returns solution x1 1 0 component (this valid solution because can solve both equations multiplying 0 in b + a*0 = b):
>> sol = [x1 x2] sol = -122.1071 -0.0537 0 -2.5605 next see how pinv returns solution x2 smaller norm:
>> nrm = [norm(x1) norm(x2)] nrm = 122.1071 2.5611 here error of both solutions acceptably small:
>> err = [norm(a*x1-b) norm(a*x2-b)] err = 1.0e-11 * 0 0.1819 note use mldivide, linsolve, or qr give pretty same results:
>> x3 = linsolve(a,b) warning: matrix close singular or badly scaled. results may inaccurate. rcond = 2.159326e-16. x3 = -122.1071 0 >> [q,r] = qr(a); x4 = r\(q'*b) x4 = -122.1071 0
Comments
Post a Comment