You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I wanted to give myself the freedom to have on_birth functions do slicing or random access. Slicing is better when adding agents in a block to the population Laserframe.
There are lots of ways to do constant-population demography. One is "constant on average" - just set birth rate = death rate and have random births and deaths as normal. Another would be deterministic constant population: add your births as normal to the laser frame, and then make sure that exactly that many existing agents are removed. As a way to be memory-efficient at very large populations, I wanted to implement a mode to enable births while maintaining strictly constant population, and one obvious way to do this is to have each "birth" just be re-initializing agents as newborns.
To do this, I needed to be able to randomly index the Laserframe rather than remove agents in slices - doing this via slicing could induce potentially buggy and hard-to-find correlations between position in the laserframe and probability of dying.
I don't want to have to build separate classes for every class with an on-birth function just to make this change. And having multiple "on_birth" methods seems wrong too, since code specifically looks for a method named on_birth, and method overloading didn't seem like the right way. So I did the below pattern - if the input parameter "iend" is none, assume istart is an index list; if istart and iend are present, assume they are the limits of a slice. Good pattern?
def on_birth(self, model, _tick, istart, iend): if iend is not None: model.population.susceptibility[istart:iend] = 1 else: model.population.susceptibility[istart] = 1
The text was updated successfully, but these errors were encountered:
I wanted to give myself the freedom to have on_birth functions do slicing or random access. Slicing is better when adding agents in a block to the population Laserframe.
There are lots of ways to do constant-population demography. One is "constant on average" - just set birth rate = death rate and have random births and deaths as normal. Another would be deterministic constant population: add your births as normal to the laser frame, and then make sure that exactly that many existing agents are removed. As a way to be memory-efficient at very large populations, I wanted to implement a mode to enable births while maintaining strictly constant population, and one obvious way to do this is to have each "birth" just be re-initializing agents as newborns.
To do this, I needed to be able to randomly index the Laserframe rather than remove agents in slices - doing this via slicing could induce potentially buggy and hard-to-find correlations between position in the laserframe and probability of dying.
I don't want to have to build separate classes for every class with an on-birth function just to make this change. And having multiple "on_birth" methods seems wrong too, since code specifically looks for a method named on_birth, and method overloading didn't seem like the right way. So I did the below pattern - if the input parameter "iend" is none, assume istart is an index list; if istart and iend are present, assume they are the limits of a slice. Good pattern?
def on_birth(self, model, _tick, istart, iend): if iend is not None: model.population.susceptibility[istart:iend] = 1 else: model.population.susceptibility[istart] = 1
The text was updated successfully, but these errors were encountered: