Scipy中nquad与tplquad计算三重积分结果不符,求问题原因
Scipy nquad调用错误原因及修正
我尝试用Scipy计算三重积分:积分范围x∈[0,1],y∈[x³,x],z∈[0,2x],被积函数为2z。
定义被积函数如下:
from scipy.integrate import dblquad, tplquad, nquad def inte(z, y, x): return 2*z
使用tplquad调用得到正确结果:
volume = tplquad(inte, 0, 1, lambda x: x**3, lambda x: x, lambda x, y: 0, lambda x, y: 2*x) volume[0] # 输出:0.33333333333333337
但使用nquad调用时得到错误结果0.2:
def range_3(): return [0, 1] def range_2(x): return [x**3, x] def range_1(x, y): return [0, 2*x] volume, error = nquad(inte, [range_1, range_2, range_3]) volume # 输出:0.2
错误原因
核心问题是**nquad和tplquad对被积函数的参数顺序要求完全相反**:
tplquad要求被积函数的参数顺序为最内层变量在前,也就是inte(z, y, x)中,z是最内层积分变量(先积z),x是最外层(最后积x),和积分顺序dz dy dx一致。nquad要求被积函数的参数顺序为最外层变量在前,也就是第一个参数是最外层积分变量(最后积),最后一个参数是最内层变量(先积),对应积分顺序dx dy dz时,参数顺序应为inte(x, y, z)。
你的nquad调用中,被积函数沿用了tplquad的参数顺序,导致nquad把z当成最外层变量、x当成最内层变量,积分顺序完全错乱;同时limits列表顺序也和错误的参数顺序不匹配,最终得到错误结果。
修正方案
修改被积函数的参数顺序,让最外层变量x在前,最内层变量z在后,同时调整limits列表的顺序与之对应:
from scipy.integrate import nquad # 修正参数顺序:x(最外层)→ y → z(最内层) def inte(x, y, z): return 2*z # limits顺序对应参数顺序:x的范围、y的范围、z的范围 volume, error = nquad( inte, [ [0, 1], # x的范围:无依赖 lambda x: [x**3, x], # y的范围:依赖外层变量x lambda x, y: [0, 2*x] # z的范围:依赖外层变量x(y不影响) ] ) print(volume) # 输出:0.33333333333333337
如果偏好函数定义范围的风格,也可以写成:
def range_x(): return [0, 1] def range_y(x): return [x**3, x] def range_z(x, y): return [0, 2*x] volume, error = nquad(inte, [range_x, range_y, range_z]) print(volume) # 输出:0.33333333333333337
内容的提问来源于stack exchange,提问作者Omnia Vanitas
相关产品推荐
相关产品推荐

