
A=[1 1; 1 -1; 1 3];
b=[1; 0; 0];

%------------------------
% EQUAZIONI NORMALI.
%------------------------
X=A'*A;

R=choleski(X);

L=R';
b1=A'*b;
y=L\b1;
x=L'\y

res=norm(A*x-b,2); % RESIDUO (NORMA 2). 
fprintf('\n \t [EN][RES,2]: %2.2e \n',res);

%------------------------
% METODO QR.
%------------------------
[Q,R]=qr(A);
x = R\(R'\(A'*b));
r = b - A*x;
e = R\(R'\(A'*r));
x = x + e

res=norm(A*x-b,2); % RESIDUO (NORMA 2).

diagR=diag(R);     % CALCOLO RANGO.
rankA=sum(sign(abs(diag(R))));
fprintf('\n \t [QR][RES,2]: %2.2e [RANK]: %5.0f \n',res,rankA);

%------------------------
% METODO SVD.
%------------------------
% DIMS: A=(m,n); x=(n,1); b=(m,1); U=(m,m); S=(m,n); V=(n,n).

[U,S,V] = svd(A);

[min_diag_S,min_diag_S_index]=min(diag(S));

if min_diag_S == 0
    rankA=min_diag_S_index-1;
else
    rankA=min_diag_S_index;
end

k=rankA;

U=U'; U=U(1:k,:);
S=S(1:k,1:k);
coeffs=U*b./diag(S);
V=V(:,1:k);
x=(coeffs'*V)'

res=norm(A*x-b,2); % RESIDUO (NORMA 2).
fprintf('\n \t [SVD][RES,2]: %2.2e [RANK]: %5.0f \n',res,rankA);

