不一致的numpy复数乘法结果

时间:2018-05-22 03:15:40

标签: python numpy complex-numbers

考虑以下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从发件人到接收者收到值ab(我验证它们已被正确接收),那么该产品是错误的,特别是{{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是否随意设置虚部,因为它比产品的实部小得多?

1 个答案:

答案 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进程只是设置真实部分,那么你应该得到不同的东西。