diff --git a/include/armadillo_bits/op_misc_bones.hpp b/include/armadillo_bits/op_misc_bones.hpp index 354096ca..21106ccc 100644 --- a/include/armadillo_bits/op_misc_bones.hpp +++ b/include/armadillo_bits/op_misc_bones.hpp @@ -90,8 +90,10 @@ struct op_eps inline static void apply(Mat& out, const mtOp& in); template - inline static void apply_noalias(Mat& out, const Mat& X); + inline static void apply_mat_noalias(Mat& out, const Mat& X); + template + inline static void apply_proxy_noalias(Mat& out, const Proxy& P); // template diff --git a/include/armadillo_bits/op_misc_meat.hpp b/include/armadillo_bits/op_misc_meat.hpp index 6e186e2d..0ba9f8bd 100644 --- a/include/armadillo_bits/op_misc_meat.hpp +++ b/include/armadillo_bits/op_misc_meat.hpp @@ -490,19 +490,39 @@ op_eps::apply(Mat& out, const mtOp U(in.m); - - if(U.is_alias(out)) + if(Proxy::use_at || is_Mat::value || is_subview_col::value || is_Mat::stored_type>::value || (arma_config::openmp && Proxy::use_mp)) { - Mat tmp; + const quasi_unwrap U(in.m); - op_eps::apply_noalias(tmp, U.M); - - out.steal_mem(tmp); + if(U.is_alias(out)) + { + Mat tmp; + + op_eps::apply_mat_noalias(tmp, U.M); + + out.steal_mem(tmp); + } + else + { + op_eps::apply_mat_noalias(out, U.M); + } } else { - op_eps::apply_noalias(out, U.M); + const Proxy P(in.m); + + if(P.is_alias(out)) + { + Mat tmp; + + op_eps::apply_proxy_noalias(tmp, P); + + out.steal_mem(tmp); + } + else + { + op_eps::apply_proxy_noalias(out, P); + } } } @@ -511,7 +531,7 @@ op_eps::apply(Mat& out, const mtOp inline void -op_eps::apply_noalias(Mat& out, const Mat& X) +op_eps::apply_mat_noalias(Mat& out, const Mat& X) { arma_debug_sigprint(); @@ -530,6 +550,29 @@ op_eps::apply_noalias(Mat& out, const Mat& X) +template +inline +void +op_eps::apply_proxy_noalias(Mat& out, const Proxy& P) + { + arma_debug_sigprint(); + + out.set_size(P.get_n_rows(), P.get_n_cols()); + + T* out_mem = out.memptr(); + + typename Proxy::ea_type Pea = P.get_ea(); + + const uword n_elem = P.get_n_elem(); + + for(uword i=0; i inline void