trapz 可以通过以下方式在 2D 中完成。用示意图绘制一个点网格,
整个网格的积分等于小区域dS的积分之和。梯形法则将小矩形 dS 上的积分近似为面积 dS 乘以 dS 角上的函数值的平均值,即网格点:
∫ f(x,y) dS = (f1 + f2 + f3 + f4)/4
其中 f1、f2、f3、f4 是矩形 dS 角上的数组值。
观察每个内部网格点输入整个积分的公式四次,因为这对于四个矩形很常见。不在拐角的边上的每个点,进入两次是两个矩形的共同点,每个拐角点只进入一次。因此,积分是通过以下函数在 numpy 中计算的:
def double_Integral(xmin, xmax, ymin, ymax, nx, ny, A):
dS = ((xmax-xmin)/(nx-1)) * ((ymax-ymin)/(ny-1))
A_Internal = A[1:-1, 1:-1]
# sides: up, down, left, right
(A_u, A_d, A_l, A_r) = (A[0, 1:-1], A[-1, 1:-1], A[1:-1, 0], A[1:-1, -1])
# corners
(A_ul, A_ur, A_dl, A_dr) = (A[0, 0], A[0, -1], A[-1, 0], A[-1, -1])
return dS * (np.sum(A_Internal)\
+ 0.5 * (np.sum(A_u) + np.sum(A_d) + np.sum(A_l) + np.sum(A_r))\
+ 0.25 * (A_ul + A_ur + A_dl + A_dr))
在 David GG 给出的函数上进行测试:
x_min,x_max,n_points_x = (0,1,50)
y_min,y_max,n_points_y = (0,5,50)
x = np.linspace(x_min,x_max,n_points_x)
y = np.linspace(y_min,y_max,n_points_y)
def F(x,y):
return x**4 * y
zz = F(x.reshape(-1,1),y.reshape(1,-1))
print(double_Integral(x_min, x_max, y_min, y_max, n_points_x, n_points_y, zz))
2.5017353157550444
其他方法(Simpson、Romberg 等)可以类似推导出来。