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

时间:2020-11-29 20:23:50

I have done some calculations in sympy, and the result is in the end a set of constants. One of them is inserted directly into the snippet below:

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

This 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

so the expression appears to be a real number, yet sympy cannot simplify it further. With pen and paper, I have simplified this to

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

cos(pi/18) / sqrt(3)

which agrees with the numerical value returned by evalf().

这与evalf()返回的数值一致。

I have tried many of the different simplification functions, but none seem to be able to reduce the expression any further. Using substitutions like

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

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

improves the expression, but still sympy is unable to conclude that it is real. Using Euler's formula for substitution,

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

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

sympy is finally able to conclude that the expression is real, but the expression itself explodes in size when printed (even if I attempt simplify after the substitution).

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

Is there a better way to try to reduce this? I have many similar expressions for complex constants that I would like to know for sure are real (or not).

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

2 个解决方案

#1


5  

For the expression you gave, the command

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

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

returns 0, which signifies that expr is real. (Double application of conjugation returns to the original value, but it gets expanded along the way, which enables subsequent simplification.) In general, the above formula returns the imaginary part multiplied by 2i.

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

To find the real part of the expression, you can use a similar trick: add it to its conjugate and simplify (and divide by 2):

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

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

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

返回sqrt(3)* cos(pi / 18)/ 3。

#2


3  

The method as_real_imag often helps to simplify a complex number, even though it's not listed among the Simplification methods. In your example,

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

expr.as_real_imag()

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

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

If a complex number is desired (rather than a tuple as above), one should not just call complex on this tuple, since this would create an object of Python complex class, involving numeric evaluation. Instead, I'd write

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

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

#1


5  

For the expression you gave, the command

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

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

returns 0, which signifies that expr is real. (Double application of conjugation returns to the original value, but it gets expanded along the way, which enables subsequent simplification.) In general, the above formula returns the imaginary part multiplied by 2i.

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

To find the real part of the expression, you can use a similar trick: add it to its conjugate and simplify (and divide by 2):

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

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

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

返回sqrt(3)* cos(pi / 18)/ 3。

#2


3  

The method as_real_imag often helps to simplify a complex number, even though it's not listed among the Simplification methods. In your example,

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

expr.as_real_imag()

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

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

If a complex number is desired (rather than a tuple as above), one should not just call complex on this tuple, since this would create an object of Python complex class, involving numeric evaluation. Instead, I'd write

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

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