計算方法實驗(一):拉格朗日插值多項式

拉格朗日插值數學原理

給定平面上n+1n + 1個不同的數據點(xk,f(xk))(x_{k},f(x_{k}))k=0,1,,nk = 0,1,\cdots,nxixjx_{i} \neq x_{j}iji \neq j;則滿足條件

Pn(xk)=f(xk),  k=0,1,,n P_{n}\left( x_{k} \right) = f\left( x_{k} \right),\ \ k = 0,1,\cdots,n

nn次拉格朗日插值多項式

Pn(x)=k=0nf(xk)lk(x) P_{n}(x) = \sum_{k = 0}^{n}{f(x_{k})}l_{k}(x)

是存在唯一的。若xk[a,b],k=0,1,,nx_{k} \in \lbrack a,b\rbrack,k = 0,1,\cdots,n,且函數f(x)f(x)充分光滑,則當x[a,b]x \in \lbrack a,b\rbrack時,有誤差估計式

f(x)Pn(x)=f(n+1)(ξ)(n+1)!(xx0)(xx1)(xxn),  ξ[a,b] f\left( x \right) - P_{n}\left( x \right) = \frac{f^{\left( n + 1 \right)}\left( \xi \right)}{\left( n + 1 \right)!}\left( x - x_{0} \right)\left( x - x_{1} \right)\cdots\left( x - x_{n} \right),\ \ \xi \in \lbrack a,b\rbrack

程序設計

核心代碼

    double x, y = 0.0;
    scanf("%lf", &x);
    double a[N + 1], b[N + 1];
    int n = 0;
    while (scanf("%lf%lf", &a[n], &b[n]) >= 2) n++;
    n--;
    for (int k = 0; k <= n; k++) {
        double l = 1.0;
        for (int j = 0; j <= n; j++) {
            if (j != k) l *= (x - a[j]) / (a[k] - a[j]);
        }
        y += l * b[k];
    }
	printf("x = %.3lf\ny = %.3lf", x, y);
  • 多個n多個x測試時怎麼辦呢?

作爲真正的程序員!一定要會設計框架!!!!!!!

so 我設計了這麼一個Lagrange測試框架 只要修改參數即可!!!!

框架示例

可以修改:

  • n的數量
  • x的數量
  • 最大的n值
  • 若干n的值
  • 若干x的值
  • 左右區間值
  • 插值點取值方法X()
  • y計算方法Y()
#include <cmath>
#include <cstdio>
#define N1 3   // n amount
#define N2 4   // x amount
#define N3 20  // n max

int Ns[N1] = {5, 10, 20};
double x[N2] = {-0.95, -0.05, 0.05, 0.95};
double l = -1.0;
double r = 1.0;

double X(int k, int n) {
    double h = (r - l) / n;
    return l + k * h;
}

double Y(double x) { return 1 / (1 + x * x); }

int main() {
    for (int i = 0; i < N2; i++) printf("\tx=%.2lf", x[i]);
    printf("\n");
    for (int i = 0; i < N1; i++) {
        double a[N3 + 1], b[N3 + 1];
        int n = Ns[i];
        for (int k = 0; k <= n; k++) {
            a[k] = X(k, n);  // x
            b[k] = Y(a[k]);  // y
        }
        printf("n=%d", n);
        for (int p = 0; p < N2; p++) {
            double y = 0.0;
            for (int k = 0; k <= n; k++) {
                double l = 1.0;
                for (int j = 0; j <= n; j++) {
                    if (j != k) l *= (x[p] - a[j]) / (a[k] - a[j]);
                }
                y += l * b[k];
            }
            printf("\t%.6lf", y);
        }
        printf("\n");
    }
    printf("Actual");
    for (int p = 0; p < N2; p++) printf("\t%.6lf", Y(x[p]));
    return 0;
}

輸出
x=0.75 x=1.75 x=2.75 x=3.75 x=4.75
n=5 0.528974 0.373325 0.153733 -0.025954 -0.015738
n=10 0.678990 0.190580 0.215592 -0.231462 1.923631
n=20 0.636755 0.238446 0.080660 -0.447052 -39.952449
Actual 0.640000 0.246154 0.116788 0.066390 0.042440

還沒完!!!!!!得出的數據直接複製到Word裏,全選+點擊“轉換文本爲表格”即可立刻變成表格!!!!!

  • 逗號分隔,導出.csv文件,用excel打開復制……那也行???

待更新詳細報告

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章