SymPy 和复数的平方根

SymPy and square roots of complex numbers

当使用 solve 计算二次方程的根时,SymPy returns 表达式可以简化,但我无法简化它们。一个最小的例子如下所示:

from sympy import *
sqrt(-24-70*I)

在这里,SymPy 只是 returns sqrt(-24-70*I),而 Mathematica 或 Maple 将用 5-7*I.

的等价物回答

我知道有两个平方根,但是这种行为意味着 SymPy 将 return 来自

的非常复杂的解决方案
z = symbols("z")
solve(z ** 2 + (1 + I) * z + (6 + 18 * I), z)

再一次,Maple 和 Mathematica 会很乐意给我求解这个方程的两个高斯整数。

有没有我遗漏的选项或东西?

如果你有mpmath包,你可以做类似

的事情
from sympy import *
import mpmath

a = -24-70*I
b = mpmath.mpc(re(a), im(a))  # a as mpmath.mpc object
c = mpmath.sqrt(b)
d = simplify(c)  # Convert back to sympy object
print(d)  # 5.0 - 7.0*I

请注意,可能有更便宜的方法(比 simplify)将转换回 sympy 对象。

更新

正如评论中所指出的,这执行的是数值评估,而不是符号评估。也就是说,上面的其实并不比这个优越:

import cmath
result = cmath.sqrt(-24 - 70j)
print(result)  # 5 - 7j

以上有两个有趣的方面。首先,cmath 模块是标准库的一部分。其次,由于 result 是以整数形式给出的,我们可以保证 result 实际上是准确的符号值(并且它可以很容易地转换为 sympy 对象)。如果解是非整数,则 result 表示为浮点数。这当然不是符号复数平方根问题的一般好的解决方案,但如果您事先知道解决方案是整数,它会很有用。

求 z 的平方根在逻辑上与求解方程式 (x+I*y)**2 = z 相同。所以你可以这样做:

from sympy import *
z = -24-70*I
x, y = symbols('x y', real=True)
result = solve((x+I*y)**2 - z, (x, y))

结果是[(-5, 7), (5, -7)]

为方便起见,可以将其包装为一个函数:

def my_sqrt(z):
    x, y = symbols('x y', real=True)
    sol = solve((x+I*y)**2 - z, (x, y))
    return sol[0][0] + sol[0][1]*I

现在您可以使用 my_sqrt(-24-70*I) 并获得 -5 + 7*I


同样的策略有助于您使用二次方程的示例:

x, y = symbols('x y', real=True)
z = x + I*y
solve(z ** 2 + (1 + I) * z + (6 + 18 * I), (x, y))

输出:[(-3, 3), (2, -4)]

另一种解决方法是使用:

sqrt(-24-70*I).as_real_imag()

这个 returns 列表中的实部和虚部,可以进一步处理以恢复复数。

奇怪的是,没有要求计算复数平方根的内置方法。