Skip to content

算法Algorithm

de Boor 样条求值

de Boor algorithm · de Boor spline evaluation

定位一个非零节点跨度,以局部凸组合计算样条值,并完整处理重节点、右端点与失败输入。

形式陈述 ​

输入为次数 p、夹持非降节点向量 t0,…,tN+p、系数 c0,…,cN−1,输出

s(x)=∑i=0N−1ciBi,p(x).

先检查两端各重 p+1 次、内部重数不超过 p+1、a<b、系数数量正确以及数值有限。本文只接受 x∈[a,b];区间外不自动外推。

若 x<b,找唯一非零跨度 tk≤x<tk+1,即相等节点块之后的那一段;若 x=b,令 k=N−1,按左极限处理。复制 di(0)=ci,i=k−p,…,k。对 r=1,…,p,计算

αi,r=x−titi+p−r+1−ti,di(r)=(1−αi,r)di−1(r−1)+αi,rdi(r−1),i=k−p+r,…,k.

返回 dk(p)。若在同一数组覆盖,每轮必须按 i=k,k−1,…,k−p+r 从右向左更新,避免读到本轮的新值。

有效跨度保证每个实际使用的分母为正:i≤k 而 i+p−r+1≥k+1,因此它至少跨越 tk<tk+1。这里不需要把有效步骤的 0/0 人为改成零;若出现零分母,应检查跨度或下标是否有误。基函数递推里省略零支撑项的约定,不能不加区分地套到系数三角表。

直觉

Cox–de Boor 递推从低阶基构造高阶基。将 s 展开后反向收集同一低阶基的系数,就得到上面的 di(1);再收集一次得 di(2)。最后只剩跨度 [tk,tk+1) 的零次基,其值为一,旁边的系数就是所求值。这给出逐层不变式

s(x)=∑i=k−p+rkdi(r)Bi,p−r(x),

其中每层只在当前查询点使用该等式。第一层到下一层的系数合并恰是递推式,末层为单项。

在合法跨度上 0≤αi,r≤1。每一步只混合两个邻系数,解释了凸包性质与局部计算。一次完整合法性预检需 O(N+p) 时间,可在固定节点和系数后缓存。预检通过的单次查询定位需 O(log⁡N),之后 p(p+1)/2 次混合,合计 O(log⁡N+p2) 时间、O(p) 额外空间;它不必先生成全部 N 个基值。

例子与边界

取 p=2、t=(0,0,0,1,1,2,3,3,3)、c=(0,1,2,0,1,3)。在 x=3/2,k=4,初行是

(d2(0),d3(0),d4(0))=(2,0,1).

第一轮 α3,1=1/2、α4,1=1/4,得到 (d3(1),d4(1))=(1,1/4);第二轮 α4,2=1/2,得到 d4(2)=5/8。这与逐基求值的 2(1/4)+0(5/8)+1(1/8) 相同。

在二重节点 x=1,仍取 k=4。第一轮两个权重都为零,得到 (2,0);第二轮权重为零,返回二。这是合法的零权重,不是零分母。若误把 [t3,t4]=[1,1] 当作有效跨度,才会制造无意义的除零。

在 x=3,选末跨度 k=5,相关权重都为一,返回 c5=3。次数零时没有混合步骤,直接返回当前跨度的系数。内部满重数允许左右值不同:例如 p=1,t=(0,0,1,1,2,2),c=(0,1,4,5),左极限为一,而算法在 x=1 返回右侧值四。

推论与应用

向量系数可逐分量执行同一表,得到参数曲线上的点。只有一个跨度时,这个三角表就是 Bernstein 表示下的 de Casteljau 求值;局部线性混合是两者共有的计算结构。

浮点凸组合避免展开大幂系数,但结果接近零时,相对误差仍可能很大;节点差极小时,减法与除法也需要尺度检查。验收可比较同一输入的基递推、分段多项式和三角求值,并检查端点、节点左右两侧以及非法输入。通过这些样例说明实现符合所定接口,不等于已经证明任意浮点输入都没有误差。

参考资料
关系图谱4 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系