Simpact Cyan
Population based event driven simulation using mNRM
population.h
Go to the documentation of this file.
1 #ifndef POPULATION_H
2 
3 #define POPULATION_H
4 
9 //#define SIMPLEMNRM -> now defined using the CMakeList.txt file
10 
11 #include "simplestate.h"
12 #include "mutex.h"
13 
15 class PersonBase;
16 class PopulationEvent;
17 
76 #ifndef SIMPLEMNRM
77 class Population : public State
78 #else
79 class Population : public SimpleState
80 #endif // SIMPLEMNRM
81 {
82 public:
86  Population(bool parallel, GslRandomNumberGenerator *pRng);
87  ~Population();
88 
89  bool isParallel() const { return m_parallel; }
90 
102  bool run(double &tMax, int64_t &maxEvents, double startTime = 0) { return State::evolve(tMax, maxEvents, startTime, false); }
103 
106  PersonBase **getAllPeople() { if (m_people.size() == 0) return 0; return &(m_people[0]); }
107 
109  PersonBase **getMen();
110 
112  PersonBase **getWomen();
113 
115  int getNumberOfPeople() const { return m_people.size(); }
116 
118  int getNumberOfMen() const { return m_numMen; }
119 
121  int getNumberOfWomen() const { return m_numWomen; }
122 
127  void addNewPerson(PersonBase *pPerson);
128 
133  void setPersonDied(PersonBase *pPerson);
134 
137  void onNewEvent(PopulationEvent *pEvt);
138 
139  // TODO: shield these from the user somehow? These functions should not be used
140  // directly by the user, they are used internally by the algorithm
141  void scheduleForRemoval(PopulationEvent *pEvt);
142  void lockEvent(PopulationEvent *pEvt) const;
143  void unlockEvent(PopulationEvent *pEvt) const;
144  void lockPerson(PersonBase *pPerson) const;
145  void unlockPerson(PersonBase *pPerson) const;
146 private:
147  bool initEventTimes() const;
148 #ifndef SIMPLEMNRM
149  EventBase *getNextScheduledEvent(double &dt);
150  void advanceEventTimes(EventBase *pScheduledEvent, double dt);
151 #else
152  const std::vector<EventBase *> &getCurrentEvents() const { return m_allEvents; }
153  void onFiredEvent(EventBase *pEvt, int position);
154 
155  std::vector<EventBase *> m_allEvents;
156 #endif // SIMPLEMNRM
157 
158 #ifdef STATE_SHOW_EVENTS
159  void showEvents(); // FOR DEBUGGING
160 #endif // STATE_SHOW_EVENTS
161  void onAlgorithmLoop();
162 
163  PopulationEvent *getEarliestEvent(const std::vector<PersonBase *> &people);
164  int64_t getNextEventID();
165  int64_t getNextPersonID();
166 
167  // These are living persons, the first part men, the second are women
168  std::vector<PersonBase *> m_people;
169  int m_numMen, m_numWomen;
170 
171  // Deceased persons
172  std::vector<PersonBase *> m_deceasedPersons;
173 
174  Mutex m_eventsToRemoveMutex;
175  std::vector<EventBase *> m_eventsToRemove;
176 
177  // For the parallel version
178  bool m_parallel;
179 
180  int64_t m_nextEventID, m_nextPersonID;
181  Mutex m_nextEventIDMutex, m_nextPersonIDMutex;
182 
183  std::vector<PopulationEvent *> m_tmpEarliestEvents;
184  std::vector<double> m_tmpEarliestTimes;
185 
186  mutable std::vector<Mutex> m_eventMutexes;
187  mutable std::vector<Mutex> m_personMutexes;
188 };
189 
190 inline int64_t Population::getNextEventID()
191 {
192  if (m_parallel)
193  m_nextEventIDMutex.lock();
194 
195  int64_t id = m_nextEventID++;
196 
197  if (m_parallel)
198  m_nextEventIDMutex.unlock();
199 
200  return id;
201 }
202 
203 inline int64_t Population::getNextPersonID()
204 {
205  if (m_parallel)
206  m_nextPersonIDMutex.lock();
207 
208  int64_t id = m_nextPersonID++;
209 
210  if (m_parallel)
211  m_nextPersonIDMutex.unlock();
212 
213  return id;
214 }
215 
216 #ifdef NDEBUG
217 
219 {
220  if (m_numMen == 0)
221  return 0;
222 
223  return &(m_people[0]);
224 }
225 
227 {
228  if (m_numWomen == 0)
229  return 0;
230 
231  return &(m_people[m_numMen]);
232 }
233 
234 #endif // NDEBUG
235 
236 #endif // POPULATION_H
bool run(double &tMax, int64_t &maxEvents, double startTime=0)
This should be called to actually start the simulation, do not call State::evolve for this...
Definition: population.h:102
int getNumberOfMen() const
Returns the number of people in the array returned by Population::getMen.
Definition: population.h:118
This class both describes the simulation state and contains the core algorithm (as shown on the main ...
Definition: state.h:40
virtual void onFiredEvent(EventBase *pEvt)
Called after pEvt is fired.
Definition: state.h:135
void addNewPerson(PersonBase *pPerson)
When a new person is introduced into the population, this function must be used to tell the simulatio...
Definition: population.cpp:513
This class provides functions for a population-based simulation using the modified Next Reaction Meth...
Definition: population.h:77
void setPersonDied(PersonBase *pPerson)
When a person has died, this function must be called to inform the simulation about this...
Definition: population.cpp:74
This class allows you to generate random numbers, and uses the GNU Scientific Library for this...
Definition: gslrandomnumbergenerator.h:15
This is the base class for events in population-based simulations which use the Population class...
Definition: populationevent.h:58
int getNumberOfPeople() const
Returns the number of people in the array returned by Population::getAllPeople.
Definition: population.h:115
This is the base class for a person in a population-based simulation that used the Population class...
Definition: personbase.h:23
Population(bool parallel, GslRandomNumberGenerator *pRng)
Constructor of the class, indicating if a parallel version should be used and which random number gen...
Definition: population.cpp:14
PersonBase ** getMen()
Same as Population::getAllPeople, but only the men are returned.
Definition: population.cpp:429
PersonBase ** getWomen()
Same as Population::getAllPeople, but only the women are returned.
Definition: population.cpp:442
This is the base class for events in the mNRM algorithm.
Definition: eventbase.h:60
bool evolve(double &tMax, int64_t &maxEvents, double startTime=0, bool initEvents=true)
This advances the simulation state using the core mNRM.
Definition: state.cpp:24
PersonBase ** getAllPeople()
Returns a list to the current living members in the population, introduced into the simulation using ...
Definition: population.h:106
void onNewEvent(PopulationEvent *pEvt)
When a new event has been created, it must be injected into the simulation using this function...
Definition: population.cpp:457
int getNumberOfWomen() const
Returns the number of people in the array returned by Population::getWomen.
Definition: population.h:121
A very naive implementation of the necessary functions from the State class.
Definition: simplestate.h:86