使用scipy.integrate在部分变量集上获得积分

时间:2016-06-15 18:39:56

标签: python scipy

我有一个功能,

f = lambda a,b,c,d: <some equation of a,b,c,d>

我想将f从a = 0整合到1,b = 0到2,这样我得到c和d中的函数。我怎么能用scipy.integrate做到这一点?

示例 -

>>> f = lambda a,b,c,d: a+b+c+d
>>> def g(*args):
        f = <some scipy code>
        return f
# After integration lets say we get a function g(c,d)
# We know g(c,d) would be equal to, 2c+2d+3 for the case discussed above. 
# Now this should give,
>>> g(1,1)
7

如何实现这样的代码?

编辑:我知道dblquad可以用于两个变量,但如果有两个以上的变量该怎么办?比如说,我们必须将f(a,b,c,d,e)整合为a = 0到1,b = 0到2和c = -1到1,这样它就得到一个函数,比如g(d,e) )。 编辑2:对于说n个变量应如何做?

4 个答案:

答案 0 :(得分:2)

您可以按this answer中所示执行此操作,只需使用dblquad代替quad。如果您想要cd的函数,请使用args的{​​{1}}参数:

dblquad

答案 1 :(得分:1)

数字整合仅在函数返回数字时有效。因此,您可以定义c和d的函数,它在每次调用时都会进行调整,或者在c和d的网格上将此函数制成表格并进行插值。

答案 2 :(得分:1)

在这里,我提出了一种解决方案,它通过一个类为任意数量的参数实现固定的高斯 - 勒让德正交。您可以使用函数和参数创建类的实例:正常参数的字符串,以及要在此变量上集成的2个数字的列表。然后__init__函数计算要评估函数的点的网格网格。您可以选择正交中的点数。

要使用该功能,请调用eval方法,该方法根据您给出的参数计算结果。

from numpy.polynomial.legendre import leggauss
class Partial_Integrated_Function:
    def __init__(self,f,*args):
        self.f=f
        self.nargs=0 # number of real arguments needed by the function
        self.nintegs=0 # number of vars to integrate
        self.n=10 # quadrature points number
        self.lg_pts,self.lg_wgt=leggauss(self.n)
        self.lg_wgt=self.lg_wgt/2 # for sum=1
        self.eval_pts=[[]] # list of points to evaluate
        self.eval_wgt=[1] # list of weights
        for arg in args:
            if type(arg)==str: # string argument: keep it as a mandatory argument
                self.nargs+=1
                for i in range(len(self.eval_pts)): # add its symbol for each point to evaluate
                    self.eval_pts[i]=self.eval_pts[i]+[arg]
            if isinstance(arg,(list,tuple)) and len(arg)==2: # list argument: integration needed
                self.nintegs+=1
                i=0
                while i<len(self.eval_pts): # for all points
                    l=self.eval_pts.pop(i) # remove the list of values
                    w=self.eval_wgt.pop(i) # remove the weight
                    a,b=arg # integration will go from a to b
                    for j in range(self.n):  # for each quadrature point
                        self.eval_pts.insert(i,l+[(a+b)/2+(b-a)/2*self.lg_pts[j]]) # add the quadrature point to evaluate
                        self.eval_wgt.insert(i,w*self.lg_wgt[j]) # multiply weight by its weight
                    i+=self.n


    def eval(self,*args):
        sum=0
        print("eval",args)
        for i in range(len(self.eval_pts)):
            pt=self.eval_pts[i].copy() # get the point
            w=self.eval_wgt[i]
            j=0 # current arg to use
            for k in range(len(pt)): 
                if type(pt[k])==str: # if we find a string
                    pt[k]=args[j] # we replace it by its value
                    j+=1
            sum+=self.f(*pt)*w 
        return sum

f=Partial_Integrated_Function(lambda x,y,z,t:x+2*y+3*z+4*t,"x",[2,3],[0,1],"t") 
# the function is x,t |-> int_y=2^3 ( int_z=0^1 x+2*y+3*z+4*t dz ) dy
# so f(x,t)=x+4*t+6.5
print(f.eval(0,0))
print(f.eval(1,0))
print(f.eval(0,1))

答案 3 :(得分:0)

scipy.integrate.nquad被使用。参见this link。因为手册对我来说还不够清楚,所以我通过反复试验得出了以下代码。

假设您要创建以下功能,如问题中所述:

$ f(d,e)= \ int _ {-1} ^ 1 \ int_0 ^ 2 \ int_0 ^ 1(a + b + c + d + e)da db dc $

(我不知道如何在这里显示数学。)

定义功能:

from scipy import integrate

def f(d, e):
    def func(a, b, c, d, e):
        return a + b + c + d + e

    def bounds_a(b, c, d, e):
        return [0, 1]

    def bounds_b(c, d, e):
        return [0, 2]

    def bounds_c(d, e):
        return [-1, 1]

    return integrate.nquad(func, [bounds_a, bounds_b, bounds_c], args=(d, e,))[0]

然后

f(1,1)

给予14.0

请注意,a,b,c,d,e[bounds_a, bounds_b, bounds_c], args=(d, e,)的顺序必须与a,b,c,d,efunc(a,b,c,d,e)的顺序相同。还请注意,,e之后是args=(d,e,)

考虑到n的结构,将其推广到a,b,c,d,e,集成情况应该是显而易见的。