svds不适用于某些矩阵?

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应该如何用于稀疏矩阵,或者这些函数有问题?

VHa*_*avy 7

是的,行为svds有点不同svd.根据MATLAB的文档:

[U,S,V] = svds(A,...)返回三个输出参数,如果Am-by- n:

Um-by- k与正交列

Sk-by- k对角线

Vn-by- k与正交列

U*S*V'是最接近秩k逼近A

事实上,通常k会有些事情6,所以你会得到相当"粗鲁"的近似.为了得到更精确的近似指定kmin(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))).