为什么scipy稀疏数组和numpy数组的乘法函数给出不同的结果?

时间:2019-09-11 13:47:35

标签: python numpy sparse-matrix

我在Python 2.7中有两个矩阵:一个密集的 A_dense 和另一个稀疏的矩阵 A_sparse 。我对计算元素加法和求和感兴趣。有两种方法可以使用:使用numpy's multiplicationscipy sparse multiplication。我希望它们能给出完全相同的结果,但执行时间有所不同。但是我发现对于某些矩阵大小,它们给出的结果不同。

import numpy as np
from scipy import sparse
L=2000
np.random.seed(2)
rand_x=np.random.rand(L)
A_sparse_init=np.diag(rand_x, -1)+np.diag(rand_x, 1)
A_sparse=sparse.csr_matrix(A_sparse_init)
A_dense=np.random.rand(L+1,L+1)
print np.sum(A_sparse.multiply(A_dense))-np.sum(np.multiply(A_dense[A_sparse.nonzero()], A_sparse.data))

输出:

1.1368683772161603e-13

如果我选择L = 2001,则输出为:

0.0

要使用两种不同的乘法方法检查差异的大小依赖性,我写道:

L=100
np.random.seed(2)
N_loop=100
multiply_diff_arr=np.zeros(N_loop)
for i in xrange(N_loop):
    rand_x=np.random.rand(L)
    A_sparse_init=np.diag(rand_x, -1)+np.diag(rand_x, 1)
    A_sparse=sparse.csr_matrix(A_sparse_init)
    A_dense=np.random.rand(L+1,L+1)
    multiply_diff_arr[i]=np.sum(A_sparse.multiply(A_dense))-np.sum(np.multiply(A_dense[A_sparse.nonzero()], A_sparse.data))
    L+=1

我得到了以下情节: enter image description here

有人可以帮助我了解发生了什么吗?我们难道不希望两种方法之间的差异至少是1e-18而不是1e-13吗?

1 个答案:

答案 0 :(得分:1)

我没有完整的答案,但这可能有助于找到答案:

在后台,scipy.sparse将转换为coo格式并执行以下操作:

ret = self.tocoo()
if self.shape == other.shape:
    data = np.multiply(ret.data, other[ret.row, ret.col])

然后的问题是,为什么这两个操作会给出不同的结果:

ret = A_sparse.tocoo()
c = np.multiply(ret.data, A_dense[ret.row, ret.col])
ret.data = c.view(type=np.ndarray)

c.sum() - ret.sum()

-1.1368683772161603e-13

编辑:

差异源于首先add.reduce在哪个轴上的不同默认值。 例如:

A_sparse.multiply(A_dense).sum(axis=1).sum()
A_sparse.multiply(A_dense).sum(axis=0).sum()

Numpy首先默认为0