Skip to content

Add multi-state neuron models #3069

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

Open
wants to merge 95 commits into
base: master
Choose a base branch
from

Conversation

jasperalbers
Copy link
Contributor

This PR proposes to add multi-state neuron models used for studying infection dynamics as described in [1]. Building on the implementation of the binary neuron, these models can be in either of three states: S, I or R.
In particular, three new neuron models are added:

  • the SIS neuron that can only be in states S or I where transitions from I to S are allowed
  • the SIR neuron that can be in all three states S, I or R where transitions from R to S are forbidden
  • the SIRS neuron that can be in all three states S, I or R where transitions from R back to S are allowed
    Their implementation closely follows the example set by the binary neuron.

If these models are deemed interesting enough to be added to the NEST simulator, we (@jasperalbers and @ClaudiaMer) would also add the corresponding documentation and tests. Here, we would be grateful for a pointer to a minimal example of what is required for both documentation and tests if that exists.

[1] https://arxiv.org/abs/2312.14851

jasperalbers and others added 19 commits August 4, 2022 11:17
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
Co-authored-by: ClaudiaMer <claudia.lioba.merger@rwth-aachen.de>
@jasperalbers jasperalbers marked this pull request as draft January 17, 2024 15:10
@terhorstd terhorstd added T: Enhancement New functionality, model or documentation S: Normal Handle this with default priority labels Jan 19, 2024
ClaudiaMer and others added 9 commits July 3, 2025 17:22
Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
Co-authored-by: jessica-mitchell <mitchell20j@gmail.com>
Copy link
Contributor

@jessica-mitchell jessica-mitchell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @ClaudiaMer

Copy link
Contributor

@clinssen clinssen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I am basically fine with everything, just some small comments.

throw BadProperty( "All time constants must be strictly positive." );
}

updateValueParam< double >( d, names::beta_sir, beta_sir_, node );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be 0 < beta < 1 or 0 <= beta <= 1?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principle one could allow beta=0 or beta=1.
beta=0 however would make the dynamics trivial (no infection can take place), and lead to a non-sensical model.
beta=1 could be allowed, it makes the dynamics deterministic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think allowing beta=0 would make sense, if only for testing purposes. As it has a consistent interpretation, we should not limit the freedom of the user.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, I was myself confused. Currently, we only raise an error if beta <0 or beta >1 (see line 193ff of sir_neuron.cpp) meaning that both beta=0 and beta=1 are currently allowed.

Copy link
Contributor

@heplesser heplesser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ClaudiaMer and @jasperalbers! Sorry for coming late to the party and raising a number of questions, mostly inline. But I also have an higher-level question: Is it strictly necessary to introduce three new neuron models? Wouldn't it be possible to create one model with a parameter that allows choosing between SIS, SIR and SIRS dynamics? This would help to keep the model zoo and the amount of code to maintain smaller.

// initialize y_new
size_t new_y;

if ( S_.y_ == 0 ) // neuron is susceptible
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For robust and readable code, it would be useful to not use magic numbers 0, 1, 2, explicitly, but rather define an

enum class InfectionState {
  SUSCEPTIBLE = 0,
  INFECTED,
 RECOVERED 
};

and to use those names here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it not more convenient to track a single integer than three separate binary variables?

@@ -183,8 +183,10 @@ enum SignalType
NONE = 0,
SPIKE = 1,
BINARY = 2,
ALL = SPIKE | BINARY
SIR = 3,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need these there new types here or couldn't one use BINARY to distinguish from SPIKE? After a non-exhaustive search, I haven't been able to find any place where these new types are actually used in the code.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could lead to confusion as the sir_neuron and sirs_neuron can take more than two states.

@@ -110,6 +110,9 @@ extern const Name beta_1;
extern const Name beta_2;

extern const Name beta_Ca;
extern const Name beta_sir;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any need to introduce new names here, just use beta (and eta and mu). From the fact that you set the beta parameter of a SIR neuron it is sufficiently clear that this is the beta of a SIR neuron.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tried to do so in the beginning, but this threw some errors when we attempted to compile the code (unfortunately I don't remember which ones), thus we solved it this way.

struct Parameters_
{
//! mean inter-update interval in ms (acts like a membrane time constant).
double tau_m_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does tau_m_ really make sense as parameter name, given that there is no membrane? Why not just tau?

Copy link

@ClaudiaMer ClaudiaMer Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tried to avoid introducing new parameters.


//! Read out the sir_neuron state of the neuron
double
get_output_state__() const
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize that the __ is inherited from the existing binary neurons, but it is not good style. Private members should be marked with a single _ at the end.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ClaudiaMer and others added 6 commits July 11, 2025 09:38
Co-authored-by: clinssen <c.linssen@fz-juelich.de>
Co-authored-by: clinssen <c.linssen@fz-juelich.de>
Co-authored-by: clinssen <c.linssen@fz-juelich.de>
Co-authored-by: Hans Ekkehard Plesser <hans.ekkehard.plesser@nmbu.no>
Co-authored-by: Hans Ekkehard Plesser <hans.ekkehard.plesser@nmbu.no>
Co-authored-by: Hans Ekkehard Plesser <hans.ekkehard.plesser@nmbu.no>
@ClaudiaMer
Copy link

Hi @ClaudiaMer and @jasperalbers! Sorry for coming late to the party and raising a number of questions, mostly inline. But I also have an higher-level question: Is it strictly necessary to introduce three new neuron models? Wouldn't it be possible to create one model with a parameter that allows choosing between SIS, SIR and SIRS dynamics? This would help to keep the model zoo and the amount of code to maintain smaller.

We found it more convenient to introduce these three neurons as it makes the communication between neurons easier: Neurons need to communicate their change in state to other neurons, in particular, when they are infected and when then exit the infected state, this is communicated via spikes of multiplicity one and two. If there are multiple transitions (e.g. from the I to the S OR from the I to the R state), this could complicate the update rule in the neurons, which is why we distinguish SIS and SIRS neurons. Second, SIR neurons that are in the R state can be considered as "silent" as they are essentially frozen for the remainder of the dynamics, while SIRS or SIS neurons are not, as they will always allow for dynamic updates.
Finally, we thought that it would be more convenient for users to use three different neurons where the transitions are explicitly known instead of having to ensure that only allowed transitions are realized.
Of course it may be convenient to define a multi-state neuron which allows for all kinds of transitions between a arbitrary number of states in an arbitrary number of ways, but writing such a code is currently beyond my resources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I: No breaking change Previously written code will work as before, no one should note anything changing (aside the fix) S: Normal Handle this with default priority stale Automatic marker for inactivity, please have another look here T: Enhancement New functionality, model or documentation
Projects
Status: Review
Status: Review
Development

Successfully merging this pull request may close these issues.

6 participants