数据集的线性插值通常是如何实现的?

How is linear interpolation of data sets usually implemented?

假设给定了一堆 (x,y) 值中的点,并且您需要通过在 x 轴上两个最接近的值之间进行线性插值来生成点,最快的实现方法是什么?

我找了一圈也没找到满意的答案,我觉得是因为我没有找对的词。

例如,如果我得到的是(0,0) (0.5 , 1) (1, 0.5),那么我想得到一个0.7的值;它将是 (0.7-0.5)/(1-0.5) * (0.5-1) + 1;但是什么数据结构可以让我找到 2 个最近的键值来插入它们之间?如果我有很多键值,那么简单的线性搜索/二进制搜索是我能做的最好的吗?

是的,一个简单的二分查找应该很好,通常就足够了。

如果你需要变得更好,你可以尝试interpolation search(与你的值插值无关)。

如果您的点按固定间隔分布(如您的示例,0 0.5 1),您还可以简单地将值存储在数组中,并通过它们的索引在恒定时间内访问它们。

我通常实现 O(1) 插值的方法是通过一个额外的数据结构,我称之为 IntervalSelector 时间 O(1) 将给出序列的两个周围值进行插值。

一个IntervalSelector是一个class,当给定一个n横坐标的sequence时,它会构建并记住一个table,它将映射任何给定的值x 到索引 i 使得 sequence[i] <= x < sequence[i+1] 在时间 O(1).

注:以下数组以1为基数

构建 table 的算法过程如下:

  1. delta为横坐标输入sequence中两个连续元素之间的最小距离
  2. 设置count := (b-a)/delta + 1,其中ab分别是第一个和最后一个(升序)sequence/代表整数除法商。
  3. 定义 tableArraycount 个元素。
  4. 对于 1n 之间的 i,设置 table[(sequence[j]-a)/delta + 1] := j.
  5. 将在 4 中访问过的 table 的每个条目重复到紧随其后的未访问位置。

在输出时,如果 (j-1)*d <= sequence[i] - a < j*d.

tablej 映射到 i

这是一个例子:

由于元素 3rd 和 4th 是最接近的元素,我们将区间划分为这个最小长度的子区间。现在,我们在 table 中记住了每个 deta- 区间左端的位置。稍后,当给出输入 x 时,我们计算 delta- 此类 x 的区间为 (x-a)/delta + 1 并使用 table 推导出相应的区间序列。如果x落在第i个序列元素的左边,我们选择第(i-1)个。

更准确地说:

给定 ab 之间的任何输入 x 计算 j := (x-a)/delta + 1i := table[j]. 如果 x < sequence[i]i := i - 1。那么,索引i满足sequence[i] <= x < sequence[i+1];否则这两个连续元素之间的距离将小于delta,这不是

备注:注意如果sequence中连续元素之间的最小距离delta太小,table也会有许多条目。我在这里提供的简单描述忽略了这些需要额外工作的病态案例。