Русская Википедия:Интерполяционный многочлен Лагранжа
Интерполяцио́нный многочле́н Лагра́нжа — многочлен минимальной степени, принимающий заданные значения в заданном наборе точек, то есть решающий задачу интерполяции.
Определение
Пусть задана <math>n+1</math> пара чисел <math>(x_0, y_0), (x_1, y_1), \ldots, (x_n, y_n),</math> где все <math>x_j</math> различны. Требуется построить многочлен <math>L(x)</math> степени не более <math>n</math>, для которого <math>L(x_j) = y_j</math>.
Общий случай
Ж. Л. Лагранж предложил следующий способ вычисления таких многочленов:
- <math>L(x) = \sum_{i=0}^n y_i l_i(x),</math>
где базисные полиномы <math>l_i</math> определяются по формуле
- <math>l_i(x)=\prod_{j=0, j\neq i}^{n} \frac{x-x_j}{x_i-x_j} = \frac{x-x_0}{x_i-x_0} \cdots \frac{x-x_{i-1}}{x_i-x_{i-1}} \cdot \frac{x-x_{i+1}}{x_i-x_{i+1}} \cdots \frac{x-x_{n}}{x_i-x_{n}}</math>
Для любого <math>i = 0,\ldots,n</math> многочлен <math>l_i</math> имеет степень <math>n</math> и
- <math> l_i(x_j) = \left\{ \begin{array}{rl} 0, &j \neq i, \\ 1, &j = i. \end{array} \right. </math>
Отсюда следует, что <math>L(x)</math>, являющийся линейной комбинацией многочленов <math>l_i(x)</math>, имеет степень не больше <math>n</math> и <math>L(x_i) = y_i</math>.
Случай равноотстоящих узлов интерполяции
Пусть узлы интерполяции <math>x_j</math> являются равноотстоящими, то есть выражаются через начальную точку <math>x_0</math> и некоторую фиксированную положительную величину <math>h</math> следующим образом:
- <math> x_j = x_0 + jh.</math>
Отсюда следует, что
- <math> x_j - x_i = (j - i)h.</math>
Подставляя эти выражения в формулу для базисного полинома и вынося <math>h</math> за знаки произведения в числителе и знаменателе, получим
- <math>l_j(x) = { \prod_{i=0,\,i \ne j}^n {(x - x_i) \over (x_j - x_i)}} = {\prod\limits_{i=0,\,i \ne j}^n (x - x_0 - ih) \over h^n\prod\limits_{i=0,\,i \ne j}^n (j - i)}</math>
Теперь можно ввести замену переменной
- <math>y = {{x - x_0} \over h}</math>
и получить выражение для базисных полиномов через <math>y</math>, которое строится с использованием только целочисленной арифметики:
- <math>l_j(x) = l_j(x_0 + yh) = (-1)^{n-j} C_n^j \dfrac{y (y-1) \ldots (y-n)}{(y-i) n!}. </math>
Данные величины называются коэффициентами Лагранжа. Они не зависят ни от <math>y_0,\ldots,y_n</math>, ни от <math>h</math> и потому могут быть вычислены заранее и записаны в виде таблиц. Недостатком данного подхода является факториальная сложность числителя и знаменателя, что требует использования длинной арифметики.
Остаточный член
Если считать числа <math>y_0,\ldots,y_n</math> значениями некоторой функции <math>f</math> в узлах <math>x_0,\ldots,x_n</math>, то ошибка интерполирования функции <math>f</math> многочленом <math>L</math> равна
- <math> f(x) - L(x) = \dfrac{f^{(n+1)}(\xi)}{(n+1)!} (x-x_0) \ldots (x-x_n),</math>
где <math>\xi</math> — некоторая средняя точка между наименьшим и наибольшим из чисел <math>x_0,\ldots,x_n</math>. Полагая <math>M_{n+1} = \sup_{x \in [x_0,x_n]} |f^{(n+1)}(x)|</math>, можно записать
- <math> |f(x) - L(x)| \leqslant \dfrac{M_{n+1}}{(n+1)!} |(x-x_0) \ldots (x-x_n)|.</math>
Единственность
Шаблон:Основная статья Существует единственный многочлен степени не превосходящей <math>n</math>, принимающий заданные значения в <math>n+1</math> заданной точке. Шаблон:Доказательство Это утверждение является обобщением того факта, что через любые две точки проходит единственная прямая.
С точки зрения линейной алгебры
На единственность интерполяционного многочлена можно также взглянуть с точки зрения СЛАУ. Рассмотрим систему уравнений <math>P(x_0)=y_0, P(x_1) = y_1, \dots, P(x_n) = y_n</math>. В явном виде она записывается как
- <math>
\begin{cases} a_0 + a_1 x_0 + a_2 x_0^2 + \dots + a_n x_0^n = y_0,\\ a_0 + a_1 x_1 + a_2 x_1^2 + \dots + a_n x_1^n = y_1,\\ \dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots\dots,\\ a_0 + a_1 x_n + a_2 x_n^2 + \dots + a_n x_n^n = y_n\\ \end{cases}</math>
Её можно переписать в виде системы уравнений <math>Xa=y</math> с неизвестным вектором <math> a = (a_0, a_1, \dots, a_n)</math>:
- <math>
\begin{bmatrix} 1 & x_0 & x_0^2 & \dots & x_0^n \\ 1 & x_1 & x_1^2 & \dots & x_1^n \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & x_n & x_n^2 & \dots & x_n^n \\ \end{bmatrix} \begin{bmatrix} a_0 \\ a_1 \\ \vdots \\ a_n \end{bmatrix} = \begin{bmatrix} y_0 \\ y_1 \\ \vdots \\ y_n \end{bmatrix} </math>
Матрица <math>X</math> в такой системе является матрицей Вандермонда и её определитель равен <math>\prod\limits_{i<j}(x_i-x_j)</math>. Соответственно, если все точки <math>x_0, x_1, \dots, x_n</math> различны, то матрица невырождена и система обладает единственным решением.
С точки зрения китайской теоремы об остатках
По теореме Безу остаток от деления <math>P(x)</math> на <math>(x-a)</math> равен <math>P(a)</math>. Таким образом, всю систему можно воспринимать в виде системы сравнений:
- <math>
\begin{cases} P(x) \equiv y_0 \pmod{x-x_0},\\ P(x) \equiv y_1 \pmod{x-x_1},\\ \dots,\\ P(x) \equiv y_n \pmod{x-x_n},\\ \end{cases} </math>
По китайской теореме об остатках у такой системы есть единственное решение по модулю <math>(x-x_0)(x-x_1)\dots(x-x_n)</math>, то есть, заданная система однозначно определяет многочлен степени не выше <math>n</math>. Такое представление многочлена в виде наборов остатков по модулям мономов аналогично представлению числа в виде остатков от деления на простые модули в системе остаточных классов. При этом явная формула для многочлена Лагранжа также может быть получена в соответствии с формулами китайской теоремы: <math display=inline> P(x) = \sum\limits_{i=0}^n y_i M_i M_i^{-1} </math>, где <math>M_i = \prod\limits_{j \neq i} (x-x_j)</math> и <math>M_i^{-1} = \prod\limits_{j \neq i}(x-x_j)^{-1}\pmod{x-x_i}= \prod\limits_{j\neq i}(x_i-x_j)^{-1}</math>.
Пример
Найдем формулу интерполяции для <math>f(x) = \mathop{\mathrm{tg}}\nolimits(x)</math> имеющей следующие значения:
- <math>
\begin{align} x_0 & = -1.5 & & & & & f(x_0) & = -14,1014 \\ x_1 & = -0.75 & & & & & f(x_1) & = -0,931596 \\ x_2 & = 0 & & & & & f(x_2) & = 0 \\ x_3 & = 0.75 & & & & & f(x_3) & = 0,931596 \\ x_4 & = 1.5 & & & & & f(x_4) & = 14,1014. \end{align} </math>
- <math>l_0(x)={x - x_1 \over x_0 - x_1}\cdot{x - x_2 \over x_0 - x_2}\cdot{x - x_3 \over x_0 - x_3}\cdot{x - x_4 \over x_0 - x_4}
={1\over 243} x (2x-3)(4x-3)(4x+3)</math>
- <math>l_1(x) = {x - x_0 \over x_1 - x_0}\cdot{x - x_2 \over x_1 - x_2}\cdot{x - x_3 \over x_1 - x_3}\cdot{x - x_4 \over x_1 - x_4}
= {} -{8\over 243} x (2x-3)(2x+3)(4x-3)</math>
- <math>l_2(x)={x - x_0 \over x_2 - x_0}\cdot{x - x_1 \over x_2 - x_1}\cdot{x - x_3 \over x_2 - x_3}\cdot{x - x_4 \over x_2 - x_4}
={3\over 243} (2x+3)(4x+3)(4x-3)(2x-3) </math>
- <math>l_3(x)={x - x_0 \over x_3 - x_0}\cdot{x - x_1 \over x_3 - x_1}\cdot{x - x_2 \over x_3 - x_2}\cdot{x - x_4 \over x_3 - x_4}
=-{8\over 243} x (2x-3)(2x+3)(4x+3)</math>
- <math>l_4(x)={x - x_0 \over x_4 - x_0}\cdot{x - x_1 \over x_4 - x_1}\cdot{x - x_2 \over x_4 - x_2}\cdot{x - x_3 \over x_4 - x_3}
={1\over 243} x (2x+3)(4x-3)(4x+3).</math>
Получим
- <math> \begin{align}L(x) &= {1\over 243}\Big(f(x_0)x (2x-3)(4x-3)(4x+3) \\
& {} \qquad {} - 8f(x_1)x (2x-3)(2x+3)(4x-3) \\ & {} \qquad {} + 3f(x_2)(2x+3)(4x+3)(4x-3)(2x-3) \\ & {} \qquad {} - 8f(x_3)x (2x-3)(2x+3)(4x+3) \\ & {} \qquad {} + f(x_4)x (2x+3)(4x-3)(4x+3)\Big)\\ & = 4,834848x^3 - 1,477474x. \end{align} </math>
Реализация общего случая на языке программирования 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
Применения
Численное интегрирование
Пусть для функции <math>f(x)</math> известны значения <math>y_i = f(x_i)</math> в некоторых точках. Тогда можно интерполировать эту функцию методом Лагранжа:
- <math>f(x) \approx \sum_{i=0}^n f(x_i) l_i(x).</math>
Полученное выражение можно использовать для приближённого вычисления определённого интеграла от функции <math>f</math>:
- <math>\int\limits_a^b f(x)dx \approx \sum_{i=0}^n f(x_i) \int\limits_a^b l_i(x) dx</math>
Значения интегралов от <math>l_i</math> не зависят от <math>f(x)</math> и их можно вычислить заранее с использованием последовательности <math>x_j</math>.
Литература
- Березин, И. С., Жидков Н. П. Методы вычислений. Том I. — 2-е изд., стереотипное — М.: Физматлит. 1962.
Ссылки
- Шаблон:КнигаШаблон:Недоступная ссылка
- А. Г. Хованский. Полиномы Лагранжа и их применения. Видео-лекция. VI Летняя школа «Современная математика», Дубна, 2006.
См. также
- Схема Эйткена
- Интерполяционные формулы Ньютона
- Интерполяция с кратными узлами
- Схема разделения секрета Шамира
- Комбинаторная теорема о нулях
- Интерполяция алгебраическими многочленами