I'm trying to simulate a stochastic model of deterministic exponential population growth, where $dN/dt = rN$ where $N$ is population size and $r$ is rate ($t$ time). I'm assuming there's no carrying capacity. This page (http://cnr.lwlss.net/DiscreteStochasticLogistic/) suggests this algorithm for simulating growth on an interval $[0, t_{end}]$:
- start at $t = 0$ with initial population size
- draw next time for birth event, $\delta t \sim Exponential(rN(1 - N/K))$ ($K$ is carrying capacity)
- increment population size, $N = N + 1$
- set $t = t + \delta t$
- if $t > t_{end}$ then quit, otherwise go to step 2.
since I don't have a carrying capacity $K$, I assume it's infinite, so the next birth time is $\delta t \sim Exponential(rN)$. Is that correct?
when I run the simulation this way it doesn't at all give similar results to $N(t) = P_0 e^{rt}$ (where $P_0$ is initial population size). even averaging over many iterations it seems to give different growth curves.
below is my code and the result of the simulation. red curve is deterministic exponential growth, black curves are simulation using exponential distribution. they clearly don't match.
import numpy as np
import matplotlib.pylab as plt
def sim(rate, start, end, init):
N = 200
finalsizes = []
results = []
for n in range(N):
size = init
curr_t = 0
times = [curr_t]
sizes = [init]
new_rate = rate
while curr_t <= end:
# simulate next birth time. the scale
# parameter is inversely proportional to population
# size
new_rate = 1/float(new_rate * size)
div_time = np.random.exponential(scale=new_rate)
# advance time
curr_t += div_time
if curr_t > end:
# if we exceed time interval, quit
break
times.append(curr_t)
# increase population size
size += 1
sizes.append(size)
finalsizes.append([times, sizes])
return finalsizes
# run simulation and plot results
init = 20
start = 0
end = 20
rate = 1
finalsizes = sim(rate, start, end, init)
plt.figure()
allsizes = []
for f in finalsizes:
allsizes.append(f[1][-1])
plt.plot(f[0], f[1], color="k", alpha=0.5)
times = np.arange(0, end + 1)
plt.plot(times, init*np.power(2, rate * times), color="r")
plt.xlabel("time")
plt.ylabel("size of population")
print "mean final size: ", np.mean(allsizes)
plt.show()
response to whuber's excellent answer: i don't understand why I have to specify the population size in advance. my simulation is meant to ask: in a given amount of time, what will be the variability in population size assuming exponential growth? (and not, how long would it take on average to make a population of size $N$, which is what whuber's simulation seems to be doing).
also, i don't think it's correct that i "haven't yet done enough simulations to appreciate what they are telling you". i updated my simulation to plot 1000 runs. as you can see, with my time-based stop condition, the results consistently underestimate the deterministic exponential growth population size.
my reasoning was that if i simulate $N$ runs for a duration $t$, then as $N \rightarrow \infty$, the average population size i get from my simulation should be an unbiased estimate of the population size based on the deterministic exponential growth model for $t$, i.e. $2^{rt}$. for example, if i simulate 3 time steps (starting with a single individual), i would expect the population size to sometimes be greater than 8 in the simulation and sometimes less than 8, and the average to converge to 8. it seems to be like this should be true even if i start with a very small population, as long as i simulate enough runs. is this incorrect? what is wrong with this reasoning? the simulations don't support this although i expected it to be true. it seems like there has to be a flaw in my reasoning and/or simulation.
update 2: fixed simulation where the scale parameter to exponential distribution decreases with population size (inversely proportional to it) and initial population size is 10. it still grossly underestimates exponential growth.
R
code I posted). $\endgroup$