[数值分析拟合]Matlab三次样条插值拟合数据

2023-11-06

           三次样条插值是一种运用极为广泛的工程插值算法,本文章编写的函数默认使用端点处的导数值代替给定的两端点的导数值使用三转角构造法进行插值(该函数也可传入端点导数数值进行分析),对数据进行方便而迅速的拟合(但是目前没有三弯矩构造法)

        一、三次样条插值的基本原理:

        首先,三次样条插值将曲线的每一段通过三次函数进行拟合。曲线会通过每一个数据点,并且在每个数据点处都有二阶连续条件(节点处的一阶导数值和二阶导数值均相同),当已知n+1个数据点时,可以设前n个节点的三次函数分别为S_i(x)=A_i+B_i(x-x_{i})+C_i(x-x_i)^2+D_i(x-x_i)^3  (i=1,2,...n)其中有4n个未知数,需要建立4n个方程来解决(下面是自己整理的总体思路,因为也是第一次写比较多的公式,如有错误和不妥之处请在评论区指正)

1) 首先有A_i=S_i(x)  (i=1,2,...n),(通过值条件)可建立n个方程,即A_i=y_i

2) 由S_{i}(x_{i+1})=S_{i+1}(x_{i+1}) (i=1,2,...n) (连续性条件)建立n个方程

3) 使用内节点处导数连续条件,即S'_i(x_{i+1})=S'_{i+1}(x_{i+1})(i=1,2,...n-1),由求导可得S'_i(x_i)=B_i+2C_i(x_i-x)+3D_i(x_i-x)^2

h_i=x_{i+1}-x_{i},

则有S'_i(x_i)=B_i

故可利用上式得出

B_i+2C_ih_i+3D_ih_i^2-B_{i+1}=0,

这样就建立了n-1个节点处导数连续的方程

3)同样地,解出二阶导数,并使S''_i(x_{i+1})=S''_{i+1}(x_{i+1})得到2C_i+6h_i*D_i-2C_{i+1}=0

其中设m_i=2C_i=S''_{i}(x)为该点处的二阶导数值,可建立n-1个相应的方程组

于是,这样对一条插值曲线的4n个未知数就产生了4n-2个约束,另外两个约束由边界条件确定

通过边界条件等4n个方程将Ai,Bi,Ci,Di用mi表示,建立方程组解出m,从而确定共4n个未知数的值,构造出每一段的三次曲线方程

        二、简介三转角构造法和三弯矩构造法

1)   三转角构造法:采用两端的导数值作为边界条件建立2个补充方程

2)三弯矩构造法:给出两端点的二阶导数值,作为补充的2个边界条件

其余的还有自然边界法等方法,这个方法会在下方的文章链接里面有详细解释

        三、详细的推导过程可以参考下面这篇文章:

****************************************

三次样条插值的原理和C语言实现

****************************************

另外这篇文章的一部分内容也是有一些比较难以推导的部分和误区,在这里补充如下:

在上述文章的【端点条件】中(端点条件即为使用三转角构造法),有推导过程

他的第二式b0=A是这样推导的:

1)利用前面的式子b.   b_i=\frac{y_{i+1}-y_i}{h_i}-\frac{h_i}{2}m_i-\frac{h_i}{6}(m_{i+1}-m_i)    (1)

可获得b0为上式值

2)所给出的边界条件中,这一张里面下标应当为bn=B(是最后一个节点的),通过这个推导下方的式子hn-1.....这里要用到导数连续条件b_{i}=b_{i-1}+2c_{i-1}h_{i-1}+3d_{i-1}h_{i-1}^2     (2)

(有c_i=\frac{m_{i}}{2},d_i=\frac{m_{i+1}-m_i}{6h_i}

 将(1)式中的i换成n-1代入(2)式(i=n)中,即可得到图中的第二个式子

        四、代码部分

下面附上完整的程序:

1)首先要在该函数的文件夹下创建一个函数len.m以便于后期取长度时调用

%返回一维数组长度(行数或列数其中大的一个,必须是一位数组)
function [length]=len(A)

    s=size(A);
    if s(2)==1
        length=s(1); %取行
    end
    if s(1)==1
        length=s(2);
    end
    if s(1)~=1 && s(2)~=1
        disp('必须是单行向量或单列向量')
        return
    end
            
end

2)Spline_3.m   (三次样条插值主函数)

%三次样条插值的matlab实现
%本例为三转角构造法,需要给出边界处的导数值
%本函数默认使用边界两点的斜率拟合最后一点的导数值
%一般默认调用方法为:[x2,y2] = Spline_3(x,y) ,  若直接使用 Spline_3(x,y)则绘图
%指定端点导数值调用方法: [x2,y2] = Spline_3(x,y,'dx',[1,-1])
function [x2,y2]=Spline_3(x,y,String,dx)  
%传入 x y 矩阵和初始参数,(默认使用三转角构造,若传入三个参数,则指定两段的导数值,
%四个参数指定两端的二阶导数值(此时第三个参数无效)(目前没有实现三弯矩构造)
n=len(x);
if n<=3
    disp('数组长度过短!')
    return
end
if n~=len(y)
    disp('两个数组长度必须相同!')
    return
end

if nargin==2
    dx=zeros(1,2);
    dx(1)=(y(2)-y(1))/(x(2)-x(1));
    dx(2)=(y(n)-y(n-1))/(x(n)-x(n-1));
    %指定末端点的导数值
else
    if nargin ==4
        if String == 'dx'
            %什么也不做
        end
    end
end
%========预分配内存空间===============================
h=zeros(n-1,1);  %步长
delta_y=zeros(n-1,1);   %增量
%解对应的系数
A=zeros(n-1,1);
B=zeros(n-1,1);
C=zeros(n-1,1);
D=zeros(n-1,1);
%G和f为需要解的n*n矩阵及其数值
G=zeros(n,n);  %是 n*n 矩阵,右端有n个二阶导数值
f=zeros(n,1);  % f是右边的矩阵
%=========================

for i=1:1:n-1
    h(i)=x(i+1)-x(i);
    delta_y(i)=y(i+1)-y(i); %每次y的增量
end
%   A是y(i)而B是导数

%if nargin==2     %这个留在后续可能要加三弯矩时使用
%采用三转角构造方式
    G(1,1)=2*h(1);
    G(1,2)=h(1);
    %n个数据共有n个导数值,这里取第n个来列方程(b(n)是倒数第一个)
    %参考资料的b(n-1)有误,应当是b(n)
    G(n,n-1)=h(n-1); 
    G(n,n)=2*h(n-1);
    a=dx(1);
    b=dx(2);
%=============构造矩阵=====================
    %填写G矩阵中其余的参数()
    for i=2:1:n-1  %从2行到n-1行的数据
        G(i,i-1)=h(i-1);
        G(i,i)=2*(h(i)+h(i-1));
        G(i,i+1)=h(i);
    end
    
    f(1)=6*( delta_y(1)/h(1) - a  ) ;    
    %在默认情况下,采用最前方的斜率代替导数值时,f(1)必然为0
    f(n)=6*(  b-delta_y(n-1)/h(n-1)  );
    %同理默认情况下  f(n-1)=0
    for i = 2:1:n-1
        f(i)=6*(delta_y(i)/h(i)-delta_y(i-1)/h(i));
    end
    %m为二阶导数值
    m=G\f;   
    %是G\f(实际上是inv(G)*f  )解出m 的值(这个看错检查我好长时间QAQ)
    m=m';
    
%=====================================================

    %计算每段样条插值的系数:
    for i=1:1:n-1
        A(i)=y(i);
        B(i)=  (y(i+1)-y(i))/h(i) -h(i)*m(i)/2 - h(i)/6*(m(i+1)-m(i));
        C(i)=m(i)/2;
        D(i)=(m(i+1)-m(i))/(6*h(i));
    end

    
%*******注意:从这里设置插值后绘制函数的精度*****可以有不同的要求,
%这里设为0.001
    x_2=min(x):0.001:max(x);  %如果用x2会有问题
    x_2=x_2';   %行向量
    %绘制插值曲线
    y2=zeros(len(x_2),1);
    j=1;
    hold on
        
    for i=1:1:len(x_2)
        while x_2(i)>x(j+1)  %变换插值函数
            j=j+1;
        end
        y2(i)=A(j)   +B(j)*(x_2(i)-x(j))  +C(j)*(x_2(i)-x(j))^2  +  D(j)*(x_2(i)-x(j))^3;
    end

%end    %三转角构造方式
x2=x_2;

if nargout==0
    plot(x2,y2)
end

end

用法示例1:三次样条插值cos

%这个是一般的最简便调用格式

t=0:1:10;
y=cos(t);
Spline_3(t,y)  %绘制三次样条插值曲线

%下面是可以返回需要的t2和y2值

t=0:1:10;
y=cos(t);
[t2,y2]=Spline_3(t,y)
plot(t2,y2)

结果:

 用法2:传入端点处的一阶导数值

t=0:1:10;
y=cos(t);
Spline_3(t,y,'dx',[10,-10]);  %这样可以指定传入首尾端点的导数值,按照首尾的导数去插值

%最后一种就是带返回值,懂的都懂AWA

结果(修改了cosx插值的端点导数):

 (这当然还是满足1,2,等过相应的值)

 五、实际应用

主要用于处理和模拟实验数据是极有效的模拟方式,我会最近发布一篇文章《三次样条插值整理实验数据》来对此做一步应用,有兴趣者可以参考

[matlab实践应用]matlab实现读取xls表格并三次样条插值拟合压杆稳定实验数据

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[数值分析拟合]Matlab三次样条插值拟合数据 的相关文章

  • 比较元胞数组中的字符串

    我试图在单词列表中找到最常见的单词 到目前为止 这是我的代码 uniWords unique lower words for i 1 length words for j 1 length uniWords if uniWords j lo
  • Matlab 中 interp2 的类似 OpenCV Api

    有没有类似的功能 其工作原理与 interp2 x y frame z xd yd linear 0 在 OpenCV 中 功能cv remap 几乎可以满足您的要求 请参阅文档here http docs opencv org modul
  • 将 Android 应用程序与服务器上的 Matlab 应用程序连接

    我正在 Android 上开发一个应用程序 它将获取图像输入 并将该输入传递到安装 MATLAB 应用程序的服务器 MATLAB 应用程序将计算结果并将其返回到该 Android 应用程序 我想知道我可以使用哪个服务器 如何将 MATLAB
  • Microsoft Visual C++ 2008 和 R2007b 的 Mex 类型

    我想对 vs2008 和 matlab2007b 使用 mex 类型 我尝试了下面的代码 include
  • 使用 java 执行 Matlab 函数

    我正在编写一个应用程序 它使用 matlab 进行图像处理 然后使用 Java 接口显示结果 由于某些原因 我必须同时使用 Java 和 Matlab 如何在java中使用matlab函数 如何创建和访问界面 MATLAB控制 http m
  • opencv中矩阵的超快中值(与matlab一样快)

    我正在 openCV 中编写一些代码 想要找到一个非常大的矩阵数组 单通道灰度 浮点数 的中值 我尝试了几种方法 例如对数组进行排序 使用 std sort 和选择中间条目 但与 matlab 中的中值函数相比 它非常慢 准确地说 在 ma
  • 将组合字符串和数字输入的元胞数组写入文本文件

    考虑以下 DateTime 2007 01 01 00 00 2007 02 01 00 00 2007 03 01 00 00 Headers Datetime Data Dat 100 200 300 Data DateTime num
  • MATLAB:比较两个不同长度的数组

    我有两个长度不同的数组 由于采样率不同 需要比较 我想对较大的数组进行下采样以匹配较小的数组的长度 但是该因子不是整数而是小数 举个例子 a 1 1 375 1 75 2 125 2 5 2 875 3 25 b 1 2 3 有什么方法可以
  • 傅里叶变换定理 matlab

    我目前正在尝试理解二维傅里叶位移定理 根据我到目前为止所了解到的情况 图像空间中的平移会导致相位差异 但不会导致频率空间中的幅度差异 我试图用一个小例子来演示这一点 但它只适用于行的移位 而不适用于列的移位 这是一个小演示 我只在这里显示幅
  • 为什么matlab的mldivide比dgels好这么多?

    Solve Ax b 真正的双 A是超定的 Mx2 其中 M gt gt 2 b是MX1 我运行了大量的数据mldivide 并且结果非常好 我用 MKL 写了一个 mex 例程LAPACKE dgels但它远没有那么好 结果有大量噪音 并
  • 优化 MATLAB 代码(嵌套 for 循环计算相似度矩阵)

    我正在 MATLAB 中基于欧几里德距离计算相似度矩阵 我的代码如下 for i 1 N M N is the size of the matrix x for whose elements I am computing similarit
  • 如何在Matlab中将世界坐标转换为像素索引

    我有 512x512x313 体积的 dicom 图像 并且我有一个以世界坐标表示的点 57 7475 63 4184 83 1515 我如何在 Matlab 中获得该世界坐标的相应像素坐标 我不想戳破你的幻想 但你所要求的是不可能的 我能
  • 为什么 MATLAB 本机函数 cov(协方差矩阵计算)使用与我预期不同的除数?

    给定一个 M 维和 N 个样本的数据矩阵数据 例如 data randn N M 我可以计算协方差矩阵 data mu data ones N 1 mean data cov matrix data mu data mu N 如果我使用原生
  • 非模态 questdlg.m 提示

    我的代码绘制了一个图 然后提示用户是否想使用不同的参数绘制另一个图 问题是 当 questdlg m 打开时 用户无法查看绘图的详细信息 这是代码 while strcmp Cont Yes 1 Some code modifying da
  • 从 Java 运行 MATLAB 函数

    我在 MATLAB 中有一个 m 文件 我想从 Java 调用该文件 并以字符串或 Java 中的任何形式获取解决方案 这听起来很简单 但由于某种原因我无法让它发挥作用 我试过这个 matlab nosplash wait nodeskto
  • 从 imread 返回的 ndims

    我正在从文件夹中选取图像 尺寸为128 128 为此 我使用以下代码行 FileName PathName uigetfile jpg Select the Cover Image file fullfile PathName FileNa
  • 使用 R2010b 中的符号工具箱来求解和/或 linsolve

    我前几天问了一个问题here https stackoverflow com questions 20317038 matlab linear congruence solver that supports a non prime modu
  • 归一化互相关的基础知识

    我正在尝试使用范数校正2 归一化互相关 http en wikipedia org wiki Cross correlation Normalized cross correlation 来自 MATLAB 用于计算发育中胚胎中移动形状的速
  • getappdata 在 MATLAB 中返回空矩阵

    我有一段代码 我在其中使用setappdata然后我使用以下方式调用数据getappdata即使它不为空 它也会返回一个空矩阵 我的一段简化代码如下 function edit1 Callback hObject eventdata han
  • 在 Matlab 的命令窗口中获取旧式帮助

    问题的简短版本 在最新版本的 Matlab 中 我在 Windows 上的 R2014b 和 R2015a 中看到过 当您键入help foo你得到一个简要描述 简介函数及其签名 例如 输入help bsxfun产生类似这样的东西 只有更好

随机推荐

  • Linux常用命令_文件处理命令:su root

    文章目录 1 命令格式与目录处理命令ls 1 1 命令格式 1 2 目录处理命令 ls 2 目录处理命令 2 1 目录处理命令 mkdir 2 2 目录处理命令 cd 2 3 目录处理命令 pwd 2 4 目录处理命令 rmdir 2 5
  • 使用arcgis修改行政区划图边界

    打开ArcMap 我的是10 8版本的 1 添加行政区划图数据 文件 添加数据 添加数据 弹出添加数据框 点击红色框中的按钮 连接到数据所在文件夹 选择要处理的数据 添加 不便放入整体规划图 放大后选取部分作为示例 本次处理目的是把红色框中
  • 3d散列点云的曲率的求法

    1 取某个区域内的n个最近邻点根据局部抛物面拟合公式 z x y Ax 2 By 2 Cxy Dx Ey F 用最小二乘法可求出上面的各个系数 即可求得空间曲面函数的系数 2 根据公式 Km A 1 E 2 B 1 D 2 CDE 1 D
  • 合宙Air105

    基础资料 基于Air105开发板 Air105 LuatOS 文档 上手 开发上手 LuatOS 文档 探讨重点 对官方Socket网络接口demo中DTU连接示例 dtu demo lua 进行复现及分析 进行用阻塞方式做串口透传DTU内
  • 数据资源丨原始数据哪里找?这些网站要用好!(建议收藏)

    资料搜集是个相当繁琐与累的工作 也是投资入门的基本 良好的信息资料搜集能力有利于我们快速了解投资主体的基本情况 为后续的调研及一手资料的获得打下较好的基础 目录 一 搜索引擎 重点掌握 1 搜索关键字的选择 2 搜索技巧 3 搜索引擎推荐
  • pptp流量分析之搭建pptp测试服务器

    1 前言 最近研究常见vpn流量协议 需要产出检测规则对此类流量进行检测 遂需要搭建测试环境抓取测试流量 简单记录一下 2 环境准备 1 ubuntu22 04 服务器 2 win11 客户机 3 安装及配置 3 1 ubuntu服务器安装
  • 高通平台USB 2.0和USB 3.0接口充电器识别原理

    1 BC 1 2 1 1 充电器类型探测 1 DCD DP上有150mV 10uA x 15K欧姆下拉电阻 的电压 DM上电压为0 2 Primary Det DP发起检测DM DP上加载0 6V电压 DM上电压为0 充电器类型是SDP D
  • Pikachu漏洞靶场的简介、下载与安装

    文章目录 简介 下载 安装 简介 pikachu是一个漏洞练习平台 其中包含了常见的web安全漏洞 Burt Force 暴力 漏洞 XSS 跨站脚本漏洞 CSRF 跨站请求伪造 SQL Inject SQL注入漏洞 RCE 远程命令 代码
  • [WSL-1-Ubuntu]使用oh-my-zsh美化你的WSL(附脚本)

    在腾讯云买的那个1c2g的服务器 想用mycat搭建一个mysql cluser 用docker部署了一主一从内存就没了一半 可一主一从没啥作用 起码也得2主2从吧 而且还有HA呢 但内存和钱包不给力 所以就想到WSL这个方案 在开wsl这
  • 发现1个拿来即用的Python高级脚本,收藏!

    今天 给大家推荐一些用Python爬虫做私活的渠道 先给各位还不熟悉Python爬虫的朋友介绍一下 可以短时间获得大量资料 可以进一步数据分析 当然也可以获得收益 学会Python爬虫以后 还可以通过各种渠道 网站接单 接单群 私人介绍 接
  • 今日头条信息流广告怎么做?(今日头条信息流广告费用解析)

    国内的各种渠道千千万 主流的广告平台不算多也不算少 而今日头条与其它平台最大区别在于 个性化推荐和智能分发 可以简单理解为 今日头条上投放的广告 是通过 机器人代码 过滤再分发出去的 因此了解 机器人 在分发过程中遵循的规则 随着网络的发展
  • pytorch: RuntimeError: DataLoader worker (pid(s) 27292) exited unexpectedly

    厉害了 用win10特有的bug 搞半天 就是把pytorch下dataloader的其中一个num workers参数注释掉 可能是win10只有一个thread的原因 torch utils data DataLoader self d
  • 同一套服务如何应对不同终端的需求——服务适配

    经过前几个章节的实践 会员已可以绑定手机号 更新个人信息 绑定个人车辆信息 开通月卡 签到等功能 下面从客户端查看自己的数据入手 再聊聊服务调用的问题 简单处理 我们已经将用户数据进行垂直拆分 分布在不同数据库中 当客户端数据展现时 就需要
  • 参加2012中国数据库技术大会大会有感

    上周末参加了 DTCC Database Technology Conference China 2012中国数据库技术大会 见到了很多熟人 开了3天 好多议题 我去了后两天 第一天是周五 没好意思向公司请假 干货还是很多的 比某些扯淡的行
  • 代理服务器(Proxy)

    目录 1 什么是代理服务器 2 代理服务器的作用 3 代理服务器的工作流程 4 安装代理服务器软件及配置文件解析 squid 5 正向代理 6 修改数据存放位置 7 设置磁盘使用阈值 代理 两字顾名思义就是以代理人的身份去帮助其他人取得所需
  • C++数组:发工资

    题目描述 财务处要给公司的n位员工发工资了 请你帮助计算最少要多少张人民币才能给每位员工发工资而不必找零呢 已知人民币的面额为100元 50元 10元 5元 2元和1元这6种 输入格式 第一个值为正整数n 后面接着n个正整数表示n位员工的工
  • Python天文数据处理——Astropy

    前言 Astropy是一个用于天文数据处理的Python包 它包含了许多常用的天文学函数和工具 可以用于处理 分析和可视化各种类型的天文数据 Astropy最新版本是v4 3 官网地址为https www astropy org Astro
  • Django计算机毕业设计个性化大学生图书推荐系统(程序+LW)Python

    该项目含有源码 文档 程序 数据库 配套开发软件 软件安装教程 项目运行 环境配置 Pychram社区版 python3 7 7 Mysql5 7 HBuilderX list pip Navicat11 Django nodejs 项目技
  • Linux进行AES加密每次结果都不一致并且解密失败报错

    1 现象 windows操作系统下进行 123456 的AES加密 encrypted message is below QLNYZyjRnKF zxAjzDt lw decrypted message is below 123456 阿里
  • [数值分析拟合]Matlab三次样条插值拟合数据

    三次样条插值是一种运用极为广泛的工程插值算法 本文章编写的函数默认使用端点处的导数值代替给定的两端点的导数值使用三转角构造法进行插值 该函数也可传入端点导数数值进行分析 对数据进行方便而迅速的拟合 但是目前没有三弯矩构造法 一 三次样条插值