我有一组非参数的data points,我需要计算它们下面的体积,我现在要做的是,首先使用线性插值来增加点,然后基本上实现离散积分。
所有的点都应该放置在半径为radius
的圆柱体内,所以我删除了阈值之外的所有点。真实的体积为5485立方米,但我的函数返回6380。我有两个问题:
1.为什么n_points
(插值点数)不改变函数的输出?我尝试了(10,10)
,(50,50)
,(100,100)
网格,结果几乎没有变化。
1.为什么结果中会有这么大的误差呢,就像我说的,我基本上只是在积分,就我所知,我在积分的过程中没有犯任何错误。
def calculate_volume2(x, y, z, radius, n_points):
x_points = n_points
y_points = n_points
# creating sample points for integral
X = np.linspace(-radius, radius, x_points)
Y = np.linspace(-radius, radius, y_points)
X, Y = np.meshgrid(X, Y)
# Interpolating object
# l = list(zip(x, y))
interp1 = scipy.interpolate.LinearNDInterpolator(
list(zip(x, y)), z, rescale=True)
# Interpolating sample point
Z0 = interp1(X, Y)
# Integral
sum_of_z = 0
num_of_valid_sample = 0
interp_points = np.zeros((1, 3))
for i in range(len(Z0)):
for j in range(len(Z0[i])):
# checking if sample point is in cylinder boundary and interpolating value is valid
if (not isnan(Z0[i][j])) and sqrt((X[i][j]) ** 2 + (Y[i][j]) ** 2) <= radius:
num_of_valid_sample = num_of_valid_sample + 1
sum_of_z += Z0[i][j]
point = np.array([X[i][j], Y[i][j], Z0[i][j]])
point = point.reshape(1, 3)
interp_points = np.concatenate((interp_points, point), axis=0)
# calculating surface of each sample tile: surface of cylinder base / number of samples
surface_of_each_sample = pi * (radius ** 2) / num_of_valid_sample
volume = sum_of_z * surface_of_each_sample
height_avg = volume / (pi * (radius ** 2))
return volume, interp_points, height_avg, surface_of_each_sample
编辑:radius
在这种情况下是11. 82米。
1条答案
按热度按时间vvppvyoh1#
正如在评论中提到的,
LinearNDInterpolator
不是在规则网格上插值数据的最佳工具,因为它通过the QHull library使用三角测量,所以它是针对分散的数据设计的。对于规则网格上的数据,首选
RegularGridInterpolator(...., method="linear")
。然而,在计算分段线性曲面下的体积时,实际上并不需要这些公式,给定由
x
、y
和z
数组定义的网格上的数据,双线性插值--本质上是一个二维梯形公式--的积分为公式来自scipy tests,我记得至少检查过一次,但您可能需要根据您的定义调整它(例如,
z
数组是1D还是2D等)。