12#ifndef RESPOND_HISTORY_HPP_
13#define RESPOND_HISTORY_HPP_
23enum class HistoryMode { Snapshot, Accumulated };
25inline HistoryMode GetDefaultHistoryMode(
const std::string &name) {
26 if (name ==
"intervention_admission" || name ==
"total_overdose" ||
27 name ==
"fatal_overdose" || name ==
"background_death") {
28 return HistoryMode::Accumulated;
30 return HistoryMode::Snapshot;
43 History(
const std::string &name =
"state",
44 const std::string &log_name =
"console")
45 :
History(name, log_name, GetDefaultHistoryMode(name)) {}
51 History(
const std::string &name,
const std::string &log_name,
53 : _log_name(log_name), _name(name), _mode(mode) {}
87 _timesteps = std::move(other._timesteps);
88 _states = std::move(other._states);
89 _name = other.GetHistoryName();
90 _log_name = other.GetLogName();
91 _mode = other.GetHistoryMode();
92 _pending_state = std::move(other._pending_state);
100 _timesteps = std::move(other._timesteps);
101 _states = std::move(other._states);
102 _name = other.GetHistoryName();
103 _log_name = other.GetLogName();
104 _mode = other.GetHistoryMode();
105 _pending_state = std::move(other._pending_state);
129 std::map<int, Eigen::VectorXd> state_map;
130 for (
size_t index = 0; index < _timesteps.size(); ++index) {
131 state_map[_timesteps[index]] = _states[index];
161 if (_timesteps.empty()) {
164 return _timesteps.back();
180 std::vector<Eigen::VectorXd> ret;
181 if (_states.empty()) {
185 int default_size = _states.front().size();
187 for (
size_t index = 0; index < _timesteps.size(); ++index) {
188 const int recorded_timestep = _timesteps[index];
189 const auto &recorded_state = _states[index];
190 if (recorded_timestep > tstep) {
193 while (recorded_timestep > tstep) {
194 ret.push_back(GetZeroVector(default_size));
197 ret.push_back(recorded_state);
209 void AddState(
const Eigen::VectorXd &state,
int timestep = -1) {
211 timestep = GetNextTimestep();
214 const auto existing =
215 std::find(_timesteps.begin(), _timesteps.end(), timestep);
216 if (existing != _timesteps.end()) {
218 static_cast<size_t>(existing - _timesteps.begin());
219 _states[index] = state;
223 _timesteps.push_back(timestep);
224 _states.push_back(state);
237 if (_mode != HistoryMode::Accumulated) {
242 if (_pending_state.size() == 0) {
243 _pending_state = state;
246 _pending_state += state;
253 if (_mode != HistoryMode::Accumulated) {
257 Eigen::VectorXd value;
258 if (_pending_state.size() > 0) {
259 value = _pending_state;
261 value = Eigen::VectorXd::Zero(state_size);
265 _pending_state.resize(0);
272 _pending_state.resize(0);
277 std::string _log_name;
283 std::vector<int> _timesteps;
285 std::vector<Eigen::VectorXd> _states;
287 Eigen::VectorXd _pending_state;
292 int GetNextTimestep() {
293 if (_timesteps.empty()) {
296 return _timesteps.back() + 1;
302 Eigen::VectorXd GetZeroVector(
const int &size)
const {
303 return Eigen::VectorXd::Zero(size);
Tracks and manages state vector history over time. History records state snapshots at discrete timest...
Definition: history.hpp:37
std::string GetHistoryName() const
Retrieves the identifier name of this history.
Definition: history.hpp:169
std::string GetLogName() const
Retrieves the logger name for this history.
Definition: history.hpp:173
History & operator=(const History &other)
Copy assignment operator implementing the Rule of Five.
Definition: history.hpp:71
Eigen::VectorXd GetPendingState() const
Retrieves the pending accumulated state.
Definition: history.hpp:156
const std::vector< Eigen::VectorXd > & GetRecordedStates() const
Retrieves the recorded state vectors without densifying gaps.
Definition: history.hpp:142
History & operator=(History &&other) noexcept
Move assignment operator implementing the Rule of Five.
Definition: history.hpp:98
History(const std::string &name="state", const std::string &log_name="console")
Constructs a History tracker.
Definition: history.hpp:43
~History()=default
Destructor (default).
void Clear()
Clears all recorded state history.
Definition: history.hpp:269
History(const History &other)
Copy constructor implementing the Rule of Five. Creates an independent copy of the history state and ...
Definition: history.hpp:59
int GetLatestRecordedTimestep() const
Retrieves the latest recorded timestep.
Definition: history.hpp:160
std::map< int, Eigen::VectorXd > GetStateMap() const
Retrieves the complete state map (timestep -> state vector).
Definition: history.hpp:128
void AddState(const Eigen::VectorXd &state, int timestep=-1)
Records a state vector at a specific or automatic timestep.
Definition: history.hpp:209
std::vector< Eigen::VectorXd > GetStateAsVector() const
Converts the sparse history map to a contiguous vector of states. Gaps in timesteps are filled with z...
Definition: history.hpp:179
bool operator!=(const History &other) const
Inequality comparison operator.
Definition: history.hpp:124
History(History &&other) noexcept
Move constructor implementing the Rule of Five.
Definition: history.hpp:86
void FlushPendingState(int timestep, Eigen::Index state_size)
Flushes pending accumulated state into a recorded timestep.
Definition: history.hpp:252
HistoryMode GetHistoryMode() const
Retrieves the configured history recording mode.
Definition: history.hpp:148
bool HasPendingState() const
Indicates whether an accumulated history has pending state.
Definition: history.hpp:152
void AccumulateState(const Eigen::VectorXd &state)
Adds a contribution to an accumulated history.
Definition: history.hpp:236
void RecordSnapshot(const Eigen::VectorXd &state, int timestep)
Records a snapshot value at a concrete timestep.
Definition: history.hpp:230
History(const std::string &name, const std::string &log_name, HistoryMode mode)
Constructs a History tracker with an explicit recording mode.
Definition: history.hpp:51
bool operator==(const History &other) const
Equality comparison operator.
Definition: history.hpp:113
const std::vector< int > & GetRecordedTimesteps() const
Retrieves the recorded timesteps without densifying gaps.
Definition: history.hpp:138