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

jos*_*inb 7 python math symbolic-math 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())
Run Code Online (Sandbox Code Playgroud)

这回来了

0.56857902130163 + 0.e-22*I
18**(1/3)/(6*(3 + sqrt(3)*I)**(1/3)) + (36 + 12*sqrt(3)*I)**(1/3)/12
Run Code Online (Sandbox Code Playgroud)

所以表达似乎是一个实数,但同情不能进一步简化它.用笔和纸,我简化了这个

cos(pi/18) / sqrt(3)
Run Code Online (Sandbox Code Playgroud)

它与返回的数值一致evalf().

我已经尝试了许多不同的简化函数,但似乎没有人能够进一步减少表达式.使用类似的替换

expr.subs(3 + sqrt(3)*I, sqrt(12) * exp(I*pi/6))
Run Code Online (Sandbox Code Playgroud)

改善表达,但仍然没有得到结论,它是真实的.使用欧拉的替代公式,

expr.subs(3 + sqrt(3)*I, sqrt(12) * (cos(pi/6) + I*sin(pi/6)))
Run Code Online (Sandbox Code Playgroud)

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

有没有更好的方法来减少这种情况?我有许多类似的复杂常量表达式,我想知道它们是真实的(或不是).

小智 5

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

(expr.conjugate().conjugate() - expr.conjugate()).simplify()
Run Code Online (Sandbox Code Playgroud)

返回0,表示expr是实数.(共轭的双重应用返回到原始值,但它会沿途扩展,这使得后续的简化.)通常,上面的公式返回虚部乘以2i.

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

((expr.conjugate().conjugate()+expr.conjugate())/2).simplify()
Run Code Online (Sandbox Code Playgroud)

回报sqrt(3)*cos(pi/18)/3.


小智 5

该方法as_real_imag通常有助于化简复数,即使它未列在化简方法中。在你的例子中,

expr.as_real_imag()
Run Code Online (Sandbox Code Playgroud)

返回 (sqrt(3)*cos(pi/18)/3, 0)

如果需要复数(而不是上面的元组),则不应只调用complex此元组,因为这将创建 Pythoncomplex类的对象,涉及数值计算。相反,我会写

pair = expr.as_real_imag()
result = pair[0] + pair[1]*I
Run Code Online (Sandbox Code Playgroud)