МатВектор

Command Palette

Search for a command to run...

🌊 Диффуры

Как решать жёсткие дифференциальные уравнения

Жёсткие ОДУ: почему явный Эйлер взрывается при h = 0,01, как работает безусловно устойчивый неявный и расчёт для y' = −1000(y − cos t) по шагам.

Сложность: Продвинутый 2 схемы действий

Симуляция химической реакции: константы скоростей различаются в тысячу раз. Вы запускаете численный метод с шагом — и к пятому шагу значения взлетают до , хотя настоящее решение давно вышло на спокойный косинус с амплитудой единица. Уменьшаете шаг в десять раз — счёт растягивается на минуты. Это не глюк программы. Это жёсткость, и у неё есть точный диагноз с лечением.

Жёсткость — свойство задачи, а не метода. Решение содержит компоненты с сильно разными масштабами времени: быстрое затухает за доли секунды, медленное живёт секунды. Формально: собственные значения линейной части различаются по модулю в десятки и сотни раз, . Беда в том, что явным методам шаг диктует самый быстрый процесс — даже когда он давно умер и в решении не участвует.

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

Канонический пример: два масштаба в одном уравнении#

Возьмём задачу, где всё видно руками: , . Это линейное уравнение первого порядка — приёмы решения стандартные. Ищем частное решение вида и подгоняем коэффициенты: при выходит , при — , откуда

A и B — коэффициенты установившегося режима: почти чистый косинус с крошечной добавкой синуса

Честная проверка: подстановка «наивного» оставляет в уравнении остаток при — чистый косинус не решение, нужна поправка . А вот полное семейство подходит:

общее решение: подстановка в уравнение даёт тождество с точностью до 10⁻⁶ — проверено численно

Смотрите, что вышло: переходная добавка умирает за время порядка — уже при от неё остаётся доли. Дальше решение — медленный косинус. Два масштаба времени и , отношение — перед нами жёсткая задача в хрестоматийном виде.

Вывод формулы стоит повторить один раз руками: уравнение приводится к виду , умножение на интегрирующий множитель и интегрирование дают общее решение за пять строк. Проверка подстановкой — вторая строка: производная , подставляем в правую часть и собираем слагаемые — всё сводится к тождеству. Навык проверки точных решений пригодится и при тестировании численных методов: без эталона не отличить устойчивость от точности.

Почему явный Эйлер взрывается#

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

Шаг hМножитель 1 − 1000hЧто происходит
рост в 9 раз за шаг:
граница устойчивости: осцилляции не затухают
переходный режим гасится за один шаг — устойчиво
плавное затухание, но счёт в 20 раз дольше
множители явного Эйлера для λ = −1000: три режима — взрыв, граница, затухание

Вдумайтесь в первую строку: шаг по точности великолепен — решение меняется на масштабе , и такая сетка разрешает его с запасом. Но множитель каждую итерацию растит ошибку в 9 раз; после десяти шагов накопление составило бы миллиарда. Числа в таблице — не мультяшка: прямая прокрутка явного Эйлера с даёт именно .

Пограничные строки таблицы тоже поучительны. При множитель равен : компонента не растёт, но и не умирает — счёт ходит по кругу с чередованием знака, и любой изгиб правой части раскачивает решение дальше. При множитель ноль — «мёртвый» режим: переходная компонента уничтожается одним шагом. Это бывает полезно, когда быструю моду нужно просто выбросить из решения, а не отобразить.

Вот суть жёсткости одним предложением: явный метод обязан шагом обслуживать самый быстрый процесс задачи, даже если тот физически уже закончился. Точность позволила бы , устойчивость запрещает всё, что больше , — и разрыв этот тем страшнее, чем больше отношение масштабов.

Неявный Эйлер: безусловно устойчив#

Лекарство меняет всего одну букву — правая часть берётся в новой точке: . Неизвестное теперь сидит в обеих частях, и для нашего уравнения шаг превращается в решение линейного уравнения:

неявный шаг для y' = −1000(y − cos t); для линейных уравнений формула явная, для общих — метод Ньютона на каждом шаге

Множитель перехода стал : при и это — затухание, причём при любом . Пока , знаменатель по модулю не меньше единицы, и метод гасит все устойчивые компоненты — это называется A-устойчивостью. Плата честная: каждый шаг дороже (уравнение надо решить), но шаг можно брать по точности, а не по выживанию.

Как распознать жёсткость на практике#

  1. Решение резко выходит на плавную кривую: первые проценты времени — переходный слалом, потом штиль.
  2. Явный метод с крупным шагом выдаёт растущие осцилляции без всякого физического смысла — знаки чередуются.
  3. Уменьшение шага лечит взрыв, но счёт становится абсурдно долгим: точность уже давно избыточна.
  4. Типичные источники: химическая кинетика с константами разных порядков, электрические схемы с малыми ёмкостями, полудискретизация УЧП по пространству.

Нюанс: жёсткость бывает локальной по времени. В задаче с включением и выключением источника решение может быть жёстким первые миллисекунды и мягким потом — или наоборот, когда медленный режим теряет устойчивость и рождает быструю релаксацию. Поэтому практичные решатели (LSODA, например) держат обе ветки — явную и неявную — и переключаются сами, следя за якобианом; пользователю остаётся указать задачу и допуски.

Числовой пример: пять шагов неявного Эйлера#

Берём ту же задачу, , , , и крутим формулу . Рядом — точное решение:

tНеявный ЭйлерТочное решение|Ошибка|
—
ошибка затухает примерно в 11 раз за шаг — ровно множитель 1/(1+1000h); расчёт проверен скриптом

Первый шаг грубоват — ошибка : метод «замыливает» резкий старт, это свойство первого порядка. Но дальше ошибка умирает геометрически, и к расхождение — одна стотысячная. Досчитайте до : неявный Эйлер даёт против точного . А явный Эйлер с тем же шагом к этому моменту давно превратил бы задачу в генератор чисел порядка — разница в семь порядков на одном и том же .

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

Что брать в бою#

  1. Оцените спектр: выпишите линейной части или прикиньте отношения констант скоростей.
  2. Прогоните явный метод с автоматическим шагом: если шаг упёрся в нижний предел — диагноз жёсткость подтверждён.
  3. Переключитесь на неявный: в SciPy это solve_ivp с method='Radau' (неявный Рунге–Кутта) или 'BDF' (формулы разной кратности); LSODA переключается сам, в MATLAB стандарт — ode15s.
  4. Проверьте на модельной задаче с известным решением: наш пример с для этого идеален.
  5. Контроль: уменьшите допуск и убедитесь, что решение меняется в пятом знаке, а не в третьем.
Проверь себя+15 XP

Явный Эйлер, задача , шаг . Во сколько раз меняется переходная компонента за один шаг?

Проверь себя+15 XP

Какой максимальный шаг допускает явный Эйлер для этой задачи по устойчивости?

Частые вопросы

Жёсткое уравнение — это всегда нелинейное?

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

Чем неявный Эйлер отличается от явного по затратам?

Один явный шаг — одно вычисление правой части. Один неявный шаг — решение уравнения относительно : для линейной задачи формула, для нелинейной — 2–3 итерации Ньютона с якобианом. Зато шаг неявный метод позволяет взять в сотни раз больше, и итог быстрее на порядки: выгодность определяет устойчивость, а не цена одного шага.

Что такое A-устойчивость простыми словами?

Метод A-устойчив, если его область устойчивости покрывает всю левую полуплоскость: любая компонента с не растёт при каком угодно шаге. У неявного Эйлера множитель по модулю не превышает единицы ровно на этой полуплоскости. Практический смысл: шаг выбирается только из точности, устойчивость перестаёт быть ограничением.

Какой метод выбрать в Python для жёсткой системы?

Первый заход — solve_ivp с method='Radau': неявный Рунге–Кутта пятого порядка с оценкой ошибки. BDF хорош, когда правая часть дешёвая, а решение гладкое, — формулы разной кратности экономят вычисления. LSODA сам детектирует жёсткость и переключается между явной и неявной ветками — удобен, если жёсткость появляется лишь на части интервала. Явные Рунге–Кутты (RK45) для жёстких задач не годятся по определению.

Куда дальше: механика явного шага и его погрешности — в уроке о методе Эйлера, общая теория того, почему решения растут или умирают, — в устойчивости решений. Численная кухня целиком — в численном решении ОДУ, откуда берутся ошибки — в источниках погрешностей. Формулы под рукой — шпаргалка по дифференциальным уравнениям; тренировка — тренажёр по дифурам и тренажёр численных методов. Общий маршрут по теме — в гайде как решать дифференциальные уравнения и задачах с решениями.