Практика численного кода и выбор метода
Заключительный урок: инженерная гигиена численного кода и карта-памятка для выбора метода под задачу.
Тестирование на известном решении — главный приём проверки численного кода: прогнать метод на задаче с заранее известным точным ответом и убедиться, что ошибка падает с ожидаемым порядком.
Гигиена численного кода
Численный код коварен: он почти никогда не падает с ошибкой — он молча возвращает неверное число. Поэтому к нему нужна особая дисциплина. Несколько правил, выстраданных практикой:
- Тестируй на известных решениях. Прогони интегратор на
∫x² = 1/3, солвер ОДУ наy'=y → eˣ, поиск корня на√2. Если на эталоне неверно — код сломан, и хорошо, что вы это поймали до реальной задачи. - Проверяй порядок сходимости. Измельчи сетку вдвое и убедись, что ошибка упала, как обещает порядок (вчетверо для 2-го, в 16 раз для 4-го). Неверный порядок — сигнал бага.
- Масштабируй данные. Если величины различаются на порядки (метры и нанометры в одной системе), приведи их к сопоставимому масштабу — это улучшает обусловленность и точность.
- Контролируй погрешность, а не доверяй на глаз. Считай невязку, сравнивай два приближения, оценивай порядок — не верь «красивому» числу без проверки.
import math
# Универсальный тест: проверяем ПОРЯДОК сходимости метода на эталоне
def трапеции(f, a, b, n):
h = (b - a) / n
return (f(a)/2 + f(b)/2 + sum(f(a + i*h) for i in range(1, n))) * h
эталон = lambda x: x*x # ∫x² от 0 до 1 = 1/3 (известный ответ!)
точно = 1/3
prev = None
print("проверка порядка сходимости (ждём ~4x за удвоение):")
for n in [8, 16, 32, 64]:
ош = abs(трапеции(эталон, 0, 1, n) - точно)
отношение = (prev / ош) if prev else float('nan')
print(f" n={n:3}: ошибка={ош:.3e} отношение к пред.={отношение:.2f}")
prev = ош
Вывод:
проверка порядка сходимости (ждём ~4x за удвоение): n= 8: ошибка=2.604e-03 отношение к пред.=nan n= 16: ошибка=6.510e-04 отношение к пред.=4.00 n= 32: ошибка=1.628e-04 отношение к пред.=4.00 n= 64: ошибка=4.069e-05 отношение к пред.=4.00
Отношение ошибок ровно 4.00 — это подтверждает второй порядок трапеций. Если бы оно оказалось 2 вместо 4, это кричало бы о баге (например, неверном весе краевых узлов). Такой тест порядка — лучшая страховка численного кода.
Карта выбора метода
Подведём итог всего курса единой таблицей: какой класс задач каким методом решать.
| Задача | Надёжный выбор | Когда быстрее/лучше |
| Корень уравнения, есть отрезок | бисекция (гарантия) | Брент / Ньютон (если есть f') |
| Корень, есть производная | Ньютон (квадратичный) | секущие (без f') |
| Малая плотная СЛАУ | Гаусс с выбором / LU | Холецкий (для SPD) |
| Трёхдиагональная СЛАУ | прогонка O(n) | — |
| Большая разреженная СЛАУ | Зейдель / сопряжённые градиенты | — |
| Кривая через точки | кубический сплайн | Лагранж (мало узлов) |
| Тренд по зашумлённым данным | МНК (регрессия) | — |
| Интеграл, гладкая 1D-функция | Симпсон / адаптивный | Гаусс (макс. точность) |
| Интеграл высокой размерности | Монте-Карло | квази-Монте-Карло |
| ОДУ, обычное | RK4 / адаптивный RK | — |
| ОДУ, жёсткое | неявные (BDF, Radau) | — |
| Главное собственное значение | степенной метод | QR (все λ) |
| Минимум 1D-функции | золотое сечение / Брент | парабол (гладкая) |
Как работает под капотом: главные оси выбора
За всем многообразием стоят несколько универсальных вопросов. Есть ли производная? — если да, Ньютон/градиентные методы быстрее; если нет — бисекция, секущие, золотое сечение. Велика ли и разрежена ли система? — малую решают прямо (Гаусс/LU), большую разреженную — итерационно. Гладкая ли функция? — гладкость позволяет методы высокого порядка (Симпсон, RK4, Гаусс); особенности требуют адаптивности или робастности. Какая размерность? — низкая благоволит сеткам, высокая — Монте-Карло. Хорошо ли обусловлена задача? — плохая обусловленность ограничивает достижимую точность независимо от метода. Держа эти оси в голове, вы выберете инструмент осознанно, а не наугад.
Частые ошибки
- Не тестировать на эталоне. Численный код молча врёт; без проверки на известном решении баги остаются незамеченными до катастрофы.
- Игнорировать порядок сходимости. Если измельчение сетки не даёт ожидаемого падения ошибки — где-то ошибка в реализации.
- Брать «крутой» метод вместо подходящего. Ньютон без производной, RK4 на жёсткой задаче, Монте-Карло в 1D — мощный метод не на своём месте проигрывает простому.
Итоги
- Численный код молча возвращает неверное — тестируйте на задачах с известным точным ответом.
- Проверяйте порядок сходимости: измельчение сетки должно давать предсказанное падение ошибки.
- Масштабируйте данные и контролируйте погрешность явно — не доверяйте числу «на глаз».
- Выбор метода определяют оси: производная, размер/разреженность, гладкость, размерность, обусловленность.