数值分析——分段低次插值

news2024/12/26 11:25:34

关键字:Matalb;曲线拟合;高次病态特性;分段低次插值

系列文章目录

数值分析——拉格朗日插值
数值分析——牛顿插值多项式
数值分析——埃尔米特(Hermit)插值


文章目录

  • 系列文章目录
  • 前言
  • 一、理论推导
    • 1.高次插值的病态特性
    • 2.分段线性插值
    • 3.分段三次Hermit插值
  • 二、MATLAB
    • 1.分段线性插值
    • 2.分段Hermit插值
    • 3.测试程序
  • 总结
  • 参考文献


前言

  一般认为对于区间 [ a , b ] \left[a,b\right] [a,b]上给出的节点做插值多项式 L n ( x ) L_n\left( x \right) Ln(x)近似 f ( x ) f\left( x \right) f(x),一般总认为 L n ( x ) L_n\left( x \right) Ln(x)的次数 n n n越高,插值函数逼近原函数的效果越好,但实际上并非如此。这是因为对于任意的插值节点,当 n → ∞ n\rightarrow \infty n时, L n ( x ) L_n\left( x \right) Ln(x)不一定收敛于 f ( x ) f\left( x \right) f(x)。为了解决高次插值的问题,学者们提出了分段低次插值的方法,即将被拟合函数 f ( x ) f\left( x \right) f(x)分为多个小区间,在小区间上利用低次多项式进行插值拟合。

本文对一些复杂的流程与概念进行了简化与省略,如果想详细了解的小伙伴可以参考李庆扬老师的《数值分析 -第5版》的第2章(需要电子版请私戳)


一、理论推导

1.高次插值的病态特性

  高次插值的病态特性指的是,在对某些函数 f ( x ) f\left( x \right) f(x)进行拟合时,高次多项式的插值函数拟合效果反而不好的特性。例如针对函数:
f ( x ) = 1 x 2 + 1 (1) f\left( x \right)=\frac{1}{x^2+1} \tag{1} f(x)=x2+11(1)使用拉格朗日插值法,在插值节点 x = − 5 , − 4 , − 3 , − 2 , − 1 , 0 , 1 , 2 , 3 , 4 , 5 x=-5,-4,-3,-2,-1,0,1,2,3,4,5 x=5,4,3,2,1,0,1,2,3,4,5拟合十次插值函数:

% 高次插值的动态特性
x=-5:0.05:5;
y=zeros(1,length(x));                                                       % 原函数y值
xInArr=-5:1:5;                                                              % 插值节点x值
yInArr=zeros(1,length(xInArr));                                             % 插值节点y值
yOutArr=zeros(1,length(x));                                                 % 插值函数y值
% 计算插值函数y值
for i=1:1:length(xInArr)
    yInArr(i)=1/(xInArr(i)^2+1);
end
% 计算十次插值多项式的poly数组
L10=func_LagrangeInterpolation(xInArr,yInArr,11);
% 计算原函数与插值函数y值
for i=1:1:length(x)
    y(i)=1/(x(i)^2+1);
    yOutArr(i)=polyval(L10,x(i));
end
% 画图
plot(x,y,'k-',x,yOutArr,'r:','LineWidth',2);
xlabel('x');
ylabel('y');
legend('f(x)','L10(x)');

其中func_LagrangeInterpolation是拉格朗日插值法函数,具体内容可参考数值分析——拉格朗日插值中的代码。得到的对比结果:
Alt

图1.1 高次插值函数的病态特性

其中红色的点线为十次拉格朗日插值函数 L 10 ( x ) L_{10}\left( x \right) L10(x),黑色的曲线为原函数 f ( x ) f\left( x \right) f(x),可以看到插值函数的拟合效果并不是很好。

2.分段线性插值

  分段线性插值就是通过插值点用折现段连接起来逼近 f ( x ) f\left( x \right) f(x)。若在已知节点 a = x 0 < x 1 < ⋯ < x n = b a=x_0<x_1<\cdots<x_n=b a=x0<x1<<xn=b,已知各点的函数值f_0,f_1,f_2,\cdots,f_{n-1},f_n,则可以设计一个插值函数:
I h ( x ) = x − x k + 1 x k − x k + 1 f k + x − x k x k + 1 − x k f k + 1 ,    x k ≤ x ≤ x k + 1 ,    k = 0 , 1 , ⋯   , n − 1 (2) I_h\left( x \right)= \frac{x-x_{k+1}}{x_{k}-x_{k+1}}f_k+ \frac{x-x_{k}}{x_{k+1}-x_{k}}f_{k+1}, \ \ x_k \le x \le x_{k+1}, \ \ k=0,1,\cdots,n-1 \tag{2} Ih(x)=xkxk+1xxk+1fk+xk+1xkxxkfk+1,  xkxxk+1,  k=0,1,,n1(2)该插值函数满足:

  1. 函数属于在区间 [ a , b ] [a,b] [a,b]连续的函数空间: I h ( x ) ∈ C [ a , b ] I_h\left( x \right)\in C\left[a,b\right] Ih(x)C[a,b]
  2. 插值函数在所有插值点的数值都等于原函数: I h ( x ) = f k ( k = 0 , 1 , ⋯   , n − 1 ) I_h\left( x \right)=f_k\left(k=0,1,\cdots,n-1\right) Ih(x)=fk(k=0,1,,n1)
  3. 插值函数在每个小区间上是线性函数: I h ( x ) = k x + b I_h\left( x \right)=kx+b Ih(x)=kx+b

3.分段三次Hermit插值

  分段线性插值函数的导数是间断的,如果在插值节点 a = x 0 < x 1 < ⋯ < x n = b a=x_0<x_1<\cdots<x_n=b a=x0<x1<<xn=b上,不仅已知函数值 f 0 , f 1 , f 2 , ⋯   , f n − 1 , f n f_0,f_1,f_2,\cdots,f_{n-1},f_n f0,f1,f2,,fn1,fn,而且已知函数导数值 f 0 ′ , f 1 ′ , f 2 ′ , ⋯   , f n − 1 ′ , f n ′ f^{'}_0,f^{'}_1,f^{'}_2,\cdots,f^{'}_{n-1},f^{'}_n f0,f1,f2,,fn1,fn,则可以设计一个插值函数:
I h ( x ) = ( x − x k + 1 x k − x k + 1 ) 2 ( 1 + 2 x − x k x k + 1 − x k ) f k + ( x − x k x k + 1 − x k ) 2 ( 1 + 2 x − x k + 1 x k − x k + 1 ) f k + 1 + ( x − x k + 1 x k − x k + 1 ) 2 ( x − x k ) f k ′ + ( x − x k x k + 1 − x k ) 2 ( x − x k + 1 ) f k + 1 ′ ,    x k ≤ x ≤ x k + 1 ,    k = 0 , 1 , ⋯   , n − 1 (3) \begin{align} I_h\left( x \right)= &\left(\frac{x-x_{k+1}}{x_{k}-x_{k+1}}\right)^2 \left( 1+2\frac{x-x_k}{x_{k+1}-x_{k}} \right)f_k+ \left(\frac{x-x_{k}}{x_{k+1}-x_{k}}\right)^2\left( 1+2\frac{x-x_{k+1}}{x_{k}-x_{k+1}} \right)f_{k+1} \\ &+\left(\frac{x-x_{k+1}}{x_{k}-x_{k+1}}\right)^2\left( x-x_k \right)f^{'}_k+\left(\frac{x-x_{k}}{x_{k+1}-x_{k}}\right)^2\left( x-x_{k+1} \right)f^{'}_{k+1}, \ \ x_k \le x \le x_{k+1}, \ \ k=0,1,\cdots,n-1 \end{align} \tag{3} Ih(x)=(xkxk+1xxk+1)2(1+2xk+1xkxxk)fk+(xk+1xkxxk)2(1+2xkxk+1xxk+1)fk+1+(xkxk+1xxk+1)2(xxk)fk+(xk+1xkxxk)2(xxk+1)fk+1,  xkxxk+1,  k=0,1,,n1(3)该插值函数满足:

  1. 插值函数属于在区间 [ a , b ] [a,b] [a,b]上一阶导数连续的函数空间: I h ( x ) ∈ C 1 [ a , b ] I_h\left( x \right)\in C^1\left[a,b\right] Ih(x)C1[a,b]
  2. 插值函数在所有插值点的数值都等于原函数: I h ( x ) = f k ( k = 0 , 1 , ⋯   , n − 1 ) I_h\left( x \right)=f_k\left(k=0,1,\cdots,n-1\right) Ih(x)=fk(k=0,1,,n1)
  3. 插值函数一阶导数在所有插值点的数值都等于原函数一阶导数: I h ′ ( x ) = f k ′ ( k = 0 , 1 , ⋯   , n − 1 ) I_h^{'}\left( x \right)=f_k^{'}\left(k=0,1,\cdots,n-1\right) Ih(x)=fk(k=0,1,,n1)
  4. 插值函数在每个小区间上是三次多项式: I h ( x ) = a x 3 + b x 2 + c x + d I_h\left( x \right)=ax^3+bx^2+cx+d Ih(x)=ax3+bx2+cx+d

二、MATLAB

1.分段线性插值

% 分段线性插值
function [yOutArr]=func_PiecewiseLinearInterpolation(xInArr,yInArr,xQuery)
    % ************************************************************
    % 识别误差
    % ************************************************************
    xInLength=length(xInArr);
    yInLength=length(yInArr);
    % 插值数组不匹配
    if xInLength~=yInLength
        error('Error:The xInArr %d and the yInArr %d are not equal in length.',xInLength,yInLength);
    end
    % ************************************************************
    % 计算查询节点在插值函数上的函数值
    % ************************************************************
    % 只一个插值节点
    if xInLength==1
        yOutArr=yInArr;
        return;
    end
    % 有多个插值节点
    xQueryLength=length(xQuery);
    yOutArr=zeros(1,xQueryLength);
    pos=1;
    for i=1:1:xQueryLength
        for j=pos:1:xInLength-1
            % 查询节点如果超出插值节点范围则报错
            if xQuery(i)>xInArr(xInLength)||xQuery(i)<xInArr(1)
                error('Error:The num of the xQuery should gainer than %d and lesser than %d.',xInArr(1),xInArr(xInLength));
            end
            % 定位查询数组在插值节点的位置
            if (xQuery(i)>xInArr(j)&&xQuery(i)<xInArr(j+1))||(xQuery(i)==xInArr(j))
                pos=j;
                break;
            end
        end
        % 计算查询节点在插值函数上的函数值
        yOutArr(i)=polyval(func_LinearInterpolation(xInArr(pos),yInArr(pos),xInArr(pos+1),yInArr(pos+1)),xQuery(i));
    end
end

2.分段Hermit插值

% 分段三次Hermit插值
function [yOutArr]=func_PiecewiseCubeHermitInterpolation(xInArr,yInArr,dyInArr,xQuery)
    % ************************************************************
    % 识别误差
    % ************************************************************
    xInLength=length(xInArr);
    yInLength=length(yInArr);
    % 插值数组不匹配
    if xInLength~=yInLength
        error('Error:The xInArr %d and the yInArr %d are not equal in length.',xInLength,yInLength);
    end
    % ************************************************************
    % 计算查询节点在插值函数上的函数值
    % ************************************************************
    % 只一个插值节点
    if xInLength==1
        yOutArr=yInArr;
        return;
    end
    % 有多个插值节点
    xQueryLength=length(xQuery);
    yOutArr=zeros(1,xQueryLength);
    pos=1;
    for i=1:1:xQueryLength
        for j=pos:1:xInLength-1
            % 查询节点如果超出插值节点范围则报错
            if xQuery(i)>xInArr(xInLength)||xQuery(i)<xInArr(1)
                error('Error:The num of the xQuery should gainer than %d and lesser than %d.',xInArr(1),xInArr(xInLength));
            end
            % 定位查询数组在插值节点的位置
            if (xQuery(i)>xInArr(j)&&xQuery(i)<xInArr(j+1))||(xQuery(i)==xInArr(j))
                pos=j;
                break;
            end
        end
        % 计算查询节点在插值函数上的函数值
        yOutArr(i)=polyval(func_2dotsCubicHermitInterpolation(xInArr(pos:1:pos+1),yInArr(pos:1:pos+1),dyInArr(pos),dyInArr(pos+1)),xQuery(i));
    end
end

3.测试程序

% 测试分段低次插值函数——func_PiecewiseLinearInterpolatio、func_PiecewiseCubeHermitInterpolation
clc;
clear;
close all;

x=-0.2*pi:0.2*pi:10*pi;
y=sin(x);
dy=diff(y,1);


xq=0:0.01*pi:10*pi;
yq1=func_PiecewiseLinearInterpolation(x(2:1:length(x)),y(2:1:length(x)),xq);
yq2=func_PiecewiseCubeHermitInterpolation(x(2:1:length(x)),y(2:1:length(x)),dy,xq);
plot(x,y,'k*',xq,yq1,'r-',xq,yq2,'b-');

Alt

图2.1 分段线性与Hermit插值

总结

  以上在本文中对分段低次插值的两种常见方法的推导进行了简单介绍,并提供了MATLAB的实现代码与测试用例。

参考文献

[1]李庆扬,王能超,易大义. 数值分析.第5版[M]. 清华大学出版社, 2008.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1969779.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python面试宝典第25题:括号生成

题目 数字n代表生成括号的对数&#xff0c;请设计一个函数&#xff0c;用于能够生成所有可能的并且有效的括号组合。 备注&#xff1a;1 < n < 8。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()"…

泛化的最近点迭代法(Generalized-ICP)

Generalized-ICP算法是由斯坦福大学的Aleksandr V. Segal、Dirk Haehnel和Sebastian Thrun提出的&#xff0c;于2009年在Robotics science and system会议上发表。 GICP是一种ICP算法的变体&#xff0c;其原理与ICP算法相同&#xff0c;之所以称为泛化的ICP算法是因为大多数ICP…

MongoDB性能调优

文章目录 MongoDB性能调优MongoDB性能不佳原因影响MongoDB性能的因素MongoDB性能监控工具mongostatmongotopProfiler模块db.currentOp() MongoDB性能调优 MongoDB性能不佳原因 慢查询阻塞等待硬件资源不足 1,2通常是因为模型/索引设计不佳导致的 排查思路&#xff1a;按1-2…

再论国产数据库的选择

如何选择国产数据库? 上篇写得很水,本来不想继续写了! 毕竟写一篇很费心力,大家觉得好,就点下广告支持下吧! 因为今天看到类总的朋友圈,发个公号文章.里面讲个故事, 数据最前线 关注数据生态&#xff0c;讲述开源故事 13篇原创内容 公众号 某国产数据库救援现场惊魂8小时…

Golang | Leetcode Golang题解之第313题超级丑数

题目&#xff1a; 题解&#xff1a; func nthSuperUglyNumber(n int, primes []int) int {dp : make([]int, n1)m : len(primes)pointers : make([]int, m)nums : make([]int, m)for i : range nums {nums[i] 1}for i : 1; i < n; i {minNum : math.MaxInt64for j : range…

【大模型框架】【推理加速】KV CACHE

1. 思想 核心思想是空间换时间来进行加速 2. 基本原理 transformer是自回归生成模型&#xff0c;abc三个字符预测def 过程是: abc -> d d进行回归得到abc,回归讲究的是回去&#xff0c;如香港回归 abcd -> e 这里abc的运算中间值Q V可以保存下来作为Cache&#xf…

爬猫眼电ying

免责声明:本文仅做分享... 未优化,dp简单实现 from DrissionPage import ChromiumPage import time urlhttps://www.maoyan.com/films?showType2&offset60 pageChromiumPage()page.get(url) time.sleep(2) for i in range(1,20):# 爬取的页数for iu_list in page.eles(.…

c语言指针中“数组名的理解”以及“一维数组传参”的本质

数组名的理解 数组名就是数组首元素的地址。 例如&#xff1a;输入一个数组的所有元素&#xff0c;再打印出来。 另一种写法 以上可以看出&#xff1a;*arri&#xff09; arr[i] 也即是&#xff1a;*(iarr)i[arr] 本质上无区别 1&#xff1a;数组就是数组&#xff0c;是一块…

List 31

ArrayList底层原理 Linkedlist的底层原理 使用场景

扎克伯格说Meta训练Llama 4所需的计算能力是Llama 3的10倍

Meta 公司开发了最大的基础开源大型语言模型之一 Llama&#xff0c;该公司认为未来将需要更强的计算能力来训练模型。马克-扎克伯格&#xff08;Mark Zuckerberg&#xff09;在本周二的 Meta 第二季度财报电话会议上表示&#xff0c;为了训练 Llama 4&#xff0c;公司需要比训练…

做管理,一定要避开这6个坑,才能成就优秀管理者

做管理&#xff0c;一定要避开这6个坑&#xff0c;才能成就优秀管理者 一、被平庸的员工绑架 要是领导不敢或者不愿意惩罚或者开除那些没完成任务的员工&#xff0c;那优秀的员工就会觉得&#xff0c;做得好做得差都一样&#xff0c;那谁还愿意努力呢&#xff1f; 二、总想改变…

【Mind+】掌控板入门教程01 “秀”出我创意

我们的好朋友麦乐佳即将举办一场派对&#xff0c;她要求每个参加派对的人都要佩戴一个可以彰显自己独特创意的装置。可以是会发光的帽子&#xff0c;可以是复古的电子表&#xff0c;还可以是其他有创意的作品。而现在&#xff0c;我们的手边刚好有一块掌控板&#xff0c;它自带…

汇聚数字智慧 构建新质未来——《CMG数字中国》融媒体节目正式上线

7月25日&#xff0c;由中央广播电视总台上海总站、央视频和数创未来&#xff08;上海&#xff09;传媒科技有限公司联合打造的《CMG数字中国》融媒体节目正式上线。 中国共产党第二十届中央委员会第三次全体会议提出&#xff0c;高质量发展是全面建设社会主义现代化国家的首要…

8.Redis的List类型

Redis中的list跟java中的LinkedList比较相似&#xff0c;可以看做是一个双向链表的结构。 既可以支持正向检索和反向检索。 特点 1.有序 2.元素可以重复 3.插入和删除快 4.查询速度一般 应用场景 点赞和评论功能&#xff0c;都会存在一个顺序&#xff0c;谁先评论&…

AI Agent学习系列:扣子智能体手把手入门教程

AI智能体为什么现在这么火&#xff1f;我个人认为有以下几点原因&#xff1a; 智能体基于大模型而又强于大模型&#xff08;垂直领域&#xff09; 智能体基于零代码或者低代码模式&#xff0c;不需要编程基础&#xff0c;对于非程序员非常友好&#xff0c;使得大多数人都能成…

CoderGuide

CoderGuide是一个针对同学们前后端求职面试的开源项目&#xff0c;作为一名互联网/IT从业人员&#xff0c;经常需要搜索一些书籍、面试题等资源&#xff0c;在这个过程中踩过很多坑、浪费过很多时间。欢迎大家 Watch、Star&#xff0c;供各位同学免费使用&#xff0c;永不收费&…

【Python】pandas:替换值、添加行/列,删除行/列,更改形状(含数据透视表)

pandas是Python的扩展库&#xff08;第三方库&#xff09;&#xff0c;为Python编程语言提供 高性能、易于使用的数据结构和数据分析工具。 pandas官方文档&#xff1a;User Guide — pandas 2.2.2 documentation (pydata.org) 帮助&#xff1a;可使用help(...)查看函数说明文…

9.Redis的Set类型

Redis的Set结构与java中的HashSet类似。 可以看做是一个value为null的HashMap。 特点 1.无序 2.元素不可重复 3.查找快 4.支持交集、并集、差集等功能 应用场景 实现共同关注&#xff0c;共同好友。 常见命令 sadd key 元素1 元素2 给set集合添加一个或多个元素 smem…

Node.js(2)——压缩前端html

需求&#xff1a;把回车符&#xff08;\r&#xff09;和换行符&#xff08;\n&#xff09;去掉后&#xff0c;写入到新的html文件中 步骤&#xff1a; 读取源html文件内容正则替换字符串写入到新的html文件中 示例&#xff1a; 获取html文件中的内容并检查&#xff08;同时…

temu电商的选品师能当成副业做吗?

在当今充满机会的电商行业中&#xff0c;成为一名选品师是否适合作为副业呢?这是一个颇具吸引力的问题&#xff0c;特别是对于那些希望在自由职业和兼职之间寻找平衡的人群。TEMU电商平台的选品师角色&#xff0c;不仅涉及到产品的挑选&#xff0c;还包括市场研究、竞争分析以…