我有一个简单的 Matlab 脚本,旨在计算矩阵的奇异值. 是一个随机密集方阵,大小为,其中 100 个奇异值被限制为 0(尽管最后一个细节似乎对我的问题无关紧要)。
我在 Matlab 中通过[Uk, Sk, Vk] = svds(A, k);
. 根据文档,svds
使用 Lanczos bidiagonalization 来计算这些值。我查看了函数定义 ( edit svds
) 并没有看到任何相关的分支,例如,根据不同的条件在后台使用不同的算法。但是,当我增加,我得到非常好奇的缩放/性能:
文档提到
增加 k 有时可以提高性能,尤其是当矩阵具有重复的奇异值时。
但我将此解释为意味着性能会有所提高,而不是大幅减少总运行时间。
这是 Lanczos 双对角化的已知行为(我不太熟悉的算法)吗?或者有没有人猜测为什么会有这样的表现svds
?
编辑:这是我的脚本的最小版本,因此其他人可以尝试重现:
results = [];
A = rand(5000, 5000);
[U, S, V] = svd(A);
dS = diag(S);
dS(4900:5000) = 0;
A = U*diag(dS)*V;
b = rand(5000, 1);
for k = 100 : 100 : 4500
tic
[Uk, Sk, Vk] = svds(A,k);
Ahat = Vk*diag(1./diag(Sk))*Uk';
test = Ahat * b;
time_k = toc
results = [results; k time_k];
end
plot(results(:,1), results(:,2))