www.gusucode.com > matlab 案例源码 matlab代码程序 > matlab/UseQRDecompositionToComputeSVDOfNearlySingularMatrixExample.m
%% Use QR Decomposition to Compute SVD of Nearly Singular Matrix % Compute the 10 smallest singular values of a nearly singular matrix. rng default format shortg B = spdiags([repelem([1; 1e-7], [198, 2]) ones(200, 1)], [0 1], 200, 200); s1 = svds(B,10,'smallest') %% % The warning indicates that |svds| fails to calculate the proper singular % values. The failure with |svds| is because of the gap between the % smallest and second smallest singular values. |svds(...,'smallest')| % needs to invert |B|, which leads to large numerical error. %% % For comparison, compute the exact singular values using |svd|. s = svd(full(B)); s = s(end-9:end) %% % In order to reproduce this calculation with |svds|, do a QR decomposition % of |B|. The singular values of the triangular matrix |R| are the same as % for |B|. [Q,R,p] = qr(B,0); %% % Plot the norm of each row of |R|. rownormR = sqrt(diag(R*R')); semilogy(rownormR) hold on; semilogy(size(R, 1), rownormR(end), 'ro') %% % The last entry in |R| is nearly zero, which causes instability in the % solution. %% % Prevent this entry from corrupting the good parts of the solution by % setting the last row of |R| to be exactly zero. R(end,:) = 0; %% % Use |svds| to find the 10 smallest singular values of |R|. The results % are comparable to those obtained by |svd|. sr = svds(R,10,'smallest') %% % To compute the singular vectors of |B| using this method, transform the % left and right singular vectors using |Q| and the permutation vector |p|. [U,S,V] = svds(R,20,'s'); U = Q*U; V(p,:) = V;