Series approximations drive physics and numerical-analysis derivations and explain limiting behaviour.
series(expr, x, x0, n) (or expr.series(x, x0, n)) expands expr around x0 up to, but not including, order n. The default is around 0 with n=6. The result ends with an order term such as O(x**6), which represents all neglected higher-order terms.
The order term is a real object with arithmetic rules: O(x**2) + x**3 simplifies to O(x**2), and multiplying series keeps track of what is still accurate. Call .removeO() to drop it and get a plain polynomial you can lambdify or compare.
Expansions are not only Taylor series:
- Around a pole you get a Laurent series with negative powers, e.g.
1/sin(x). - Around infinity,
series(f, x, oo, n)gives an asymptotic expansion in powers of1/x. - Around a nonzero point, the result is written in powers of
(x - x0), shown asO((x - x0)**n, (x, x0)).
The n argument counts orders of the expansion variable, not number of terms: series(cos(x), x, 0, 6) returns terms up to x**4 because the odd powers vanish.
For the coefficient of one specific power, expr.series(x, 0, n).removeO().coeff(x, k) is simple and clear. For lazy generation of terms one at a time, use expr.lseries(x).
Example
from sympy import symbols, series, sin, cos, exp, sqrt, oo, O
x = symbols("x")
print(series(exp(x), x, 0, 4)) # 1 + x + x**2/2 + x**3/6 + O(x**4)
print(cos(x).series(x, 0, 6)) # 1 - x**2/2 + x**4/24 + O(x**6)
print(series(1 / sin(x), x, 0, 4)) # 1/x + x/6 + 7*x**3/360 + O(x**4)
print(series(sqrt(x**2 + 1) - x, x, oo, 4)) # -1/(8*x**3) + 1/(2*x) + O(x**(-4), (x, oo))
print(O(x**2) + x**3) # O(x**2)
p = sin(x).series(x, 0, 8).removeO()
print(p) # -x**7/5040 + x**5/120 - x**3/6 + x
print(p.coeff(x, 5)) # 1/120Remember
- series(f, x, x0, n) expands up to order n, ending in O(...)
- removeO() drops the order term to get a usable polynomial
- Expansions around poles and infinity give Laurent and asymptotic series
Watch out for
- Treating n as a number of nonzero terms rather than the order cutoff.