35

在 Python numpy 中,有一个unwrap函数:

通过将大于不连续的绝对跳跃更改为沿给定轴的 2*pi 补码来展开弧度相位 p。

现在,我想做相反的功能。如何包装一系列阶段?例如,如何转换所有角度以将它们限制在 -π 和 π 之间?

显而易见的方法是执行以下操作:

for i, a in enumerate(phases):
    while a < pi:
        a += 2 * pi
    while a > pi:
        a -= 2 * pi
    phases[i] = a

但是有没有更简单/更快的方法?

4

4 回答 4

51
phases = (phases + np.pi) % (2 * np.pi) - np.pi
于 2013-04-10T13:56:43.220 回答
12
import numpy as np
phases = np.arctan2(np.sin(phases), np.cos(phases))

这是因为 sin(phases)/cos(phases) == tan(phases)。我们使用反正切函数返回相位(模 2π)。在数学上,反正切函数是多值的,因此在编程语言中通常定义为以固定间隔返回相位。

双参数反正切函数,即np.arctan2(numerator, denominator),与常规反正切函数相同,只是它跟踪分子和分母的符号,因此能够返回模 2π 的相位,而不是np.arctan(numerator/denominator)仅返回能够返回相位模 π。Numpy 的arctan2函数实现被定义为返回 [-π, +π] 范围内的相位,这是 OP 请求的范围。

附加说明:此 arctan2 方法直接来自复数表示,并且在数学上完全等价于:

phases = np.angle(np.exp(1j*phases))

这可能更直观。事实上,numpy 的angle函数arctan2在幕后使用来分离指数的虚部和实部,即正弦和余弦。

于 2015-03-24T16:11:57.587 回答
8

此答案与 sega_sai 答案略有不同,即:

phases = ( phases + np.pi) % (2 * np.pi ) - np.pi

这将阶段映射到 [-pi, pi) -> 这意味着 pi 映射到 -pi

此处显示:

In [27]: phases = np.pi

In [28]: phases = ( phases + np.pi) % (2 * np.pi ) - np.pi

In [29]: print phases
-3.14159265359

这是完全合法的,但如果你想要 (-pi, pi] 的映射,那么

乘以购买操作的输入和输出 -1。像这样:

phases =  (( -phases + np.pi) % (2.0 * np.pi ) - np.pi) * -1.0
于 2015-08-28T08:03:00.800 回答
0

我已经在我的实用程序库haggis中实现了类似于建议功能的功能。该功能haggis.math.ang_diff_min完全符合您的要求。您可以手动设置一个完整圆的定义,如果您想使用度数或梯度或任何其他任意角度度量,这很好:

 ang_diff_min(phases, 0)
于 2022-01-18T11:49:07.297 回答