Tutorial 8
Click the badges above to run this tutorial interactively in your browser without installing anything!
- Binder: Free cloud-based Jupyter environment
- Colab: Google's free Jupyter notebook environment
Topics Covered
This tutorial covers the following topics using Python and SymPy:
- Integration by parts
- Partial fractions
- Trigonometric integrals
- Trigonometric substitution
- Verifying an antiderivative by differentiating it back
Introduction
integrate(f, x) returns an antiderivative of f with respect to x. Because an
antiderivative is only defined up to an additive constant, SymPy's answer may look
different from the printed solution while still being correct. The reliable check is
always the same: differentiate the answer and see whether you get the integrand back.
import sympy as sy
from sympy.abc import x, t, u
from sympy import (sqrt, sin, cos, tan, sec, csc, cot, pi, ln, log, exp, atan, asin,
apart, integrate, diff, simplify, expand, Symbol)
sy.init_printing(use_latex=True)
def check(F, f):
"""Differentiate the antiderivative F and compare with the integrand f."""
return simplify(diff(F, x) - f)
Question 1
res = integrate(ln(x**2 + 2), x)
display(res) # x*log(x^2+2) - 2*x + 2*sqrt(2)*atan(sqrt(2)*x/2)
display(check(res, ln(x**2 + 2))) # 0 -> correct
Rearranging gives .
Question 2
res = integrate(x**2*ln(x), x)
display(res) # x**3*(3*log(x) - 1)/9
display(check(res, x**2*ln(x))) # 0
Question 3
res = integrate(x**3*exp(x**2), x)
display(res) # (x**2 - 1)*exp(x**2)/2
display(check(res, x**3*exp(x**2))) # 0
Question 4
Partial fractions first, then integrate term by term.
f = (x + 1)/(x**3 + x**2 - 6*x)
display(sy.factor(x**3 + x**2 - 6*x)) # x*(x - 2)*(x + 3)
display(apart(f, x)) # -2/(15*(x+3)) + 3/(10*(x-2)) - 1/(6*x)
display(integrate(f, x))
Question 5
f = (x**3 + x**2 + x + 2)/(x**4 + 3*x**2 + 2)
display(sy.factor(x**4 + 3*x**2 + 2)) # (x**2 + 1)*(x**2 + 2)
display(apart(f, x)) # x/(x**2 + 2) + 1/(x**2 + 1)
display(integrate(f, x)) # log(x**2 + 2)/2 + atan(x)
Question 6
f = tan(3*x)**3*sec(3*x)**4
res = integrate(f, x)
display(res)
display(check(res, f)) # 0
SymPy returns , which is the tutorial's answer up to a constant. Expanding both in powers of shows they agree:
expected = tan(3*x)**4/12 + tan(3*x)**6/18
display(simplify(res - expected)) # -1/36 (a constant -> same family)
Question 7
f = sin(x)**4*cos(x)**7
res = expand(integrate(f, x))
display(res)
expected = sin(x)**5/5 - 3*sin(x)**7/7 + sin(x)**9/3 - sin(x)**11/11
display(simplify(res - expected)) # 0 -> identical
Question 8
SymPy's direct answer is a Piecewise, because the antiderivative is only real on
. The textbook route is the substitution , which we can do
step by step:
display(integrate(1/(x**2*sqrt(9 - x**2)), x)) # Piecewise - domain dependent
th = Symbol('theta', positive=True)
sub = (3*cos(th)) / ((3*sin(th))**2 * 3*cos(th)) # dx / (x^2 sqrt(9 - x^2))
display(simplify(sub)) # 1/(9*sin(theta)**2)
display(simplify(integrate(sub, th))) # -1/(9*tan(theta))
Since , we have , so
res = -sqrt(9 - x**2)/(9*x)
display(check(res, 1/(x**2*sqrt(9 - x**2)))) # 0 -> correct
Additional exercises
1.
There is a repeated linear factor, so the partial fraction decomposition needs a term as well as .
f = (x + 7)/(x**2*(x + 2))
display(apart(f, x)) # 5/(4*(x+2)) - 5/(4*x) + 7/(2*x**2)
display(integrate(f, x))
2.
Substitute , so :
display(apart(1/(u**3 + u), u)) # 1/u - u/(u^2 + 1)
display(integrate(1/(u**3 + u), u)) # log(u) - log(u^2 + 1)/2
Substituting back :
res = ln(sin(x)) - ln(sin(x)**2 + 1)/2
display(check(res, cos(x)/(sin(x)**3 + sin(x)))) # 0 -> correct
Extra Learning Resources
Key Concepts to Master
- Integration by parts:
- Partial fractions: factor the denominator, then match coefficients (or substitute convenient values of )
- Repeated factors need one term per power:
- Odd power of or : split off one factor and substitute for the other
- Trigonometric substitution: , ,
SymPy Resources
- SymPy
integrate— both definite and indefinite integrals - SymPy
apart— partial fraction decomposition - SymPy
factor— factorising the denominator
Common Pitfalls
- SymPy does not add
+ C; you must write it in your final answer - An antiderivative that differs from the printed one by a constant is still correct — always verify by differentiating
log(x, 10)is base 10; useln(x)for the natural logarithm- A
Piecewiseresult just means SymPy had to split the domain; substitute the branch valid on your interval - Remember the absolute value inside logarithms for indefinite integrals