Интерполяционный многочлен Лагранжа

Материал из testwiki
Перейти к навигации Перейти к поиску

Интерполяцио́нный многочле́н Лагра́нжа — многочлен минимальной степени, принимающий заданные значения в заданном наборе точек, то есть решающий задачу интерполяции.

Определение

Интерполяционный многочлен Лагранжа для четырёх точек (-9,5), (-4,2), (-1,-2) и (7,9), а также полиномы yili(x), каждый из которых проходит через одну из выделенных точек, и принимает нулевое значение в остальных.

Пусть задана n+1 пара чисел (x0,y0),(x1,y1),,(xn,yn), где все xj различны. Требуется построить многочлен L(x) степени не более n, для которого L(xj)=yj.

Общий случай

Ж. Л. Лагранж предложил следующий способ вычисления таких многочленов:

L(x)=i=0nyili(x),

где базисные полиномы li определяются по формуле

li(x)=j=0,jinxxjxixj=xx0xix0xxi1xixi1xxi+1xixi+1xxnxixn

Для любого i=0,,n многочлен li имеет степень n и

li(xj)={0,ji,1,j=i.

Отсюда следует, что L(x), являющийся линейной комбинацией многочленов li(x), имеет степень не больше n и L(xi)=yi.

Случай равноотстоящих узлов интерполяции

Пусть узлы интерполяции xj являются равноотстоящими, то есть выражаются через начальную точку x0 и некоторую фиксированную положительную величину h следующим образом:

xj=x0+jh.

Отсюда следует, что

xjxi=(ji)h.

Подставляя эти выражения в формулу для базисного полинома и вынося h за знаки произведения в числителе и знаменателе, получим

lj(x)=i=0,ijn(xxi)(xjxi)=i=0,ijn(xx0ih)hni=0,ijn(ji)

Теперь можно ввести замену переменной

y=xx0h

и получить выражение для базисных полиномов через y, которое строится с использованием только целочисленной арифметики:

lj(x)=lj(x0+yh)=(1)njCnjy(y1)(yn)(yj)n!.

Данные величины называются коэффициентами Лагранжа. Они не зависят ни от y0,,yn, ни от h и потому могут быть вычислены заранее и записаны в виде таблиц. Недостатком данного подхода является факториальная сложность числителя и знаменателя, что требует использования длинной арифметики.

Остаточный член

Если считать числа y0,,yn значениями некоторой функции f в узлах x0,,xn, то ошибка интерполирования функции f многочленом L равна

f(x)L(x)=f(n+1)(ξ)(n+1)!(xx0)(xxn),

где ξ — некоторая средняя точка между наименьшим и наибольшим из чисел x0,,xn. Полагая Mn+1=supx[x0,xn]|f(n+1)(x)|, можно записать

|f(x)L(x)|Mn+1(n+1)!|(xx0)(xxn)|.

Единственность

Шаблон:Основная статья Существует единственный многочлен степени не превосходящей n, принимающий заданные значения в n+1 заданной точке. Шаблон:Доказательство Это утверждение является обобщением того факта, что через любые две точки проходит единственная прямая.

С точки зрения линейной алгебры

На единственность интерполяционного многочлена можно также взглянуть с точки зрения СЛАУ. Рассмотрим систему уравнений P(x0)=y0,P(x1)=y1,,P(xn)=yn. В явном виде она записывается как

{a0+a1x0+a2x02++anx0n=y0,a0+a1x1+a2x12++anx1n=y1,,a0+a1xn+a2xn2++anxnn=yn

Её можно переписать в виде системы уравнений Xa=y с неизвестным вектором a=(a0,a1,,an):

[1x0x02x0n1x1x12x1n1xnxn2xnn][a0a1an]=[y0y1yn]

Матрица X в такой системе является матрицей Вандермонда и её определитель равен i<j(xixj). Соответственно, если все точки x0,x1,,xn различны, то матрица невырождена и система обладает единственным решением.

По теореме Безу остаток от деления P(x) на (xa) равен P(a). Таким образом, всю систему можно воспринимать в виде системы сравнений:

{P(x)y0(modxx0),P(x)y1(modxx1),,P(x)yn(modxxn),

По китайской теореме об остатках у такой системы есть единственное решение по модулю (xx0)(xx1)(xxn), то есть, заданная система однозначно определяет многочлен степени не выше n. Такое представление многочлена в виде наборов остатков по модулям мономов аналогично представлению числа в виде остатков от деления на простые модули в системе остаточных классов. При этом явная формула для многочлена Лагранжа также может быть получена в соответствии с формулами китайской теоремы: P(x)=i=0nyiMiMi1, где Mi=ji(xxj) и Mi1=ji(xxj)1(modxxi)=ji(xixj)1.

Пример

Приближение функции f(x)=tg(x) (синяя линия) многочленом L(x)=4,834848x31,477474x (зелёная линия).

Найдем формулу интерполяции для f(x)=tg\nolimits (x) имеющей следующие значения:

x0=1.5f(x0)=14,1014x1=0.75f(x1)=0,931596x2=0f(x2)=0x3=0.75f(x3)=0,931596x4=1.5f(x4)=14,1014.
l0(x)=xx1x0x1xx2x0x2xx3x0x3xx4x0x4=1243x(2x3)(4x3)(4x+3)
l1(x)=xx0x1x0xx2x1x2xx3x1x3xx4x1x4=8243x(2x3)(2x+3)(4x3)
l2(x)=xx0x2x0xx1x2x1xx3x2x3xx4x2x4=3243(2x+3)(4x+3)(4x3)(2x3)
l3(x)=xx0x3x0xx1x3x1xx2x3x2xx4x3x4=8243x(2x3)(2x+3)(4x+3)
l4(x)=xx0x4x0xx1x4x1xx2x4x2xx3x4x3=1243x(2x+3)(4x3)(4x+3).

Получим

L(x)=1243(f(x0)x(2x3)(4x3)(4x+3)8f(x1)x(2x3)(2x+3)(4x3)+3f(x2)(2x+3)(4x+3)(4x3)(2x3)8f(x3)x(2x3)(2x+3)(4x+3)+f(x4)x(2x+3)(4x3)(4x+3))=4,834848x31,477474x.

Реализация общего случая на языке программирования Python

import numpy as np

# данные для примера
xi = np.array([-1.5, -0.75, 0, 0.75, 1.5])
yi = np.array([-14.1014, -0.931596, 0, 0.931596, 14.1014])


def get_coefficients(_pl: int, _xi: np.ndarray):
    '''
    Определение коэффициентов для множителей базисных полиномов l_i
    :param _pl: индекс базисного полинома
    :param _xi: массив значений x
    :return:
    '''
    n = int(_xi.shape[0])
    coefficients = np.empty((n, 2), dtype=float)
    for i in range(n):
        if i == _pl:
            coefficients[i][0] = float('inf')
            coefficients[i][1] = float('inf')
        else:
            coefficients[i][0] = 1 / (_xi[_pl] - _xi[i])
            coefficients[i][1] = -_xi[i] / (_xi[_pl] - _xi[i])
    filtered_coefficients = np.empty((n - 1, 2), dtype=float)
    j = 0
    for i in range(n):
        if coefficients[i][0] != float('inf'):
            # изменение последовательности, степень увеличивается
            filtered_coefficients[j][0] = coefficients[i][1]
            filtered_coefficients[j][1] = coefficients[i][0]
            j += 1
    return filtered_coefficients


def get_polynomial_l(_xi: np.ndarray):
    '''
    Определение базисных полиномов
    :param _xi: массив значений x
    :return:
    '''
    n = int(_xi.shape[0])
    pli = np.zeros((n, n), dtype=float)
    for pl in range(n):
        coefficients = get_coefficients(pl, _xi)
        for i in range(1, n - 1):  # проходим по массиву coefficients
            if i == 1:  # на второй итерации занимаются 0-2 степени
                pli[pl][0] = coefficients[i - 1][0] * coefficients[i][0]
                pli[pl][1] = coefficients[i - 1][1] * coefficients[i][0] + coefficients[i][1] * coefficients[i - 1][0]
                pli[pl][2] = coefficients[i - 1][1] * coefficients[i][1]
            else:
                clone_pli = np.zeros(n, dtype=float)
                for val in range(n):
                    clone_pli[val] = pli[pl][val]
                zeros_pli = np.zeros(n, dtype=float)
                for j in range(n-1):  # проходим по строке pl массива pli
                    product_1 = clone_pli[j] * coefficients[i][0]
                    product_2 = clone_pli[j] * coefficients[i][1]
                    zeros_pli[j] += product_1
                    zeros_pli[j+1] += product_2
                for val in range(n):
                    pli[pl][val] = zeros_pli[val]
    return pli

def get_polynomial(_xi: np.ndarray, _yi: np.ndarray):
    '''
    Определение интерполяционного многочлена Лагранжа
    :param _xi: массив значений x
    :param _yi: массив значений y
    :return:
    '''
    n = int(_xi.shape[0])
    polynomial_l = get_polynomial_l(_xi)
    for i in range(n):
        for j in range(n):
            polynomial_l[i][j] *= _yi[i]
    L = np.zeros(n, dtype=float)
    for i in range(n):
        for j in range(n):
            L[i] += polynomial_l[j][i]
    return L

# результат в виде массива коэффициентов многочлена при x в порядке увеличения степени
# [ 0.         -1.47747378  0.          4.8348476   0.        ]
# т.е. результирующий многочлен имеет вид: y(x) = -1.47747378*x + 4.8348476*x^3

Применения

Многочлены Лагранжа степеней от нулевой до пятой для функции cos(5πx)

Численное интегрирование

Пусть для функции f(x) известны значения yi=f(xi) в некоторых точках. Тогда можно интерполировать эту функцию методом Лагранжа:

f(x)i=0nf(xi)li(x).

Полученное выражение можно использовать для приближённого вычисления определённого интеграла от функции f:

abf(x)dxi=0nf(xi)abli(x)dx

Значения интегралов от li не зависят от f(x) и их можно вычислить заранее с использованием последовательности xj.

Литература

Ссылки

См. также

Шаблон:Викиучебник