二次样条插值

☆樱花仙子☆ 提交于 2020-01-20 05:02:54
# encoding:utf-8
import numpy as np
import matplotlib.pyplot as plt

# 关键点
x = [2.0, 4.5, 7.0, 9.0, 11.0]
y = [1.5, 2.5, 1.5, 0.5, 5.0]

def main():
    # 检查长度
    if len(x) != len(y):
        print('error! len(x) != len(y)')
        return

    # 第一个点到第二个点之间使用直线连接,计算斜率和截距
    slope = (y[1] - y[0]) / (x[1] - x[0])
    intercept = y[0] - slope * x[0]
    bivariate_primary_plot(0, slope, intercept, x[0], x[1])

    # 第二个点到最后一个点之间使用二次函数拟合
    for i in range(1, len(x) - 1):
        # 2 * x1 * a + b = y1'
        # x1 * x1 * a + x1 * b + c = y1
        # x2 * x2 * a + x2 * b + c = y2
        a11 = 2 * x[i]
        a12 = 1
        a13 = 0
        b1 = slope
        a21 = x[i] * x[i]
        a22 = x[i]
        a23 = 1
        b2 = y[i]
        a31 = x[i + 1] * x[i + 1]
        a32 = x[i + 1]
        a33 = 1
        b3 = y[i + 1]

        [a, b, c] = cramer_law(a11, a12, a13, b1, a21, a22, a23, b2, a31, a32, a33, b3)

        slope = 2 * a * x[i + 1] + b

        bivariate_primary_plot(a, b, c, x[i], x[i + 1])

    # 画出关键点
    plt.scatter(x, y, marker = 'o', color = 'black', s = 60)

    plt.grid()
    plt.show()

# 画二次函数曲线
def bivariate_primary_plot(a, b, c, x_min, x_max):
    x = np.arange(x_min, x_max, 0.01)
    y = a * x * x + b * x + c
    plt.plot(x, y, linewidth = '2.5', color = 'red')

# 克拉莫法则解三元一次方程组
# a11 * x1 + a12 * x2 + a13 * x3 = b1
# a21 * x1 + a22 * x2 + a23 * x3 = b2
# a31 * x1 + a32 * x2 + a33 * x3 = b3
def cramer_law(a11, a12, a13, b1, a21, a22, a23, b2, a31, a32, a33, b3):
    d0 = a11 * a22 * a33 + a12 * a23 * a31 + a13 * a21 * a32 - a11 * a23 * a32 - a12 * a21 * a33 - a13 * a22 * a31
    d1 = b1  * a22 * a33 + a12 * a23 * b3  + a13 * b2  * a32 - b1  * a23 * a32 - a12 * b2  * a33 - a13 * a22 * b3  
    d2 = a11 * b2  * a33 + b1  * a23 * a31 + a13 * a21 * b3  - a11 * a23 * b3  - b1  * a21 * a33 - a13 * b2  * a31
    d3 = a11 * a22 * b3  + a12 * b2  * a31 + b1  * a21 * a32 - a11 * b2  * a32 - a12 * a21 * b3  - b1  * a22 * a31
    return [d1 / d0, d2 / d0, d3 / d0]

if __name__ == '__main__':
    main()

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!