Numpy - -1 的平方根留下一个小的实部
也许这是一个算法问题,但以下代码
numpy.power((-1+0j),0.5)
产生以下输出
(6.1230317691118863e-17+1j)
code>
类似的表达式例如 numpy.power(complex(-1),.5)
产生相同的结果,但是 - numpy.sqrt(complex(-1))
产生 1j
的预期结果。显然,结果应该没有真正的部分,所以我错过了一些关键的东西,或者我是否需要将此报告给 numpy 开发人员。
如果有人问,不,我不能舍入实部(我需要完全精确的计算),是的,我需要使用幂函数。
Perhaps this is an algorithmic issue, but the following piece of code
numpy.power((-1+0j),0.5)
produces the following output
(6.1230317691118863e-17+1j)
Analogous expressions e.g. numpy.power(complex(-1),.5)
yield the same result, however - numpy.sqrt(complex(-1))
yields the expected result of 1j
. Clearly the result should have no real part, so I am missing something crucial or do I need to report this to numpy dev's.
In case anyone asks, no I can not round away the real part (I need full precision for this calculation) and yes I need to use the power function.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
所发生的情况是,-1 的平方根计算为 exp(iphase/2),其中(-1 的)相位大约 π。事实上,
这说明-1的相位只有π到几个1e-17;除以 2 的相位也仅约为 π/2,其余弦仅约为 0,因此您的结果(结果的实部是这个余弦)。
问题最终源于这样一个事实:只有固定的、有限数量的浮点数。数字 π 不在浮点数列表中,因此只能近似表示。 π/2 也无法精确表示,因此 -1 的平方根的实部是 π/2 的浮点近似的余弦(因此余弦不同于 0)。
因此,Python 的
numpy.power(complex(-1), .5)
的近似值最终是由于浮点数的限制,并且可能在许多语言中找到。通过数字幂的实现,您所观察到的结果与浮点限制有关。在您的示例中,平方根是通过评估复数的模块和参数来计算的(本质上是通过 log 函数,它返回 log(module) + i 阶段)。另一方面,
cmath.sqrt(-1)
恰好给出1j
,因为它使用不同的方法,并且不会遇到的浮点近似问题。 (-1+0j)**0.5
(根据 TonyK 的建议)。What happens is that the square root of -1 is calculated as exp(i phase/2), where the phase (of -1) is approximately π. In fact,
This shows that the phase of -1 is π only up to a few 1e-17; the phase divided by 2 is also only approximately π/2, and its cosine is only approximately 0, hence your result (the real part of your result is this cosine).
The problem comes ultimately from the fact that there is only a fixed, finite number of floating point numbers. The number π is not in the list of floating point numbers, and can therefore only be represented approximately. π/2 cannot be exactly represented either, so that the real part of the square root of -1 is the cosine of the floating point approximation of π/2 (hence a cosine that differs from 0).
So, Python's approximate value for
numpy.power(complex(-1), .5)
is ultimately due to a limitation of floating point numbers, and is likely to be found in many languages.What you observe is connected to this floating point limitation, through the implementation of the power of a number. In your example, the square root is calculated by evaluating the the module and the argument of your complex number (essentially via the log function, which returns log(module) + i phase). On the other hand,
cmath.sqrt(-1)
gives exactly1j
because it uses a different method, and does not suffer from the floating point approximation problem of(-1+0j)**0.5
(as suggested by TonyK).这是复数实现 numpy.power() 的副作用。 stdlib 也存在同样的问题。
It's a side effect of the implementation of
numpy.power()
for complex numbers. The stdlib exhibits the same issue.尝试 numpy.real_if_close()。
请参阅:接近时为实数
Try numpy.real_if_close().
See: Real if close