基于python的三次样条插值原理及代码

news2024/12/28 17:50:15

1 三次样条插值

1.1 三次样条插值的基本概念

        三次样条插值是通过求解三弯矩方程组(即三次样条方程组的特殊形式)来得出曲线函数组的过程。在实际计算中,还需要引入边界条件来完成计算。样条插值的名称来源于早期工程师制图时使用的细长木条(样条),这些木条被固定在样点上,然后自由弯曲以绘制出曲线。

1.2 三次样条插值的条件

        假设在区间[a, b]上有n+1个样本点,即[a, b]区间被划分成n个小区间[(x_{0},x_{1}),(x_{1}, x_{2}), ...,(x_{n-1}, x_{n})],其中x_{0}=a, x_{n}=b。三次样条插值需要满足以下条件:

  1. 在每个分段区间[x_{i},x_{i+1}]上,插值函数S(x) = S_{i}(x)都是一个三次多项式
  2. 满足插值条件,即S(x_i) = y_i \quad (i = 0, 1, ..., n)
  3. 曲线光滑,即S(x)、S'(x)、S''(x)连续

1.3 三次样条插值的公式推导

1. 3.1 三次样条函数的形式

        在每个小区间[x_{i},x_{i+1}]上,三次样条函数S_i(x)可以表示为:

S_i(x) = a_i + b_i(x - x_i) + c_i(x - x_i)2 + d_i(x - x_i)3

        其中,a_i ,b_i,c_i,d_i是待求的系数。

1.3.2 插值条件

        由于S(x_{i}) = y_{i},我们可以得到n+1个方程:

 S_i(x_i) = a_i = y_i \quad (i = 0, 1, ..., n) 

1.3.3 连续性条件

        除了插值条件外,还需要保证曲线在样本点处的一阶导数和二阶导数连续。即:

  • 一阶导数连续:对于任意i(0 < i < n),有

    S_i'(x_{i+1}) = S_{i+1}'(x_{i+1})

  • 二阶导数连续:对于任意i(0 < i < n),有

    S_i''(x_{i+1}) = S_{i+1}''(x_{i+1})

1.3.4 求解未知数

        每个小区间内有4个未知数(a_i ,b_i,c_i,d_i),共有n个小区间,所以一共有4n个未知数。根据插值条件、一阶导数连续和二阶导数连续条件,我们可以列出以下方程组:

  • 插值条件:提供n+1个方程(其中ai=yi已知)。
  • 一阶导数连续:提供n-1个方程(两个端点不参与此条件)。
  • 二阶导数连续:提供n-1个方程(同样,两个端点不参与此条件)。

        这样,我们总共有4n-2个方程,但还需要两个额外的方程来求解所有未知数。这两个额外的方程由边界条件给出。

1.3.5 边界条件

        常用的边界条件有三种:

  • 自然边界(Natural Spline):指定端点二阶导数为0,即

    S''(x_0) = 0 = S''(x_n)

  • 固定边界(Clamped Spline):指定端点一阶导数,即

    S'(x_0) = A, \quad S'(x_n) = B 

  • 非扭结边界(Not-a-Knot Spline):使两端点的三阶导与这两端点的邻近点的三阶导相等,即

    S'''(x_0) = S'''(x_1), \quad S'''(x_{n-1}) = S'''(x_n) 

1.3.6 求解过程

        以自然边界条件为例,即 S''(x_0) = 0, \quad S''(x_n) = 0,我们需要通过这些条件来求解每个小区间上的二阶导数 m_{i}=S''(x_i)(通常称为样条曲线的“弯矩”或“斜率”)。

        步骤一:设置方程

        在每个小区间[x_{i},x_{i+1}]上,三次样条S_i(x)的二阶导数 S''(x_n) 是一个常数 m_{i}。因此,三次样条S_i(x) 可以表示为:

S_i(x) = \frac{m_i}{6}(x_{i+1} - x)3 + \frac{m_{i+1}}{6}(x - x_i)3 + a_i(x_{i+1} - x) + b_i(x - x_i) + c_i

其中 a_i ,b_i,c_i​ 是需要通过插值条件和其他连续性条件求解的系数。

        步骤二:利用插值条件

        由于 S_i(x_{i}) = y_{i},S_i(x_{i+1}) = y_{i+1},我们可以列出 n+1 个插值方程。但由于 a_{i}=b_{i}由 S_i(x_{i}) = y_{i} 直接得出),我们实际上只需要解出a_{i},b_{i}​(或者更直接地,解出 m_{i})。

        步骤三:利用一阶导数连续性

        在 x=x_{i}+1处,有 S_i{}'(x_{i}) = S_{i+1}{}'(x_{i+1})。对 S_i{}(x_{i}) = S_{i+1}{}(x) 求导并设置相等,我们可以得到一个关于 m_{i}和 m_{i+1}​ 的方程。由于有 n−1 个这样的内部节点,因此我们可以得到 n−1 个这样的方程。

        步骤四:利用二阶导数连续性(自然边界条件)

        在 x=x_{0} 和 x=x_{n} 处,有S''(x_0) = 0, \quad S''(x_n) = 0,即 m_{0}=0 和 m_{n}=0这两个条件提供了额外的两个方程。

        步骤五:解线性方程组

        现在,我们有了 n−1 个一阶导数连续性方程,加上两个自然边界条件方程,共 n+1 个方程,用于求解 n 个未知数 m_{1},m_{2},...m_{n-1}​(注意 m_{0}和 m_{n}​ 已知为0)。这是一个线性方程组,可以通过高斯消元法、LU分解等方法求解。

        步骤六:计算系数 a_i ,b_i,c_i

        一旦我们得到了所有的 mi​,就可以通过插值条件和其他连续性条件回代求解出每个小区间上的 a_i ,b_i,c_i​。具体来说,可以使用以下公式:

  • a_{i}=b_{i}(已知)
  • b_{i},c_{i}可以通过 S_i(x_{i+1}) = y_{i+1}和 S_i{}'(x_{i}) = S_{i+1}{}'(x_{i+1}) 的联立方程求解。

        步骤七:构建完整的三次样条函数

        最后,我们得到了每个小区间上的三次多项式 S_i(x),它们共同构成了完整的三次样条插值函数 S(x)。在任意点 x∈[x_{i},x_{i+1}] 上,S(x) = S_{i}(x)

1.4 总结

        三次样条插值通过求解一系列线性方程组来确定每个小区间上的三次多项式,这些多项式在样本点处满足插值条件,并且具有连续的一阶导数和二阶导数。自然边界条件、固定边界条件或非扭结边界条件等不同的边界条件选择会影响求解过程和最终的插值曲线形状。三次样条插值因其光滑性和易于实现的特性,在数值分析、数据可视化、计算机辅助设计等领域有着广泛的应用。

2 代码

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline

# 定义数据点
x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
y1 = np.array([0, 4, 6, 8, 9, 11, 13, 16, 19, 21, 23, 25, 28, 30, 33, 34])
y2 = np.array([0, 1, 2, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 25, 29, 34])
y3 = np.array([0, 8, 12, 18, 20, 26, 30, 32, 33, 34, 34, 36, 36, 35, 35, 34])

# 创建三次样条插值函数
cs1 = CubicSpline(x, y1)
cs2 = CubicSpline(x, y2)
cs3 = CubicSpline(x, y3)

# 生成插值后的x坐标
x_new = np.linspace(0, 15, 100)

# 计算插值后的y坐标
y_new1 = cs1(x_new)
y_new2 = cs2(x_new)
y_new3 = cs3(x_new)

# 设置颜色选择器和颜色映射
select2 = (0.1, 0.4, 0.5, 0.3, 0.8, 1.0) # 非连续型色组在0-(色组长度-1)之间选择
colors = plt.get_cmap('rainbow')(select2) # 从色组里选择颜色

# 绘制原始数据点和插值曲线
# 调整图表大小和位置
plt.figure(figsize=(10, 5))
plt.plot(x, y1, 'o', color=colors[0], label='ori_y1')
plt.plot(x, y2, 'o', color=colors[2], label='ori_y2')
plt.plot(x, y3, 'o', color=colors[4], label='ori_y3')
plt.plot(x_new, y_new1, '-', color=colors[3], label='y1_interp_curve')
plt.plot(x_new, y_new2, '-', color=colors[1], label='y2_interp_curve')
plt.plot(x_new, y_new3, '-', color=colors[5], label='y3_interp_curve')

# 设置图例和标题
plt.legend()
plt.xticks(np.arange(0, 16, 1))
plt.title('Cubic Spline Interpolation Example')
plt.xlabel('x')
plt.ylabel('y')


# 显示图表
plt.show()

3 插值结果

图3-1 插值结果

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

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

相关文章

【机器学习】--过采样原理及代码详解

过采样&#xff08;Oversampling&#xff09;是一个在多个领域都有应用的技术&#xff0c;其具体含义和应用方法会根据领域的不同而有所差异。以下是对过采样技术的详细解析&#xff0c;主要从机器学习和信号处理两个领域进行阐述。 一、机器学习中的过采样 在机器学习中&…

未来的社交标杆:如何通过AI让Facebook更加智能化?

在当今信息爆炸的时代&#xff0c;社交媒体平台的智能化已成为提高用户体验和互动质量的关键因素。Facebook&#xff0c;作为全球最大的社交平台之一&#xff0c;通过人工智能&#xff08;AI&#xff09;的广泛应用&#xff0c;正不断推进其智能化进程。本文将探讨Facebook如何…

Qt日志库QsLog使用教程

前言 最近项目中需要用到日志库。上一次项目中用到了log4qt库&#xff0c;这个库有个麻烦的点是要配置config文件&#xff0c;所以这次切换到了QsLog。用了后这个库的感受是&#xff0c;比较轻量级&#xff0c;嘎嘎好用&#xff0c;推荐一波。 下载QsLog库 https://github.c…

CSS技巧专栏:一日一例 7 - 纯CSS实现炫光边框按钮特效

CSS技巧专栏&#xff1a;一日一例 7 - 纯CSS实现炫光边框按钮特效 本例效果图 案例分析 相信你可能已经在网络见过类似这样的流光的按钮&#xff0c;在羡慕别人做的按钮这么酷的时候&#xff0c;你有没有扒一下它的源代码的冲动&#xff1f;或者你当时有点冲动&#xff0c;却…

在Oxygen中比较两个目录的差异,用于编写手册两个版本的变更说明

▲ 搜索“大龙谈智能内容”关注公众号▲ 当我们对手册进行改版的时候&#xff0c;我们通常需要编写变更说明&#xff0c;如下图&#xff1a; 改版通常会改动很多文件的很多地方&#xff0c;如何知道哪些地方更改了呢&#xff1f; Oxygen提供了比较两个目录的功能&#xff0c…

载均衡技术全解析:Pulsar 分布式系统的最佳实践

背景 Pulsar 有提供一个查询 Broker 负载的接口&#xff1a; /*** Get load for this broker.** return* throws PulsarAdminException*/ LoadManagerReport getLoadReport() throws PulsarAdminException;public interface LoadManagerReport extends ServiceLookupData { Re…

【devops】ttyd 一个web版本的shell工具 | web版本shell工具 | web shell

一、什么是 TTYD ttyd是在web端一个简单的服务器命令行工具 类似我们在云厂商上直接ssh链接我们的服务器输入指令一样 二、安装ttyd 1、macOS Install with Homebrew: brew install ttydInstall with MacPorts: sudo port install ttyd 2、linux Binary version (recommend…

将达梦数据库的JDBC驱动包 DmJdbcDriver18.jar 安装到本地 Maven 仓库

项目打包报错&#xff1a;Failure to find com.dameng:DmJdbcDriver18:jar:8.1.3.12 in http://maven.aliyun.com/nexus/content/groups/public 解决方式如下&#xff1a; 从 https://eco.dameng.com/download/ 中下载 达梦JDBC 驱动包&#xff0c;如下 JDK 1.8 对应的 JDBC…

镜像与容器

Docker Image (镜像) Docker 镜像概念 Docker iamge 本质上是一个 read-only 只读文件&#xff0c;这个文件包含了文件系统、源码、库文件、依赖、工具等一些运行 application 所必需的文件。 可以把 Docker image 理解成一个模板&#xff0c;可以通过这个模板实例化出来很多…

2024全球和国内最常用的弱密码,有没有你的?

密码管理器NordPass分析了来自公开来源的超过4.3TB 的密码数据&#xff0c;找出了当前为止&#xff08;2024年&#xff09;最常用&#xff08;最脆弱&#xff09;的密码。 这些密码主要有下面这些特征&#xff1a; 简单且常用&#xff0c;万年弱密码&#xff0c;比如123456、a…

Axure中继器入门:打造你的动态原型

前言 中继器 是 Axure 中的一个高级功能&#xff0c;它能够在静态页面上模拟后台数据交互的操作&#xff0c;如增加、删除、修改和查询数据&#xff0c;尽管它不具备真实数据存储能力。 中继器就像是一个临时的数据库&#xff0c;为我们在设计原型时提供动态数据管理的体验&a…

IntelliJ IDEA 使用maven构建项目时一直卡在Compiling 阶段

IntelliJ IDEA 使用maven构建项目时一直卡在Compiling 阶段 1. maven log [DEBUG] incrementalBuildHelper#beforeRebuildExecution [INFO] Compiling 56 source files to D:\code\short-url\target\classes...2. 增加日志级别 通过添加 -X 参数到 Maven 命令中&#xff08;例…

Ubuntu 24.04 LTS 桌面安装MT4或MT5 (MetaTrader)教程

运行脚本即可在 Ubuntu 24.04 LTS Noble Linux 上轻松安装 MetaTrader 5 或 4 应用程序&#xff0c;使用 WineHQ 进行外汇交易。 MetaTrader 4 (MT4) 或 MetaTrader 5 是用于交易外汇对和商品的流行平台。它支持各种外汇经纪商、内置价格分析工具以及通过专家顾问 (EA) 进行自…

曲轴自动平衡机:提升制造精度与效率的利器

在现代制造业中&#xff0c;曲轴作为发动机的核心部件之一&#xff0c;其质量和性能直接影响着整个发动机的运行效果。而曲轴自动平衡机的出现&#xff0c;为曲轴的生产制造带来了显著的优势。 一、高精度平衡校正 曲轴自动平衡机采用先进的传感技术和精密的测量系统&#xff0…

Qt 快速保存配置的方法

Qt 快速保存配置的方法 一、概述二、代码1. QFileHelper.cpp2. QSettingHelper.cpp 三、使用 一、概述 这里分享一下&#xff0c;Qt界面开发时&#xff0c;快速保存界面上一些参数配置的方法。 因为我在做实验的时候&#xff0c;界面上可能涉及到很多参数的配置&#xff0c;我…

FastAPI 学习之路(五十六)将token缓存到redis

在之前的文章中&#xff0c;FastAPI 学习之路&#xff08;二十九&#xff09;使用&#xff08;哈希&#xff09;密码和 JWT Bearer 令牌的 OAuth2&#xff0c;FastAPI 学习之路&#xff08;二十八&#xff09;使用密码和 Bearer 的简单 OAuth2&#xff0c;FastAPI 学习之路&…

【笔记】一起齿轮箱的故障和相应的数学模拟实验

1.齿轮箱故障一例 出处&#xff1a;设备的故障识别 GearBox的频谱图&#xff0c;原作者不知道是从哪里拷贝来的&#xff0c;待会儿确认一下。 齿轮啮合频率GMF等于齿数乘以齿轮转速频率&#xff1a; ★齿轮啮合频率两边有边频&#xff0c;间距为1X&#xff08;这是由冲击响应…

游泳溺水智能监测报警摄像机

当今社会&#xff0c;游泳已经成为人们重要的休闲活动之一。然而&#xff0c;溺水事故时有发生&#xff0c;尤其是在公共泳池或开放水域。为了提高游泳安全&#xff0c;智能监测技术的应用变得尤为重要。本文将探讨一种创新的游泳溺水智能监测报警摄像机系统&#xff0c;旨在有…

git使用以及理解

git练习网站 Learn Git Branching git操作大全Oh Shit, Git!?! git commit git branch name git merge bugFix 合并俩个分支 git rebase main git checkout headgit switch head 会导致HEAD分离 &#xff0c;就是指head->HEAD->c1 相对引用 ------------------- …

PDF文件无法编辑?3步快速移除PDF编辑限制

正常来说,我们通过编辑器打开pdf文件后,就可以进行编辑了&#xff61;如果遇到了打开pdf却不能编辑的情况,那有可能是因为密码或是扫描件的原因&#xff61;小编整理了一些pdf文件无法编辑&#xff0c;以及pdf文件无法编辑时我们要如何处理的方法&#xff61;下面就随小编一起来…