Непоследовательные результаты комплексного умножения - PullRequest
0 голосов
/ 22 мая 2018

Рассмотрим следующий код 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)

Теперь продукт должен быть -7.979228021897728000e+16 + 48j, что правильно при запуске на Spyder.Однако, если я получаю значения a и b от отправителя к получателю через MPI в программе MPI4py (я проверяю, что они были получены правильно), продукт неверен и, в частности, -7.97922801e+16+28534416.j.В обоих случаях я использую numpy 1.14.3 и Python 2.7.14.Единственное отличие в последнем случае состоит в том, что до получения значений я инициализирую матрицы с помощью:

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 верны, а c неверен?NumPy произвольно устанавливает мнимую часть, так как она значительно меньше реальной части продукта?

1 Ответ

0 голосов
/ 22 мая 2018

Во-первых, это не относится к материалу 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 просто устанавливает реальную часть, вы должны получить что-то другое.

...