diff --git a/include/armadillo_bits/op_all_bones.hpp b/include/armadillo_bits/op_all_bones.hpp index b8faf9a2..6ebea6ba 100644 --- a/include/armadillo_bits/op_all_bones.hpp +++ b/include/armadillo_bits/op_all_bones.hpp @@ -68,9 +68,11 @@ class op_all static inline bool all_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_all_meat.hpp b/include/armadillo_bits/op_all_meat.hpp index 185d4eec..a7503e46 100644 --- a/include/armadillo_bits/op_all_meat.hpp +++ b/include/armadillo_bits/op_all_meat.hpp @@ -277,17 +277,15 @@ op_all::all_vec(T1& X) -template +template inline void -op_all::apply_helper(Mat& out, const Proxy& P, const uword dim) +op_all::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) { @@ -297,37 +295,18 @@ op_all::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) + uword count = 0; + + for(uword row=0; row < n_rows; ++row) { - const eT* colmem = U.M.colptr(col); - - uword count = 0; - - for(uword row=0; row < n_rows; ++row) - { - count += (colmem[row] != eT(0)) ? uword(1) : uword(0); - } - - out_mem[col] = (n_rows == count) ? uword(1) : uword(0); - } - } - else - { - for(uword col=0; col < n_cols; ++col) - { - uword count = 0; - - for(uword row=0; row < n_rows; ++row) - { - if(P.at(row,col) != eT(0)) { ++count; } - } - - out_mem[col] = (n_rows == count) ? uword(1) : uword(0); + count += (colmem[row] != eT(0)) ? uword(1) : uword(0); } + + out_mem[col] = (n_rows == count) ? uword(1) : uword(0); } } else @@ -338,31 +317,15 @@ op_all::apply_helper(Mat& out, const Proxy& P, const uword dim) // internal dual use of 'out': keep the counts for each row - 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) - { - out_mem[row] += (colmem[row] != eT(0)) ? uword(1) : uword(0); - } + out_mem[row] += (colmem[row] != eT(0)) ? uword(1) : uword(0); } } - 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[row]; } - } - } - } - // see what the counts tell us @@ -370,7 +333,63 @@ op_all::apply_helper(Mat& out, const Proxy& P, const uword dim) { out_mem[row] = (n_cols == out_mem[row]) ? uword(1) : uword(0); } + } + } + + + +template +inline +void +op_all::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); + if(out.n_elem == 0) { return; } + + uword* out_mem = out.memptr(); + + for(uword col=0; col < n_cols; ++col) + { + uword count = 0; + + for(uword row=0; row < n_rows; ++row) + { + if(P.at(row,col) != eT(0)) { ++count; } + } + + out_mem[col] = (n_rows == count) ? uword(1) : uword(0); + } + } + else + { + out.zeros(n_rows, 1); + + uword* out_mem = out.memptr(); + + // internal dual use of 'out': keep the counts for each row + + 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]; } + } + + // see what the counts tell us + + for(uword row=0; row < n_rows; ++row) + { + out_mem[row] = (n_cols == out_mem[row]) ? uword(1) : uword(0); + } } } @@ -385,19 +404,39 @@ op_all::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_all::apply_helper(out, P, dim); + const quasi_unwrap U(X.m); + + if(U.is_alias(out) == false) + { + op_all::apply_mat_noalias(out, U.M, dim); + } + else + { + Mat tmp; + + op_all::apply_mat_noalias(tmp, U.M, dim); + + out.steal_mem(tmp); + } } else { - Mat out2; + const Proxy P(X.m); - op_all::apply_helper(out2, P, dim); - - out.steal_mem(out2); + if(P.is_alias(out) == false) + { + op_all::apply_proxy_noalias(out, P, dim); + } + else + { + Mat tmp; + + op_all::apply_proxy_noalias(tmp, P, dim); + + out.steal_mem(tmp); + } } }