From dd48fa3dc21690bbd8e5681eada59ef47f5b0b01 Mon Sep 17 00:00:00 2001 From: "George G. Vega Yon" Date: Tue, 19 Sep 2023 10:16:24 -0600 Subject: [PATCH] Adding option for row/col major in DEFM --- defm.hpp | 85 +++++++++++++----------- include/barry/models/defm/defm-bones.hpp | 56 ++++++---------- include/barry/models/defm/defm-meat.hpp | 29 +++++++- tests/16-defm-counts-with-formulas.cpp | 14 ++-- tests/main.cpp | 3 +- 5 files changed, 106 insertions(+), 81 deletions(-) diff --git a/defm.hpp b/defm.hpp index 5be56c0e3..4cccfe3c7 100644 --- a/defm.hpp +++ b/defm.hpp @@ -1220,34 +1220,32 @@ inline void rules_dont_become_zero( class DEFM : public DEFMModel { private: - // std::shared_ptr< std::mt19937 > rengine = nullptr; - // std::shared_ptr< DEFMModel > model = nullptr; - /** * @brief Model data */ ///@{ - int * Y = nullptr; ///< Outcome variable - int * ID = nullptr; ///< Individual ids - double * X = nullptr; ///< Covariates + int * Y = nullptr; ///< Outcome variable + int * ID = nullptr; ///< Individual ids + double * X = nullptr; ///< Covariates + bool column_major = true; ///< Whether the data is column major or not // In case we need a copy of the data - std::shared_ptr> Y_shared; ///< Outcome variable - std::shared_ptr> ID_shared; ///< Individual ids - std::shared_ptr> X_shared;///< Covariates + std::shared_ptr> Y_shared; ///< Outcome variable + std::shared_ptr> ID_shared; ///< Individual ids + std::shared_ptr> X_shared; ///< Covariates - size_t N; ///< Number of agents/individuals - size_t ID_length; ///< Length of the vector IDs - size_t Y_ncol; ///< Number of columns in the response - size_t Y_length; ///< Length of the vector Y - size_t X_ncol; ///< Number of columns in the features - size_t X_length; ///< Length of the vector X - size_t M_order; ///< Markov order of the model - - std::vector< std::string > Y_names; - std::vector< std::string > X_names; - std::vector< size_t > start_end; - std::vector< size_t > model_ord; + size_t N; ///< Number of agents/individuals + size_t ID_length; ///< Length of the vector IDs + size_t Y_ncol; ///< Number of columns in the response + size_t Y_length; ///< Length of the vector Y + size_t X_ncol; ///< Number of columns in the features + size_t X_length; ///< Length of the vector X + size_t M_order; ///< Markov order of the model + + std::vector< std::string > Y_names; ///< Names of the response variables + std::vector< std::string > X_names; ///< Names of the covariates + std::vector< size_t > start_end; ///< Start and end of each observation + std::vector< size_t > model_ord; ///< Order of the model ///@} public: @@ -1260,22 +1258,10 @@ class DEFM : public DEFMModel { size_t y_ncol, size_t x_ncol, size_t m_order, - bool copy_data = true + bool copy_data = true, + bool column_major = true ); - // ~DEFM() { - - // if (n_owners-- == 1) - // { - // delete[] Y; - // delete[] ID; - // delete[] X; - // } - - // DEFMModel::~Model(); - - // }; - DEFMModel & get_model() { return *this; }; @@ -1450,7 +1436,8 @@ inline DEFM::DEFM( size_t y_ncol, size_t x_ncol, size_t m_order, - bool copy_data + bool copy_data, + bool column_major ) { // Pointers @@ -1557,6 +1544,24 @@ inline void DEFM::init() // Adding the rule rules_markov_fixed(this->get_rules(), M_order); + // Element access will be contingent on the column major + std::function element_access; + + if (this->column_major) + { + + element_access = [](size_t i, size_t j, size_t nrow, size_t) -> size_t { + return i + j * nrow; + }; + + } else { + + element_access = [](size_t i, size_t j, size_t, size_t ncol) -> size_t { + return j + i * ncol; + }; + + } + // Creating the arrays for (size_t i = 0u; i < N; ++i) { @@ -1581,7 +1586,13 @@ inline void DEFM::init() // Filling-out the array for (size_t k = 0u; k < Y_ncol; ++k) for (size_t o = 0u; o < (M_order + 1u); ++o) - array(o, k) = *(Y + k * ID_length + start_i + n_proc + o); + // array(o, k) = *(Y + k * ID_length + start_i + n_proc + o); + array(o, k) = *(Y + element_access( + start_i + n_proc + o, // Row + k, // Column + ID_length, // N_row + Y_ncol // N_col + )); // Adding to the model model_ord.push_back( this->add_array(array, true) ); diff --git a/include/barry/models/defm/defm-bones.hpp b/include/barry/models/defm/defm-bones.hpp index c96b786c0..27197d60e 100644 --- a/include/barry/models/defm/defm-bones.hpp +++ b/include/barry/models/defm/defm-bones.hpp @@ -4,34 +4,32 @@ class DEFM : public DEFMModel { private: - // std::shared_ptr< std::mt19937 > rengine = nullptr; - // std::shared_ptr< DEFMModel > model = nullptr; - /** * @brief Model data */ ///@{ - int * Y = nullptr; ///< Outcome variable - int * ID = nullptr; ///< Individual ids - double * X = nullptr; ///< Covariates + int * Y = nullptr; ///< Outcome variable + int * ID = nullptr; ///< Individual ids + double * X = nullptr; ///< Covariates + bool column_major = true; ///< Whether the data is column major or not // In case we need a copy of the data - std::shared_ptr> Y_shared; ///< Outcome variable - std::shared_ptr> ID_shared; ///< Individual ids - std::shared_ptr> X_shared;///< Covariates + std::shared_ptr> Y_shared; ///< Outcome variable + std::shared_ptr> ID_shared; ///< Individual ids + std::shared_ptr> X_shared; ///< Covariates - size_t N; ///< Number of agents/individuals - size_t ID_length; ///< Length of the vector IDs - size_t Y_ncol; ///< Number of columns in the response - size_t Y_length; ///< Length of the vector Y - size_t X_ncol; ///< Number of columns in the features - size_t X_length; ///< Length of the vector X - size_t M_order; ///< Markov order of the model - - std::vector< std::string > Y_names; - std::vector< std::string > X_names; - std::vector< size_t > start_end; - std::vector< size_t > model_ord; + size_t N; ///< Number of agents/individuals + size_t ID_length; ///< Length of the vector IDs + size_t Y_ncol; ///< Number of columns in the response + size_t Y_length; ///< Length of the vector Y + size_t X_ncol; ///< Number of columns in the features + size_t X_length; ///< Length of the vector X + size_t M_order; ///< Markov order of the model + + std::vector< std::string > Y_names; ///< Names of the response variables + std::vector< std::string > X_names; ///< Names of the covariates + std::vector< size_t > start_end; ///< Start and end of each observation + std::vector< size_t > model_ord; ///< Order of the model ///@} public: @@ -44,22 +42,10 @@ class DEFM : public DEFMModel { size_t y_ncol, size_t x_ncol, size_t m_order, - bool copy_data = true + bool copy_data = true, + bool column_major = true ); - // ~DEFM() { - - // if (n_owners-- == 1) - // { - // delete[] Y; - // delete[] ID; - // delete[] X; - // } - - // DEFMModel::~Model(); - - // }; - DEFMModel & get_model() { return *this; }; diff --git a/include/barry/models/defm/defm-meat.hpp b/include/barry/models/defm/defm-meat.hpp index 0d7361ce0..ba7635e2e 100644 --- a/include/barry/models/defm/defm-meat.hpp +++ b/include/barry/models/defm/defm-meat.hpp @@ -109,7 +109,8 @@ inline DEFM::DEFM( size_t y_ncol, size_t x_ncol, size_t m_order, - bool copy_data + bool copy_data, + bool column_major ) { // Pointers @@ -216,6 +217,24 @@ inline void DEFM::init() // Adding the rule rules_markov_fixed(this->get_rules(), M_order); + // Element access will be contingent on the column major + std::function element_access; + + if (this->column_major) + { + + element_access = [](size_t i, size_t j, size_t nrow, size_t) -> size_t { + return i + j * nrow; + }; + + } else { + + element_access = [](size_t i, size_t j, size_t, size_t ncol) -> size_t { + return j + i * ncol; + }; + + } + // Creating the arrays for (size_t i = 0u; i < N; ++i) { @@ -240,7 +259,13 @@ inline void DEFM::init() // Filling-out the array for (size_t k = 0u; k < Y_ncol; ++k) for (size_t o = 0u; o < (M_order + 1u); ++o) - array(o, k) = *(Y + k * ID_length + start_i + n_proc + o); + // array(o, k) = *(Y + k * ID_length + start_i + n_proc + o); + array(o, k) = *(Y + element_access( + start_i + n_proc + o, // Row + k, // Column + ID_length, // N_row + Y_ncol // N_col + )); // Adding to the model model_ord.push_back( this->add_array(array, true) ); diff --git a/tests/16-defm-counts-with-formulas.cpp b/tests/16-defm-counts-with-formulas.cpp index f4725f1cc..b15888910 100644 --- a/tests/16-defm-counts-with-formulas.cpp +++ b/tests/16-defm-counts-with-formulas.cpp @@ -29,13 +29,13 @@ BARRY_TEST_CASE("DEFM motif formula", "[DEFM motif formula]") { std::vector< bool > sign_2 = {true, true, true, false}; std::vector< bool > sign_3 = {true}; - defmcounters::defm_motif_parser("{y1, y3}", res_locations1a, res_sign1a, 1, 4); - defmcounters::defm_motif_parser("{y1_0, y3} > {y1_1, 0y3_1}", res_locations2a, res_sign2a, 1, 4); - defmcounters::defm_motif_parser("{y1}", res_locations3a, res_sign3a, 1, 4); + defm::defm_motif_parser("{y1, y3}", res_locations1a, res_sign1a, 1, 4); + defm::defm_motif_parser("{y1_0, y3} > {y1_1, 0y3_1}", res_locations2a, res_sign2a, 1, 4); + defm::defm_motif_parser("{y1}", res_locations3a, res_sign3a, 1, 4); - defmcounters::defm_motif_parser("{y1_1, y3}", res_locations1b, res_sign1b, 1, 4); - defmcounters::defm_motif_parser("{y1_0, y3_0} > {y1, 0y3_1}", res_locations2b, res_sign2b, 1, 4); - defmcounters::defm_motif_parser("{y1_1}", res_locations3b, res_sign3b, 1, 4); + defm::defm_motif_parser("{y1_1, y3}", res_locations1b, res_sign1b, 1, 4); + defm::defm_motif_parser("{y1_0, y3_0} > {y1, 0y3_1}", res_locations2b, res_sign2b, 1, 4); + defm::defm_motif_parser("{y1_1}", res_locations3b, res_sign3b, 1, 4); #ifdef CATCH_CONFIG_MAIN @@ -70,6 +70,8 @@ BARRY_TEST_CASE("DEFM motif formula", "[DEFM motif formula]") { #endif + #ifndef CATCH_CONFIG_MAIN return 0; + #endif } \ No newline at end of file diff --git a/tests/main.cpp b/tests/main.cpp index f4c9beef3..1be397328 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -24,4 +24,5 @@ #include "10-geese-predict.cpp" // This is not working yet #include "11-phylo-counts.cpp" #include "14-variable-transformation.cpp" -#include "15-defm-counts.cpp" \ No newline at end of file +#include "15-defm-counts.cpp" +#include "16-defm-counts-with-formulas.cpp"