簡體   English   中英

使用scipy.integrate在部分變量集上獲得積分

[英]Use scipy.integrate to get integral over a partial set of variables

我有一個功能,

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個變量應如何做?

您可以執行此操作, 如此答案所示,只需使用dblquad代替quad 如果你想要cd的函數,可以使用dblquadargs參數:

def g(c,d):
    return scipy.integrate.dblquad(f, 0, 1, lambda x: 0, lambda x: 2, args=(c,d))

僅當函數返回數字時,數字整數才有效。 因此,您可以定義c和d的函數,該函數在每次調用時都會進行調整,或者在c和d的網格上對此函數進行制表和插值。

在這里,我提出了一種解決方案,它通過一個類為任意數量的參數實現固定的高斯 - 勒讓德正交。 您可以使用函數和參數創建類的實例:正常參數的字符串,以及要在此變量上集成的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))

scipy.integrate.nquad 看到這個鏈接 因為手冊對我來說不夠清楚,所以我通過反復試驗得到了以下代碼。

假設您要創建以下函數,如問題中所述:

$ 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

注意, [bounds_a, bounds_b, bounds_c], args=(d, e,)a,b,c,d,e[bounds_a, bounds_b, bounds_c], args=(d, e,)必須與func(a,b,c,d,e)a,b,c,d,efunc(a,b,c,d,e) 還要注意,args=(d,e,)之后有e

考慮到a,b,c,d,e,結構a,b,c,d,e,將這推廣到n積分情況應該是顯而易見的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM