首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lambdify参数积分

Lambdify参数积分
EN

Stack Overflow用户
提问于 2018-07-04 12:41:52
回答 2查看 450关注 0票数 3

我有以下问题:我想lambdify一个包含参数积分(如Integral(tanh(a*x),(x,0,1)) )的sympy表达式。我尝试做一个手动实现like here.

我们想要的基本上是积分被转换成这样的东西:

lambda theta: quad(lambda x: g(x,theta), a,b)[0]

哪里

g = sp.lambdify((x,param), f, modules='numpy'))

考虑以下MWE:

代码语言:javascript
复制
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)给出

代码语言:javascript
复制
AttributeError: 'Mul' object has no attribute 'tanh'

有谁知道怎么解决这个问题吗?

注意:手动执行是没有选择的,因为我处理的表达式要复杂得多,可能包含几个不同的积分。所以我真的需要开始工作了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-04 16:24:43

我认为从integral_as_quad返回lambda不能工作,因为这个lambda永远不会被调用,因为SymPy中的Integral对象是不可调用的。相反,参数元组可以通过其quad参数传递给args。我所做的另一项改变是在外部凝固,取代了

代码语言:javascript
复制
modules=['numpy', {'Integral':integral_as_quad}] 

使用

代码语言:javascript
复制
modules=[{'Integral': integral_as_quad}, 'sympy'] 

我们的想法是,在这个阶段,我们还不需要NumPy函数,我们只想用可调用的方法来代替积分。modules列表的顺序很重要:字典首先是为了防止SymPy将积分保持为整数。

现在L(1)返回正确的数量。

代码语言:javascript
复制
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'])
票数 3
EN

Stack Overflow用户

发布于 2018-07-04 14:37:13

因此,我发现了一个可能的解决办法,但我不满意,因为对我的应用程序来说太慢了,这就是:

代码语言:javascript
复制
def to_lambda(expr, param):
    # Preprocessing
    expr = expr.evalf()
    f = sp.lambdify([param], expr, modules='sympy')
    fun = lambda x: np.array(np.array(f(x).evalf()), dtype='float64')
    return fun

因此,首先,expr使用sympy-functions转换为lambda函数,例如,我们有

f = lambda a: Integral(tanh(a*x),(x,0,1))

然后,我们使用sympy的内部积分器通过evalf() (慢!)。

另外,不要问我为什么会有双np.array,如果将dtype='float64'放入第一个,那么它会返回TypeError: __array__() takes 1 positional argument but 2 were given

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51173981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档