numpy 角度函数 returns 相同输入的不同答案?
The numpy angle function returns different answers for the same input?
我正在使用 Python 3.7.7 和 numpy 1.19.1。这是代码:
import numpy as np
a = 55.74947517067784019673 + 0j
print(f'{-a == -1 * a}, {np.angle(-a)}, {np.angle(-1 * a)}')
这是输出:
True, -3.141592653589793, 3.141592653589793
我有两个问题:
- 为什么角度函数对于相同的输入给出不同的输出?
- 根据文档,角度输出范围是
(-pi, pi]
,那么为什么输出之一是 -np.pi
?
对于 1) 打印 -a
和 -1*a
,您会发现它们是不同的。
-a
Out[4]: (-55.74947517067784-0j)
-1*a
Out[5]: (-55.74947517067784+0j) # note +0j not -0j
在不知道 numpy 实现细节的情况下,虚部的符号可能用于计算角度...这可以解释为什么这种退化的情况会给出不同的结果。
对于 2) 这对我来说看起来像是一个错误或 doco 错误...
如果您查看 the source of the np.angle
, it uses the function np.arctan2
. Now, according to the numpy docs,np.arctan2
使用底层 C 库,它具有以下规则:
注意 +0 和 -0 是不同的浮点数,+inf 和 -inf 也是如此。
使用 +/-0
进行计算时会导致不同的行为。所以,在这种情况下,规则是:
y: +/- 0
x: <0
angle: +/- pi
现在,如果你尝试:
a = 55.74947517067784019673
print(f'{-a == -1 * a}, {np.angle(-a)}, {np.angle(-1 * a)}')
#True, 3.141592653589793, 3.141592653589793
如果你尝试:
a = 55.74947517067784019673 + 0j
print(-a)
#(-55.74947517067784-0j)
print(-1*a)
#(-55.74947517067784+0j)
print(f'{-a == -1 * a}, {np.angle(-a)}, {np.angle(-1 * a)}')
#True, -3.141592653589793, 3.141592653589793
与库协议内联。
关于你的第二个问题,我猜这是一个 typo/mistake 因为 np.arctan2
doc 说:
以弧度为单位的角度数组,在 [-pi, pi] 范围内。如果 x1 和 x2 都是标量,则这是一个标量。
-a
与 -1*a
的解释:
首先,55.74947517067784019673 + 0j
不是复数的构造,只是复数的浮点数加法 (要显式构造复数,请使用 complex(55.74947517067784019673, 0.0)
并注意整数没有带符号的零,只有浮点数有)。 -a
只是简单地恢复符号并且很容易解释。让我们看看当我们计算 -1*a
:
时会发生什么
为简单起见,假设 a = 55.5 + 0j
- 首先
a = 55.5+0j
转换为complex(55.5, 0.0)
- 第二个
-1
等于complex(-1.0, 0.0)
- 然后
complex(-1.0, 0.0)*complex(55.5, 0.0)
等于complex((-1.0*55.5 - 0.0*0.0), (-1.0*0.0 + 0.0*55.5))
等于complex((-55.5 - 0.0), (-0.0 + 0.0))
然后等于complex(-55.5, 0.0)
.
请注意 -0.0+0.0
等于 0.0
并且符号规则仅适用于此 link 中提到的乘法和除法,并在下面的评论中引用。为了更好地理解它,请看这个:
print(complex(-1.0, -0.0)*complex(55.5, 0.0))
#(-55.5-0j)
其中虚部为(-0.0*55.5 - 1.0*0.0) = (-0.0 - 0.0) = -0.0
我正在使用 Python 3.7.7 和 numpy 1.19.1。这是代码:
import numpy as np
a = 55.74947517067784019673 + 0j
print(f'{-a == -1 * a}, {np.angle(-a)}, {np.angle(-1 * a)}')
这是输出:
True, -3.141592653589793, 3.141592653589793
我有两个问题:
- 为什么角度函数对于相同的输入给出不同的输出?
- 根据文档,角度输出范围是
(-pi, pi]
,那么为什么输出之一是-np.pi
?
对于 1) 打印 -a
和 -1*a
,您会发现它们是不同的。
-a
Out[4]: (-55.74947517067784-0j)
-1*a
Out[5]: (-55.74947517067784+0j) # note +0j not -0j
在不知道 numpy 实现细节的情况下,虚部的符号可能用于计算角度...这可以解释为什么这种退化的情况会给出不同的结果。
对于 2) 这对我来说看起来像是一个错误或 doco 错误...
如果您查看 the source of the np.angle
, it uses the function np.arctan2
. Now, according to the numpy docs,np.arctan2
使用底层 C 库,它具有以下规则:
注意 +0 和 -0 是不同的浮点数,+inf 和 -inf 也是如此。
使用 +/-0
进行计算时会导致不同的行为。所以,在这种情况下,规则是:
y: +/- 0
x: <0
angle: +/- pi
现在,如果你尝试:
a = 55.74947517067784019673
print(f'{-a == -1 * a}, {np.angle(-a)}, {np.angle(-1 * a)}')
#True, 3.141592653589793, 3.141592653589793
如果你尝试:
a = 55.74947517067784019673 + 0j
print(-a)
#(-55.74947517067784-0j)
print(-1*a)
#(-55.74947517067784+0j)
print(f'{-a == -1 * a}, {np.angle(-a)}, {np.angle(-1 * a)}')
#True, -3.141592653589793, 3.141592653589793
与库协议内联。
关于你的第二个问题,我猜这是一个 typo/mistake 因为 np.arctan2
doc 说:
以弧度为单位的角度数组,在 [-pi, pi] 范围内。如果 x1 和 x2 都是标量,则这是一个标量。
-a
与 -1*a
的解释:
首先,55.74947517067784019673 + 0j
不是复数的构造,只是复数的浮点数加法 (要显式构造复数,请使用 complex(55.74947517067784019673, 0.0)
并注意整数没有带符号的零,只有浮点数有)。 -a
只是简单地恢复符号并且很容易解释。让我们看看当我们计算 -1*a
:
为简单起见,假设 a = 55.5 + 0j
- 首先
a = 55.5+0j
转换为complex(55.5, 0.0)
- 第二个
-1
等于complex(-1.0, 0.0)
- 然后
complex(-1.0, 0.0)*complex(55.5, 0.0)
等于complex((-1.0*55.5 - 0.0*0.0), (-1.0*0.0 + 0.0*55.5))
等于complex((-55.5 - 0.0), (-0.0 + 0.0))
然后等于complex(-55.5, 0.0)
.
请注意 -0.0+0.0
等于 0.0
并且符号规则仅适用于此 link 中提到的乘法和除法,并在下面的评论中引用。为了更好地理解它,请看这个:
print(complex(-1.0, -0.0)*complex(55.5, 0.0))
#(-55.5-0j)
其中虚部为(-0.0*55.5 - 1.0*0.0) = (-0.0 - 0.0) = -0.0