Utopia  2
Framework for studying models of complex & adaptive systems.
state.hh
Go to the documentation of this file.
1 #ifndef UTOPIA_MODELS_SEIRD_STATE_HH
2 #define UTOPIA_MODELS_SEIRD_STATE_HH
3 
4 #include <algorithm>
5 
6 #include <utopia/core/types.hh>
7 
8 
9 namespace Utopia::Models::SEIRD
10 {
11 
12 // -- Kind enum (and related constants) ---------------------------------------
13 
15 enum class Kind : char
16 {
18  empty = 0,
20  susceptible = 1,
22  exposed = 2,
24  infected = 3,
26  recovered = 4,
28  deceased = 5,
30  source = 6,
32  inert = 7,
33 
35 
38  COUNT = 8,
39 };
40 
42 const std::map<const std::string, Kind> kind_from_string {
43  {"empty", Kind::empty},
44  {"susceptible", Kind::susceptible},
45  {"exposed", Kind::exposed},
46  {"infected", Kind::infected},
47  {"recovered", Kind::recovered},
48  {"deceased", Kind::deceased},
49  {"source", Kind::source},
50  {"inert", Kind::inert}
51 };
52 
54 
56 const std::map<const Kind, std::string> string_from_kind =
57  [](){
58  auto sfk = std::map<const Kind, std::string>{};
59 
60  for (auto i = 0u; i < static_cast<char>(Kind::COUNT); i++) {
61  const Kind kind = static_cast<Kind>(i);
62  const auto item =
63  std::find_if(kind_from_string.begin(), kind_from_string.end(),
64  [&](const auto& kv){ return kv.second == kind; });
65  sfk[kind] = item->first;
66  }
67 
68  return sfk;
69  }();
70 
72 
76 const std::array<std::string, static_cast<char>(Kind::COUNT)> kind_names =
77  [](){
78  auto names = std::array<std::string, static_cast<char>(Kind::COUNT)>{};
79  for (auto i = 0u; i < static_cast<char>(Kind::COUNT); i++) {
80  names[i] = string_from_kind.at(static_cast<Kind>(i));
81  }
82  return names;
83  }();
84 
85 
86 // -- State -------------------------------------------------------------------
87 
89 struct State
90 {
93 
95  bool immune;
96 
99  double p_transmit;
100 
102  unsigned exposed_time;
103 
105  unsigned age;
106 
108  unsigned num_recoveries;
109 
111  unsigned int cluster_id;
112 
114  template<class RNG>
115  State(const DataIO::Config& cfg, const std::shared_ptr<RNG>& rng)
116  :
117  kind(Kind::empty),
118  immune(false),
119  p_transmit(1),
120  exposed_time(0),
121  age(0),
122  num_recoveries(0),
123  cluster_id(0)
124  {
125  // Check if p_susceptible is available to set up cell state
126  if (cfg["p_susceptible"]) {
127  const auto init_density = get_as<double>("p_susceptible", cfg);
128 
129  if (init_density < 0. or init_density > 1.) {
130  throw std::invalid_argument("p_susceptible needs to be in "
131  "interval [0., 1.], but was " +
132  std::to_string(init_density) + "!");
133  }
134 
135  // With this probability, the cell state is a susceptible
136  if (std::uniform_real_distribution<double>(0., 1.)(*rng) <
137  init_density) {
139  }
140 
141  // If cells are susceptible check whether they are immune
142  // Check if p_immune is available to set up cell state
143  if (cfg["p_immune"]) {
144  const auto init_density = get_as<double>("p_immune", cfg);
145 
146  if (init_density < 0. or init_density > 1.) {
147  throw std::invalid_argument("p_immune needs to be in "
148  "interval [0., 1.], but was " +
149  std::to_string(init_density) +
150  "!");
151  }
152 
153  // With this probability, the cell state is immune
154  if (std::uniform_real_distribution<double>(0., 1.)(*rng) <
155  init_density) {
156  immune = true;
157  }
158  else {
159  immune = false;
160  }
161  }
162  }
163  // Check if p_transmit is available to set up cell state
164  if (cfg["p_transmit"]) {
165  p_transmit = initialize_p_transmit(cfg["p_transmit"], rng);
166  }
167  }
168 
170  template<typename RNG>
171  static double initialize_p_transmit(const DataIO::Config& cfg,
172  const std::shared_ptr<RNG>& rng)
173  {
174  const auto mode = get_as<std::string>("mode", cfg);
175 
176  if (mode == "value") {
177  // Return the default value
178  return get_as<double>("default",
179  get_as<DataIO::Config>("value", cfg));
180  }
181  else if (mode == "uniform") {
182  const auto range = get_as<std::pair<double, double>>(
183  "range",
184  get_as<DataIO::Config>("uniform", cfg));
185 
186  // Create a uniform real distribution from the specified range
187  std::uniform_real_distribution<double> distr(range.first,
188  range.second);
189 
190  // Draw a random number from the range and return it
191  return distr(*rng);
192  }
193  else {
194  throw std::invalid_argument(fmt::format(
195  "Invalid mode! Need be either 'value' or 'uniform', was '{}'!",
196  mode)
197  );
198  }
199  };
200 };
201 
202 } // namespace Utopia::Models::SEIRD
203 
204 #endif // UTOPIA_MODELS_SEIRD_STATE_HH
@ empty
Every entity is utterly alone in the world.
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
std::string to_string(const Config &node)
Given a config node, returns a string representation of it.
Definition: cfg_utils.hh:110
decltype(auto) range(const Graph &g)
Get the iterator range over selected graph entities.
Definition: iterator.hh:149
std::mt19937 rng
– Type definitions ----------------------------------------------------—
Definition: test_revision.cc:17
Definition: counters.hh:10
const std::map< const std::string, Kind > kind_from_string
Map the Kind name given as a string to the actual Kind.
Definition: state.hh:42
const std::map< const Kind, std::string > string_from_kind
The inverse of the kind_from_string mapping.
Definition: state.hh:56
Kind
The kind of the cell.
Definition: state.hh:16
@ source
Cell is an infection source: constantly infected, spreading infection.
@ inert
Cell does not partake in the dynamics.
@ COUNT
The number of kinds (COUNT)
@ recovered
Cell is recovered.
@ infected
Cell is infected.
@ deceased
Cell is deceased.
@ exposed
Cell is exposed to the dease but not yet infected.
@ susceptible
Cell represents a susceptible.
const std::array< std::string, static_cast< char >Kind::COUNT)> kind_names
The associated string names of each Kind enum entry.
Definition: state.hh:76
The full cell struct for the SEIRD model.
Definition: state.hh:90
unsigned age
The age of the cell.
Definition: state.hh:105
double p_transmit
Definition: state.hh:99
unsigned int cluster_id
An ID denoting to which cluster this cell belongs.
Definition: state.hh:111
static double initialize_p_transmit(const DataIO::Config &cfg, const std::shared_ptr< RNG > &rng)
Initialize p_transmit from a configuration node.
Definition: state.hh:171
unsigned num_recoveries
The number of recoveries.
Definition: state.hh:108
Kind kind
The cell state.
Definition: state.hh:92
bool immune
Whether the agent is immune.
Definition: state.hh:95
unsigned exposed_time
The time passed since first being exposed.
Definition: state.hh:102
State(const DataIO::Config &cfg, const std::shared_ptr< RNG > &rng)
Construct the cell state from a configuration and an RNG.
Definition: state.hh:115