[计算机数值分析]牛顿插值公式

Spring-_-Bear 的 CSDN 博客导航

埃特金算法虽然具有承袭性,但其算式是递推型的,不便于进行理论上的分析。所以采用具有承袭性的显式的牛顿插值公式是不错的选择。

p n ( x ) = f ( x 0 ) + f ( x 0 , x 1 ) ( x − x 0 ) + . . . + f ( x 0 , x 1 , . . . , x n , x ) ( x − x 0 ) ( x − x 1 ) . . . ( x − x n ) (1) p_{n}(x)=f(x_{0})+f(x_{0},x_{1})(x-x_{0})+...+f(x_{0},x_{1},...,x_{n},x)(x-x_{0})(x-x_{1})...({x-x_{n}})\tag1 pn(x)=f(x0)+f(x0,x1)(xx0)+...+f(x0,x1,...,xn,x)(xx0)(xx1)...(xxn)(1)

例:已知四个节点

( 0 , 1 ) , ( 2 , 3 ) , ( 3 , 2 ) , ( 5 , 5 ) (0,1),(2,3),(3,2),(5,5) (0,1)(2,3)(3,2)(5,5)

构造三次牛顿插值多项式,计算当 x = 2.5 x=2.5 x=2.5 时牛顿多项式插值结果。

解:根据牛顿插值公式,如式(1),我们很容易写出三次牛顿插值多项式如下:

p 3 ( x ) = f ( x 0 ) + f ( x 0 , x 1 ) ( x − x 0 ) + f ( x 0 , x 1 , x 2 ) ( x − x 0 ) ( x − x 1 ) + f ( x 0 , x 1 , x 2 , x 3 ) ( x − x 0 ) ( x − x 1 ) ( x − x 2 ) p_{3}(x)=f(x_{0})+f(x_{0},x_{1})(x-x_{0})+f(x_{0},x_{1},x_{2})(x-x_{0})(x-x_{1})+f(x_{0},x_{1},x_{2},x_{3})(x-x_{0})(x-x_{1})(x-x_{2}) p3(x)=f(x0)+f(x0,x1)(xx0)+f(x0,x1,x2)(xx0)(xx1)+f(x0,x1,x2,x3)(xx0)(xx1)(xx2)

化简得

p 3 ( x ) = 3 10 x 3 − 13 6 x 2 + 62 15 x + 1 p_{3}(x)=\frac{3}{10}x^{3}-\frac{13}{6}x^{2}+\frac{62}{15}x+1 p3(x)=103x3613x2+1562x+1

x = 2.5 x=2.5 x=2.5 时,三次牛顿插值多项式结果为 p 3 ( x ) = 2.479167 p_{3}(x)=2.479167 p3(x)=2.479167

运行示例:

在这里插入图片描述

程序源码:

#include <iostream>

using namespace std;

#define MAX 10

typedef struct Point
{
    double x;
    double y;
} point;

int main(void)
{
    int n;
    cout << "请输入插值节点的个数(<10):";
    cin >> n;

    point p[MAX];
    for (int i = 1; i <= n; i++)
    {
        cout << "请输入第 " << i << " 个点的坐标:";
        cin >> p[i].x;
        cin >> p[i].y;
    }

    double x;
    cout << "请输入 x 的值:";
    cin >> x;

    double sum = 0;
    for (int i = 1; i <= n; i++)
    {
        // 根据牛顿插值公式,第一项为 f(x1) 即 0 阶差商
        if (i == 1)
        {
            sum += p[1].y;
            continue;
        }

        // 求右半部分,即 (x-x0) || (x-x0)(x-x1) || (x-x0)(x-x1)(x-x2)...
        double right = 1;
        for (int j = 1; j < i; j++)
        {
            right *= (x - p[j].x);
        }

        // 求左半部分 leftSum 即 f(x0,x1) || f(x0,x1,x2)...也即差商
        double leftSum = 0;
        for (int k = 1; k <= i; k++)
        {
            if (i == 1)
            {
                leftSum = 1;
                break;
            }

            double denominator = 1;
            for (int m = 1; m <= i; m++)
            {
                if (m == k)
                {
                    continue;
                }
                // 累乘分母
                denominator *= (p[k].x - p[m].x);
            }

            // 累加组成差商的每一项,最终结果为差商
            leftSum += p[k].y / denominator;
        }

        // 累加差商与右半部分的和得最终插值结果
        sum += leftSum * right;
    }

    cout << "\n运用牛顿插值法求得 f(x) =" << sum << endl;

    return 0;
}
  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春天熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值