Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Good pattern for allowing on_birth functions to have slicing or random access? #5

Open
KevinMcCarthyAtIDM opened this issue Dec 6, 2024 · 1 comment
Labels
help wanted Extra attention is needed

Comments

@KevinMcCarthyAtIDM
Copy link
Collaborator

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

@KevinMcCarthyAtIDM KevinMcCarthyAtIDM added the help wanted Extra attention is needed label Dec 6, 2024
@clorton
Copy link
Contributor

clorton commented Dec 6, 2024

Good question. IMO, this relates to our experiment on grouping agents by state - grouping agents by node (in order to efficiently select k from N).

Another option we can try is passing a Boolean array of all the agents of interest in a slice rather than having to call on_birth() once per agent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants