Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
CopyMeGrid.hh
Go to the documentation of this file.
1#ifndef UTOPIA_MODELS_COPYMEGRID_HH
2#define UTOPIA_MODELS_COPYMEGRID_HH
3// TODO Adjust above include guard (and at bottom of file)
4
5// standard library includes
6#include <random>
7
8// third-party library includes
9
10// Utopia-related includes
11#include <utopia/core/model.hh>
13#include <utopia/core/apply.hh>
14
15
17
18// ++ Type definitions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19
21struct CellState {
23 double some_state;
24
27
30
33 :
34 some_state(get_as<double>("some_state", cfg)),
35 some_trait(get_as<int>("some_trait", cfg)),
37 {}
38
40 template<class RNG>
41 CellState(const DataIO::Config& cfg, const std::shared_ptr<RNG>& rng)
42 :
43 // Use the config constructor to get the values
44 CellState(cfg)
45 {
46 // Do some more things using the random number generator
47 // There is the possibility to set a random initial trait
48 if (cfg["random_initial_trait"]) {
49 if (not get_as<bool>("random_initial_trait", cfg)) {
50 // Is set, but is false. Just return:
51 return;
52 }
53
54 // Choose a random value between 0 and the current value
55 some_trait = std::uniform_int_distribution(0, some_trait)(*rng);
56 }
57 // else: the config option was not available
58 }
59};
60
61
63
69
70
73
74
75// ++ Model definition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
76
78
84 public Model<CopyMeGrid, ModelTypes>
85{
86public:
89
91 using DataGroup = typename Base::DataGroup;
92
94 using DataSet = typename Base::DataSet;
95
98 // NOTE that it requires the model's type as second template argument
99
101
109
110
111private:
112 // Base members: _time, _name, _cfg, _hdfgrp, _rng, _monitor, _log, _space
113 // ... but you should definitely check out the documentation ;)
114
115 // -- Members -------------------------------------------------------------
118
121
122 // More parameters here ...
123
124
126 std::uniform_real_distribution<double> _prob_distr;
127
128 // .. Temporary objects ...................................................
129
130
131 // .. Datasets ............................................................
132 // NOTE They should be named '_dset_<name>', where <name> is the
133 // dataset's actual name as set in its constructor. If you are using
134 // data groups, prefix them with _dgrp_<groupname>
136 std::shared_ptr<DataSet> _dset_some_state;
137
139 std::shared_ptr<DataSet> _dset_some_trait;
140
141
142public:
143 // -- Model Setup ---------------------------------------------------------
144
146
154 template<class ParentModel>
156 const std::string& name,
158 const DataIO::Config& custom_cfg = {}
159 )
160 :
161 // Initialize first via base model
163
164 // Now initialize the cell manager
165 _cm(*this),
166
167 // Initialize model parameters
168 _some_parameter(get_as<double>("some_parameter", this->_cfg)),
169 // ...
170
171 // Initialize the uniform real distribution to range [0., 1.]
172 _prob_distr(0., 1.),
173
174 // Datasets
175 // For setting up datasets that store CellManager data, you can use the
176 // helper functions to take care of setting them up:
177 _dset_some_state(this->create_cm_dset("some_state", _cm)),
178 _dset_some_trait(this->create_cm_dset("some_trait", _cm))
179 // NOTE To set up datasets that have a different shape, we suggest to
180 // use the Model::create_dset helper, which already takes care of
181 // using the correct length into the time dimension (depending on
182 // the num_steps and write_every parameters). The syntax is:
183 //
184 // this->create_dset("mean_state", {}) // 1D {#writes}
185 // this->create_dset("a_vec", {num_cols}) // 2D {#writes, #cols}
186 {
187 // Can do remaining initialization steps here ...
188 // Example:
189 apply_rule([this](const auto& cell){
190 auto state = cell->state();
191
192 // Every 13th cell (on average) is a VIP cell
193 if (this->_prob_distr(*this->_rng) < (1./13.)) {
194 state.is_a_vip_cell = true;
195 }
196
197 return state;
198 }, _cm.cells());
199 // NOTE Compare this to the apply_rule calls in the perform_step method
200 // where a _stored_ lambda function is passed to it. For the setup
201 // done here, the function is only used once; thus, it makes more
202 // sense to just use a temporary lambda.
203
204 this->_log->debug("VIP cells set up.");
205
206 // NOTE The initial state need and should NOT be written here. The
207 // write_data method is invoked first at time `write_start`.
208 // However, this is a good place to store data that is constant
209 // during the run and needs to be written at some point.
210
211 // Initialization should be finished here.
212 this->_log->debug("{} model fully set up.", this->_name);
213 }
214
215
216private:
217 // .. Setup functions .....................................................
218 // Can add additional setup functions here ...
219
220
221 // .. Helper functions ....................................................
222
224 double calc_some_state_mean () const {
225 double sum = 0.;
226 for (const auto &cell : _cm.cells()) {
227 sum += cell->state().some_state;
228 }
229 return sum / _cm.cells().size();
230 }
231
232
233 // .. Rule functions ......................................................
234 // Rule functions that can be applied to the CellManager's cells
235 // NOTE The below are examples; delete and/or adjust them to your needs!
236 // Ideally, only define those rule functions as members that are used
237 // more than once.
238
240 const RuleFunc _some_interaction = [this](const auto& cell){
241 // Get the current state of the cell
242 auto state = cell->state();
243
244 // Increase some_state by one
245 state.some_state += 1;
246
247 // Iterate over all neighbors of the current cell
248 for (auto& nb : this->_cm.neighbors_of(cell)) {
249 // Obvious thing to do is to increase some_trait by the sum of
250 // some_traits's of the neighbor. Sure thing.
251 state.some_trait += nb->state().some_trait;
252
253 // Let's add a random number in range [-1, +1] as well
254 state.some_trait += (this->_prob_distr(*this->_rng) * 2. - 1.);
255 }
256
257 // Ahhh and obviously you need to divide some float by _some_parameter
258 // because that makes totally sense
259 state.some_trait /= this->_some_parameter;
260
261 // Return the new cell state
262 return state;
263 };
264
265
267 const RuleFunc _some_other_rule = [this](const auto& cell){
268 // Get the current state of the cell
269 auto state = cell->state();
270
271 // With a probability of 0.3 set the cell's state.some_state to 0
272 if (this->_prob_distr(*this->_rng) < 0.3) {
273 state.some_state = 0;
274 }
275
276 // Return the new cell state
277 return state;
278 };
279
280
281public:
282 // -- Public Interface ----------------------------------------------------
283 // .. Simulation Control ..................................................
284
286
289 void perform_step () {
290 // Apply the rules to all cells, first the interaction, then the update
293 }
294
295
297
305 void monitor () {
306 this->_monitor.set_entry("some_value", 42);
307 this->_monitor.set_entry("state_mean", calc_some_state_mean());
308 }
309
310
312
316 void write_data () {
317 // Write out the some_state of all cells
318 _dset_some_state->write(_cm.cells().begin(), _cm.cells().end(),
319 [](const auto& cell) {
320 return cell->state().some_state;
321 });
322
323 // Write out the some_trait of all cells
324 _dset_some_trait->write(_cm.cells().begin(), _cm.cells().end(),
325 [](const auto& cell) {
326 return cell->state().some_trait;
327 });
328 }
329
330
331 // .. Getters and setters .................................................
332 // Add getters and setters here to interface with other models
333
334};
335
336} // namespace Utopia::Models::CopyMeGrid
337
338#endif // UTOPIA_MODELS_COPYMEGRID_HH
typename std::function< CellState(const std::shared_ptr< Cell > &)> RuleFunc
The type of a rule function acting on cells of this cell manager.
Definition cell_manager.hh:84
CellContainer< Cell > neighbors_of(const Cell &cell) const
Retrieve the given cell's neighbors.
Definition cell_manager.hh:458
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition cell_manager.hh:219
Base class interface for Models using the CRT Pattern.
Definition model.hh:112
std::shared_ptr< DataSet > create_cm_dset(const std::string name, const CellManager &cm, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
Create a dataset storing data from a CellManager.
Definition model.hh:849
Monitor _monitor
The monitor.
Definition model.hh:188
typename ModelTypes::DataSet DataSet
Data type that is used for storing data.
Definition model.hh:125
const Config _cfg
Config node belonging to this model instance.
Definition model.hh:158
const std::string _name
Name of the model instance.
Definition model.hh:149
typename ModelTypes::DataGroup DataGroup
Data type that is used for storing datasets.
Definition model.hh:122
const std::shared_ptr< spdlog::logger > _log
The (model) logger.
Definition model.hh:164
const std::shared_ptr< RNG > _rng
The RNG shared between models.
Definition model.hh:161
The CopyMeGrid Model; a good start for a CA-based model.
Definition CopyMeGrid.hh:85
typename CellManager::RuleFunc RuleFunc
Extract the type of the rule function from the CellManager.
Definition CopyMeGrid.hh:108
const RuleFunc _some_other_rule
Some other rule function.
Definition CopyMeGrid.hh:267
double _some_parameter
Some parameter.
Definition CopyMeGrid.hh:120
CellManager _cm
The cell manager.
Definition CopyMeGrid.hh:117
typename Base::DataGroup DataGroup
Data type of the group to write model data to, holding datasets.
Definition CopyMeGrid.hh:91
std::uniform_real_distribution< double > _prob_distr
A re-usable uniform real distribution to evaluate probabilities.
Definition CopyMeGrid.hh:126
void monitor()
Monitor model information.
Definition CopyMeGrid.hh:305
std::shared_ptr< DataSet > _dset_some_trait
A dataset for storing all cells' some_trait.
Definition CopyMeGrid.hh:139
std::shared_ptr< DataSet > _dset_some_state
A dataset for storing all cells' some_state.
Definition CopyMeGrid.hh:136
void write_data()
Write data.
Definition CopyMeGrid.hh:316
Model< CopyMeGrid, ModelTypes > Base
The type of the Model base class of this derived class.
Definition CopyMeGrid.hh:88
CopyMeGrid(const std::string &name, ParentModel &parent_model, const DataIO::Config &custom_cfg={})
Construct the CopyMeGrid model.
Definition CopyMeGrid.hh:155
double calc_some_state_mean() const
Calculate the mean of all cells' some_state.
Definition CopyMeGrid.hh:224
void perform_step()
Iterate a single step.
Definition CopyMeGrid.hh:289
const RuleFunc _some_interaction
An interaction function of a single cell with its neighbors.
Definition CopyMeGrid.hh:240
typename Base::DataSet DataSet
Data type for a dataset.
Definition CopyMeGrid.hh:94
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition types.hh:71
ReturnType get_as(const std::string &key, const DataIO::Config &node)
This function is a wrapper around the yaml-cpp YAML::Node::as function.
Definition cfg_utils.hh:158
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
void apply_rule(Rule &&rule, const ContTarget &cont_target, ContArgs &&... cont_args)
Sequential overload.
Definition apply.hh:133
Definition CopyMeGrid.hh:16
The entity traits struct gathers types to be used for specializing an entity.
Definition entity.hh:49
Wrapper struct for defining model class data types.
Definition model.hh:92
The type of a cell's state.
Definition CopyMeGrid.hh:21
int some_trait
Another useful documentation string, yeah.
Definition CopyMeGrid.hh:26
double some_state
A useful documentation string.
Definition CopyMeGrid.hh:23
CellState(const DataIO::Config &cfg, const std::shared_ptr< RNG > &rng)
Construct the cell state from a configuration and an RNG.
Definition CopyMeGrid.hh:41
CellState(const DataIO::Config &cfg)
Construct the cell state from a configuration.
Definition CopyMeGrid.hh:32
bool is_a_vip_cell
Whether this cell is very important.
Definition CopyMeGrid.hh:29