Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Lambdify参数积分_Python 3.x_Sympy - Fatal编程技术网

Python 3.x Lambdify参数积分

Python 3.x Lambdify参数积分,python-3.x,sympy,Python 3.x,Sympy,我有以下问题:我想lambdifyasympy表达式,其中包含参数积分,如Integral(tanh(a*x)、(x,0,1))。我试着手动实现 我们想要的是,积分被转换成如下形式: 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.integr

我有以下问题:我想
lambdify
a
sympy
表达式,其中包含参数积分,如
Integral(tanh(a*x)、(x,0,1))
。我试着手动实现

我们想要的是,积分被转换成如下形式:

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'
有人知道如何解决这个问题吗


注意:手动操作是没有选择的,因为我处理的表达式要复杂得多,可能包含几个不同的积分。因此,我真的需要让lambdify正常工作。

因此,我找到了一个可能的解决方法,但我不满意,因为它对我的应用程序来说太慢了,如下所示:

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
-函数转换为lambda函数,例如

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

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


另外,不要问我为什么会有双
np.array
,如果将
dtype='float64'
放在第一个数组中,那么它会返回
TypeError:uu array\uuuuuu()接受1个位置参数,但给出了2个
我认为从
整数返回lambda作为四元组
是行不通的,因为永远不会调用这个lambda,因为SymPy中的
Integral
对象是不可调用的。相反,参数元组可以通过其
args
参数传递给
quad
。我所做的另一个更改是外部lambdification,替换

modules=['numpy', {'Integral':integral_as_quad}] 

我们的想法是,在这个阶段我们还不需要NumPy函数,我们只想用可调用函数替换积分。
模块的顺序
列表很重要:字典放在第一位是为了防止Symphy将积分作为一个积分来保存

现在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'])

非常感谢你,你是我的救星!通过添加
a=sp.lambdify((),a,'numpy')
b=sp.lambdify((),b,'numpy')
返回四元组(f,a(),b(),args=param)[0]
我们甚至可以处理
oo
或依赖
param
的整数边界!!!!你认为有没有可能把这种方法推广到一种情况,当你想把一个可能包含任意数量嵌套参数积分的通用表达式拉姆迪化时?我不知道。发布一个关于嵌套积分的新问题,其中有一个最小的例子,这里所写的内容没有涵盖。
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'])