函数逼近——两点三次Hermite(埃尔米特)、分段Hermite插值法 | 北太天元 or Matlab

一、两点三次Hermite插值

已知: 两个插值节点机器对应的导数值 ( x 0 , y 0 ) , ( x 1 , y 1 ) , y 0 ′ , y 1 ′ . (x_0,y_0),(x_1,y_1),y_0',y_1'. (x0,y0),(x1,y1),y0,y1.

H ( x ) = α 0 ( x ) y 0 + α 1 ( x ) y 1 + β 0 ( x ) y 0 ′ + β 1 ( x ) y 1 ′ H(x)=\alpha_0(x)y_0+\alpha_1(x)y_1+\beta_0(x)y_0'+\beta_1(x)y_1' H(x)=α0(x)y0+α1(x)y1+β0(x)y0+β1(x)y1

其中
{ α 0 ( x ) = ( 1 + 2 x − x 0 x 1 − x 0 ) ( x − x 1 x 0 − x 1 ) 2 α 1 ( x ) = ( 1 + 2 x − x 1 x 0 − x 1 ) ( x − x 0 x 1 − x 0 ) 2 { β 0 ( x ) = ( x − x 0 ) ( x − x 1 x 0 − x 1 ) 2 β 1 ( x ) = ( x − x 1 ) ( x − x 0 x 1 − x 0 ) 2 \begin{cases}\alpha_0(x)=\left(1+2\dfrac{x-x_0}{x_1-x_0}\right)\left(\dfrac{x-x_1}{x_0-x_1}\right)^2\\\alpha_1(x)=\left(1+2\dfrac{x-x_1}{x_0-x_1}\right)\left(\dfrac{x-x_0}{x_1-x_0}\right)^2\end{cases}\begin{cases}\beta_0(x)=(x-x_0)\left(\dfrac{x-x_1}{x_0-x_1}\right)^2\\\beta_1(x)=(x-x_1)\left(\dfrac{x-x_0}{x_1-x_0}\right)^2\end{cases} α0(x)=(1+2x1x0xx0)(x0x1xx1)2α1(x)=(1+2x0x1xx1)(x1x0xx0)2 β0(x)=(xx0)(x0x1xx1)2β1(x)=(xx1)(x1x0xx0)2

二、分段三次Hermite插值

H ( x i ) = f i , H ′ ( x i ) = f i ′ , i = 0 , 1 , ⋯   , n . H(x_i) = f_i,H'(x_i)=f'_i,i=0,1,\cdots,n. H(xi)=fi,H(xi)=fi,i=0,1,,n.

在每个 [ x i , x i − 1 ] [x_i,x_{i-1}] [xi,xi1]上利用 ( x i , y i ) , ( x i − 1 , y i − 1 ) , y i ′ , y i − 1 ′ (x_i,y_i),(x_{i-1},y_{i-1}),y_i',y_{i-1}' (xi,yi),(xi1,yi1),yi,yi1 进行三次Hermite插值

三、北太天元 or Matlab 实现

两点三次Hermite插值

function [output]= Hermite_interp(x0,y0,dy0,x)
% 两点三次 Hermite 插值
% x0 : [x1 x2]
% y0 : [y1 y2]
% dy0 : [y1' y2']
% length(x)=1
%
%   Version:            1.0
%   last modified:      05/16/2023
    h = x0(2)-x0(1);
    h1 = x - x0(1);
    h2 = x - x0(2);
    X1 = (h2/h)^2;
    X2 = (h1/h)^2;
    alpha1 = (1+2*h1/h)*X1;
    alpha2 = (1+2*h2/(-h))*X2;
    beta1 = h1*X1;
    beta2 = h2*X2;
    output = alpha1*y0(1)+alpha2*y0(2)+beta1*dy0(1)+beta2*dy0(2);
end

将上述代码保存为 Hermite_interp.m 文件.

分段三次Hermite插值

function [out1] = piecewise_Hermite_interp(x0,y0,dy0,x)
    % 分段Hermite插值
    % x0 : [x1 x2 ...]
    % y0 : [y1 y2...]
    % dy0 : [y1' y2'...]
    %
    %   Version:            1.0
    %   last modified:      09/13/2023
    %   file need: Hermite_interp.m
    m = length(x);
    n = length(x0);
    y = zeros(1,m);
    for k =1:1:m
        for i =1:1:n-1
        	   if x0(i)<=x(k) && x(k)<= x0(i+1)
        	   	 y(k) = Hermite_interp(x0([i,i+1]),y0([i,i+1]),dy0([i,i+1]),x(k));
        	   end
        end
    end
    out1 = y;
end

将上述代码保存为 piecewise_Hermite_interp 文件.

这里命名比较长,不过也没什么关系,我比较喜欢把意思表示清楚,另外也有代码的自动补全,也没有怎么不方便

四、简单实现一下

例1

% Hermite_v0 例子1
%   last modified:      04/17/2024
%   file need: Hermite_interp.m   piecewise_Hermite_interp.m
clc;clear all;
%样本点
x0 = [0 pi/2];%x0 = [0 pi];
y0 = sin(x0);
dy0 = cos(x0);

x = 0:pi/20:pi
y = zeros(1,length(x));
for i= 1:1:length(x)
    y(i) = Hermite_interp(x0,y0,dy0,x(i));
end

plot(x,y);
hold on 
    plot(x,sin(x),'r');
    legend('H(x)','sin(x)');
    title('H(x)与sin(x)的图像')
hold off

运行后得到在这里插入图片描述
上面这张图中设置的插值节点是在 0 , π 2 0,\frac{\pi}{2} 0,2π,所以在前半部分比较贴合。

例2

%% 分段Hermite_v0 例子2
clc;clear all;
Runge = @(x)1./(x.^2+1);  % 定义Runge函数
dRunge = @(x) -(2*x)./((x.^2+1).^2); % 定义导函数

x0 = linspace(-5,5,11);
y0 = Runge(x0);
dy0 = dRunge(x0);
x = linspace(-5,5,100);
yy = piecewise_Hermite_interp(x0,y0,dy0,x);
plot(x,yy);
hold on
plot(x,Runge(x),'r');
legend('分段Hermite','Runge函数')
hold off

下面这张图为分段三次Hermite插值在Runge函数上的表现,也算是分段上的一种优势。
在这里插入图片描述

这一小节内容比较简单,就介绍到这里。至于详细的理论证明,书本上已经写的很好了,我为什么要再抄一遍呢。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清水折木

谢谢前辈的鼓励,我会继续加油的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值