diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c064021..9ec0ed6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,6 +81,7 @@ target_sources(respond_model include/respond/logging.hpp include/respond/markov.hpp include/respond/respond.hpp + include/respond/transition.hpp include/respond/types.hpp include/respond/version.hpp ) diff --git a/include/respond/markov.hpp b/include/respond/markov.hpp index 547b465f..d07cc5ee 100644 --- a/include/respond/markov.hpp +++ b/include/respond/markov.hpp @@ -4,7 +4,7 @@ // Created Date: 2025-08-05 // // Author: Matthew Carroll // // ----- // -// Last Modified: 2026-01-26 // +// Last Modified: 2026-02-02 // // Modified By: Matthew Carroll // // ----- // // Copyright (c) 2025-2026 Syndemics Lab at Boston Medical Center // @@ -15,21 +15,14 @@ #include #include +#include #include -#include +#include namespace respond { -/// @brief type for a general function to apply a transition to the model state. -using transition_function = std::function &, - HistoryStamp &)>; - -/// @brief The pair of functions and transition matrices. -using transition = std::pair>; - /// @brief Class describing the Respond model simulation. class Markov { public: @@ -46,15 +39,15 @@ class Markov { /// @brief Setter for the transition operations. /// @param transitions A vector of transition operations and matrices. - virtual void SetTransitions(const std::vector &transitions) = 0; + virtual void SetTransitions(const std::vector &transitions) = 0; /// @brief Getter for the transition operations. /// @return Vector of transition operations and matrices. - virtual std::vector GetTransitions() const = 0; + virtual std::vector GetTransitions() const = 0; /// @brief Add a single transition operation to the vector. /// @param transition A transition operation and the matrices. - virtual void AddTransition(const transition &transition) = 0; + virtual void AddTransition(const Transition &transition) = 0; /// @brief Core function to Run the Markov model. /// @param num_steps The number of steps to run through the model. diff --git a/include/respond/transition.hpp b/include/respond/transition.hpp new file mode 100644 index 00000000..3c7e0d43 --- /dev/null +++ b/include/respond/transition.hpp @@ -0,0 +1,57 @@ +//////////////////////////////////////////////////////////////////////////////// +// File: transition.hpp // +// Project: respond // +// Created Date: 2026-02-02 // +// Author: Matthew Carroll // +// ----- // +// Last Modified: 2026-02-02 // +// Modified By: Matthew Carroll // +// ----- // +// Copyright (c) 2026 Syndemics Lab at Boston Medical Center // +//////////////////////////////////////////////////////////////////////////////// + +#ifndef RESPOND_TRANSITION_HPP_ +#define RESPOND_TRANSITION_HPP_ + +#include +#include + +#include + +#include + +namespace respond { + +/// @brief A helper class to hold Transitions +class Transition { +public: + /// @brief A vector of matrices containing the transition matrices to + /// multiply. + std::vector transition_matrices; + + void SetCallback(std::function &, HistoryStamp &)> + cb) { + _callback = std::move(cb); + } + + Eigen::VectorXd Execute(const Eigen::VectorXd &a, + const std::vector &b, + HistoryStamp &c) { + if (_callback) { + return _callback(a, b, c); + } + return a; + } + +private: + /// @brief The callback function to apply. + std::function &, + HistoryStamp &)> + _callback; +}; +} // namespace respond + +#endif \ No newline at end of file diff --git a/include/respond/types.hpp b/include/respond/types.hpp index 42534872..b34ad221 100644 --- a/include/respond/types.hpp +++ b/include/respond/types.hpp @@ -4,7 +4,7 @@ // Created Date: 2025-08-05 // // Author: Matthew Carroll // // ----- // -// Last Modified: 2026-01-26 // +// Last Modified: 2026-02-02 // // Modified By: Matthew Carroll // // ----- // // Copyright (c) 2025-2026 Syndemics Lab at Boston Medical Center // @@ -23,14 +23,6 @@ /// @brief General Namespace for all RESPOND repo related code. namespace respond { -/// @brief Type alias for a string map -/// @tparam T Type of key for the map -template using StringMap = std::map; - -/// @brief Type alias for a string unordered map -/// @tparam T Type of key for the unordered map -template using StringUOMap = std::unordered_map; - /// @brief Struct grouping together matrices containing run history struct HistoryStamp { Eigen::VectorXd state = Eigen::VectorXd::Zero(0); diff --git a/src/internals/markov_internals.hpp b/src/internals/markov_internals.hpp index 39a95044..73cefd5d 100644 --- a/src/internals/markov_internals.hpp +++ b/src/internals/markov_internals.hpp @@ -4,7 +4,7 @@ // Created Date: 2025-08-05 // // Author: Matthew Carroll // // ----- // -// Last Modified: 2026-01-26 // +// Last Modified: 2026-02-02 // // Modified By: Matthew Carroll // // ----- // // Copyright (c) 2025-2026 Syndemics Lab at Boston Medical Center // @@ -50,18 +50,18 @@ class MarkovImpl : public virtual Markov { } Eigen::VectorXd GetState() const override { return _state; } - void SetTransitions(const std::vector &tr) override { + void SetTransitions(const std::vector &transitions) override { _transitions.clear(); // This is required for a deep copy of the matrices from the vector - for (const auto &t : tr) { + for (const auto &t : transitions) { _transitions.push_back(t); } } - std::vector GetTransitions() const override { + std::vector GetTransitions() const override { return _transitions; } - void AddTransition(const transition &transition) override { + void AddTransition(const Transition &transition) override { _transitions.push_back(transition); } @@ -74,7 +74,7 @@ class MarkovImpl : public virtual Markov { private: std::string _logger_name; Eigen::VectorXd _state; - std::vector _transitions = {}; + std::vector _transitions = {}; int _time = 0; HistoryOverTime _history = {}; diff --git a/src/markov.cpp b/src/markov.cpp index 49d38185..62da9e18 100644 --- a/src/markov.cpp +++ b/src/markov.cpp @@ -4,7 +4,7 @@ // Created Date: 2025-07-07 // // Author: Matthew Carroll // // ----- // -// Last Modified: 2026-01-26 // +// Last Modified: 2026-02-02 // // Modified By: Matthew Carroll // // ----- // // Copyright (c) 2025-2026 Syndemics Lab at Boston Medical Center // @@ -63,9 +63,8 @@ void MarkovImpl::LogDebugPoint(const std::string &message, } void MarkovImpl::Step(HistoryStamp &hs) { - for (int i = 0; i < _transitions.size(); ++i) { - transition t = _transitions[i]; - _state = (t.first)(_state, t.second, hs); + for (Transition t : _transitions) { + _state = t.Execute(_state, t.transition_matrices, hs); } } diff --git a/tests/markov_test.cpp b/tests/markov_test.cpp index c684f1ba..437277db 100644 --- a/tests/markov_test.cpp +++ b/tests/markov_test.cpp @@ -4,7 +4,7 @@ // Created Date: 2025-06-06 // // Author: Matthew Carroll // // ----- // -// Last Modified: 2026-01-26 // +// Last Modified: 2026-02-02 // // Modified By: Matthew Carroll // // ----- // // Copyright (c) 2025-2026 Syndemics Lab at Boston Medical Center // @@ -26,6 +26,12 @@ class MarkovTest : public ::testing::Test { void TearDown() override {} }; +Eigen::VectorXd test_func(const Eigen::VectorXd &s, + const std::vector &t, + HistoryStamp &h) { + return s + t[0]; +} + TEST_F(MarkovTest, ZeroDuration) { auto markov = Markov::Create("test_logger"); markov->Run(0); @@ -41,10 +47,9 @@ TEST_F(MarkovTest, SingleStep) { auto markov = Markov::Create("test_logger"); markov->SetState(Eigen::VectorXd::Ones(5)); - transition t = {[](const Eigen::VectorXd &state, - const std::vector &transitions, - HistoryStamp &hs) { return state + transitions[0]; }, - {Eigen::VectorXd::Ones(5)}}; + Transition t; + t.SetCallback(test_func); + t.transition_matrices = {Eigen::VectorXd::Ones(5)}; markov->SetTransitions({t}); markov->Run(1); @@ -57,12 +62,11 @@ TEST_F(MarkovTest, MultipleTransitions) { auto markov = Markov::Create("test_logger"); markov->SetState(Eigen::VectorXd::Ones(5)); - transition t = {[](const Eigen::VectorXd &state, - const std::vector &transitions, - HistoryStamp &hs) { return state + transitions[0]; }, - {Eigen::VectorXd::Ones(5)}}; - markov->SetTransitions({t, t, t, t, t}); + Transition t; + t.SetCallback(test_func); + t.transition_matrices = {Eigen::VectorXd::Ones(5)}; + markov->SetTransitions({t, t, t, t, t}); markov->Run(1); auto results = markov->GetRunResults(); diff --git a/tests/mocks/markov_mock.hpp b/tests/mocks/markov_mock.hpp index ab435305..de3eefe8 100644 --- a/tests/mocks/markov_mock.hpp +++ b/tests/mocks/markov_mock.hpp @@ -4,10 +4,10 @@ // Created Date: 2025-08-01 // // Author: Matthew Carroll // // ----- // -// Last Modified: 2025-08-01 // +// Last Modified: 2026-02-02 // // Modified By: Matthew Carroll // // ----- // -// Copyright (c) 2025 Syndemics Lab at Boston Medical Center // +// Copyright (c) 2025-2026 Syndemics Lab at Boston Medical Center // //////////////////////////////////////////////////////////////////////////////// #ifndef RESPOND_TESTS_MARKOVMOCK_HPP_ #define RESPOND_TESTS_MARKOVMOCK_HPP_ @@ -19,18 +19,18 @@ #include #include -#include +#include namespace respond { class MockMarkov : public virtual Markov { public: MOCK_METHOD(void, SetState, (const Eigen::VectorXd &), (override)); MOCK_METHOD(Eigen::VectorXd, GetState, (), (const, override)); - MOCK_METHOD(void, SetTransitions, (const std::vector &), + MOCK_METHOD(void, SetTransitions, (const std::vector &), (override)); - MOCK_METHOD((std::vector), GetTransitions, (), + MOCK_METHOD((std::vector), GetTransitions, (), (const, override)); - MOCK_METHOD(void, AddTransition, (const transition &), (override)); + MOCK_METHOD(void, AddTransition, (const Transition &), (override)); MOCK_METHOD(void, Run, (const int &), (override)); MOCK_METHOD(HistoryOverTime, GetRunResults, (), (const, override)); };