Численное интегрирование: интерполяция многочленом
Рассмотрим задачу о нахождении интеграла
Приближённо это значение можно определить, приблизив подынтегральную функцию многочленом:
при этом получается следующее приближение для интеграла:
Для построения многочлена нужно определить коэффициентов . Их можно определить, выбрав на точки и составив систему уравнений
которую можно переписать в матричном виде:
Эта система линейных алгебраических уравнений (СЛАУ) содержит уравнение и столько же неизвестных. Если все точки различны, то определитель матрицы этой системы отличен от нуля и она имеет единственное решение. Его можно найти численно, используя, например, LUP-разложение.
По традиции, код для python 2.7:
# coding: utf8
def polynomial(f, a, b, n):
'''
Интегрирование f(x) на [a, b] при помощи
интерполяционного многочлена порядка n
'''
# формируем массив точек для интерполяции
# для простоты рассмотрим равномерное распределение
xs = [a + (b - a) * float(i) / n for i in range(n + 1)]
# формируем матрицу системы и столбец свободных членов
A = [[x ** j for j in range(n + 1)] for x in xs]
B = [f(x) for x in xs]
# определяем коэффициенты многочлена
# пример такой функции описан в статье про LUP-разложение
ps = solve(A, B)
# считаем ответ
return sum(ps[i] * (b ** (i + 1) - a ** (i + 1)) / (i + 1)
for i in range(n + 1))
Вдумчивый читатель может заметить, что если края отрезка интегрирования имеют величину порядка 10, то уже при интерполировании кубическим четырёхчленом в матрице появляются элементы порядка
- В этом случае, с ростом элементы матрицы будут расти экспоненциально, что может привести к существенным неточностям.
Для решения этой проблемы можно воспользоваться преобразованием координат. Пусть
тогда
Так как узлы по модулю не превосходят 1, то при их возведении в степень они не будут возрастать и точность будет выше.