目录
- 1、定义
- 2、已知条件求解
- 3、具体推导
- 4、matlab案例
- 5、案例结果
- 6、matlab仿真
1、定义
给定 n + 1 n+1 n+1个数据点,共有 n n n个区间,三次样条方程 S ( n ) S(n) S(n)满足以下条件:在每个分段区间内 ( x i , x i + 1 ) (x_i,x_{i+1}) (xi,xi+1)( i = 0 , 1 , . . . , n − 1 , x i=0,1,...,n-1,x i=0,1,...,n−1,x递增), S ( x ) = S i ( x ) S(x)=S_i(x) S(x)=Si(x)是一个三次多项式;满足 S ( x i ) = y i ( i = 0 , 1 , . . . , n ) S(x_i)=y_i(i=0,1,...,n) S(xi)=yi(i=0,1,...,n); 导数 S ′ ( x ) S'(x) S′(x)、二阶导数 S ′ ′ ( x ) S''(x) S′′(x)在区间是连续的,即 S ( x ) S(x) S(x)曲线是光滑的。
那么 n n n个三次多项式分段可以写作:
S i ( x ) = a i + b i ( x − x i ) + c i ( x − x i ) 2 + d i ( x − x i ) 3 (1) S_i(x)=a_i+b_i(x-x_i)+c_i(x-x_i)^2+d_i(x-x_i)^3\tag{1} Si(x)=ai+bi(x−xi)+ci(x−xi)2+di(x−xi)3(1)
i = 0 , 1 , . . . , n − 1 i=0,1,...,n-1 i=0,1,...,n−1。
其中: a i 、 b i 、 c i 、 d i a_i、b_i、c_i、d_i ai、bi、ci、di代表 4 n 4n 4n个未知数。
2、已知条件求解
3、具体推导
4、matlab案例
clc;
clear;P = [4.0,4.2;4.3 5.7;4.6,6.6;5.3,4.8;5.9,4.6];x = P(:,1);
y = P(:,2);xx = linspace(min(x),max(x),20);
yy = csapi(x,y,xx); % 三次样条插值
plot(x,y,'b*',xx,yy,'r-',LineWidth=2)
title('Cubic Spline Interpolant')
5、案例结果
6、matlab仿真
4的案例代码是我自己实现的,做实验应付用足够。做研究还是要清楚具体实现过程的,于是乎,需要详细过程实现。仿真代码来自:三次样条Cubic Spline简介。其他博客翻阅了有数百篇,没一个好用的。
clc;
clear;
close;P = [4.0,4.2;4.3 5.7;4.6,6.6;5.3,4.8;5.9,4.6];x = P(:,1);
y = P(:,2);% 计算矩阵A,B
n = size(x,1);
h = arr_diff(x);
A = calc_A(n,h);
B = calc_B(n,y,h);% 求解abcd
a = y;
b = zeros(n-1,1);
c = A^-1*B;
d = zeros(n-1,1);for i=1:n-1d(i) = (c(i+1)-c(i))/(3*h(i));b(i) = (a(i+1)-a(i))/h(i) - h(i)*(c(i+1)+2*c(i))/3;
end% 绘制原始点
plot(x,y,'b*',LineWidth=2);hold on% 三次样条曲线点采样
accuracy = 0.1;
num = int32((max(x) - min(x))/accuracy) + 1;
pnt = zeros(num,2);
i = 1;
for v = min(x):accuracy:max(x)idx = find_latest_index(v,x);ai = a(idx);bi = b(idx);ci = c(idx);di = d(idx);dx = v - x(idx);w = ((di*dx + ci)*dx + bi)*dx + ai;pnt(i,1) = v;pnt(i,2) = w;i = i+1;
end
plot(pnt(:,1),pnt(:,2),'r-',LineWidth=2);% 求差值函数
function h = arr_diff(a)sz = size(a,1);h = zeros(sz-1,1);for i=1:sz-1h(i) = a(i+1)-a(i);end
end% 计算A矩阵
function A = calc_A(n,h)A = zeros(n,n);A(1,1) = 1;for i=1:n-1if i ~= n-1A(i+1,i+1) = 2*(h(i) + h(i+1));endA(i,i+1) = h(i);A(i+1,i) = h(i);endA(1,2) = 0;A(n,n-1) = 0;A(n,n) = 1;
end% 计算B矩阵
function B = calc_B(n,y,h)B = zeros(n,1);for i = 1:n-2B(i+1) = 3*((y(i+2)-y(i+1))/h(i+1) - (y(i+1)-y(i))/h(i));end
end% 计算s中不大于si的值的最大索引
function idx = find_latest_index(si,s)[row,~] = size(s);if si <= 0 || row <= 1idx = 1;return;endfor i=2:rowif(s(i-1,1) <= si && si <= s(i,1))idx = i-1;return;endendidx = row;
end
三次样条插值法