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

时间:2015-08-20 07:30:50

标签: python math sympy symbolic-math

我在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())

返回

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

因此表达式似乎是一个实数,但同情不能进一步简化它。使用笔和纸,我已将其简化为

cos(pi/18) / sqrt(3)

evalf()返回的数值一致。

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

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

改善了表达,但仍然不能断定它是真实的。使用欧拉的替代公式,

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

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

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

2 个答案:

答案 0 :(得分:5)

对于您提供的表达式,命令

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

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

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

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

返回'

答案 1 :(得分:4)

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

expr.as_real_imag()

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

如果需要一个复数(而不是上面的元组),那么不应该在这个元组上调用complex,因为这会创建一个Python complex类的对象,涉及数值评估。相反,我会写

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