14

也许这是一个算法问题,但是下面的代码

numpy.power((-1+0j),0.5)

产生以下输出

(6.1230317691118863e-17+1j)

类似的表达式例如numpy.power(complex(-1),.5)产生相同的结果,但是 -numpy.sqrt(complex(-1))产生预期的结果1j。显然结果应该没有真正的部分,所以我错过了一些重要的东西,或者我需要向 numpy dev 报告这个。

如果有人问,不,我不能四舍五入(我需要完全精确的计算),是的,我需要使用幂函数。

4

3 回答 3

15

发生的情况是 -1 的平方根计算为 exp(i phase/2),其中(-1 的)相位约为π。实际上,

>>> import cmath, math
>>> z = -1+0j
>>> cmath.phase(z)
3.141592653589793
>>> math.cos(_/2)
6.123233995736766e-17

这说明-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 所建议的)的浮点逼近问题的影响。

于 2011-06-09T13:11:05.997 回答
9

numpy.power()这是实现复数的副作用。标准库表现出同样的问题。

>>> numpy.power(-1+0j, 0.5)
(6.123233995736766e-17+1j)
>>> cmath.exp(cmath.log(-1)/2)
(6.123233995736766e-17+1j)
于 2011-06-09T08:51:26.020 回答
5

试试 numpy.real_if_close()。

请参阅:如果关闭,则为真实

于 2011-06-27T13:16:17.860 回答