Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 小圆点问题_Python_Numpy_Matrix Multiplication - Fatal编程技术网

Python 小圆点问题

Python 小圆点问题,python,numpy,matrix-multiplication,Python,Numpy,Matrix Multiplication,我正在使用NumPy中的点函数来执行矩阵乘法 如果我正确理解矩阵乘法,则以下所有方法应给出完全相同的输出: print(L.dot(Linv)[3,9]) # 1.6335244394160178 print((L @ Linv)[3,9]) # 1.6335244394160178 print(np.einsum("ab,bc->ac", L, Linv)[3,9]) # 0.0 print(np.sum(L[3,:] * Linv[:, 9])) # 0.0 然而

我正在使用NumPy中的点函数来执行矩阵乘法

如果我正确理解矩阵乘法,则以下所有方法应给出完全相同的输出:

print(L.dot(Linv)[3,9]) # 1.6335244394160178
print((L @ Linv)[3,9]) # 1.6335244394160178
print(np.einsum("ab,bc->ac", L, Linv)[3,9]) # 0.0
print(np.sum(L[3,:] * Linv[:, 9])) # 0.0
然而,我得到了不同的输出。numpy的@和点函数到底在做什么?指南中指出,如果参数是矩阵,则执行矩阵乘法

我在这里添加脚本的要点以重现结果(L和Linv数据):

编辑:

我在Ubuntu 20.04上,使用Anaconda和python 3.8.5(GCC 7.3.0),numpy 1.19.2:

np.show\u config()
的结果是

blas_mkl_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/home/darth-vader/anaconda3/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/home/darth-vader/anaconda3/include']
blas_opt_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/home/darth-vader/anaconda3/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/home/darth-vader/anaconda3/include']
lapack_mkl_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/home/darth-vader/anaconda3/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/home/darth-vader/anaconda3/include']
lapack_opt_info:
    libraries = ['mkl_rt', 'pthread']
    library_dirs = ['/home/darth-vader/anaconda3/lib']
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['/home/darth-vader/anaconda3/include']
使用示例数组(复制和粘贴字符串很好):

对于所有[3,9]元素,我得到0

In [90]: np.allclose(X.dot(Y),X@Y)
Out[90]: True
In [91]: np.allclose(X.dot(Y),np.einsum('ab,bc->ac',X,Y))
Out[91]: True
In [92]: (X@Y)[3,9]
Out[92]: 0.0
我想我找到了问题所在, 文本或python安装没有问题,但这是矩阵本身的问题。 通过替换

# Write the data
fp = open("_L_", "w")
fp.write(L)
fp.close()

fp = open("_Linv_", "w")
fp.write(Linv)
fp.close()


# Load them as numpy array
L = np.loadtxt("_L_")
Linv = np.loadtxt("_Linv_")
与:

问题解决了(两者给出相同的结果,不同于双精度获得的结果)。事实上,Linv的元件大到1e17,这是双精度数值精度的极限。 因此,如果通过按不同顺序对元素求和来执行逐列矩阵乘法,则截断错误的作用将不同。这就是为什么np.dot和matmul给出与einsum和sum不同的结果的原因


我认为,在某些numpy版本中,其原因可能取决于blas、lapack和mkl的配置,这可能会改变dot和matmul函数的行为。

这确实是有关联的。我尝试用anaconda更新到numpy的最新版本,但它仍然给了我错误的答案(dot和einsum结果之间的allclose对我来说是错误的,dot给出了错误的结果,形状是正确的)。是否存在一个numpy测试套件来检查一切是否正常工作?我认为python/numpy iInstallation没有任何问题。关于数组,文本版本无法传达某些信息。您是否在新的python会话中测试过该代码?我的机器直接运行linux/pip安装,我想这是因为我有anaconda版本的numpy,安装了MKL库。通过这种方式,numpy的点函数以不同的方式实现,以利用多处理,这就是我们的结果不同的原因。您使用的是什么操作系统?
np.show\u config()
显示了什么?@Eric我在python版本的答案中添加了详细信息。
In [90]: np.allclose(X.dot(Y),X@Y)
Out[90]: True
In [91]: np.allclose(X.dot(Y),np.einsum('ab,bc->ac',X,Y))
Out[91]: True
In [92]: (X@Y)[3,9]
Out[92]: 0.0
# Write the data
fp = open("_L_", "w")
fp.write(L)
fp.close()

fp = open("_Linv_", "w")
fp.write(Linv)
fp.close()


# Load them as numpy array
L = np.loadtxt("_L_")
Linv = np.loadtxt("_Linv_")
L = np.genfromtxt(L.splitlines(), dtype = np.float128)
Linv = np.genfromtxt(Linv.splitlines(), dtype = np.float128)