Numpy 复杂相角处理中的可能错误
Possible Bug in Numpy Complex Phase Angle Handling
我正在尝试确定两个叠加的复平面波的相位。有两种简单的实现方式:
- 首先是把每一个都写成一个复数数组,然后相加。
- 第二种是在幕后做一些数学运算,让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 > π 选择了错误的分支。
我正在尝试确定两个叠加的复平面波的相位。有两种简单的实现方式:
- 首先是把每一个都写成一个复数数组,然后相加。
- 第二种是在幕后做一些数学运算,让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 > π 选择了错误的分支。