Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
env_param_func_collection.hh
Go to the documentation of this file.
1#ifndef UTOPIA_MODELS_ENVIRONMENT_ENVPARAMFUNCCOLLECTION_HH
2#define UTOPIA_MODELS_ENVIRONMENT_ENVPARAMFUNCCOLLECTION_HH
3
4#include <math.h>
5
6#include "tools.hh"
7
9namespace ParameterFunctionCollection {
10
11
14
15// -- Helper functions --------------------------------------------------------
16
18
21template<typename EnvModel, class DistType,
22 class EnvParamFunc = typename EnvModel::EnvParamFunc>
23EnvParamFunc
25 DistType&& dist,
26 const std::string& param_name,
27 const ValMode& mode)
28{
29 // NOTE It is VITAL to move-construct the perfectly-forwarded dist into
30 // the lambda; otherwise it has to be stored outside, which is a
31 // real pita. Also, the lambda has to be declared mutable such
32 // that the captured object are allowed to be changed; again, this
33 // is only relevant for the distribution's internal state ...
34 return
35 [&model, param_name, mode, dist{std::move(dist)}] () mutable {
36 double current_value = 0.;
37 if (mode == ValMode::Add) {
38 current_value = model.get_parameter(param_name);
39 }
40 const double rn = dist(*model.get_rng());
41
42 return current_value + rn;
43 };
44}
45
51// -- Environment parameter modification functions ----------------------------
52// .. Keep these in alphabetical order and prefix with _epf_ ! .............
53// NOTE The methods below do _not_ change any state, they just generate
54// a function object that does so at the desired point in time.
55
57
71template<typename EnvModel,
72 class EnvParamFunc = typename EnvModel::EnvParamFunc>
73EnvParamFunc epf_increment(const EnvModel& model, const std::string param_name,
74 const Config& cfg)
75{
76 const auto value = get_as<double>("value", cfg);
77 EnvParamFunc epf = [&model, param_name, value] () mutable
78 {
79 return model.get_parameter(param_name) + value;
80 };
81
82 return epf;
83}
84
86
104template<typename EnvModel,
105 class EnvParamFunc = typename EnvModel::EnvParamFunc>
106EnvParamFunc epf_random(const EnvModel& model, const std::string& param_name,
107 const Config& cfg)
108{
109 const auto mode = extract_val_mode(cfg, "random");
110 const auto distribution = get_as<std::string>("distribution", cfg);
111
112 // Depending on chosen distribution, construct it and build a rule
113 // function using a reference to the newly created one...
114 if (distribution == "normal") {
115 const auto mean = get_as<double>("mean", cfg);
116 const auto stddev = get_as<double>("stddev", cfg);
117 std::normal_distribution<> dist(mean, stddev);
118
119 return build_rng_env_param_func(model, std::move(dist), param_name,
120 mode);
121 }
122 else if (distribution == "poisson") {
123 const auto mean = get_as<double>("mean", cfg);
124 std::poisson_distribution<> dist(mean);
125
126 return build_rng_env_param_func(model, std::move(dist), param_name,
127 mode);
128 }
129 else if (distribution == "exponential") {
130 const auto lambda = get_as<double>("lambda", cfg);
131 std::exponential_distribution<> dist(lambda);
132
133 return build_rng_env_param_func(model, std::move(dist), param_name,
134 mode);
135 }
136 else if (distribution == "uniform_int") {
137 auto interval = get_as<std::array<int, 2>>("interval", cfg);
138 std::uniform_int_distribution<> dist(interval[0], interval[1]);
139
140 return build_rng_env_param_func(model, std::move(dist), param_name,
141 mode);
142 }
143 else if (distribution == "uniform_real" or distribution == "uniform") {
144 auto interval = get_as<std::array<double, 2>>("interval", cfg);
145 std::uniform_real_distribution<> dist(interval[0], interval[1]);
146
147 return build_rng_env_param_func(model, std::move(dist), param_name,
148 mode);
149 }
150 else {
151 throw std::invalid_argument("No method implemented to resolve "
152 "noise distribution '" + distribution + "'! Valid options: "
153 "normal, poisson, uniform_int, uniform_real.");
154 }
155};
156
158
179template<typename EnvModel,
180 class EnvParamFunc = typename EnvModel::EnvParamFunc>
181EnvParamFunc epf_rectangular(const EnvModel& model, const Config& cfg)
182{
183 using Time = typename EnvModel::Time;
184
185 double min_value = get_as<double>("offset", cfg, 0.);
186 double max_value = get_as<double>("amplitude", cfg) + min_value;
187 Time period = get_as<Time>("period", cfg);
188 Time time_in_max = get_as<Time>("time_in_max", cfg, period / 2.);
189 double phase = get_as<double>("phase", cfg, 0) * period;
190
191 // Check parameter
192 if (time_in_max > period) {
193 throw std::invalid_argument("The `time_in_max` argument cannot be "
194 "larger than the `period` argument in rectangular "
195 "environment parameter function!");
196 }
198 throw std::invalid_argument("The `phase` argument was not in interval "
199 "[0., 1.]!");
200 }
201
202 // get starting time
204
205 // Build function
206 EnvParamFunc epf = [&model, max_value, min_value,
207 period, time_in_max, phase, time_start] () mutable
208 {
209 auto time = (model.get_time()+1 - time_start) % period;
210 if (time >= phase and time < time_in_max + phase) {
211 return max_value;
212 }
213 return min_value;
214 };
215
216 return epf;
217}
218
220
234template<typename EnvModel,
235 class EnvParamFunc = typename EnvModel::EnvParamFunc>
236EnvParamFunc epf_set(const EnvModel&, const Config& cfg)
237{
238 const auto value = get_as<double>("value", cfg);
239 EnvParamFunc epf = [value] () mutable
240 {
241 return value;
242 };
243
244 return epf;
245}
246
248
268template<typename EnvModel,
269 class EnvParamFunc = typename EnvModel::EnvParamFunc>
270EnvParamFunc epf_sinusoidal(const EnvModel& model, const Config& cfg)
271{
272 using Time = typename EnvModel::Time;
273
274 const auto period = get_as<double>("period", cfg);
275 const auto amplitude = get_as<double>("amplitude", cfg);
276 double phase = 0;
277 if (cfg["phase"]) {
278 phase = get_as<double>("phase", cfg);
279 }
280 double offset = 0.;
281 if (cfg["offset"]) {
282 offset = get_as<double>("offset", cfg);
283 }
284
285 // get starting time
287
288 EnvParamFunc epf = [&model, period, amplitude,
289 phase, offset, time_start] () mutable
290 {
291 double x = (model.get_time() + 1 - time_start)/period * 2*M_PI;
292 return offset + amplitude * sin(x + phase * M_PI);
293 };
294
295 return epf;
296}
297
298// end group Environment
303} // namespace ParameterFunctionCollection
304} // namespace Utopia::Models::Environment
305
306#endif
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition types.hh:71
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
EnvParamFunc epf_sinusoidal(const EnvModel &model, const Config &cfg)
Creates a rule function for sinusoidal parameter values.
Definition env_param_func_collection.hh:270
EnvParamFunc epf_random(const EnvModel &model, const std::string &param_name, const Config &cfg)
Creates a rule function for random parameter values.
Definition env_param_func_collection.hh:106
EnvParamFunc epf_increment(const EnvModel &model, const std::string param_name, const Config &cfg)
Creates a rule function for incrementing parameter values.
Definition env_param_func_collection.hh:73
ValMode extract_val_mode(const DataIO::Config &cfg, const std::string &context)
Given a configuration node, extract the value mode.
Definition tools.hh:19
EnvParamFunc epf_rectangular(const EnvModel &model, const Config &cfg)
Creates a rule function for rectangular function like parameter values.
Definition env_param_func_collection.hh:181
EnvParamFunc epf_set(const EnvModel &, const Config &cfg)
Creates a rule function for setting a parameter value.
Definition env_param_func_collection.hh:236
ValMode
Value calculation mode.
Definition tools.hh:10
@ Add
Add the new value to the existing value.
EnvParamFunc build_rng_env_param_func(const EnvModel &model, DistType &&dist, const std::string &param_name, const ValMode &mode)
Create a rule function that uses a random number distribution.
Definition env_param_func_collection.hh:24
DataIO::Config Config
Configuration node type alias.
Definition env_param_func_collection.hh:13
Definition env_param_func_collection.hh:8
unsigned int DistType
Type for distancens, i.e. intermediately long unsigned integers.
Definition types.hh:37