快速稀疏矩阵乘法

时间:2013-03-28 22:55:01

标签: c++ matrix linear-algebra sparse-matrix matrix-multiplication

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

我想知道是否存在一种存储稀疏矩阵的着名方法,以便使用向量进行乘法相对较快。

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:23)

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

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

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

  1. 将结果向量归零,y。
  2. 为矩阵的非零元素A。
  3. 初始化迭代器
  4. 获取矩阵的下一个非零元素,A [i,j]说。请注意,i,j的模式不遵循常规模式。它只是反映了存储A的非零元素的顺序。
  5. y [i] + = A [i,j] * x [j]
  6. 如果有更多元素A,请转到3。
  7. 我怀疑你正在编写经典的双循环密集乘法代码:

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

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

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