From f883b8c07776db6f789d0220a34edc812d164316 Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Tue, 16 Jun 2026 05:23:48 -0500 Subject: [PATCH 1/2] Armadillo 15.3.91 aka 15.4-rc1 --- inst/include/armadillo | 2 + inst/include/armadillo_bits/Col_bones.hpp | 10 +- inst/include/armadillo_bits/Col_meat.hpp | 77 +-- .../armadillo_bits/CubeToMatOp_bones.hpp | 2 + inst/include/armadillo_bits/Cube_bones.hpp | 2 + inst/include/armadillo_bits/Cube_meat.hpp | 31 +- inst/include/armadillo_bits/GenCube_bones.hpp | 5 +- inst/include/armadillo_bits/Gen_bones.hpp | 2 + .../include/armadillo_bits/GlueCube_bones.hpp | 2 + inst/include/armadillo_bits/Glue_bones.hpp | 2 + inst/include/armadillo_bits/Mat_bones.hpp | 12 +- inst/include/armadillo_bits/Mat_meat.hpp | 217 ++++++- inst/include/armadillo_bits/OpCube_bones.hpp | 2 + inst/include/armadillo_bits/Op_bones.hpp | 2 + inst/include/armadillo_bits/Proxy.hpp | 8 +- inst/include/armadillo_bits/Row_bones.hpp | 10 +- inst/include/armadillo_bits/Row_meat.hpp | 77 +-- inst/include/armadillo_bits/SpGlue_bones.hpp | 2 + inst/include/armadillo_bits/SpMat_bones.hpp | 2 + inst/include/armadillo_bits/SpOp_bones.hpp | 2 + .../armadillo_bits/SpSubview_bones.hpp | 6 + .../SpSubview_col_list_bones.hpp | 2 + .../armadillo_bits/SpToDGlue_bones.hpp | 2 + inst/include/armadillo_bits/SpToDOp_bones.hpp | 2 + inst/include/armadillo_bits/arma_forward.hpp | 9 +- inst/include/armadillo_bits/arma_version.hpp | 6 +- inst/include/armadillo_bits/auxlib_meat.hpp | 20 +- .../include/armadillo_bits/diagview_bones.hpp | 2 + .../armadillo_bits/eglue_core_meat.hpp | 50 +- inst/include/armadillo_bits/fn_as_scalar.hpp | 4 +- inst/include/armadillo_bits/fn_conv_to.hpp | 334 ++++++++-- inst/include/armadillo_bits/fn_find.hpp | 8 +- inst/include/armadillo_bits/fn_inv.hpp | 2 +- inst/include/armadillo_bits/fn_inv_sympd.hpp | 2 +- inst/include/armadillo_bits/fn_powext.hpp | 4 +- inst/include/armadillo_bits/fn_sylvester.hpp | 6 +- inst/include/armadillo_bits/fn_trimat.hpp | 12 +- .../armadillo_bits/glue_atan2_meat.hpp | 4 +- inst/include/armadillo_bits/glue_cor_meat.hpp | 4 +- inst/include/armadillo_bits/glue_cov_meat.hpp | 4 +- inst/include/armadillo_bits/glue_max_meat.hpp | 36 +- inst/include/armadillo_bits/glue_min_meat.hpp | 36 +- .../armadillo_bits/glue_powext_bones.hpp | 4 + .../armadillo_bits/glue_powext_meat.hpp | 4 + .../armadillo_bits/glue_times_meat.hpp | 8 +- inst/include/armadillo_bits/gmm_diag_meat.hpp | 28 +- inst/include/armadillo_bits/gmm_full_meat.hpp | 22 +- inst/include/armadillo_bits/mp_misc.hpp | 4 +- .../armadillo_bits/mtGlueCube_bones.hpp | 2 + inst/include/armadillo_bits/mtGlue_bones.hpp | 2 + .../include/armadillo_bits/mtOpCube_bones.hpp | 2 + inst/include/armadillo_bits/mtOp_bones.hpp | 2 + .../include/armadillo_bits/mtSpGlue_bones.hpp | 2 + inst/include/armadillo_bits/mtSpOp_bones.hpp | 2 + .../armadillo_bits/mtSpReduceOp_bones.hpp | 2 + inst/include/armadillo_bits/op_clamp_meat.hpp | 4 +- inst/include/armadillo_bits/op_cor_meat.hpp | 8 +- inst/include/armadillo_bits/op_cov_meat.hpp | 8 +- .../armadillo_bits/op_diagmat_meat.hpp | 4 +- inst/include/armadillo_bits/op_dot_meat.hpp | 4 +- .../include/armadillo_bits/op_expmat_meat.hpp | 4 +- .../armadillo_bits/op_find_aux_bones.hpp | 81 +++ .../armadillo_bits/op_find_aux_meat.hpp | 425 +++++++++++++ inst/include/armadillo_bits/op_find_bones.hpp | 8 +- inst/include/armadillo_bits/op_find_meat.hpp | 18 +- inst/include/armadillo_bits/op_flip_meat.hpp | 4 +- .../include/armadillo_bits/op_htrans_meat.hpp | 2 +- .../include/armadillo_bits/op_logmat_meat.hpp | 4 +- .../armadillo_bits/op_princomp_meat.hpp | 4 +- .../armadillo_bits/op_reshape_meat.hpp | 4 +- .../include/armadillo_bits/op_resize_meat.hpp | 4 +- .../armadillo_bits/op_reverse_meat.hpp | 4 +- .../armadillo_bits/op_shuffle_meat.hpp | 4 +- inst/include/armadillo_bits/op_sort_meat.hpp | 4 +- .../armadillo_bits/op_sqrtmat_meat.hpp | 4 +- .../include/armadillo_bits/op_strans_meat.hpp | 2 +- .../include/armadillo_bits/op_symmat_meat.hpp | 16 +- .../include/armadillo_bits/op_trimat_meat.hpp | 10 +- .../armadillo_bits/op_vectorise_meat.hpp | 4 +- .../include/armadillo_bits/sp_auxlib_meat.hpp | 2 +- .../armadillo_bits/spdiagview_bones.hpp | 2 + .../armadillo_bits/spdiagview_meat.hpp | 8 +- inst/include/armadillo_bits/strip.hpp | 42 ++ inst/include/armadillo_bits/subview_bones.hpp | 12 + .../armadillo_bits/subview_cube_bones.hpp | 2 + .../armadillo_bits/subview_cube_each_meat.hpp | 118 ++-- .../armadillo_bits/subview_cube_meat.hpp | 9 +- .../subview_cube_slices_bones.hpp | 2 + .../armadillo_bits/subview_each_meat.hpp | 12 +- .../armadillo_bits/subview_elem1_bones.hpp | 29 +- .../armadillo_bits/subview_elem1_meat.hpp | 571 ++++++------------ .../armadillo_bits/subview_elem2_bones.hpp | 32 +- .../armadillo_bits/subview_elem2_meat.hpp | 303 ++-------- inst/include/armadillo_bits/subview_meat.hpp | 4 +- inst/include/armadillo_bits/unwrap.hpp | 93 ++- 95 files changed, 1811 insertions(+), 1172 deletions(-) create mode 100644 inst/include/armadillo_bits/op_find_aux_bones.hpp create mode 100644 inst/include/armadillo_bits/op_find_aux_meat.hpp diff --git a/inst/include/armadillo b/inst/include/armadillo index db139188..ebeab003 100644 --- a/inst/include/armadillo +++ b/inst/include/armadillo @@ -306,6 +306,7 @@ namespace arma #include "armadillo_bits/op_orth_null_bones.hpp" #include "armadillo_bits/op_relational_bones.hpp" #include "armadillo_bits/op_find_bones.hpp" + #include "armadillo_bits/op_find_aux_bones.hpp" #include "armadillo_bits/op_find_unique_bones.hpp" #include "armadillo_bits/op_chol_bones.hpp" #include "armadillo_bits/op_cx_scalar_bones.hpp" @@ -765,6 +766,7 @@ namespace arma #include "armadillo_bits/op_orth_null_meat.hpp" #include "armadillo_bits/op_relational_meat.hpp" #include "armadillo_bits/op_find_meat.hpp" + #include "armadillo_bits/op_find_aux_meat.hpp" #include "armadillo_bits/op_find_unique_meat.hpp" #include "armadillo_bits/op_chol_meat.hpp" #include "armadillo_bits/op_cx_scalar_meat.hpp" diff --git a/inst/include/armadillo_bits/Col_bones.hpp b/inst/include/armadillo_bits/Col_bones.hpp index 32dd67f0..8adad5ca 100644 --- a/inst/include/armadillo_bits/Col_bones.hpp +++ b/inst/include/armadillo_bits/Col_bones.hpp @@ -33,6 +33,8 @@ class Col : public Mat static constexpr bool is_row = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = false; + inline Col(); inline Col(const Col& X); @@ -67,9 +69,6 @@ class Col : public Mat inline Col(Col&& m); inline Col& operator=(Col&& m); - // inline Col(Mat&& m); - // inline Col& operator=(Mat&& m); - inline Col& operator=(const eT val); inline Col& operator=(const Col& m); @@ -153,6 +152,7 @@ class Col : public Mat arma_warn_unused arma_inline eT& at(const uword in_row, const uword in_col); arma_warn_unused arma_inline const eT& at(const uword in_row, const uword in_col) const; + inline void push_back(const eT val); inline constexpr bool is_vec() const { return true; } inline constexpr bool is_rowvec() const { return false; } @@ -210,6 +210,8 @@ class Col::fixed : public Col static constexpr bool is_row = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = false; + static const uword n_rows; // value provided below the class definition static const uword n_cols; // value provided below the class definition static const uword n_elem; // value provided below the class definition @@ -265,6 +267,8 @@ class Col::fixed : public Col arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col); arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const; + inline void push_back(const eT) = delete; + arma_warn_unused arma_inline eT* memptr(); arma_warn_unused arma_inline const eT* memptr() const; diff --git a/inst/include/armadillo_bits/Col_meat.hpp b/inst/include/armadillo_bits/Col_meat.hpp index 91d93eb3..669a1b74 100644 --- a/inst/include/armadillo_bits/Col_meat.hpp +++ b/inst/include/armadillo_bits/Col_meat.hpp @@ -431,64 +431,6 @@ Col::operator=(Col&& X) -// template -// inline -// Col::Col(Mat&& X) -// : Mat(arma_vec_indicator(), 1) -// { -// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X); -// -// if(X.n_cols != 1) { const Mat& XX = X; Mat::operator=(XX); return; } -// -// access::rw(Mat::n_rows) = X.n_rows; -// access::rw(Mat::n_cols) = 1; -// access::rw(Mat::n_elem) = X.n_elem; -// access::rw(Mat::n_alloc) = X.n_alloc; -// -// if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) ) -// { -// access::rw(Mat::mem_state) = X.mem_state; -// access::rw(Mat::mem) = X.mem; -// -// access::rw(X.n_rows) = 0; -// access::rw(X.n_elem) = 0; -// access::rw(X.n_alloc) = 0; -// access::rw(X.mem_state) = 0; -// access::rw(X.mem) = nullptr; -// } -// else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3) -// { -// (*this).init_cold(); -// -// arrayops::copy( (*this).memptr(), X.mem, X.n_elem ); -// -// if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) -// { -// access::rw(X.n_rows) = 0; -// access::rw(X.n_elem) = 0; -// access::rw(X.mem) = nullptr; -// } -// } -// } -// -// -// -// template -// inline -// Col& -// Col::operator=(Mat&& X) -// { -// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X); -// -// if(X.n_cols != 1) { const Mat& XX = X; Mat::operator=(XX); return *this; } -// -// (*this).steal_mem(X, true); -// -// return *this; -// } - - - template inline Col& @@ -1208,6 +1150,25 @@ Col::at(const uword in_row, const uword) const +template +inline +void +Col::push_back(const eT val) + { + arma_debug_sigprint(); + + if(Mat::mem_state != 0) + { + arma_conform_check(true, "Col::push_back(): unsupported operation as auxiliary memory is in use"); + + return; + } + + Mat::vec_push_back(val, arma_colvec_indicator()); + } + + + template inline typename Col::row_iterator diff --git a/inst/include/armadillo_bits/CubeToMatOp_bones.hpp b/inst/include/armadillo_bits/CubeToMatOp_bones.hpp index 5d01be71..b783ff11 100644 --- a/inst/include/armadillo_bits/CubeToMatOp_bones.hpp +++ b/inst/include/armadillo_bits/CubeToMatOp_bones.hpp @@ -40,6 +40,8 @@ struct CubeToMatOp : public Base< typename T1::elem_type, CubeToMatOp::is_row; static constexpr bool is_col = op_type::template traits::is_col; static constexpr bool is_xvec = op_type::template traits::is_xvec; + + static constexpr bool has_subview = T1::has_subview; }; diff --git a/inst/include/armadillo_bits/Cube_bones.hpp b/inst/include/armadillo_bits/Cube_bones.hpp index 3c97d4ae..f3f1f83a 100644 --- a/inst/include/armadillo_bits/Cube_bones.hpp +++ b/inst/include/armadillo_bits/Cube_bones.hpp @@ -82,6 +82,8 @@ class Cube : public BaseCube< eT, Cube > public: + static constexpr bool has_subview = false; + inline ~Cube(); inline Cube(); diff --git a/inst/include/armadillo_bits/Cube_meat.hpp b/inst/include/armadillo_bits/Cube_meat.hpp index f44d0465..508ddc6e 100644 --- a/inst/include/armadillo_bits/Cube_meat.hpp +++ b/inst/include/armadillo_bits/Cube_meat.hpp @@ -807,11 +807,29 @@ Cube::Cube(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, cons { init_cold(); - arrayops::copy( memptr(), aux_mem, n_elem ); + if(aux_mem == nullptr) + { + arrayops::fill_zeros(memptr(), n_elem); + } + else + { + arrayops::copy( memptr(), aux_mem, n_elem ); + } } else { - create_mat(); + if(aux_mem == nullptr) + { + access::rw(mem_state) = 0; + + init_cold(); + + arrayops::fill_zeros(memptr(), n_elem); + } + else + { + create_mat(); + } } } @@ -835,7 +853,14 @@ Cube::Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols init_cold(); - arrayops::copy( memptr(), aux_mem, n_elem ); + if(aux_mem == nullptr) + { + arrayops::fill_zeros(memptr(), n_elem); + } + else + { + arrayops::copy( memptr(), aux_mem, n_elem ); + } } diff --git a/inst/include/armadillo_bits/GenCube_bones.hpp b/inst/include/armadillo_bits/GenCube_bones.hpp index 349fd74b..2cb04d59 100644 --- a/inst/include/armadillo_bits/GenCube_bones.hpp +++ b/inst/include/armadillo_bits/GenCube_bones.hpp @@ -28,8 +28,9 @@ struct GenCube typedef eT elem_type; typedef typename get_pod_type::result pod_type; - static constexpr bool use_at = false; - static constexpr bool is_simple = (is_same_type::value) || (is_same_type::value); + static constexpr bool use_at = false; + static constexpr bool is_simple = (is_same_type::value) || (is_same_type::value); + static constexpr bool has_subview = false; const uword n_rows; const uword n_cols; diff --git a/inst/include/armadillo_bits/Gen_bones.hpp b/inst/include/armadillo_bits/Gen_bones.hpp index 4609b6fb..db8d6292 100644 --- a/inst/include/armadillo_bits/Gen_bones.hpp +++ b/inst/include/armadillo_bits/Gen_bones.hpp @@ -35,6 +35,8 @@ struct Gen static constexpr bool is_col = T1::is_col; static constexpr bool is_xvec = T1::is_xvec; + static constexpr bool has_subview = false; + const uword n_rows; const uword n_cols; diff --git a/inst/include/armadillo_bits/GlueCube_bones.hpp b/inst/include/armadillo_bits/GlueCube_bones.hpp index 63e7f612..e50f119c 100644 --- a/inst/include/armadillo_bits/GlueCube_bones.hpp +++ b/inst/include/armadillo_bits/GlueCube_bones.hpp @@ -28,6 +28,8 @@ struct GlueCube : public BaseCube< typename T1::elem_type, GlueCube::result pod_type; + static constexpr bool has_subview = T1::has_subview || T2::has_subview; + inline GlueCube(const BaseCube& in_A, const BaseCube& in_B); inline ~GlueCube(); diff --git a/inst/include/armadillo_bits/Glue_bones.hpp b/inst/include/armadillo_bits/Glue_bones.hpp index 042d39b2..89734cde 100644 --- a/inst/include/armadillo_bits/Glue_bones.hpp +++ b/inst/include/armadillo_bits/Glue_bones.hpp @@ -50,6 +50,8 @@ struct Glue typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; + static constexpr bool has_subview = T1::has_subview || T2::has_subview; + inline Glue(const T1& in_A, const T2& in_B); inline Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword); inline ~Glue(); diff --git a/inst/include/armadillo_bits/Mat_bones.hpp b/inst/include/armadillo_bits/Mat_bones.hpp index d2839d9a..a56e4f7b 100644 --- a/inst/include/armadillo_bits/Mat_bones.hpp +++ b/inst/include/armadillo_bits/Mat_bones.hpp @@ -57,6 +57,8 @@ class Mat : public Base< eT, Mat > static constexpr bool is_row = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = false; + inline ~Mat(); inline Mat(); @@ -452,6 +454,8 @@ class Mat : public Base< eT, Mat > arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col); arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const; + inline void push_back(const eT val); + arma_inline const Mat& operator++(); arma_inline void operator++(int); @@ -819,6 +823,8 @@ class Mat : public Base< eT, Mat > inline Mat(const arma_fixed_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state, const eT* in_mem); + template inline void vec_push_back(const eT val, const arma_vec_mode_indicator&); + friend class Cube; friend class subview_cube; @@ -830,7 +836,7 @@ class Mat : public Base< eT, Mat > friend struct op_mean; friend struct op_max; friend struct op_min; - + public: @@ -866,6 +872,8 @@ class Mat::fixed : public Mat static constexpr bool is_row = (fixed_n_rows == 1); static constexpr bool is_xvec = false; + static constexpr bool has_subview = false; + static const uword n_rows; // value provided below the class definition static const uword n_cols; // value provided below the class definition static const uword n_elem; // value provided below the class definition @@ -922,6 +930,8 @@ class Mat::fixed : public Mat arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col); arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const; + inline void push_back(const eT) = delete; + arma_warn_unused arma_inline eT* colptr(const uword in_col); arma_warn_unused arma_inline const eT* colptr(const uword in_col) const; diff --git a/inst/include/armadillo_bits/Mat_meat.hpp b/inst/include/armadillo_bits/Mat_meat.hpp index 511d44df..b2e3d272 100644 --- a/inst/include/armadillo_bits/Mat_meat.hpp +++ b/inst/include/armadillo_bits/Mat_meat.hpp @@ -1369,7 +1369,23 @@ Mat::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const { init_cold(); - arrayops::copy( memptr(), aux_mem, n_elem ); + if(aux_mem == nullptr) + { + arrayops::fill_zeros(memptr(), n_elem); + } + else + { + arrayops::copy( memptr(), aux_mem, n_elem ); + } + } + else + if(aux_mem == nullptr) + { + access::rw(mem_state) = 0; + + init_cold(); + + arrayops::fill_zeros(memptr(), n_elem); } } @@ -1392,7 +1408,14 @@ Mat::Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols) init_cold(); - arrayops::copy( memptr(), aux_mem, n_elem ); + if(aux_mem == nullptr) + { + arrayops::fill_zeros(memptr(), n_elem); + } + else + { + arrayops::copy( memptr(), aux_mem, n_elem ); + } } @@ -2591,9 +2614,9 @@ Mat::operator+=(const subview_elem1& X) { arma_debug_sigprint(); - subview_elem1::plus_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator+=(tmp); } @@ -2606,9 +2629,9 @@ Mat::operator-=(const subview_elem1& X) { arma_debug_sigprint(); - subview_elem1::minus_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator-=(tmp); } @@ -2621,9 +2644,9 @@ Mat::operator*=(const subview_elem1& X) { arma_debug_sigprint(); - glue_times::apply_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator*=(tmp); } @@ -2636,9 +2659,9 @@ Mat::operator%=(const subview_elem1& X) { arma_debug_sigprint(); - subview_elem1::schur_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator%=(tmp); } @@ -2651,9 +2674,9 @@ Mat::operator/=(const subview_elem1& X) { arma_debug_sigprint(); - subview_elem1::div_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator/=(tmp); } @@ -2719,9 +2742,9 @@ Mat::operator+=(const subview_elem2& X) { arma_debug_sigprint(); - subview_elem2::plus_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator+=(tmp); } @@ -2734,9 +2757,9 @@ Mat::operator-=(const subview_elem2& X) { arma_debug_sigprint(); - subview_elem2::minus_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator-=(tmp); } @@ -2749,9 +2772,9 @@ Mat::operator*=(const subview_elem2& X) { arma_debug_sigprint(); - glue_times::apply_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator*=(tmp); } @@ -2764,9 +2787,9 @@ Mat::operator%=(const subview_elem2& X) { arma_debug_sigprint(); - subview_elem2::schur_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator%=(tmp); } @@ -2779,9 +2802,9 @@ Mat::operator/=(const subview_elem2& X) { arma_debug_sigprint(); - subview_elem2::div_inplace(*this, X); + const Mat tmp(X); - return *this; + return (*this).operator/=(tmp); } @@ -4980,8 +5003,8 @@ Mat::insert_rows(const uword row_num, const Base& X) { arma_debug_sigprint(); - const unwrap tmp(X.get_ref()); - const Mat& C = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& C = tmp.M; const uword C_n_rows = C.n_rows; const uword C_n_cols = C.n_cols; @@ -5056,8 +5079,8 @@ Mat::insert_cols(const uword col_num, const Base& X) { arma_debug_sigprint(); - const unwrap tmp(X.get_ref()); - const Mat& C = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& C = tmp.M; const uword C_n_rows = C.n_rows; const uword C_n_cols = C.n_cols; @@ -7037,6 +7060,31 @@ Mat::at(const uword in_row, const uword in_col) const +template +inline +void +Mat::push_back(const eT val) + { + arma_debug_sigprint(); + + if(mem_state != 0) + { + arma_conform_check(true, "Mat::push_back(): unsupported operation as auxiliary memory is in use"); + + return; + } + + const uword t_n_rows = n_rows; + const uword t_n_cols = n_cols; + + if( (vec_state == 1) || (t_n_cols == 1) || ((t_n_cols == 0) && (t_n_rows == 0)) ) { (*this).vec_push_back(val, arma_colvec_indicator()); return; } + if( (vec_state == 2) || (t_n_rows == 1) ) { (*this).vec_push_back(val, arma_rowvec_indicator()); return; } + + arma_conform_check(true, "Mat::push_back(): column or row vector layout required"); + } + + + //! prefix ++ template arma_inline @@ -10047,6 +10095,119 @@ Mat::back() const +template +template +inline +void +Mat::vec_push_back(const eT val, const arma_vec_mode_indicator&) + { + arma_debug_sigprint( arma_str::format("n_elem: %u; n_alloc: %u") % n_elem % n_alloc ); + + // vec_mode = 1 means col vector layout + // vec_mode = 2 means row vector layout + + const uword old_n_elem = n_elem; + const uword new_n_elem = old_n_elem + 1; + + if(old_n_elem <= arma_config::mat_prealloc) + { + if(old_n_elem == 0) + { + mem_local[0] = val; + + access::rw(mem ) = mem_local; + access::rw(n_rows) = 1; + access::rw(n_cols) = 1; + access::rw(n_elem) = 1; + } + else + if(old_n_elem < arma_config::mat_prealloc) + { + // condition: (old_n_elem >= 1) && (old_n_elem < arma_config::mat_prealloc) + + mem_local[old_n_elem] = val; + + if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; } + if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; } + + access::rw(n_elem) = new_n_elem; + } + else + { + // condition: old_n_elem == arma_config::mat_prealloc + + const uword new_n_alloc = (std::max)(uword(64), uword(arma_config::mat_prealloc + arma_config::mat_prealloc/2)); + + arma_debug_print( arma_str::format("acquiring new memory; new_n_alloc: %u") % new_n_alloc ); + + eT* new_mem_ptr = memory::acquire(new_n_alloc); + + if(new_mem_ptr == nullptr) { return; } + + arma_debug_print("copying memory"); + + arrayops::copy(new_mem_ptr, mem_local, arma_config::mat_prealloc); + + new_mem_ptr[old_n_elem] = val; + + access::rw(mem) = new_mem_ptr; + + if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; } + if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; } + + access::rw(n_elem) = new_n_elem; + access::rw(n_alloc) = new_n_alloc; + } + } + else + { + // condition: old_n_elem > arma_config::mat_prealloc + + if(n_alloc >= new_n_elem) + { + access::rw(mem[old_n_elem]) = val; + + if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; } + if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; } + + access::rw(n_elem) = new_n_elem; + } + else + { + // condition: n_alloc < new_n_elem + + const uword new_n_alloc = (std::max)(uword(256), uword(n_alloc + n_alloc/2)); + + arma_debug_print( arma_str::format("acquiring new memory; new_n_alloc: %u") % new_n_alloc ); + + const eT* old_mem_ptr = mem; + eT* new_mem_ptr = memory::acquire(new_n_alloc); + + if(new_mem_ptr == nullptr) { return; } + + arma_debug_print("copying memory"); + + arrayops::copy(new_mem_ptr, old_mem_ptr, n_elem); + + new_mem_ptr[old_n_elem] = val; + + access::rw(mem) = new_mem_ptr; + + if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; } + if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; } + + access::rw(n_elem ) = new_n_elem; + access::rw(n_alloc) = new_n_alloc; + + arma_debug_print("releasing old memory"); + + memory::release(old_mem_ptr); + } + } + } + + + template template arma_inline @@ -10798,8 +10959,8 @@ Mat_aux::set_real(Mat& out, const Base& X) { arma_debug_sigprint(); - const unwrap tmp(X.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& A = tmp.M; arma_conform_assert_same_size( out, A, "Mat::set_real()" ); diff --git a/inst/include/armadillo_bits/OpCube_bones.hpp b/inst/include/armadillo_bits/OpCube_bones.hpp index 14ed03d4..595334bf 100644 --- a/inst/include/armadillo_bits/OpCube_bones.hpp +++ b/inst/include/armadillo_bits/OpCube_bones.hpp @@ -26,6 +26,8 @@ struct OpCube : public BaseCube< typename T1::elem_type, OpCube > typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; + static constexpr bool has_subview = T1::has_subview; + inline explicit OpCube(const BaseCube& in_m); inline OpCube(const BaseCube& in_m, const elem_type in_aux); inline OpCube(const BaseCube& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c); diff --git a/inst/include/armadillo_bits/Op_bones.hpp b/inst/include/armadillo_bits/Op_bones.hpp index 89b58543..5226d609 100644 --- a/inst/include/armadillo_bits/Op_bones.hpp +++ b/inst/include/armadillo_bits/Op_bones.hpp @@ -50,6 +50,8 @@ struct Op typedef typename T1::elem_type elem_type; typedef typename get_pod_type::result pod_type; + static constexpr bool has_subview = T1::has_subview; + inline explicit Op(const T1& in_m); inline Op(const T1& in_m, const elem_type in_aux); inline Op(const T1& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b); diff --git a/inst/include/armadillo_bits/Proxy.hpp b/inst/include/armadillo_bits/Proxy.hpp index 834ca1a9..4cb5b7b2 100644 --- a/inst/include/armadillo_bits/Proxy.hpp +++ b/inst/include/armadillo_bits/Proxy.hpp @@ -1523,7 +1523,7 @@ struct Proxy_xtrans_default< Op > static constexpr bool is_col = false; static constexpr bool is_xvec = false; - const unwrap U; + const plain_unwrap U; const xtrans_mat Q; inline explicit Proxy_xtrans_default(const Op& A) @@ -1564,7 +1564,7 @@ struct Proxy_xtrans_default< Op > static constexpr bool is_col = false; static constexpr bool is_xvec = false; - const unwrap U; + const plain_unwrap U; const xtrans_mat Q; inline explicit Proxy_xtrans_default(const Op& A) @@ -2419,8 +2419,8 @@ struct Proxy_vectorise_col_mat< Op > static constexpr bool is_col = true; static constexpr bool is_xvec = false; - const unwrap U; - const Mat Q; + const plain_unwrap U; + const Mat Q; inline explicit Proxy_vectorise_col_mat(const Op& A) : U(A.m) diff --git a/inst/include/armadillo_bits/Row_bones.hpp b/inst/include/armadillo_bits/Row_bones.hpp index fdb9612f..3dfebea6 100644 --- a/inst/include/armadillo_bits/Row_bones.hpp +++ b/inst/include/armadillo_bits/Row_bones.hpp @@ -33,6 +33,8 @@ class Row : public Mat static constexpr bool is_row = true; static constexpr bool is_xvec = false; + static constexpr bool has_subview = false; + inline Row(); inline Row(const Row& X); @@ -67,9 +69,6 @@ class Row : public Mat inline Row(Row&& m); inline Row& operator=(Row&& m); - // inline Row(Mat&& m); - // inline Row& operator=(Mat&& m); - inline Row& operator=(const eT val); inline Row& operator=(const Row& X); @@ -153,6 +152,7 @@ class Row : public Mat arma_warn_unused arma_inline eT& at(const uword in_row, const uword in_col); arma_warn_unused arma_inline const eT& at(const uword in_row, const uword in_col) const; + inline void push_back(const eT val); inline constexpr bool is_vec() const { return true; } inline constexpr bool is_rowvec() const { return true; } @@ -213,6 +213,8 @@ class Row::fixed : public Row static constexpr bool is_row = true; static constexpr bool is_xvec = false; + static constexpr bool has_subview = false; + static const uword n_rows; // value provided below the class definition static const uword n_cols; // value provided below the class definition static const uword n_elem; // value provided below the class definition @@ -268,6 +270,8 @@ class Row::fixed : public Row arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col); arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const; + inline void push_back(const eT) = delete; + arma_warn_unused arma_inline eT* memptr(); arma_warn_unused arma_inline const eT* memptr() const; diff --git a/inst/include/armadillo_bits/Row_meat.hpp b/inst/include/armadillo_bits/Row_meat.hpp index 012423a1..ac4a5c20 100644 --- a/inst/include/armadillo_bits/Row_meat.hpp +++ b/inst/include/armadillo_bits/Row_meat.hpp @@ -431,64 +431,6 @@ Row::operator=(Row&& X) -// template -// inline -// Row::Row(Mat&& X) -// : Mat(arma_vec_indicator(), 2) -// { -// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X); -// -// if(X.n_rows != 1) { const Mat& XX = X; Mat::operator=(XX); return; } -// -// access::rw(Mat::n_rows) = 1; -// access::rw(Mat::n_cols) = X.n_cols; -// access::rw(Mat::n_elem) = X.n_elem; -// access::rw(Mat::n_alloc) = X.n_alloc; -// -// if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) ) -// { -// access::rw(Mat::mem_state) = X.mem_state; -// access::rw(Mat::mem) = X.mem; -// -// access::rw(X.n_cols) = 0; -// access::rw(X.n_elem) = 0; -// access::rw(X.n_alloc) = 0; -// access::rw(X.mem_state) = 0; -// access::rw(X.mem) = nullptr; -// } -// else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3) -// { -// (*this).init_cold(); -// -// arrayops::copy( (*this).memptr(), X.mem, X.n_elem ); -// -// if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) ) -// { -// access::rw(X.n_cols) = 0; -// access::rw(X.n_elem) = 0; -// access::rw(X.mem) = nullptr; -// } -// } -// } -// -// -// -// template -// inline -// Row& -// Row::operator=(Mat&& X) -// { -// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X); -// -// if(X.n_rows != 1) { const Mat& XX = X; Mat::operator=(XX); return *this; } -// -// (*this).steal_mem(X, true); -// -// return *this; -// } - - - template inline Row& @@ -1208,6 +1150,25 @@ Row::at(const uword, const uword in_col) const +template +inline +void +Row::push_back(const eT val) + { + arma_debug_sigprint(); + + if(Mat::mem_state != 0) + { + arma_conform_check(true, "Row::push_back(): unsupported operation as auxiliary memory is in use"); + + return; + } + + Mat::vec_push_back(val, arma_rowvec_indicator()); + } + + + template inline typename Row::row_iterator diff --git a/inst/include/armadillo_bits/SpGlue_bones.hpp b/inst/include/armadillo_bits/SpGlue_bones.hpp index f76894af..6d69c1cc 100644 --- a/inst/include/armadillo_bits/SpGlue_bones.hpp +++ b/inst/include/armadillo_bits/SpGlue_bones.hpp @@ -31,6 +31,8 @@ struct SpGlue : public SpBase< typename T1::elem_type, SpGlue::is_col; static constexpr bool is_xvec = spglue_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview || T2::has_subview; + inline SpGlue(const T1& in_A, const T2& in_B); inline SpGlue(const T1& in_A, const T2& in_B, const elem_type in_aux); inline ~SpGlue(); diff --git a/inst/include/armadillo_bits/SpMat_bones.hpp b/inst/include/armadillo_bits/SpMat_bones.hpp index f28b8c2e..05c795a9 100644 --- a/inst/include/armadillo_bits/SpMat_bones.hpp +++ b/inst/include/armadillo_bits/SpMat_bones.hpp @@ -33,6 +33,8 @@ class SpMat : public SpBase< eT, SpMat > static constexpr bool is_col = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = false; + const uword n_rows; //!< number of rows (read-only) const uword n_cols; //!< number of columns (read-only) const uword n_elem; //!< number of elements (read-only) diff --git a/inst/include/armadillo_bits/SpOp_bones.hpp b/inst/include/armadillo_bits/SpOp_bones.hpp index 9d8fa51d..c46834c3 100644 --- a/inst/include/armadillo_bits/SpOp_bones.hpp +++ b/inst/include/armadillo_bits/SpOp_bones.hpp @@ -31,6 +31,8 @@ struct SpOp : public SpBase< typename T1::elem_type, SpOp > static constexpr bool is_col = op_type::template traits::is_col; static constexpr bool is_xvec = op_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview; + inline explicit SpOp(const T1& in_m); inline SpOp(const T1& in_m, const elem_type in_aux); inline SpOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); diff --git a/inst/include/armadillo_bits/SpSubview_bones.hpp b/inst/include/armadillo_bits/SpSubview_bones.hpp index 4cf60621..fdb36240 100644 --- a/inst/include/armadillo_bits/SpSubview_bones.hpp +++ b/inst/include/armadillo_bits/SpSubview_bones.hpp @@ -34,6 +34,8 @@ class SpSubview : public SpBase< eT, SpSubview > static constexpr bool is_col = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + const uword aux_row1; const uword aux_col1; const uword n_rows; @@ -351,6 +353,8 @@ class SpSubview_col : public SpSubview static constexpr bool is_col = true; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + inline void operator= (const SpSubview& x); inline void operator= (const SpSubview_col& x); @@ -391,6 +395,8 @@ class SpSubview_row : public SpSubview static constexpr bool is_col = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + inline void operator= (const SpSubview& x); inline void operator= (const SpSubview_row& x); diff --git a/inst/include/armadillo_bits/SpSubview_col_list_bones.hpp b/inst/include/armadillo_bits/SpSubview_col_list_bones.hpp index f2c9a637..47ed069f 100644 --- a/inst/include/armadillo_bits/SpSubview_col_list_bones.hpp +++ b/inst/include/armadillo_bits/SpSubview_col_list_bones.hpp @@ -33,6 +33,8 @@ class SpSubview_col_list : public SpBase< eT, SpSubview_col_list > static constexpr bool is_col = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + const SpMat& m; const quasi_unwrap U_ci; diff --git a/inst/include/armadillo_bits/SpToDGlue_bones.hpp b/inst/include/armadillo_bits/SpToDGlue_bones.hpp index 160657d8..d3df19f7 100644 --- a/inst/include/armadillo_bits/SpToDGlue_bones.hpp +++ b/inst/include/armadillo_bits/SpToDGlue_bones.hpp @@ -31,6 +31,8 @@ struct SpToDGlue : public Base< typename T1::elem_type, SpToDGlue::is_col; static constexpr bool is_xvec = glue_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview || T2::has_subview; + inline explicit SpToDGlue(const T1& in_A, const T2& in_B); inline ~SpToDGlue(); diff --git a/inst/include/armadillo_bits/SpToDOp_bones.hpp b/inst/include/armadillo_bits/SpToDOp_bones.hpp index 2e6e183c..c186c78d 100644 --- a/inst/include/armadillo_bits/SpToDOp_bones.hpp +++ b/inst/include/armadillo_bits/SpToDOp_bones.hpp @@ -32,6 +32,8 @@ struct SpToDOp : public Base< typename T1::elem_type, SpToDOp > static constexpr bool is_col = op_type::template traits::is_col; static constexpr bool is_xvec = op_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview; + inline explicit SpToDOp(const T1& in_m); inline SpToDOp(const T1& in_m, const elem_type in_aux); inline SpToDOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); diff --git a/inst/include/armadillo_bits/arma_forward.hpp b/inst/include/armadillo_bits/arma_forward.hpp index a71cc4cb..778a329b 100644 --- a/inst/include/armadillo_bits/arma_forward.hpp +++ b/inst/include/armadillo_bits/arma_forward.hpp @@ -286,8 +286,9 @@ template struct ProxyCube; template struct diagmat_proxy; -template struct unwrap; +template struct plain_unwrap; template struct quasi_unwrap; + template struct unwrap_cube; template struct unwrap_spmat; @@ -365,6 +366,12 @@ struct arma_zeros_indicator : public arma_initmode_indicator {}; struct arma_nozeros_indicator : public arma_initmode_indicator {}; +template struct arma_vec_mode_indicator {}; + +struct arma_colvec_indicator : public arma_vec_mode_indicator<1> {}; +struct arma_rowvec_indicator : public arma_vec_mode_indicator<2> {}; + + //! \addtogroup injector //! @{ diff --git a/inst/include/armadillo_bits/arma_version.hpp b/inst/include/armadillo_bits/arma_version.hpp index 2a0b40a2..ae6f4982 100644 --- a/inst/include/armadillo_bits/arma_version.hpp +++ b/inst/include/armadillo_bits/arma_version.hpp @@ -22,9 +22,9 @@ #define ARMA_VERSION_MAJOR 15 -#define ARMA_VERSION_MINOR 2 -#define ARMA_VERSION_PATCH 7 -#define ARMA_VERSION_NAME "Medium Roast Deluxe" +#define ARMA_VERSION_MINOR 3 +#define ARMA_VERSION_PATCH 91 +#define ARMA_VERSION_NAME "15.4-RC1" diff --git a/inst/include/armadillo_bits/auxlib_meat.hpp b/inst/include/armadillo_bits/auxlib_meat.hpp index cc842997..87af2cba 100644 --- a/inst/include/armadillo_bits/auxlib_meat.hpp +++ b/inst/include/armadillo_bits/auxlib_meat.hpp @@ -2932,8 +2932,8 @@ auxlib::qr_econ(Mat& Q, Mat& R, const Base& X) { if(is_Mat::value) { - const unwrap tmp(X.get_ref()); - const Mat& M = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& M = tmp.M; if(M.n_rows < M.n_cols) { return auxlib::qr(Q, R, X); } } @@ -5160,8 +5160,8 @@ auxlib::solve_rect_fast(Mat& out, Mat U(B_expr.get_ref()); - const Mat& B = U.M; + const plain_unwrap U(B_expr.get_ref()); + const Mat& B = U.M; arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); @@ -5254,8 +5254,8 @@ auxlib::solve_rect_rcond(Mat& out, typename T1::pod_type out_rcond = T(0); - const unwrap U(B_expr.get_ref()); - const Mat& B = U.M; + const plain_unwrap U(B_expr.get_ref()); + const Mat& B = U.M; arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); @@ -5387,8 +5387,8 @@ auxlib::solve_approx_svd(Mat& out, Mat U(B_expr.get_ref()); - const Mat& B = U.M; + const plain_unwrap U(B_expr.get_ref()); + const Mat& B = U.M; arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); @@ -5509,8 +5509,8 @@ auxlib::solve_approx_svd(Mat< std::complex >& out, Mat< s typedef typename T1::pod_type T; typedef typename std::complex eT; - const unwrap U(B_expr.get_ref()); - const Mat& B = U.M; + const plain_unwrap U(B_expr.get_ref()); + const Mat& B = U.M; arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" ); diff --git a/inst/include/armadillo_bits/diagview_bones.hpp b/inst/include/armadillo_bits/diagview_bones.hpp index 3ef0f1db..2eb89228 100644 --- a/inst/include/armadillo_bits/diagview_bones.hpp +++ b/inst/include/armadillo_bits/diagview_bones.hpp @@ -35,6 +35,8 @@ class diagview : public Base< eT, diagview > static constexpr bool is_col = true; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + const uword row_offset; const uword col_offset; diff --git a/inst/include/armadillo_bits/eglue_core_meat.hpp b/inst/include/armadillo_bits/eglue_core_meat.hpp index 03838010..8f8fbc51 100644 --- a/inst/include/armadillo_bits/eglue_core_meat.hpp +++ b/inst/include/armadillo_bits/eglue_core_meat.hpp @@ -265,6 +265,7 @@ eglue_core::apply(outT& out, const eGlue& x) constexpr bool use_at = (Proxy::use_at || Proxy::use_at); constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (Proxy::use_mp && Proxy::use_mp); // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing; // size setting and alias checking is done by either the Mat constructor or operator=() @@ -276,7 +277,7 @@ eglue_core::apply(outT& out, const eGlue& x) { const uword n_elem = x.get_n_elem(); - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename Proxy::ea_type P1 = x.P1.get_ea(); typename Proxy::ea_type P2 = x.P2.get_ea(); @@ -333,7 +334,7 @@ eglue_core::apply(outT& out, const eGlue& x) const Proxy& P1 = x.P1; const Proxy& P2 = x.P2; - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_2_mp(=, +); } else if(is_same_type::yes) { arma_applier_2_mp(=, -); } @@ -371,12 +372,13 @@ eglue_core::apply_inplace_plus(Mat& out, con constexpr bool use_at = (Proxy::use_at || Proxy::use_at); constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (Proxy::use_mp && Proxy::use_mp); if(use_at == false) { const uword n_elem = x.get_n_elem(); - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename Proxy::ea_type P1 = x.P1.get_ea(); typename Proxy::ea_type P2 = x.P2.get_ea(); @@ -430,7 +432,7 @@ eglue_core::apply_inplace_plus(Mat& out, con const Proxy& P1 = x.P1; const Proxy& P2 = x.P2; - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_2_mp(+=, +); } else if(is_same_type::yes) { arma_applier_2_mp(+=, -); } @@ -468,12 +470,13 @@ eglue_core::apply_inplace_minus(Mat& out, co constexpr bool use_at = (Proxy::use_at || Proxy::use_at); constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (Proxy::use_mp && Proxy::use_mp); if(use_at == false) { const uword n_elem = x.get_n_elem(); - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename Proxy::ea_type P1 = x.P1.get_ea(); typename Proxy::ea_type P2 = x.P2.get_ea(); @@ -527,7 +530,7 @@ eglue_core::apply_inplace_minus(Mat& out, co const Proxy& P1 = x.P1; const Proxy& P2 = x.P2; - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_2_mp(-=, +); } else if(is_same_type::yes) { arma_applier_2_mp(-=, -); } @@ -565,12 +568,13 @@ eglue_core::apply_inplace_schur(Mat& out, co constexpr bool use_at = (Proxy::use_at || Proxy::use_at); constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (Proxy::use_mp && Proxy::use_mp); if(use_at == false) { const uword n_elem = x.get_n_elem(); - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename Proxy::ea_type P1 = x.P1.get_ea(); typename Proxy::ea_type P2 = x.P2.get_ea(); @@ -624,7 +628,7 @@ eglue_core::apply_inplace_schur(Mat& out, co const Proxy& P1 = x.P1; const Proxy& P2 = x.P2; - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_2_mp(*=, +); } else if(is_same_type::yes) { arma_applier_2_mp(*=, -); } @@ -662,12 +666,13 @@ eglue_core::apply_inplace_div(Mat& out, cons constexpr bool use_at = (Proxy::use_at || Proxy::use_at); constexpr bool use_mp = (Proxy::use_mp || Proxy::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (Proxy::use_mp && Proxy::use_mp); if(use_at == false) { const uword n_elem = x.get_n_elem(); - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename Proxy::ea_type P1 = x.P1.get_ea(); typename Proxy::ea_type P2 = x.P2.get_ea(); @@ -721,7 +726,7 @@ eglue_core::apply_inplace_div(Mat& out, cons const Proxy& P1 = x.P1; const Proxy& P2 = x.P2; - if(use_mp && mp_gate::use_mp && Proxy::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_2_mp(/=, +); } else if(is_same_type::yes) { arma_applier_2_mp(/=, -); } @@ -757,6 +762,7 @@ eglue_core::apply(Cube& out, const eGlueCube constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (ProxyCube::use_mp && ProxyCube::use_mp); // NOTE: we're assuming that the cube has already been set to the correct size and there is no aliasing; // size setting and alias checking is done by either the Cube constructor or operator=() @@ -768,7 +774,7 @@ eglue_core::apply(Cube& out, const eGlueCube { const uword n_elem = out.n_elem; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename ProxyCube::ea_type P1 = x.P1.get_ea(); typename ProxyCube::ea_type P2 = x.P2.get_ea(); @@ -826,7 +832,7 @@ eglue_core::apply(Cube& out, const eGlueCube const ProxyCube& P1 = x.P1; const ProxyCube& P2 = x.P2; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_3_mp(=, +); } else if(is_same_type::yes) { arma_applier_3_mp(=, -); } @@ -865,12 +871,13 @@ eglue_core::apply_inplace_plus(Cube& out, co constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (ProxyCube::use_mp && ProxyCube::use_mp); if(use_at == false) { const uword n_elem = out.n_elem; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename ProxyCube::ea_type P1 = x.P1.get_ea(); typename ProxyCube::ea_type P2 = x.P2.get_ea(); @@ -924,7 +931,7 @@ eglue_core::apply_inplace_plus(Cube& out, co const ProxyCube& P1 = x.P1; const ProxyCube& P2 = x.P2; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_3_mp(+=, +); } else if(is_same_type::yes) { arma_applier_3_mp(+=, -); } @@ -963,12 +970,13 @@ eglue_core::apply_inplace_minus(Cube& out, c constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (ProxyCube::use_mp && ProxyCube::use_mp); if(use_at == false) { const uword n_elem = out.n_elem; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename ProxyCube::ea_type P1 = x.P1.get_ea(); typename ProxyCube::ea_type P2 = x.P2.get_ea(); @@ -1022,7 +1030,7 @@ eglue_core::apply_inplace_minus(Cube& out, c const ProxyCube& P1 = x.P1; const ProxyCube& P2 = x.P2; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_3_mp(-=, +); } else if(is_same_type::yes) { arma_applier_3_mp(-=, -); } @@ -1061,12 +1069,13 @@ eglue_core::apply_inplace_schur(Cube& out, c constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (ProxyCube::use_mp && ProxyCube::use_mp); if(use_at == false) { const uword n_elem = out.n_elem; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename ProxyCube::ea_type P1 = x.P1.get_ea(); typename ProxyCube::ea_type P2 = x.P2.get_ea(); @@ -1120,7 +1129,7 @@ eglue_core::apply_inplace_schur(Cube& out, c const ProxyCube& P1 = x.P1; const ProxyCube& P2 = x.P2; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_3_mp(*=, +); } else if(is_same_type::yes) { arma_applier_3_mp(*=, -); } @@ -1159,12 +1168,13 @@ eglue_core::apply_inplace_div(Cube& out, con constexpr bool use_at = (ProxyCube::use_at || ProxyCube::use_at); constexpr bool use_mp = (ProxyCube::use_mp || ProxyCube::use_mp) && (arma_config::openmp); + constexpr bool use_ht = (ProxyCube::use_mp && ProxyCube::use_mp); if(use_at == false) { const uword n_elem = out.n_elem; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(n_elem)) + if(use_mp && mp_gate::eval(n_elem)) { typename ProxyCube::ea_type P1 = x.P1.get_ea(); typename ProxyCube::ea_type P2 = x.P2.get_ea(); @@ -1218,7 +1228,7 @@ eglue_core::apply_inplace_div(Cube& out, con const ProxyCube& P1 = x.P1; const ProxyCube& P2 = x.P2; - if(use_mp && mp_gate::use_mp && ProxyCube::use_mp)>::eval(x.get_n_elem())) + if(use_mp && mp_gate::eval(x.get_n_elem())) { if(is_same_type::yes) { arma_applier_3_mp(/=, +); } else if(is_same_type::yes) { arma_applier_3_mp(/=, -); } diff --git a/inst/include/armadillo_bits/fn_as_scalar.hpp b/inst/include/armadillo_bits/fn_as_scalar.hpp index 30a65f10..fc16f9bb 100644 --- a/inst/include/armadillo_bits/fn_as_scalar.hpp +++ b/inst/include/armadillo_bits/fn_as_scalar.hpp @@ -281,8 +281,8 @@ as_scalar_diag(const Base& X) typedef typename T1::elem_type eT; - const unwrap tmp(X.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& A = tmp.M; arma_conform_check_bounds( (A.n_elem != 1), "as_scalar(): expected 1x1 matrix" ); diff --git a/inst/include/armadillo_bits/fn_conv_to.hpp b/inst/include/armadillo_bits/fn_conv_to.hpp index 99e19b08..b9661da4 100644 --- a/inst/include/armadillo_bits/fn_conv_to.hpp +++ b/inst/include/armadillo_bits/fn_conv_to.hpp @@ -21,6 +21,276 @@ +template +struct conv_to_helper_Mat_same_type + { + template + inline + static + Mat + apply(const Base& in) + { + arma_debug_sigprint(); + + return Mat(in.get_ref()); + } + + inline + static + Mat + apply(const std::vector& in) + { + arma_debug_sigprint(); + + const uword N = uword( in.size() ); + + const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr; + + return Mat(in_memptr, N, 1); + } + }; + + + +template +struct conv_to_helper_Mat_diff_type + { + template + inline + static + Mat + apply(const Base& in) + { + arma_debug_sigprint(); + + const quasi_unwrap tmp(in.get_ref()); + const Mat& X = tmp.M; + + Mat out(X.n_rows, X.n_cols, arma_nozeros_indicator()); + + arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); + + return out; + } + + inline + static + Mat + apply(const std::vector& in) + { + arma_debug_sigprint(); + + const uword N = uword( in.size() ); + + Mat out(N, 1, arma_nozeros_indicator()); + + if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); } + + return out; + } + }; + + + +template +struct conv_to_helper_Mat_redirect {}; + +template +struct conv_to_helper_Mat_redirect { typedef conv_to_helper_Mat_same_type result; }; + +template +struct conv_to_helper_Mat_redirect { typedef conv_to_helper_Mat_diff_type result; }; + + + +template +struct conv_to_helper_Row_same_type + { + template + inline + static + Row + apply(const Base& in) + { + arma_debug_sigprint(); + + Mat X(in.get_ref()); + + arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); + + access::rw(X.n_rows ) = uword(1); + access::rw(X.n_cols ) = X.n_elem; + access::rw(X.vec_state) = uword(2); + + Row out; out.steal_mem(X); + + return out; + } + + inline + static + Row + apply(const std::vector& in) + { + arma_debug_sigprint(); + + const uword N = uword( in.size() ); + + const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr; + + return Row(in_memptr, N); + } + }; + + + +template +struct conv_to_helper_Row_diff_type + { + template + inline + static + Row + apply(const Base& in) + { + arma_debug_sigprint(); + + const quasi_unwrap tmp(in.get_ref()); + const Mat& X = tmp.M; + + arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); + + Row out(X.n_elem, arma_nozeros_indicator()); + + arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); + + return out; + } + + inline + static + Row + apply(const std::vector& in) + { + arma_debug_sigprint(); + + const uword N = uword( in.size() ); + + Row out(N, arma_nozeros_indicator()); + + if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); } + + return out; + } + }; + + + +template +struct conv_to_helper_Row_redirect {}; + +template +struct conv_to_helper_Row_redirect { typedef conv_to_helper_Row_same_type result; }; + +template +struct conv_to_helper_Row_redirect { typedef conv_to_helper_Row_diff_type result; }; + + + +template +struct conv_to_helper_Col_same_type + { + template + inline + static + Col + apply(const Base& in) + { + arma_debug_sigprint(); + + Mat X(in.get_ref()); + + arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); + + access::rw(X.n_rows ) = X.n_elem; + access::rw(X.n_cols ) = uword(1); + access::rw(X.vec_state) = uword(1); + + Col out; out.steal_mem(X); + + return out; + } + + inline + static + Col + apply(const std::vector& in) + { + arma_debug_sigprint(); + + const uword N = uword( in.size() ); + + const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr; + + return Col(in_memptr, N); + } + }; + + + +template +struct conv_to_helper_Col_diff_type + { + template + inline + static + Col + apply(const Base& in) + { + arma_debug_sigprint(); + + const quasi_unwrap tmp(in.get_ref()); + const Mat& X = tmp.M; + + arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); + + Col out(X.n_elem, arma_nozeros_indicator()); + + arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); + + return out; + } + + inline + static + Col + apply(const std::vector& in) + { + arma_debug_sigprint(); + + const uword N = uword( in.size() ); + + Col out(N, arma_nozeros_indicator()); + + if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); } + + return out; + } + }; + + + +template +struct conv_to_helper_Col_redirect {}; + +template +struct conv_to_helper_Col_redirect { typedef conv_to_helper_Col_same_type result; }; + +template +struct conv_to_helper_Col_redirect { typedef conv_to_helper_Col_diff_type result; }; + + + //! conversion from Armadillo Base and BaseCube objects to scalars //! NOTE: use as_scalar() instead; this functionality is kept only for compatibility with old user code template @@ -195,14 +465,9 @@ conv_to< Mat >::from(const Base& in, const typename arma_not_ arma_debug_sigprint(); arma_ignore(junk); - const quasi_unwrap tmp(in.get_ref()); - const Mat& X = tmp.M; + typedef typename conv_to_helper_Mat_redirect::value>::result helper_type; - Mat out(X.n_rows, X.n_cols, arma_nozeros_indicator()); - - arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); - - return out; + return helper_type::apply(in.get_ref()); } @@ -297,16 +562,9 @@ conv_to< Mat >::from(const std::vector& in, const typename arma_n arma_debug_sigprint(); arma_ignore(junk); - const uword N = uword( in.size() ); - - Mat out(N, 1, arma_nozeros_indicator()); + typedef typename conv_to_helper_Mat_redirect::value>::result helper_type; - if(N > 0) - { - arrayops::convert( out.memptr(), &(in[0]), N ); - } - - return out; + return helper_type::apply(in); } @@ -366,16 +624,9 @@ conv_to< Row >::from(const Base& in, const typename arma_not_ arma_debug_sigprint(); arma_ignore(junk); - const quasi_unwrap tmp(in.get_ref()); - const Mat& X = tmp.M; - - arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); - - Row out(X.n_elem, arma_nozeros_indicator()); - - arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); + typedef typename conv_to_helper_Row_redirect::value>::result helper_type; - return out; + return helper_type::apply(in.get_ref()); } @@ -414,16 +665,9 @@ conv_to< Row >::from(const std::vector& in, const typename arma_n arma_debug_sigprint(); arma_ignore(junk); - const uword N = uword( in.size() ); - - Row out(N, arma_nozeros_indicator()); - - if(N > 0) - { - arrayops::convert( out.memptr(), &(in[0]), N ); - } + typedef typename conv_to_helper_Row_redirect::value>::result helper_type; - return out; + return helper_type::apply(in); } @@ -483,16 +727,9 @@ conv_to< Col >::from(const Base& in, const typename arma_not_ arma_debug_sigprint(); arma_ignore(junk); - const quasi_unwrap tmp(in.get_ref()); - const Mat& X = tmp.M; - - arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" ); + typedef typename conv_to_helper_Col_redirect::value>::result helper_type; - Col out(X.n_elem, arma_nozeros_indicator()); - - arrayops::convert( out.memptr(), X.memptr(), X.n_elem ); - - return out; + return helper_type::apply(in.get_ref()); } @@ -531,16 +768,9 @@ conv_to< Col >::from(const std::vector& in, const typename arma_n arma_debug_sigprint(); arma_ignore(junk); - const uword N = uword( in.size() ); - - Col out(N, arma_nozeros_indicator()); - - if(N > 0) - { - arrayops::convert( out.memptr(), &(in[0]), N ); - } + typedef typename conv_to_helper_Col_redirect::value>::result helper_type; - return out; + return helper_type::apply(in); } diff --git a/inst/include/armadillo_bits/fn_find.hpp b/inst/include/armadillo_bits/fn_find.hpp index bd06c753..aa73873d 100644 --- a/inst/include/armadillo_bits/fn_find.hpp +++ b/inst/include/armadillo_bits/fn_find.hpp @@ -28,13 +28,13 @@ typename enable_if2 < is_arma_type::value, - const mtOp + const mtOp >::result find(const T1& X) { arma_debug_sigprint(); - return mtOp(X); + return mtOp(X); } @@ -42,7 +42,7 @@ find(const T1& X) template arma_warn_unused inline -const mtOp +const mtOp find(const Base& X, const uword k, const char* direction = "first") { arma_debug_sigprint(); @@ -57,7 +57,7 @@ find(const Base& X, const uword k, const char* direct const uword type = ( (sig == 'f') || (sig == 'F') ) ? 0 : 1; - return mtOp(X.get_ref(), k, type); + return mtOp(X.get_ref(), k, type); } diff --git a/inst/include/armadillo_bits/fn_inv.hpp b/inst/include/armadillo_bits/fn_inv.hpp index 9a468889..e522d0fc 100644 --- a/inst/include/armadillo_bits/fn_inv.hpp +++ b/inst/include/armadillo_bits/fn_inv.hpp @@ -63,7 +63,7 @@ inv template arma_warn_unused -arma_inline +inline typename enable_if2< is_blas_type::value, const Op >::result inv ( diff --git a/inst/include/armadillo_bits/fn_inv_sympd.hpp b/inst/include/armadillo_bits/fn_inv_sympd.hpp index 9caf41d5..bf3e4cfc 100644 --- a/inst/include/armadillo_bits/fn_inv_sympd.hpp +++ b/inst/include/armadillo_bits/fn_inv_sympd.hpp @@ -63,7 +63,7 @@ inv_sympd template arma_warn_unused -arma_inline +inline typename enable_if2< is_blas_type::value, const Op >::result inv_sympd ( diff --git a/inst/include/armadillo_bits/fn_powext.hpp b/inst/include/armadillo_bits/fn_powext.hpp index e49e0dd7..d42226c5 100644 --- a/inst/include/armadillo_bits/fn_powext.hpp +++ b/inst/include/armadillo_bits/fn_powext.hpp @@ -78,7 +78,7 @@ pow template -[[deprecated]] +[[deprecated("refactor your code to use pow() in conjunction with repcube()")]] inline Cube pow @@ -160,7 +160,7 @@ pow template -[[deprecated]] +[[deprecated("refactor your code to use pow() in conjunction with repcube()")]] inline Cube< std::complex > pow diff --git a/inst/include/armadillo_bits/fn_sylvester.hpp b/inst/include/armadillo_bits/fn_sylvester.hpp index 8c01646e..eb2f0a93 100644 --- a/inst/include/armadillo_bits/fn_sylvester.hpp +++ b/inst/include/armadillo_bits/fn_sylvester.hpp @@ -97,9 +97,9 @@ sylvester typedef typename T1::elem_type eT; - const unwrap tmp_A( in_A.get_ref() ); - const unwrap tmp_B( in_B.get_ref() ); - const unwrap tmp_C( in_C.get_ref() ); + const plain_unwrap tmp_A( in_A.get_ref() ); + const plain_unwrap tmp_B( in_B.get_ref() ); + const plain_unwrap tmp_C( in_C.get_ref() ); const Mat& A = tmp_A.M; const Mat& B = tmp_B.M; diff --git a/inst/include/armadillo_bits/fn_trimat.hpp b/inst/include/armadillo_bits/fn_trimat.hpp index bd19dba0..b10b9ec9 100644 --- a/inst/include/armadillo_bits/fn_trimat.hpp +++ b/inst/include/armadillo_bits/fn_trimat.hpp @@ -48,7 +48,7 @@ trimatl(const Base& X) template arma_warn_unused -arma_inline +inline const SpOp trimatu(const SpBase& X) { @@ -61,7 +61,7 @@ trimatu(const SpBase& X) template arma_warn_unused -arma_inline +inline const SpOp trimatl(const SpBase& X) { @@ -78,7 +78,7 @@ trimatl(const SpBase& X) template arma_warn_unused -arma_inline +inline const Op trimatl(const Base& X, const sword k) { @@ -94,7 +94,7 @@ trimatl(const Base& X, const sword k) template arma_warn_unused -arma_inline +inline const Op trimatu(const Base& X, const sword k) { @@ -110,7 +110,7 @@ trimatu(const Base& X, const sword k) template arma_warn_unused -arma_inline +inline const SpOp trimatu(const SpBase& X, const sword k) { @@ -126,7 +126,7 @@ trimatu(const SpBase& X, const sword k) template arma_warn_unused -arma_inline +inline const SpOp trimatl(const SpBase& X, const sword k) { diff --git a/inst/include/armadillo_bits/glue_atan2_meat.hpp b/inst/include/armadillo_bits/glue_atan2_meat.hpp index 53d1c55f..749b249a 100644 --- a/inst/include/armadillo_bits/glue_atan2_meat.hpp +++ b/inst/include/armadillo_bits/glue_atan2_meat.hpp @@ -103,8 +103,8 @@ glue_atan2::apply_noalias(Mat& out, const Proxy& P1, { if(use_mp) { - const unwrap::stored_type> U1(P1.Q); - const unwrap::stored_type> U2(P2.Q); + const plain_unwrap::stored_type> U1(P1.Q); + const plain_unwrap::stored_type> U2(P2.Q); out = arma::atan2(U1.M, U2.M); } diff --git a/inst/include/armadillo_bits/glue_cor_meat.hpp b/inst/include/armadillo_bits/glue_cor_meat.hpp index 7a9f09ba..a0cf91b0 100644 --- a/inst/include/armadillo_bits/glue_cor_meat.hpp +++ b/inst/include/armadillo_bits/glue_cor_meat.hpp @@ -32,8 +32,8 @@ glue_cor::apply(Mat& out, const Glue& X) const uword norm_type = X.aux_uword; - const unwrap UA(X.A); - const unwrap UB(X.B); + const plain_unwrap UA(X.A); + const plain_unwrap UB(X.B); const Mat& A = UA.M; const Mat& B = UB.M; diff --git a/inst/include/armadillo_bits/glue_cov_meat.hpp b/inst/include/armadillo_bits/glue_cov_meat.hpp index d311b0d3..2932983c 100644 --- a/inst/include/armadillo_bits/glue_cov_meat.hpp +++ b/inst/include/armadillo_bits/glue_cov_meat.hpp @@ -32,8 +32,8 @@ glue_cov::apply(Mat& out, const Glue& X) const uword norm_type = X.aux_uword; - const unwrap UA(X.A); - const unwrap UB(X.B); + const plain_unwrap UA(X.A); + const plain_unwrap UB(X.B); const Mat& A = UA.M; const Mat& B = UB.M; diff --git a/inst/include/armadillo_bits/glue_max_meat.hpp b/inst/include/armadillo_bits/glue_max_meat.hpp index 15995a7f..93404704 100644 --- a/inst/include/armadillo_bits/glue_max_meat.hpp +++ b/inst/include/armadillo_bits/glue_max_meat.hpp @@ -75,13 +75,41 @@ glue_max::apply(Mat& out, const Proxy& PA, const Proxy& PB) const uword N = PA.get_n_elem(); - for(uword i=0; i& out, const Proxy& PA, const Proxy& PB) const uword N = PA.get_n_elem(); - for(uword i=0; i inline static void apply(Mat& out, const Mat& A, const Mat& B); + // TODO: deprecated; remove in next major version template inline static Mat apply(const subview_each1& X, const Base& Y); // @@ -38,6 +39,7 @@ struct glue_powext template inline static void apply(Cube& out, const Cube& A, const Cube& B); + // TODO: deprecated; remove in next major version template inline static Cube apply(const subview_cube_each1& X, const Base& Y); }; @@ -50,6 +52,7 @@ struct glue_powext_cx template inline static void apply(Mat< std::complex >& out, const Mat< std::complex >& A, const Mat& B); + // TODO: deprecated; remove in next major version template inline static Mat apply(const subview_each1& X, const Base& Y); // @@ -58,6 +61,7 @@ struct glue_powext_cx template inline static void apply(Cube< std::complex >& out, const Cube< std::complex >& A, const Cube& B); + // TODO: deprecated; remove in next major version template inline static Cube< std::complex > apply(const subview_cube_each1< std::complex >& X, const Base& Y); }; diff --git a/inst/include/armadillo_bits/glue_powext_meat.hpp b/inst/include/armadillo_bits/glue_powext_meat.hpp index c88981d4..37de7f18 100644 --- a/inst/include/armadillo_bits/glue_powext_meat.hpp +++ b/inst/include/armadillo_bits/glue_powext_meat.hpp @@ -97,6 +97,7 @@ glue_powext::apply(Mat& out, const Mat& A, const Mat& B) +// TODO: deprecated; remove in next major version template inline Mat @@ -280,6 +281,7 @@ glue_powext::apply(Cube& out, const Cube& A, const Cube& B) +// TODO: deprecated; remove in next major version template inline Cube @@ -426,6 +428,7 @@ glue_powext_cx::apply(Mat< std::complex >& out, const Mat< std::complex >& +// TODO: deprecated; remove in next major version template inline Mat @@ -603,6 +606,7 @@ glue_powext_cx::apply(Cube< std::complex >& out, const Cube< std::complex +// TODO: deprecated; remove in next major version template inline Cube< std::complex > diff --git a/inst/include/armadillo_bits/glue_times_meat.hpp b/inst/include/armadillo_bits/glue_times_meat.hpp index ac5534ec..821d2d00 100644 --- a/inst/include/armadillo_bits/glue_times_meat.hpp +++ b/inst/include/armadillo_bits/glue_times_meat.hpp @@ -109,11 +109,11 @@ glue_times_redirect2_helper::apply(Mat::no) && (strip_inv::do_inv_gen) && (is_Mat::value) && (is_Mat::value) ) { - const unwrap UA(A_strip.M); - const unwrap UB(X.B); + const plain_unwrap UA(A_strip.M); + const plain_unwrap UB(X.B); - const typename unwrap::stored_type& A = UA.M; - const typename unwrap::stored_type& B = UB.M; + const typename plain_unwrap::stored_type& A = UA.M; + const typename plain_unwrap::stored_type& B = UB.M; const uword N = A.n_rows; diff --git a/inst/include/armadillo_bits/gmm_diag_meat.hpp b/inst/include/armadillo_bits/gmm_diag_meat.hpp index 918d1fa4..34d82520 100644 --- a/inst/include/armadillo_bits/gmm_diag_meat.hpp +++ b/inst/include/armadillo_bits/gmm_diag_meat.hpp @@ -137,9 +137,9 @@ gmm_diag::set_params(const Base& in_means_expr, const Base& in { arma_debug_sigprint(); - const unwrap tmp1(in_means_expr.get_ref()); - const unwrap tmp2(in_dcovs_expr.get_ref()); - const unwrap tmp3(in_hefts_expr.get_ref()); + const plain_unwrap tmp1(in_means_expr.get_ref()); + const plain_unwrap tmp2(in_dcovs_expr.get_ref()); + const plain_unwrap tmp3(in_hefts_expr.get_ref()); const Mat& in_means = tmp1.M; const Mat& in_dcovs = tmp2.M; @@ -179,7 +179,7 @@ gmm_diag::set_means(const Base& in_means_expr) { arma_debug_sigprint(); - const unwrap tmp(in_means_expr.get_ref()); + const plain_unwrap tmp(in_means_expr.get_ref()); const Mat& in_means = tmp.M; @@ -199,7 +199,7 @@ gmm_diag::set_dcovs(const Base& in_dcovs_expr) { arma_debug_sigprint(); - const unwrap tmp(in_dcovs_expr.get_ref()); + const plain_unwrap tmp(in_dcovs_expr.get_ref()); const Mat& in_dcovs = tmp.M; @@ -222,7 +222,7 @@ gmm_diag::set_hefts(const Base& in_hefts_expr) { arma_debug_sigprint(); - const unwrap tmp(in_hefts_expr.get_ref()); + const plain_unwrap tmp(in_hefts_expr.get_ref()); const Mat& in_hefts = tmp.M; @@ -602,8 +602,8 @@ gmm_diag::raw_hist(const Base& expr, const gmm_dist_mode& dist_mode) { arma_debug_sigprint(); - const unwrap tmp(expr.get_ref()); - const Mat& X = tmp.M; + const plain_unwrap tmp(expr.get_ref()); + const Mat& X = tmp.M; arma_conform_check( (X.n_rows != means.n_rows), "gmm_diag::raw_hist(): incompatible dimensions" ); @@ -626,8 +626,8 @@ gmm_diag::norm_hist(const Base& expr, const gmm_dist_mode& dist_mode) { arma_debug_sigprint(); - const unwrap tmp(expr.get_ref()); - const Mat& X = tmp.M; + const plain_unwrap tmp(expr.get_ref()); + const Mat& X = tmp.M; arma_conform_check( (X.n_rows != means.n_rows), "gmm_diag::norm_hist(): incompatible dimensions" ); @@ -687,8 +687,8 @@ gmm_diag::learn arma_conform_check( (seed_mode_ok == false), "gmm_diag::learn(): unknown seed_mode" ); arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_diag::learn(): variance floor must be > 0" ); - const unwrap tmp_X(data.get_ref()); - const Mat& X = tmp_X.M; + const plain_unwrap tmp_X(data.get_ref()); + const Mat& X = tmp_X.M; if(X.is_empty() ) { arma_warn(3, "gmm_diag::learn(): given matrix is empty" ); return false; } if(X.internal_has_nonfinite()) { arma_warn(3, "gmm_diag::learn(): given matrix has non-finite values"); return false; } @@ -815,8 +815,8 @@ gmm_diag::kmeans_wrapper arma_conform_check( (seed_mode_ok == false), "kmeans(): unknown seed_mode" ); - const unwrap tmp_X(data.get_ref()); - const Mat& X = tmp_X.M; + const plain_unwrap tmp_X(data.get_ref()); + const Mat& X = tmp_X.M; if(X.is_empty() ) { arma_warn(3, "kmeans(): given matrix is empty" ); return false; } if(X.internal_has_nonfinite()) { arma_warn(3, "kmeans(): given matrix has non-finite values"); return false; } diff --git a/inst/include/armadillo_bits/gmm_full_meat.hpp b/inst/include/armadillo_bits/gmm_full_meat.hpp index d8cd16a3..751ca0f0 100644 --- a/inst/include/armadillo_bits/gmm_full_meat.hpp +++ b/inst/include/armadillo_bits/gmm_full_meat.hpp @@ -137,9 +137,9 @@ gmm_full::set_params(const Base& in_means_expr, const BaseCube { arma_debug_sigprint(); - const unwrap tmp1(in_means_expr.get_ref()); - const unwrap_cube tmp2(in_fcovs_expr.get_ref()); - const unwrap tmp3(in_hefts_expr.get_ref()); + const plain_unwrap tmp1(in_means_expr.get_ref()); + const unwrap_cube tmp2(in_fcovs_expr.get_ref()); + const plain_unwrap tmp3(in_hefts_expr.get_ref()); const Mat & in_means = tmp1.M; const Cube& in_fcovs = tmp2.M; @@ -183,7 +183,7 @@ gmm_full::set_means(const Base& in_means_expr) { arma_debug_sigprint(); - const unwrap tmp(in_means_expr.get_ref()); + const plain_unwrap tmp(in_means_expr.get_ref()); const Mat& in_means = tmp.M; @@ -230,7 +230,7 @@ gmm_full::set_hefts(const Base& in_hefts_expr) { arma_debug_sigprint(); - const unwrap tmp(in_hefts_expr.get_ref()); + const plain_unwrap tmp(in_hefts_expr.get_ref()); const Mat& in_hefts = tmp.M; @@ -641,8 +641,8 @@ gmm_full::raw_hist(const Base& expr, const gmm_dist_mode& dist_mode) { arma_debug_sigprint(); - const unwrap tmp(expr.get_ref()); - const Mat& X = tmp.M; + const plain_unwrap tmp(expr.get_ref()); + const Mat& X = tmp.M; arma_conform_check( (X.n_rows != means.n_rows), "gmm_full::raw_hist(): incompatible dimensions" ); @@ -665,8 +665,8 @@ gmm_full::norm_hist(const Base& expr, const gmm_dist_mode& dist_mode) { arma_debug_sigprint(); - const unwrap tmp(expr.get_ref()); - const Mat& X = tmp.M; + const plain_unwrap tmp(expr.get_ref()); + const Mat& X = tmp.M; arma_conform_check( (X.n_rows != means.n_rows), "gmm_full::norm_hist(): incompatible dimensions" ); @@ -726,8 +726,8 @@ gmm_full::learn arma_conform_check( (seed_mode_ok == false), "gmm_full::learn(): unknown seed_mode" ); arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_full::learn(): variance floor must be > 0" ); - const unwrap tmp_X(data.get_ref()); - const Mat& X = tmp_X.M; + const plain_unwrap tmp_X(data.get_ref()); + const Mat& X = tmp_X.M; if(X.is_empty() ) { arma_warn(3, "gmm_full::learn(): given matrix is empty" ); return false; } if(X.internal_has_nonfinite()) { arma_warn(3, "gmm_full::learn(): given matrix has non-finite values"); return false; } diff --git a/inst/include/armadillo_bits/mp_misc.hpp b/inst/include/armadillo_bits/mp_misc.hpp index b8c59ab3..b25cef7f 100644 --- a/inst/include/armadillo_bits/mp_misc.hpp +++ b/inst/include/armadillo_bits/mp_misc.hpp @@ -22,7 +22,7 @@ -template +template struct mp_gate { arma_inline @@ -32,7 +32,7 @@ struct mp_gate { #if defined(ARMA_USE_OPENMP) { - const bool length_ok = (is_cx::yes || use_smaller_thresh) ? (n_elem >= (arma_config::mp_threshold/uword(2))) : (n_elem >= arma_config::mp_threshold); + const bool length_ok = (is_cx::yes || use_half_threshold) ? (n_elem >= (arma_config::mp_threshold/uword(2))) : (n_elem >= arma_config::mp_threshold); return (length_ok) ? (bool(omp_in_parallel()) == false) : false; } diff --git a/inst/include/armadillo_bits/mtGlueCube_bones.hpp b/inst/include/armadillo_bits/mtGlueCube_bones.hpp index d158631d..20c21202 100644 --- a/inst/include/armadillo_bits/mtGlueCube_bones.hpp +++ b/inst/include/armadillo_bits/mtGlueCube_bones.hpp @@ -27,6 +27,8 @@ struct mtGlueCube : public BaseCube< out_eT, mtGlueCube::result pod_type; + static constexpr bool has_subview = T1::has_subview || T2::has_subview; + arma_inline mtGlueCube(const T1& in_A, const T2& in_B); arma_inline mtGlueCube(const T1& in_A, const T2& in_B, const uword in_aux_uword); arma_inline ~mtGlueCube(); diff --git a/inst/include/armadillo_bits/mtGlue_bones.hpp b/inst/include/armadillo_bits/mtGlue_bones.hpp index e187e6ce..d5f472b6 100644 --- a/inst/include/armadillo_bits/mtGlue_bones.hpp +++ b/inst/include/armadillo_bits/mtGlue_bones.hpp @@ -31,6 +31,8 @@ struct mtGlue : public Base< out_eT, mtGlue > static constexpr bool is_col = glue_type::template traits::is_col; static constexpr bool is_xvec = glue_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview || T2::has_subview; + arma_inline mtGlue(const T1& in_A, const T2& in_B); arma_inline mtGlue(const T1& in_A, const T2& in_B, const uword in_aux_uword); arma_inline ~mtGlue(); diff --git a/inst/include/armadillo_bits/mtOpCube_bones.hpp b/inst/include/armadillo_bits/mtOpCube_bones.hpp index 3cd05462..33e796bf 100644 --- a/inst/include/armadillo_bits/mtOpCube_bones.hpp +++ b/inst/include/armadillo_bits/mtOpCube_bones.hpp @@ -32,6 +32,8 @@ struct mtOpCube : public BaseCube< out_eT, mtOpCube > typedef typename T1::elem_type in_eT; + static constexpr bool has_subview = T1::has_subview; + inline explicit mtOpCube(const T1& in_m); inline mtOpCube(const T1& in_m, const in_eT in_aux); inline mtOpCube(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c); diff --git a/inst/include/armadillo_bits/mtOp_bones.hpp b/inst/include/armadillo_bits/mtOp_bones.hpp index b40182e4..f035e26a 100644 --- a/inst/include/armadillo_bits/mtOp_bones.hpp +++ b/inst/include/armadillo_bits/mtOp_bones.hpp @@ -35,6 +35,8 @@ struct mtOp : public Base< out_eT, mtOp > static constexpr bool is_col = op_type::template traits::is_col; static constexpr bool is_xvec = op_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview; + inline explicit mtOp(const T1& in_m); inline mtOp(const T1& in_m, const in_eT in_aux); inline mtOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); diff --git a/inst/include/armadillo_bits/mtSpGlue_bones.hpp b/inst/include/armadillo_bits/mtSpGlue_bones.hpp index e6a64798..a43ed554 100644 --- a/inst/include/armadillo_bits/mtSpGlue_bones.hpp +++ b/inst/include/armadillo_bits/mtSpGlue_bones.hpp @@ -31,6 +31,8 @@ struct mtSpGlue : public SpBase< out_eT, mtSpGlue > static constexpr bool is_col = spglue_type::template traits::is_col; static constexpr bool is_xvec = spglue_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview || T2::has_subview; + inline mtSpGlue(const T1& in_A, const T2& in_B); inline ~mtSpGlue(); diff --git a/inst/include/armadillo_bits/mtSpOp_bones.hpp b/inst/include/armadillo_bits/mtSpOp_bones.hpp index dc3e2d39..36e59a98 100644 --- a/inst/include/armadillo_bits/mtSpOp_bones.hpp +++ b/inst/include/armadillo_bits/mtSpOp_bones.hpp @@ -36,6 +36,8 @@ struct mtSpOp : public SpBase< out_eT, mtSpOp > static constexpr bool is_col = spop_type::template traits::is_col; static constexpr bool is_xvec = spop_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview; + inline explicit mtSpOp(const T1& in_m); inline mtSpOp(const T1& in_m, const in_eT in_aux); inline mtSpOp(const T1& in_m, const uword aux_uword_a, const uword aux_uword_b); diff --git a/inst/include/armadillo_bits/mtSpReduceOp_bones.hpp b/inst/include/armadillo_bits/mtSpReduceOp_bones.hpp index e1531457..60d75b7e 100644 --- a/inst/include/armadillo_bits/mtSpReduceOp_bones.hpp +++ b/inst/include/armadillo_bits/mtSpReduceOp_bones.hpp @@ -46,6 +46,8 @@ struct mtSpReduceOp : public SpBase< out_eT, mtSpReduceOp > static constexpr bool is_col = op_type::template traits::is_col; static constexpr bool is_xvec = op_type::template traits::is_xvec; + static constexpr bool has_subview = T1::has_subview; + inline explicit mtSpReduceOp(const T1& in_m); inline mtSpReduceOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b); inline ~mtSpReduceOp(); diff --git a/inst/include/armadillo_bits/op_clamp_meat.hpp b/inst/include/armadillo_bits/op_clamp_meat.hpp index 65531d2e..915f2640 100644 --- a/inst/include/armadillo_bits/op_clamp_meat.hpp +++ b/inst/include/armadillo_bits/op_clamp_meat.hpp @@ -38,7 +38,7 @@ op_clamp::apply(Mat& out, const mtOp::value) { - const unwrap U(in.m); + const plain_unwrap U(in.m); // detect in-place operation if(&out == &(U.M)) @@ -310,7 +310,7 @@ op_clamp_cx::apply(Mat& out, const mtOp::value) { - const unwrap U(in.m); + const plain_unwrap U(in.m); op_clamp_cx::apply_direct(out, U.M, in.aux, in.aux_out_eT); } diff --git a/inst/include/armadillo_bits/op_cor_meat.hpp b/inst/include/armadillo_bits/op_cor_meat.hpp index 29f74456..012f7966 100644 --- a/inst/include/armadillo_bits/op_cor_meat.hpp +++ b/inst/include/armadillo_bits/op_cor_meat.hpp @@ -33,8 +33,8 @@ op_cor::apply(Mat& out, const Op& in) const uword norm_type = in.aux_uword_a; - const unwrap U(in.m); - const Mat& A = U.M; + const plain_unwrap U(in.m); + const Mat& A = U.M; if(A.n_elem == 0) { @@ -87,8 +87,8 @@ op_cor::apply(Mat& out, const Op< Op, op_c } else { - const unwrap U(in.m.m); - const Mat& A = U.M; + const plain_unwrap U(in.m.m); + const Mat& A = U.M; if(A.n_elem == 0) { diff --git a/inst/include/armadillo_bits/op_cov_meat.hpp b/inst/include/armadillo_bits/op_cov_meat.hpp index e12d1820..dbd1f5a7 100644 --- a/inst/include/armadillo_bits/op_cov_meat.hpp +++ b/inst/include/armadillo_bits/op_cov_meat.hpp @@ -33,8 +33,8 @@ op_cov::apply(Mat& out, const Op& in) const uword norm_type = in.aux_uword_a; - const unwrap U(in.m); - const Mat& A = U.M; + const plain_unwrap U(in.m); + const Mat& A = U.M; if(A.n_elem == 0) { @@ -76,8 +76,8 @@ op_cov::apply(Mat& out, const Op< Op, op_c } else { - const unwrap U(in.m.m); - const Mat& A = U.M; + const plain_unwrap U(in.m.m); + const Mat& A = U.M; if(A.n_elem == 0) { diff --git a/inst/include/armadillo_bits/op_diagmat_meat.hpp b/inst/include/armadillo_bits/op_diagmat_meat.hpp index 8796c6ba..1dd0e58a 100644 --- a/inst/include/armadillo_bits/op_diagmat_meat.hpp +++ b/inst/include/armadillo_bits/op_diagmat_meat.hpp @@ -34,8 +34,8 @@ op_diagmat::apply(Mat& out, const Op& X) { // allow detection of in-place operation - const unwrap U(X.m); - const Mat& A = U.M; + const plain_unwrap U(X.m); + const Mat& A = U.M; if(&out != &A) // no aliasing { diff --git a/inst/include/armadillo_bits/op_dot_meat.hpp b/inst/include/armadillo_bits/op_dot_meat.hpp index 6ecb446f..1858e627 100644 --- a/inst/include/armadillo_bits/op_dot_meat.hpp +++ b/inst/include/armadillo_bits/op_dot_meat.hpp @@ -601,8 +601,8 @@ op_cdot::apply_unwrap(const T1& X, const T2& Y) typedef typename T1::elem_type eT; - const unwrap tmp1(X); - const unwrap tmp2(Y); + const plain_unwrap tmp1(X); + const plain_unwrap tmp2(Y); const Mat& A = tmp1.M; const Mat& B = tmp2.M; diff --git a/inst/include/armadillo_bits/op_expmat_meat.hpp b/inst/include/armadillo_bits/op_expmat_meat.hpp index 7fdd81e8..26e99e06 100644 --- a/inst/include/armadillo_bits/op_expmat_meat.hpp +++ b/inst/include/armadillo_bits/op_expmat_meat.hpp @@ -200,8 +200,8 @@ op_expmat_sym::apply_direct(Mat& out, const Base U(expr.get_ref()); - const Mat& X = U.M; + const plain_unwrap U(expr.get_ref()); + const Mat& X = U.M; arma_conform_check( (X.is_square() == false), "expmat_sym(): given matrix must be square sized" ); diff --git a/inst/include/armadillo_bits/op_find_aux_bones.hpp b/inst/include/armadillo_bits/op_find_aux_bones.hpp new file mode 100644 index 00000000..38f01562 --- /dev/null +++ b/inst/include/armadillo_bits/op_find_aux_bones.hpp @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup op_find_aux +//! @{ + + + +struct op_find_aux + : public traits_op_default + { + template + inline static void + apply + ( + functor element_processor, + const Base& X + ); + + template + inline static void + apply + ( + functor element_processor, + const mtOp& X, + const typename arma_op_rel_only::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr + ); + + template + inline static void + apply + ( + functor element_processor, + const mtOp& X, + const typename arma_op_rel_only::result* junk1 = nullptr, + const typename arma_cx_only::result* junk2 = nullptr + ); + + template + inline static void + apply + ( + functor element_processor, + const mtGlue& X, + const typename arma_glue_rel_only::result* junk1 = nullptr, + const typename arma_not_cx::result* junk2 = nullptr, + const typename arma_not_cx::result* junk3 = nullptr + ); + + template + inline static void + apply + ( + functor element_processor, + const mtGlue& X, + const typename arma_glue_rel_only::result* junk1 = nullptr, + const typename arma_cx_only::result* junk2 = nullptr, + const typename arma_cx_only::result* junk3 = nullptr + ); + }; + + + +//! @} diff --git a/inst/include/armadillo_bits/op_find_aux_meat.hpp b/inst/include/armadillo_bits/op_find_aux_meat.hpp new file mode 100644 index 00000000..60fd3e8e --- /dev/null +++ b/inst/include/armadillo_bits/op_find_aux_meat.hpp @@ -0,0 +1,425 @@ +// SPDX-License-Identifier: Apache-2.0 +// +// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au) +// Copyright 2008-2016 National ICT Australia (NICTA) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + + + +//! \addtogroup op_find_aux +//! @{ + + + +template +inline +void +op_find_aux::apply + ( + functor element_processor, + const Base& X + ) + { + arma_debug_sigprint(); + + typedef typename T1::elem_type eT; + + const Proxy A(X.get_ref()); + + const uword n_elem = A.get_n_elem(); + + if(Proxy::use_at == false) + { + typename Proxy::ea_type PA = A.get_ea(); + + for(uword i=0; i +inline +void +op_find_aux::apply + ( + functor element_processor, + const mtOp& X, + const typename arma_op_rel_only::result* junk1, + const typename arma_not_cx::result* junk2 + ) + { + arma_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + typedef typename T1::elem_type eT; + + const eT val = X.aux; + + if((is_same_type::yes || is_same_type::yes) && arma_config::check_conform && arma_isnan(val)) + { + arma_warn(1, "find(): NaN is not equal to anything; suggest to use find_nonfinite() instead"); + } + + const Proxy A(X.m); + + const uword n_elem = A.get_n_elem(); + + if(Proxy::use_at == false) + { + typename Proxy::ea_type PA = A.get_ea(); + + uword i,j; + for(i=0, j=1; j < n_elem; i+=2, j+=2) + { + const eT tpi = PA[i]; + const eT tpj = PA[j]; + + bool not_zero_i; + bool not_zero_j; + + if(is_same_type::yes) { not_zero_i = (val < tpi); } + else if(is_same_type::yes) { not_zero_i = (tpi < val); } + else if(is_same_type::yes) { not_zero_i = (val > tpi); } + else if(is_same_type::yes) { not_zero_i = (tpi > val); } + else if(is_same_type::yes) { not_zero_i = (val <= tpi); } + else if(is_same_type::yes) { not_zero_i = (tpi <= val); } + else if(is_same_type::yes) { not_zero_i = (val >= tpi); } + else if(is_same_type::yes) { not_zero_i = (tpi >= val); } + else if(is_same_type::yes) { not_zero_i = (tpi == val); } + else if(is_same_type::yes) { not_zero_i = (tpi != val); } + else { not_zero_i = false; } + + if(is_same_type::yes) { not_zero_j = (val < tpj); } + else if(is_same_type::yes) { not_zero_j = (tpj < val); } + else if(is_same_type::yes) { not_zero_j = (val > tpj); } + else if(is_same_type::yes) { not_zero_j = (tpj > val); } + else if(is_same_type::yes) { not_zero_j = (val <= tpj); } + else if(is_same_type::yes) { not_zero_j = (tpj <= val); } + else if(is_same_type::yes) { not_zero_j = (val >= tpj); } + else if(is_same_type::yes) { not_zero_j = (tpj >= val); } + else if(is_same_type::yes) { not_zero_j = (tpj == val); } + else if(is_same_type::yes) { not_zero_j = (tpj != val); } + else { not_zero_j = false; } + + if(not_zero_i) { element_processor(i); } + if(not_zero_j) { element_processor(j); } + } + + if(i < n_elem) + { + bool not_zero; + + const eT tmp = PA[i]; + + if(is_same_type::yes) { not_zero = (val < tmp); } + else if(is_same_type::yes) { not_zero = (tmp < val); } + else if(is_same_type::yes) { not_zero = (val > tmp); } + else if(is_same_type::yes) { not_zero = (tmp > val); } + else if(is_same_type::yes) { not_zero = (val <= tmp); } + else if(is_same_type::yes) { not_zero = (tmp <= val); } + else if(is_same_type::yes) { not_zero = (val >= tmp); } + else if(is_same_type::yes) { not_zero = (tmp >= val); } + else if(is_same_type::yes) { not_zero = (tmp == val); } + else if(is_same_type::yes) { not_zero = (tmp != val); } + else { not_zero = false; } + + if(not_zero) { element_processor(i); } + } + } + else + { + const uword n_rows = A.get_n_rows(); + const uword n_cols = A.get_n_cols(); + + uword i = 0; + + for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) + { + const eT tmp = A.at(row,col); + + bool not_zero; + + if(is_same_type::yes) { not_zero = (val < tmp); } + else if(is_same_type::yes) { not_zero = (tmp < val); } + else if(is_same_type::yes) { not_zero = (val > tmp); } + else if(is_same_type::yes) { not_zero = (tmp > val); } + else if(is_same_type::yes) { not_zero = (val <= tmp); } + else if(is_same_type::yes) { not_zero = (tmp <= val); } + else if(is_same_type::yes) { not_zero = (val >= tmp); } + else if(is_same_type::yes) { not_zero = (tmp >= val); } + else if(is_same_type::yes) { not_zero = (tmp == val); } + else if(is_same_type::yes) { not_zero = (tmp != val); } + else { not_zero = false; } + + if(not_zero) { element_processor(i); } + + ++i; + } + } + } + + + +template +inline +void +op_find_aux::apply + ( + functor element_processor, + const mtOp& X, + const typename arma_op_rel_only::result* junk1, + const typename arma_cx_only::result* junk2 + ) + { + arma_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + + typedef typename T1::elem_type eT; + typedef typename Proxy::ea_type ea_type; + + const eT val = X.aux; + + if((is_same_type::yes || is_same_type::yes) && arma_config::check_conform && arma_isnan(val)) + { + arma_warn(1, "find(): NaN is not equal to anything; suggest to use find_nonfinite() instead"); + } + + const Proxy A(X.m); + + const uword n_elem = A.get_n_elem(); + + if(Proxy::use_at == false) + { + ea_type PA = A.get_ea(); + + for(uword i=0; i::yes) { not_zero = (tmp == val); } + else if(is_same_type::yes) { not_zero = (tmp != val); } + else { not_zero = false; } + + if(not_zero) { element_processor(i); } + } + } + else + { + const uword n_rows = A.get_n_rows(); + const uword n_cols = A.get_n_cols(); + + uword i = 0; + + for(uword col=0; col::yes) { not_zero = (tmp == val); } + else if(is_same_type::yes) { not_zero = (tmp != val); } + else { not_zero = false; } + + if(not_zero) { element_processor(i); } + + i++; + } + } + } + + + +template +inline +void +op_find_aux::apply + ( + functor element_processor, + const mtGlue& X, + const typename arma_glue_rel_only::result* junk1, + const typename arma_not_cx::result* junk2, + const typename arma_not_cx::result* junk3 + ) + { + arma_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + arma_ignore(junk3); + + typedef typename T1::elem_type eT1; + typedef typename T2::elem_type eT2; + + typedef typename Proxy::ea_type ea_type1; + typedef typename Proxy::ea_type ea_type2; + + const Proxy A(X.A); + const Proxy B(X.B); + + arma_conform_assert_same_size(A, B, "relational operator"); + + const uword n_elem = A.get_n_elem(); + + if((Proxy::use_at == false) && (Proxy::use_at == false)) + { + ea_type1 PA = A.get_ea(); + ea_type2 PB = B.get_ea(); + + for(uword i=0; i::yes) { not_zero = (tmp1 < tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 > tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 <= tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 >= tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 == tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 != tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 && tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 || tmp2); } + else { not_zero = false; } + + if(not_zero) { element_processor(i); } + } + } + else + { + const uword n_rows = A.get_n_rows(); + const uword n_cols = A.get_n_cols(); + + uword i = 0; + + for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) + { + const eT1 tmp1 = A.at(row,col); + const eT2 tmp2 = B.at(row,col); + + bool not_zero; + + if(is_same_type::yes) { not_zero = (tmp1 < tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 > tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 <= tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 >= tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 == tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 != tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 && tmp2); } + else if(is_same_type::yes) { not_zero = (tmp1 || tmp2); } + else { not_zero = false; } + + if(not_zero) { element_processor(i); } + + i++; + } + } + } + + + +template +inline +void +op_find_aux::apply + ( + functor element_processor, + const mtGlue& X, + const typename arma_glue_rel_only::result* junk1, + const typename arma_cx_only::result* junk2, + const typename arma_cx_only::result* junk3 + ) + { + arma_debug_sigprint(); + arma_ignore(junk1); + arma_ignore(junk2); + arma_ignore(junk3); + + typedef typename Proxy::ea_type ea_type1; + typedef typename Proxy::ea_type ea_type2; + + const Proxy A(X.A); + const Proxy B(X.B); + + arma_conform_assert_same_size(A, B, "relational operator"); + + const uword n_elem = A.get_n_elem(); + + if((Proxy::use_at == false) && (Proxy::use_at == false)) + { + ea_type1 PA = A.get_ea(); + ea_type2 PB = B.get_ea(); + + for(uword i=0; i::yes) { not_zero = (PA[i] == PB[i]); } + else if(is_same_type::yes) { not_zero = (PA[i] != PB[i]); } + else { not_zero = false; } + + if(not_zero) { element_processor(i); } + } + } + else + { + const uword n_rows = A.get_n_rows(); + const uword n_cols = A.get_n_cols(); + + uword i = 0; + + for(uword col=0; col::yes) { not_zero = (A.at(row,col) == B.at(row,col)); } + else if(is_same_type::yes) { not_zero = (A.at(row,col) != B.at(row,col)); } + else { not_zero = false; } + + if(not_zero) { element_processor(i); } + + i++; + } + } + } + + + +//! @} diff --git a/inst/include/armadillo_bits/op_find_bones.hpp b/inst/include/armadillo_bits/op_find_bones.hpp index 040defd1..ef859ab8 100644 --- a/inst/include/armadillo_bits/op_find_bones.hpp +++ b/inst/include/armadillo_bits/op_find_bones.hpp @@ -22,7 +22,7 @@ -struct op_find +struct op_find_generic : public traits_op_col { template @@ -76,16 +76,16 @@ struct op_find ); template - inline static void apply(Mat& out, const mtOp& X); + inline static void apply(Mat& out, const mtOp& X); }; -struct op_find_simple +struct op_find_default : public traits_op_col { template - inline static void apply(Mat& out, const mtOp& X); + inline static void apply(Mat& out, const mtOp& X); }; diff --git a/inst/include/armadillo_bits/op_find_meat.hpp b/inst/include/armadillo_bits/op_find_meat.hpp index 8671570f..32ce70e5 100644 --- a/inst/include/armadillo_bits/op_find_meat.hpp +++ b/inst/include/armadillo_bits/op_find_meat.hpp @@ -25,7 +25,7 @@ template inline uword -op_find::helper +op_find_generic::helper ( Mat& indices, const Base& X @@ -77,7 +77,7 @@ op_find::helper template inline uword -op_find::helper +op_find_generic::helper ( Mat& indices, const mtOp& X, @@ -209,7 +209,7 @@ op_find::helper template inline uword -op_find::helper +op_find_generic::helper ( Mat& indices, const mtOp& X, @@ -290,7 +290,7 @@ op_find::helper template inline uword -op_find::helper +op_find_generic::helper ( Mat& indices, const mtGlue& X, @@ -386,7 +386,7 @@ op_find::helper template inline uword -op_find::helper +op_find_generic::helper ( Mat& indices, const mtGlue& X, @@ -461,7 +461,7 @@ op_find::helper template inline void -op_find::apply(Mat& out, const mtOp& X) +op_find_generic::apply(Mat& out, const mtOp& X) { arma_debug_sigprint(); @@ -469,7 +469,7 @@ op_find::apply(Mat& out, const mtOp& X) const uword type = X.aux_uword_b; Mat indices; - const uword n_nz = op_find::helper(indices, X.m); + const uword n_nz = op_find_generic::helper(indices, X.m); if(n_nz > 0) { @@ -497,12 +497,12 @@ op_find::apply(Mat& out, const mtOp& X) template inline void -op_find_simple::apply(Mat& out, const mtOp& X) +op_find_default::apply(Mat& out, const mtOp& X) { arma_debug_sigprint(); Mat indices; - const uword n_nz = op_find::helper(indices, X.m); + const uword n_nz = op_find_generic::helper(indices, X.m); out.steal_mem_col(indices, n_nz); } diff --git a/inst/include/armadillo_bits/op_flip_meat.hpp b/inst/include/armadillo_bits/op_flip_meat.hpp index 636da944..97b45a87 100644 --- a/inst/include/armadillo_bits/op_flip_meat.hpp +++ b/inst/include/armadillo_bits/op_flip_meat.hpp @@ -32,7 +32,7 @@ op_flipud::apply(Mat& out, const Op& in) if(is_Mat::value) { - const unwrap U(in.m); + const plain_unwrap U(in.m); if(&out == &(U.M)) { op_flipud::apply_mat_inplace(out); return; } @@ -166,7 +166,7 @@ op_fliplr::apply(Mat& out, const Op& in) if(is_Mat::value) { - const unwrap U(in.m); + const plain_unwrap U(in.m); if(&out == &(U.M)) { op_fliplr::apply_mat_inplace(out); return; } diff --git a/inst/include/armadillo_bits/op_htrans_meat.hpp b/inst/include/armadillo_bits/op_htrans_meat.hpp index 38e3c24c..cbe952ea 100644 --- a/inst/include/armadillo_bits/op_htrans_meat.hpp +++ b/inst/include/armadillo_bits/op_htrans_meat.hpp @@ -309,7 +309,7 @@ op_htrans::apply_direct(Mat& out, const T1& X) // allow detection of in-place transpose if(is_Mat::value) { - const unwrap U(X); + const plain_unwrap U(X); op_htrans::apply_mat(out, U.M); } diff --git a/inst/include/armadillo_bits/op_logmat_meat.hpp b/inst/include/armadillo_bits/op_logmat_meat.hpp index 1168f667..6f9fa63d 100644 --- a/inst/include/armadillo_bits/op_logmat_meat.hpp +++ b/inst/include/armadillo_bits/op_logmat_meat.hpp @@ -500,8 +500,8 @@ op_logmat_sympd::apply_direct(Mat& out, const Base U(expr.get_ref()); - const Mat& X = U.M; + const plain_unwrap U(expr.get_ref()); + const Mat& X = U.M; arma_conform_check( (X.is_square() == false), "logmat_sympd(): given matrix must be square sized" ); diff --git a/inst/include/armadillo_bits/op_princomp_meat.hpp b/inst/include/armadillo_bits/op_princomp_meat.hpp index 6acbbb54..ab46e61f 100644 --- a/inst/include/armadillo_bits/op_princomp_meat.hpp +++ b/inst/include/armadillo_bits/op_princomp_meat.hpp @@ -268,8 +268,8 @@ op_princomp::direct_princomp typedef typename T1::elem_type eT; typedef typename T1::pod_type T; - const unwrap Y( X.get_ref() ); - const Mat& in = Y.M; + const plain_unwrap Y( X.get_ref() ); + const Mat& in = Y.M; if(in.n_elem != 0) { diff --git a/inst/include/armadillo_bits/op_reshape_meat.hpp b/inst/include/armadillo_bits/op_reshape_meat.hpp index e7879a12..7cec2c2f 100644 --- a/inst/include/armadillo_bits/op_reshape_meat.hpp +++ b/inst/include/armadillo_bits/op_reshape_meat.hpp @@ -36,8 +36,8 @@ op_reshape::apply(Mat& out, const Op& in) if(is_Mat::value) { - const unwrap U(in.m); - const Mat& A = U.M; + const plain_unwrap U(in.m); + const Mat& A = U.M; if(&out == &A) { diff --git a/inst/include/armadillo_bits/op_resize_meat.hpp b/inst/include/armadillo_bits/op_resize_meat.hpp index dee6ee03..caabf9da 100644 --- a/inst/include/armadillo_bits/op_resize_meat.hpp +++ b/inst/include/armadillo_bits/op_resize_meat.hpp @@ -36,8 +36,8 @@ op_resize::apply(Mat& out, const Op& in) if(is_Mat::value) { - const unwrap U(in.m); - const Mat& A = U.M; + const plain_unwrap U(in.m); + const Mat& A = U.M; if(&out == &A) { diff --git a/inst/include/armadillo_bits/op_reverse_meat.hpp b/inst/include/armadillo_bits/op_reverse_meat.hpp index e0a9acd0..1511ed3c 100644 --- a/inst/include/armadillo_bits/op_reverse_meat.hpp +++ b/inst/include/armadillo_bits/op_reverse_meat.hpp @@ -36,7 +36,7 @@ op_reverse::apply(Mat& out, const Op& in) if(is_Mat::value) { - const unwrap U(in.m); + const plain_unwrap U(in.m); if(&out == &(U.M)) { @@ -101,7 +101,7 @@ op_reverse_vec::apply(Mat& out, const Op::value) { - const unwrap U(in.m); + const plain_unwrap U(in.m); if(&out == &(U.M)) { diff --git a/inst/include/armadillo_bits/op_shuffle_meat.hpp b/inst/include/armadillo_bits/op_shuffle_meat.hpp index d6932628..fc3d4953 100644 --- a/inst/include/armadillo_bits/op_shuffle_meat.hpp +++ b/inst/include/armadillo_bits/op_shuffle_meat.hpp @@ -213,7 +213,7 @@ op_shuffle::apply(Mat& out, const Op& in) { arma_debug_sigprint(); - const unwrap U(in.m); + const plain_unwrap U(in.m); const uword dim = in.aux_uword_a; @@ -231,7 +231,7 @@ op_shuffle_vec::apply(Mat& out, const Op U(in.m); + const plain_unwrap U(in.m); const uword dim = (T1::is_xvec) ? uword(U.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0); diff --git a/inst/include/armadillo_bits/op_sort_meat.hpp b/inst/include/armadillo_bits/op_sort_meat.hpp index 067da347..516addf7 100644 --- a/inst/include/armadillo_bits/op_sort_meat.hpp +++ b/inst/include/armadillo_bits/op_sort_meat.hpp @@ -264,8 +264,8 @@ op_sort_vec::apply(Mat& out, const Op& i typedef typename T1::elem_type eT; - const unwrap U(in.m); // not using quasi_unwrap, to ensure there is no aliasing with subviews - const Mat& X = U.M; + const plain_unwrap U(in.m); // not using quasi_unwrap, to ensure there is no aliasing with subviews + const Mat& X = U.M; const uword sort_mode = in.aux_uword_a; diff --git a/inst/include/armadillo_bits/op_sqrtmat_meat.hpp b/inst/include/armadillo_bits/op_sqrtmat_meat.hpp index 648f60f2..e553bd83 100644 --- a/inst/include/armadillo_bits/op_sqrtmat_meat.hpp +++ b/inst/include/armadillo_bits/op_sqrtmat_meat.hpp @@ -477,8 +477,8 @@ op_sqrtmat_sympd::apply_direct(Mat& out, const Base U(expr.get_ref()); - const Mat& X = U.M; + const plain_unwrap U(expr.get_ref()); + const Mat& X = U.M; arma_conform_check( (X.is_square() == false), "sqrtmat_sympd(): given matrix must be square sized" ); diff --git a/inst/include/armadillo_bits/op_strans_meat.hpp b/inst/include/armadillo_bits/op_strans_meat.hpp index 002e26b3..8beb9800 100644 --- a/inst/include/armadillo_bits/op_strans_meat.hpp +++ b/inst/include/armadillo_bits/op_strans_meat.hpp @@ -389,7 +389,7 @@ op_strans::apply_direct(Mat& out, const T1& X) // allow detection of in-place transpose if(is_Mat::value) { - const unwrap U(X); + const plain_unwrap U(X); op_strans::apply_mat(out, U.M); } diff --git a/inst/include/armadillo_bits/op_symmat_meat.hpp b/inst/include/armadillo_bits/op_symmat_meat.hpp index 8dfbed99..c058f90a 100644 --- a/inst/include/armadillo_bits/op_symmat_meat.hpp +++ b/inst/include/armadillo_bits/op_symmat_meat.hpp @@ -30,8 +30,8 @@ op_symmatu::apply(Mat& out, const Op& in) typedef typename T1::elem_type eT; - const unwrap tmp(in.m); - const Mat& A = tmp.M; + const plain_unwrap tmp(in.m); + const Mat& A = tmp.M; arma_conform_check( (A.is_square() == false), "symmatu(): given matrix must be square sized" ); @@ -81,8 +81,8 @@ op_symmatl::apply(Mat& out, const Op& in) typedef typename T1::elem_type eT; - const unwrap tmp(in.m); - const Mat& A = tmp.M; + const plain_unwrap tmp(in.m); + const Mat& A = tmp.M; arma_conform_check( (A.is_square() == false), "symmatl(): given matrix must be square sized" ); @@ -136,8 +136,8 @@ op_symmatu_cx::apply(Mat& out, const Op tmp(in.m); - const Mat& A = tmp.M; + const plain_unwrap tmp(in.m); + const Mat& A = tmp.M; arma_conform_check( (A.is_square() == false), "symmatu(): given matrix must be square sized" ); @@ -210,8 +210,8 @@ op_symmatl_cx::apply(Mat& out, const Op tmp(in.m); - const Mat& A = tmp.M; + const plain_unwrap tmp(in.m); + const Mat& A = tmp.M; arma_conform_check( (A.is_square() == false), "symmatl(): given matrix must be square sized" ); diff --git a/inst/include/armadillo_bits/op_trimat_meat.hpp b/inst/include/armadillo_bits/op_trimat_meat.hpp index d7d09bf3..3933d405 100644 --- a/inst/include/armadillo_bits/op_trimat_meat.hpp +++ b/inst/include/armadillo_bits/op_trimat_meat.hpp @@ -70,7 +70,7 @@ op_trimat::apply(Mat& out, const Op& in) // allow detection of in-place operation if(is_Mat::value) { - const unwrap U(in.m); + const plain_unwrap U(in.m); if(&out == &(U.M)) { @@ -236,8 +236,8 @@ op_trimatu_ext::apply(Mat& out, const Op tmp(in.m); - const Mat& A = tmp.M; + const plain_unwrap tmp(in.m); + const Mat& A = tmp.M; arma_conform_check( (A.is_square() == false), "trimatu(): given matrix must be square sized" ); @@ -327,8 +327,8 @@ op_trimatl_ext::apply(Mat& out, const Op tmp(in.m); - const Mat& A = tmp.M; + const plain_unwrap tmp(in.m); + const Mat& A = tmp.M; arma_conform_check( (A.is_square() == false), "trimatl(): given matrix must be square sized" ); diff --git a/inst/include/armadillo_bits/op_vectorise_meat.hpp b/inst/include/armadillo_bits/op_vectorise_meat.hpp index f185ac4c..27d4e201 100644 --- a/inst/include/armadillo_bits/op_vectorise_meat.hpp +++ b/inst/include/armadillo_bits/op_vectorise_meat.hpp @@ -46,7 +46,7 @@ op_vectorise_col::apply_direct(Mat& out, const T1& expr) // allow detection of in-place operation if(is_Mat::value) { - const unwrap U(expr); + const plain_unwrap U(expr); if(&out == &(U.M)) { @@ -317,7 +317,7 @@ op_vectorise_row::apply_proxy(Mat& out, const Proxy& { if(is_Mat::stored_type>::value) { - const unwrap::stored_type> tmp(P.Q); + const plain_unwrap::stored_type> tmp(P.Q); arrayops::copy(out.memptr(), tmp.M.memptr(), n_elem); } diff --git a/inst/include/armadillo_bits/sp_auxlib_meat.hpp b/inst/include/armadillo_bits/sp_auxlib_meat.hpp index 30ae561f..2f74aa42 100644 --- a/inst/include/armadillo_bits/sp_auxlib_meat.hpp +++ b/inst/include/armadillo_bits/sp_auxlib_meat.hpp @@ -1303,7 +1303,7 @@ sp_auxlib::spsolve_refine(Mat& X, typename T1::pod_type& const unwrap_spmat tmp1(A_expr.get_ref()); const SpMat& A = tmp1.M; - const unwrap tmp2(B_expr.get_ref()); + const plain_unwrap tmp2(B_expr.get_ref()); const Mat& B_unwrap = tmp2.M; const bool B_is_modified = ( (user_opts.equilibrate) || (&B_unwrap == &X) ); diff --git a/inst/include/armadillo_bits/spdiagview_bones.hpp b/inst/include/armadillo_bits/spdiagview_bones.hpp index d0aab6e3..9f4b24be 100644 --- a/inst/include/armadillo_bits/spdiagview_bones.hpp +++ b/inst/include/armadillo_bits/spdiagview_bones.hpp @@ -35,6 +35,8 @@ class spdiagview : public SpBase< eT, spdiagview > static constexpr bool is_col = true; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + const uword row_offset; const uword col_offset; diff --git a/inst/include/armadillo_bits/spdiagview_meat.hpp b/inst/include/armadillo_bits/spdiagview_meat.hpp index 1d3c4a4e..480dc256 100644 --- a/inst/include/armadillo_bits/spdiagview_meat.hpp +++ b/inst/include/armadillo_bits/spdiagview_meat.hpp @@ -283,7 +283,7 @@ spdiagview::operator+=(const Base& o) if( (is_Mat::stored_type>::value) || (Proxy::use_at) ) { - const unwrap::stored_type> tmp(P.Q); + const plain_unwrap::stored_type> tmp(P.Q); const Mat& x = tmp.M; const eT* x_mem = x.memptr(); @@ -332,7 +332,7 @@ spdiagview::operator-=(const Base& o) if( (is_Mat::stored_type>::value) || (Proxy::use_at) ) { - const unwrap::stored_type> tmp(P.Q); + const plain_unwrap::stored_type> tmp(P.Q); const Mat& x = tmp.M; const eT* x_mem = x.memptr(); @@ -381,7 +381,7 @@ spdiagview::operator%=(const Base& o) if( (is_Mat::stored_type>::value) || (Proxy::use_at) ) { - const unwrap::stored_type> tmp(P.Q); + const plain_unwrap::stored_type> tmp(P.Q); const Mat& x = tmp.M; const eT* x_mem = x.memptr(); @@ -430,7 +430,7 @@ spdiagview::operator/=(const Base& o) if( (is_Mat::stored_type>::value) || (Proxy::use_at) ) { - const unwrap::stored_type> tmp(P.Q); + const plain_unwrap::stored_type> tmp(P.Q); const Mat& x = tmp.M; const eT* x_mem = x.memptr(); diff --git a/inst/include/armadillo_bits/strip.hpp b/inst/include/armadillo_bits/strip.hpp index 138ac7c8..8c34de74 100644 --- a/inst/include/armadillo_bits/strip.hpp +++ b/inst/include/armadillo_bits/strip.hpp @@ -168,6 +168,48 @@ struct strip_trimat< Op > +template +struct strip_op_find_default + { + typedef T1 stored_type; + + inline + strip_op_find_default(const T1& X) + : M(X) + { + arma_debug_sigprint(); + } + + static constexpr bool do_op_find_default = false; + + const T1& M; + }; + + + +template +struct strip_op_find_default< mtOp > + { + typedef T1 stored_type; + + inline + strip_op_find_default(const mtOp& X) + : M(X.m) + { + arma_debug_sigprint(); + } + + static constexpr bool do_op_find_default = true; + + const T1& M; + }; + + + +// + + + template struct sp_strip_trans { diff --git a/inst/include/armadillo_bits/subview_bones.hpp b/inst/include/armadillo_bits/subview_bones.hpp index 30cbc933..2a53422d 100644 --- a/inst/include/armadillo_bits/subview_bones.hpp +++ b/inst/include/armadillo_bits/subview_bones.hpp @@ -36,6 +36,8 @@ class subview : public Base< eT, subview > static constexpr bool is_col = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + const uword aux_row1; const uword aux_col1; @@ -376,6 +378,8 @@ class subview_col : public subview static constexpr bool is_col = true; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + const eT* colmem; inline void operator= (const subview& x); @@ -480,6 +484,8 @@ class subview_cols : public subview static constexpr bool is_col = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + inline subview_cols(const subview_cols& in); inline subview_cols( subview_cols&& in); @@ -541,6 +547,8 @@ class subview_row : public subview static constexpr bool is_col = false; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + const eT* rowmem; inline void operator= (const subview& x); @@ -644,6 +652,8 @@ class subview_row_strans : public Base< eT, subview_row_strans > static constexpr bool is_col = true; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + arma_aligned const subview_row& sv_row; const uword n_rows; // equal to n_elem @@ -679,6 +689,8 @@ class subview_row_htrans : public Base< eT, subview_row_htrans > static constexpr bool is_col = true; static constexpr bool is_xvec = false; + static constexpr bool has_subview = true; + arma_aligned const subview_row& sv_row; const uword n_rows; // equal to n_elem diff --git a/inst/include/armadillo_bits/subview_cube_bones.hpp b/inst/include/armadillo_bits/subview_cube_bones.hpp index 0923fe03..acd2486a 100644 --- a/inst/include/armadillo_bits/subview_cube_bones.hpp +++ b/inst/include/armadillo_bits/subview_cube_bones.hpp @@ -50,6 +50,8 @@ class subview_cube : public BaseCube< eT, subview_cube > public: + static constexpr bool has_subview = true; + inline ~subview_cube(); inline subview_cube() = delete; diff --git a/inst/include/armadillo_bits/subview_cube_each_meat.hpp b/inst/include/armadillo_bits/subview_cube_each_meat.hpp index 2df51b5b..b0b44739 100644 --- a/inst/include/armadillo_bits/subview_cube_each_meat.hpp +++ b/inst/include/armadillo_bits/subview_cube_each_meat.hpp @@ -101,8 +101,8 @@ subview_cube_each1::operator= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); @@ -128,8 +128,8 @@ subview_cube_each1::operator+= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); @@ -155,8 +155,8 @@ subview_cube_each1::operator-= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); @@ -182,8 +182,8 @@ subview_cube_each1::operator%= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); @@ -209,8 +209,8 @@ subview_cube_each1::operator/= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); @@ -287,12 +287,12 @@ subview_cube_each2::operator= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); - const unwrap U( base_indices.get_ref() ); + const plain_unwrap U( base_indices.get_ref() ); check_indices(U.M); @@ -328,12 +328,12 @@ subview_cube_each2::operator+= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); - const unwrap U( base_indices.get_ref() ); + const plain_unwrap U( base_indices.get_ref() ); check_indices(U.M); @@ -369,12 +369,12 @@ subview_cube_each2::operator-= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); - const unwrap U( base_indices.get_ref() ); + const plain_unwrap U( base_indices.get_ref() ); check_indices(U.M); @@ -410,12 +410,12 @@ subview_cube_each2::operator%= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); - const unwrap U( base_indices.get_ref() ); + const plain_unwrap U( base_indices.get_ref() ); check_indices(U.M); @@ -451,12 +451,12 @@ subview_cube_each2::operator/= (const Base& in) Cube& p = access::rw(subview_cube_each_common::P); - const unwrap tmp( in.get_ref() ); - const Mat& A = tmp.M; + const plain_unwrap tmp( in.get_ref() ); + const Mat& A = tmp.M; subview_cube_each_common::check_size(A); - const unwrap U( base_indices.get_ref() ); + const plain_unwrap U( base_indices.get_ref() ); check_indices(U.M); @@ -507,8 +507,8 @@ subview_cube_each1_aux::operator_plus Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); - const unwrap tmp(Y.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& A = tmp.M; X.check_size(A); @@ -547,8 +547,8 @@ subview_cube_each1_aux::operator_minus Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); - const unwrap tmp(Y.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& A = tmp.M; X.check_size(A); @@ -587,8 +587,8 @@ subview_cube_each1_aux::operator_minus Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); - const unwrap tmp(X.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& A = tmp.M; Y.check_size(A); @@ -627,8 +627,8 @@ subview_cube_each1_aux::operator_schur Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); - const unwrap tmp(Y.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& A = tmp.M; X.check_size(A); @@ -667,8 +667,8 @@ subview_cube_each1_aux::operator_div Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); - const unwrap tmp(Y.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& A = tmp.M; X.check_size(A); @@ -707,8 +707,8 @@ subview_cube_each1_aux::operator_div Cube out(p_n_rows, p_n_cols, p_n_slices, arma_nozeros_indicator()); - const unwrap tmp(X.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& A = tmp.M; Y.check_size(A); @@ -741,8 +741,8 @@ subview_cube_each1_aux::operator_times const Cube& C = X.P; - const unwrap tmp(Y.get_ref()); - const Mat& M = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& M = tmp.M; if(arma_config::check_conform) { @@ -782,8 +782,8 @@ subview_cube_each1_aux::operator_times { arma_debug_sigprint(); - const unwrap tmp(X.get_ref()); - const Mat& M = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& M = tmp.M; const Cube& C = Y.P; @@ -838,10 +838,10 @@ subview_cube_each2_aux::operator_plus Cube out = p; - const unwrap tmp(Y.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& A = tmp.M; - const unwrap U(X.base_indices.get_ref()); + const plain_unwrap U(X.base_indices.get_ref()); X.check_size(A); X.check_indices(U.M); @@ -885,10 +885,10 @@ subview_cube_each2_aux::operator_minus Cube out = p; - const unwrap tmp(Y.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& A = tmp.M; - const unwrap U(X.base_indices.get_ref()); + const plain_unwrap U(X.base_indices.get_ref()); X.check_size(A); X.check_indices(U.M); @@ -933,10 +933,10 @@ subview_cube_each2_aux::operator_minus Cube out = p; - const unwrap tmp(X.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& A = tmp.M; - const unwrap U(Y.base_indices.get_ref()); + const plain_unwrap U(Y.base_indices.get_ref()); Y.check_size(A); Y.check_indices(U.M); @@ -981,10 +981,10 @@ subview_cube_each2_aux::operator_schur Cube out = p; - const unwrap tmp(Y.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& A = tmp.M; - const unwrap U(X.base_indices.get_ref()); + const plain_unwrap U(X.base_indices.get_ref()); X.check_size(A); X.check_indices(U.M); @@ -1028,10 +1028,10 @@ subview_cube_each2_aux::operator_div Cube out = p; - const unwrap tmp(Y.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(Y.get_ref()); + const Mat& A = tmp.M; - const unwrap U(X.base_indices.get_ref()); + const plain_unwrap U(X.base_indices.get_ref()); X.check_size(A); X.check_indices(U.M); @@ -1076,10 +1076,10 @@ subview_cube_each2_aux::operator_div Cube out = p; - const unwrap tmp(X.get_ref()); - const Mat& A = tmp.M; + const plain_unwrap tmp(X.get_ref()); + const Mat& A = tmp.M; - const unwrap U(Y.base_indices.get_ref()); + const plain_unwrap U(Y.base_indices.get_ref()); Y.check_size(A); Y.check_indices(U.M); diff --git a/inst/include/armadillo_bits/subview_cube_meat.hpp b/inst/include/armadillo_bits/subview_cube_meat.hpp index e031e074..7159f32c 100644 --- a/inst/include/armadillo_bits/subview_cube_meat.hpp +++ b/inst/include/armadillo_bits/subview_cube_meat.hpp @@ -1257,7 +1257,7 @@ void subview_cube::fill(const eT val) { arma_debug_sigprint(); - + const uword local_n_rows = n_rows; const uword local_n_cols = n_cols; const uword local_n_slices = n_slices; @@ -1288,6 +1288,13 @@ subview_cube::zeros() if( (local_n_rows == 0) || (local_n_cols == 0) ) { return; } + if( (aux_row1 == 0) && (local_n_rows == m.n_rows) && (aux_col1 == 0) && (local_n_cols == m.n_cols) ) + { + arrayops::fill_zeros( slice_colptr(0,0), n_elem ); + + return; + } + for(uword slice = 0; slice < local_n_slices; ++slice) { for(uword col = 0; col < local_n_cols; ++col) diff --git a/inst/include/armadillo_bits/subview_cube_slices_bones.hpp b/inst/include/armadillo_bits/subview_cube_slices_bones.hpp index 53bf6f85..90c1bced 100644 --- a/inst/include/armadillo_bits/subview_cube_slices_bones.hpp +++ b/inst/include/armadillo_bits/subview_cube_slices_bones.hpp @@ -40,6 +40,8 @@ class subview_cube_slices : public BaseCube< eT, subview_cube_slices > public: + static constexpr bool has_subview = true; + inline ~subview_cube_slices(); inline subview_cube_slices() = delete; diff --git a/inst/include/armadillo_bits/subview_each_meat.hpp b/inst/include/armadillo_bits/subview_each_meat.hpp index 47ec9d79..4c4d85ca 100644 --- a/inst/include/armadillo_bits/subview_each_meat.hpp +++ b/inst/include/armadillo_bits/subview_each_meat.hpp @@ -1078,7 +1078,7 @@ subview_each2_aux::operator_plus const quasi_unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; - const unwrap U(X.base_indices.get_ref()); + const plain_unwrap U(X.base_indices.get_ref()); X.check_size(A); X.check_indices(U.M); @@ -1142,7 +1142,7 @@ subview_each2_aux::operator_minus const quasi_unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; - const unwrap U(X.base_indices.get_ref()); + const plain_unwrap U(X.base_indices.get_ref()); X.check_size(A); X.check_indices(U.M); @@ -1206,7 +1206,7 @@ subview_each2_aux::operator_minus const quasi_unwrap tmp(X.get_ref()); const Mat& A = tmp.M; - const unwrap U(Y.base_indices.get_ref()); + const plain_unwrap U(Y.base_indices.get_ref()); Y.check_size(A); Y.check_indices(U.M); @@ -1276,7 +1276,7 @@ subview_each2_aux::operator_schur const quasi_unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; - const unwrap U(X.base_indices.get_ref()); + const plain_unwrap U(X.base_indices.get_ref()); X.check_size(A); X.check_indices(U.M); @@ -1340,7 +1340,7 @@ subview_each2_aux::operator_div const quasi_unwrap tmp(Y.get_ref()); const Mat& A = tmp.M; - const unwrap U(X.base_indices.get_ref()); + const plain_unwrap U(X.base_indices.get_ref()); X.check_size(A); X.check_indices(U.M); @@ -1404,7 +1404,7 @@ subview_each2_aux::operator_div const quasi_unwrap tmp(X.get_ref()); const Mat& A = tmp.M; - const unwrap U(Y.base_indices.get_ref()); + const plain_unwrap U(Y.base_indices.get_ref()); Y.check_size(A); Y.check_indices(U.M); diff --git a/inst/include/armadillo_bits/subview_elem1_bones.hpp b/inst/include/armadillo_bits/subview_elem1_bones.hpp index 449298b8..31717f21 100644 --- a/inst/include/armadillo_bits/subview_elem1_bones.hpp +++ b/inst/include/armadillo_bits/subview_elem1_bones.hpp @@ -33,9 +33,11 @@ class subview_elem1 : public Base< eT, subview_elem1 > static constexpr bool is_col = true; static constexpr bool is_xvec = false; - arma_aligned const Mat fake_m; - arma_aligned const Mat& m; - arma_aligned const Base& a; + static constexpr bool has_subview = true; + + const Mat fake_m; + const Mat& m; + const Base& a; protected: @@ -49,9 +51,8 @@ class subview_elem1 : public Base< eT, subview_elem1 > inline ~subview_elem1(); inline subview_elem1() = delete; - template inline void inplace_op(const eT val); - template inline void inplace_op(const subview_elem1& x ); - template inline void inplace_op(const Base& x ); + template inline void inplace_op(const eT val ); + template inline void inplace_op(const Base& expr); arma_inline const Op,op_htrans> t() const; arma_inline const Op,op_htrans> ht() const; @@ -76,13 +77,8 @@ class subview_elem1 : public Base< eT, subview_elem1 > // deliberately returning void - template inline void operator_equ(const subview_elem1& x); - template inline void operator= (const subview_elem1& x); - inline void operator= (const subview_elem1& x); - template inline void operator+= (const subview_elem1& x); - template inline void operator-= (const subview_elem1& x); - template inline void operator%= (const subview_elem1& x); - template inline void operator/= (const subview_elem1& x); + template inline void operator= (const subview_elem1& x); + inline void operator= (const subview_elem1& x); template inline void operator= (const Base& x); template inline void operator+= (const Base& x); @@ -94,13 +90,6 @@ class subview_elem1 : public Base< eT, subview_elem1 > inline static void extract(Mat& out, const subview_elem1& in); - template inline static void mat_inplace_op(Mat& out, const subview_elem1& in); - - inline static void plus_inplace(Mat& out, const subview_elem1& in); - inline static void minus_inplace(Mat& out, const subview_elem1& in); - inline static void schur_inplace(Mat& out, const subview_elem1& in); - inline static void div_inplace(Mat& out, const subview_elem1& in); - template inline bool is_alias(const Mat& X) const; diff --git a/inst/include/armadillo_bits/subview_elem1_meat.hpp b/inst/include/armadillo_bits/subview_elem1_meat.hpp index 11703dc5..10d4741d 100644 --- a/inst/include/armadillo_bits/subview_elem1_meat.hpp +++ b/inst/include/armadillo_bits/subview_elem1_meat.hpp @@ -64,8 +64,33 @@ subview_elem1::inplace_op(const eT val) eT* m_mem = m_local.memptr(); const uword m_n_elem = m_local.n_elem; - const unwrap_check_mixed tmp(a.get_ref(), m_local); - const umat& aa = tmp.M; + if(strip_op_find_default::do_op_find_default) + { + const strip_op_find_default strip(a.get_ref()); + + constexpr bool has_sv = strip_op_find_default::stored_type::has_subview; + + if( (has_sv == false) || ((has_sv == true) && (strip.M.is_alias(m_local) == false)) ) + { + if(has_sv == false) { arma_debug_print("op_find_default optimisation; has_sv = false"); } + if(has_sv == true ) { arma_debug_print("op_find_default optimisation; has_sv = true" ); } + + bool mi_bad = false; + + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { m_mem[mi] = val; } else { mi_bad = true; } }; op_find_aux::apply(modifier, strip.M); } + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { m_mem[mi] += val; } else { mi_bad = true; } }; op_find_aux::apply(modifier, strip.M); } + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { m_mem[mi] -= val; } else { mi_bad = true; } }; op_find_aux::apply(modifier, strip.M); } + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { m_mem[mi] *= val; } else { mi_bad = true; } }; op_find_aux::apply(modifier, strip.M); } + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { m_mem[mi] /= val; } else { mi_bad = true; } }; op_find_aux::apply(modifier, strip.M); } + + arma_conform_check_bounds( mi_bad, "Mat::elem(): index out of bounds" ); + + return; + } + } + + const unwrap_check_mixed U(a.get_ref(), m_local); + const umat& aa = U.M; if(resolves_to_vector::no) { @@ -75,33 +100,47 @@ subview_elem1::inplace_op(const eT val) const uword* aa_mem = aa.memptr(); const uword aa_n_elem = aa.n_elem; + bool ii_jj_bad = false; + uword iq,jq; for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2) { const uword ii = aa_mem[iq]; const uword jj = aa_mem[jq]; - arma_conform_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); - - if(is_same_type::yes) { m_mem[ii] = val; m_mem[jj] = val; } - if(is_same_type::yes) { m_mem[ii] += val; m_mem[jj] += val; } - if(is_same_type::yes) { m_mem[ii] -= val; m_mem[jj] -= val; } - if(is_same_type::yes) { m_mem[ii] *= val; m_mem[jj] *= val; } - if(is_same_type::yes) { m_mem[ii] /= val; m_mem[jj] /= val; } + if( (ii < m_n_elem) && (jj < m_n_elem) ) + { + if(is_same_type::yes) { m_mem[ii] = val; m_mem[jj] = val; } + if(is_same_type::yes) { m_mem[ii] += val; m_mem[jj] += val; } + if(is_same_type::yes) { m_mem[ii] -= val; m_mem[jj] -= val; } + if(is_same_type::yes) { m_mem[ii] *= val; m_mem[jj] *= val; } + if(is_same_type::yes) { m_mem[ii] /= val; m_mem[jj] /= val; } + } + else + { + ii_jj_bad = true; + } } if(iq < aa_n_elem) { const uword ii = aa_mem[iq]; - arma_conform_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); - - if(is_same_type::yes) { m_mem[ii] = val; } - if(is_same_type::yes) { m_mem[ii] += val; } - if(is_same_type::yes) { m_mem[ii] -= val; } - if(is_same_type::yes) { m_mem[ii] *= val; } - if(is_same_type::yes) { m_mem[ii] /= val; } + if(ii < m_n_elem) + { + if(is_same_type::yes) { m_mem[ii] = val; } + if(is_same_type::yes) { m_mem[ii] += val; } + if(is_same_type::yes) { m_mem[ii] -= val; } + if(is_same_type::yes) { m_mem[ii] *= val; } + if(is_same_type::yes) { m_mem[ii] /= val; } + } + else + { + ii_jj_bad = true; + } } + + arma_conform_check_bounds( ii_jj_bad, "Mat::elem(): index out of bounds" ); } @@ -110,114 +149,54 @@ template template inline void -subview_elem1::inplace_op(const subview_elem1& x) +subview_elem1::inplace_op(const Base& expr) { arma_debug_sigprint(); - subview_elem1& s = *this; + Mat& m_local = const_cast< Mat& >(m); - if(&(s.m) == &(x.m)) - { - arma_debug_print("subview_elem1::inplace_op(): aliasing detected"); - - const Mat tmp(x); - - if(is_same_type::yes) { s.operator= (tmp); } - if(is_same_type::yes) { s.operator+=(tmp); } - if(is_same_type::yes) { s.operator-=(tmp); } - if(is_same_type::yes) { s.operator%=(tmp); } - if(is_same_type::yes) { s.operator/=(tmp); } - } - else + eT* m_mem = m_local.memptr(); + const uword m_n_elem = m_local.n_elem; + + typedef typename quasi_unwrap::stored_type U1_M_type; + + const quasi_unwrap U1(expr.get_ref()); + const unwrap_check U2(U1.M, U1.is_alias(m_local)); + + const eT* X_mem = U2.M.memptr(); + const uword X_n_elem = U2.M.n_elem; + + if(strip_op_find_default::do_op_find_default) { - Mat& s_m_local = const_cast< Mat& >(s.m); - const Mat& x_m_local = x.m; - - const unwrap_check_mixed s_tmp(s.a.get_ref(), s_m_local); - const unwrap_check_mixed x_tmp(x.a.get_ref(), s_m_local); - - const umat& s_aa = s_tmp.M; - const umat& x_aa = x_tmp.M; - - arma_conform_check - ( - ( ((s_aa.is_vec() == false) && (s_aa.is_empty() == false)) || ((x_aa.is_vec() == false) && (x_aa.is_empty() == false)) ), - "Mat::elem(): given object must be a vector" - ); - - const uword* s_aa_mem = s_aa.memptr(); - const uword* x_aa_mem = x_aa.memptr(); - - const uword s_aa_n_elem = s_aa.n_elem; - - arma_conform_check( (s_aa_n_elem != x_aa.n_elem), "Mat::elem(): size mismatch" ); - + const strip_op_find_default strip(a.get_ref()); - eT* s_m_mem = s_m_local.memptr(); - const uword s_m_n_elem = s_m_local.n_elem; + constexpr bool has_sv = strip_op_find_default::stored_type::has_subview; - const eT* x_m_mem = x_m_local.memptr(); - const uword x_m_n_elem = x_m_local.n_elem; - - uword iq,jq; - for(iq=0, jq=1; jq < s_aa_n_elem; iq+=2, jq+=2) + if( (has_sv == false) || ((has_sv == true) && (strip.M.is_alias(m_local) == false)) ) { - const uword s_ii = s_aa_mem[iq]; - const uword s_jj = s_aa_mem[jq]; + if(has_sv == false) { arma_debug_print("op_find_default optimisation; has_sv = false"); } + if(has_sv == true ) { arma_debug_print("op_find_default optimisation; has_sv = true" ); } - const uword x_ii = x_aa_mem[iq]; - const uword x_jj = x_aa_mem[jq]; + bool mi_bad = false; - arma_conform_check_bounds - ( - (s_ii >= s_m_n_elem) || (s_jj >= s_m_n_elem) || (x_ii >= x_m_n_elem) || (x_jj >= x_m_n_elem), - "Mat::elem(): index out of bounds" - ); + uword Xi = 0; - if(is_same_type::yes) { s_m_mem[s_ii] = x_m_mem[x_ii]; s_m_mem[s_jj] = x_m_mem[x_jj]; } - if(is_same_type::yes) { s_m_mem[s_ii] += x_m_mem[x_ii]; s_m_mem[s_jj] += x_m_mem[x_jj]; } - if(is_same_type::yes) { s_m_mem[s_ii] -= x_m_mem[x_ii]; s_m_mem[s_jj] -= x_m_mem[x_jj]; } - if(is_same_type::yes) { s_m_mem[s_ii] *= x_m_mem[x_ii]; s_m_mem[s_jj] *= x_m_mem[x_jj]; } - if(is_same_type::yes) { s_m_mem[s_ii] /= x_m_mem[x_ii]; s_m_mem[s_jj] /= x_m_mem[x_jj]; } - } - - if(iq < s_aa_n_elem) - { - const uword s_ii = s_aa_mem[iq]; - const uword x_ii = x_aa_mem[iq]; + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { if(Xi < X_n_elem) { m_mem[mi] = X_mem[Xi]; } } else { mi_bad = true; } ++Xi; }; op_find_aux::apply(modifier, strip.M); } + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { if(Xi < X_n_elem) { m_mem[mi] += X_mem[Xi]; } } else { mi_bad = true; } ++Xi; }; op_find_aux::apply(modifier, strip.M); } + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { if(Xi < X_n_elem) { m_mem[mi] -= X_mem[Xi]; } } else { mi_bad = true; } ++Xi; }; op_find_aux::apply(modifier, strip.M); } + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { if(Xi < X_n_elem) { m_mem[mi] *= X_mem[Xi]; } } else { mi_bad = true; } ++Xi; }; op_find_aux::apply(modifier, strip.M); } + if(is_same_type::yes) { auto modifier = [&](const uword mi) { if(mi < m_n_elem) { if(Xi < X_n_elem) { m_mem[mi] /= X_mem[Xi]; } } else { mi_bad = true; } ++Xi; }; op_find_aux::apply(modifier, strip.M); } + + arma_conform_check_bounds( mi_bad, "Mat::elem(): index out of bounds" ); - arma_conform_check_bounds - ( - ( (s_ii >= s_m_n_elem) || (x_ii >= x_m_n_elem) ), - "Mat::elem(): index out of bounds" - ); + arma_conform_check( (Xi != X_n_elem), "Mat::elem(): size mismatch" ); - if(is_same_type::yes) { s_m_mem[s_ii] = x_m_mem[x_ii]; } - if(is_same_type::yes) { s_m_mem[s_ii] += x_m_mem[x_ii]; } - if(is_same_type::yes) { s_m_mem[s_ii] -= x_m_mem[x_ii]; } - if(is_same_type::yes) { s_m_mem[s_ii] *= x_m_mem[x_ii]; } - if(is_same_type::yes) { s_m_mem[s_ii] /= x_m_mem[x_ii]; } + return; } } - } - - - -template -template -inline -void -subview_elem1::inplace_op(const Base& x) - { - arma_debug_sigprint(); - - Mat& m_local = const_cast< Mat& >(m); - eT* m_mem = m_local.memptr(); - const uword m_n_elem = m_local.n_elem; - - const unwrap_check_mixed aa_tmp(a.get_ref(), m_local); - const umat& aa = aa_tmp.M; + const unwrap_check_mixed U(a.get_ref(), m_local); + const umat& aa = U.M; if(resolves_to_vector::no) { @@ -227,81 +206,49 @@ subview_elem1::inplace_op(const Base& x) const uword* aa_mem = aa.memptr(); const uword aa_n_elem = aa.n_elem; - const Proxy P(x.get_ref()); + arma_conform_check( (aa_n_elem != X_n_elem), "Mat::elem(): size mismatch" ); - arma_conform_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" ); + bool ii_jj_bad = false; - const bool have_alias = P.is_alias(m); - - if( (have_alias == false) && (Proxy::use_at == false) ) + uword iq,jq; + for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2) { - typename Proxy::ea_type X = P.get_ea(); + const uword ii = aa_mem[iq]; + const uword jj = aa_mem[jq]; - uword iq,jq; - for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2) + if( (ii < m_n_elem) && (jj < m_n_elem) ) { - const uword ii = aa_mem[iq]; - const uword jj = aa_mem[jq]; - - arma_conform_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); - - if(is_same_type::yes) { m_mem[ii] = X[iq]; m_mem[jj] = X[jq]; } - if(is_same_type::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; } - if(is_same_type::yes) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; } - if(is_same_type::yes) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; } - if(is_same_type::yes) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; } + if(is_same_type::yes) { m_mem[ii] = X_mem[iq]; m_mem[jj] = X_mem[jq]; } + if(is_same_type::yes) { m_mem[ii] += X_mem[iq]; m_mem[jj] += X_mem[jq]; } + if(is_same_type::yes) { m_mem[ii] -= X_mem[iq]; m_mem[jj] -= X_mem[jq]; } + if(is_same_type::yes) { m_mem[ii] *= X_mem[iq]; m_mem[jj] *= X_mem[jq]; } + if(is_same_type::yes) { m_mem[ii] /= X_mem[iq]; m_mem[jj] /= X_mem[jq]; } } - - if(iq < aa_n_elem) + else { - const uword ii = aa_mem[iq]; - - arma_conform_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); - - if(is_same_type::yes) { m_mem[ii] = X[iq]; } - if(is_same_type::yes) { m_mem[ii] += X[iq]; } - if(is_same_type::yes) { m_mem[ii] -= X[iq]; } - if(is_same_type::yes) { m_mem[ii] *= X[iq]; } - if(is_same_type::yes) { m_mem[ii] /= X[iq]; } + ii_jj_bad = true; } } - else + + if(iq < aa_n_elem) { - arma_debug_print("subview_elem1::inplace_op(): aliasing or use_at detected"); - - const unwrap_check::stored_type> tmp(P.Q, have_alias); - const Mat& M = tmp.M; - - const eT* X = M.memptr(); + const uword ii = aa_mem[iq]; - uword iq,jq; - for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2) + if(ii < m_n_elem) { - const uword ii = aa_mem[iq]; - const uword jj = aa_mem[jq]; - - arma_conform_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); - - if(is_same_type::yes) { m_mem[ii] = X[iq]; m_mem[jj] = X[jq]; } - if(is_same_type::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; } - if(is_same_type::yes) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; } - if(is_same_type::yes) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; } - if(is_same_type::yes) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; } + if(is_same_type::yes) { m_mem[ii] = X_mem[iq]; } + if(is_same_type::yes) { m_mem[ii] += X_mem[iq]; } + if(is_same_type::yes) { m_mem[ii] -= X_mem[iq]; } + if(is_same_type::yes) { m_mem[ii] *= X_mem[iq]; } + if(is_same_type::yes) { m_mem[ii] /= X_mem[iq]; } } - - if(iq < aa_n_elem) + else { - const uword ii = aa_mem[iq]; - - arma_conform_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); - - if(is_same_type::yes) { m_mem[ii] = X[iq]; } - if(is_same_type::yes) { m_mem[ii] += X[iq]; } - if(is_same_type::yes) { m_mem[ii] -= X[iq]; } - if(is_same_type::yes) { m_mem[ii] *= X[iq]; } - if(is_same_type::yes) { m_mem[ii] /= X[iq]; } + ii_jj_bad = true; } } + + arma_conform_check_bounds( ii_jj_bad, "Mat::elem(): index out of bounds" ); } @@ -353,8 +300,8 @@ subview_elem1::replace(const eT old_val, const eT new_val) eT* m_mem = m_local.memptr(); const uword m_n_elem = m_local.n_elem; - const unwrap_check_mixed tmp(a.get_ref(), m_local); - const umat& aa = tmp.M; + const unwrap_check_mixed U(a.get_ref(), m_local); + const umat& aa = U.M; if(resolves_to_vector::no) { @@ -597,20 +544,6 @@ subview_elem1::operator/= (const eT val) -template -template -inline -void -subview_elem1::operator_equ(const subview_elem1& x) - { - arma_debug_sigprint(); - - inplace_op(x); - } - - - - template template inline @@ -619,72 +552,23 @@ subview_elem1::operator= (const subview_elem1& x) { arma_debug_sigprint(); - (*this).operator_equ(x); - } - - - -//! work around compiler bugs -template -inline -void -subview_elem1::operator= (const subview_elem1& x) - { - arma_debug_sigprint(); + const Mat tmp(x); - (*this).operator_equ(x); + inplace_op(tmp); } template -template inline void -subview_elem1::operator+= (const subview_elem1& x) - { - arma_debug_sigprint(); - - inplace_op(x); - } - - - -template -template -inline -void -subview_elem1::operator-= (const subview_elem1& x) - { - arma_debug_sigprint(); - - inplace_op(x); - } - - - -template -template -inline -void -subview_elem1::operator%= (const subview_elem1& x) +subview_elem1::operator= (const subview_elem1& x) { arma_debug_sigprint(); - inplace_op(x); - } - - - -template -template -inline -void -subview_elem1::operator/= (const subview_elem1& x) - { - arma_debug_sigprint(); + const Mat tmp(x); - inplace_op(x); + inplace_op(tmp); } @@ -766,57 +650,36 @@ subview_elem1::extract_noalias(Mat& out, const subview_elem1& { arma_debug_sigprint(); - const quasi_unwrap tmp1(in.a.get_ref()); - const umat& aa = tmp1.M; - - if(resolves_to_vector::no) - { - arma_conform_check( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), "Mat::elem(): given object must be a vector" ); - } - - const uword* aa_mem = aa.memptr(); - const uword aa_n_elem = aa.n_elem; - const eT* m_mem = in.m.memptr(); const uword m_n_elem = in.m.n_elem; - out.set_size(aa_n_elem, 1); - - eT* out_mem = out.memptr(); - - uword i,j; - for(i=0, j=1; j::do_op_find_default) { - const uword ii = aa_mem[i]; - const uword jj = aa_mem[j]; + arma_debug_print("op_find_default optimisation"); - arma_conform_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + const strip_op_find_default strip(in.a.get_ref()); - out_mem[i] = m_mem[ii]; - out_mem[j] = m_mem[jj]; - } - - if(i < aa_n_elem) - { - const uword ii = aa_mem[i]; + Mat tmp(m_n_elem, 1, arma_nozeros_indicator()); // worst-case scenario + + eT* tmp_mem = tmp.memptr(); + + uword count = 0; + + bool mi_bad = false; - arma_conform_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + auto element_extractor = [&](const uword mi) { if((mi < m_n_elem) && (count < m_n_elem)) { tmp_mem[count] = m_mem[mi]; ++count; } else { mi_bad = true; } }; - out_mem[i] = m_mem[ii]; + op_find_aux::apply(element_extractor, strip.M); + + arma_conform_check_bounds( mi_bad, "Mat::elem(): index out of bounds" ); + + out.steal_mem_col(tmp, count); + + return; } - } - - - -template -inline -void -subview_elem1::extract(Mat& actual_out, const subview_elem1& in) - { - arma_debug_sigprint(); - const unwrap_check_mixed tmp1(in.a.get_ref(), actual_out); - const umat& aa = tmp1.M; + const quasi_unwrap U(in.a.get_ref()); + const umat& aa = U.M; if(resolves_to_vector::no) { @@ -826,158 +689,86 @@ subview_elem1::extract(Mat& actual_out, const subview_elem1& i const uword* aa_mem = aa.memptr(); const uword aa_n_elem = aa.n_elem; - const Mat& m = in.m; - - const eT* m_mem = m.memptr(); - const uword m_n_elem = m.n_elem; - - const bool alias = (&actual_out == &m); - - if(alias) { arma_debug_print("subview_elem1::extract(): aliasing detected"); } - - Mat* tmp_out = alias ? new Mat() : nullptr; - Mat& out = alias ? *tmp_out : actual_out; - out.set_size(aa_n_elem, 1); eT* out_mem = out.memptr(); + bool ii_jj_bad = false; + uword i,j; for(i=0, j=1; j= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + eT m_ii_val; + eT m_jj_val; - out_mem[i] = m_mem[ii]; - out_mem[j] = m_mem[jj]; + if( (ii < m_n_elem) && (jj < m_n_elem) ) + { + m_ii_val = m_mem[ii]; + m_jj_val = m_mem[jj]; + } + else + { + ii_jj_bad = true; + + m_ii_val = eT(0); + m_jj_val = eT(0); + } + + out_mem[i] = m_ii_val; + out_mem[j] = m_jj_val; } if(i < aa_n_elem) { const uword ii = aa_mem[i]; - arma_conform_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); + eT m_ii_val; - out_mem[i] = m_mem[ii]; + if(ii < m_n_elem) + { + m_ii_val = m_mem[ii]; + } + else + { + ii_jj_bad = true; + + m_ii_val = eT(0); + } + + out_mem[i] = m_ii_val; } - if(alias) - { - actual_out.steal_mem(out); - delete tmp_out; - } + arma_conform_check_bounds( ii_jj_bad, "Mat::elem(): index out of bounds" ); } template -template inline void -subview_elem1::mat_inplace_op(Mat& out, const subview_elem1& in) +subview_elem1::extract(Mat& out, const subview_elem1& in) { arma_debug_sigprint(); - const unwrap tmp1(in.a.get_ref()); - const umat& aa = tmp1.M; - - if(resolves_to_vector::no) + if(in.is_alias(out)) { - arma_conform_check( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), "Mat::elem(): given object must be a vector" ); - } - - const uword* aa_mem = aa.memptr(); - const uword aa_n_elem = aa.n_elem; - - const unwrap_check< Mat > tmp2(in.m, out); - const Mat& m_local = tmp2.M; - - const eT* m_mem = m_local.memptr(); - const uword m_n_elem = m_local.n_elem; - - arma_conform_check( (out.n_elem != aa_n_elem), "Mat::elem(): size mismatch" ); - - eT* out_mem = out.memptr(); - - uword i,j; - for(i=0, j=1; j tmp; - arma_conform_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); + subview_elem1::extract_noalias(tmp, in); - if(is_same_type::yes) { out_mem[i] += m_mem[ii]; out_mem[j] += m_mem[jj]; } - if(is_same_type::yes) { out_mem[i] -= m_mem[ii]; out_mem[j] -= m_mem[jj]; } - if(is_same_type::yes) { out_mem[i] *= m_mem[ii]; out_mem[j] *= m_mem[jj]; } - if(is_same_type::yes) { out_mem[i] /= m_mem[ii]; out_mem[j] /= m_mem[jj]; } + out.steal_mem(tmp); } - - if(i < aa_n_elem) + else { - const uword ii = aa_mem[i]; - - arma_conform_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); - - if(is_same_type::yes) { out_mem[i] += m_mem[ii]; } - if(is_same_type::yes) { out_mem[i] -= m_mem[ii]; } - if(is_same_type::yes) { out_mem[i] *= m_mem[ii]; } - if(is_same_type::yes) { out_mem[i] /= m_mem[ii]; } + subview_elem1::extract_noalias(out, in); } } -template -inline -void -subview_elem1::plus_inplace(Mat& out, const subview_elem1& in) - { - arma_debug_sigprint(); - - mat_inplace_op(out, in); - } - - - -template -inline -void -subview_elem1::minus_inplace(Mat& out, const subview_elem1& in) - { - arma_debug_sigprint(); - - mat_inplace_op(out, in); - } - - - -template -inline -void -subview_elem1::schur_inplace(Mat& out, const subview_elem1& in) - { - arma_debug_sigprint(); - - mat_inplace_op(out, in); - } - - - -template -inline -void -subview_elem1::div_inplace(Mat& out, const subview_elem1& in) - { - arma_debug_sigprint(); - - mat_inplace_op(out, in); - } - - - template template inline diff --git a/inst/include/armadillo_bits/subview_elem2_bones.hpp b/inst/include/armadillo_bits/subview_elem2_bones.hpp index d215f655..14349e41 100644 --- a/inst/include/armadillo_bits/subview_elem2_bones.hpp +++ b/inst/include/armadillo_bits/subview_elem2_bones.hpp @@ -33,10 +33,12 @@ class subview_elem2 : public Base< eT, subview_elem2 > static constexpr bool is_col = false; static constexpr bool is_xvec = false; - arma_aligned const Mat& m; + static constexpr bool has_subview = true; - arma_aligned const Base& base_ri; - arma_aligned const Base& base_ci; + const Mat& m; + + const Base& base_ri; + const Base& base_ci; const bool all_rows; const bool all_cols; @@ -44,7 +46,7 @@ class subview_elem2 : public Base< eT, subview_elem2 > protected: - arma_inline subview_elem2(const Mat& in_m, const Base& in_ri, const Base& in_ci, const bool in_all_rows, const bool in_all_cols); + inline subview_elem2(const Mat& in_m, const Base& in_ri, const Base& in_ci, const bool in_all_rows, const bool in_all_cols); public: @@ -52,11 +54,8 @@ class subview_elem2 : public Base< eT, subview_elem2 > inline ~subview_elem2(); inline subview_elem2() = delete; - template - inline void inplace_op(const eT val); - - template - inline void inplace_op(const Base& x); + template inline void inplace_op(const eT val); + template inline void inplace_op(const Base& x ); inline void replace(const eT old_val, const eT new_val); @@ -77,14 +76,8 @@ class subview_elem2 : public Base< eT, subview_elem2 > // deliberately returning void - template inline void operator_equ(const subview_elem2& x); - template inline void operator= (const subview_elem2& x); - inline void operator= (const subview_elem2& x); - - template inline void operator+= (const subview_elem2& x); - template inline void operator-= (const subview_elem2& x); - template inline void operator%= (const subview_elem2& x); - template inline void operator/= (const subview_elem2& x); + template inline void operator= (const subview_elem2& x); + inline void operator= (const subview_elem2& x); template inline void operator= (const Base& x); template inline void operator+= (const Base& x); @@ -102,11 +95,6 @@ class subview_elem2 : public Base< eT, subview_elem2 > inline static void extract(Mat& out, const subview_elem2& in); - inline static void plus_inplace(Mat& out, const subview_elem2& in); - inline static void minus_inplace(Mat& out, const subview_elem2& in); - inline static void schur_inplace(Mat& out, const subview_elem2& in); - inline static void div_inplace(Mat& out, const subview_elem2& in); - template inline bool is_alias(const Mat& X) const; diff --git a/inst/include/armadillo_bits/subview_elem2_meat.hpp b/inst/include/armadillo_bits/subview_elem2_meat.hpp index c7810715..f8b241b3 100644 --- a/inst/include/armadillo_bits/subview_elem2_meat.hpp +++ b/inst/include/armadillo_bits/subview_elem2_meat.hpp @@ -29,7 +29,7 @@ subview_elem2::~subview_elem2() template -arma_inline +inline subview_elem2::subview_elem2 ( const Mat& in_m, @@ -64,11 +64,11 @@ subview_elem2::inplace_op(const eT val) if( (all_rows == false) && (all_cols == false) ) { - const unwrap_check_mixed tmp1(base_ri.get_ref(), m_local); - const unwrap_check_mixed tmp2(base_ci.get_ref(), m_local); + const unwrap_check_mixed U1(base_ri.get_ref(), m_local); + const unwrap_check_mixed U2(base_ci.get_ref(), m_local); - const umat& ri = tmp1.M; - const umat& ci = tmp2.M; + const umat& ri = U1.M; + const umat& ci = U2.M; arma_conform_check ( @@ -105,9 +105,9 @@ subview_elem2::inplace_op(const eT val) else if( (all_rows == true) && (all_cols == false) ) { - const unwrap_check_mixed tmp2(base_ci.get_ref(), m_local); + const unwrap_check_mixed U2(base_ci.get_ref(), m_local); - const umat& ci = tmp2.M; + const umat& ci = U2.M; arma_conform_check ( @@ -136,9 +136,9 @@ subview_elem2::inplace_op(const eT val) else if( (all_rows == false) && (all_cols == true) ) { - const unwrap_check_mixed tmp1(base_ri.get_ref(), m_local); + const unwrap_check_mixed U1(base_ri.get_ref(), m_local); - const umat& ri = tmp1.M; + const umat& ri = U1.M; arma_conform_check ( @@ -182,16 +182,16 @@ subview_elem2::inplace_op(const Base& x) const uword m_n_rows = m_local.n_rows; const uword m_n_cols = m_local.n_cols; - const unwrap_check tmp(x.get_ref(), m_local); - const Mat& X = tmp.M; + const unwrap_check U(x.get_ref(), m_local); + const Mat& X = U.M; if( (all_rows == false) && (all_cols == false) ) { - const unwrap_check_mixed tmp1(base_ri.get_ref(), m_local); - const unwrap_check_mixed tmp2(base_ci.get_ref(), m_local); + const unwrap_check_mixed U1(base_ri.get_ref(), m_local); + const unwrap_check_mixed U2(base_ci.get_ref(), m_local); - const umat& ri = tmp1.M; - const umat& ci = tmp2.M; + const umat& ri = U1.M; + const umat& ci = U2.M; arma_conform_check ( @@ -230,9 +230,9 @@ subview_elem2::inplace_op(const Base& x) else if( (all_rows == true) && (all_cols == false) ) { - const unwrap_check_mixed tmp2(base_ci.get_ref(), m_local); + const unwrap_check_mixed U2(base_ci.get_ref(), m_local); - const umat& ci = tmp2.M; + const umat& ci = U2.M; arma_conform_check ( @@ -264,9 +264,9 @@ subview_elem2::inplace_op(const Base& x) else if( (all_rows == false) && (all_cols == true) ) { - const unwrap_check_mixed tmp1(base_ri.get_ref(), m_local); + const unwrap_check_mixed U1(base_ri.get_ref(), m_local); - const umat& ri = tmp1.M; + const umat& ri = U1.M; arma_conform_check ( @@ -675,20 +675,6 @@ subview_elem2::operator/= (const eT val) -template -template -inline -void -subview_elem2::operator_equ(const subview_elem2& x) - { - arma_debug_sigprint(); - - inplace_op(x); - } - - - - template template inline @@ -697,72 +683,23 @@ subview_elem2::operator= (const subview_elem2& x) { arma_debug_sigprint(); - (*this).operator_equ(x); - } - - - -//! work around compiler bugs -template -inline -void -subview_elem2::operator= (const subview_elem2& x) - { - arma_debug_sigprint(); - - (*this).operator_equ(x); - } - - - -template -template -inline -void -subview_elem2::operator+= (const subview_elem2& x) - { - arma_debug_sigprint(); - - inplace_op(x); - } - - - -template -template -inline -void -subview_elem2::operator-= (const subview_elem2& x) - { - arma_debug_sigprint(); + const Mat tmp(x); - inplace_op(x); + inplace_op(tmp); } template -template inline void -subview_elem2::operator%= (const subview_elem2& x) +subview_elem2::operator= (const subview_elem2& x) { arma_debug_sigprint(); - inplace_op(x); - } - - - -template -template -inline -void -subview_elem2::operator/= (const subview_elem2& x) - { - arma_debug_sigprint(); + const Mat tmp(x); - inplace_op(x); + inplace_op(tmp); } @@ -931,11 +868,11 @@ subview_elem2::extract_noalias(Mat& out, const subview_elem2 tmp1(in.base_ri.get_ref()); - const quasi_unwrap tmp2(in.base_ci.get_ref()); + const quasi_unwrap U1(in.base_ri.get_ref()); + const quasi_unwrap U2(in.base_ci.get_ref()); - const umat& ri = tmp1.M; - const umat& ci = tmp2.M; + const umat& ri = U1.M; + const umat& ci = U2.M; arma_conform_check ( @@ -974,9 +911,9 @@ subview_elem2::extract_noalias(Mat& out, const subview_elem2 tmp2(in.base_ci.get_ref()); + const quasi_unwrap U2(in.base_ci.get_ref()); - const umat& ci = tmp2.M; + const umat& ci = U2.M; arma_conform_check ( @@ -1001,9 +938,9 @@ subview_elem2::extract_noalias(Mat& out, const subview_elem2 tmp1(in.base_ri.get_ref()); + const quasi_unwrap U1(in.base_ri.get_ref()); - const umat& ri = tmp1.M; + const umat& ri = U1.M; arma_conform_check ( @@ -1035,186 +972,22 @@ subview_elem2::extract_noalias(Mat& out, const subview_elem2 inline void -subview_elem2::extract(Mat& actual_out, const subview_elem2& in) +subview_elem2::extract(Mat& out, const subview_elem2& in) { arma_debug_sigprint(); - const Mat& m = in.m; - - const uword m_n_rows = m.n_rows; - const uword m_n_cols = m.n_cols; - - const bool alias = (&actual_out == &m); - - if(alias) { arma_debug_print("subview_elem2::extract(): aliasing detected"); } - - Mat* tmp_out = alias ? new Mat() : nullptr; - Mat& out = alias ? *tmp_out : actual_out; - - if( (in.all_rows == false) && (in.all_cols == false) ) + if(in.is_alias(out)) { - const unwrap_check_mixed tmp1(in.base_ri.get_ref(), actual_out); - const unwrap_check_mixed tmp2(in.base_ci.get_ref(), actual_out); - - const umat& ri = tmp1.M; - const umat& ci = tmp2.M; - - arma_conform_check - ( - ( ((ri.is_vec() == false) && (ri.is_empty() == false)) || ((ci.is_vec() == false) && (ci.is_empty() == false)) ), - "Mat::elem(): given object must be a vector" - ); - - const uword* ri_mem = ri.memptr(); - const uword ri_n_elem = ri.n_elem; - - const uword* ci_mem = ci.memptr(); - const uword ci_n_elem = ci.n_elem; + Mat tmp; - out.set_size(ri_n_elem, ci_n_elem); + subview_elem2::extract_noalias(tmp, in); - eT* out_mem = out.memptr(); - uword out_count = 0; - - for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) - { - const uword col = ci_mem[ci_count]; - - arma_conform_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); - - for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count) - { - const uword row = ri_mem[ri_count]; - - arma_conform_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); - - out_mem[out_count] = m.at(row,col); - ++out_count; - } - } + out.steal_mem(tmp); } else - if( (in.all_rows == true) && (in.all_cols == false) ) { - const unwrap_check_mixed tmp2(in.base_ci.get_ref(), m); - - const umat& ci = tmp2.M; - - arma_conform_check - ( - ( (ci.is_vec() == false) && (ci.is_empty() == false) ), - "Mat::elem(): given object must be a vector" - ); - - const uword* ci_mem = ci.memptr(); - const uword ci_n_elem = ci.n_elem; - - out.set_size(m_n_rows, ci_n_elem); - - for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count) - { - const uword col = ci_mem[ci_count]; - - arma_conform_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" ); - - arrayops::copy( out.colptr(ci_count), m.colptr(col), m_n_rows ); - } + subview_elem2::extract_noalias(out, in); } - else - if( (in.all_rows == false) && (in.all_cols == true) ) - { - const unwrap_check_mixed tmp1(in.base_ri.get_ref(), m); - - const umat& ri = tmp1.M; - - arma_conform_check - ( - ( (ri.is_vec() == false) && (ri.is_empty() == false) ), - "Mat::elem(): given object must be a vector" - ); - - const uword* ri_mem = ri.memptr(); - const uword ri_n_elem = ri.n_elem; - - out.set_size(ri_n_elem, m_n_cols); - - for(uword col=0; col < m_n_cols; ++col) - { - for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count) - { - const uword row = ri_mem[ri_count]; - - arma_conform_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" ); - - out.at(ri_count,col) = m.at(row,col); - } - } - } - - - if(alias) - { - actual_out.steal_mem(out); - - delete tmp_out; - } - } - - - -// TODO: implement a dedicated function instead of creating a temporary (but lots of potential aliasing issues) -template -inline -void -subview_elem2::plus_inplace(Mat& out, const subview_elem2& in) - { - arma_debug_sigprint(); - - const Mat tmp(in); - - out += tmp; - } - - - -template -inline -void -subview_elem2::minus_inplace(Mat& out, const subview_elem2& in) - { - arma_debug_sigprint(); - - const Mat tmp(in); - - out -= tmp; - } - - - -template -inline -void -subview_elem2::schur_inplace(Mat& out, const subview_elem2& in) - { - arma_debug_sigprint(); - - const Mat tmp(in); - - out %= tmp; - } - - - -template -inline -void -subview_elem2::div_inplace(Mat& out, const subview_elem2& in) - { - arma_debug_sigprint(); - - const Mat tmp(in); - - out /= tmp; } diff --git a/inst/include/armadillo_bits/subview_meat.hpp b/inst/include/armadillo_bits/subview_meat.hpp index c1f73aef..3b20e2b6 100644 --- a/inst/include/armadillo_bits/subview_meat.hpp +++ b/inst/include/armadillo_bits/subview_meat.hpp @@ -3449,7 +3449,7 @@ subview_col::operator=(const Base& expr) if(is_Mat::value) { - const unwrap U(expr.get_ref()); // deliberately not using quasi_unwrap + const plain_unwrap U(expr.get_ref()); // deliberately not using quasi_unwrap arma_conform_assert_same_size(subview::n_rows, uword(1), U.M.n_rows, U.M.n_cols, "copy into submatrix"); @@ -4511,7 +4511,7 @@ subview_row::operator=(const Base& X) if(is_Mat::value) { - const unwrap U(X.get_ref()); // deliberately not using quasi_unwrap + const plain_unwrap U(X.get_ref()); // deliberately not using quasi_unwrap arma_conform_assert_same_size(uword(1), subview::n_cols, U.M.n_rows, U.M.n_cols, "copy into submatrix"); diff --git a/inst/include/armadillo_bits/unwrap.hpp b/inst/include/armadillo_bits/unwrap.hpp index a4e51bb9..736e6c71 100644 --- a/inst/include/armadillo_bits/unwrap.hpp +++ b/inst/include/armadillo_bits/unwrap.hpp @@ -21,17 +21,17 @@ // TODO: document the conditions and restrictions for the use of each unwrap variant: -// TODO: unwrap, unwrap_check, quasi_unwrap, partial_unwrap +// TODO: plain_unwrap, quasi_unwrap, unwrap_check, partial_unwrap, ... template -struct unwrap_default +struct plain_unwrap_default { typedef typename T1::elem_type eT; typedef Mat stored_type; inline - unwrap_default(const T1& A) + plain_unwrap_default(const T1& A) : M(A) { arma_debug_sigprint(); @@ -46,12 +46,13 @@ struct unwrap_default template -struct unwrap_fixed +struct plain_unwrap_fixed { - typedef T1 stored_type; + typedef typename T1::elem_type eT; + typedef T1 stored_type; inline explicit - unwrap_fixed(const T1& A) + plain_unwrap_fixed(const T1& A) : M(A) { arma_debug_sigprint(); @@ -60,27 +61,27 @@ struct unwrap_fixed const T1& M; template - arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } + arma_inline bool is_alias(const Mat& X) const { return (is_same_type::yes) && (void_ptr(&M) == void_ptr(&X)); } }; template -struct unwrap_redirect {}; +struct plain_unwrap_redirect {}; template -struct unwrap_redirect { typedef unwrap_default result; }; +struct plain_unwrap_redirect { typedef plain_unwrap_default result; }; template -struct unwrap_redirect { typedef unwrap_fixed result; }; +struct plain_unwrap_redirect { typedef plain_unwrap_fixed result; }; template -struct unwrap : public unwrap_redirect::value>::result +struct plain_unwrap : public plain_unwrap_redirect::value>::result { inline - unwrap(const T1& A) - : unwrap_redirect::value>::result(A) + plain_unwrap(const T1& A) + : plain_unwrap_redirect::value>::result(A) { } }; @@ -88,12 +89,12 @@ struct unwrap : public unwrap_redirect::value>::result template -struct unwrap< Mat > +struct plain_unwrap< Mat > { typedef Mat stored_type; inline - unwrap(const Mat& A) + plain_unwrap(const Mat& A) : M(A) { arma_debug_sigprint(); @@ -108,12 +109,12 @@ struct unwrap< Mat > template -struct unwrap< Row > +struct plain_unwrap< Row > { typedef Row stored_type; inline - unwrap(const Row& A) + plain_unwrap(const Row& A) : M(A) { arma_debug_sigprint(); @@ -128,12 +129,12 @@ struct unwrap< Row > template -struct unwrap< Col > +struct plain_unwrap< Col > { typedef Col stored_type; inline - unwrap(const Col& A) + plain_unwrap(const Col& A) : M(A) { arma_debug_sigprint(); @@ -148,12 +149,12 @@ struct unwrap< Col > template -struct unwrap< subview_col > +struct plain_unwrap< subview_col > { typedef Col stored_type; inline - unwrap(const subview_col& A) + plain_unwrap(const subview_col& A) : M(A.colmem, A.n_rows) { arma_debug_sigprint(); @@ -168,12 +169,12 @@ struct unwrap< subview_col > template -struct unwrap< subview_cols > +struct plain_unwrap< subview_cols > { typedef Mat stored_type; inline - unwrap(const subview_cols& A) + plain_unwrap(const subview_cols& A) : M(A.colptr(0), A.n_rows, A.n_cols) { arma_debug_sigprint(); @@ -188,12 +189,12 @@ struct unwrap< subview_cols > template -struct unwrap< mtGlue > +struct plain_unwrap< mtGlue > { typedef Mat stored_type; inline - unwrap(const mtGlue& A) + plain_unwrap(const mtGlue& A) : M(A) { arma_debug_sigprint(); @@ -208,12 +209,12 @@ struct unwrap< mtGlue > template -struct unwrap< mtOp > +struct plain_unwrap< mtOp > { typedef Mat stored_type; inline - unwrap(const mtOp& A) + plain_unwrap(const mtOp& A) : M(A) { arma_debug_sigprint(); @@ -237,6 +238,7 @@ template struct quasi_unwrap_default { typedef typename T1::elem_type eT; + typedef Mat stored_type; inline quasi_unwrap_default(const T1& A) @@ -262,6 +264,7 @@ template struct quasi_unwrap_fixed { typedef typename T1::elem_type eT; + typedef T1 stored_type; inline explicit quasi_unwrap_fixed(const T1& A) @@ -277,7 +280,7 @@ struct quasi_unwrap_fixed static constexpr bool has_orig_mem = true; template - arma_inline bool is_alias(const Mat& X) const { return (void_ptr(&M) == void_ptr(&X)); } + arma_inline bool is_alias(const Mat& X) const { return (is_same_type::yes) && (void_ptr(&M) == void_ptr(&X)); } }; @@ -316,6 +319,8 @@ struct quasi_unwrap : public quasi_unwrap_redirect::value>: template struct quasi_unwrap< Mat > { + typedef Mat stored_type; + inline quasi_unwrap(const Mat& A) : M(A) @@ -338,6 +343,8 @@ struct quasi_unwrap< Mat > template struct quasi_unwrap< Row > { + typedef Row stored_type; + inline quasi_unwrap(const Row& A) : M(A) @@ -360,6 +367,8 @@ struct quasi_unwrap< Row > template struct quasi_unwrap< Col > { + typedef Col stored_type; + inline quasi_unwrap(const Col& A) : M(A) @@ -382,6 +391,8 @@ struct quasi_unwrap< Col > template struct quasi_unwrap< subview > { + typedef Mat stored_type; + inline quasi_unwrap(const subview& A) : sv( A ) @@ -406,6 +417,8 @@ struct quasi_unwrap< subview > template struct quasi_unwrap< subview_row > { + typedef Row stored_type; + inline quasi_unwrap(const subview_row& A) : sv( A ) @@ -430,6 +443,8 @@ struct quasi_unwrap< subview_row > template struct quasi_unwrap< subview_col > { + typedef Col stored_type; + inline quasi_unwrap(const subview_col& A) : orig( A.m ) @@ -454,6 +469,8 @@ struct quasi_unwrap< subview_col > template struct quasi_unwrap< subview_cols > { + typedef Mat stored_type; + inline quasi_unwrap(const subview_cols& A) : orig( A.m ) @@ -478,6 +495,8 @@ struct quasi_unwrap< subview_cols > template struct quasi_unwrap< mtGlue > { + typedef Mat stored_type; + inline quasi_unwrap(const mtGlue& A) : M(A) @@ -500,6 +519,8 @@ struct quasi_unwrap< mtGlue > template struct quasi_unwrap< mtOp > { + typedef Mat stored_type; + inline quasi_unwrap(const mtOp& A) : M(A) @@ -523,6 +544,7 @@ template struct quasi_unwrap< Op > { typedef typename T1::elem_type eT; + typedef Mat stored_type; inline quasi_unwrap(const Op& A) @@ -548,6 +570,8 @@ struct quasi_unwrap< Op > template struct quasi_unwrap< Op, op_strans> > { + typedef Row stored_type; + inline quasi_unwrap(const Op, op_strans>& A) : orig(A.m) @@ -572,6 +596,8 @@ struct quasi_unwrap< Op, op_strans> > template struct quasi_unwrap< Op, op_strans> > { + typedef Col stored_type; + inline quasi_unwrap(const Op, op_strans>& A) : orig(A.m) @@ -596,6 +622,8 @@ struct quasi_unwrap< Op, op_strans> > template struct quasi_unwrap< Op, op_strans> > { + typedef Row stored_type; + inline quasi_unwrap(const Op, op_strans>& A) : orig( A.m.m ) @@ -628,6 +656,8 @@ struct quasi_unwrap_Col_htrans template struct quasi_unwrap_Col_htrans< Op, op_htrans> > { + typedef Row stored_type; + inline quasi_unwrap_Col_htrans(const Op, op_htrans>& A) : orig(A.m) @@ -692,6 +722,8 @@ struct quasi_unwrap_Row_htrans template struct quasi_unwrap_Row_htrans< Op, op_htrans> > { + typedef Col stored_type; + inline quasi_unwrap_Row_htrans(const Op, op_htrans>& A) : orig(A.m) @@ -756,6 +788,8 @@ struct quasi_unwrap_subview_col_htrans template struct quasi_unwrap_subview_col_htrans< Op, op_htrans> > { + typedef Row stored_type; + inline quasi_unwrap_subview_col_htrans(const Op, op_htrans>& A) : orig(A.m.m) @@ -813,6 +847,7 @@ template struct quasi_unwrap< CubeToMatOp > { typedef typename T1::elem_type eT; + typedef Mat stored_type; inline quasi_unwrap(const CubeToMatOp& A) @@ -838,6 +873,8 @@ struct quasi_unwrap< CubeToMatOp > template struct quasi_unwrap< SpToDOp, op_sp_nonzeros> > { + typedef Mat stored_type; + inline quasi_unwrap(const SpToDOp, op_sp_nonzeros>& A) : orig( A.m ) From 50f2d530f7e6d97984cf8f1a9fd5c8521208bf4e Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Tue, 16 Jun 2026 22:09:33 -0500 Subject: [PATCH 2/2] RcppArmadillo 15.3.91-1 --- ChangeLog | 9 +++++++++ DESCRIPTION | 4 ++-- configure | 18 +++++++++--------- configure.ac | 2 +- inst/NEWS.Rd | 15 +++++++++++++++ 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2dbf1cc7..e75da9c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2026-06-16 Dirk Eddelbuettel + + * DESCRIPTION (Version, Date): RcppArmadillo 15.3.91-1 + * inst/NEWS.Rd: Idem + * configure.ac: Idem + * configure: Idem + + * inst/include/armadillo*: Armadillo 15.3.91 aka 15.4-rc1 + 2026-05-29 Dirk Eddelbuettel * DESCRIPTION (Version, Date): RcppArmadillo 15.2.7-1 diff --git a/DESCRIPTION b/DESCRIPTION index 8ac2294d..67d201e7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: RcppArmadillo Type: Package Title: 'Rcpp' Integration for the 'Armadillo' Templated Linear Algebra Library -Version: 15.2.7-1 -Date: 2026-05-29 +Version: 15.3.91-1 +Date: 2026-06-16 Authors@R: c(person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org", comment = c(ORCID = "0000-0001-6419-907X")), person("Romain", "Francois", role = "aut", diff --git a/configure b/configure index c83e0ab7..874e87f7 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for RcppArmadillo 15.2.7-1. +# Generated by GNU Autoconf 2.72 for RcppArmadillo 15.3.91-1. # # Report bugs to . # @@ -603,8 +603,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='RcppArmadillo' PACKAGE_TARNAME='rcpparmadillo' -PACKAGE_VERSION='15.2.7-1' -PACKAGE_STRING='RcppArmadillo 15.2.7-1' +PACKAGE_VERSION='15.3.91-1' +PACKAGE_STRING='RcppArmadillo 15.3.91-1' PACKAGE_BUGREPORT='edd@debian.org' PACKAGE_URL='' @@ -1223,7 +1223,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures RcppArmadillo 15.2.7-1 to adapt to many kinds of systems. +'configure' configures RcppArmadillo 15.3.91-1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1285,7 +1285,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of RcppArmadillo 15.2.7-1:";; + short | recursive ) echo "Configuration of RcppArmadillo 15.3.91-1:";; esac cat <<\_ACEOF @@ -1366,7 +1366,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -RcppArmadillo configure 15.2.7-1 +RcppArmadillo configure 15.3.91-1 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1482,7 +1482,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by RcppArmadillo $as_me 15.2.7-1, which was +It was created by RcppArmadillo $as_me 15.3.91-1, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3946,7 +3946,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by RcppArmadillo $as_me 15.2.7-1, which was +This file was extended by RcppArmadillo $as_me 15.3.91-1, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4001,7 +4001,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -RcppArmadillo config.status 15.2.7-1 +RcppArmadillo config.status 15.3.91-1 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index e6d1d8b4..20691775 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ AC_PREREQ([2.69]) ## Process this file with autoconf to produce a configure script. -AC_INIT([RcppArmadillo],[15.2.7-1],[edd@debian.org]) +AC_INIT([RcppArmadillo],[15.3.91-1],[edd@debian.org]) ## Set R_HOME, respecting an environment variable if one is set : ${R_HOME=$(R RHOME)} diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 8745b32b..0785dd1a 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -3,6 +3,21 @@ \newcommand{\ghpr}{\href{https://github.com/RcppCore/RcppArmadillo/pull/#1}{##1}} \newcommand{\ghit}{\href{https://github.com/RcppCore/RcppArmadillo/issues/#1}{##1}} +\section{Changes in RcppArmadillo version 15.3.91-1 (2026-06-19)}{ + \itemize{ + \item Upgraded to Armadillo release 15.3.91 (15.4-rc1) + \itemize{ + \item Added \code{fill::nan}, \code{fill::pos_inf}, + \code{fill::neg_inf} as optional fill forms for the Mat class + \item Added \code{.push_back()} for appending elements to vectors + \item Faster handling of \code{find()} within \code{.elem()} + \item Faster element-wise \code{min()} and \code{max()} + \item Faster \code{conv_to} when element types of input and output + objects are the same + } + } +} + \section{Changes in RcppArmadillo version 15.2.7-1 (2026-05-29)}{ \itemize{ \item Upgraded to Armadillo release 15.2.7 (Medium Roast Deluxe)