</>
Тема 1 из 5

Символы и выражения

SymPy — библиотека символьной математики. Обычный Python считает с числами: 2 ** 0.5 — это 1.4142135623730951, приближение. SymPy работает с формулами, как человек на бумаге: √ 2 остаётся корнем из двух, (x + 1)2 можно раскрыть, продифференцировать или решить уравнение — и получить точный ответ.

Символы

Переменные-буквы создают функцией symbols:

from sympy import symbols

x, y = symbols("x y")
e = (x + y) ** 2 - 2 * x * y
print(e)        # -2*x*y + (x + y)**2

e — не число, а выражение: дерево из символов и операций. SymPy сразу делает только очевидные упрощения (складывает числа, объединяет одинаковые слагаемые), а остальное — по вашей команде.

Точные числа

Деление целых чисел в Python даёт дробное число с погрешностью. В SymPy для дробей есть Rational:

from sympy import Rational, sqrt

print(Rational(1, 3) + Rational(1, 6))   # 1/2
print(Rational("3/4") * 2)               # 3/2
print(sqrt(8))                           # 2*sqrt(2)

Осторожно: в выражении x / 3 всё в порядке (символ делится на целое — дробь точная), но x + 1 / 3 сначала посчитает 1 / 3 как обычное число 0.333…. Пишите x + Rational(1, 3).

Приближённое значение точного выражения даёт .evalf() или функция N: sqrt(2).evalf() → 1.41421356237310, N(sqrt(2), 30) — 30 знаков.

Строка → выражение: sympify

Формулу из ввода превращает в выражение функция sympify. Символы создаются автоматически:

from sympy import sympify

e = sympify("x**2 - 3*x + 2")
print(e.free_symbols)    # {x}

Строка записывается по правилам Python: степень — **, умножение — явная *. Целые числа внутри sympify становятся точными, поэтому sympify("1/3") — это дробь 1/3.

Преобразования

from sympy import expand, factor, simplify, symbols
x = symbols("x")

print(expand((x + 1) ** 3))          # x**3 + 3*x**2 + 3*x + 1
print(factor(x ** 2 - 5 * x + 6))    # (x - 3)*(x - 2)
print(simplify((x ** 2 - 1) / (x - 1)))   # x + 1
  • expand — раскрыть скобки;
  • factor — разложить многочлен на множители (с рациональными коэффициентами);
  • simplify — попытаться упростить «как получится»: удобно, но результат не всегда предсказуем. Если нужна конкретная форма, вызывайте конкретную функцию.

SymPy печатает выражения в своём порядке слагаемых и множителей — он одинаков для одинаковых выражений, поэтому результат expand или factor можно сравнивать как строку.

Подстановка: subs

e = x ** 2 + y
print(e.subs(x, 3))                          # y + 9
print(e.subs({x: Rational(1, 2), y: 1}))     # 5/4

subs возвращает новое выражение, исходное не меняется. Если подставить точные числа — получится точный ответ.

Красиво, «в столбик», выражение печатает pprint(e), а latex(e) возвращает запись для LaTeX.

Итог

  • symbols("x y") — символы; выражения из них — формулы, а не числа;
  • Rational(p, q) — точная дробь; .evalf() — приближённое значение;
  • sympify(строка) — выражение из текста;
  • expand, factor, simplify — раскрыть, разложить, упростить;
  • e.subs({x: значение}) — подстановка.