繁体   English   中英

快速稀疏矩阵乘法

[英]Fast sparse matrix multiplication

对于类,我必须为稀疏矩阵编写自己的线性方程求解器。 我可以自由地为稀疏矩阵使用任何类型的数据结构,我必须实现几个解,包括共轭渐变。

我想知道是否有一种着名的方法来存储稀疏矩阵,使得与向量的乘法相对较快。

现在我的稀疏矩阵基本上实现了一个包装的std::map< std::pair<int, int>, double> ,它存储数据(如果有的话)。 这将矩阵与向量的乘法转换为O(n²)复杂度到O(n²log(n)),因为我必须对每个矩阵元素进行查找。 我查看了耶鲁稀疏矩阵格式,似乎元素的检索也在O(log(n))中,所以我不确定它是否会更快。

作为参考,我有一个800x800矩阵,填充了5000个条目。 使用共轭梯度法大约需要450秒来解决这样的系统。

您认为使用其他数据结构可以更快地完成吗?

谢谢!

最常见的选择是CSC或CSR存储 这些对于矩阵向量乘法都是有效的。 如果你必须自己编写,那么编写这些乘法例程也很容易。

也就是说,耶鲁存储也产生非常有效的矩阵向量乘法。 如果您正在执行矩阵元素查找,那么您误解了如何使用该格式。 我建议你研究一些标准的稀疏库来学习如何实现矩阵向量乘法。

即使使用当前存储,您也可以执行O(n)复杂度的矩阵乘法。 我见过的所有稀疏矩阵向量乘法算法归结为相同的步骤。 例如,考虑y = Ax。

  1. 将结果向量归零,y。
  2. 初始化矩阵的非零元素的迭代器,A。
  3. 得到矩阵的下一个非零元素,A [i,j]说。 请注意,i,j的模式不遵循常规模式。 它只是反映了存储A的非零元素的顺序。
  4. y [i] + = A [i,j] * x [j]
  5. 如果有更多A元素,请转到3。

我怀疑你正在编写经典的双循环密集乘法代码:

for (i=0; i<N; i++)
    for (j=0; j<N; j++)
        y[i] += A[i,j]*x[j]

这就是导致你执行查找的原因。

但我并不是说你坚持使用std::map存储。 这不会超级高效。 我推荐CSC主要是因为它是使用最广泛的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM