如何在 MATLAB 中计算大型稀疏矩阵的秩

计算科学 matlab 稀疏矩阵 矩阵
2021-12-20 14:04:43

我有兴趣计算相当大的等级,最大的数量级为 x,稀疏矩阵的整数都是 0、1 或 -1。我一直在尝试使用 Matlab 来实现这一点。特别是,我的方法是使用 QR 因式分解——将我的矩阵分解为,其中是置换矩阵,是正交是上三角矩阵——然后计算非的对角线上的零条目106106TTP=QRPQRR

使用 Matlab 的内置QR 函数,以下 Matlab 代码计算我的一些示例的正确排名。(我已经确认了一些针对 rank(full(T)) 的较小矩阵的排名。)

load(‘FILE_NAME.dat') 
T = spconvert(FILE_NAME);

tic

[Q,R,P]=qr(T);
[m,n] = size(T);
tol = max(size(T))*eps*abs(R(1,1));
r = 0;

while (r<min(m,n) & abs(R(r+1,r+1)) >= tol)
r = r+1;
end

tim=toc
r

也就是说,即使对于我的一些较小的矩阵,此代码似乎也相当慢且内存密集。例如,在其中一个约为 70,000 x ~50,000 的矩阵上,上述代码在 64 GB 服务器上需要花费数小时和大部分内存。(我注意到的一件事是,如果我将上面计算的 Q、R 和 P 保存到 .mat 文件中,文件大小似乎会快速增长。例如,当初始矩阵为 ~15,000 x 时,.mat 文件为 ~1 GB ~15,000)

是否有更好的(更快或更少内存密集型)方法来计算大型稀疏矩阵的等级?例如,一种更有效的实现 QR 分解的方法,甚至是完全不同于 QR 的方法?

3个回答

您可以做两件事来显着减少计算时间和使用的内存。

首先,你没有使用 Q 矩阵,所以不要让 MATLAB 来计算它。既然是密集的,那肯定会节省很多内存。你可以简单地做:

R=qr(T);

其次,在稀疏分解中,方程的顺序会对分解过程中的填充量和计算时间产生巨大影响。即使对于发生旋转以确保数值稳定性的 QR 和 LU 分解也是如此。

稀疏 QR 分解的一个有效策略是首先对列重新排序以保持稀疏性。有时这会在内存使用和分解时间上产生巨大差异——取决于矩阵。可以这样做,如下所示:

[m,n]=size(T);
q=colamd(T, [n m]);
R=qr(T(:,q));

Davis 在这篇论文中讨论了该算法(和实现)的等级揭示特性的细节:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.319.4864&rep=rep1&type=pdf

揭示 LU 分解的等级(例如 LUSOL)可能是您想要的:

http://web.stanford.edu/group/SOL/software/lusol/

如果您知道秩会很小(比如小于 100)并且您的矩阵是正方形的,请使用eigs(A,100)来获得 100 个最大的特征值。特征值使用稀疏矩阵技术求解,速度更快。在这种情况下,无需创建完整矩阵。

另一方面,如果您知道秩将接近矩阵大小,则可以尝试eigs(A,100,0),它应该为您提供 100 个最小的特征值。