Локальная и глобальная ошибка метода Эйлера

«Метод Эйлера имеет первый порядок точности» — фраза из любого учебника. Но что это значит на практике? Что ошибка ведёт себя как h в первой степени: уменьшили шаг вдвое — уменьшили ошибку вдвое. Сейчас мы это не просто объявим, а измерим в эксперименте и поймём, откуда берётся противоречие между ошибкой одного шага и ошибкой всего расчёта.

Порядок метода — показатель p в оценке глобальной ошибки C·h⁰: чем выше порядок, тем быстрее падает погрешность при измельчении шага. У метода Эйлера p = 1 (первый порядок).

Две разные ошибки

Когда говорят про точность численного метода, всегда нужно уточнять: ошибка одного шага или ошибка всего расчёта. Это разные вещи, и их легко перепутать.

Локальная ошибка усечения — насколько мы промахиваемся за один шаг, если стартовали из точного значения. Мы уже видели в прошлом уроке: разложение точного решения по Тейлору даёт y(t_n + h) = y_n + h·y'_n + (h²/2)·y''(ξ), а метод Эйлера оставляет только первые два члена. Значит, за один шаг мы отбрасываем член порядка . Локальная ошибка — это O(h²).

Глобальная ошибка — насколько численное решение отличается от точного в конце расчёта, после всех шагов, с учётом того, что ошибки накапливаются. И вот здесь происходит понижение на единицу: глобальная ошибка оказывается O(h), первый порядок.

Как работает под капотом: куда девается одна степень h

Логика простая и стоит того, чтобы её прочувствовать. Пусть мы решаем задачу на фиксированном отрезке [t0, T] длины L = T - t0. Сколько шагов мы сделаем? N = L / h штук. Чем мельче шаг, тем больше шагов.

На каждом шаге мы добавляем локальную ошибку порядка . Если бы ошибки просто складывались, общая накопленная погрешность была бы примерно:

(число шагов) × (ошибка одного шага)
  = N · O(h²)
  = (L / h) · O(h²)
  = L · O(h)
  = O(h)

Вот оно: множитель 1/h от числа шагов «съедает» одну степень h из локальной ошибки. Было на шаг — стало h на весь расчёт. Поэтому говорят: глобальная ошибка на единицу хуже локальной. (Строгое доказательство учитывает ещё и то, что ранние ошибки подрастают по ходу расчёта, но итоговая оценка та же — O(h).)

Почему ошибка накапливается, а не гасится

Можно было бы понадеяться: вдруг ошибки разных знаков и они взаимно сократятся? Для метода Эйлера на гладких задачах этого обычно не происходит. Промахи систематичны: на выпуклом решении метод всё время отстаёт, на вогнутом — всё время опережает, ошибки одного знака и складываются. Хуже того, каждый шаг стартует уже из ошибочной точки, и эта ошибка тащится дальше и подрастает. Поэтому к концу длинного расчёта погрешность максимальна — мы это видели в таблице прошлого урока, где ошибка росла от 0.005 до 0.12.

Измеряем порядок в эксперименте

Хватит теории — проверим формулу O(h) руками. Идея эксперимента: решить одну и ту же задачу y' = y, y(0) = 1 на отрезке [0, 1] несколько раз, каждый раз уменьшая шаг вдвое, и посмотреть на ошибку в конечной точке. Точное значение там — math.exp(1), то есть число e ≈ 2.71828.

Если порядок и правда первый, то при делении h пополам ошибка должна падать примерно вдвое, и отношение соседних ошибок будет стремиться к 2.

import math

def euler_final(f, t0, y0, h, n):
    """Возвращает только конечное значение после n шагов."""
    t, y = t0, y0
    for _ in range(n):
        y = y + h * f(t, y)
        t = t + h
    return y

f = lambda t, y: y
exact = math.exp(1.0)   # точное решение в t = 1

print(f"{'h':>8} {'N':>4} {'y(1) chisl':>12} {'oshibka':>12} {'otnosh':>10}")
prev_err = None
for h in [0.1, 0.05, 0.025, 0.0125]:
    n = round(1.0 / h)                 # число шагов до t = 1
    y = euler_final(f, 0.0, 1.0, h, n)
    err = abs(exact - y)
    ratio = '-' if prev_err is None else f"{prev_err / err:.3f}"
    print(f"{h:8.4f} {n:4d} {y:12.6f} {err:12.6f} {ratio:>10}")
    prev_err = err

Вывод:

       h    N   y(1) chisl      oshibka     otnosh
  0.1000   10     2.593742     0.124539          -
  0.0500   20     2.653298     0.064984      1.916
  0.0250   40     2.685064     0.033218      1.956
  0.0125   80     2.701485     0.016797      1.978

Смотрите на последний столбец: отношения 1.916, 1.956, 1.978 — и с каждым измельчением они всё ближе к двойке. Это и есть экспериментальное доказательство первого порядка. Половиним шаг — ошибка падает в (почти) два раза. Если бы метод был второго порядка, отношение стремилось бы к 4; третьего — к 8.

Заодно виден неприятный вывод: чтобы получить ещё один верный десятичный знак (ошибку в 10 раз меньше), методу Эйлера нужно уменьшить шаг в 10 раз, то есть сделать в 10 раз больше работы. Это очень дорого. Именно поэтому в реальных задачах применяют методы повыше порядком — там для лишнего знака точности шаг нужно уменьшить всего вчетверо (для второго порядка) или ещё меньше. К таким методам мы перейдём в конце раздела.

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

Путают локальный и глобальный порядок. Локальная ошибка Эйлера — O(h²), но это не порядок метода. Порядком называют показатель именно глобальной ошибки, он на единицу меньше — O(h). Сравнивать методы нужно по глобальному порядку.

Меняют шаг, но забывают пересчитать число шагов. Чтобы дойти ровно до t = 1, при h = 0.05 нужно 20 шагов, при h = 0.025 — 40. Если оставить число шагов прежним, вы будете сравнивать ошибки в разных точках — и никакой закономерности не увидите. В коде n = round(1.0 / h) следит за этим.

Ждут идеального отношения ровно 2. Оценка O(h) асимптотическая — она точна в пределе h -> 0. При конечных h есть поправки высших порядков, поэтому отношение лишь приближается к 2 снизу. Видеть 1.92 вместо 2.00 — это норма, а не баг.

Уменьшают шаг до экстремально малого. При очень маленьком h число операций огромно, и ошибка округления float начинает доминировать над ошибкой метода. Отношения «поплывут». У точности есть практический предел снизу.

  • Локальная ошибка усечения (промах за один шаг из точной точки) у метода Эйлера — O(h²).
  • Глобальная ошибка (промах в конце расчёта) — O(h): число шагов N = L/h «съедает» одну степень h.
  • Порядок метода определяют по глобальной ошибке, поэтому Эйлер — метод первого порядка.
  • Ошибки систематичны и одного знака, поэтому накапливаются и растут к концу расчёта.
  • Эксперимент: деление h вдвое уменьшает ошибку вдвое (отношение стремится к 2) — это и есть подпись первого порядка.
  • Получить лишний знак точности дорого: нужно в 10 раз больше шагов — мотив переходить к методам высшего порядка.
Проверьте себя
1. Каков порядок глобальной ошибки метода Эйлера?
AO(h²) — второй порядок
BO(h) — первый порядок
CO(h³) — третий порядок
DO(1) — не зависит от h
2. В эксперименте при делении шага h вдвое глобальная ошибка уменьшилась примерно в 2 раза (отношение ~1.95). О чём это говорит?
AО том, что метод имеет второй порядок
BОб ошибке в коде — отношение должно быть ровно 1
CО первом порядке метода: ошибка пропорциональна h в первой степени
DО накоплении ошибок округления float
3. Почему глобальный порядок на единицу хуже локального?
AИз-за ошибок округления, которые добавляют одну степень h
BПотому что число шагов N = L/h обратно пропорционально h и умножает локальную ошибку O(h²) на 1/h
CПотому что f(t, y) вычисляется приближённо
DЭто случайное совпадение, верное только для y' = y
4. Сколько примерно дополнительной работы нужно методу Эйлера, чтобы получить лишний верный десятичный знак (ошибку в 10 раз меньше)?
AУменьшить шаг вдвое — то есть вдвое больше шагов
BУменьшить шаг в 10 раз — то есть примерно в 10 раз больше шагов
CУменьшить шаг в √10 раз
DТочность от числа шагов не зависит