0、定义

已知函数在区间个互异节点,处的函数值为,若构造函数,满足:

  1. 在每个小区间上是一个不超过三次的多项式
  2. 上连续

则称的三次样条插值函数。

根据定义知道规律为:

已知:

  • n+1个数据点[xi, yi], i = 0, 1, …, n
  • 每一分段都是三次多项式函数曲线
  • 节点达到二阶连续
  • 左右两端点处特性(自然边界,固定边界,非节点边界)

根据定点,求出每段样条曲线方程中的系数,即可得到每段曲线的具体表达式。

一、推导

插值和连续性:

其中.

微分连续性:

其中.

样条曲线的微分式:

将步长  带入样条曲线的条件:

  1.     
  2.                                                                                                      

  3. .
  • 设  ,那么  可改写为 
  • 将  带入 ,得 
  • 将  代入,得

至此,可以得到一个关于m为未知数的线性方程组,通过解这个方程组,确定其系数。

二、边界条件建立方程

边界条件有三种:自由边界条件、固定边界条件、非节点边界条件。

1、自由边界条件

两端没有任何限制,即。求解方程为:

2、固定边界条件

数据两端节点的微分值是已知的,令分别为A 和B。则有

则有

3、非节点边界条件

指定样条曲线的三次微分匹配,

由  . 

则有

三、代码实现

1、matlab

在matlab中,spline函数可以实现三次样条插值。例:

clc;
clear;
//x = [ 0, 3, 5, 7, 9, 11, 12, 13, 14, 15 ];
//y = [0,1.2,1.7,2.0,2.1,2.0,1.8,1.2,1.0,1.6 ];
//x_ = 0:.1:15;
x = -pi:pi;
y = sin(x);
x_ = -pi:.1:pi;
p1 = spline(x,y,x_); % 分段三次样条插值
plot(x,y,'ko',x_,p1,'b.')
legend('插值节点','分段三次样条插值','location','southeast')

可以看出,由点组成得曲线比较平滑。

2、C++

程序我有用到矩阵库Armadillo,没有安装的请点这个安装教程链接

#include<iostream>
#include<armadillo>
#include<vector>
using namespace std;
using namespace arma;int main()
{double x[] = { 0, 3, 5, 7, 9, 11, 12, 13, 14, 15 };double y[] = { 0,1.2,1.7,2.0,2.1,2.0,1.8,1.2,1.0,1.6 };int size = sizeof(x) / sizeof(double);const double min = x[0];const double max = x[size - 1];vector<double> xx, yy;              //插值点与计算的函数值for (double i = x[0]; i <= x[size - 1]; i = i + 0.1) {xx.push_back(i);}int size_xx = xx.size();vector<double> dx, dy;           //差分,即步长for (int i = 0; i < size - 1; i++) {double temp_dx = x[i + 1] - x[i];dx.push_back(temp_dx);double temp_dy = y[i + 1] - y[i];dy.push_back(temp_dy);}mat H, Y, M;           // H * M = YH.zeros(size, size);Y.zeros(size,1);//M.zeros(1, size);H(0, 0) = 1;H(size - 1, size - 1) = 1;for (int i = 1; i < size - 1; i++) {H(i, i - 1) = dx[i - 1];H(i, i) = 2 * (dx[i - 1] + dx[i]);H(i, i + 1) = dx[i];Y(i) = 3 * (dy[i] / dx[i] - dy[i - 1] / dx[i - 1]);}M = solve(H,Y);vector<double> ai, bi, ci, di;         //系数for (int i = 0; i < size - 1; i++) {ai.push_back(y[i]);di.push_back((M(i + 1) - M(i)) / (3 * dx[i]));bi.push_back(dy[i] / dx[i] - dx[i] * (2 * M(i) + M(i + 1)) / 3);ci.push_back(M(i));}vector<int> x_, xx_;for (int i = 0; i < size; i++) {int temp = x[i] / 0.1;x_.push_back(temp);}for (int i = 0; i < size_xx; i++) {int temp = xx[i] / 0.1;xx_.push_back(temp);}for (int i = 0; i < size_xx; i++) {int k = 0;for (int j = 0; j < size - 1; j++) {if (xx_[i] >= x_[j] && xx_[i] < x_[j + 1]) {k = j;break;}else if (xx[i] == x[size - 1]) {k = size - 1;}}//yy(i) = y[i] + bi(k) * (xx[i] - x[k]) + 1 / 2.0 * M(i) * pow((xx[i] - x[k]) , 2) + di(k) * pow((xx[i] - x[k]),3);double temp = ai[k] + bi[k] * (xx[i] - x[k]) + M(k) * pow((xx[i] - x[k]), 2) + di[k] * pow((xx[i] - x[k]), 3);yy.push_back(temp);}std::ofstream output;output.open("Spline.txt");for (unsigned i = 0; i < size_xx; i++) {output << xx[i] << '\t' << yy[i] << std::endl;}output.close();cout << "Hello World !" << endl;
}

结果用matlab显示为:

四、小结

1、算法流程

  1. 计算步长  
  2. 根据边界条件填充矩阵 
  3. 解矩阵方程 
  4. 由  得到样条插值函数的系数

2、难点

三次样条插值的整体推导,以及 H 矩阵的填充。

数值计算笔记之插值(四)三次样条插值相关推荐

  1. 清风数学建模学习笔记——应用matlab实现分段三次埃尔米特(Hermite)插值与三次样条插值

    插值算法   数模比赛中,常常需要根据已知的函数点进行数据.模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,模拟产生一些新的但又比较靠谱的值来满足需求 ...

  2. 【matlab】三次埃尔米特插值与三次样条插值的实际应用代码

    要求:完成下列这些数据的插值,并将结果保存到一个EXCEL表格中.要求至少选取两种插值方法,并对1号池中的这些指标做出插值后图像(显示在同一个图像中) Z.mat load Z.mat x=Z(1,: ...

  3. 【插值】牛顿插值、拉格朗日插值、三次样条插值的Python代码实现

    插值简介 插值即根据有限的离散点绘制出穿过所有样本点的曲线,从直观上想象似乎画一条穿过n个特定点的曲线有无数种画法,但从数学意义上来说我们希望画出的曲线能够尽量平滑,震荡幅度尽量小能够在非样本点上符合 ...

  4. python 插值_三次样条插值在Python中的实现

    什么是三次样条插值 三次样条插值(Cubic Spline Interpolation)简称Spline插值,是通过一系列形值点的一条光滑曲线,数学上通过求解三弯矩方程组得出曲线函数组的过程. 实际计 ...

  5. 数学建模十大算法02—插值与拟合(拉格朗日插值、三次样条插值、线性最小二乘法……)

    文章目录 引入 一.插值 1.1 分段线性插值 1.2 牛顿插值法 1.3 拉格朗日插值多项式 1.4 样条插值 1.4.1 三次样条插值 1.5 二维插值 1.5.1 插值节点为网格节点 1.5.2 ...

  6. 5.3 matlab数据插值(线性插值、最近点插值、埃尔米特插值、三次样条插值)

    ①数据插值可以根据有限个点的取值状况,合理估算出附近其他点的取值,从而节约大量的实验和测试资源,节省大量的人力.物力和财力. ②数据插值能够根据已知数据推算未知数据,这使得人们解决问题的能力得到了拓展 ...

  7. 数学建模——插值算法(分段三次埃尔米特插值、三次样条插值)思想及Matlab实现

    数模比赛中,常常需要根据已知的函数点进行数据.模型的处理和 分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,"模拟产生"一些新的但又比较靠谱的 ...

  8. python三次样条插值拟合的树行线_数学建模笔记——插值拟合模型(一)

    啊好像距离上次写作又过了七天,啊好像我之前计划的一周两三篇,啊辣鸡小说毁我青春,啊我是一只可怜的鸽子. 不管怎样,我又回来了,并坚定地更新着hhh.再过两三天就是我们学校数学建模选拔,再过八九天就是期 ...

  9. Matlab数值分析实例:三次样条插值

    Matlab数值分析实例:三次样条插值 任务要求 分析 代码实现 总结 任务要求 湖水在夏天会出现分层现象,接近湖面温度较高,越往下温度变低.这种上热下冷的现象影响了水的对流和混合过程,使得下层水域缺 ...

  10. 数学建模准备 插值(拉格朗日多项式插值,牛顿多项式插值,分段线性插值,分段三次样条插值,分段三次Hermite插值)

    文章目录 摘要(必看) 0 基础概念 什么是插值 插值用途 什么是拟合 插值和拟合的相同点 插值和拟合的不同点 1 常用的基本插值方法 1.1 多项式插值法 1.1.1 拉格朗日多项式插值法 多项式插 ...

最新文章

  1. 全部开课!加入学习群一起进步(附点云、多传感器融合、SLAM、三维重建课程)...
  2. easyUI创建人员树
  3. android 垂直 SeekBar 源代码(VerticalSeekBar)[转]
  4. ubuntu下docker环境、php环境以及laravel的安装
  5. 算法题目——使用最小花费爬楼梯(动态规划)
  6. gluon_带有Gluon Ignite和Dagger的JavaFX中的依赖注入
  7. css居中最佳方案,CSS 水平、垂直居中的5种最佳方案
  8. [转载] NumPy Beginner‘s Guide 2e 带注释源码 七、NumPy 特殊例程
  9. 一文轻松搞懂-条件随机场CRF
  10. 通俗理解数字签名,数字证书和https
  11. 肌酸怎么吃效果最好?为什么使用肌酸没有效果!
  12. 北斗导航 | BDS RTK高精度定位算法在形变检测中的应用(算法原理讲解)
  13. abb机器人伺服电机报闸是什么_ABB机器人伺服电机维修常见4大故障处理
  14. 如何在Mac计算机上添加删除打印机和扫描仪,以及高质量扫描文档
  15. ai语音系统智能AI机器人AI源码营销机器人电销机器人智能电话机器人拨号机器人语音机器人空号识别科大识别阿里识别语音识别语音翻译FreeSWITCH呼叫中心中间ipbxIPBX
  16. 抖音只能上下滑动吗_抖音的上下滑实现—iOS
  17. 假设检验、显著性水平α、P值、置信区间
  18. 传微信要开直播业务:主流社交工具全面杀入直播战场
  19. Tableau常用可视化图形介绍及其适用场景
  20. 获取当年的法定节假日和周末_通过可配置的周末和节假日添加工作日

热门文章

  1. Java字符串转Json对象
  2. HCNA安全学习笔记
  3. scrapy模拟点击
  4. 力扣算法——78_子集
  5. TBB基础之parallel_for
  6. MySQL - 用户管理
  7. React 动效 Framer motion,给你的页面添加一点动感
  8. IDEA-集成VisualVM插件,启动Java VisualVM
  9. 深度学习笔记之一—— 生翻 deeplearning(2015,Yann LeCun, Yoshua Bengio Geoffrey Hinton)
  10. 零知识证明学习(三)—— 非交互式零知识证明(zkSNARKs)