Stride Reference Manual  1.0
Population.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This is free software: you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 3 of the License, or
6  * any later version.
7  * The software is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License
12  * along with the software. If not, see <http://www.gnu.org/licenses/>.
13  *
14  * Copyright 2017, Willem L, Kuylen E, Stijven S & Broeckhove J
15  */
16 
22 #include "Person.h"
23 #include "core/Health.h"
24 #include "sim/Simulator.h"
25 #include "util/SimplePlanner.h"
26 
27 #include <numeric>
28 #include <vector>
29 
30 namespace stride {
31 
32 using namespace std;
33 using namespace util;
34 
35 class Population;
36 
37 // Writing your own iterator 101
38 // Forward? Backward? Random access? Constness?
39 // PopT is either `Population` or `const Population`
40 template<typename PopT, typename IterT>
42 protected:
43  _PopulationIterator(PopT& pop, unsigned int index, bool in_planner = false, unsigned int day = 0)
44  : m_pop(pop), m_in_planner(in_planner), m_index(index), m_day(day) {}
45 
46  friend class Population;
47 
48  void next() {
49  m_index++;
50  if (not m_in_planner) {
51  if (m_index >= m_pop.m_original.size()) {
52  m_in_planner = true;
53  m_index = 0;
54  m_day = 0;
55  m_day_iter = m_pop.m_visitors.getAgenda().begin();
56  }
57  }
58  if (m_in_planner) {
59  while (true) {
60  if (m_day >= m_pop.m_visitors.days()) {
61  m_index = 0;
62  break;
63  } else if ((m_index >= m_pop.m_visitors.getDay(m_day)->size())) {
64  m_day++;
65  m_day_iter++;
66  m_index = 0;
67  } else {
68  break;
69  }
70  }
71  }
72  }
73 
74  void trueNext() {
75  if (isEnd()) {
76  return;
77  }
78  while (true) {
79  next();
80  if (isEnd()) {
81  return;
82  }
83  if (m_in_planner or (not(*(*this)).isOnVacation())) {
84  return;
85  }
86  }
87  }
88 
89 public:
90 
91  void operator++(int) { trueNext(); }
92 
93  void operator++() { trueNext(); }
94 
95  bool operator==(const _PopulationIterator& other) const {
96  return &m_pop == &(other.m_pop)
97  and m_in_planner == other.m_in_planner
98  and m_index == other.m_index
99  and m_day == other.m_day;
100  }
101 
102  bool operator!=(const _PopulationIterator& other) const {
103  return not(*this == other);
104  }
105 
106  const typename PopT::PersonType& operator*() const {
107  if (m_in_planner) return *((*m_day_iter->get()).at(m_index));
108  else return m_pop.m_original.at(m_index);
109  }
110 
111  bool isEnd() {
112  return m_in_planner
113  and m_index == 0
114  and m_day == m_pop.m_visitors.days();
115  }
116 
117 protected:
118  PopT& m_pop;
120  unsigned int m_index; // when in planner, denotes the index within the day
121  unsigned int m_day; // not used when not in planner
122  IterT m_day_iter;
123 };
124 
125 class PopulationIterator;
126 
128 
132 class Population {
133 public:
134  Population() = default;
135 
138  using VectorType = vector<PersonType>;
139 
141  unsigned int getInfectedCount() const;
142 
143  double getFractionInfected() const {
144  return getInfectedCount() / (this->m_original.size() + this->m_visitors.size());
145  }
146 
147  size_t size() const {
148  return m_original.size() + m_visitors.size();
149  }
150 
151  template<typename BeliefPolicy>
152  unsigned int getAdoptedCount() const;
153 
154  PopulationIterator begin();
155 
156  PopulationIterator end();
157 
158  ConstPopulationIterator begin() const;
159 
160  ConstPopulationIterator end() const;
161 
162  // These are public, since otherwise I'd have to proxy literally every operation.
165 
166  // standard library style
169 };
170 
171 
173 
174 class PopulationIterator : public _PopIter {
175 public:
176  friend class Population;
177 
179 
180  Population::PersonType& operator*() const;
181 };
182 
183 
185 
187 public:
188  friend class Population;
189 
191 };
192 
193 template<typename BeliefPolicy>
194 unsigned int Population::getAdoptedCount() const {
195  unsigned int total {0U};
196 
197  for (const auto& p: *this) {
198  auto belief_data = p.getBeliefData();
199  bool adopted = BeliefPolicy::hasAdopted(belief_data);
200  if (adopted) {
201  total++;
202  }
203  }
204  return total;
205 }
206 
207 
208 }
Person< BehaviourPolicy, BeliefPolicy > PersonType
Definition: Simulator.h:72
VectorType m_original
Definition: Population.h:163
bool operator==(const _PopulationIterator &other) const
Definition: Population.h:95
size_t size() const
Definition: Population.h:147
Time Dependent Person DataType.
Definition: NoBehaviour.h:17
PlannerType m_visitors
Definition: Population.h:164
Header file for the Person class.
Header for the Simulator class.
bool operator!=(const _PopulationIterator &other) const
Definition: Population.h:102
Container for persons in population.
Definition: Population.h:132
Forward declaration of class Person.
Definition: ThresholdData.h:15
unsigned int getAdoptedCount() const
Definition: Population.h:194
double getFractionInfected() const
Definition: Population.h:143
STL namespace.
vector< PersonType > VectorType
Definition: Population.h:138
_PopulationIterator(PopT &pop, unsigned int index, bool in_planner=false, unsigned int day=0)
Definition: Population.h:43
const PopT::PersonType & operator*() const
Definition: Population.h:106