Интерполяцио́нный многочле́н Лагра́нжа — многочлен минимальной степени, принимающий заданные значения в заданном наборе точек, то есть решающий задачу интерполяции.
Пусть узлы интерполяции являются равноотстоящими, то есть выражаются через начальную точку и некоторую фиксированную положительную величину следующим образом:
Отсюда следует, что
Подставляя эти выражения в формулу для базисного полинома и вынося за знаки произведения в числителе и знаменателе, получим
Теперь можно ввести замену переменной
и получить выражение для базисных полиномов через , которое строится с использованием только целочисленной арифметики:
Данные величины называются коэффициентами Лагранжа. Они не зависят ни от , ни от и потому могут быть вычислены заранее и записаны в виде таблиц. Недостатком данного подхода является факториальная сложность числителя и знаменателя, что требует использования длинной арифметики.
Существует единственный многочлен степени не превосходящей , принимающий заданные значения в заданной точке.
Доказательство
Предположим, что существуют два различных многочлена и степени не более , для которых верно, что для пар чисел где все различны, Рассмотрим многочлен . Подставляя в него (), получаем, что . Таким образом, многочлен имеет корней и все они различны. Следовательно , так как ненулевой многочлен степени не превосходящей имеет не более корней. Следовательно, . ■
Это утверждение является обобщением того факта, что через любые две точки проходит единственная прямая.
На единственность интерполяционного многочлена можно также взглянуть с точки зрения СЛАУ. Рассмотрим систему уравнений . В явном виде она записывается как
Её можно переписать в виде системы уравнений с неизвестным вектором :
Матрица в такой системе является матрицей Вандермонда и её определитель равен . Соответственно, если все точки различны, то матрица невырождена и система обладает единственным решением.
По теореме Безу остаток от деления на равен . Таким образом, всю систему можно воспринимать в виде системы сравнений:
По китайской теореме об остатках у такой системы есть единственное решение по модулю , то есть, заданная система однозначно определяет многочлен степени не выше . Такое представление многочлена в виде наборов остатков по модулям мономов аналогично представлению числа в виде остатков от деления на простые модули в системе остаточных классов. При этом явная формула для многочлена Лагранжа также может быть получена в соответствии с формулами китайской теоремы:
, где и .
importnumpyasnp# данные для примераxi=np.array([-1.5,-0.75,0,0.75,1.5])yi=np.array([-14.1014,-0.931596,0,0.931596,14.1014])defget_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)foriinrange(n):ifi==_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=0foriinrange(n):ifcoefficients[i][0]!=float('inf'):# изменение последовательности, степень увеличиваетсяfiltered_coefficients[j][0]=coefficients[i][1]filtered_coefficients[j][1]=coefficients[i][0]j+=1returnfiltered_coefficientsdefget_polynomial_l(_xi:np.ndarray):''' Определение базисных полиномов :param _xi: массив значений x :return: '''n=int(_xi.shape[0])pli=np.zeros((n,n),dtype=float)forplinrange(n):coefficients=get_coefficients(pl,_xi)foriinrange(1,n-1):# проходим по массиву coefficientsifi==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)forvalinrange(n):clone_pli[val]=pli[pl][val]zeros_pli=np.zeros(n,dtype=float)forjinrange(n-1):# проходим по строке pl массива pliproduct_1=clone_pli[j]*coefficients[i][0]product_2=clone_pli[j]*coefficients[i][1]zeros_pli[j]+=product_1zeros_pli[j+1]+=product_2forvalinrange(n):pli[pl][val]=zeros_pli[val]returnplidefget_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)foriinrange(n):forjinrange(n):polynomial_l[i][j]*=_yi[i]L=np.zeros(n,dtype=float)foriinrange(n):forjinrange(n):L[i]+=polynomial_l[j][i]returnL# результат в виде массива коэффициентов многочлена при x в порядке увеличения степени# [ 0. -1.47747378 0. 4.8348476 0. ]# т.е. результирующий многочлен имеет вид: y(x) = -1.47747378*x + 4.8348476*x^3