From b05f4ca6bc3ff2042d0a0370e91c6095362f48ee Mon Sep 17 00:00:00 2001 From: conrad Date: Thu, 15 Sep 2022 11:34:34 +1000 Subject: [PATCH] expanded pow() to handle subview_each1 --- include/armadillo_bits/fn_powext.hpp | 39 +++++- include/armadillo_bits/glue_powext_bones.hpp | 5 + include/armadillo_bits/glue_powext_meat.hpp | 129 ++++++++++++++++++ include/armadillo_bits/subview_each_bones.hpp | 6 +- include/armadillo_bits/subview_each_meat.hpp | 8 +- 5 files changed, 178 insertions(+), 9 deletions(-) diff --git a/include/armadillo_bits/fn_powext.hpp b/include/armadillo_bits/fn_powext.hpp index 8c816ee5..dd169ef5 100644 --- a/include/armadillo_bits/fn_powext.hpp +++ b/include/armadillo_bits/fn_powext.hpp @@ -65,11 +65,42 @@ pow -// TODO: mat = pow(mat.each_col(), mat) (no promotion) -// TODO: mat = pow(mat.each_row(), mat) (no promotion) +template +arma_warn_unused +inline +Mat +pow + ( + const subview_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + return glue_powext::apply(X,Y); + } -// TODO: cx_mat = pow(cx_mat.each_col(), mat) (promotion) -// TODO: cx_mat = pow(cx_mat.each_row(), mat) (promotion) + + +template +arma_warn_unused +inline +typename +enable_if2 + < + ( is_cx::yes && is_same_type::yes ), + Mat + >::result +pow + ( + const subview_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + return glue_powext_cx::apply(X,Y); + } diff --git a/include/armadillo_bits/glue_powext_bones.hpp b/include/armadillo_bits/glue_powext_bones.hpp index 99f6e2e3..c0035391 100644 --- a/include/armadillo_bits/glue_powext_bones.hpp +++ b/include/armadillo_bits/glue_powext_bones.hpp @@ -31,6 +31,9 @@ class glue_powext template inline static void apply(Mat& out, const Glue& X); template inline static void apply(Mat& out, const Mat& A, const Mat& B); + + template inline static Mat apply(const subview_each1& X, const Base& Y); + }; @@ -43,6 +46,8 @@ class glue_powext_cx template inline static void apply(Mat& out, const mtGlue& X); template inline static void apply(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat& B); + + template inline static Mat apply(const subview_each1& X, const Base& Y); }; diff --git a/include/armadillo_bits/glue_powext_meat.hpp b/include/armadillo_bits/glue_powext_meat.hpp index fe5b2566..5cbba179 100644 --- a/include/armadillo_bits/glue_powext_meat.hpp +++ b/include/armadillo_bits/glue_powext_meat.hpp @@ -83,6 +83,70 @@ glue_powext::apply(Mat& out, const Mat& A, const Mat& B) +template +inline +Mat +glue_powext::apply + ( + const subview_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + typedef typename parent::elem_type eT; + + const parent& A = X.P; + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + + Mat out(A_n_rows, A_n_cols, arma_nozeros_indicator()); + + const quasi_unwrap tmp(Y.get_ref()); + const Mat& B = tmp.M; + + X.check_size(B); + + // TODO: investigate use of openmp + + const eT* B_mem = B.memptr(); + + if(mode == 0) // each column + { + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = eop_aux::pow(A_mem[row], B_mem[row]); + } + } + } + + if(mode == 1) // each row + { + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + const eT B_val = B_mem[i]; + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = eop_aux::pow(A_mem[row], B_val); + } + } + } + + return out; + } + + + // @@ -148,4 +212,69 @@ glue_powext_cx::apply(Mat< std::complex >& out, const Mat< std::complex >& +template +inline +Mat +glue_powext_cx::apply + ( + const subview_each1& X, + const Base& Y + ) + { + arma_extra_debug_sigprint(); + + typedef typename parent::elem_type eT; + typedef typename parent::pod_type T; + + const parent& A = X.P; + + const uword A_n_rows = A.n_rows; + const uword A_n_cols = A.n_cols; + + Mat out(A_n_rows, A_n_cols, arma_nozeros_indicator()); + + const quasi_unwrap tmp(Y.get_ref()); + const Mat& B = tmp.M; + + X.check_size(B); + + // TODO: investigate use of openmp + + const T* B_mem = B.memptr(); + + if(mode == 0) // each column + { + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = std::pow(A_mem[row], B_mem[row]); + } + } + } + + if(mode == 1) // each row + { + for(uword i=0; i < A_n_cols; ++i) + { + const eT* A_mem = A.colptr(i); + eT* out_mem = out.colptr(i); + + const eT B_val = B_mem[i]; + + for(uword row=0; row < A_n_rows; ++row) + { + out_mem[row] = std::pow(A_mem[row], B_val); + } + } + } + + return out; + } + + + //! @} diff --git a/include/armadillo_bits/subview_each_bones.hpp b/include/armadillo_bits/subview_each_bones.hpp index 09d14cff..4a19e46a 100644 --- a/include/armadillo_bits/subview_each_bones.hpp +++ b/include/armadillo_bits/subview_each_bones.hpp @@ -30,7 +30,8 @@ class subview_each_common const parent& P; - inline void check_size(const Mat& A) const; + template + inline void check_size(const Mat& A) const; protected: @@ -43,7 +44,8 @@ class subview_each_common arma_inline const Mat& get_mat_ref() const; - arma_cold inline const std::string incompat_size_string(const Mat& A) const; + template + arma_cold inline const std::string incompat_size_string(const Mat& A) const; }; diff --git a/include/armadillo_bits/subview_each_meat.hpp b/include/armadillo_bits/subview_each_meat.hpp index 2acf52e5..9f178d23 100644 --- a/include/armadillo_bits/subview_each_meat.hpp +++ b/include/armadillo_bits/subview_each_meat.hpp @@ -65,11 +65,12 @@ subview_each_common::get_mat_ref() const template +template inline void -subview_each_common::check_size(const Mat& A) const +subview_each_common::check_size(const Mat& A) const { - if(arma_config::debug == true) + if(arma_config::debug) { if(mode == 0) { @@ -91,10 +92,11 @@ subview_each_common::check_size(const Mat +template arma_cold inline const std::string -subview_each_common::incompat_size_string(const Mat& A) const +subview_each_common::incompat_size_string(const Mat& A) const { std::ostringstream tmp;