如何使用 SymPy 加速符号集成?

How to speed up symbolic integration using SymPy?

我正在尝试对以下表达式进行符号积分(最终表达式将以 x 表示):

from sympy import *
x, y = symbols('x, y')
expr = 0.25*sqrt(15/(2*pi)) * exp(2j*y) * (sin(x))**2 * sin(x) * sqrt(cos(x))
int_expr = simplify(integrate(expr, x,(y,0,2*pi)))
print(int_expr)

需要注意的一点是,当我集成 0.25*sqrt(15/(2*pi)) * exp(2j*y) * (sin(x))**2 * sin(x) 程序运行速度稍快一些。加入 sqrt(cos(x)) 会使它变得非常慢,并且需要很长时间才能实现代码。 经过大量简化后,我得到了这个数学表达式,它使程序 'start working' 有什么办法可以加快这段代码的速度吗?非常感谢任何建议。

首先,我建议不要使用浮点数,尤其是在指数中(即 2j)。您应该使用 sympy 的精确有理数,并且 I 用于 sqrt(-1).

这给了我们这个:

In [11]: expr = sqrt(15/(2*pi))/4 * exp(2*I*y) * (sin(x))**2 * sin(x) * sqrt(cos(x))

In [12]: int_expr = Integral(expr, (x, 0, 2*pi))

In [13]: int_expr
Out[13]: 
2⋅π                                 
 ⌠                                  
 ⎮       2⋅ⅈ⋅y    3      ________   
 ⎮  √30⋅ℯ     ⋅sin (x)⋅╲╱ cos(x)    
 ⎮  ───────────────────────────── dx
 ⎮               8⋅√π               
 ⌡                                  
 0  

现在我注意到实际上可以从这个积分中剔除无关因素。我们可以使用 factor_terms 来做到这一点:

In [14]: factor_terms(int_expr)
Out[14]: 
           2⋅π                      
            ⌠                       
     2⋅ⅈ⋅y  ⎮     3      ________   
√30⋅ℯ     ⋅ ⎮  sin (x)⋅╲╱ cos(x)  dx
            ⌡                       
            0                       
────────────────────────────────────
                8⋅√π                

看到剩下的积分值得知道的是,当你有一个没有自由符号的积分时(被积函数中唯一的符号是虚拟积分符号)然后你通常可以通过评估更快地获得近似结果数值积分:

In [15]: Integral(sin(x)**3 * sqrt(cos(x)), (x, 0, 2*pi))
Out[15]: 
2⋅π                      
 ⌠                       
 ⎮     3      ________   
 ⎮  sin (x)⋅╲╱ cos(x)  dx
 ⌡                       
 0                       

In [16]: _.n()
Out[16]: -0.e-103 + 0.e-103⋅ⅈ

这说明积分基本为零

在某些情况下,用于符号积分的算法可能非常慢。这是许多积分算法的普遍问题,它们通常对输入的确切形式非常敏感。 sqrt(cos(x)) 的附加因子改变了事情,您不应该感到惊讶:它会使手工积分变得更加困难,而且积分没有“乘积规则”。在这个例子中,它在“heurisch”算法中很慢,所以你可以设置 heurisch=False 来禁用它,但是其他算法的 none 可以计算积分,所以你不会得到结果。

通常替换会使积分更容易,您可以要求 sympy 明确地进行替换。在这种情况下,我们可以使用替换 z = cos(x) 但我们需要将积分分成两部分,从 0pi 和从 pi2*pi 以便每个部分的替换都是单调的:

In [30]: Integral(expr, (x, 0, pi))
Out[30]: 
π                                 
⌠                                 
⎮      2⋅ⅈ⋅y    3      ________   
⎮ √30⋅ℯ     ⋅sin (x)⋅╲╱ cos(x)    
⎮ ───────────────────────────── dx
⎮              8⋅√π               
⌡                                 
0                                 

In [31]: Integral(expr, (x, 0, pi)).transform(cos(x), z)
Out[31]: 
1                           
⌠                           
⎮         ⎛     2⎞  2⋅ⅈ⋅y   
⎮  √30⋅√z⋅⎝1 - z ⎠⋅ℯ        
⎮  ────────────────────── dz
⎮           8⋅√π            
⌡                           
-1                          

In [32]: Integral(expr, (x, 0, pi)).transform(cos(x), z).doit()
Out[32]: 
     2⋅ⅈ⋅y          2⋅ⅈ⋅y
√30⋅ℯ        √30⋅ⅈ⋅ℯ     
────────── + ────────────
  21⋅√π         21⋅√π    

In [33]: _ + Integral(expr, (x, pi, 2*pi)).transform(cos(x), z).doit()
Out[33]: 0