我有以下问题:我想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:
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)给出
AttributeError: 'Mul' object has no attribute 'tanh'有谁知道怎么解决这个问题吗?
注意:手动执行是没有选择的,因为我处理的表达式要复杂得多,可能包含几个不同的积分。所以我真的需要开始工作了。
发布于 2018-07-04 16:24:43
我认为从integral_as_quad返回lambda不能工作,因为这个lambda永远不会被调用,因为SymPy中的Integral对象是不可调用的。相反,参数元组可以通过其quad参数传递给args。我所做的另一项改变是在外部凝固,取代了
modules=['numpy', {'Integral':integral_as_quad}] 使用
modules=[{'Integral': integral_as_quad}, 'sympy'] 我们的想法是,在这个阶段,我们还不需要NumPy函数,我们只想用可调用的方法来代替积分。modules列表的顺序很重要:字典首先是为了防止SymPy将积分保持为整数。
现在L(1)返回正确的数量。
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'])发布于 2018-07-04 14:37:13
因此,我发现了一个可能的解决办法,但我不满意,因为对我的应用程序来说太慢了,这就是:
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
https://stackoverflow.com/questions/51173981
复制相似问题