我想解决我的其他问题here,因此,当没有积分的解析/符号解决方案时,我需要sympy返回错误。
例如,如果我尝试:
from sympy import *
init_printing(use_unicode=False, wrap_line=False, no_global=True)
x = Symbol('x')
integrate(1/cos(x**2), x)
它只是[漂亮]打印出积分本身
而不解决和/或给出无法解决的错误!
附言我也问过这个问题here on Reddit。
最佳答案
始终存在“符号”解决方案:我刚刚发明了一个新函数intcos(x)
,根据定义,该函数是1/cos(x**2)
的反导数。现在,此积分具有符号解决方案!
为了严格回答问题,必须限制答案中允许的功能类别。通常,人们会考虑elementary functions。正如SymPy integral reference解释的那样,它所采用的Risch算法可以证明某些函数没有基本的反导数。使用选项risch=True
并检查返回值是否为sympy.integrals.risch.NonElementaryIntegral
的实例
from sympy.integrals.risch import NonElementaryIntegral
isinstance(integrate(1/exp(x**2), x, risch=True), NonElementaryIntegral) # True
但是,由于Risch算法的实现不完整,因此在许多情况下,例如
1/cos(x**2)
,它都会返回一个普通的Integral对象。这意味着它既不能找到基本的反导,也不能证明不存在。对于此示例,它有助于使用
rewrite(cos, exp)
重写指数函数的三角函数:isinstance(integrate((1/cos(x**2)).rewrite(cos, exp), x, risch=True), NonElementaryIntegral)
返回True,因此我们知道积分是非基本的。
非基本反导
但是通常我们并不需要真正的基本功能。像Gamma或erf或Bessel函数之类的东西可能还可以;只要它是一些“已知”功能(当然这是一个模糊术语)。问题变成了:如何判断SymPy是否能够集成特定的表达式?使用
.has(Integral)
检查:integrate(2/cos(x**2), x).has(Integral) # True
(不是
isinstance(Integral)
,因为返回值可以是2*Integral(1/cos(x**2), x)
。)除了SymPy无法找到反导数之外,这没有其他证明。该抗衍生物很可能是一种已知功能,甚至是一种基本功能。