使用 lambdify 将硬积分转换为 lambda 函数

Converting hard integral to lambda function with lambdify

我想对函数 Integral(t**t,(t,0,x)) 进行 lambdify。它有效,但我的新函数由 lambdify return 编辑,不是 return 数字,而是 sympy.integrals.integrals.Integral class。但我不想要那个,我想要它 return 一个浮点数。

这是我的代码:

import sympy as sp
import numpy as np
f = sp.lambdify(x,sp.integrate(t**t,(t,0,x)))
print(f(2)) #return Integral(t**t, (t, 0, 2))
#but i want 2.83387674524687

Sympy 无法为该积分找到封闭形式的解析解,因此它 returns 是一个未计算的 sympy 积分对象。由于您似乎可以使用数值解,因此您可以为此目的使用 scipy 的 quad 函数

import scipy.integrate

def f(x):
    return scipy.integrate.quad(lambda t: t**t, 0,x)[0]

f(2)

2.83387674525

最后,我找到了下一个解决方案。 我环顾四周,发现 return lambda 是函数。 当你用一个数字调用它时,它 return object (Integarl).

所以我可以调用这个对象的 evalf(),它将 return 一个数字。 像这样:

import sympy as sp
import numpy as np
x = sp.symbols('x')
f = sp.lambdify(x,sp.integrate(t**t,(t,0,x)))
def return_number(z):
    return f(z).evalf()
return_number(2) #return 2.83387674524687

有效。

lambdify不直接支持scipy.integrate.quadyet,但添加合适的定义并不难。只需告诉 lambdify 如何打印 Integral:

def integral_as_quad(expr, lims):
    var, a, b = lims
    return scipy.integrate.quad(lambdify(var, expr), a, b)

f = lambdify(x, Integral(t**t,(t,0,x)), modules={"Integral": integral_as_quad})

结果是

In [42]: f(2)
Out[42]: (2.8338767452468625, 2.6601787439517466e-10)

我们在这里做的是定义一个函数 integral_as_quad,它将 SymPy Integral 转换为 scipy.integrate.quad 调用,递归地对被积函数进行 lambdifying(如果你有更复杂的或符号积分限制,您也需要递归地对它们进行 lambdify 化)。