B 样条
一、直观理解:用“局部积木”搭建光滑曲线
B 样条(B-spline, Basis spline)把曲线写成若干基函数的线性组合。每个基函数只在有限区间上非零(局部支撑),因此移动一个控制顶点或调整一个系数,通常只改变曲线的局部形状。
可以把它想象成:曲线由一组可重叠的“驼峰形”积木加权叠加而成。积木的位置由节点向量决定,积木的“胖瘦/平滑程度”由**阶数(次数)**决定。三次 B 样条是最常见选择。
与“三次样条插值一定穿过数据点”不同,B 样条既可以做插值,也可以做逼近(拟合);在 CAD、数据平滑与灵活曲线建模中非常通用。
二、适用场景与优缺点
| 类型 | 说明 |
|---|---|
| 适用场景 | 需要局部修改曲线;平滑含噪数据;构造灵活的非线性回归基;CAD/几何造型;比高次多项式更稳的全局逼近。 |
| 核心优点 | 局部支撑;数值稳定;可控制连续性;易扩展到样条回归与惩罚样条;次数较低也能足够光滑。 |
| 局限与缺点 | 节点与次数选择有学问;插值条件需额外求解系数;概念比 interp1 重;解释系数不如“过点折线”直观。 |
三、核心原理:节点向量与 Cox–de Boor 递推
给定次数 、节点向量 ,B 样条基 由递推定义:
曲线/函数表示为
重要性质
- 局部支撑: 只在 非零;
- 非负性与单位分解:(在有效定义域内);
- 连续性:在单节点处通常 ,重节点会降低连续性。
三次样条插值可以用 B 样条基表示,此时系数由插值条件唯一确定(在合适端点条件下)。
四、关键选择:次数、节点、插值还是拟合
- 次数 :3 最常用;更高次数更光滑但更易振荡;
- 节点:均匀节点简单;分位数节点适应数据疏密;
- 插值:解线性系统使 ;
- 拟合:最小二乘 ,可加粗糙惩罚(smoothing spline 思想);
- 边界:开区间、重复端节点(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("截断幂三次样条回归(概念演示)");
六、如何解释结果
报告应写清:
- 次数/阶数与节点向量(或节点选择规则);
- 插值还是最小二乘逼近;
- 系数个数与有效自由度;
- 拟合优度(RMSE、、验证误差);
- 局部修改或平滑的目的是否达到;
- 与多项式拟合、三次样条插值的对比理由。
七、常见误区
1. 节点过多导致过拟合
B 样条很灵活,节点太密时会贴近噪声。
2. 把控制顶点当成数据点
一般 不是简单的 ,除非做了插值约束。
3. 忽略端节点重复规则
CAD 中常见端点重复 次以实现夹持;写错节点向量曲线会怪。
4. 工具箱函数当黑盒
不理解 order 与 degree 的差别(MATLAB 中 order = degree+1)容易设错。
附:建模流程中的落地清单(B 样条)
要把方法真正写进论文,建议补齐以下模块,而不是只贴一个最终数字。
1. 问题对齐与假设
说明题目中的输入/输出如何映射到本方法,并显式列出关键假设。假设越清楚,后面的敏感性分析越有对象。
2. 关键关系
,基函数局部支撑;可插值也可最小二乘逼近。
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 样条用局部支撑基函数构造光滑曲线,兼顾灵活性与数值稳定性,既能插值也能逼近。数学建模里,它适合需要可调光滑度的曲线表示与样条回归;若目标只是对无噪节点做标准光滑插值,三次样条插值往往已够用。