C++:Lagrange插值方法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本篇文章是在学习计算方法后,尝试用Lagrange插值方法进行插值,其中遇到了一些问题,询问了一下别人得到了解决方法,因此写下了这篇文章。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Lagrange形式

为了构造出Lagrange形式的插值公式,可以先作插值数据点
{( x 0 x_0 x0,0),( x 1 x_1 x1,0),…,( x i − 1 x_{i-1} xi1,0),( x i x_i xi,0),( x i + 1 x_{i+1} xi+1,0),…,( x n x_n xn,0)}
的n次插值多项式为 l i l_i li(x),由插值条件可知:
l i ( x k ) = δ i k = { 0 , k ≠ i 1 , k = i l_i(x_k)=\delta_{ik}= \left \{\begin{array}{cc} 0, &k\neq i\\ 1, & k=i \end{array}\right. li(xk)=δik={0,1,k=ik=i
l i ( x ) l_i(x) li(x)是有 n n n个根 x 0 , x 1 , . . . , x i − 1 , x i + 1 , . . . , x n x_0,x_1,...,x_{i-1},x_{i+1},...,x_n x0,x1,...,xi1,xi+1,...,xn n n n次多项式,因此可以写成下面这种形式:
l i ( x ) = a ( x − x 0 ) . . . ( x − x i − 1 ) ( x − x i + 1 ) . . . ( x − x n ) l_i(x)=a(x-x_0)...(x-x_{i-1})(x-x_{i+1})...(x-x_n) li(x)=a(xx0)...(xxi1)(xxi+1)...(xxn)
其中, a a a是一个待定的常数,令 x = x i x=x_i x=xi,代入上式并可以有插值条件可得:
1 = l i ( x ) = a ( x − x 0 ) . . . ( x − x i − 1 ) ( x − x i + 1 ) . . . ( x − x n ) 1=l_i(x)=a(x-x_0)...(x-x_{i-1})(x-x_{i+1})...(x-x_n) 1=li(x)=a(xx0)...(xxi1)(xxi+1)...(xxn)
因此:
a = [ ∏ k ≠ i ( x i − x k ) ] − 1 a=\left[\prod_{{ \begin{gathered} k\neq i\\ \end{gathered} }} (x_i-x_k)\right]^{-1} a=k=i(xixk)1
从而可以得到:
l i ( x ) = ∏ k ≠ i ( x − x k ) ∏ k ≠ i ( x i − x k ) , i = 0 , 1 , 2 , . . . , n (1) l_i(x)=\frac{\prod_{{ \begin{gathered} k\neq i\\ \end{gathered} }} (x-x_k)}{\prod_{{ \begin{gathered} k\neq i\\ \end{gathered} }} (x_i-x_k)},i=0,1,2,...,n \tag{1} li(x)=k=i(xixk)k=i(xxk),i=0,1,2,...,n(1)
若采用记号:
ω ( x ) = ∏ k = 1 n x − x k (2) \omega(x)=\prod_{k=1}^n{ x-x_k} \tag{2} ω(x)=k=1nxxk(2)

l i ( x ) = ω ( x ) ( x − x i ) ω ′ ( x i ) (3) l_i(x)=\frac {\omega(x)}{(x-x_i)\omega^\prime(x_i)} \tag{3} li(x)=(xxi)ω(xi)ω(x)(3)
有式 ( 1 ) (1) (1)或式 ( 3 ) (3) (3)定义的 n n n次多项式 l i ( x ) l_i(x) li(x)称为Lagrange基本插值多项式,由它们可以构成插值多项式的Lagrange形式:
L ( x ) = ∑ i = 0 n y i l i ( x ) = ∑ i = 0 n y i ω ( x ) ( x − x i ) ω ′ ( x i ) (4) L(x)=\sum_{i=0}^n{y_il_i(x)}=\sum_{i=0}^n{y_i\frac {\omega(x)}{(x-x_i)\omega^\prime(x_i)}} \tag{4} L(x)=i=0nyili(x)=i=0nyi(xxi)ω(xi)ω(x)(4)
( 4 ) (4) (4)为满足下列插值条件
P ( x i ) = p i = y i , i = 0 , 1 , 2 , … , m (5) P(x_i)=p_i=y_i, i=0,1,2,\ldots,m \tag{5} P(xi)=pi=yi,i=0,1,2,,m(5)
的次数不超过 n n n的多项式。
但是直接利用式 ( 4 ) (4) (4)来计算给定的 x ˉ \bar{x} xˉ处的值是不经济的,大约需要 n 2 n^2 n2flop。若先计算出与求值点 x ˉ \bar{x} xˉ无关的量
d i = ω ′ ( x i ) , i = 0 , 1 , 2 , … , n d_i=\omega^\prime(x_i),i=0,1,2,\ldots,n di=ω(xi),i=0,1,2,,n
则式 ( 4 ) (4) (4)可以写成
L ( x ) = ω ( x ) ∑ i = 0 n y i d i ( x − x i ) (6) L(x)=\omega(x)\sum_{i=0}^n{\frac {y_i}{d_i(x-x_i)}} \tag{6} L(x)=ω(x)i=0ndi(xxi)yi(6)
如果所有的 d i d_i di都已经计算出,则可以按照式 ( 6 ) (6) (6)求值 l ( x ˉ ) l(\bar{x}) l(xˉ)约需要 3 n 3n 3nflop。因为 d i d_i di不依赖于求值点 x ˉ \bar{x} xˉ,它们可以预先计算出来,以备作插值时使用。

二、程序算法

代码如下(示例):

double Lagrange(double X[], double Y[], int n, double x)//采用Lagrange插值方法,分别表示,长度,深度,数组数目和所需要计算点的值
{
    double result = 0.0;//最后得到的函数解
    double li[200];//lagrange基本插值多项式
    double temp1, temp2;//分别用来存储Lagrange多项式的分母和分子
    int i, j;//循环变量
    for (i = 0; i < n; i++)
    {
        temp1 = 1.0; temp2 = 1.0;
        for (j = 0; j < n; j++)
        {
            if (i == j)
                continue;
            temp1 = temp1 * (x - X[j]);
            temp2 = temp2 * (X[i] - X[j]);
        }
        li[i] = temp1 / temp2;
    }
    for (i = 0; i < n; i++)
    {
        result = result + Y[i] * li[i];
    }
    return result;
}

三、病态问题

因为Lagrange插值本身存在的问题,可能会出现插值得到的结果不正常,产生一个特别大的误差。此时如果想在这得到准确的解可以进行分段插值的方法,在此就不在赘述了,只是在这里表明存在着这么一个问题,如果是不想这样的话,建议直接使用分段样条插值的方法。

总结

此篇文章对Lagrange插值方法进行了总结,指出其存在着病态问题,最后在计算的时候应该十分的注意。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值