1 #ifndef UTOPIA_MODELS_SIMPLEEG_HH
2 #define UTOPIA_MODELS_SIMPLEEG_HH
71 public Model<SimpleEG, ModelTypes>
143 template<
class ParentModel>
145 const std::string& name,
146 ParentModel& parent_model,
151 Base(name, parent_model, custom_cfg),
171 this->
_hdfgrp->add_attribute(
"ia_matrix", _ia_matrix);
184 static_assert(Base::Space::dim == 2,
"Only 2D space is supported.");
187 auto initial_state = get_as<std::string>(
"initial_state", this->
_cfg);
189 this->
_log->info(
"Initializing cells in '{}' mode ...", initial_state);
192 if (initial_state ==
"random") {
194 const auto s1_prob = get_as<double>(
"s1_prob", this->
_cfg);
197 auto set_random_strategy = [
this, &s1_prob](
const auto cell) {
198 auto state = cell->state();
215 else if (initial_state ==
"fraction") {
217 const auto s1_fraction = get_as<double>(
"s1_fraction", this->
_cfg);
219 if (s1_fraction > 1. or s1_fraction < 0.) {
220 throw std::invalid_argument(
"Need `s1_fraction` in [0, 1], "
225 const auto num_cells =
_cm.
cells().size();
226 const std::size_t num_s1 = s1_fraction * num_cells;
229 this->
_log->debug(
"Cells with strategy 1: {} of {}",
237 std::size_t num_set = 0;
241 std::shuffle(random_cells.begin(), random_cells.end(),
245 for (
const auto& cell : random_cells) {
247 if (num_set < num_s1) {
264 else if (initial_state ==
"single_s0" or initial_state ==
"single_s1"){
266 const auto& grid_shape =
_cm.
grid()->shape();
269 if (grid_shape[0] % 2 == 0 or grid_shape[1] % 2 == 0) {
270 throw std::invalid_argument(
"In mode '" + initial_state +
"', "
271 "odd grid extensions are required to calculate the "
272 "central cell! Either adapt your grid resolution or the "
273 "space's extent in order to have a different shape. "
284 Strategy default_strategy, single_strategy;
285 if (initial_state ==
"single_s0") {
295 auto set_initial_strategy = [&](
const auto& cell) {
297 auto state = cell->state();
302 if ( midx[0] == grid_shape[0] / 2
303 and midx[1] == grid_shape[1] / 2) {
305 state.strategy = single_strategy;
309 state.strategy = default_strategy;
319 throw std::invalid_argument(
"Invalid value '" + initial_state
320 +
"' for parameter `initial_state`! Allowed values: random, "
321 "fraction, single_s0, single_s1.");
325 this->
_log->info(
"Initialized all {} cells.", _cm.
cells().size());
358 if (this->
_cfg[
"ia_matrix"]) {
359 return get_as<IAMatrixType>(
"ia_matrix", this->
_cfg);
361 else if (this->
_cfg[
"bc_pair"]) {
364 const auto [b, c] = get_as<std::pair<double, double>>(
"bc_pair",
366 const double ia_00 = b - c;
367 const double ia_01 = -c;
368 const double ia_10 = b;
369 const double ia_11 = 0.;
371 const std::array<double,2> row0({{ia_00, ia_01}});
372 const std::array<double,2> row1({{ia_10, ia_11}});
376 else if (this->
_cfg[
"b"]) {
379 const auto b = get_as<double>(
"b", this->
_cfg);
382 throw std::invalid_argument(
"Parameter `b` needs to be >1, "
386 const double ia_00 = 1;
387 const double ia_01 = 0;
388 const double ia_10 = b;
389 const double ia_11 = 0.;
391 const std::array<double, 2> row0({{ia_00, ia_01}});
392 const std::array<double, 2> row1({{ia_10, ia_11}});
398 throw std::invalid_argument(
"No interaction matrix given! Check that "
399 "at least one of the following config "
400 "entries is available: `ia_matrix`, "
414 auto state = cell->state();
424 const auto nb_strategy = nb->state().strategy;
428 if (state.strategy ==
S0 and nb_strategy ==
S0) {
431 else if (state.strategy ==
S0 and nb_strategy ==
S1) {
434 else if (state.strategy ==
S1 and nb_strategy ==
S0) {
437 else if (state.strategy ==
S1 and nb_strategy ==
S1) {
460 auto state = cell->state();
463 double highest_payoff = state.payoff;
469 if (nb->state().payoff > highest_payoff) {
471 highest_payoff = nb->state().payoff;
475 else if (nb->state().payoff == highest_payoff) {
496 throw std::runtime_error(
"There was no fittest neighbor in the "
497 "cell update. Should not have occurred!");
535 [](
const auto& cell) {
536 return static_cast<unsigned short int>(cell->state().strategy);
542 [](
const auto& cell) {
543 return cell->state().payoff;
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition: cell_manager.hh:219
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
MultiIndex midx_of(const Cell &cell) const
Returns the multi-index of the given cell.
Definition: cell_manager.hh:236
const std::shared_ptr< GridType > & grid() const
Return const reference to the grid.
Definition: cell_manager.hh:214
CellContainer< Cell > neighbors_of(const Cell &cell) const
Retrieve the given cell's neighbors.
Definition: cell_manager.hh:458
Base class interface for Models using the CRT Pattern.
Definition: model.hh:112
const std::shared_ptr< DataGroup > _hdfgrp
The HDF group this model instance should write its data to.
Definition: model.hh:176
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
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
typename ModelTypes::Config Config
Data type that holds the configuration.
Definition: model.hh:116
typename ModelTypes::RNG RNG
Data type of the shared RNG.
Definition: model.hh:128
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
Simple model of evolutionary games on grids.
Definition: SimpleEG.hh:72
typename CellManager::RuleFunc RuleFunc
Extract the type of the rule function from the CellManager.
Definition: SimpleEG.hh:95
typename Base::RNG RNG
Data type of the shared RNG.
Definition: SimpleEG.hh:98
typename Base::Config Config
Data type that holds the configuration.
Definition: SimpleEG.hh:78
RuleFunc _update
The update rule.
Definition: SimpleEG.hh:458
RuleFunc _interaction
The interaction between players.
Definition: SimpleEG.hh:412
CellManager _cm
The cell manager.
Definition: SimpleEG.hh:110
void perform_step()
Iterate a single step.
Definition: SimpleEG.hh:518
std::shared_ptr< DataSet > _dset_payoff
Stores cell payoffs over time.
Definition: SimpleEG.hh:129
std::shared_ptr< DataSet > _dset_strategy
Stores cell strategies over time.
Definition: SimpleEG.hh:126
SimpleEG(const std::string &name, ParentModel &parent_model, const DataIO::Config &custom_cfg={})
Construct the SimpleEG model.
Definition: SimpleEG.hh:144
IAMatrixType extract_ia_matrix() const
Extract the interaction matrix from the config file.
Definition: SimpleEG.hh:356
typename std::array< std::array< double, 2 >, 2 > IAMatrixType
Type of the interaction matrix.
Definition: SimpleEG.hh:101
void monitor()
Monitor model information.
Definition: SimpleEG.hh:526
void write_data()
Write data: the strategy and payoff of each cell.
Definition: SimpleEG.hh:532
void initialize_cells()
Initialize the cells according to initial_state config parameter.
Definition: SimpleEG.hh:183
Model< SimpleEG, ModelTypes > Base
The base model.
Definition: SimpleEG.hh:75
typename Base::DataSet DataSet
Data type for a dataset.
Definition: SimpleEG.hh:81
std::uniform_real_distribution< double > _prob_distr
Uniform real distribution in [0., 1.) used for evaluating probabilities.
Definition: SimpleEG.hh:121
const IAMatrixType _ia_matrix
The interaction matrix (extracted during initialization)
Definition: SimpleEG.hh:113
CellContainer< typename CellManager::Cell > _fittest_cells_in_nbhood
A container to temporarily accumulate the fittest neighbor cells in.
Definition: SimpleEG.hh:118
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
void apply_rule(Rule &&rule, const ContTarget &cont_target, ContArgs &&... cont_args)
Sequential overload.
Definition: apply.hh:133
Strategy
Strategy enum.
Definition: SimpleEG.hh:19
@ S1
Definition: SimpleEG.hh:19
@ S0
Definition: SimpleEG.hh:19
EntityContainer< CellType > CellContainer
Type of the variably sized container for cells.
Definition: types.hh:26
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 the cell state for the SimpleEG model.
Definition: SimpleEG.hh:22
CellState()
Default constructor: strategy S0 and zero payoff.
Definition: SimpleEG.hh:30
double payoff
The payoff.
Definition: SimpleEG.hh:27
Strategy strategy
The strategy.
Definition: SimpleEG.hh:24