Python中的复数平方根

20
我在使用Python计算复数的平方根时遇到了一些混乱的行为。运行以下代码:

I have run across some confusing behaviour with square roots of complex numbers in python. Running this code:


from cmath import sqrt
a = 0.2
b = 0.2 + 0j
print(sqrt(a / (a - 1)))
print(sqrt(b / (b - 1)))

输出结果

0.5j
-0.5j

类似的事情也会发生在

print(sqrt(-1 * b))
print(sqrt(-b))

看起来这些语句应该给出相同的答案吗?


根据Wolfram,您是正确的。第一对(链接链接) 都应该是0.5i,而第二对(链接链接) 都应该是 0.447214...icmath.sqrt() 的源代码在这里 - Jens
7
两个答案都是正确的,问题是为什么它返回不同的共轭形式。 - tzaman
就此问题而言,在Python 2.7和3.5中的行为似乎是相同的。 - tzaman
2
复杂根有多个解决方案。 - roadrunner66
3
@tzaman...如果有地方明确规定了Python应该返回哪一个选项,那就以那个为准。如果没有明确规定,Python有权选择任何一个选项。 - George Sovetov
2个回答

12

两个答案(+0.5j-0.5j) 都是正确的,因为它们是共轭复数 -- 即实部相同,虚部反号。

查看代码可以清楚地了解行为 - 结果的虚部始终与输入的虚部具有相同的符号,如第790和793行所示:

r.imag = copysign(d, z.imag);

由于 a/(a-1) 是隐式的 0.25+0j,你会得到一个正结果;b/(b-1) 产生了 0.25-0j(因为某种原因;不确定为什么它没有导致 0.25+0j)所以你的结果也是负数。

编辑:这个问题 对同样的问题进行了一些有用的讨论。


a / (a - 1) 的值为 -0.25。将其转换为复数形式为 -0.25+0j。与 b 结合使用,则得到 -0.25-0j - Seth
1
文档还指定分支切割线沿着从0到-∞的射线选择,这将给出观察到的行为。有趣的是,b/(b-1)对于虚部会得到一个负零。 - user2357112
@user2357112,是的,这很奇怪,我不确定为什么会这样。在IDLE中将1-0j直接输入作为文字量时,会产生值1+0j。有趣的是,单独输入-0j会产生-0-0j的结果。 - tzaman
3
这是语法中一个棘手的边缘情况。具有负零虚部的复数会被表示为“0.2-0j”,但表达式“0.2-0j”实际上是“0.2”和“0j”的减法。减法得出零虚部,因为“0j-0j”等于的“0j”。在错误跟踪器上已经出现过几次了。还有一个相关问题,即负零实部在repr输出中根本不可见。 - user2357112
@user2357112,太棒了,感谢分享链接! - tzaman

2
我可以回答为什么会发生这种情况,但不能回答为什么选择了这种行为。
a/(a - 1)

计算结果为0.2/-0.8,即-0.25,然后使用cmath.sqrt将其转换为复数。

b/(b - 1)

这段代码的结果是(0.2+0j)/(-0.8+0j),即(-0.25-0j)。最终转换成一个复数,其虚部为负数。

举个简单的例子:

cmath.sqrt(0j) == 0j
cmath.sqrt(-0j) == -0j

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接