Makima修正Hermite插值

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

function [yi] = interp1TestHermite(x, y, xi)
% 测试makima插值
% 输入 - x: 距离, y: 函数值 , xi 待插值点
% 输出 - yi: 待插值点的函数值
% 不考虑越界的情况

% 保证一维输入且x与y的长度一致
sizex = (size(x));
sizey = (size(y));
if ~(sizex(1)*sizex(2)==sizex(1) || sizex(1)*sizex(2)==sizex(2)) || ~(sizey(1)*sizey(2)==sizey(1) || sizey(1)*sizey(2)==sizey(2))
    error('the input x or y must be one dimension!')
end

if length(x) ~= length(y)
    error('the lenth of x or y must be same!');
end

% 修正Akima插值计算点的导数
len = length(x);
extendInt = 0;
slope = (y(2 : end) - y(1 : end -1))./(x(2 : end) - x(1 : end -1));

w1 = zeros(1, len-1);
w2 = zeros(1, len-1);

for i = 3 : len-2
    w1(i) = abs(slope(i+1+extendInt) - slope(i+extendInt)) + abs(slope(i+1+extendInt) + slope(i+extendInt))/2;
    w2(i) = abs(slope(i-1+extendInt) - slope(i-2+extendInt)) + abs(slope(i-1+extendInt) + slope(i-2+extendInt))/2;
end
d = zeros(1, len-1);
for i = 3 : len-2
    d(i) = w1(i)/(w1(i)+w2(i))*slope(i-1+extendInt) + w2(i)/(w1(i)+w2(i)) * slope(i+extendInt);
end

% 三次hermite插值
yi = zeros(1, length(xi));
for i = 1 : length(xi)
    xIndex = 0;
    for j = 1 : 1 : length(x)
        if xi(i) - x(j) >= 0
            xIndex = j;
        end
    end
    fprintf(2, 'xIndex = %d\n', xIndex);
    
    yi(i) = ((1+2*(xi(i)-x(xIndex))/(x(xIndex+1)-x(xIndex)))*y(xIndex) + (xi(i)-x(xIndex))*d(xIndex))*((xi(i)-x(xIndex+1))/(x(xIndex)-x(xIndex+1)))^2+...
           ((1+2*(xi(i)-x(xIndex+1))/(x(xIndex)-x(xIndex+1)))*y(xIndex+1) + (xi(i)-x(xIndex+1))*d(xIndex+1))*((xi(i)-x(xIndex))/(x(xIndex+1)-x(xIndex)))^2;
   
%     % 已知x的间距全部为1
%     frac = xi(i)-x(xIndex);
%     fracInv = frac - 1;
%     yi(i) = ((1+2*frac)*y(xIndex) + frac * d(xIndex))*fracInv*fracInv  + ...
%             ((1-2*fracInv)*y(xIndex+1) + fracInv * d(xIndex+1))*frac*frac;
end

end


function [yi] = interp1TestHermiteMakima(x, y, xi)
% 测试makima插值
% 输入 - x: 距离, y: 函数值 , xi 待插值点
% 输出 - yi: 待插值点的函数值
% 不考虑越界的情况

% 保证一维输入且x与y的长度一致
sizex = (size(x));
sizey = (size(y));
if ~(sizex(1)*sizex(2)==sizex(1) || sizex(1)*sizex(2)==sizex(2)) || ~(sizey(1)*sizey(2)==sizey(1) || sizey(1)*sizey(2)==sizey(2))
    error('the input x or y must be one dimension!')
end

if length(x) ~= length(y)
    error('the lenth of x or y must be same!');
end

% 修正Akima插值计算点的导数
len = length(x);
if len < 2
    error('the lenth of x can not be smaller than 2!');
end
extendInt = 2;
slope0 = (y(2 : end) - y(1 : end -1))./(x(2 : end) - x(1 : end -1));
% slope 需要向左和右各扩展两个点
slope = zeros(1, length(slope0)+2*extendInt);
slope(3 : end-2) = slope0;
if len >= 3
    slope(1) = 2*slope0(1) - slope0(2);
    slope(2) = 3*slope0(1) - 2 * slope0(2);
    slope(end-1) = 2*slope0(end) - slope0(end-1);
    slope(end) = 3*slope0(end) - 2*slope0(end-1);
end
if len == 2
    slope(1) = slope0(1);
    slope(2) = slope0(1);
    slope(end-1) = slope0(1);
    slope(end) = slope0(1);
end

w1 = zeros(1, len-1);
w2 = zeros(1, len-1);

for i = 3-extendInt : len-2+extendInt
    w1(i) = abs(slope(i+1+extendInt) - slope(i+extendInt)) + abs(slope(i+1+extendInt) + slope(i+extendInt))/2;
    w2(i) = abs(slope(i-1+extendInt) - slope(i-2+extendInt)) + abs(slope(i-1+extendInt) + slope(i-2+extendInt))/2;
end
d = zeros(1, len-1);
for i = 3-extendInt : len-2+extendInt
    d(i) = w1(i)/(w1(i)+w2(i))*slope(i-1+extendInt) + w2(i)/(w1(i)+w2(i)) * slope(i+extendInt);
end
d(isnan(d)) = 0;


% 三次hermite插值
yi = zeros(1, length(xi));
for i = 1 : length(xi)
    xIndex = 0;
    for j = 1 : 1 : length(x)
        if xi(i) - x(j) >= 0
            xIndex = j;
        end
    end
    fprintf(2, 'xIndex = %d\n', xIndex);
    
    if xIndex < 1
        xIndex = 1;
    end
    if xIndex >= len
        xIndex = len - 1;
    end
    
    yi(i) = ((1+2*(xi(i)-x(xIndex))/(x(xIndex+1)-x(xIndex)))*y(xIndex) + (xi(i)-x(xIndex))*d(xIndex))*((xi(i)-x(xIndex+1))/(x(xIndex)-x(xIndex+1)))^2+...
           ((1+2*(xi(i)-x(xIndex+1))/(x(xIndex)-x(xIndex+1)))*y(xIndex+1) + (xi(i)-x(xIndex+1))*d(xIndex+1))*((xi(i)-x(xIndex))/(x(xIndex+1)-x(xIndex)))^2;
    
end

end


clc
clear all; close all;

%% 测试只考虑中间部分的hermite插值
slen = 16;
space = 0.1;
x = 1 : slen;
y = rand(1, slen)*10;
xi = 3 : space : slen-2 ;
yi = interp1(x, y, xi, 'makima');
yis = interp1TestHermite(x, y, xi);

figure
plot(x,y,'*-', xi, yi, 'r*-', xi, yis, 'bo-');
legend('origin data','matlab interp1-makima', 'hermite-makima');
title('interpolation hermite-makima test');
mean((yis - yi))

%% 测试只有两个点的makima修正的hermite插值
slen = 2;
space = 0.1;
x = 1 : slen;
y = rand(1, slen)*10;
xi = 1 : space : slen ;
yi = interp1(x, y, xi, 'makima');
yis = interp1TestHermiteMakima(x, y, xi);

figure
plot(x,y,'*-', xi, yi, 'r*-', xi, yis, 'bo-');
legend('origin data','matlab interp1-makima', 'hermite-makima(two points)');
title('interpolation hermite-makima only two point test');
mean((yis - yi))

%% 测试包含多个点的makima修正hermite插值
slen = 16;
space = 0.1;
x = 1 : slen;
y = rand(1, slen)*10;
xi = 1 : space : slen ;
yi = interp1(x, y, xi, 'makima');
yis = interp1TestHermiteMakima(x, y, xi);

figure
plot(x,y,'*-', xi, yi, 'r*-', xi, yis, 'bo-');
legend('origin data','matlab interp1-makima', 'hermite-makima');
title('interpolation hermite-makima extral four-points');
mean((yis - yi))



代码如上所示,分别测试了不外扩的makima修正三阶hermite插值、外扩4个点的makima修正三阶hermite插值(仅包含两个点,包含多个点的情况)。结果如图所示。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值