数学建模-插值和拟合

本文详细介绍了插值和拟合的概念及应用,包括拉格朗日、牛顿、分段线性、埃尔米特、样条和B样条插值方法,以及解方程法、多项式拟合、最小二乘优化等曲线拟合技术。通过实例展示了各种方法的Matlab实现,强调了数据插值与曲线拟合的异同和适用场景。

插值和拟合

2021.8.11《数学建模算法与应用》读书笔记

一、定义

(1)插值

​ 求过已知有限个数据点的近似函数。

(2)拟合

​ 已知有限个数据点,求近似函数,不要求过已知数据点,只要求在某种意义

下它在这些点上的总偏差最小。

(3)数据插值和曲线拟合比较

①相同点

1、都属于函数逼近的方法

2、都能进行数据估算

②不同点

1、实现方法不同

数据插值要求逼近函数经过样本点,曲线拟合只要求总体误差最小

2、结果形式不同

数据插值分段进行逼近,没有统一的逼近函数。

曲线拟合有确定的逼近函数表达式。

3、侧重点不同

数据插值一般用于样本区间内的插值计算。

曲线拟合不仅可以估算区间内其他点的函数值,还可以预测持续数字的发展。

4、应用场合不同

样本数据是精确数据,适合采用数据插值方法。

样本数据统计数据,存在误差,适合用曲线拟合的方法。

二、插值方法

(1)常用的插值分类

  • 拉格朗日多项式插值

  • 牛顿插值

  • 分段线性插值

  • Hermite 插值

  • 三次样条插值。

(2)拉格朗日多项式插值(Lagrange插值)

2.1.1 插值多项式

在这里插入图片描述

2.1.2 拉格朗日插值多项式

在这里插入图片描述

2.1.3 Matlab实现Lagrange 插值
  • lagrange.m
%{
   
   
设n 个节点数据以数组 x0, y0输入(注意 Matlat 的数组下标从 1 开始),m 个插值
点以数组 x 输入,输出数组 y 为m 个插值。

    参数输入:
        x0,y0是原有的数据
        x为插值点(范围)
    参数输出
        y为x的插值输出
%}
function y=lagrange(x0,y0,x);
n=length(x0);m=length(x);
for i=1:m
    z=x(i);
    s=0.0;
    for k=1:n
        p=1.0;
        for j=1:n
            if j~=k
                p=p*(z-x0(j))/(x0(k)-x0(j));
            end
        end
        s=p*y0(k)+s;
    end
    y(i)=s;
end
  • 实例测试
% 拉格朗日插值法

% 原始数据
x0 = 0:0.1:1;
y0 = [-0.447,1.978,3.28,6.16,7.08,7.34,7.66,9.56,9.48,9.3,11.2];
hold on;
grid on;
plot(x0,y0,'b*')

% 插值点
x = 0:0.01:1;
% 拉格朗日多项式插值
y = lagrange(x0,y0,x);
plot(x,y,'r--');
legend('原始数据','拉格朗日插值','Location','North');
  • 测试结果
    在这里插入图片描述

(3)牛顿插值(Newton)

3.1 差商(预备知识)

在这里插入图片描述

3.2 牛顿插值公式

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

代码来自https://blog.csdn.net/seamanj/article/details/37562791

  • newton.m
%   newton.m
%   求牛顿插值多项式、差商、插值及其误差估计的MATLAB主程序
%   输入的量:X是n+1个节点(x_i,y_i)(i = 1,2, ... , n+1)横坐标向量,Y是纵坐标向量,
%   x是以向量形式输入的m个插值点,M[a,b]上满足|f~(n+1)(x)|≤M
%   注:f~(n+1)(x)表示f(x)的n+1阶导数
%   输出的量:向量y是向量x处的插值,误差限R,n次牛顿插值多项式L及其系数向量C%   差商的矩阵A
function[y,R,A,C,L] = newton(X,Y,x,M)
n = length(X);
m = length(x);
for t = 1 : m
    z = x(t);
    A = zeros(n,n);
    A(:,1) = Y';
    s = 0.0; p = 1.0; q1 = 1.0; c1 = 1.0;
        for j = 2 : n
            for i = j : n
                A(i,j) = (A(i,j-1) - A(i-1,j-1))/(X(i)-X(i-j+1));
            end
            q1 = abs(q1*(z-X(j-1)));
            c1 = c1 * j;
        end
        C = A(n, n); q1 = abs(q1*(z-X(n)));
        for k = (n-1):-1:1
            C = conv(C, poly(X(k)));
            d = length(C);
            C(d) = C(d) + A(k,k);%在最后一维,也就是常数项加上新的差商
        end
        y(t) = polyval(C,z);
        R(t) = M * q1 / c1;
end
L = poly2sym(C);
  • 实例运行
X = [0 pi/6 pi/4 pi/3 pi/2];  
Y = [0 0.5 0.7071 0.8660 1];  
x = linspace(0,pi,50);  
hold on;
grid on;
M = 1;  
[y,R,A,C,L] = newton(X, Y, x, M); 
plot(X,Y,'r*');
plot(x,y,'b--');
legend('原始数据','牛顿插值');
  • 运行结果
    在这里插入图片描述

对于其他的一些插值方法就不放原理了。直接掌握使用方式和使用情况。

(4)分段线性插值

①定义

将每两个相邻的节点用直线连起来,如此形成的一条折线就是分段线性插值函数

②Lagrange的问题

在这里插入图片描述

③matlab实现

在这里插入图片描述
代码看后文样条插值

(5)埃尔米特(Hermite)插值

①定义

如果对插值函数,不仅要求它 在 节 点 处 与 函 数 同 值 \color{blue}{在节点处与函数同值} ,而且要求它 与 函 数 有 相 同 的 一 阶 、 二 阶 甚 至 更 高 阶 的 导 数 值 \color{blue}{与函数有相同的一阶、二阶甚至更高阶的导数值} ,这就是 Hermite 插值问题。

②代码实现
  • hermite.m
%{
   
   
    设n 个节点的数据以
    数组 x0 (已知点的横坐标)
    y0 (函数值)
    y1(导数值)
    输入(注意 Matlat 的数组下标从 1 开始)
    m 个插值点以数组 x 输入
    输出数组 y 为m个插值
%}
function y=hermite(x0,y0,y1,x);
n=length(x0);m=length(x);
for k=1:m
    yy=0.0;
    for i=1:n
        h=1.0;
        a=0.0;
        for j=1:n
            if j~=i
                h=h*((x(k)-x0(j))/(x0(i)-x0(j)))^2;
                a=1/(x0(i)-x0(j))+a;
            end
        end
        yy=yy+h*((x0(i)-x(k
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值