• 基于MATLAB的函数拟合


    函数拟合

    整体思路

    将给定的坐标点分为 6 段部分,即左、左下、下、右、右上、上,6 部分。

    其中左下和右上部分使用二次函数进行拟合,其他部分使用一次函数进行拟合。

    观察数据

    第 1-76 个点作为左边部分线性拟合

    第 67-96 个点作为左下部分二次拟合

    第 84-215 个点作为下部分线性拟合

    第 216-275 个点作为右部分线性拟合

    第 269-298 个点作为右上部分二次拟合

    第 296-382 个点作为上部分一次拟合

    代码实现

    先得到 x、y 数据的散点向量,然后调用 polyfit 库函数,返回线性回归的函数参数,然后初始化较为密集的 x 横坐标作为样点横坐标,用求得的拟合函数代入样点横坐标得到样点纵坐标。此时较为密集的样点通过 plot 函数显示出来,即可得到拟合效果图

    • 最终效果

    在这里插入图片描述

    可以看出,在左下和右上通过二次函数拟合,在其他位置使用一次函数线性拟合

    • 遇到的问题和解决方案

    在最初选取拟合的坐标时,在 6 个曲线部分,每个部分选择的点集都不相交(相互互斥),此时的效果图并不理想:如下

    在这里插入图片描述

    可以看出曲线中间有较大的空余,为了解决这个问题,不断地调整点集的区间(适当扩大),使每个区间的点集相互是有部分交集的,例如点 1-76 是第一部分,点 67-96 是第二部分,此时点 67-76 不但是左边部分的点来线性拟合,又是左下部分的点来二次拟合,效果会好很多,如下:

    在这里插入图片描述

    • 拟合结果:

    左边(第 1-76 个点):y=0.0983x-381.095

    左下(第 67-96 个点):y=0.0055

    在这里插入图片描述

    +4.5245x+299.2073
    
    • 1

    下边(第 84-215 个点):y=0.0208x-600.9287

    右边(第 216-275 个点):y=-0.0721x+383.0611

    右上(第 269-298 个点):y=-0.0056
    在这里插入图片描述

    +4.0934x-901.1372
    
    • 1

    上边(第 296-382 个点):y=0.011x-181.6471

    函数插值

    线性插值

    整体思路

    首先将标记为 1 的点单独储存在 v1 矩阵中,每一行为点的时间、横纵坐标,然后对于每一个标记为 0 的缺失点 Q,找到其最近的前后存在的点 AB,用 A 和 B 进行线性插值,该缺失点在线性插值直线 AB 上,且由 Q 的时间已知,AB 的到达时间也已知。不妨假设时间的比例(tQ-tA)/(tB-tA)和横坐标比例(xQ-xA)/(xB-xA)相等解出缺失点的横坐标,然后代入插值函数,求得缺失点坐标然后把缺失点存储在 v2 矩阵中,每一行为缺失点信息最后用 plot 把图像描绘出来

    代码实现

    利用 coord 的第二列为横坐标,第三列为纵坐标,第一列为时间将未缺失点存储在 v1 中,缺失点存储在 v2 中,利用假设物体在横坐标的投影匀速移动得到缺失时刻对应横坐标,然后利用插值函数(线性插值)获取纵坐标,利用 plot 函数描绘曲线。插值函数即获取斜率 k 和截距 b 即可

    斜率 k=(y2-y1)/(x2-x1)

    截距 b 为(x1y2-x2y1)/(x1-x2)

    Temp_x,temp_y 用来暂时存储缺失点的横纵坐标,最终存储在 v2 矩阵中

    最终效果

    在这里插入图片描述

    三次样条插值

    整体思路

    • 对于 309 个未缺失的点,存在 308 个区间,每个区间都用三次函数插值
    • 一共需要 4*308 个参数要确定
    • 那么需要 4*408 个方程
    • 其中 309 个是插值函数满足的点的插值条件个内点满足:函数值、导数值、二阶导数值连续
    • 还需要 2 个边界条件,不妨设第一个点和最后一个点处导数是 0(自然边界起始条件)
    • 核心思想就是解这 4408 个方程得到 4408 个系数的结果。
    • 那么 M 为系数矩阵,Y 为方程的结果向量,
    • 系数矩阵填上系数(对应于方程)
    • 然后利用 M\Y 即可获得 X,即 4*408 个待定系数的值,然后描绘出这些插值函数。
    • 同样假设物体在横坐标的投影匀速移动
    • 那么缺失点横坐标可以用时间比例确定,再根据其所在区间,代入对应三次函数获得纵坐标的值

    代码实现

    同样将未缺失点存入 v1 矩阵,M 用来存系数矩阵,Y 用来存结果向量,X 为算出来的插值函数的结果系数的向量

    • 最终效果

    插值函数的效果图:

    在这里插入图片描述

    缺失点的插值效果图

    在这里插入图片描述

    红色为缺失点插值结果,蓝色点为未缺失点,黑色为插值曲线

    多项式插值

    实现思路

    具体实现考虑使用分段二次函数插值,把 309 个存在点,308 个区间分成 154 组,每一个组有两个区间,三个点,相邻组之间会对存在的内点共用。

    例如:x1、x2、x3 为第一组的三个插值点,x3、x4、x5 为第二组的插值点,相邻组对 x3 进行了共用。一共 154*3 个参数需要确定,每个二次函数确定 3 个参数。

    可以列的方程也有 154*3 个,每个区间上都可以用待定系数的方式得到插值条件方程。

    同理,填好 M 矩阵,和 Y 结果向量,运算得到二次函数系数结果向量 X

    代码实现

    用来存已知点

    Vx1 和 vy1 存已知点横纵坐标

    Vx2 和 vy2 存缺失点横纵坐标

    缺失点横坐标用假设物体在横坐标的投影匀速移动来计算

    缺失点纵坐标用插值函数进行计算

    最终效果

    在这里插入图片描述

    插值方法对比

    线性插值:优点是实现非常简单,只需要用原始点进行直线插值即可,缺点是在分段处衔接不够平滑,只能表示总体趋势,在细节上的增加难以有效表现

    三次样条插值:优点是效果好,在分段处的函数值、斜率、凹凸性都非常平滑

    缺点是方程数量比较庞大、复杂,一旦出现缺失点异常,最终结果会受到很大波动!

    分段多项式插值(二次):优点是形式简单,且总体曲线比较平滑,应该说综合了线性插值和三次样条插值的有点,效果较好!

  • 相关阅读:
    【C++】GoogleTest进阶之gMock
    postgres 自定义内置函数
    EasyRecovery适用于Windows和Mac的专业硬盘恢复软件
    Hadoop学习总结
    Spring学习笔记注解式开发(3)
    java与es8实战之五:SpringBoot应用中操作es8(带安全检查:https、账号密码、API Key)
    聊一聊的有限状态机
    Java项目开发-基于Java的宠物领养管理系统(附源码)
    spark伪分布部署
    微信小程序配置
  • 原文地址:https://blog.csdn.net/newlw/article/details/126031797