[英]how to use scipy.integrate to get the volume of a truncated sphere?
[英]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
。 如果你想要c
和d
的函數,可以使用dblquad
的args
參數:
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,e
的func(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.