Интегралы: 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² равен 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, получили обратно x². Это и есть основная теорема анализа, связывающая интеграл и производную.
Когда 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. - Под капотом — таблицы, правила и алгоритм Риша (находит ответ либо доказывает его отсутствие).