There is no single 'simplest' form; knowing the targeted functions gives you control over the result.
simplify() tries many strategies and returns whatever looks shortest. It is great for exploration, but it is slow and its output form is unpredictable. When you know the shape you want, use a targeted function:
expand(e)multiplies out products and powers:(x + 1)**2becomesx**2 + 2*x + 1.factor(e)does the reverse for polynomials, factoring over the rationals.collect(e, x)groups terms by powers ofx.cancel(e)puts a rational function into the canonical form p/q with common factors removed.apart(e)does partial fraction decomposition.together(e)combines terms over a common denominator.trigsimp,expand_trig,powsimp,logcombinehandle trig, power and log identities.
To test whether two expressions are equal mathematically, check simplify(a - b) == 0. Plain a == b compares tree structure, so (x + 1)**2 == x**2 + 2*x + 1 is False.
Some identities only hold under assumptions. simplify(sqrt(x**2)) stays sqrt(x**2) because for negative or complex x it is not x; declaring the symbol positive changes that.
Example
from sympy import symbols, simplify, expand, factor, collect, cancel, apart, sin, cos
x, y = symbols("x y")
print(expand((x + 1)**2)) # x**2 + 2*x + 1
print(factor(x**3 - x**2 + x - 1)) # (x - 1)*(x**2 + 1)
print(collect(x*y + x - 3 + 2*x**2 - x**2*y, x)) # x**2*(2 - y) + x*(y + 1) - 3
print(cancel((x**2 + 2*x + 1) / (x**2 + x))) # (x + 1)/x
print(apart(1 / (x**2 - 1))) # -1/(2*(x + 1)) + 1/(2*(x - 1))
print(simplify(sin(x)**2 + cos(x)**2)) # 1
a, b = (x + 1)**2, x**2 + 2*x + 1
print(a == b, simplify(a - b) == 0) # False TrueRemember
- simplify is a heuristic; prefer expand, factor, collect, cancel, apart when you know the target
- == is structural equality; use simplify(a - b) == 0 for math equality
Watch out for
- Calling simplify inside loops over large expressions: it can be very slow.