I'm trying to write a simple implementation of Singular Value Decomposition (SVD). I'm using the one-sided Jacobi algorithm since it seemed like a simple one. The algorithm is described here and there's a simple Matlab code for that here (exercise 4). I've implemented the same code and it works ok and by that I mean that SVD(A) = U * S * V' (or any other notation that's used) and for some matrices the result is the same as what Matlab's SVD produces (except this function doesn't sort the singular values). But my problem is that when the matrix A has a 0 singular value, U and V are no longer unitary matrices as they should be!
Is there a way to update this algorithm so that it works for cases with 0 singular value too? If not, is there another algorithm for SVD that's as easy to implement? Any help is appreciated.
Here's my Matlab code that's basically same as the one in the link above, just completed and with minor changes.
function [U,S,V] = jacobi_SVD(A)
TOL=1.e-4;
n=size(A,1);
U=A';
V=eye(n);
converge=TOL+1;
while converge>TOL
converge=0;
for i=1:n-1
for j=i+1:n
% compute [alpha gamma;gamma beta]=(i,j) submatrix of U*U'
alpha=sumsqr(U(i, :));
beta=sumsqr(U(j, :));
gamma=sum(U(i, :).* U(j, :));
converge=max(converge,abs(gamma)/sqrt(alpha*beta));
% compute Jacobi rotation that diagonalizes
% [alpha gamma;gamma beta]
zeta=(beta-alpha)/(2*gamma);
t=sign(zeta)/(abs(zeta)+sqrt(1+zeta^2));
c= 1.0 / (sqrt(1 + t * t));
s= c * t;
% update columns i and j of U
t=U(i, :);
U(i, :)=c*t-s*U(j, :);
U(j, :)=s*t+c*U(j, :);
% update matrix V of right singular vectors
t=V(i, :);
V(i, :)=c*t-s*V(j, :);
V(j, :)=s*t+c*V(j, :);
end
end
end
% the singular values are the norms of the columns of U
% the left singular vectors are the normalized columns of U
for j=1:n
singvals(j)=norm(U(j, :));
U(j, :)=U(j, :)/singvals(j);
end
S=diag(singvals);
U = U';
V = V'; %return V, not V'
end