CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

Public worksheets for UCLA's Mathematics for Life Scientists course

Views: 10255

Exponential growth and decay

in continuous-time (ODE) models and discrete-time models

Continuous time

(We covered this in LS 30A, around week 5 or 6.)

General form of the differential equation: X=rXX' = rX

General form of the solution to this: X(t)=X(0)ertX(t) = X(0) \cdot e^{rt}

The parameter rr is the growth/decay rate. In particular, this model yields the following behaviors:

  • Exponential growth if r>0r > 0

  • Exponential decay if r<0r < 0

Example 1:

A population NN, starting with 400400 individuals, growing at a constant per-capita rate of 3%3\% per year:

$$ \begin{align*}

\text{Differential equation:} \qquad & N' = 0.03 N \\ \text{Solution:} \qquad & N(t) = 400 e^{0.03t}

\end{align*} $$

# Solved by simulating with desolve_odeint: f(N) = 0.03*N t_values = srange(0, 100, 0.1) solution = desolve_odeint(f, 400, t_values, N) p = list_plot(zip(t_values, solution), plotjoined=True) p += text("$r = 0.03$\nExponential growth, continuous-time", (50, 7000), color="red", fontsize=14) p.show(ymin=0, axes_labels=("$t$", "$N$"))
# Solved by just plotting the solution function given above: N(t) = 400*e^(0.03*t) p = plot(N, (t, 0, 100)) p += text("$r = 0.03$\nExponential growth, continuous-time", (50, 7000), color="red", fontsize=14) p.show(ymin=0, axes_labels=("$t$", "$N$"))
# Note that the two plots above are identical.

Example 2:

A drug concentration in the bloodstream, DD, that starts at 2.72.7 mg/L, and is being metabolized and/or excreted at a (per-mass) rate of 12%12\% per hour:

$$ \begin{align*}

\text{Differential equation:} \qquad & D' = -0.12 D \\ \text{Solution:} \qquad & D(t) = 2.7 e^{-0.12t}

\end{align*} $$

# Solved by simulating with desolve_odeint: f(D) = -0.12*D t_values = srange(0, 50, 0.1) solution = desolve_odeint(f, 2.7, t_values, D) p = list_plot(zip(t_values, solution), plotjoined=True) p += text("$r = -0.12$\nExponential decay, continuous-time", (25, 2), color="red", fontsize=14) p.show(ymin=0, axes_labels=("$t$", "$D$"))
# Solved by just plotting the solution function given above: D(t) = 2.7*e^(-0.12*t) p = plot(D, (t, 0, 50)) p += text("$r = -0.12$\nExponential decay, continuous-time", (25, 2), color="red", fontsize=14) p.show(ymin=0, axes_labels=("$t$", "$D$"))
# Again, the two plots above are identical.

Discrete time

(We covered this in LS 30B, beginning of week 4.)

General form of the discrete-time model (difference equation): Xt+1=RXtX_{t+1} = RX_t

General form of the solution to this: Xt=X0RtX_t = X_0 \cdot R^t

The parameter RR is the factor by which XX grows/decays at each time step, but note that this is not the same as the growth/decay rate in the continuous-time case. For example, if a population is growing at 10%10\% per year, you would use R=1.10R = 1.10, and if it's declining at 7%7\% per year, you would use R=0.93R = 0.93. This is the reason that I have used lowercase rr in the continuous-time setting, but uppercase RR in the discrete-time setting. In simple cases, the relationship between these two is just

R=1+rR = 1 + r

That should explain the examples given in this paragraph: growing at 10%10\% per year means r=0.10r = 0.10, so R=1+0.10=1.10R = 1 + 0.10 = 1.10. Declining at 7%7\% per year means r=0.07r = -0.07, so R=1+(0.07)=0.93R = 1 + (-0.07) = 0.93.

In particular, this model yields the following behaviors:

  • Exponential growth if R>1\lvert R \rvert > 1

  • Exponential decay if R<1\lvert R \rvert < 1

Example 3:

A population NN, starting with 400400 individuals, growing at a constant per-capita rate of 3%3\% per year, in discrete time (so R=1.03R = 1.03):

$$ \begin{align*}

\text{Discrete-time model:} \qquad & N_{t+1} = 1.03 N_t \\ \text{Solution:} \qquad & N_t = 400 \cdot 1.03^t

\end{align*} $$

# Solved by simulating (iterating) with a for loop: f(N) = 1.03*N solution = [400] for t in srange(100): solution.append(f(solution[-1])) p = list_plot(solution, plotjoined=False) p += text("$R = 1.03$\nExponential growth (at $3\%$ per year), discrete-time", (50, 7000), color="red", fontsize=14) p.show(ymin=0, axes_labels=("$t$", "$N$"))
# Solved by just plotting the solution function given above: N(t) = 400*1.03^t p = list_plot([N(t) for t in srange(101)]) p += text("$R = 1.03$\nExponential growth (at $3\%$ per year), discrete-time", (50, 7000), color="red", fontsize=14) p.show(ymin=0, axes_labels=("$t$", "$N$"))
# Note that the two plots above are identical.

Example 4:

Once every hour, one of your roommates opens the fridge to find your leftover birthday cake, and eats one quarter of whatever is remaining. Let CC be the fraction of the cake that's remaining, which starts at 0.60.6. (That is, 60%60\% of the cake is in the fridge initially.)

$$ \begin{align*}

\text{Discrete-time model:} \qquad & C_{t+1} = 0.75 C_t \\ \text{Solution:} \qquad & C_t = 0.6 \cdot 0.75^t

\end{align*} $$

# Solved by simulating (iterating) with a for loop: f(C) = 0.75*C solution = [0.6] for t in srange(20): solution.append(f(solution[-1])) p = list_plot(solution, pointsize=40) p += text("$R = 0.75$\nExponential decay (at $25\%$ per hour), discrete-time", (10, 0.5), color="red", fontsize=14) p.show(ymin=0, axes_labels=("$t$", "$C$"))
# Solved by just plotting the solution function given above: C(t) = 0.6*0.75^t p = list_plot([C(t) for t in srange(21)], pointsize=40) p += text("$R = 0.75$\nExponential decay (at $25\%$ per hour), discrete-time", (10, 0.5), color="red", fontsize=14) p.show(ymin=0, axes_labels=("$t$", "$C$"))
# Again, the two plots above are identical.

NOTE: A new type of behavior can happen in the discrete-time case, that can't happen in the continuous-time case:

Suppose RR is negative. Then the state variable will alternate back and forth between positive and negative values. However, the overall behavior is still growth/decay of the magnitude (size) of the state variable.

Example 5:

R=1.2R = -1.2, starting with an initial XX value of X0=10X_0 = 10:

$$ \begin{align*}

\text{Discrete-time model:} \qquad & X_{t+1} = -1.2 X_t \\ \text{Solution:} \qquad & X_t = 10 \cdot (-1.2)^t \end{align*} $$

This will have exponential growth, since 1.2>1\lvert -1.2 \rvert > 1.

X(t) = 10*(-1.2)^t solution = [X(t0) for t0 in srange(31)] p = list_plot(solution, pointsize=40) p += list_plot(solution, plotjoined=True) p += text("$R = -1.2$\nExponential growth, alternating $+/-$", (15, 2000), color="red", fontsize=14) p.show(axes_labels=("$t$", "$X$"))

Here is the same graph, but with green exponential growth curves to show how the positive and negative values are all growing away from zero.

X(t) = 10*(-1.2)^t solution = [X(t0) for t0 in srange(31)] p = list_plot(solution, pointsize=40) p += list_plot(solution, plotjoined=True) p += text("$R = -1.2$\nExponential growth, alternating $+/-$", (15, 2000), color="red", fontsize=14) p += plot(abs(X(t)), (t, 0, 30), color="green", linestyle="dashed") p += plot(-abs(X(t)), (t, 0, 30), color="green", linestyle="dashed") p.show(axes_labels=("$t$", "$X$"))

Example 6:

R=0.85R = -0.85, starting with an initial XX value of X0=300X_0 = 300:

$$ \begin{align*}

\text{Discrete-time model:} \qquad & X_{t+1} = -0.85 X_t \\ \text{Solution:} \qquad & X_t = 300 \cdot (-0.85)^t \end{align*} $$

This will have exponential decay, since 0.85<1\lvert -0.85 \rvert < 1.

X(t) = 300*(-0.85)^t solution = [X(t0) for t0 in srange(41)] p = list_plot(solution, pointsize=40) p += list_plot(solution, plotjoined=True) p += text("$R = -0.85$\nExponential decay, alternating $+/-$", (20, 200), color="red", fontsize=14) p.show(axes_labels=("$t$", "$X$"))

Here is the same graph, but with green exponential decay curves to show how the positive and negative values are all decaying toward zero.

X(t) = 300*(-0.85)^t solution = [X(t0) for t0 in srange(41)] p = list_plot(solution, pointsize=40) p += list_plot(solution, plotjoined=True) p += text("$R = -0.85$\nExponential decay, alternating $+/-$", (20, 200), color="red", fontsize=14) p += plot(abs(X(t)), (t, 0, 40), color="green", linestyle="dashed") p += plot(-abs(X(t)), (t, 0, 40), color="green", linestyle="dashed") p.show(axes_labels=("$t$", "$X$"))

These last two examples demonstrate the reason for the absolute value on the RR in the explanation of the discrete-time case above. Again, that conclusion is the following: in the discrete-time model Xt+1=RXtX_{t+1} = R X_t, the behavior is

  • Exponential growth if R>1\lvert R \rvert > 1

  • Exponential decay if R<1\lvert R \rvert < 1

One last thing:

(And this will be really important for understanding stability of equilibrium points by linear approximation)

Notice that, if we consider a model in which the state variable XX can have either positive or negative values, then you shouldn't think of exponential growth as “grows to infinity”. Rather, you should think of it as “grows away from zero”, but that growth can be in either the positive or the negative direction, depending on the initial condition (starting value of XX).

Similarly, for exponential decay, note that the “decay” doesn't mean that XX always decreases. Rather, it “goes toward zero”.

This is all true for both continuous-time and discrete-time exponential growth/decay.

Examples:

The first graph below shows several different time series, starting from different initial states. Note that these are all from the same exponential growth model (in particular, they all have the same exponential growth rate). The ones that start with X>0X > 0 grow up toward infinity. The ones that start with X<0X < 0 “grow” in the opposite direction, toward negative infinity.

The second graph below shows the same sort of thing, but for exponential decay. Note that the solutions that start with a negative XX value actually go up, but you can still say that they are “decaying” toward zero.

initial_states = [1, 5, 10, -1, -5, -10] p = Graphics() for X0 in initial_states: X(t) = X0*e^(0.1*t) p += plot(X, (t, 0, 45), color="red") p += text("$r = 0.1$\nExponential growth\n(continuous time)", (10, 80), color="blue", fontsize=14) p.show(axes_labels=("$t$", "$X$"), ymin=-100, ymax=100)
initial_states = [10, 50, 100, -10, -50, -100] p = Graphics() for X0 in initial_states: X(t) = X0*0.8^t solution = [X(t) for t in srange(20)] p += list_plot(solution, color="green", pointsize=40) p += list_plot(solution, color="green", plotjoined=True) p += text("$R = 0.8$\nExponential decay (at $20\%$ per year)\n(discrete time)", (10, 80), color="blue", fontsize=14) p.show(axes_labels=("$t$", "$X$"), ymin=-100, ymax=100)

Think about the above two graphs in terms of equilibrium points

In all exponential growth/decay models, there is one equilibrium point. Where is it? What do the above graphs say about the stability of that equilibrium point?