如何使用 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
我在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