如何计算稀疏矩阵的矩阵乘积?我知道传统的数学方法,但似乎效率不高。有没有可以改进的方法?
我考虑过将第一个矩阵存储为CSR形式,第二个矩阵存储为CSC形式,因此由于行和列向量已排序,我不必搜索需要的特定行/列,但我想这并没有多大帮助。
如何计算稀疏矩阵的矩阵乘积?我知道传统的数学方法,但似乎效率不高。有没有可以改进的方法?
我考虑过将第一个矩阵存储为CSR形式,第二个矩阵存储为CSC形式,因此由于行和列向量已排序,我不必搜索需要的特定行/列,但我想这并没有多大帮助。
在强调以下内容不应实现自己的稀疏矩阵包并且如果必须实现,应该先阅读Tim Davis关于稀疏线性代数的书籍的前提下,以下是一种实现稀疏矩阵乘法的方法。
通常的朴素密集矩阵乘法如下所示。
C = 0
for i {
for j {
for k {
C(i, j) = C(i, j) + (A(i, k) * B(k, j))
}
}
}
由于加法满足交换律,我们可以随意改变循环索引的顺序。让我们将 j
放在最外层,将 i
放在最内层。
C = 0
for j {
for k {
for i {
C(i, j) = C(i, j) + (A(i, k) * B(k, j))
}
}
}
将所有矩阵以CSC形式存储。由于j
是最外层,我们按列对B
和C
进行操作(但不涉及A
)。中间循环是在k
上进行的,即B
的行数,方便之处在于,我们不需要访问B
中值为零的条目。这使得外部两个循环按自然顺序遍历B
的非零条目。内部循环通过将C
的第j
列增加A
的第k
列乘以B(k,j)
来实现。为了简化操作,我们将当前列的C
密集存储,并将这一列为非零的索引集合,作为一个列表/密集布尔数组。通过通常的隐式初始化技巧,我们避免编写整个C
或布尔数组。