复数相关的点积运算

3

好的,这个问题可能有一个非常简单的答案,但我已经搜索了相当长的时间,没有找到...

我想在复平面空间中获得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

但是我很惊讶没有找到一个好的ufunc来完成这个任务。它不存在吗?我没想到要编写自己的ufunc来向量化这样一个常见操作。

我的担忧之一是,看起来我的表达式在提取实部/虚部时做了很多额外的工作,而它们应该已经在相邻的内存位置中(考虑到a、b实际上已经结合在像complex64这样的数据类型中)。这可能会导致非常严重的减速。

** 编辑

最终,我使用Numba定义了一个ufunc:

@vectorize
def cdot(a, b):
    return (a.real*b.real + a.imag*b.imag)

这使我能够正确地关联复杂的数据。以下是一张相关性图像,供帮助我的人们参考!

enter image description here


这可能是因为复数的点乘与实数不同吗?https://math.stackexchange.com/questions/2459814/what-is-the-dot-product-of-complex-vectors - Emile Akbarzadeh
1
我认为你误解了复平面中的点积。通常情况下,(1 + 1j) * (1 - 1j) == 2,而不是 0 - Gorisanson
@Gorisanson - 我正在尝试计算复数的点积,将其视为 x=实部、y=虚部。换句话说,就好像它们是复平面向量一样。 - Colin Marcus
@ColinMarcus 你的意思是好像它们在一个真实的平面上一样吗? - Gorisanson
是的,抱歉术语有些妨碍。 - Colin Marcus
显示剩余4条评论
1个回答

1

对于数组和 np.complex 标量,但不适用于普通的 python complex 数字,您可以将其转换为浮点数进行查看。例如:

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]])

这真的很有趣!我理解viewcasting对于“纯Python复杂”不起作用是因为它没有将实数/虚数存储在相邻的内存地址中?而且,viewcasting是否适用于任意大的复数数组,或者在某些点上地址相邻性会失效? - Colin Marcus
@ColinMarcus 我认为这更多是因为Python数字没有实现数组接口。我不知道数组大小是否有任何影响。话虽如此,我不能百分之百确定内存布局是否得到保证。理论上可能是一些实现细节。 - Paul Panzer
你的inner等于np.outer(a, np.conj(b)).real - hpaulj
@hpaulj 是的,但是需要一半的算术运算。 - Paul Panzer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接