Matlab实现Newton插值、Lagrange插值、分段线性插值和三次自然样条曲线插值

Matlab实现Newton插值、Lagrange插值、分段线性插值和三次自然样条曲线插值

  • 对Runge函数 R ( x ) = 1 / ( 1 + 25 x 2 ) R(x)=1/(1+25x^2) R(x)=1/(1+25x2)在区间[-1,1]插值
    • Newton插值
    • Lagrange插值
    • 分段线性插值
    • 三次自然样条插值
      • 递归计算牛顿均差

对Runge函数 R ( x ) = 1 / ( 1 + 25 x 2 ) R(x)=1/(1+25x^2) R(x)=1/(1+25x2)在区间[-1,1]插值

Newton插值

牛顿均差
牛顿插值公式

%Runge 1/(1+25x2)   [-1.1]
tic
f = @(x) 1./(1+25*x.^2);
h = 0.1;
i = [0:20];
x = -1 + i*h;
%20次插值
N=20;

t1 = toc; %第一次计时

x2 = -1:0.01:1;
fx2 = x2.*0 + f(x(1));

for i = 1:N
    temp = ones(size(x2));
    for j = 1:i
        temp = temp .* (x2 - x(j));
    end
 
    temp = temp * juncha(x(1:j+1),f);
    fx2 = fx2 + temp;
end

t2 = toc; %第er次计时

t2 - t1

plot(x2,f(x2))
hold on 

plot(x2,fx2)
legend('Runge函数','20次等距牛顿插值多项式')

norm(fx2 - f(x2),inf) %计算误差

Lagrange插值

拉格朗日插值法的节点基函数
拉格朗日插值多项式

%Runge 1/(1+25x2)   [-1,1]
clc,clear all
f = @(x) 1./(1+25*x.^2);
i = [0:20];
x = cos((2*i+1)/42*pi);
%20次插值
N=20;
tic
fx0 = f(x(1));


t1 = toc; %第一次计时

x2 = -1:0.01:1;
fx2 = x2.*0;
for i = 1:N+1
    temp = ones(size(x2));
    for j = 1:N+1
        %节点基函数lj的计算
        if j ~= i 
            temp = temp .* (x2 - x(j)) / (x(i) - x(j));
        end
    end
    fx2 = fx2 + f(x(i))*temp;
end
t2 = toc; %第一次计时
t2 - t1
plot(x2,f(x2))
hold on 
plot(x2,fx2)
legend('Runge函数','20次余弦拉格朗日插值')

norm(fx2 - f(x2),inf)

分段线性插值

Matlab实现Newton插值、Lagrange插值、分段线性插值和三次自然样条曲线插值_第1张图片
插值多项式

%piecewise
clear all, clc
f = @(x) 1./(1+25*x.^2);
h = 0.1;
i = [0:20];
x = -1 + i*h;
N = 20
tic
x2 = [-1:0.001:1];
t1 = toc; %第一次计时

fx2 = zeros(size(x2));
for i = 1:N+1
    li = zeros(size(x2));
    if i== 1
        li(find(x(i)<x2&x2<x(i+1))) = (x2(find(x(i)<x2&x2<x(i+1))) - x(i+1))/(x(i)-x(i+1));
    elseif i == N+1
        li(find(x(i-1)<=x2&x2<=x(i))) = fliplr((x2(find(x(i-1)<=x2&x2<=x(i))) - x(i))/(x(i-1)-x(i)));
    else
        li(find(x(i)<x2&x2<x(i+1))) = (x2(find(x(i)<x2&x2<x(i+1))) - x(i+1))/(x(i)-x(i+1));
        li(find(x(i-1)<=x2&x2<=x(i))) = fliplr((x2(find(x(i-1)<=x2&x2<=x(i))) - x(i))/(x(i-1)-x(i)));
    end
    fx2 = fx2 + f(x(i))*li;
end

t2 = toc; %第一次计时
t2 - t1
plot(x2,f(x2))
hold on 

plot(x2,fx2)
legend('Runge函数','20次线性分段插值')

norm(fx2 - f(x2),inf)

三次自然样条插值

%Cubic natural spline interpolation

clear all, clc
f = @(x) 1./(1+25*x.^2);
h = 0.1;
i = [0:20];
x = -1 + i*h;
N = 20;
tic
x2 = [-1:0.001:1];
h = h* ones(size(x2));
t1 = toc; %第一次计时
fx2 = zeros(size(x2));
dx = 0.00000001;
M(0+1) = (f(x(1)) - f(x(1)-dx))/dx;
M(N+1) = (f(x(N+1)) - f(x(N+1)-dx))/dx;
lambda = 1/2;
miu = 1/2;
for i = 2:N
    d(i - 1) = 6*juncha(x(i-1:i+1),f);
    b(i-1) = d (i-1);
end

b(1) = b(1) - miu*M(0+1);
b(N-1) = b(N-1) - lambda*M(N+1);

for i = 1:N-1
    A(i,i) = 2;
    if i <N-1
        A(i,i+1) = lambda;
        A(i+1,i) = miu;
    end
end

M(2:N) = A\b';



for i = 1:N
    li = zeros(size(x2));
    t = x2(find(x(i)<=x2&x2<x(i+1)));
    li(find(x(i)<=x2&x2<x(i+1))) = M(i)*(x(i+1)-t).^3/6/h(i) + M(i+1)*(t - x(i)).^3/6/h(i) + (f(x(i)) - M(i)*h(i).^2/6)*(x(i+1)-t)/h(i) + (f(x(i+1))- M(i+1)*h(i).^2/6)*(t - x(i))/h(i);
    fx2 = fx2 + li;

end

t2 = toc; %第一次计时
t2 - t1
plot(x2,f(x2))
hold on 

plot(x2,fx2)
legend('Runge函数','三次自然样条插值')

norm(fx2 - f(x2),inf)

递归计算牛顿均差

function [res] = juncha(vxk,f)
%递归计算牛顿均差
    L = length(vxk);
    if L == 1
        res = f(vxk);
    else
        res = (juncha(vxk(2:L),f) - juncha(vxk(1:L-1),f))/(vxk(L)-vxk(1));
    end

end


你可能感兴趣的:(Matlab实现Newton插值、Lagrange插值、分段线性插值和三次自然样条曲线插值)