Numpy 复杂相角处理中的可能错误

Possible Bug in Numpy Complex Phase Angle Handling

我正在尝试确定两个叠加的复平面波的相位。有两种简单的实现方式:

  1. 首先是把每一个都写成一个复数数组,然后相加。
  2. 第二种是在幕后做一些数学运算,让numpy写出准确的结果。

两个结果不一致。这是一个 MWE:

from pylab import *

x = linspace(0,2*pi)

k1 = 1
k2 = 2

planewave1 = exp(1j*k1*x)
planewave2 = exp(1j*k2*x)

superwave = planewave1 + planewave2

rho = 2 + 2*cos( (k2-k1)*x )
theta = (k1+k2)/2 * x

superwave_theory = sqrt(rho) * exp(1j*theta)

phase_Numpy  = angle(superwave)
phase_theory = angle(superwave_theory) # = theta % pi

每种方法计算出的这些相位角不一致:

为什么结果不一致?

理论计算表明叠加波的相位是单个波相位的平均值。我在各个平面波的相位上点了点,从中我们可以看出这是正确的(橙色线在“内部”的黑色虚线之间的中间)。

当然相位角继续超过 Pi,但是 numpy 的 angle() 将结果包装在 (-pi,pi].

这两种方法一致,直到较慢的平面波环绕到-pi。从图中可以清楚地看出,numpy 方法(蓝线)位于包裹的第一阶段线和 unwrapped 较慢阶段之间。这不应该发生,并给出一个由 pi 关闭的结果。

对我来说,这似乎是 NumPy 处理复杂算术的一个错误,但我可能以某种方式滥用了代码。

我正在使用 NumPy 1.21.1

您的公式不适用于所有 x。考虑 x = 3.5:

In [49]: import cmath, math

In [50]: k1 = 1

In [51]: k2 = 2

In [52]: x = 3.5

这是复指数的总和:

In [53]: cmath.exp(1j*k1*x) + cmath.exp(1j*k2*x)
Out[53]: (-0.18255443294749174+0.3062033710291692j)

这是你的公式:

In [54]: math.sqrt(2 + 2*math.cos((k2 - k1)*x))*cmath.exp(1j*(k1 + k2)*x/2)
Out[54]: (0.18255443294749166-0.3062033710291693j)

请注意,使用公式计算的结果符号错误(相当于相差π)。

是真的

(exp(1j*k1*x) + exp(1j*k2*x))**2 = (2 + 2*cos((k1 - k2)*x))*exp(1j*(k1+k2)*x)

(我希望我们在 Whosebug 上有 LaTeX。)为了得到你的公式,你必须取两边的平方根,但复杂的平方根是多值的。您的公式为 x > π 选择了错误的分支。