如何检查 SymPy 表达式是否具有解析积分

Foa*_*oad 2 python symbolic-math sympy integral

我想在这里解决我的另一个问题,所以只要没有积分的解析/符号解决方案,我就需要 sympy 返回错误。

例如,如果我尝试:

from sympy import *
init_printing(use_unicode=False, wrap_line=False, no_global=True)
x = Symbol('x')
integrate(1/cos(x**2), x)
Run Code Online (Sandbox Code Playgroud)

它只是 [漂亮] 打印积分本身

在此处输入图片说明

没有解决和/或给出无法解决的错误!

PS 我也在Reddit 上问过这个问题。

小智 5

“符号”解总是存在的:我刚刚发明了一个新函数intcos(x),根据定义,它是 的反导数1/cos(x**2)。现在这个积分有一个符号解!

对于要严格回答的问题,必须限制答案中允许的函数类别。通常考虑基本函数。正如SymPy 积分参考所解释的那样,它采用的 Risch 算法可以证明某些函数没有初等反导数。使用该选项risch=True并检查返回值是否是sympy.integrals.risch.NonElementaryIntegral

from sympy.integrals.risch import NonElementaryIntegral
isinstance(integrate(1/exp(x**2), x, risch=True), NonElementaryIntegral)  # True
Run Code Online (Sandbox Code Playgroud)

但是,由于 Risch 算法的实现是不完整的,在很多情况下1/cos(x**2)它就像返回一个普通的 Integral 对象。这意味着它既无法找到基本的反导数,也无法证明它不存在。

对于此示例,它有助于根据指数重写三角函数,其中rewrite(cos, exp):

isinstance(integrate((1/cos(x**2)).rewrite(cos, exp), x, risch=True), NonElementaryIntegral)  
Run Code Online (Sandbox Code Playgroud)

返回 True,所以我们知道积分是非初等的。

非基本反衍生物

但通常我们并不真正需要一个初等函数;Gamma 或 erf 或 Bessel 函数之类的东西可能没问题;只要它是一些“已知”的功能(这当然是一个模糊的术语)。问题变成了:如何判断 SymPy 是否能够集成特定的表达式?使用.has(Integral)检查:

integrate(2/cos(x**2), x).has(Integral)   # True
Run Code Online (Sandbox Code Playgroud)

(不是isinstance(Integral)因为返回值可以是,就像这里,2*Integral(1/cos(x**2), x)。)除了 SymPy 未能找到反导数之外,这并不能证明其他任何事情。反导数很可能是一个已知函数,甚至是基本函数。