Интегралы: integrate, и почему это сложнее

SymPy берёт интегралы — операцию, обратную производной. Но в отличие от дифференцирования, интегрирование — настоящее искусство, и иногда не получается ни у кого.

integrate — функция SymPy для символьного интегрирования: находит первообразную (неопределённый интеграл) или точное значение определённого интеграла.

Дифференцировать легко, интегрировать трудно

Производная — это «механика»: применяй правила и получишь ответ. Интеграл — обратная задача, и она капризна. Нет универсального алгоритма «по шагам»; нужны догадки, замены переменных, разбиение на части. Хуже того: у многих простых на вид функций (например, e^(−x²) или sin(x)/x) первообразной не существует в элементарных функциях вообще. SymPy здесь — мощный, но не всесильный помощник.

Неопределённые и определённые интегралы

import sympy as sp
x = sp.symbols("x")

# неопределённый интеграл (первообразная, без константы C)
print(sp.integrate(x**2, x))         # x**3/3
print(sp.integrate(sp.cos(x), x))    # sin(x)
print(sp.integrate(1/x, x))          # log(x)

# определённый интеграл (точное значение)
print(sp.integrate(x**2, (x, 0, 1))) # 1/3 — точно, без округления!
print(sp.integrate(sp.exp(-x**2), (x, -sp.oo, sp.oo)))  # sqrt(pi)

Гляньте на последнюю строку: интеграл от гауссова колокола по всей оси SymPy даёт точное √π — то самое значение, которое в разделе про SciPy мы добывали численно. Символьно — это просто sqrt(pi).

Проверим: интеграл — обратная производной

SymPy утверждает, что интеграл от равен x³/3. Проверим фундаментальную связь: если продифференцировать первообразную, вернётся подынтегральная функция. Сделаем это численно на stdlib:

def antideriv(x):
    return x**3 / 3          # первообразная от x^2

# численно дифференцируем первообразную в точке x=2
h = 1e-6
x0 = 2.0
back = (antideriv(x0 + h) - antideriv(x0 - h)) / (2 * h)

print("d/dx [x^3/3] в точке 2 :", round(back, 4))
print("исходная f(x)=x^2 в 2  :", x0**2)

Вывод:

d/dx [x^3/3] в точке 2 : 4.0
исходная f(x)=x^2 в 2  : 4.0

Совпало: продифференцировав первообразную x³/3, получили обратно . Это и есть основная теорема анализа, связывающая интеграл и производную.

Когда SymPy сдаётся

Для функций без элементарной первообразной SymPy может вернуть невычисленный объект Integral или ответ через спецфункции:

import sympy as sp
x = sp.symbols("x")

print(sp.integrate(sp.exp(-x**2), x))    # sqrt(pi)*erf(x)/2 — через erf!
print(sp.integrate(sp.sin(x)/x, x))      # Si(x) — спецфункция "интегральный синус"

Заметьте: SymPy не сдаётся полностью — он выражает ответ через специальные функции (erf, Si), которые мы изучали в разделе про scipy.special. Вот где сходятся две половины курса.

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

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

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

  • Ждать первообразную всегда. Для e^(−x²), sin(x)/x её нет в элементарных функциях — будет ответ через спецфункции или невычисленный Integral.
  • Забыть пределы в определённом интеграле. integrate(f, x) — неопределённый; integrate(f, (x, a, b)) — определённый с пределами в кортеже.
  • Гонять integrate по точкам как численный метод. Если нужно много чисел — выведите формулу один раз и считайте через lambdify/SciPy.

Итог

  • integrate находит первообразную или точное значение определённого интеграла.
  • Интегрирование сложнее дифференцирования: нет универсального алгоритма, иногда первообразной не существует.
  • SymPy выражает «трудные» интегралы через спецфункции (erf, Si) — мост к scipy.special.
  • Под капотом — таблицы, правила и алгоритм Риша (находит ответ либо доказывает его отсутствие).
Проверьте себя
1. Почему интегрирование принципиально сложнее дифференцирования?
AИнтегралы требуют больше памяти
BДифференцирование — механическое применение правил, а интегрирование — поиск без универсального алгоритма; первообразной может вообще не существовать в элементарных функциях
CИнтегралы всегда комплексные
DSymPy не умеет интегрировать
2. Что вернёт sp.integrate(exp(-x**2), x), раз элементарной первообразной нет?
AОшибку
BОтвет через специальную функцию: sqrt(pi)*erf(x)/2
CНоль
DСамо выражение без изменений
3. Что лежит в основе символьного интегрирования в SymPy?
AЧисленные методы трапеций
BТаблицы интегралов, правила и алгоритм Риша (находит первообразную или доказывает её отсутствие)
CМашинное обучение
DСлучайный перебор