如何将scipy.interpolate.LinearNDInterpolator与自己的三角剖分一起使用

时间:2018-09-24 17:31:58

标签: scipy scipy-spatial

我有my own triangulation algorithm可以根据Delaunay的条件和渐变来创建三角剖分,以使三角形与渐变对齐。

这是示例输出: enter image description here

以上描述与问题无关,但对于上下文而言是必需的。

现在,我想对deny from 192.144. 使用三角剖分来进行插值。

借助scipy的Delaunay,我将执行以下操作

scipy.interpolate.LinearNDInterpolator

import numpy as np import scipy.interpolate import scipy.spatial points = np.random.rand(100, 2) values = np.random.rand(100) delaunay = scipy.spatial.Delaunay(points) ip = scipy.interpolate.LinearNDInterpolator(delaunay, values) 对象具有构成三角剖分的delaunaydelaunay.points。我拥有自己的三角剖分信息完全相同,但是delaunay.simplices需要一个scipy.interpolate.LinearNDInterpolator对象。

我认为我需要继承scipy.spatial.Delaunay并实现相关方法。但是,我不知道要到达那里需要哪些。

1 个答案:

答案 0 :(得分:0)

我想用 triangle package 提供的 Delaunay 三角剖分做同样的事情。在大 (~100_000) 点上,三角形 Delaunay 代码比 SciPy 代码快八倍。 (我鼓励其他开发人员尝试击败它 :) )

不幸的是,Scipy LinearNDInterpolator 函数严重依赖于 SciPy Delaunay 三角剖分对象中存在的特定属性。这些是由难以反汇编的 _get_delaunay_info() CPython 代码创建的。即使知道需要哪些属性(似乎有很多,包括 paraboloid_scaleparaboloid_shift 之类的东西),我也不确定如何从不同的三角剖分库中提取它。

相反,我尝试了@Patol75 的方法(对上述问题的评论),但使用 LinearTriInterpolator 而不是 Cubic 方法。代码运行正确,但比在 SciPy 中完成整个事情要慢。使用 matplotlib 代码从 400_000 个点的云中插入 400_000 个点比使用 scipy 需要大约 3 倍的时间。 Matplotlib tri code is written in C++,因此将代码转换为 CuPy 并不简单。如果我们可以混合使用这两种方法,我们可以将总时间从 3.65 秒 / 10.2 秒减少到 1.1 秒!

import numpy as np
np.random.seed(1)
N = 400_000
shape = (100, 100)
points = np.random.random((N, 2)) * shape # spread over 100, 100 to avoid float point errors
vals = np.random.random((N,))
interp_points1 = np.random.random((N,2)) * shape
interp_points2 = np.random.random((N,2)) * shape

triangle_input = dict(vertices=points)

### Matplotlib Tri
import triangle as tr
from matplotlib.tri import Triangulation, LinearTriInterpolator

triangle_output = tr.triangulate(triangle_input) # 280 ms
tri = tr.triangulate(triangle_input)['triangles'] # 280 ms
tri = Triangulation(*points.T, tri) # 5 ms
func = LinearTriInterpolator(tri, vals) # 9490 ms
func(*interp_points.T).data # 116 ms
# returns [0.54467719, 0.35885304, ...]
# total time 10.2 sec

### Scipy interpolate
tri = Delaunay(points) # 2720 ms
func = LinearNDInterpolator(tri, vals) # 1 ms
func(interp_points) # 925 ms

# returns [0.54467719, 0.35885304, ...]
# total time 3.65 sec