三次样条插值(python完美实现,三种形式都有!)

这篇具有很好参考价值的文章主要介绍了三次样条插值(python完美实现,三种形式都有!)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

三次样条插值法

使用的是公式法迭代,没有用牛顿,我认为更加精准,牛顿只是方便手算误差自然大。

import time
import numpy as np
import sympy
from sympy import symbols, plot_implicit, Eq
from fractions import Fraction
import matplotlib.pyplot as plt

'''
程序名称:三次样条插值算法程序
程序功能:解决三种三次样条插值问题
程序作者:Yaung
'''


# 四舍五入函数
def round_up(n, m):
    n = str(n)
    if len(n) - n.index(".") - 1 == m + 1:
        n += "01"
    n = float(n)
    return np.round(n, m)


while True:
    # 界面展示
    print("\t**********第一类固定边界(输入:1)")
    print("\t\tS'(x0)=f0'\tS'(xn)=fn'")
    print("\t**********第二类自由边界(输入:2)")
    print("\t\tS''(x0)=f0''\tS''(xn)=fn''")
    print("\t**********第三类非节点边界(输入:3)")
    print("\t\tlimSp(x0+)=limSp(xn-)\tp=0,1,2")
    print("\t**********退出程序(输入:4)")

    # 选项输入
    choice = eval(input('请输入你的选项数字:'))
    if choice == 4:
        exit()  # 退出程序
    # 输入数据的个数
    N = eval(input('请输入数据的个数:'))
    arr = input('请输入xk的所有值(每个值用空格隔开):')
    X = np.array([float(i) for i in arr.split()])
    arr = input('请输入每个xk所对应的函数值f(xk)(每个值用空格隔开):')
    Y = np.array([float(i) for i in arr.split()])
    C = np.array([0, 0])
    if choice != 3:
        arr = input('请输入两个边界条件(每个值用空格隔开):')
        C = np.array([float(i) for i in arr.split()])
    '''
    测试

    第二类
    >>
    2
    4
    1 2 4 5
    1 3 4 2
    0 0
    3
    <<
    4.25

    '''
    # 基础公式
    # 计算h
    H = np.array([])
    for i in range(0, N - 1):
        H = np.r_[H, X[i + 1] - X[i]]
    # 计算U
    U = np.array([np.max])
    for i in range(1, N - 1):
        U = np.r_[U, round_up(H[i - 1] / (H[i] + H[i - 1]), 6)]
    # 计算R
    R = np.array([np.max])
    for i in range(1, N - 1):
        R = np.r_[R, round_up(H[i] / (H[i] + H[i - 1]), 6)]
    # 计算G
    G = np.array([3 * (Y[1] - Y[0]) / H[0] - H[0] / 2 * C[0]])  # 一开始第一个先按照第二类初始化
    for i in range(1, N - 1):
        # print(3*(U[0,i]*(Y[i+1]-Y[i])+R[0,i]*(Y[i]-Y[i-1])))
        G = np.r_[G, 3 * (U[i] * (Y[i + 1] - Y[i]) / H[i] + R[i] * (Y[i] - Y[i - 1]) / H[i - 1])]

    # 边界类型判断
    if choice == 1:
        # 第一类固定边界条件
        # 求解方程组
        A1 = np.array([[]])
        for i in range(1, N - 1):
            Ai = np.array([])
            Ai = np.r_[Ai, [0 for j in range(i - 2)]]
            if i > 1:
                Ai = np.r_[Ai, R[i]]
            Ai = np.r_[Ai, 2]
            if i != N - 2:
                Ai = np.r_[Ai, U[i]]
            Ai = np.r_[Ai, [0 for j in range(N - 2 - Ai.size)]]
            if i == 1:
                A1 = np.c_[A1, [Ai]]
            else:
                A1 = np.r_[A1, [Ai]]

        b1 = np.array([G[1] - R[1] * C[0]])
        b1 = np.r_[b1, [G[i] for i in range(2, N - 2)]]
        b1 = np.r_[b1, G[N - 2] - U[N - 2] * C[1]]
        M = np.array([C[0]])
        M = np.r_[M, np.linalg.solve(A1, b1)]
        M = np.r_[M, C[1]]
    elif choice == 2:
        # 第二类自由边界条件
        # 补充最后一个G
        G = np.r_[G, 3 * (Y[N - 1] - Y[N - 2]) / H[N - 2] + H[N - 2] / 2 * C[1]]
        # 解方程组求M
        A2 = np.array([[2, 1]])
        A2 = np.c_[A2, [[0 for i in range(N - 2)]]]
        for i in range(1, N - 1):
            Ai = np.array([])
            Ai = np.r_[Ai, [0 for j in range(i - 1)]]
            Ai = np.r_[Ai, [R[i], 2, U[i]]]
            Ai = np.r_[Ai, [0 for j in range(N - Ai.size)]]
            A2 = np.r_[A2, [Ai]]
        # A2 = np.r_[A2,[0 for i in range(N-2)]]
        A2 = np.r_[A2, [np.r_[[0 for i in range(N - 2)], [1, 2]]]]

        b2 = np.array([G[i] for i in range(N)])
        M = np.array(np.linalg.solve(A2, b2))
    elif choice == 3:
        # 第三类非节点边界条件9
        # 新增U,R,G的最后一个值
        U = np.r_[U, H[N - 2] / (H[0] + H[N - 2])]
        R = np.r_[R, H[0] / (H[0] + H[N - 2])]
        G = np.r_[G, 3 * (U[N - 1] * (Y[1] - Y[0]) / H[0] + R[N - 1] * (Y[N - 1] - Y[N - 2]) / H[N - 2])]

        # 解方程组求M
        A3 = np.array([[]])
        for i in range(1, N):
            Ai = np.array([])
            if i == N - 1:
                Ai = np.r_[Ai, U[N - 1]]
                Ai = np.r_[Ai, [0 for j in range(i - 3)]]
            else:
                Ai = np.r_[Ai, [0 for j in range(i - 2)]]
            if i > 1:
                Ai = np.r_[Ai, R[i]]
            Ai = np.r_[Ai, 2]
            if i != N - 1:
                Ai = np.r_[Ai, U[i]]
            if i == 1:
                Ai = np.r_[Ai, [0 for j in range(N - 2 - Ai.size)]]
                Ai = np.r_[Ai, R[1]]
            else:
                Ai = np.r_[Ai, [0 for j in range(N - 1 - Ai.size)]]
            if i == 1:
                A3 = np.c_[A3, [Ai]]
            else:
                A3 = np.r_[A3, [Ai]]
        b3 = np.array([G[i] for i in range(1, N)])
        M = np.array(np.linalg.solve(A3, b3))
        M = np.r_[M[N - 2], M]

    # 求出全部表达式
    x = sympy.symbols("x")  # 申明未知数"x"

    S = np.array([])
    for i in range(X.size - 1):
        S = np.r_[S, [(H[i] + 2 * (x - X[i])) / np.power(H[i], 3) * np.power(x - X[i + 1], 2) * Y[i] + (
                    H[i] - 2 * (x - X[i + 1])) / np.power(H[i], 3) * np.power(x - X[i], 2) * Y[i + 1] + (
                                x - X[i]) * np.power(x - X[i + 1], 2) / np.power(H[i], 2) * M[i] + (
                                x - X[i + 1]) * np.power(x - X[i], 2) / np.power(H[i], 2) * M[i + 1]]]

    while True:
        # 输入预测值
        x1 = eval(input('请输入需要预测的值:'))

        xl = 0
        xlid = 0
        xr = 0
        xrid = 0
        for i in range(X.size):
            if X[i] > x1:
                xr = X[i]
                xrid = i
                xl = X[i - 1]
                xlid = i - 1
                break
        y = (H[xlid] + 2 * (x - X[xlid])) / np.power(H[xlid], 3) * np.power(x - X[xrid], 2) * Y[xlid] + (
                    H[xlid] - 2 * (x - X[xrid])) / np.power(H[xlid], 3) * np.power(x - X[xlid], 2) * Y[xrid] + (
                        x - X[xlid]) * np.power(x - X[xrid], 2) / np.power(H[xlid], 2) * M[xlid] + (
                        x - X[xrid]) * np.power(x - X[xlid], 2) / np.power(H[xlid], 2) * M[xrid]
        y1 = y.evalf(subs={x: x1})

        # 打印数据
        print("方程组的解为:")
        print(M)
        print("三次样条插值的表达式为:")
        print(S)

        # 打印预测值
        print("预测值为:")
        print(y1)

        # 画图
        picture = plt.figure()
        # plt.ion()
        plt.scatter(X, Y, marker='.', c='b')
        # plt.pause(0.01)

        # 画出预测值
        plt.scatter(x1, y1, marker='.', c='r')
        # plt.pause(0.01)

        # 画函数曲线
        for i in range(S.size):
            XX = np.arange(X[i], X[i + 1], 0.01)
            XX = np.array(XX)
            YY = np.array([])
            for j in range(XX.size):
                Z = S[i]
                K = Z.evalf(subs={x: XX[j]})
                YY = np.r_[YY, K]
            plt.plot(XX, YY, color='k')
            # plt.pause(0.01)

        # plt.pause(0.01)
        # plt.ioff()  # 关闭interactive mode
        plt.show(block=True)
        tmpFlag = eval(input('输入\'1\'继续预测,输入\'2\'重新执行程序。'))
        if tmpFlag != 1:
            plt.close()
            break
        plt.close()
    tmpFlag = eval(input('输入\'1\'继续程序,输入\'2\'退出程序。'))
    if tmpFlag != 1:
        break

测试样例

# 第二类
>>
2
4
1 2 4 5
1 3 4 2
0 0
3
<<
4.25

----以上为个人思考与见解,有误请指点,有想法也可联系交流!

               ~~~~~~~~~~~~~~               谢谢观看!文章来源地址https://www.toymoban.com/news/detail-721249.html

到了这里,关于三次样条插值(python完美实现,三种形式都有!)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于MATLAB的三维数据插值拟合与三次样条拟合算法(附完整代码)

    目录 一. 三维插值 例题1 二. 高维度插值拟合 格式一 格式二 格式三 格式四 格式五 例题2 三. 单变量三次样条插值 例题3 例题4 四. 多变量三次样条插值 例题6 首先三维网格生成是利用 meshgrid() 函数,在MATLAB中调用格式如下: 三维插值运算,主要利用griddata()函数与interp()函数

    2024年02月14日
    浏览(32)
  • 曲线生成 | 图解三次样条曲线生成原理(附ROS C++/Python/Matlab仿真)

    🔥附C++/Python/Matlab全套代码🔥课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。 🚀详情:图解自动驾驶中的运动规划(Mo

    2024年01月22日
    浏览(30)
  • 三次样条样条:Bézier样条和Hermite样条

    总结 What is the Difference Between Natural Cubic Spline, Hermite Spline, Bézier Spline and B-spline? 1.多项式拟合中的 Runge Phenomenon 找到一条通过N+1个点的多项式曲线 ,需要N次曲线。通过两个点的多项式曲线为一次,三个点的多项式曲线为二次。当点数较多时,曲线阶数增高,在端点处易出现

    2024年02月04日
    浏览(33)
  • 【心电图信号压缩】ECG信号压缩与通过三次样条近似重建的ECG信号压缩研究(Matlab代码实现)

     💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 心电图

    2024年02月13日
    浏览(30)
  • 分段三次Hermite插值的原理、matlab代码和Python代码

    目录 一、分段三次Hermite插值 二、分段三次Hermite插值多项式的推导 三、分段三次Hermite插值的matlab实现  四、分段三次Hermite插值的Python实现 已知,求一个分段函数H(x),使其满足: (1) (2)在每个子区间  上,H(x)是次数不超过3的多项式。 称满足上述条件的函数H(x)为分段

    2024年02月05日
    浏览(30)
  • OpenCV之薄板样条插值(ThinPlateSpline)

    官方文档:OpenCV: cv::ThinPlateSplineShapeTransformer Class Reference  使用方法: 头文件:#include opencv2/shape/shape_transformer.hpp (2)计算转换矩阵 (3)获取任意点的转换值 (4)图像变换         图像变换与多点变换相同,注意estimateTransformation只接受输入为(1,m,2)的tuple,不然就会报

    2024年02月12日
    浏览(26)
  • B-spline三次B样条曲线方程

    一、B-样条基函数 它有两条贝塞尔基函数所没有的特性, (1)定义域被节点细分(subdivided); (2) 基函数不是在整个区间非零。实际上,每个B样条基函数在附近一个子区间非零, 因此,B-样条基函数相当“局部”。 1.节点 设 U  是 m  + 1 个非递减数的集合, u 0 =  u 2 =  u 3 

    2024年02月06日
    浏览(30)
  • 贝塞尔曲线 PH曲线 C曲线 B样条 NURBS样条曲线 三次Cardinal样条曲线对比 也涉及到不同曲线加速度的一些东西,不过有待细化

    本文很多直接截图论文的,因为不需要重复造轮子,对比也只是为了选择更佳的路径规划曲线,对比于B曲线,时间不够,概括会有所疏漏,下表是曲线的对比表格,看完可以直接看下面,也涉及到不同曲线加速度的一些东西,不过有待细化,2022/3/17后来上了高等工程数学,如

    2024年02月03日
    浏览(29)
  • 基于Matlab的插值问题(Lagrange插值法、三次插值多项式)

    要求 1、 利用Lagrange插值公式 L n ( x ) = ∑ k = 0 n ( ∏ i = 0 , i ≠ k n x − x i x k − x i ) y k {L_n}(x) = sumlimits_{k = 0}^n {left( {prodlimits_{i = 0,i ne k}^n {frac{{x - {x_i}}}{{{x_k} - {x_i}}}} } right)} {y_k} L n ​ ( x ) = k = 0 ∑ n ​ ( i = 0 , i  = k ∏ n ​ x k ​ − x i ​ x − x i ​ ​ ) y k ​ 编写出

    2024年02月07日
    浏览(31)
  • 分段三次hermit插值

    一、插值函数建立 设函数 y = F ( x ) y=F(x) y = F ( x ) 在区间 [ a , b ] [a,b] [ a , b ] 上有定义,且已知在离散点 a = x 0 x 1 . . . x n = b a=x_0x_1...x_n = b a = x 0 ​ x 1 ​ ... x n ​ = b 上的值 y 0 , y 1 , . . . y n , y_0,y_1,...y_n, y 0 ​ , y 1 ​ , ... y n ​ , f ( x ) f(x) f ( x ) 在 [ x j , x j + 1 ] [x_j,x_

    2024年02月11日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包