如何使用 sympy 简化复杂常量的表达式?

How to simplify an expression for a complex constant using sympy?

我在sympy中做了一些计算,结果最后是一组常量。其中之一直接插入到下面的代码片段中:

from sympy import *
expr = (18**(Rational(1, 3))/(6*(3 + sqrt(3)*I)**(Rational(1, 3)))
        + 12**(Rational(1, 3))*(3 + sqrt(3)*I)**(Rational(1, 3))/12)
print(expr.evalf())
print(expr.simplify())

这个returns

0.56857902130163 + 0.e-22*I
18**(1/3)/(6*(3 + sqrt(3)*I)**(1/3)) + (36 + 12*sqrt(3)*I)**(1/3)/12

所以表达式看起来是一个实数,但 sympy 无法进一步简化它。我用笔和纸将其简化为

cos(pi/18) / sqrt(3)

evalf()返回的数值一致。

我尝试了许多不同的简化函数,但 none 似乎能够进一步简化表达式。使用像

这样的替换
expr.subs(3 + sqrt(3)*I, sqrt(12) * exp(I*pi/6))

改进了表达方式,但是sympy还是无法断定是真的。用欧拉公式代入,

expr.subs(3 + sqrt(3)*I, sqrt(12) * (cos(pi/6) + I*sin(pi/6)))

sympy 最终能够得出表达式是真实的结论,但表达式本身在打印时会爆炸(即使我在替换后尝试 simplify)。

有没有更好的方法来减少这种情况?我有许多类似的复杂常量表达式,我想确定它们是否真实。

对于你给出的表达式,命令

(expr.conjugate().conjugate() - expr.conjugate()).simplify()

returns 0,表示expr是实数。 (将共轭returns 两次应用到原始值,但它会沿途扩展,从而可以进行后续简化。)一般来说,上面的公式returns 是虚部乘以2i。

要找到表达式的实部,您可以使用类似的技巧:将其添加到其共轭并化简(并除以 2):

((expr.conjugate().conjugate()+expr.conjugate())/2).simplify()

returns sqrt(3)*cos(pi/18)/3.

方法 as_real_imag 通常有助于化简复数,即使它没有列在化简方法中。在您的示例中,

expr.as_real_imag()

returns (sqrt(3)*cos(pi/18)/3, 0)

如果需要一个复数(而不是上面的元组),不应该只调用这个元组的 complex,因为这会创建一个 Python [=14= 的对象] class,涉及数值求值。相反,我会写

pair = expr.as_real_imag()
result = pair[0] + pair[1]*I