矩阵(scipy稀疏) - 矩阵(密集; numpy数组)乘法效率

时间:2017-04-21 15:18:42

标签: python numpy scipy

我是一名从事地球物理反演的研究员。这可能需要求解线性系统: Au = rhs 。这里 A 通常是稀疏矩阵,但rhs和u可以是密集矩阵或向量。为了进行基于梯度的反演,我们需要灵敏度计算,并且它需要许多矩阵 - 矩阵和矩阵 - 向量乘法。最近我在矩阵(稀疏) - 矩阵(密集)乘法中发现了一种奇怪的行为,下面是一个例子:

import numpy as np
import scipy.sparse as sp
n = int(1e6)
m = int(100)
e = np.ones(n)
A = sp.spdiags(np.vstack((e, e, e)), np.array([-1, 0, 1]), n, n)
A = A.tocsr()
u = np.random.randn(n,m)

%timeit rhs = A*u[:,0]
#10 loops, best of 3: 22 ms per loop    
%timeit rhs = A*u[:,:10]
#10 loops, best of 3: 98.4 ms per loop
%timeit rhs = A*u
#1 loop, best of 3: 570 ms per loop​

当我增加密集矩阵u的大小乘以稀疏矩阵A时,我期望计算时间几乎呈线性增长(例如,假设我的第二个A*u[:,:10] 220 ms最后一个A*u[:,:10] 2.2s)。但是,它比我预期的要快得多。相反,矩阵向量乘法比矩阵 - 矩阵乘法慢得多。有人可以解释原因吗?此外,是否有一种有效的方法来提升Matrix-vector乘法效率与Matrix-Matrix乘法相似的效率?

1 个答案:

答案 0 :(得分:2)

如果查看source code,可以看到csr_matvec(实现矩阵向量乘法)在C代码中实现为一个简单的求和循环,而csr_matvecs(实现矩阵 - 矩阵乘法)实现为对axpy BLAS例程的调用。根据您的安装链接到哪个BLAS库,这样的调用比用于矩阵向量乘法的简单C实现更有效。这可能是你看到矩阵向量乘法的原因很慢。

更改scipy以便在矩阵向量的情况下调用BLAS可能对包有用。