1

这是我的测试功能:

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

4

1 回答 1

8

是的, 的行为svdssvd. 根据 MA​​TLAB 的文档:

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

Um正交k列组成

Sk对角线k_

Vn正交k列组成

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

事实上,通常k会是关于 的东西6,所以你会得到相当“粗鲁”的近似值。要获得更精确的近似值,请指定kmin(size(y))

[U, S, V] = svds(y, min(size(y)))

并且您将得到与 情况相同数量级的误差svd

PS 另外,MATLAB 的文档说:

Notesvds最适合用于查找大型稀疏矩阵的几个奇异值。要找到这样一个矩阵的所有奇异值,svd(full(A))通常会比svds(A,min(size(A))).

于 2013-04-06T00:00:12.297 回答