scipy.linalg.block_diag与scipy.sparse.block_diag在效率方面



我有一个关于 scipy 构建块对角矩阵的方式的问题。我期望创建一个稀疏块对角矩阵会比创建一个密集的对角矩阵更快、更有效(因为稀疏压缩(。但事实证明并非如此(或者我使用了某种低效的方法(:

from timeit import default_timer as timer
import numpy as np
from scipy.sparse import block_diag as bd_sp
from scipy.linalg import block_diag as bd_la
m = [np.identity(1)] * 10000
before = timer()
res = bd_sp(m)
timer()-before
#takes 33.79 secs
before = timer()
res = bd_la(*m)
timer()-before
#takes 0.069 secs

我错过了什么?提前感谢您的回复。

In [625]: [np.identity(1)*i for i in range(1,5)]
Out[625]: [array([[1.]]), array([[2.]]), array([[3.]]), array([[4.]])]
In [626]: sparse.block_diag(_)
Out[626]: 
<4x4 sparse matrix of type '<class 'numpy.float64'>'
    with 4 stored elements in COOrdinate format>
In [627]: _.A
Out[627]: 
array([[1., 0., 0., 0.],
       [0., 2., 0., 0.],
       [0., 0., 3., 0.],
       [0., 0., 0., 4.]])

block_diag使用bmat来连接元素。 bmat 从所有元素制作coo矩阵,并将它们的属性与偏移量组合在一起,并创建一个新的coo矩阵。代码是可读的Python。

构建自己的data, row, col数组可能更有效。 block_diag是一种方便,对于组合几个大矩阵来说很好,但在组合许多小矩阵时效率不高。

linalg函数也是Python(而且很短(。 If 创建正确形状的 out 数组,并插入具有切片索引的块。 这是一种高效的密集阵列解决方案。 大部分艰苦的工作都是在编译numpy代码中完成的。

稀疏矩阵在

执行矩阵乘法(以及相关的 linalg 求解器(时会更快。 对于大多数其他操作(包括初始化(,它们比等效的密集代码慢。 当问题太大时,它们也很有价值。

最新更新