expanded pow() to handle subview_each1
This commit is contained in:
@@ -65,11 +65,42 @@ pow
|
||||
|
||||
|
||||
|
||||
// TODO: mat = pow(mat.each_col(), mat) (no promotion)
|
||||
// TODO: mat = pow(mat.each_row(), mat) (no promotion)
|
||||
template<typename parent, unsigned int mode, typename T2>
|
||||
arma_warn_unused
|
||||
inline
|
||||
Mat<typename parent::elem_type>
|
||||
pow
|
||||
(
|
||||
const subview_each1<parent,mode>& X,
|
||||
const Base<typename parent::elem_type,T2>& Y
|
||||
)
|
||||
{
|
||||
arma_extra_debug_sigprint();
|
||||
|
||||
return glue_powext::apply(X,Y);
|
||||
}
|
||||
|
||||
// TODO: cx_mat = pow(cx_mat.each_col(), mat) (promotion)
|
||||
// TODO: cx_mat = pow(cx_mat.each_row(), mat) (promotion)
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2>
|
||||
arma_warn_unused
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
( is_cx<typename parent::elem_type>::yes && is_same_type<typename parent::pod_type, typename T2::elem_type>::yes ),
|
||||
Mat<typename parent::elem_type>
|
||||
>::result
|
||||
pow
|
||||
(
|
||||
const subview_each1<parent,mode>& X,
|
||||
const Base<typename T2::elem_type,T2>& Y
|
||||
)
|
||||
{
|
||||
arma_extra_debug_sigprint();
|
||||
|
||||
return glue_powext_cx::apply(X,Y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ class glue_powext
|
||||
template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_powext>& X);
|
||||
|
||||
template<typename eT> inline static void apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B);
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2> inline static Mat<typename parent::elem_type> apply(const subview_each1<parent,mode>& X, const Base<typename parent::elem_type,T2>& Y);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -43,6 +46,8 @@ class glue_powext_cx
|
||||
template<typename T1, typename T2> inline static void apply(Mat<typename T1::elem_type>& out, const mtGlue<typename T1::elem_type,T1,T2,glue_powext_cx>& X);
|
||||
|
||||
template<typename T> inline static void apply(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat<T>& B);
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2> inline static Mat<typename parent::elem_type> apply(const subview_each1<parent,mode>& X, const Base<typename T2::elem_type,T2>& Y);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -83,6 +83,70 @@ glue_powext::apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B)
|
||||
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2>
|
||||
inline
|
||||
Mat<typename parent::elem_type>
|
||||
glue_powext::apply
|
||||
(
|
||||
const subview_each1<parent,mode>& X,
|
||||
const Base<typename parent::elem_type,T2>& Y
|
||||
)
|
||||
{
|
||||
arma_extra_debug_sigprint();
|
||||
|
||||
typedef typename parent::elem_type eT;
|
||||
|
||||
const parent& A = X.P;
|
||||
|
||||
const uword A_n_rows = A.n_rows;
|
||||
const uword A_n_cols = A.n_cols;
|
||||
|
||||
Mat<eT> out(A_n_rows, A_n_cols, arma_nozeros_indicator());
|
||||
|
||||
const quasi_unwrap<T2> tmp(Y.get_ref());
|
||||
const Mat<eT>& B = tmp.M;
|
||||
|
||||
X.check_size(B);
|
||||
|
||||
// TODO: investigate use of openmp
|
||||
|
||||
const eT* B_mem = B.memptr();
|
||||
|
||||
if(mode == 0) // each column
|
||||
{
|
||||
for(uword i=0; i < A_n_cols; ++i)
|
||||
{
|
||||
const eT* A_mem = A.colptr(i);
|
||||
eT* out_mem = out.colptr(i);
|
||||
|
||||
for(uword row=0; row < A_n_rows; ++row)
|
||||
{
|
||||
out_mem[row] = eop_aux::pow(A_mem[row], B_mem[row]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mode == 1) // each row
|
||||
{
|
||||
for(uword i=0; i < A_n_cols; ++i)
|
||||
{
|
||||
const eT* A_mem = A.colptr(i);
|
||||
eT* out_mem = out.colptr(i);
|
||||
|
||||
const eT B_val = B_mem[i];
|
||||
|
||||
for(uword row=0; row < A_n_rows; ++row)
|
||||
{
|
||||
out_mem[row] = eop_aux::pow(A_mem[row], B_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
@@ -148,4 +212,69 @@ glue_powext_cx::apply(Mat< std::complex<T> >& out, const Mat< std::complex<T> >&
|
||||
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2>
|
||||
inline
|
||||
Mat<typename parent::elem_type>
|
||||
glue_powext_cx::apply
|
||||
(
|
||||
const subview_each1<parent,mode>& X,
|
||||
const Base<typename T2::elem_type,T2>& Y
|
||||
)
|
||||
{
|
||||
arma_extra_debug_sigprint();
|
||||
|
||||
typedef typename parent::elem_type eT;
|
||||
typedef typename parent::pod_type T;
|
||||
|
||||
const parent& A = X.P;
|
||||
|
||||
const uword A_n_rows = A.n_rows;
|
||||
const uword A_n_cols = A.n_cols;
|
||||
|
||||
Mat<eT> out(A_n_rows, A_n_cols, arma_nozeros_indicator());
|
||||
|
||||
const quasi_unwrap<T2> tmp(Y.get_ref());
|
||||
const Mat<T>& B = tmp.M;
|
||||
|
||||
X.check_size(B);
|
||||
|
||||
// TODO: investigate use of openmp
|
||||
|
||||
const T* B_mem = B.memptr();
|
||||
|
||||
if(mode == 0) // each column
|
||||
{
|
||||
for(uword i=0; i < A_n_cols; ++i)
|
||||
{
|
||||
const eT* A_mem = A.colptr(i);
|
||||
eT* out_mem = out.colptr(i);
|
||||
|
||||
for(uword row=0; row < A_n_rows; ++row)
|
||||
{
|
||||
out_mem[row] = std::pow(A_mem[row], B_mem[row]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mode == 1) // each row
|
||||
{
|
||||
for(uword i=0; i < A_n_cols; ++i)
|
||||
{
|
||||
const eT* A_mem = A.colptr(i);
|
||||
eT* out_mem = out.colptr(i);
|
||||
|
||||
const eT B_val = B_mem[i];
|
||||
|
||||
for(uword row=0; row < A_n_rows; ++row)
|
||||
{
|
||||
out_mem[row] = std::pow(A_mem[row], B_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -30,7 +30,8 @@ class subview_each_common
|
||||
|
||||
const parent& P;
|
||||
|
||||
inline void check_size(const Mat<typename parent::elem_type>& A) const;
|
||||
template<typename eT2>
|
||||
inline void check_size(const Mat<eT2>& A) const;
|
||||
|
||||
|
||||
protected:
|
||||
@@ -43,7 +44,8 @@ class subview_each_common
|
||||
|
||||
arma_inline const Mat<typename parent::elem_type>& get_mat_ref() const;
|
||||
|
||||
arma_cold inline const std::string incompat_size_string(const Mat<typename parent::elem_type>& A) const;
|
||||
template<typename eT2>
|
||||
arma_cold inline const std::string incompat_size_string(const Mat<eT2>& A) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -65,11 +65,12 @@ subview_each_common<parent,mode>::get_mat_ref() const
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode>
|
||||
template<typename eT2>
|
||||
inline
|
||||
void
|
||||
subview_each_common<parent,mode>::check_size(const Mat<typename parent::elem_type>& A) const
|
||||
subview_each_common<parent,mode>::check_size(const Mat<eT2>& A) const
|
||||
{
|
||||
if(arma_config::debug == true)
|
||||
if(arma_config::debug)
|
||||
{
|
||||
if(mode == 0)
|
||||
{
|
||||
@@ -91,10 +92,11 @@ subview_each_common<parent,mode>::check_size(const Mat<typename parent::elem_typ
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode>
|
||||
template<typename eT2>
|
||||
arma_cold
|
||||
inline
|
||||
const std::string
|
||||
subview_each_common<parent,mode>::incompat_size_string(const Mat<typename parent::elem_type>& A) const
|
||||
subview_each_common<parent,mode>::incompat_size_string(const Mat<eT2>& A) const
|
||||
{
|
||||
std::ostringstream tmp;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user