
先说结论高次多项式插值在两端振荡常见的解释是次数太高了。这个解释不对或者说只抓到了表象。真正的原因是三句话多项式是全局刚性的。所有系数共同决定每一点的值你没法只在局部修一修。区间两端的约束天生不足。内部的点左右都有邻居夹着两端的点只有单侧邻居那里的行为更像外推而不是插值。等间距采样恰好在最需要信息的地方给得最少。三者叠在一起误差放大倍数随次数呈2n2^n2n增长。次数一上去就立刻崩。为什么次数太高是个错解释因为有一个很干脆的反例。同样的函数、同样的次数只把采样点改成两端密、中间疏振荡就消失了。这种摆法叫切比雪夫节点xkcos (kπn)x_k \cos\!\left(\frac{k\pi}{n}\right)xkcos(nkπ)在这个分布下Runge 函数做到1000 次多项式都能收敛到机器精度。次数一个字没改。变的只有点的位置。等间距11 点—— 均匀铺开两端稀疏 ●────●────●────●────●────●────●────●────●────● -1.0 0.0 1.0 ↑ 两端和中间一样稀 ↑ 切比雪夫11 点—— 两端挤在一起 ●─●───●─────●───────●───────●─────●───●─● -1.0 0.0 1.0 ↑↑ ↑↑ 两端加密 两端加密所以次数高不是病因它只是把病因放大了。病因是采样分布和多项式的需求不匹配。全局刚性意味着什么这是整件事的根。一个nnn次多项式由n1n1n1个系数完全确定而每个系数都影响每一点的值。你挪动一个采样点整条曲线从头到尾都会重排。这跟分段函数完全不同。分段函数你改一段别的段不动。多项式没有段的概念——它是一个整体一动全动。刚性本身不是坏事。坏的是刚性加上约束分布不均。想象一根钢条你要把它固定成某个形状。钢条很硬刚性你在上面钉了一排钉子。中间的钉子每一颗都被左右邻居协同约束着位置很确定。但最外侧那两颗钉子外侧没有任何东西拉住它——钢条在那里可以自由翘起来。●───●───●───●───●───●───●───●───●───● ↑ ↑ 只有右侧有邻居 只有左侧有邻居 外侧无约束 → 自由翘起 外侧无约束 → 自由翘起钢条越硬次数越高翘得越远。为什么端点处是外推这个说法值得展开一下因为它解释了为什么问题只出在两端。插值是在已知点之间求值外推是在已知点之外求值。外推不稳定是常识。区间端点的处境很微妙它在数据范围之内但邻域有一半在数据范围之外。多项式在那附近的行为受到的有效约束只有单侧所以它表现得更接近外推。区间内部 区间端点 ←─ 数据 ─●─ 数据 ─→ ←─ 数据 ─● 无数据 双侧约束稳定 单侧约束接近外推这就是为什么振荡的位置永远在两端而且越靠边越厉害。中间那一段其实拟合得很好——误差分布是明确的两极分化不是整体退化。所以等间距错在哪把上面几点连起来答案就是一句话多项式在区间两端需要更密的采样才能被钉住等间距分布却给了和中间一样的密度。这是一个供需错配。两端的约束需求最大供给却和别处相同。切比雪夫节点做的事就是把供给往需求大的地方调。那个cos\coscos函数本质上是在把均匀分布的角度映射到xxx轴上——角度均匀投影到直线上就自然两端密、中间疏。在圆上均匀取角度投影到 x 轴 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ↓ ↓ ↓ ↓ ↓ ↓ ●─●──●────●────●──●─● ← 两端自动变密不是人为凑的分布是从几何上自然长出来的。这个认知的实际用处知道病因在分布而不在次数会改变你的处理方式。如果你能选采样点就按切比雪夫分布采。这在拟合解析函数、做查找表、预计算光照曲线时都可行。同样的次数精度提升可以差几个数量级。如果采样点由别人给定关卡编辑器里的航点、动画师 K 的关键帧、从设备读来的数据那你就改不了分布。这时唯一的出路是换方法。这正是样条存在的理由。样条怎么绕开这件事样条没有解决这个问题它绕开了。高次多项式三次样条想更精确升次加段次数跟着涨钉死在 3刚性全局局部会不会振荡会随次数指数恶化不会改一个控制点整条曲线变形只影响邻近两段三个关键变化正好对上前面说的三个病因次数钉死在 3于是2n2^n2n那个指数放大器被掐住了。一段三次曲线最多两个拐点翻不起浪来。提高精度靠加段而不是升次于是想更准和会更不稳解耦了。刚性从全局变成局部于是动一个点只影响邻近两段。两端的约束不足影响范围也被限制在最边上那一段。高次多项式 三次样条 一条 20 次曲线 7 段三次曲线 ╮ ╭ ╭──╮ ╭──╮ ╭──╮ ╭── │ 一动全动两端失控 │ │ │ │ │ │ │ │ ╰──────────────────────╯ ╰──╯──╰──╯──╰──╯──╰── ↑ ↑ ↑ 接缝处约定连续性代价是你从此得管接缝——得决定每个接缝做到 C¹ 还是 C²。但这笔交易很划算把一个全局的、指数爆炸的问题换成了一堆局部的、可精确控制的接缝条件。全局的坏问题换成局部的好问题。这是数值方法里反复出现的套路。一分钟验证不用相信上面任何话跑一遍就有答案importnumpyasnpdefrunge(x):return1.0/(1.025.0*x**2)xsnp.linspace(-1,1,20000)truthrunge(xs)fornin[11,21,41]:forname,nodesin[(等间距 ,np.linspace(-1,1,n)),(切比雪夫,np.cos(np.arange(n)*np.pi/(n-1))),]:pnp.polyval(np.polyfit(nodes,runge(nodes),n-1),xs)print(f{n:3}点{name}最大误差{np.abs(p-truth).max():14.4f})重点看两件事等间距那几行误差随点数一路膨胀。切比雪夫那几行次数完全相同误差却一路下降。同样的函数同样的次数只换了点的位置。这一组数字就是整篇文章的全部证据。带走不是次数太高是点摆错了位置。多项式全局刚性两端约束不足而等间距采样偏偏在两端给得最少——三件事叠起来误差按2n2^n2n放大。能控制采样点就往两端加密。不能控制就别用高次多项式改用分段三次样条。想要更精确不是升次是分段。