2. Separable equations
§13.0 approximated a differential equation's solution one small step at a time. This lesson finds an exact solution — no approximation at all — for the specific (but very common) case where the equation's two variables can be pulled apart algebraically onto opposite sides.
What makes an equation separable
A first-order equation is separable if it can be written as
\frac{dy}{dx}=g(x)h(y)
— the right side factors into a piece depending only on x and a piece depending only on y. Treating \frac{dy}{dx} as a genuine ratio of differentials (a notational liberty justified rigorously by the substitution rule, §4.5), divide both sides by h(y) and multiply by dx:
\frac{dy}{h(y)}=g(x)\,dx
Every y is now on the left, every x on the right — separated. Integrate each side independently:
\int\frac{dy}{h(y)}=\int g(x)\,dx
This produces an equation relating x and y (usually with y appearing inside a logarithm or some other function), plus a single constant of integration (the two separate +C's from each side combine into one, since they can be moved to either side freely).
Solving for y explicitly
After integrating, the result is often implicit — an equation relating x and y, not yet solved for y directly. Algebraic manipulation (frequently exponentiating both sides, if a logarithm appeared) recovers an explicit solution y=y(x) when possible. An initial condition, exactly as in §13.0, pins the arbitrary constant down to a single specific solution.
Doing it in Python
Solving \frac{dy}{dx}=xy by separating variables, integrating both sides, and applying the initial condition y(0)=2:
import sympy as sp
x, y, C = sp.symbols('x y C')
# separate: dy/y = x dx
lhs = sp.integrate(1/y, y)
rhs = sp.integrate(x, x)
print(f"integral of dy/y = {lhs}")
print(f"integral of x dx = {rhs}")
# ln|y| = x^2/2 + C => y = A*e^(x^2/2), A = e^C
A = sp.Symbol('A')
general_solution = A * sp.exp(x**2 / 2)
print(f"general solution: y = {general_solution}")
# apply y(0) = 2
A_value = sp.solve(sp.Eq(general_solution.subs(x, 0), 2), A)[0]
particular_solution = general_solution.subs(A, A_value)
print(f"particular solution: y = {particular_solution}")
Confirming the solution satisfies the original differential equation, by direct substitution:
import sympy as sp
x = sp.Symbol('x')
y = 2 * sp.exp(x**2 / 2)
dy_dx = sp.diff(y, x)
check = sp.simplify(dy_dx - x * y)
print(f"dy/dx = {dy_dx}")
print(f"dy/dx - x*y = {check} (should be 0)")
Confirming the same answer using SymPy's built-in ODE solver, as an independent check:
import sympy as sp
x = sp.Symbol('x')
y = sp.Function('y')
solution = sp.dsolve(sp.Eq(y(x).diff(x), x * y(x)), y(x), ics={y(0): 2})
print(f"sympy's dsolve: {solution}")
Worked example
Solve \dfrac{dy}{dx}=xy, y(0)=2.
Separate:
\frac{dy}y=x\,dx
Integrate both sides:
\int\frac{dy}y=\int x\,dx\ \Longrightarrow\ \ln|y|=\frac{x^2}2+C
Solve for y: exponentiate both sides.
|y|=e^{x^2/2+C}=e^C\cdot e^{x^2/2}
Absorb \pm e^C into a single constant A (which can now be any nonzero real number, positive or negative, since the absolute value and the sign ambiguity from exponentiating both fold into this one relabeling):
y=Ae^{x^2/2}
Apply the initial condition y(0)=2:
2=Ae^0=A\ \Longrightarrow\ A=2
\boxed{y=2e^{x^2/2}}
Sanity check. Differentiate directly: $\frac{dy}{dx}=2\cdot x\,e^{x^2/2}=x\cdot\big(2e^{x^2/2}\big)=xy$ ✓ — matches the original equation exactly, by the chain rule (§2.4) applied to the exponential. And y(0)=2e^0=2 ✓, matching the initial condition. Both checks confirm the solution independently of how it was derived. This solution also grows faster than e^0=1 scaling as x increases (since the exponent is x^2/2, not just x) — consistent with \frac{dy}{dx}=xy having a slope that itself grows with x, unlike the constant-relative- growth equation y'=y from §13.0. ✓
Your turn
1. Solve \dfrac{dy}{dx}=\dfrac{x}y (separable — separate and integrate; leave the answer implicit if it doesn't solve cleanly for y).
2. Solve \dfrac{dy}{dx}=3y, y(0)=5.
3. True or false: every first-order differential equation \frac{dy}{dx}=f(x,y) is separable.
Solutions
1. Separate: y\,dy=x\,dx. Integrate: \dfrac{y^2}2=\dfrac{x^2}2+C\Rightarrow y^2-x^2=2C. Relabeling 2C=K:
\boxed{y^2-x^2=K}
— a family of hyperbolas (§10.0's saddle-shaped level curves, resurfacing here as solution curves rather than as a function's contour lines).
2. Separate: \dfrac{dy}y=3\,dx. Integrate: $\ln|y|=3x+C\Rightarrow y=Ae^{3x}$. Apply y(0)=5: A=5.
\boxed{y=5e^{3x}}
3. False. \frac{dy}{dx}=x+y (from §13.0's own worked example) cannot be split into a product g(x)h(y) at all — the right side is a sum, not a product, of an x-only piece and a y-only piece. Separability is a genuine restriction on the shape of f(x,y), not a property every first-order equation automatically has; equations like y'=x+y need an entirely different technique, which §13.2 supplies next.
Check yourself in code
Solve \dfrac{dy}{dx}=xy, y(0)=2 by separating variables and applying the initial condition.
Print exactly this:
integral of dy/y = log(y)
integral of x dx = x**2/2
particular solution: y = 2*exp(x**2/2)
import sympy as sp
x, y, A = sp.symbols('x y A')
lhs = sp.integrate(1/y, y)
print("integral of dy/y = ...")
rhs = sp.integrate(x, x)
print("integral of x dx = ...")
general_solution = A * sp.exp(x**2 / 2)
A_value = sp.solve(sp.Eq(general_solution.subs(x, 0), 2), A)[0]
particular_solution = general_solution.subs(A, A_value)
print("particular solution: y = ...")
import sympy as sp
x, y, A = sp.symbols('x y A')
lhs = sp.integrate(1/y, y)
print(f"integral of dy/y = {lhs}")
rhs = sp.integrate(x, x)
print(f"integral of x dx = {rhs}")
general_solution = A * sp.exp(x**2 / 2)
A_value = sp.solve(sp.Eq(general_solution.subs(x, 0), 2), A)[0]
particular_solution = general_solution.subs(A, A_value)
print(f"particular solution: y = {particular_solution}")
A separable equation, \frac{dy}{dx}=g(x)h(y), splits into \frac{dy}{h(y)}=g(x)\,dx and integrates each side independently using nothing beyond Module 4's toolkit, recovering an exact solution rather than Euler's method's numerical approximation. Not every first-order equation factors this way — y'=x+y is the standard counterexample — and recognizing when separation applies is the main skill; the integration itself is routine once the split is made.
Next: first-order linear equations, a different (and larger) family that includes y'=x+y, solved with a clever multiplication trick called the integrating factor.