三次样条插值是一种常用的数值计算方法,可以用于在给定的一组数据点上构造一条平滑的曲线。以下是用C++实现三次样条插值的代码:

#include <iostream>
#include <vector>

using namespace std;

struct Spline {
    vector<double> a, b, c, d, x;
    int n;

    void build(vector<double> &y) {
        n = y.size();
        a = y;
        b.resize(n);
        c.resize(n);
        d.resize(n);
        x.resize(n);

        // step 1: compute x
        for (int i = 0; i < n; i++) {
            x[i] = i;
        }

        // step 2: solve tridiagonal system
        vector<double> h(n), alpha(n), l(n), mu(n), z(n);
        for (int i = 1; i < n; i++) {
            h[i] = x[i] - x[i - 1];
            alpha[i] = 3.0 / h[i] * (a[i + 1] - a[i]) - 3.0 / h[i - 1] * (a[i] - a[i - 1]);
        }
        l[0] = 1;
        mu[0] = z[0] = 0;
        for (int i = 1; i < n - 1; i++) {
            l[i] = 2 * (x[i + 1] - x[i - 1]) - h[i - 1] * mu[i - 1];
            mu[i] = h[i] / l[i];
            z[i] = (alpha[i] - h[i - 1] * z[i - 1]) / l[i];
        }
        l[n - 1] = 1;
        z[n - 1] = 0;
        c[n - 1] = 0;
        for (int j = n - 2; j >= 0; j--) {
            c[j] = z[j] - mu[j] * c[j + 1];
            b[j] = (a[j + 1] - a[j]) / h[j] - h[j] * (c[j + 1] + 2 * c[j]) / 3;
            d[j] = (c[j + 1] - c[j]) / (3 * h[j]);
        }
    }

    double evaluate(double t) {
        int i = 0, j = n - 1;
        while (i < j) {
            int k = (i + j) / 2;
            if (x[k] < t) {
                i = k + 1;
            } else {
                j = k;
            }
        }
        double dx = t - x[i];
        return a[i] + b[i] * dx + c[i] * dx * dx + d[i] * dx * dx * dx;
    }
};

int main() {
    vector<double> x = {0, 1, 2, 3, 4, 5};
    vector<double> y = {0, 1, 4, 9, 16, 25};
    Spline spline;
    spline.build(y);
    for (int i = 0; i < x.size(); i++) {
        cout << "x = " << x[i] << ", y = " << spline.evaluate(x[i]) << endl;
    }
    return 0;
}

在上述代码中,我们首先定义了一个结构体Spline,用于表示三次样条插值。其中,abcd分别表示三次样条函数的系数,x表示数据点的横坐标,n表示数据点的个数。

在函数build中,我们首先计算出数据点的横坐标x,然后根据三次样条插值的求解方法,解出三对角线矩阵的系数。具体而言,我们计算出向量halphalmuz,然后通过追赶法求解三对角线矩阵的系数。

在函数evaluate中,我们首先根据给定的横坐标t,找到其对应的区间[x[i], x[i+1]),然后根据三次样条函数的表达式计算出纵坐标。

最后,在main函数中,我们定义了一个数据点的横坐标x和纵坐标y,然后调用spline.build(y)求解三次样条插值,最后,通过spline.evaluate(x[i])计算出对应的纵坐标。

用c++实现三次样条插值

原文地址: https://www.cveoy.top/t/topic/w54 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录