跳到主要内容

B 样条

一、直观理解:用“局部积木”搭建光滑曲线​

B 样条(B-spline, Basis spline)把曲线写成若干基函数的线性组合。每个基函数只在有限区间上非零(局部支撑),因此移动一个控制顶点或调整一个系数,通常只改变曲线的局部形状。

可以把它想象成:曲线由一组可重叠的“驼峰形”积木加权叠加而成。积木的位置由节点向量决定,积木的“胖瘦/平滑程度”由**阶数(次数)**决定。三次 B 样条是最常见选择。

与“三次样条插值一定穿过数据点”不同,B 样条既可以做插值,也可以做逼近(拟合);在 CAD、数据平滑与灵活曲线建模中非常通用。

二、适用场景与优缺点​

类型说明
适用场景需要局部修改曲线;平滑含噪数据;构造灵活的非线性回归基;CAD/几何造型;比高次多项式更稳的全局逼近。
核心优点局部支撑;数值稳定;可控制连续性;易扩展到样条回归与惩罚样条;次数较低也能足够光滑。
局限与缺点节点与次数选择有学问;插值条件需额外求解系数;概念比 interp1 重;解释系数不如“过点折线”直观。

三、核心原理:节点向量与 Cox–de Boor 递推​

给定次数 pp、节点向量 t0≤t1≤⋯≤tmt_0\le t_1\le\cdots\le t_m,B 样条基 Ni,p(x)N_{i,p}(x) 由递推定义:

Ni,0(x)={1,ti≤x<ti+10,otherwiseN_{i,0}(x)=\begin{cases}1,& t_i\le x<t_{i+1}\\0,&\text{otherwise}\end{cases} Ni,p(x)=x−titi+p−tiNi,p−1(x)+ti+p+1−xti+p+1−ti+1Ni+1,p−1(x)N_{i,p}(x)=\frac{x-t_i}{t_{i+p}-t_i}N_{i,p-1}(x)+\frac{t_{i+p+1}-x}{t_{i+p+1}-t_{i+1}}N_{i+1,p-1}(x)

曲线/函数表示为

s(x)=∑iciNi,p(x)s(x)=\sum_{i}c_i N_{i,p}(x)

重要性质​

  • 局部支撑:Ni,pN_{i,p} 只在 [ti,ti+p+1)[t_i,t_{i+p+1}) 非零;
  • 非负性与单位分解:∑iNi,p(x)=1\sum_i N_{i,p}(x)=1(在有效定义域内);
  • 连续性:在单节点处通常 Cp−1C^{p-1},重节点会降低连续性。

三次样条插值可以用 B 样条基表示,此时系数由插值条件唯一确定(在合适端点条件下)。

四、关键选择:次数、节点、插值还是拟合​

  1. 次数 pp:3 最常用;更高次数更光滑但更易振荡;
  2. 节点:均匀节点简单;分位数节点适应数据疏密;
  3. 插值:解线性系统使 s(xj)=yjs(x_j)=y_j;
  4. 拟合:最小二乘 min⁡c∥y−Bc∥2\min_c\|y-Bc\|^2,可加粗糙惩罚(smoothing spline 思想);
  5. 边界:开区间、重复端节点(clamped)等。

五、MATLAB 示例​

MATLAB Curve Fitting Toolbox 提供 spapi、spap2、fnval 等。若无工具箱,也可用 spline/csape 处理三次样条特例,或用多项式基做教学替代。下面给出基于工具箱的写法,并附一个不依赖工具箱的三次样条对照。

%% 若有 Curve Fitting Toolbox:B 样条插值与最小二乘逼近
x = linspace(0, 2*pi, 12);
y = sin(x) + 0.08*randn(size(x));
xq = linspace(0, 2*pi, 300);

% 插值型三次样条(B 形表示)
try
sp_interp = spapi(4, x, y); % 4 = 阶数(order)=次数+1
yq1 = fnval(sp_interp, xq);

% 最小二乘 B 样条逼近:用较少系数平滑噪声
knots = augknt(linspace(0, 2*pi, 8), 4);
sp_fit = spap2(knots, 4, x, y);
yq2 = fnval(sp_fit, xq);

figure;
plot(x, y, "ko", "MarkerFaceColor", "y"); hold on;
plot(xq, sin(xq), "k--");
plot(xq, yq1, "r-");
plot(xq, yq2, "b-", "LineWidth", 1.2);
legend("含噪数据", "真值", "B样条插值", "B样条最小二乘", "Location", "best");
title("B 样条:插值 vs 逼近");
grid on;
catch ME
warning("Curve Fitting Toolbox 不可用,改用 spline 对照:%s", ME.message);
yq1 = spline(x, y, xq);
figure;
plot(x, y, "ko", xq, yq1, "r-", xq, sin(xq), "k--");
legend("数据", "三次样条", "真值"); grid on;
title("无工具箱时的三次样条对照");
end

不依赖工具箱的“样条回归”教学版(用截断幂基,概念相近):

%% 截断幂三次基的最小二乘(教学用)
rng(2);
x = linspace(0, 1, 40)';
y = sin(2*pi*x) + 0.15*randn(size(x));
knots = [0.25 0.5 0.75];

% 设计矩阵: 1, x, x^2, x^3, (x-k)_+^3
Xdes = [ones(size(x)), x, x.^2, x.^3];
for k = knots
Xdes = [Xdes, max(x - k, 0).^3]; %#ok<AGROW>
end
coef = Xdes \ y;
xq = linspace(0, 1, 200)';
Xq = [ones(size(xq)), xq, xq.^2, xq.^3];
for k = knots
Xq = [Xq, max(xq - k, 0).^3]; %#ok<AGROW>
end
yq = Xq * coef;

figure;
plot(x, y, "o"); hold on;
plot(xq, yq, "LineWidth", 1.5);
plot(xq, sin(2*pi*xq), "--");
legend("数据", "样条回归", "真值"); grid on;
title("截断幂三次样条回归(概念演示)");

六、如何解释结果​

报告应写清:

  1. 次数/阶数与节点向量(或节点选择规则);
  2. 插值还是最小二乘逼近;
  3. 系数个数与有效自由度;
  4. 拟合优度(RMSE、R2R^2、验证误差);
  5. 局部修改或平滑的目的是否达到;
  6. 与多项式拟合、三次样条插值的对比理由。

七、常见误区​

1. 节点过多导致过拟合​

B 样条很灵活,节点太密时会贴近噪声。

2. 把控制顶点当成数据点​

一般 cic_i 不是简单的 (xi,yi)(x_i,y_i),除非做了插值约束。

3. 忽略端节点重复规则​

CAD 中常见端点重复 p+1p+1 次以实现夹持;写错节点向量曲线会怪。

4. 工具箱函数当黑盒​

不理解 order 与 degree 的差别(MATLAB 中 order = degree+1)容易设错。

附:建模流程中的落地清单(B 样条)​

要把方法真正写进论文,建议补齐以下模块,而不是只贴一个最终数字。

1. 问题对齐与假设​

说明题目中的输入/输出如何映射到本方法,并显式列出关键假设。假设越清楚,后面的敏感性分析越有对象。

2. 关键关系​

s(x)=∑iciNi,p(x)s(x)=\sum_i c_i N_{i,p}(x),基函数局部支撑;可插值也可最小二乘逼近。

3. 补充实现片段​

% 无工具箱时用三次样条对照
x=linspace(0,1,12); y=sin(2*pi*x)+0.05*randn(size(x)); xq=linspace(0,1,200); plot(x,y,'o',xq,spline(x,y,xq),'-');

4. 报告要素​

次数/节点、插值还是逼近、RMSE、自由度。

5. 不适用情形​

节点过密过拟合;混淆控制顶点与数据点。

6. 与验证章节的衔接​

至少做一项:参数扰动、与基线方法对照、极限情形检查。把“方法正文”和“全局方法论(第15门类)”连起来,结论才站得住。

八、小结​

B 样条用局部支撑基函数构造光滑曲线,兼顾灵活性与数值稳定性,既能插值也能逼近。数学建模里,它适合需要可调光滑度的曲线表示与样条回归;若目标只是对无噪节点做标准光滑插值,三次样条插值往往已够用。