Lambdify 参数积分 [英] Lambdify A Parametric Integral

查看:26
本文介绍了Lambdify 参数积分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题:我想 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆