Дифуравнения символьно: dsolve

В разделе про SciPy мы решали дифуры численно — траекторией из точек. SymPy решает их символьно, выдавая точную формулу решения.

dsolve — функция SymPy для символьного решения дифференциальных уравнений: возвращает решение в виде формулы y(x) = ....

Численно vs символьно: две картины

Численный solve_ivp из SciPy даёт числа: «при t=2 величина равна 36.79». Символьный dsolve даёт формулу: «y(t) = C·e^(−0.5t)». Формула мощнее: в неё можно подставить любое t, проанализировать поведение, продифференцировать. Но символьно решаются далеко не все дифуры — только определённые типы.

Решаем радиоактивный распад символьно

То самое уравнение y' = −k·y из урока про ОДУ. Численно мы получали приближение; символьно — точную экспоненту:

import sympy as sp

t = sp.symbols("t")
k = sp.symbols("k", positive=True)
y = sp.Function("y")

# уравнение y'(t) = -k * y(t)
eq = sp.Eq(y(t).diff(t), -k * y(t))
solution = sp.dsolve(eq, y(t))
print(solution)        # Eq(y(t), C1*exp(-k*t))

# с начальным условием y(0) = 100:
sol_ic = sp.dsolve(eq, y(t), ics={y(0): 100})
print(sol_ic)          # Eq(y(t), 100*exp(-k*t))

SymPy вывел точное решение y(t) = 100·e^(−kt) — ту самую формулу, которую численный метод лишь приближал. Теперь её можно вычислить в любой точке без накопления ошибок.

Проверим формулу численно «руками»

SymPy утверждает: решение y' = −0.5y, y(0)=100 — это y(t) = 100·e^(−0.5t). Проверим, что эта формула и впрямь удовлетворяет уравнению (производная равна −0.5·y) на чистом Python:

import math

def y(t):
    return 100 * math.exp(-0.5 * t)

# численно дифференцируем формулу в точке t=3
h = 1e-6
t0 = 3.0
y_prime = (y(t0 + h) - y(t0 - h)) / (2 * h)

print("y'(3) численно :", round(y_prime, 6))
print("-0.5 * y(3)    :", round(-0.5 * y(t0), 6))
print("Совпадают?     :", abs(y_prime - (-0.5 * y(t0))) < 1e-4)

Вывод:

y'(3) численно : -11.156508
-0.5 * y(3)    : -11.156508
Совпадают?     : True

Формула удовлетворяет уравнению: производная решения равна −0.5·y в каждой точке. SymPy не просто угадал — он вывел и доказал решение.

Что dsolve умеет и не умеет

Тип уравненияdsolve
Линейные с постоянными коэффициентамирешает всегда
Разделяющиеся переменныеобычно решает
Многие классические типы (Бернулли, Риккати…)часто решает
Произвольные нелинейныечасто не может — нужен численный метод

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

dsolve работает как умный «классификатор»: он распознаёт тип уравнения (разделяющиеся переменные, линейное, однородное, точное и т.д.) и применяет соответствующий известный метод решения из учебника по дифурам. Для каждого типа есть свой алгоритм: для линейных с постоянными коэффициентами — характеристическое уравнение, для разделяющихся — интегрирование обеих частей. Если ни один распознанный тип не подходит, SymPy честно сообщает, что решить символьно не может. Это фундаментально: большинство «реальных» нелинейных дифуров не имеют решения в замкнутой форме вообще — для них существует только численный путь (SciPy solve_ivp).

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

  • Забыть Function. Неизвестная функция объявляется через y = Function("y"), а в уравнении пишется y(t), а не просто y.
  • Ждать решения для любого дифура. Большинство нелинейных уравнений символьно не решаются — это нормально, переходите к численному методу.
  • Путать C1 с числом. Без начальных условий решение содержит произвольные константы; задайте ics, чтобы их определить.

Итог

  • dsolve решает дифуравнения символьно — выдаёт формулу y(x)=..., а не числа.
  • Начальные условия задаются через ics, определяя константы.
  • Работает для распознаваемых типов (линейные, разделяющиеся и др.); произвольные нелинейные — численно.
  • Формула мощнее траектории: точна в любой точке, поддаётся анализу.
Проверьте себя
1. Чем результат dsolve отличается от результата численного solve_ivp?
AНичем
Bdsolve даёт точную ФОРМУЛУ решения y(x)=…, а solve_ivp — приближённую траекторию из чисел
Cdsolve быстрее
Dsolve_ivp точнее
2. Как dsolve решает дифференциальное уравнение?
AЧисленным интегрированием
BРаспознаёт ТИП уравнения (линейное, разделяющееся и т.д.) и применяет соответствующий известный метод; если тип не распознан — не решает
CПеребором формул
DМашинным обучением
3. Что означает C1 в выводе dsolve без начальных условий?
AОшибку
BПроизвольную константу интегрирования; чтобы её определить, задают начальные условия через ics
CПервый корень
DКоэффициент уравнения