我有一个功能,
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个变量应如何做?
答案 0 :(得分:2)
您可以按this answer中所示执行此操作,只需使用dblquad
代替quad
。如果您想要c
和d
的函数,请使用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,e
中func(a,b,c,d,e)
的顺序相同。还请注意,,
中e
之后是args=(d,e,)
。
考虑到n
的结构,将其推广到a,b,c,d,e,
集成情况应该是显而易见的。