我有my own triangulation algorithm可以根据Delaunay的条件和渐变来创建三角剖分,以使三角形与渐变对齐。
以上描述与问题无关,但对于上下文而言是必需的。
现在,我想对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)
对象具有构成三角剖分的delaunay
和delaunay.points
。我拥有自己的三角剖分信息完全相同,但是delaunay.simplices
需要一个scipy.interpolate.LinearNDInterpolator
对象。
我认为我需要继承scipy.spatial.Delaunay
并实现相关方法。但是,我不知道要到达那里需要哪些。
答案 0 :(得分:0)
我想用 triangle
package 提供的 Delaunay 三角剖分做同样的事情。在大 (~100_000) 点上,三角形 Delaunay 代码比 SciPy 代码快八倍。 (我鼓励其他开发人员尝试击败它 :) )
不幸的是,Scipy LinearNDInterpolator
函数严重依赖于 SciPy Delaunay 三角剖分对象中存在的特定属性。这些是由难以反汇编的 _get_delaunay_info()
CPython 代码创建的。即使知道需要哪些属性(似乎有很多,包括 paraboloid_scale
和 paraboloid_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