use*_*609 0 matlab linear-algebra
这是我的测试功能:
function diff = svdtester()
y = rand(500,20);
[U,S,V] = svd(y);
%{
y = sprand(500,20,.1);
[U,S,V] = svds(y);
%}
diff_mat = y - U*S*V';
diff = mean(abs(diff_mat(:)));
end
Run Code Online (Sandbox Code Playgroud)
有两个非常相似的部分:一个找到随机矩阵的SVD,另一个找到随机稀疏矩阵的SVD.无论您选择评论哪一个(现在第二个被注释掉),我们计算原始矩阵与其SVD组件的乘积之间的差异,并返回平均绝对差值.
使用rand/svd时,典型的返回(平均误差)值约为8.8e-16,基本为零.当使用sprand/svds时,典型的返回值约为0.07,考虑到稀疏矩阵的开始是90%0,这是相当糟糕的.
我是否误解了SVD应该如何用于稀疏矩阵,或者这些函数有问题?
是的,行为svds有点不同svd.根据MATLAB的文档:
[U,S,V] = svds(A,...)返回三个输出参数,如果A是m-by-n:
U被m-by-k与正交列
S是k-by-k对角线
V被n-by-k与正交列
U*S*V'是最接近秩k逼近A
事实上,通常k会有些事情6,所以你会得到相当"粗鲁"的近似.为了得到更精确的近似指定k为min(size(y)):
[U, S, V] = svds(y, min(size(y)))
Run Code Online (Sandbox Code Playgroud)
你会得到与之相同数量级的错误svd.
PS此外,MATLAB的文件说:
注意
svds最好用于查找大型稀疏矩阵的一些奇异值.要找到这种矩阵的所有奇异值,svd(full(A))通常会表现得更好svds(A,min(size(A))).