5. Modelling: growth, decay, logistic, and Newton's cooling
§13.1–§13.3 built three solving techniques. This lesson points them at real phenomena — population growth, radioactive decay, cooling coffee, and a population that can't grow forever — showing that a handful of short differential equations, each solvable by tools already in hand, model an enormous range of physical behavior.
Exponential growth and decay
\frac{dy}{dt}=ky
— separable (§13.1), with solution y=y_0e^{kt} (§13.0's own opening example, generalized with a rate constant k). k>0 gives growth (population, compound interest, §2.6's e itself), k<0 gives decay (radioactive material, drug concentration in the bloodstream).
Half-life and doubling time follow directly — from two different equations that happen to land on the same formula up to a sign. Half-life solves \frac12y_0=y_0e^{kt}, giving t=\frac{\ln2}{-k}, positive exactly when k<0 (decay). Doubling time solves 2y_0=y_0e^{kt}, giving t=\frac{\ln2}k, positive exactly when k>0 (growth). They mirror each other because \ln\frac12=-\ln2.
Newton's law of cooling
\frac{dT}{dt}=-k(T-T_{\text{amb}})
— an object's temperature T approaches the ambient temperature T_{\text{amb}} at a rate proportional to the current gap between them. This is linear (§13.2): rearranged to T'+kT=kT_{\text{amb}}, the integrating factor \mu=e^{kt} solves it directly, giving
T(t)=T_{\text{amb}}+(T_0-T_{\text{amb}})e^{-kt}
The temperature gap itself decays exponentially — the same e^{-kt} shape as radioactive decay, applied to a difference rather than to the quantity directly.
The logistic equation
Exponential growth assumes unlimited resources — realistic only briefly. The logistic equation caps growth at a carrying capacity M:
\frac{dP}{dt}=kP\left(1-\frac PM\right)
When P is small compared to M, \frac PM\approx0 and this behaves like ordinary exponential growth (P'\approx kP); as P approaches M, the factor \left(1-\frac PM\right) shrinks toward 0, throttling growth to a halt.
Solving it — separable, but the partial-fraction decomposition from §4.9 is required to integrate the left side:
\int\frac{dP}{P(1-P/M)}=\int k\,dt
\frac M{P(M-P)}=\frac1P+\frac1{M-P}\qquad\text{(§4.9's technique, applied here)}
\int\left(\frac1P+\frac1{M-P}\right)dP=kt+C\ \Longrightarrow\ \ln\left|\frac P{M-P}\right|=kt+C
Exponentiating and solving for P (algebra parallel to §13.1's worked example) gives the logistic curve:
P(t)=\frac M{1+Ae^{-kt}}\qquad\text{where }A=\frac{M-P_0}{P_0}
This function starts near-exponential, then bends over and levels off at M — an S-shaped ("sigmoid") curve, the standard model for population growth under limited resources, disease spread, and (not coincidentally) the activation functions used throughout the neural networks previewed in §14.
Doing it in Python
Solving the logistic equation with M=1000, k=0.5, P_0=100, and evaluating at t=4:
import sympy as sp
t = sp.Symbol('t')
M, k, P0 = sp.Integer(1000), sp.Rational(1, 2), sp.Integer(100)
A = (M - P0) / P0
P = M / (1 + A * sp.exp(-k * t))
print(f"logistic solution: P(t) = {P}")
print(f"P(4) = {float(P.subs(t, 4)):.4f}")
print(f"as t -> infinity, P -> {M} (the carrying capacity)")
Newton's law of cooling, solved with SymPy's built-in ODE solver as an independent check against the closed-form formula:
import sympy as sp
t = sp.Symbol('t')
T = sp.Function('T')
T_amb, k = 20, sp.Rational(1, 20)
ode = sp.Eq(T(t).diff(t), -k * (T(t) - T_amb))
solution = sp.dsolve(ode, T(t), ics={T(0): 100})
print(f"T(t) = {solution.rhs}")
print(f"T(20) = {float(solution.rhs.subs(t, 20)):.4f}")
Radioactive decay: finding the decay constant from a known half-life, then the time to decay to a given fraction:
import sympy as sp
t = sp.Symbol('t', positive=True)
half_life = 10
k = sp.ln(2) / half_life
print(f"decay constant k = {k} = {float(k):.6f}")
time_to_20_percent = sp.solve(sp.Eq(sp.exp(-k * t), sp.Rational(1, 5)), t)
print(f"time to decay to 20%: {time_to_20_percent[0]} = {float(time_to_20_percent[0]):.4f}")
Worked example
A population follows the logistic equation with carrying capacity M=1000, growth rate k=0.5, and initial population P_0=100. Find P(4).
A=\frac{M-P_0}{P_0}=\frac{1000-100}{100}=9
P(t)=\frac{1000}{1+9e^{-0.5t}}
P(4)=\frac{1000}{1+9e^{-2}}
Using e^{-2}\approx0.1353:
P(4)=\frac{1000}{1+9(0.1353)}=\frac{1000}{1+1.2177}=\frac{1000}{2.2177}\approx\boxed{450.9}
Sanity check. At t=0: P(0)=\frac{1000}{1+9}=\frac{1000}{10}=100 ✓, matching the initial condition exactly. As t\to\infty, e^{-0.5t}\to0, so P(t)\to\frac{1000}{1+0}=1000=M ✓ — the population approaches but never exceeds the carrying capacity, exactly the qualitative behavior the equation was built to produce. And P(4)\approx450.9 sits comfortably between the initial value 100 and the ceiling 1000, past the midpoint — consistent with the population having grown substantially in 4 time units at growth rate k=0.5, but not yet having saturated near M. ✓
Your turn
1. A radioactive isotope has a half-life of 20 years. Find its decay constant k, and the fraction remaining after 50 years.
2. A cup of coffee at 95°C is placed in a 20°C room, with cooling constant k=0.08 (per minute). Find its temperature after 15 minutes.
3. True or false: as t\to\infty, the logistic solution P(t)=\dfrac M{1+Ae^{-kt}} always approaches M, regardless of the initial population P_0 (as long as P_0>0 and k>0).
Solutions
1. k=\dfrac{\ln2}{20}\approx0.03466 per year.
Fraction remaining after 50 years: e^{-kt}=e^{-0.03466\times50}=e^{-1.733}\approx\boxed{0.177} (about 17.7\% remaining).
2. T(t)=20+(95-20)e^{-0.08t}=20+75e^{-0.08t}.
T(15)=20+75e^{-1.2}\approx20+75(0.3012)\approx20+22.59=\boxed{42.59°\text{C}}
3. True. For any A>0 (equivalently, any P_0 strictly between 0 and M) and k>0, e^{-kt}\to0 as t\to\infty, so P(t)\to\dfrac M{1+0}=M regardless of the specific starting value. This is exactly the logistic model's defining feature: every population eventually approaches the same carrying capacity, whether it started small (mostly exponential growth phase) or already close to M (mostly flat from the start).
Check yourself in code
Solve the logistic equation with M=1000, k=0.5, P_0=100, and evaluate P(4).
Print exactly this:
P(t) = 1000/(1 + 9*exp(-t/2))
P(4) = 450.8531
import sympy as sp
t = sp.Symbol('t')
M, k, P0 = sp.Integer(1000), sp.Rational(1, 2), sp.Integer(100)
A = (M - P0) / P0
P = M / (1 + A * sp.exp(-k * t))
print("P(t) = ...")
print(f"P(4) = ...")
import sympy as sp
t = sp.Symbol('t')
M, k, P0 = sp.Integer(1000), sp.Rational(1, 2), sp.Integer(100)
A = (M - P0) / P0
P = M / (1 + A * sp.exp(-k * t))
print(f"P(t) = {P}")
print(f"P(4) = {float(P.subs(t, 4)):.4f}")
Exponential growth and decay (y'=ky), Newton's cooling (T'=-k(T-T_{\text{amb}})), and the logistic equation (P'=kP(1-P/M)) are all solved with tools already built — separation for the first and third, the integrating factor for the second, with §4.9's partial fractions doing the extra work the logistic equation demands. The logistic curve's S-shape — near-exponential growth that bends over and saturates at a carrying capacity — is the standard model wherever growth faces a hard resource limit, from populations to epidemics.
Next: differential equations that involve a second derivative, where an entirely new solving technique — matching an exponential guess against a characteristic polynomial — takes over from first-order methods.