为什么这些计算不能给出相同的结果?
import numpy as np
M = 1000
N = 500
tab = np.random.random_sample([N,M])
vectors = np.random.random_sample([P,M])
np.einsum('ij,kj->ki',tab,vectors) - np.dot(tab,vectors.T).T
为什么np.einsum('ij,kj->ki',tab,vectors)
不等于np.dot(tab,vectors.T).T
?
请注意,就运行时而言,np.dot(tab,vectors.T).T
比np.einsum('ij,kj->ki',tab,vectors)
快。
答案 0 :(得分:1)
这是一个精确的问题。让我们看一下尺寸较小的np.einsum('ij,kj->ki',tab,vectors) - np.dot(tab,vectors.T).T
import numpy as np
M = 5
N = 5
P = 2
tab = np.random.random_sample([N,M])
vectors = tab
print np.einsum('ij,kj->ki',tab,vectors) - np.dot(tab,vectors.T).T
>> [[ 0.00000000e+00 2.22044605e-16 2.22044605e-16 2.22044605e-16
0.00000000e+00]
[ 2.22044605e-16 0.00000000e+00 2.22044605e-16 0.00000000e+00
0.00000000e+00]
[ 2.22044605e-16 2.22044605e-16 0.00000000e+00 -4.44089210e-16
0.00000000e+00]
[ 2.22044605e-16 0.00000000e+00 -4.44089210e-16 0.00000000e+00
0.00000000e+00]
[ -2.22044605e-16 0.00000000e+00 0.00000000e+00 0.00000000e+00
0.00000000e+00]]
正如我们所看到的,它提供了一个非常小的"彩车。现在让int
dtype代替float
import numpy as np
import random as rd
M = 5
N = 5
P = 2
tab = np.array([ rd.randint(-10,10) for i in range(N*M) ]).reshape(N,M)
vectors = tab
print np.einsum('ij,kj->ki',tab,vectors) - np.dot(tab,vectors.T).T
>> [[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 0]]
所以,你试图做的事情永远不会给出零数组,原因很简单np.einsum
的浮点比np.dot()
更精确(因为第一个&的正号) #39;结果)
答案 1 :(得分:0)
结果与某些数值精度相同。差异看起来像
[ 5.68434189e-14, 0.00000000e+00, 8.52651283e-14, ...,
8.52651283e-14, 0.00000000e+00, -5.68434189e-14],
[ -8.52651283e-14, 0.00000000e+00, -5.68434189e-14, ...,
0.00000000e+00, 5.68434189e-14, -8.52651283e-14],
[ 1.42108547e-13, 5.68434189e-14, 0.00000000e+00, ...,
1.13686838e-13, -5.68434189e-14, 1.13686838e-13]])
正如@wflynny在评论中提到的,在数组a
和b
上执行此测试的最佳方法是
np.allclose(a, b)
一种可能更快的方法是:
from numpy.core.umath_tests import matrix_multiply
matrix_multiply(tab, vectors.T).T
答案 2 :(得分:0)
@YXD
matrix_multiply非常慢!
使用以下代码:
代码:
d