这是我的测试功能:
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
有两个非常相似的部分:一个找到随机矩阵的SVD,另一个找到随机稀疏矩阵的SVD。无论你选择评论哪一个(现在第二个被注释掉),我们计算原始矩阵与其SVD组件的乘积之间的差异,并返回平均绝对差值。
使用rand / svd时,典型的返回(平均误差)值约为8.8e-16,基本为零。当使用sprand / svds时,典型的返回值大约为0.07,考虑到稀疏矩阵的开始是90%0,这是非常糟糕的。
我是否误解了SVD应如何用于稀疏矩阵,或者这些函数有问题?
答案 0 :(得分:6)
是的,svds
的行为与svd
略有不同。根据MATLAB的文档:
[U,S,V] = svds(A,...)
返回三个输出参数,如果A
为m
,则为n
:
U
是m
- by -k
,其标准为正交列
S
是k
- 按 -k
对角线
V
是n
- by -k
,其标准为正交列最接近的等级
U*S*V'
是与[{1}}k
近似值
事实上,通常A
会成为关于k
的事情,所以你会得到相当“粗鲁”的近似。要获得更精确的近似值,请将6
指定为k
:
min(size(y))
并且您将获得与[U, S, V] = svds(y, min(size(y)))
相同数量级的错误。
P.S。此外,MATLAB的文件说:
注意
svd
最适合用于查找大型稀疏矩阵的一些奇异值。要查找此类矩阵的所有奇异值,svds
的效果通常会优于svd(full(A))
。