这个内容比较简单,主要是对线性插值的一个应用
将大区间先划分为 很多个小区间,再取这些小区间的端点为插值节点,两两进行线性插值,
最终得到的就是分段线性插值了
分段线性插值
函数代码
这个代码写的很粗糙,能实现就行,我们主要看它的效果。
function output = piecewise_linear_interp(x0,y0,x)
% 分段线性插值
% x0为样本点横坐标,行向量
% y0为样本点纵坐标,行向量
% x 为 自变量
%
% Version: 1.0
% last modified: 06/14/2023
n1 = length(x0);
n2 = length(x);
l = zeros(1,n1); %预留出基函数的空间
y = zeros(1,n2); %预留出x所对的y的空间
for j =1:1:n2
if x(j)>=x0(1) && x(j)<=x0(2)
l(1) = (x(j)-x0(2))/(x0(1)-x0(2));
else
l(1) = 0;
end
for i = 2:1:n1-1;
if x0(i-1) <= x(j) && x(j)<=x0(i)
l(i) = (x(j) - x0(i-1))/(x0(i)-x0(i-1));
elseif x0(i)<=x(j) && x(j)<=x0(i+1)
l(i) = (x(j) - x0(i+1))/(x0(i)-x0(i+1));
else
l(i) = 0;
end
end
if x0(n1-1) <= x(j) && x(j) <= x0(n1)
l(n1) = (x(j) - x0(n1-1))/(x0(n1)-x0(n1-1));
else
l(n1) = 0;
end
y(j) = y0 * l';
end
output = y;
end
分段线性插值在龙格函数上的一个应用
%% 分段线性
clc;clear all;format long;
x = linspace(-5,5,100);
% 使用函数句柄的方式表示函数
Runge = @(x)1./(x.^2+1);
y = Runge(x);
% 计算误差前的准备
x2 = linspace(-5,5,1001);
y2 = Runge(x2);
delta = zeros(1,19);
% 绘制 f(x)图像和 插值函数图像
for n = 2:1:20
figure(n);
% 随着 n 的 变化,样本点也在发生变化
x1 = linspace(-5,5,n+1);
y1 = Runge(x1);
Ln = piecewise_linear_interp(x1,y1,x);
plot(x,Ln,'b');
hold on
plot(x,y,'r');
plot(x1,y1,'ob')
legend('分段线性','原函数')
hold off
% 计算误差
delta(n-1) = max(abs(y2 - piecewise_linear_interp(x1,y1,x2)));
end
% 观察误差
n = 2:1:20;
plot(n,delta,'o-b');
title('误差变化');
执行后得到
分段插值函数与原函数随着插值节点的增加误差变化如下
相比高次的Lagrange插值,收敛效果还是不错的。
插值节点平均取的两种情况
(下面这张图顶部没有完全取到,是因为取的画图的点与插值节点没有重合导致的,画图的点取的更密集一些就可以了)
讨论
上图中的的插值节点是平均取的,导致其并不会每次都取到我们想要的地方,由此我们有这样一个想法
怎么样取插值节点,可以达到更好的逼近效果
对于这个问题,后续文章会继续进行讨论。