diff --git a/include/armadillo_bits/op_any_bones.hpp b/include/armadillo_bits/op_any_bones.hpp index ffb197bd..6156dd48 100644 --- a/include/armadillo_bits/op_any_bones.hpp +++ b/include/armadillo_bits/op_any_bones.hpp @@ -68,9 +68,11 @@ class op_any static inline bool any_vec(T1& X); - template - static inline void apply_helper(Mat& out, const Proxy& P, const uword dim); + template + static inline void apply_mat_noalias(Mat& out, const Mat& X, const uword dim); + template + static inline void apply_proxy_noalias(Mat& out, const Proxy& P, const uword dim); template static inline void apply(Mat& out, const mtOp& X); diff --git a/include/armadillo_bits/op_any_meat.hpp b/include/armadillo_bits/op_any_meat.hpp index 3d5ff8aa..6e769b76 100644 --- a/include/armadillo_bits/op_any_meat.hpp +++ b/include/armadillo_bits/op_any_meat.hpp @@ -269,17 +269,15 @@ op_any::any_vec(T1& X) -template +template inline void -op_any::apply_helper(Mat& out, const Proxy& P, const uword dim) +op_any::apply_mat_noalias(Mat& out, const Mat& X, const uword dim) { arma_debug_sigprint(); - const uword n_rows = P.get_n_rows(); - const uword n_cols = P.get_n_cols(); - - typedef typename Proxy::elem_type eT; + const uword n_rows = X.n_rows; + const uword n_cols = X.n_cols; if(dim == 0) // traverse rows (ie. process each column) { @@ -287,28 +285,13 @@ op_any::apply_helper(Mat& out, const Proxy& P, const uword dim) uword* out_mem = out.memptr(); - if(is_Mat::stored_type>::value) + for(uword col=0; col < n_cols; ++col) { - const unwrap::stored_type> U(P.Q); + const eT* colmem = X.colptr(col); - for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) { - const eT* colmem = U.M.colptr(col); - - for(uword row=0; row < n_rows; ++row) - { - if(colmem[row] != eT(0)) { out_mem[col] = uword(1); break; } - } - } - } - else - { - for(uword col=0; col < n_cols; ++col) - { - for(uword row=0; row < n_rows; ++row) - { - if(P.at(row,col) != eT(0)) { out_mem[col] = uword(1); break; } - } + if(colmem[row] != eT(0)) { out_mem[col] = uword(1); break; } } } } @@ -318,28 +301,57 @@ op_any::apply_helper(Mat& out, const Proxy& P, const uword dim) uword* out_mem = out.memptr(); - if(is_Mat::stored_type>::value) + for(uword col=0; col < n_cols; ++col) { - const unwrap::stored_type> U(P.Q); + const eT* colmem = X.colptr(col); - for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) { - const eT* colmem = U.M.colptr(col); - - for(uword row=0; row < n_rows; ++row) - { - if(colmem[row] != eT(0)) { out_mem[row] = uword(1); } - } + if(colmem[row] != eT(0)) { out_mem[row] = uword(1); } } } - else + } + } + + + +template +inline +void +op_any::apply_proxy_noalias(Mat& out, const Proxy& P, const uword dim) + { + arma_debug_sigprint(); + + typedef typename Proxy::elem_type eT; + + const uword n_rows = P.get_n_rows(); + const uword n_cols = P.get_n_cols(); + + if(dim == 0) // traverse rows (ie. process each column) + { + out.zeros(1, n_cols); + + uword* out_mem = out.memptr(); + + for(uword col=0; col < n_cols; ++col) { - for(uword col=0; col < n_cols; ++col) + for(uword row=0; row < n_rows; ++row) { - for(uword row=0; row < n_rows; ++row) - { - if(P.at(row,col) != eT(0)) { out_mem[row] = uword(1); } - } + if(P.at(row,col) != eT(0)) { out_mem[col] = uword(1); break; } + } + } + } + else + { + out.zeros(n_rows, 1); + + uword* out_mem = out.memptr(); + + for(uword col=0; col < n_cols; ++col) + { + for(uword row=0; row < n_rows; ++row) + { + if(P.at(row,col) != eT(0)) { out_mem[row] = uword(1); } } } } @@ -356,19 +368,39 @@ op_any::apply(Mat& out, const mtOp& X) const uword dim = X.aux_uword_a; - const Proxy P(X.m); - - if(P.is_alias(out) == false) + if( (is_Mat::value) || (is_Mat::stored_type>::value) || (arma_config::openmp && Proxy::use_mp) ) { - op_any::apply_helper(out, P, dim); + const quasi_unwrap U(X.m); + + if(U.is_alias(out) == false) + { + op_any::apply_mat_noalias(out, U.M, dim); + } + else + { + Mat tmp; + + op_any::apply_mat_noalias(tmp, U.M, dim); + + out.steal_mem(tmp); + } } else { - Mat out2; + const Proxy P(X.m); - op_any::apply_helper(out2, P, dim); - - out.steal_mem(out2); + if(P.is_alias(out) == false) + { + op_any::apply_proxy_noalias(out, P, dim); + } + else + { + Mat tmp; + + op_any::apply_proxy_noalias(tmp, P, dim); + + out.steal_mem(tmp); + } } }