Точечный продукт для корреляции с комплексными числами - PullRequest
1 голос
/ 12 июля 2020

Хорошо, на этот вопрос, вероятно, есть очень простой ответ, но я долго искал безуспешно ...

Я хочу получить скалярное произведение 2 комплексных чисел в комплексе- самолет-пространство. Однако и np.dot, и np.vdot дают неправильный результат.

Пример того, что Я ХОЧУ сделать:

a = 1+1j
b = 1-1j
dot(a,b) == 0

Что я получаю на самом деле:

np.dot(a,b) == 2+0j
np.vdot(a,b) == 0-2j
np.conj(a)*b == 0-2j

Я могу получить то, что хочу, используя это довольно неуклюжее выражение (отредактируйте для удобства чтения):

a.real*b.real + a.imag*b.imag

Но я очень удивлен, что не нашел для этого красивого ufun c. Не существует? Я не ожидал, что мне придется писать свой собственный ufun c для векторизации такой распространенной операции.

Отчасти меня беспокоит то, что кажется, что мое выражение выполняет много дополнительной работы, извлекая реальные / мнимые части, когда они уже должны быть в соседних ячейках памяти (учитывая, что a, b на самом деле уже объединены в тип данных, например complex64). Это может вызвать довольно серьезное замедление. правильно соотносить сложные данные. Вот корреляционное изображение для ребят, которые мне помогли!

введите описание изображения здесь

1 Ответ

1 голос
/ 12 июля 2020

Для массивов и np.complex скаляров, но не для простых python complex чисел, вы можете использовать viewcast как float. Например:

a = np.exp(1j*np.arange(4))
b = np.exp(-1j*np.arange(4))
a
# array([ 1.        +0.j        ,  0.54030231+0.84147098j,
#        -0.41614684+0.90929743j, -0.9899925 +0.14112001j])
b
# array([ 1.        -0.j        ,  0.54030231-0.84147098j,
#        -0.41614684-0.90929743j, -0.9899925 -0.14112001j])
ar = a[...,None].view(float)
br = b[...,None].view(float)
ar
# array([[ 1.        ,  0.        ],
#        [ 0.54030231,  0.84147098],
#        [-0.41614684,  0.90929743],
#        [-0.9899925 ,  0.14112001]])
br
# array([[ 1.        , -0.        ],
#        [ 0.54030231, -0.84147098],
#        [-0.41614684, -0.90929743],
#        [-0.9899925 , -0.14112001]])

Теперь, например, все попарные скалярные произведения:

np.inner(ar,br)
# array([[ 1.        ,  0.54030231, -0.41614684, -0.9899925 ],
#        [ 0.54030231, -0.41614684, -0.9899925 , -0.65364362],
#        [-0.41614684, -0.9899925 , -0.65364362,  0.28366219],
#        [-0.9899925 , -0.65364362,  0.28366219,  0.96017029]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...