Open daniel-klein opened 3 days ago
We had discussed this issue previously here: https://github.com/starsimhub/starsim/issues/303
I agree with the logic that newborns have a nonzero mortality risk, so this makes sense. It's like how the population replacement rate is closer to 2.1 than 2.0 births per woman -- nonintuitive, but correct.
I'm also not sure I'd call the drop "dramatic": take a look at this:
import starsim as ss
import matplotlib.pyplot as plt
dems = [
ss.Births(pars=dict(birth_rate=20)),
ss.Deaths(pars=dict(death_rate=20))
]
sim = ss.Sim(demographics=dems, dur=30)
sim.run()
res = sim.results
plt.plot(res.timevec, res.n_alive)
plt.ylim(bottom=0, top=10_000)
plt.show()
Just curious, why not have a separation of labor between - calculation/drawing of transitions (eg. n_births, n_deaths etc.) in one step and then application of transitions (eg., ΔState = n_births-n_deaths) in other? That way all transitions will based on the same denominator?
Good question! Two main reasons:
t
, they couldn't start treatment until day t+1
, and then this wouldn't impact their probability of death/infectiousness until day t+2
).
Consider a simulation with the following demographics
One might expect a stable population. However, the result is a dramatically declining population.
This result is for two reasons:
Births
takes the floor when deterministically adding agents.n_new = int(np.floor(sim.people.alive.count() * scaled_birth_prob))
Module order matters. Because
Births
comes beforeDeaths
in the list ofdems
, agents are added to the population (resulting in a larger population), and thenDeaths
applies the death rate to all agents, including the new agents. A 1% increase followed by a 1% decrease results in a net decline.Switching the order of demographic module updates (and changing the Births floor to something like
sc.randround
) resolves the issue. Why? BecauseDeaths
simply schedules agents for death viati_death
without actually removing them from the population. TheBirths
module then adds agents considering the same denominator as used for deaths.We cannot expect users to know they have to put
Deaths
beforeBirths
to get a stable population.Next Steps:
Births
away fromfloor
. It could apply a probability per-agentBirthDeath
module that would act on the same denominator.Pregnancy
) at the end of the time step, although that will likely create other problems.Deaths
followsBirths
.Thanks to Deven for raising this issue in the context of SEIRD in TBsim.