use Proxy for compound expressions

This commit is contained in:
conrad
2025-08-20 13:17:57 +10:00
parent 9e1a000e4b
commit 9d5cfe2016
2 changed files with 55 additions and 10 deletions
+3 -1
View File
@@ -90,8 +90,10 @@ struct op_eps
inline static void apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_eps>& in);
template<typename T, typename eT>
inline static void apply_noalias(Mat<T>& out, const Mat<eT>& X);
inline static void apply_mat_noalias(Mat<T>& out, const Mat<eT>& X);
template<typename T, typename T1>
inline static void apply_proxy_noalias(Mat<T>& out, const Proxy<T1>& P);
//
template<typename T1>
+52 -9
View File
@@ -490,19 +490,39 @@ op_eps::apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type,
typedef typename T1::pod_type T;
const quasi_unwrap<T1> U(in.m);
if(U.is_alias(out))
if(Proxy<T1>::use_at || is_Mat<T1>::value || is_subview_col<T1>::value || is_Mat<typename Proxy<T1>::stored_type>::value || (arma_config::openmp && Proxy<T1>::use_mp))
{
Mat<T> tmp;
const quasi_unwrap<T1> U(in.m);
op_eps::apply_noalias(tmp, U.M);
out.steal_mem(tmp);
if(U.is_alias(out))
{
Mat<T> 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<T1> P(in.m);
if(P.is_alias(out))
{
Mat<T> 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<typename T1::pod_type>& out, const mtOp<typename T1::pod_type,
template<typename T, typename eT>
inline
void
op_eps::apply_noalias(Mat<T>& out, const Mat<eT>& X)
op_eps::apply_mat_noalias(Mat<T>& out, const Mat<eT>& X)
{
arma_debug_sigprint();
@@ -530,6 +550,29 @@ op_eps::apply_noalias(Mat<T>& out, const Mat<eT>& X)
template<typename T, typename T1>
inline
void
op_eps::apply_proxy_noalias(Mat<T>& out, const Proxy<T1>& P)
{
arma_debug_sigprint();
out.set_size(P.get_n_rows(), P.get_n_cols());
T* out_mem = out.memptr();
typename Proxy<T1>::ea_type Pea = P.get_ea();
const uword n_elem = P.get_n_elem();
for(uword i=0; i<n_elem; ++i)
{
out_mem[i] = op_eps::direct_eps( Pea[i] );
}
}
template<typename T1>
inline
void