现在,我需要在C++中使用Eigen3.3.8来实现稀疏矩阵切片,但是我无法像Python中的scipy那样快速地实现。
例如,A是一个形状稀疏矩阵(1000000,1000000),index是我想从A中选择的列表。
当我这样写的时候:
A=A[index,:]
它花费了0.5114s。
当我这样写的时候:
def extractor(indices,N)::
indptr=np.arange(len(indices)+1)
data=np.ones(len(indices))
shape=(len(indices),N)
return sparse.csr_matrix((data,indices,indptr), shape=shape)
A=extractor(index,A.shape[0])*A
它花费3.381s。(这个想法来自Sparse matrix slicing using list of int)。
那么如何实现快速的CSR矩阵切片呢?
2条答案
按热度按时间n3h0vuf21#
对于一个更小的矩阵,我的提取器代码会更慢,但只有2倍。
提取器:
nnz
匹配:稍微慢一点,但没有你的例子那么快。
这比我5年前测试的要大。
因为我还有其他事情要做,所以我不打算尝试测试其他情况--更大的
M
和更长的idx
。欢迎您探索
sparse
代码,看看他们是否改变了计算,可能以各种方式简化了它,我的重建没有捕捉到。kt06eoxx2#
正如我之前在注解中提到的,你列出的两个方法是不等价的。带有索引列表的
A[index]
改变了输出的形状。它还可以置换或复制行。这可以像下面这样相当快地实现:如果索引是排序的,运行速度会更快,但在其他排列方式下仍然可以工作。InnerIterator可能是Eigen-3.4中的新功能。
第二个选项是与对角矩阵相乘,它保留了元素的原始形状和顺序。它可以像这样完成:
这仍然是相当快的。遗憾的是,似乎没有一个版本使用稀疏向量作为对角线。在我的测试中,使用
prune
方法更快: