bitrl & cuberl Documentation
Simulation engine for reinforcement learning agents
Loading...
Searching...
No Matches
system_state.h
Go to the documentation of this file.
1#ifndef SYSTEM_STATE_H
2#define SYSTEM_STATE_H
3
4#include "bitrl/bitrl_types.h"
5#include "bitrl/extern/nlohmann/json/json.hpp"
6
7#include <algorithm>
8#include <array>
9#include <iomanip> // std::setprecision
10#include <ostream>
11#include <stdexcept>
12#include <string>
13#include <utility>
14#include <vector>
15
16namespace bitrl
17{
18namespace dynamics
19{
20
24template <int dim> class SysState
25{
26
27 public:
31 static const int dimension = dim;
32
36 typedef std::array<std::pair<std::string, real_t>, dim> value_type;
37
41 template <int dim1, int dim2>
42 static void extract(const SysState<dim1> &state, SysState<dim2> &other);
43
48
52 SysState(std::array<std::pair<std::string, real_t>, dim> &&values);
53
58 SysState(std::array<std::string, dim> &&names, real_t val);
59
63 SysState(const SysState<dim> &other);
64
68 template <int other_dim> SysState(const SysState<other_dim> &other);
69
74
79
84
90
96
101
105 real_t get(const std::string &name) const;
106
110 void set(const std::string &name, real_t val);
111
115 void set(uint_t i, const std::pair<std::string, real_t> &value);
116
121 void add(const DynVec<real_t> &container);
122
127 void add(const std::vector<real_t> &container);
128
132 uint_t size() const { return dim; }
133
137 const std::array<real_t, dim> get_values() const;
138
142 const std::vector<std::string_view> get_names() const;
143
148
152 const real_t &operator[](uint_t) const;
153
157 real_t &operator[](const std::string &name) { return this->operator()(name); }
158
162 const real_t &operator[](const std::string &name) const { return this->operator()(name); }
163
167 real_t &operator()(const std::string &name);
168
172 const real_t &operator()(const std::string &name) const;
173
177 real_t &operator()(const std::string_view name) { return (*this)(std::string(name)); }
178
182 const real_t &operator()(const std::string_view name) const
183 {
184 return (*this)(std::string(name));
185 }
186
190 void clear();
191
195 std::ostream &print(std::ostream &out) const;
196
201
205 const std::string as_string() const;
206
209 nlohmann::json as_json() const;
210
214 void scale(real_t val);
215
219 template <typename Container> void set(const Container &container);
220
225 // template<typename Container>
226 // Container get_values_view(uint_t start, uint_t end)const;
227
228 private:
232 std::array<std::pair<std::string, real_t>, dim> values_;
233};
234
235template <int dim>
236template <int dim1, int dim2>
238{
239
240 static_assert(dim2 <= dim1, "Invalid dimension dim2 > dim1");
241
242 for (auto &name : other.get_names())
243 {
244 auto value = state(name);
245 other.set(std::string(name), value);
246 }
247}
248
249template <int dim> SysState<dim>::SysState() : values_()
250{
251 std::for_each(values_.begin(), values_.end(),
252 [](std::pair<std::string, real_t> &item)
253 {
254 item.first = "NO NAME";
255 item.second = 0.0;
256 });
257}
258
259template <int dim>
260SysState<dim>::SysState(std::array<std::pair<std::string, real_t>, dim> &&values) : values_(values)
261{
262}
263
264template <int dim>
265SysState<dim>::SysState(std::array<std::string, dim> &&names, real_t val) : values_()
266{
267 for (uint_t i = 0; i < dim; ++i)
268 {
269 values_[i] = std::pair(names[i], val);
270 }
271}
272
273template <int dim> SysState<dim>::SysState(const SysState<dim> &other) : values_(other.values_) {}
274
275template <int dim>
276template <int other_dim>
278{
279 static_assert(dim <= other_dim, "Invalid dimension: dim < other_dim");
280
281 auto names = other.get_names();
282 auto values = other.get_values();
283
284 for (uint_t i = 0; i < dim; ++i)
285 {
286 values_[i] = std::make_pair(names[i], values[i]);
287 }
288}
289
290template <int dim> SysState<dim> &SysState<dim>::operator=(const SysState<dim> &other)
291{
292
293 if (this == &other)
294 {
295 return *this;
296 }
297
298 this->values_ = other.values_;
299 return *this;
300}
301
302template <int dim> SysState<dim>::SysState(SysState &&other) : values_(other.values_)
303{
304 other.clear();
305}
306
308{
309
310 if (this == &other)
311 {
312 return *this;
313 }
314
315 this->values_ = other.values_;
316 other.clear();
317 return *this;
318}
319
321{
322 add(vec);
323 return *this;
324}
325
327{
328 add(-1.0 * vec);
329 return *this;
330}
331
333{
334 scale(val);
335 return *this;
336}
337
338template <int dim> void SysState<dim>::scale(real_t val)
339{
340 std::for_each(values_.begin(), values_.end(), [=](auto &item) { item.second *= val; });
341}
342
343template <int dim> real_t SysState<dim>::get(const std::string &name) const
344{
345
346 auto itr = std::find_if(values_.begin(), values_.end(),
347 [&](const std::pair<std::string, real_t> &item)
348 { return item.first == name; });
349
350 if (itr == values_.end())
351 {
352 auto error_msg("Invalid variable name. Name ");
353 auto names = get_names();
354 std::string name_strs("[");
355 for (auto &name : names)
356 {
357 name_strs += std::string(name);
358 name_strs += std::string(",");
359 }
360
361 name_strs += std::string("]");
362 throw std::invalid_argument(error_msg + name + std::string(" not in: ") + name_strs);
363 }
364
365 return itr->second;
366}
367
368template <int dim> DynVec<real_t> SysState<dim>::as_vector() const
369{
370 DynVec<real_t> vec(dim);
371 for (uint_t v = 0; v < values_.size(); ++v)
372 {
373 vec(v) = values_[v].second;
374 }
375 return vec;
376}
377
378template <int dim> void SysState<dim>::set(const std::string &name, real_t val)
379{
380
381 auto itr = std::find_if(values_.begin(), values_.end(),
382 [&](const std::pair<std::string, real_t> &item)
383 { return item.first == name; });
384
385 if (itr == values_.end())
386 {
387 auto error_msg("Invalid variable name. Name ");
388 auto names = get_names();
389 std::string name_strs("[");
390 for (auto &name : names)
391 {
392
393 name_strs += std::string(name);
394 name_strs += std::string(",");
395 }
396
397 name_strs += std::string("]");
398 throw std::invalid_argument(error_msg + name + std::string(" not in: ") + name_strs);
399 }
400
401 itr->second = val;
402}
403
404template <int dim> template <typename Container> void SysState<dim>::set(const Container &container)
405{
406
407 if (container.size() != dim)
408 {
409 throw std::invalid_argument(
410 "Container has incorrect size: " + std::to_string(container.size()) + " not equal to " +
411 std::to_string(dim));
412 }
413
414 uint counter = 0;
415 std::for_each(values_.begin(), values_.end(),
416 [&](auto &arg) { arg.second = container[counter++]; });
417}
418
419template <int dim> void SysState<dim>::set(uint_t i, const std::pair<std::string, real_t> &value)
420{
421 values_[i] = value;
422}
423
424template <int dim> real_t &SysState<dim>::operator[](uint_t i) { return values_[i].second; }
425
426template <int dim> const real_t &SysState<dim>::operator[](uint_t i) const
427{
428 return values_[i].second;
429}
430
431template <int dim> real_t &SysState<dim>::operator()(const std::string &name)
432{
433
434 auto itr = std::find_if(values_.begin(), values_.end(),
435 [&](const std::pair<std::string, real_t> &item)
436 { return item.first == name; });
437
438 if (itr == values_.end())
439 {
440 auto error_msg("Invalid variable name. Name ");
441 auto names = get_names();
442 std::string name_strs("[");
443 for (auto &name : names)
444 {
445
446 name_strs += std::string(name);
447 name_strs += std::string(",");
448 }
449
450 name_strs += std::string("]");
451 throw std::invalid_argument(error_msg + name + std::string(" not in: ") + name_strs);
452 }
453
454 return itr->second;
455}
456
457template <int dim> const real_t &SysState<dim>::operator()(const std::string &name) const
458{
459
460 auto itr = std::find_if(values_.begin(), values_.end(),
461 [&](const std::pair<std::string, real_t> &item)
462 { return item.first == name; });
463
464 if (itr == values_.end())
465 {
466 auto error_msg("Invalid variable name. Name ");
467 auto names = get_names();
468 std::string name_strs("[");
469 for (auto &name : names)
470 {
471
472 name_strs += std::string(name);
473 name_strs += std::string(",");
474 }
475
476 name_strs += std::string("]");
477 throw std::invalid_argument(error_msg + name + std::string(" not in: ") + name_strs);
478 }
479
480 return itr->second;
481}
482
483template <int dim> void SysState<dim>::clear()
484{
485
486 std::for_each(values_.begin(), values_.end(),
487 [](std::pair<std::string, real_t> &item) { item.second = 0.0; });
488}
489
490template <int dim> const std::array<real_t, dim> SysState<dim>::get_values() const
491{
492
493 std::array<real_t, dim> copy;
494
495 for (uint_t i = 0; i < dim; ++i)
496 {
497 copy[i] = values_[i].second;
498 }
499
500 return copy;
501}
502
503template <int dim> const std::vector<std::string_view> SysState<dim>::get_names() const
504{
505
506 std::vector<std::string_view> copy(dim);
507
508 for (uint_t i = 0; i < dim; ++i)
509 {
510 copy[i] = values_[i].first;
511 }
512
513 return copy;
514}
515
516template <int dim> std::ostream &SysState<dim>::print(std::ostream &out) const
517{
518
519 out << std::fixed << std::setprecision(4);
520
521 std::for_each(values_.begin(), values_.end(),
522 [&](const std::pair<std::string, real_t> &vals)
523 { out << vals.first << ":" << vals.second << std::endl; });
524
525 return out;
526}
527
528template <int dim> const std::string SysState<dim>::as_string() const
529{
530
531 std::string result;
532 bool first = true;
533
534 for (const auto &[name, value] : values_)
535 {
536 if (!first)
537 result += ","; // add comma before the next element
538 first = false;
539
540 result += name;
541 result += ":";
542 result += std::to_string(value);
543 }
544
545 return result;
546}
547template <int dim> nlohmann::json SysState<dim>::as_json() const
548{
549 nlohmann::json j;
550 for (const auto &[name, value] : values_)
551 {
552 j[name] = value;
553 }
554 return j;
555}
556
557template <int dim> void SysState<dim>::add(const DynVec<real_t> &container)
558{
559 if (container.size() != dim)
560 {
561 throw std::logic_error("Invalid container size for update. " +
562 std::to_string(container.size()) + " should be" +
563 std::to_string(dim));
564 }
565
566 for (uint_t i = 0; i < dim; ++i)
567 {
568 values_[i].second += container[i];
569 }
570}
571
572template <int dim> void SysState<dim>::add(const std::vector<real_t> &container)
573{
574 if (container.size() != dim)
575 {
576 throw std::logic_error("Invalid container size for update. " +
577 std::to_string(container.size()) + " should be" +
578 std::to_string(dim));
579 }
580
581 for (uint_t i = 0; i < dim; ++i)
582 {
583 values_[i].second += container[i];
584 }
585}
586
587template <int dim> inline std::ostream &operator<<(std::ostream &out, const SysState<dim> &state)
588{
589 return state.print(out);
590}
591
592} // namespace dynamics
593
594} // namespace bitrl
595
596#endif // SYSTEM_STATE_H
SysState utility class describing the state of a system.
Definition system_state.h:25
SysState & operator+=(const DynVec< real_t > &vec)
Add to this state the entries of the give vector.
Definition system_state.h:320
real_t & operator[](uint_t)
Access operator.
Definition system_state.h:424
void scale(real_t val)
Scale the values of the state.
Definition system_state.h:338
static void extract(const SysState< dim1 > &state, SysState< dim2 > &other)
Extract a state of different dimension.
Definition system_state.h:237
void add(const DynVec< real_t > &container)
Set the values of state variables container must be of size dim.
Definition system_state.h:557
DynVec< real_t > as_vector() const
Returns the entries of this state as a DynVec.
Definition system_state.h:368
SysState(const SysState< other_dim > &other)
Copy constructor.
Definition system_state.h:277
SysState(std::array< std::string, dim > &&names, real_t val)
Constructor. Initialize the state with the given names all variables will be initialized with val.
Definition system_state.h:265
real_t get(const std::string &name) const
Returns the value for the variable name.
Definition system_state.h:343
std::array< std::pair< std::string, real_t >, dim > value_type
The type of the stored values.
Definition system_state.h:36
real_t & operator()(const std::string &name)
Access operator.
Definition system_state.h:431
SysState(std::array< std::pair< std::string, real_t >, dim > &&values)
Constructor. Initialize the state with the given names and values.
Definition system_state.h:260
real_t & operator()(const std::string_view name)
Access operator.
Definition system_state.h:177
nlohmann::json as_json() const
Definition system_state.h:547
void set(const Container &container)
Set the values.
Definition system_state.h:404
const real_t & operator()(const std::string &name) const
Access operator.
Definition system_state.h:457
SysState(SysState &&other)
Move copy constructor.
Definition system_state.h:302
void set(const std::string &name, real_t val)
Set the value for the variable name.
Definition system_state.h:378
const std::array< real_t, dim > get_values() const
Returns a copy of the state values.
Definition system_state.h:490
SysState()
Constructor. Initialize the state with no names.
Definition system_state.h:249
uint_t size() const
Returns the size of the system.
Definition system_state.h:132
SysState & operator*=(real_t val)
Scale this state by the given factor.
Definition system_state.h:332
const real_t & operator[](uint_t) const
Access operator.
Definition system_state.h:426
SysState(const SysState< dim > &other)
Copy constructor.
Definition system_state.h:273
const std::vector< std::string_view > get_names() const
Returns a copy of the state names.
Definition system_state.h:503
void clear()
clear the state
Definition system_state.h:483
SysState & operator-=(const DynVec< real_t > &vec)
Subtract from this state the entries of the give vector.
Definition system_state.h:326
void set(uint_t i, const std::pair< std::string, real_t > &value)
Set the name and value of the i-th variable.
Definition system_state.h:419
const real_t & operator[](const std::string &name) const
Access operator.
Definition system_state.h:162
SysState & operator=(const SysState< dim > &other)
Copy assignement constructor.
Definition system_state.h:290
static const int dimension
The dimension of the state.
Definition system_state.h:31
const real_t & operator()(const std::string_view name) const
Access operator.
Definition system_state.h:182
std::ostream & print(std::ostream &out) const
Print the state at the given stream.
Definition system_state.h:516
const std::string as_string() const
Return the state as string.
Definition system_state.h:528
SysState & operator=(SysState &&other)
Move copy constructor.
Definition system_state.h:307
real_t & operator[](const std::string &name)
Access operator.
Definition system_state.h:157
void add(const std::vector< real_t > &container)
Set the values of state variables container must be of size dim.
Definition system_state.h:572
std::ostream & operator<<(std::ostream &out, const SysState< dim > &state)
Definition system_state.h:587
Definition bitrl_consts.h:14
double real_t
real_t
Definition bitrl_types.h:23
Eigen::RowVectorX< T > DynVec
Dynamically sized row vector.
Definition bitrl_types.h:74
std::size_t uint_t
uint_t
Definition bitrl_types.h:43