考虑以下Python代码,它将两个复数相乘:
import numpy as np
a = np.matrix('28534314.10478439+28534314.10478436j').astype(np.complex128)
b = np.matrix('-1.39818115e+09+1.39818115e+09j').astype(np.complex128)
#Verify values
print(a)
print(b)
c=np.dot(a.getT(),b)
#Verify product
print(c)
现在,当我在Spyder上运行时,产品应该是-7.979228021897728000e+16 + 48j
,这是正确的。但是,如果我在MPI4py程序上通过MPI从发件人到接收者收到值a
和b
(我验证它们已被正确接收),那么该产品是错误的,特别是{{1} }。在这两种情况下,我使用的是numpy 1.14.3和Python 2.7.14。后一种情况的唯一区别是,在接收值之前,我用以下内容初始化矩阵:
-7.97922801e+16+28534416.j
然后函数a = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)
b = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)
为它们提供正确的值。
如果MPI::Comm::Irecv()
和a
正确但b
错误,后一种情况会出现什么问题? numpy是否随意设置虚部,因为它比产品的实部小得多?
答案 0 :(得分:0)
首先,这并不涉及mp
内容,但因为它是在评论中提出的:
np.matrix
可以接受一个字符串参数,并从中生成一个数字矩阵。还要注意形状是(1,1)
In [145]: a = np.matrix('28534314.10478439+28534314.10478436j')
In [146]: a
Out[146]: matrix([[28534314.10478439+28534314.10478436j]])
In [147]: a.dtype
Out[147]: dtype('complex128')
输入np.array
的字符串会产生一个字符串:
In [148]: a = np.array('28534314.10478439+28534314.10478436j')
In [149]: a
Out[149]: array('28534314.10478439+28534314.10478436j', dtype='<U36')
但省略引号,我们得到复数数组,其中包含shape()(0d):
In [151]: a = np.array(28534314.10478439+28534314.10478436j)
In [152]: a
Out[152]: array(28534314.10478439+28534314.10478436j)
In [153]: a.dtype
Out[153]: dtype('complex128')
这些价值观的产物:
In [154]: b = np.array(-1.39818115e+09+1.39818115e+09j)
In [155]: a*b # a.dot(b) same thing
Out[155]: (-7.979228021897728e+16+48j)
不使用mp
,我假设初始化和设置是这样的:
In [179]: x=np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)
In [180]: x[:]=a
In [181]: x
Out[181]: matrix([[28534314.10478439+28534314.10478436j]])
In [182]: y=np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)
In [183]: y[:]=b
In [184]: y
Out[184]: matrix([[-1.39818115e+09+1.39818115e+09j]])
In [185]: x*y
Out[185]: matrix([[-7.97922802e+16+48.j]])
值得尝试np.zeros_like
而不是np.empty_like
。这将确保虚部为0,而不是随机的。然后,如果mp
进程只是设置真实部分,那么你应该得到不同的东西。