Разделённые разности Ньютона

Урок про форму Ньютона интерполяционного полинома — гибкую альтернативу Лагранжу, удобную для наращивания узлов.

Форма Ньютона записывает интерполяционный полином как P(x) = c₀ + c₁(x−x₀) + c₂(x−x₀)(x−x₁) + ..., где коэффициенты c_kразделённые разности.

Идея: строить полином по нарастающей

Полином через узлы — тот же самый, что у Лагранжа (он единственный), но форма записи другая. Ньютон складывает его из слагаемых, каждое из которых добавляет один узел и не портит совпадение в предыдущих. Первое слагаемое — константа c₀ = y₀. Второе — c₁(x−x₀): оно зануляется в x₀ (там уже всё верно) и подправляет значение в x₁. Третье — c₂(x−x₀)(x−x₁): зануляется в x₀ и x₁, подправляет x₂. И так далее. Главный плюс: добавили узел — дописали одно слагаемое, ничего не пересчитывая.

Разделённые разности

Коэффициенты c_k — это разделённые разности, рекурсивный аналог производных по таблице. Разность нулевого порядка — само значение f[x_i] = y_i. Первого — f[x_i,x_{i+1}] = (f[x_{i+1}] − f[x_i])/(x_{i+1} − x_i) (наклон). Каждая следующая строится из двух соседних предыдущего порядка. Удобно считать на месте в одном массиве.

def разделённые_разности(xs, ys):
    n = len(xs)
    c = ys[:]                       # начнём с y-значений
    for j in range(1, n):
        # пересчёт справа налево, чтобы не затереть нужное
        for i in range(n - 1, j - 1, -1):
            c[i] = (c[i] - c[i - 1]) / (xs[i] - xs[i - j])
    return c                        # c[k] — коэффициенты полинома Ньютона

def ньютон_значение(xs, c, x):
    # схема Горнера: P(x) = (...((c_n)(x-x_{n-1}) + c_{n-1})...)
    n = len(xs)
    результат = c[-1]
    for i in range(n - 2, -1, -1):
        результат = результат * (x - xs[i]) + c[i]
    return результат

xs = [0.0, 1.0, 2.0]
ys = [1.0, 3.0, 2.0]
c = разделённые_разности(xs, ys)
print("коэффициенты Ньютона:", [round(v, 4) for v in c])
print(f"P(0.5) = {ньютон_значение(xs, c, 0.5):.6f}")
print(f"P(1.5) = {ньютон_значение(xs, c, 1.5):.6f}")
# совпадает ли с Лагранжем из прошлого урока? Должно — полином один!
print("в узлах:", [round(ньютон_значение(xs, c, t), 4) for t in xs])

Вывод:

коэффициенты Ньютона: [1.0, 2.0, -1.5]
P(0.5) = 2.375000
P(1.5) = 2.875000
в узлах: [1.0, 3.0, 2.0]

Те же P(0.5)=2.375 и P(1.5)=2.875, что у Лагранжа — потому что полином через эти узлы единственный. Различается лишь форма записи и удобство.

Таблица разделённых разностей

На бумаге разделённые разности удобно строить «лесенкой»: в первом столбце — значения y, в каждом следующем — разности соседних элементов предыдущего, делённые на разность соответствующих x. Коэффициенты полинома — верхняя диагональ таблицы.

x_i  f[x_i]   f[.,.]    f[.,.,.]
 0    1
              (3-1)/(1-0)=2
 1    3                 (-1-2)/(2-0)=-1.5
              (2-3)/(2-1)=-1
 2    2
коэффициенты P: c0=1, c1=2, c2=-1.5  (верхняя диагональ)

Как работает под капотом

Вычисление полинома ведут по схеме Горнера — она минимизирует число умножений и численно устойчива: P(x) = ((c₂)(x−x₁) + c₁)(x−x₀) + c₀. Разделённые разности симметричны относительно перестановки узлов, поэтому порядок узлов на итоговый полином не влияет (хотя на численную устойчивость промежуточных вычислений — немного влияет). Связь с производными прямая: k-я разделённая разность равна f^{(k)}(ξ)/k! в некоторой точке ξ — поэтому форма Ньютона так похожа на ряд Тейлора, только «по узлам».

Частые ошибки

  • Затирать массив при пересчёте. Внутренний цикл по i идёт справа налево, иначе обновлённые значения испортят ещё не использованные.
  • Считать, что Ньютон точнее Лагранжа. Полином тот же; разница только в форме и инкрементности, а не в точности.
  • Вычислять полином «в лоб» по степеням. Раскрытие скобок теряет точность; используйте схему Горнера по форме Ньютона.

Итоги

  • Форма Ньютона: полином как сумма слагаемых, каждое добавляет один узел и не портит предыдущие.
  • Коэффициенты — разделённые разности, считаются рекурсивно одним проходом по таблице.
  • Инкрементность: новый узел = одно новое слагаемое без пересчёта; вычисление — по схеме Горнера.
  • Итоговая кривая совпадает с Лагранжевой — полином через узлы единственный.
Проверьте себя
1. Чему равна разделённая разность нулевого порядка f[x_i]?
Aпроизводной f в x_i
Bсамому значению y_i
Cнулю
D(y_i + y_{i+1})/2
2. Главное преимущество формы Ньютона перед формой Лагранжа:
Aона точнее
Bпри добавлении нового узла дописывается одно слагаемое без полного пересчёта
Cона не требует деления
Dона даёт другой, лучший полином
3. Почему форма Ньютона даёт тот же результат, что и Лагранж в тех же узлах?
AЭто совпадение
BИнтерполяционный полином через данные узлы единственен — отличается лишь форма записи
CНьютон округляет к Лагранжу
DОни совпадают только в узлах, между — нет