Что такое SymPy: точное против приближённого
До сих пор мы считали числа приближённо. SymPy умеет иначе — работать с точными формулами, как математик с ручкой.
SymPy — библиотека символьной (компьютерной) алгебры: она оперирует не числами, а математическими выражениями, давая точные ответы вроде √2, π/4, sin(x).
Две вселенные: число и символ
Когда вы пишете в обычном Python import math; math.sqrt(2), получаете 1.4142135623730951 — приближение из 17 цифр. Корень из двух иррационален, точно его в float не записать. SymPy идёт другим путём: для него √2 — это объект «корень из двойки», точный, без потери цифр. Возведите его в квадрат — получите ровно 2, а не 2.0000000000000004.
| Аспект | Численно (SciPy) | Символьно (SymPy) |
| √2 | 1.4142135623730951 | sqrt(2) — точно |
| 1/3 | 0.3333333333333333 | 1/3 — точная дробь |
| Производная x² | нет понятия | 2·x — формула |
| Скорость | очень быстро | медленно |
Зачем это нужно
Символьная математика делает то, что раньше требовало математика с бумагой: выводит формулы, берёт производные и интегралы, решает уравнения «в буквах», упрощает громоздкие выражения. Результат — не число, а формула, в которую потом можно подставить любые значения. Это бесценно, когда нужна точность (криптография, теория чисел), вывод аналитических зависимостей или проверка ручных выкладок.
Точные дроби — это умеет даже stdlib
Чтобы прочувствовать идею «точно, а не приближённо», начнём с того, что есть прямо в Python — модуль fractions. Сложим 1/10 + 2/10 точно:
from fractions import Fraction
a = Fraction(1, 10)
b = Fraction(2, 10)
print("Точно :", a + b) # 3/10, без округления
# а вот как это выглядит в обычном float:
print("Приближ.:", 0.1 + 0.2) # 0.30000000000000004
Вывод:
Точно : 3/10 Приближ.: 0.30000000000000004
Видите разницу? float дал 0.30000...004 вместо ровного 0.3 — накопилась ошибка округления (0.1 и 0.2 не представимы точно в двоичной системе). Fraction хранит числитель и знаменатель целыми и считает точно. SymPy делает то же самое, но не только с дробями, а с любыми математическими выражениями — переменными, функциями, корнями.
Как выглядит SymPy
В SymPy выражения строятся из символов (код для чтения, в браузере не исполняется — нужна сторонняя библиотека):
import sympy as sp
x = sp.Symbol("x")
expr = (x + 1)**2
print(sp.expand(expr)) # x**2 + 2*x + 1 — раскрыли скобки точно
print(sp.sqrt(8)) # 2*sqrt(2) — упростил корень точно
print(sp.Rational(1, 3) + sp.Rational(1, 6)) # 1/2
Как работает под капотом
SymPy представляет каждое выражение как дерево. Запись x**2 + 2*x + 1 внутри — это узел «сложение» с тремя ветвями: «x в степени 2», «2 умножить на x» и «1». Любая операция (упрощение, дифференцирование) — это обход и перестройка этого дерева по правилам математики. Числа SymPy хранит как точные объекты: целые произвольной длины, рациональные дроби, символические константы (π, e). Именно поэтому SymPy медленный — он не считает в «железных» float, а манипулирует структурами в памяти Python. Зато не теряет ни бита точности.
Когда что брать
- SymPy — вывести формулу, взять производную/интеграл «в буквах», решить уравнение точно, проверить выкладки.
- SciPy/NumPy — посчитать много чисел быстро, обработать данные, симуляции.
- Часто их связывают: SymPy выводит формулу,
lambdifyпревращает её в быструю численную функцию (об этом — позже).
Частые ошибки
- Ждать от SymPy скорости NumPy. Символьные вычисления на порядки медленнее — не гоняйте их в циклах по миллиону точек.
- Писать
1/3вместоRational(1,3). Обычное деление в Python даст float и «заразит» всё выражение приближением. - Путать символ и переменную Python.
x = Symbol('x')создаёт математический символ; имя переменной Python и имя символа — разные вещи.
Итог
- SymPy работает с точными формулами, а не приближёнными числами.
- √2, 1/3, производная — для SymPy это точные объекты, а не float.
- Идею «точно» демонстрирует даже stdlib-модуль
fractions. - Под капотом — деревья выражений; цена точности — скорость.