如何在Python中编写含复合函数的复杂积分?含报错及nquad咨询
问题分析与解决:Scipy积分复合函数报错与nquad用法
问题描述
运行Python积分代码时出现如下错误:
m2=quad(lambda h:fh(h), 0, lambda x:S-x)[0] TypeError: '<' not supported between instances of 'function' and 'int'
推测原因是x、h等变量被错误当作函数而非数值传递,同时咨询是否可通过nquad实现一行式多重积分。
用户完整代码如下:
import numpy as np from scipy.integrate import quad, dblquad, tplquad,nquad #INPUT a2=18 b2=5 a1=3 b1=2.5 p=1 l=0.5 ci=0.05 cr=1 cf=10 S=5 T=10 mi=0.1 #Rate of opportunity Cost=lenght=0 def objective(S,T): def f01(x):#weibull density (strong component) return (b1/a1**b1)*(x**(b1-1))*np.exp(-(x/a1)**b1) def f02(x): #weibull density (weak component) return (b2/a2**b2)*(x**(b2-1))*np.exp(-(x/a2)**b2) #DEFECT def fx(x): return p*f01(x)+(1-p)*f02(x) #DELAY TIME def fh(h):#exponential density return l*np.exp(-l*h) def Fh(h):#cumulative exponential return 1-np.exp(-l*h) #DEMAND def fz(z):#exponential density return l*np.exp(-l*z) def Fz(z):#cumulative exponential return 1-np.exp(-l*z) #OPPORTUNIY def fw(w):#exponential density return l*np.exp(-l*w) def Fw(w):#cumulative exponential return 1-np.exp(-l*w) m1=quad(lambda x:fx(x), 0,S)[0] m2=quad(lambda h:fh(h), 0, lambda x:S-x)[0] m3=1-quad(lambda z:fz(z), lambda x,h: x+h,T)[0] m4=1-quad(lambda w:mi*np.exp(-mi*(w-S))*fw(w), S,T) [0] P1=m1*m2*m3*m4 return P1 print(objective(S,T))
错误原因
scipy.integrate.quad仅支持数值类型的积分上下限,你传入的lambda x:S-x是函数对象,quad尝试比较函数与整数时触发类型错误。同时m3中使用lambda x,h: x+h作为积分下限,同样违反了quad的参数要求。
修正方案:分步多重积分
由于你的积分是嵌套依赖关系(x∈[0,S],h∈[0,S-x],z∈[x+h,T]),需使用多重积分函数处理动态上下限。以下是修正后的分步实现:
import numpy as np from scipy.integrate import quad, dblquad,nquad #INPUT参数保持不变 a2=18 b2=5 a1=3 b1=2.5 p=1 l=0.5 ci=0.05 cr=1 cf=10 S=5 T=10 mi=0.1 #Rate of opportunity def objective(S,T): def f01(x): return (b1/a1**b1)*(x**(b1-1))*np.exp(-(x/a1)**b1) def f02(x): return (b2/a2**b2)*(x**(b2-1))*np.exp(-(x/a2)**b2) def fx(x): return p*f01(x)+(1-p)*f02(x) def fh(h): return l*np.exp(-l*h) def fz(z): return l*np.exp(-l*z) def fw(w): return l*np.exp(-l*w) # 先计算独立的m4(常数) m4, _ = quad(lambda w: mi*np.exp(-mi*(w-S))*fw(w), S, T) m4 = 1 - m4 # 用dblquad处理x和h的嵌套积分,内部包含z的积分 def inner_integral(h, x): z_integral, _ = quad(lambda z: fz(z), x+h, T) return fh(h) * (1 - z_integral) # dblquad顺序:先积分h,再积分x,h的范围依赖x xh_integral, _ = dblquad(inner_integral, 0, S, lambda x:0, lambda x:S-x) # 计算x的边缘积分并合并结果 m1, _ = quad(lambda x:fx(x), 0, S) P1 = m1 * xh_integral * m4 return P1 print(objective(S,T))
使用nquad实现简洁多重积分
nquad可直接处理任意维度的多重积分,通过定义变量的动态范围实现复合逻辑,以下是简化实现:
import numpy as np from scipy.integrate import quad, nquad #INPUT参数保持不变 a2=18 b2=5 a1=3 b1=2.5 p=1 l=0.5 ci=0.05 cr=1 cf=10 S=5 T=10 mi=0.1 #Rate of opportunity def objective(S,T): def f01(x): return (b1/a1**b1)*(x**(b1-1))*np.exp(-(x/a1)**b1) def f02(x): return (b2/a2**b2)*(x**(b2-1))*np.exp(-(x/a2)**b2) def fx(x): return p*f01(x)+(1-p)*f02(x) def fh(h): return l*np.exp(-l*h) def fz(z): return l*np.exp(-l*z) def fw(w): return l*np.exp(-l*w) # 计算独立的m4常数 m4, _ = quad(lambda w: mi*np.exp(-mi*(w-S))*fw(w), S, T) m4 = 1 - m4 # 定义二重积分的被积函数 def integrand(x, h): z_int, _ = quad(lambda z: fz(z), x+h, T) return fx(x) * fh(h) * (1 - z_int) # 定义变量范围:x∈[0,S],h∈[0,S-x] limits = [ [0, S], lambda x: [0, S - x] ] # 执行nquad积分并合并结果 double_result, _ = nquad(integrand, limits) P1 = double_result * m4 return P1 print(objective(S,T))
总结
- 核心错误:
quad不支持函数作为上下限,仅多重积分函数(dblquad/nquad)支持依赖外层变量的动态区间。 nquad可简化多重积分代码,通过列表定义各变量的范围(固定值或动态函数)即可实现复合逻辑的积分计算。
内容的提问来源于stack exchange,提问作者Toye Aribisala
相关产品推荐
相关产品推荐

