繁体   English   中英

用Delaunay三角剖分进行插值(n-dim)

[英]Interpolation with Delaunay Triangulation (n-dim)

我想在Python中使用Delaunay三角剖分法对3D点进行插值。

我有的是

# my array of points
points = [[1,2,3], [2,3,4], ...]
# my array of values
values = [7, 8, ...]
# an object with triangulation
tri = Delaunay(points)        
# a set of points at which I want to interpolate
p = [[1.5, 2.5, 3.5], ...]
# this gets simplexes that contain given points
s = tri.find_simplex(p)
# this gets vertices for the simplexes
v = tri.vertices[s]

我在这里只能找到一个建议使用transform方法进行插值的答案 ,但没有更具体的答案

我需要知道的是如何使用包含单纯形的顶点来获取线性插值的权重。 让我们假设一个普通的n-dim情况,以便答案不取决于尺寸。

编辑:我不想使用LinearNDInterpolator或类似的方法,因为我没有在每个点的数字作为值,而是更复杂的东西(数组/函数)。

您不需要从头开始实现此功能,scipy中已经内置了对此功能的支持:

scipy.interpolate.LinearNDInterpolator

经过一些试验,解决方案看起来很简单(这篇文章很有帮助):

# dimension of the problem (in this example I use 3D grid,
# but the method works for any dimension n>=2)
n = 3
# my array of grid points (array of n-dimensional coordinates)
points = [[1,2,3], [2,3,4], ...]
# each point has some assigned value that will be interpolated
# (e.g. a float, but it can be a function or anything else)
values = [7, 8, ...]
# a set of points at which I want to interpolate (it must be a NumPy array)
p = np.array([[1.5, 2.5, 3.5], [1.1, 2.2, 3.3], ...])

# create an object with triangulation
tri = Delaunay(points)        
# find simplexes that contain interpolated points
s = tri.find_simplex(p)
# get the vertices for each simplex
v = tri.vertices[s]
# get transform matrices for each simplex (see explanation bellow)
m = tri.transform[s]

# for each interpolated point p, mutliply the transform matrix by 
# vector p-r, where r=m[:,n,:] is one of the simplex vertices to which 
# the matrix m is related to (again, see bellow)
b = np.einsum('ijk,ik->ij', m[:,:n,:n], p-m[:,n,:])

# get the weights for the vertices; `b` contains an n-dimensional vector
# with weights for all but the last vertices of the simplex
# (note that for n-D grid, each simplex consists of n+1 vertices);
# the remaining weight for the last vertex can be copmuted from
# the condition that sum of weights must be equal to 1
w = np.c_[b, 1-b.sum(axis=1)]

要理解的关键方法是transform ,该文档有简短的文档,但是文档说明了所有需要说明的内容。 对于每个单纯形, transform[:,:n,:n]包含转换矩阵, transform[:,n,:]包含与矩阵相关的向量r。 似乎r向量被选择为单纯形的最后一个顶点。

另一个棘手的问题是如何获取b ,因为我想做的是

for i in range(len(p)): b[i] = m[i,:n,:n].dot(p[i]-m[i,n,:])

本质上,我需要一个点积数组,而dot给出两个数组的积。 可以像上面那样在单个单纯形上循环,但是可以一步完成,因为有了numpy.einsum ,它可以更快地完成:

b = np.einsum('ijk,ik->ij', m[:,:n,:n], p-m[:,n,:])

现在, v包含每个单纯形的顶点索引, w包含相应的权重。 要获取点p处的插值p_values ,我们可以这样做(注意:为此, values必须为NumPy数组):

values = np.array(values)
for i in range(len(p)): p_values[i] = np.inner(values[v[i]], w[i])

或者我们可以再次使用`np.einsum'一步完成:

p_values = np.einsum('ij,ij->i', values[v], w)

当某些插值点位于网格外部时,必须格外小心。 在这种情况下, find_simplex(p)对这些点返回-1 ,然后您将不得不屏蔽掉它们(也许使用屏蔽数组 )。

您需要一个间隔和一个线性插值,即边的长度和插值点到起始顶点的距离。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM