Lambdify 参数积分 [英] Lambdify A Parametric Integral
问题描述
我有以下问题:我想 lambdify
一个包含参数积分的 sympy
表达式,例如 Integral(tanh(a*x),(x,0,1))
.我尝试手动实现像这里.
I have the following issue: I want to lambdify
a sympy
expression containing parametric integrals like Integral(tanh(a*x),(x,0,1))
. I tried to do a manual implementation like here.
我们想要的本质上是积分被转换成类似的东西:
What we want is essentially that the integral gets converted to something like:
lambda theta: quad(lambda x: g(x,theta), a,b)[0]
哪里
g = sp.lambdify((x,param), f, modules='numpy'))
考虑以下 MWE:
import sympy as sp
import numpy as np
from scipy.integrate import quad
def integral_as_quad(function, limits):
x, a, b = limits
param = function.free_symbols - {x}
f = sp.lambdify( (x,*param), function, modules='numpy')
return lambda y: quad(lambda x: f(x,y), a,b)[0]
a, x = sp.symbols('a,x')
I = sp.Integral(sp.tanh(a*x),(x,0,1))
K = integral_as_quad(sp.tanh(a*x),(x,0,1))
L = sp.lambdify(a, I, modules=['numpy', {'Integral':integral_as_quad}] )
然后调用例如 K(1)
返回正确的值.但是 L(1)
给出
Then calling for example K(1)
returns the correct value. However L(1)
gives
AttributeError: 'Mul' object has no attribute 'tanh'
有人知道如何解决这个问题吗?
Does anyone have an idea how to fix this?
注意: 手动执行是不可能的,因为我处理的表达式要复杂得多,并且可能包含几个不同的积分.所以我真的需要让lambdify 工作.
NOTE: Doing it manually is no option, since the expressions I deal with are way more complicated and may contain several different integrals. So I really need to get the lambdify working.
推荐答案
我认为从 integral_as_quad
返回一个 lambda 是行不通的,因为这个 lambda 永远不会被调用,因为 Integral 对象不可调用.相反,参数元组可以通过其
args
参数传递给 quad
.我做的另一个改变是在外部lambdification,替换
I think returning a lambda from integral_as_quad
cannot work, because this lambda will never be called, as the Integral
object in SymPy is not callable. Instead, the parameter tuple can be passed to quad
via its args
argument. Another change I made is in the outer lambdification, replacing
modules=['numpy', {'Integral':integral_as_quad}]
与
modules=[{'Integral': integral_as_quad}, 'sympy']
我们的想法是在这个阶段我们还不需要 NumPy 函数,我们只想用我们的可调用函数替换 Integral.modules
列表的顺序很重要:字典首先是为了防止 SymPy 将 Integral 保持为 Integral.
The idea is that at this stage we don't need NumPy functions yet, we just want to replace the Integral by our callable. The order of modules
list matters: the dictionary comes first to prevent SymPy from keeping Integral as an Integral.
现在 L(1) 返回正确的数量.
Now L(1) returns the correct amount.
import sympy as sp
import numpy as np
from scipy.integrate import quad
def integral_as_quad(function, limits):
x, a, b = limits
param = tuple(function.free_symbols - {x})
f = sp.lambdify((x, *param), function, modules=['numpy'])
return quad(f, a, b, args=param)[0]
a, x = sp.symbols('a,x')
I = sp.Integral(sp.tanh(a*x), (x,0,1))
L = sp.lambdify(a, I, modules=[{'Integral': integral_as_quad}, 'sympy'])
这篇关于Lambdify 参数积分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!