拉格朗日插值多项式

1.拉格朗日插值多项式

首先给出,n次插值基函数定义
若 n 次 多 项 式 l j ( x ) ( j = 1 , 2 , … , n ) 在 n + 1 个 节 点 x 0 < x 1 < … < x n 上 满 足 条 件 若n次多项式l_j(x)(j=1,2,\ldots,n)在n+1个节点x_0nlj(x)(j=1,2,,n)n+1x0<x1<<xn
l j ( x k ) = { 1 , k = j , j , k = 0 , 1 , … , n , 0 , k ≠ j , l_j(x_k)=\begin{cases} 1,k=j,\\ \qquad\qquad j,k=0,1,\ldots,n,\\ 0,k\neq j, \end{cases} lj(xk)=1,k=j,j,k=0,1,,n,0,k=j,
就称这 n + 1 个 n 次 多 项 式 l 0 ( x ) , l 1 ( x ) , … , l n ( x ) 为 节 点 x 0 , x 1 , … , x n 上 的 n次插值基函数 . n+1个n次多项式l_0(x),l_1(x),\ldots,l_n(x)为节点x_0,x_1,\ldots,x_n上的\textbf{n次插值基函数}. n+1nl0(x),l1(x),,ln(x)x0,x1,,xnn次插值基函数.
由此可以得到 n 次 插 值 基 函 数 n次插值基函数 n
l k ( x ) = ( x − x 0 ) … ( x − x k − 1 ) ( x − x k + 1 ) … ( x − x n ) ( x k − x 0 ) … ( x k − x k − 1 ) ( x k − x k + 1 ) … ( x k − x n ) , k = 0 , 1 , … , n . l_k(x)=\frac{(x-x_0)\ldots(x-x_{k-1})(x-x_{k+1})\ldots(x-x_n)}{(x_k-x_0)\ldots(x_k-x_{k-1})(x_k-x_{k+1})\ldots(x_k-x_n)},k=0,1,\ldots,n. lk(x)=(xkx0)(xkxk1)(xkxk+1)(xkxn)(xx0)(xxk1)(xxk+1)(xxn),k=0,1,,n.
显然它满足n次插值基函数定义的条件.于是,满足 L n ( x j ) = y j , j = 0 , 1 , … , n . L_n(x_j)=y_j,j=0,1,\ldots,n. Ln(xj)=yj,j=0,1,,n.条件的 L n ( x ) L_n(x) Ln(x)可表示为
L n ( x ) = ∑ k = 0 n y k l k ( x ) . L_n(x)=\sum_{k = 0}^{n}y_kl_k(x). Ln(x)=k=0nyklk(x).
形如上式的插值多项式 L n ( x ) 称 为 拉格朗日(Lagrange)插值多项式 L_n(x)称为\textbf{拉格朗日(Lagrange)插值多项式} Ln(x)拉格朗日(Lagrange)插值多项式
l k ( x ) l_k(x) lk(x)的定义,知
L n ( x j ) = ∑ k = 0 n y k l k ( x j ) = y j , j = 0 , 1 , … , n . L_n(x_j)=\sum_{k = 0}^{n}y_kl_k(x_j)=y_j,\quad j=0,1,\ldots,n. Ln(xj)=k=0nyklk(xj)=yj,j=0,1,,n.

2.Python实现拉格朗日插值多项式

import numpy as np
from sympy import expand
from sympy.abc import x


# 自己原创
# 拉格朗日插值多项式输出显示形式与scipy.interpolate模块的同名函数有差距,有待继续优化
def lagrange(x_list: list, y_array: np.ndarray):
    """
    实现拉格朗日插值函数
    :param x_list: 插值点横坐标列表
    :param y_array: 插值点纵坐标数组
    :return: 拉格朗日插值多项式
    """
    degree = y_array.shape[0]
    l_n = 0
    for k in range(degree):
        # 注意不能同时对列表进行遍历和删除,否则索引会超出范围报错,有几种方式解决,此处使用切片
        l_n += y_array[k] * lagrange_base_function(k, x_list[::])
    return expand(l_n)


# 自己原创
def lagrange_base_function(k, x_list: list):
    """
    实现拉格朗日插值基函数
    :param k: 插值结点横坐标x_k的下标
    :param x_list: 插值点横坐标列表
    :return: 第k个插值结点的插值基函数
    """
    x_k = x_list[k]  # 取得xk处的值
    x_list.pop(k)  # 删除xk处的值
    x_list = np.array(x_list)
    #  向量运算实现插值基函数
    return np.prod((x - x_list) / (x_k - x_list))
    # 按元素实现插值基函数
    # l_k = 1
    # for i in range(x_coefficient.shape[0]):
    #     l_k *= (x - x_coefficient[i]) / (x_k - x_coefficient[i])
    # return l_k

3.插值多项式测试

if __name__ == '__main__':
    # 拉格朗日插值多项式测试成功,来源详见李庆扬数值分析第5版P48,e.x.1
    x_coefficient_list = [1, -1, 2]
    x_coefficient_array = np.array(x_coefficient_list)
    y = np.array([0, -3, 4])
    lagrange_interpolation_polynomial = lagrange(x_coefficient_list, y)
    print("拉格朗日插值多项式为:{}".format(lagrange_interpolation_polynomial))
    # 计算拉格朗日插值多项式在x=2处的值
    print("拉格朗日插值多项式在x=2处的值为:{}".format(lagrange_interpolation_polynomial.subs(x, 2)))

4.运行结果

拉格朗日插值多项式_第1张图片

你可能感兴趣的:(数值分析,人工智能数理基础,算法,拉格朗日插值多项式,函数插值,Python)