inline bool op_all::all_vec_helper(const Base<typename T1::elem_type, T1>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const Proxy<T1> P(X.get_ref()); const uword n_elem = P.get_n_elem(); uword count = 0; if(Proxy<T1>::prefer_at_accessor == false) { typename Proxy<T1>::ea_type Pea = P.get_ea(); for(uword i=0; i<n_elem; ++i) { if(Pea[i] != eT(0)) { ++count; } } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { if(P.at(row,col) != eT(0)) { ++count; } } } // NOTE: for empty vectors it makes more sense to return false, but we need to return true for compatability with Octave return (n_elem == count); }
inline void glue_min::apply(Mat<eT>& out, const Proxy<T1>& PA, const Proxy<T2>& PB) { arma_extra_debug_sigprint(); const uword n_rows = PA.get_n_rows(); const uword n_cols = PA.get_n_cols(); arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise minimum"); out.set_size(n_rows, n_cols); eT* out_mem = out.memptr(); if( (Proxy<T1>::use_at == false) && (Proxy<T2>::use_at == false) ) { typename Proxy<T1>::ea_type A = PA.get_ea(); typename Proxy<T2>::ea_type B = PB.get_ea(); const uword N = PA.get_n_elem(); for(uword i=0; i<N; ++i) { out_mem[i] = (std::min)(A[i], B[i]); } } else { for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { *out_mem = (std::min)( PA.at(row,col), PB.at(row,col) ); ++out_mem; } } }
arma_hot inline typename arma_cx_only<typename T1::elem_type>::result op_dot::apply_proxy(const Proxy<T1>& PA, const Proxy<T2>& PB) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; typedef typename get_pod_type<eT>::result T; typedef typename Proxy<T1>::ea_type ea_type1; typedef typename Proxy<T2>::ea_type ea_type2; const uword N = PA.get_n_elem(); ea_type1 A = PA.get_ea(); ea_type2 B = PB.get_ea(); T val_real = T(0); T val_imag = T(0); for(uword i=0; i<N; ++i) { const std::complex<T> xx = A[i]; const std::complex<T> yy = B[i]; const T a = xx.real(); const T b = xx.imag(); const T c = yy.real(); const T d = yy.imag(); val_real += (a*c) - (b*d); val_imag += (a*d) + (b*c); } return std::complex<T>(val_real, val_imag); }
inline typename arma_cx_only<typename T1::elem_type>::result op_min::min(const Base<typename T1::elem_type,T1>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; typedef typename get_pod_type<eT>::result T; const Proxy<T1> P(X.get_ref()); const uword n_elem = P.get_n_elem(); arma_debug_check( (n_elem == 0), "min(): given object has no elements" ); T min_val = priv::most_pos<T>(); if(Proxy<T1>::prefer_at_accessor == false) { typedef typename Proxy<T1>::ea_type ea_type; ea_type A = P.get_ea(); uword index = 0; for(uword i=0; i<n_elem; ++i) { const T tmp = std::abs(A[i]); if(tmp < min_val) { min_val = tmp; index = i; } } return( A[index] ); } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); uword best_row = 0; uword best_col = 0; if(n_rows == 1) { for(uword col=0; col < n_cols; ++col) { const T tmp = std::abs(P.at(0,col)); if(tmp < min_val) { min_val = tmp; best_col = col; } } } else { for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const T tmp = std::abs(P.at(row,col)); if(tmp < min_val) { min_val = tmp; best_row = row; best_col = col; } } } return P.at(best_row, best_col); } }
inline uword op_find::helper ( Mat<uword>& indices, const mtOp<uword, T1, op_type>& X, const typename arma_op_rel_only<op_type>::result junk1, const typename arma_not_cx<typename T1::elem_type>::result junk2 ) { arma_extra_debug_sigprint(); arma_ignore(junk1); arma_ignore(junk2); typedef typename T1::elem_type eT; const eT val = X.aux; const Proxy<T1> A(X.m); const uword n_elem = A.get_n_elem(); indices.set_size(n_elem, 1); uword* indices_mem = indices.memptr(); uword n_nz = 0; if(Proxy<T1>::prefer_at_accessor == false) { typename Proxy<T1>::ea_type PA = A.get_ea(); uword i,j; for(i=0, j=1; j < n_elem; i+=2, j+=2) { const eT tpi = PA[i]; const eT tpj = PA[j]; bool not_zero_i; bool not_zero_j; if(is_same_type<op_type, op_rel_lt_pre >::value == true) { not_zero_i = (val < tpi); } else if(is_same_type<op_type, op_rel_lt_post >::value == true) { not_zero_i = (tpi < val); } else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { not_zero_i = (val > tpi); } else if(is_same_type<op_type, op_rel_gt_post >::value == true) { not_zero_i = (tpi > val); } else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { not_zero_i = (val <= tpi); } else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { not_zero_i = (tpi <= val); } else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { not_zero_i = (val >= tpi); } else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { not_zero_i = (tpi >= val); } else if(is_same_type<op_type, op_rel_eq >::value == true) { not_zero_i = (tpi == val); } else if(is_same_type<op_type, op_rel_noteq >::value == true) { not_zero_i = (tpi != val); } else not_zero_i = false; if(is_same_type<op_type, op_rel_lt_pre >::value == true) { not_zero_j = (val < tpj); } else if(is_same_type<op_type, op_rel_lt_post >::value == true) { not_zero_j = (tpj < val); } else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { not_zero_j = (val > tpj); } else if(is_same_type<op_type, op_rel_gt_post >::value == true) { not_zero_j = (tpj > val); } else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { not_zero_j = (val <= tpj); } else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { not_zero_j = (tpj <= val); } else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { not_zero_j = (val >= tpj); } else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { not_zero_j = (tpj >= val); } else if(is_same_type<op_type, op_rel_eq >::value == true) { not_zero_j = (tpj == val); } else if(is_same_type<op_type, op_rel_noteq >::value == true) { not_zero_j = (tpj != val); } else not_zero_j = false; if(not_zero_i == true) { indices_mem[n_nz] = i; ++n_nz; } if(not_zero_j == true) { indices_mem[n_nz] = j; ++n_nz; } } if(i < n_elem) { bool not_zero; const eT tmp = PA[i]; if(is_same_type<op_type, op_rel_lt_pre >::value == true) { not_zero = (val < tmp); } else if(is_same_type<op_type, op_rel_lt_post >::value == true) { not_zero = (tmp < val); } else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { not_zero = (val > tmp); } else if(is_same_type<op_type, op_rel_gt_post >::value == true) { not_zero = (tmp > val); } else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { not_zero = (val <= tmp); } else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { not_zero = (tmp <= val); } else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { not_zero = (val >= tmp); } else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { not_zero = (tmp >= val); } else if(is_same_type<op_type, op_rel_eq >::value == true) { not_zero = (tmp == val); } else if(is_same_type<op_type, op_rel_noteq >::value == true) { not_zero = (tmp != val); } else not_zero = false; if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } } } else { const uword n_rows = A.get_n_rows(); const uword n_cols = A.get_n_cols(); uword i = 0; for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT tmp = A.at(row,col); bool not_zero; if(is_same_type<op_type, op_rel_lt_pre >::value == true) { not_zero = (val < tmp); } else if(is_same_type<op_type, op_rel_lt_post >::value == true) { not_zero = (tmp < val); } else if(is_same_type<op_type, op_rel_gt_pre >::value == true) { not_zero = (val > tmp); } else if(is_same_type<op_type, op_rel_gt_post >::value == true) { not_zero = (tmp > val); } else if(is_same_type<op_type, op_rel_lteq_pre >::value == true) { not_zero = (val <= tmp); } else if(is_same_type<op_type, op_rel_lteq_post>::value == true) { not_zero = (tmp <= val); } else if(is_same_type<op_type, op_rel_gteq_pre >::value == true) { not_zero = (val >= tmp); } else if(is_same_type<op_type, op_rel_gteq_post>::value == true) { not_zero = (tmp >= val); } else if(is_same_type<op_type, op_rel_eq >::value == true) { not_zero = (tmp == val); } else if(is_same_type<op_type, op_rel_noteq >::value == true) { not_zero = (tmp != val); } else not_zero = false; if(not_zero == true) { indices_mem[n_nz] = i; ++n_nz; } ++i; } } return n_nz; }
inline void op_vectorise_col::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; if(P.is_alias(out) == false) { const uword N = P.get_n_elem(); out.set_size(N, 1); if(is_Mat<typename Proxy<T1>::stored_type>::value == true) { const unwrap<typename Proxy<T1>::stored_type> tmp(P.Q); arrayops::copy(out.memptr(), tmp.M.memptr(), N); } else { eT* outmem = out.memptr(); if(Proxy<T1>::use_at == false) { // TODO: add handling of aligned access ? typename Proxy<T1>::ea_type A = P.get_ea(); uword i,j; for(i=0, j=1; j < N; i+=2, j+=2) { const eT tmp_i = A[i]; const eT tmp_j = A[j]; outmem[i] = tmp_i; outmem[j] = tmp_j; } if(i < N) { outmem[i] = A[i]; } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { for(uword i=0; i < n_cols; ++i) { outmem[i] = P.at(0,i); } } else { for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { *outmem = P.at(row,col); outmem++; } } } } } else // we have aliasing { arma_extra_debug_print("op_vectorise_col::apply(): aliasing detected"); if( (is_Mat<typename Proxy<T1>::stored_type>::value == true) && (Proxy<T1>::fake_mat == false) ) { out.set_size(out.n_elem, 1); // set_size() doesn't destroy data as long as the number of elements in the matrix remains the same } else { Mat<eT> tmp; op_vectorise_col::apply_proxy(tmp, P); out.steal_mem(tmp); } } }
arma_hot inline typename T1::pod_type op_norm::vec_norm_2(const Proxy<T1>& P, const typename arma_cx_only<typename T1::elem_type>::result* junk) { arma_extra_debug_sigprint(); arma_ignore(junk); typedef typename T1::elem_type eT; typedef typename T1::pod_type T; T acc = T(0); if(Proxy<T1>::use_at == false) { typename Proxy<T1>::ea_type A = P.get_ea(); const uword N = P.get_n_elem(); for(uword i=0; i<N; ++i) { const std::complex<T>& X = A[i]; const T a = X.real(); const T b = X.imag(); acc += (a*a) + (b*b); } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { for(uword col=0; col<n_cols; ++col) { const std::complex<T>& X = P.at(0,col); const T a = X.real(); const T b = X.imag(); acc += (a*a) + (b*b); } } else { for(uword col=0; col<n_cols; ++col) for(uword row=0; row<n_rows; ++row) { const std::complex<T>& X = P.at(row,col); const T a = X.real(); const T b = X.imag(); acc += (a*a) + (b*b); } } } const T sqrt_acc = std::sqrt(acc); if( (sqrt_acc != T(0)) && arma_isfinite(sqrt_acc) ) { return sqrt_acc; } else { arma_extra_debug_print("op_norm::vec_norm_2(): detected possible underflow or overflow"); const quasi_unwrap<typename Proxy<T1>::stored_type> R(P.Q); const uword N = R.M.n_elem; const eT* R_mem = R.M.memptr(); T max_val = priv::most_neg<T>(); for(uword i=0; i<N; ++i) { const T val_i = std::abs(R_mem[i]); if(val_i > max_val) { max_val = val_i; } } if(max_val == T(0)) { return T(0); } T alt_acc = T(0); for(uword i=0; i<N; ++i) { const T val_i = std::abs(R_mem[i]) / max_val; alt_acc += val_i * val_i; } return ( std::sqrt(alt_acc) * max_val ); } }
arma_hot inline typename T1::pod_type op_norm::vec_norm_1(const Proxy<T1>& P, const typename arma_not_cx<typename T1::elem_type>::result* junk) { arma_extra_debug_sigprint(); arma_ignore(junk); const bool have_direct_mem = (is_Mat<typename Proxy<T1>::stored_type>::value) || (is_subview_col<typename Proxy<T1>::stored_type>::value); if(have_direct_mem) { const quasi_unwrap<typename Proxy<T1>::stored_type> tmp(P.Q); return op_norm::vec_norm_1_direct_std(tmp.M); } typedef typename T1::pod_type T; T acc = T(0); if(Proxy<T1>::use_at == false) { typename Proxy<T1>::ea_type A = P.get_ea(); const uword N = P.get_n_elem(); T acc1 = T(0); T acc2 = T(0); uword i,j; for(i=0, j=1; j<N; i+=2, j+=2) { acc1 += std::abs(A[i]); acc2 += std::abs(A[j]); } if(i < N) { acc1 += std::abs(A[i]); } acc = acc1 + acc2; } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { for(uword col=0; col<n_cols; ++col) { acc += std::abs(P.at(0,col)); } } else { T acc1 = T(0); T acc2 = T(0); for(uword col=0; col<n_cols; ++col) { uword i,j; for(i=0, j=1; j<n_rows; i+=2, j+=2) { acc1 += std::abs(P.at(i,col)); acc2 += std::abs(P.at(j,col)); } if(i < n_rows) { acc1 += std::abs(P.at(i,col)); } } acc = acc1 + acc2; } } return acc; }
inline void op_fft_real::apply( Mat< std::complex<typename T1::pod_type> >& out, const mtOp<std::complex<typename T1::pod_type>,T1,op_fft_real>& in ) { arma_extra_debug_sigprint(); typedef typename T1::pod_type in_eT; typedef typename std::complex<in_eT> out_eT; const Proxy<T1> P(in.m); const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); const uword n_elem = P.get_n_elem(); const bool is_vec = ( (n_rows == 1) || (n_cols == 1) ); const uword N_orig = (is_vec) ? n_elem : n_rows; const uword N_user = (in.aux_uword_b == 0) ? in.aux_uword_a : N_orig; fft_engine<out_eT,false> worker(N_user); // no need to worry about aliasing, as we're going from a real object to complex complex, which by definition cannot alias if(is_vec) { (n_cols == 1) ? out.set_size(N_user, 1) : out.set_size(1, N_user); if( (out.n_elem == 0) || (N_orig == 0) ) { out.zeros(); return; } if( (N_user == 1) && (N_orig >= 1) ) { out[0] = out_eT( P[0] ); return; } podarray<out_eT> data(N_user); out_eT* data_mem = data.memptr(); if(N_user > N_orig) { arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); } const uword N = (std::min)(N_user, N_orig); if(Proxy<T1>::use_at == false) { typename Proxy<T1>::ea_type X = P.get_ea(); for(uword i=0; i < N; ++i) { data_mem[i] = out_eT( X[i], in_eT(0) ); } } else { if(n_cols == 1) { for(uword i=0; i < N; ++i) { data_mem[i] = out_eT( P.at(i,0), in_eT(0) ); } } else { for(uword i=0; i < N; ++i) { data_mem[i] = out_eT( P.at(0,i), in_eT(0) ); } } } worker.run( out.memptr(), data_mem ); } else { // process each column seperately out.set_size(N_user, n_cols); if( (out.n_elem == 0) || (N_orig == 0) ) { out.zeros(); return; } if( (N_user == 1) && (N_orig >= 1) ) { for(uword col=0; col < n_cols; ++col) { out.at(0,col) = out_eT( P.at(0,col) ); } return; } podarray<out_eT> data(N_user); out_eT* data_mem = data.memptr(); if(N_user > N_orig) { arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); } const uword N = (std::min)(N_user, N_orig); for(uword col=0; col < n_cols; ++col) { for(uword i=0; i < N; ++i) { data_mem[i] = P.at(i, col); } worker.run( out.colptr(col), data_mem ); } } }
inline bool op_any::any_vec_helper ( const mtOp<uword, T1, op_type>& X, const typename arma_op_rel_only<op_type>::result junk1, const typename arma_not_cx<typename T1::elem_type>::result junk2 ) { arma_extra_debug_sigprint(); arma_ignore(junk1); arma_ignore(junk2); typedef typename T1::elem_type eT; const eT val = X.aux; const Proxy<T1> P(X.m); if(Proxy<T1>::prefer_at_accessor == false) { 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) { const eT tmp = Pea[i]; if(is_same_type<op_type, op_rel_lt_pre >::yes) { if(val < tmp) { return true; } } else if(is_same_type<op_type, op_rel_lt_post >::yes) { if(tmp < val) { return true; } } else if(is_same_type<op_type, op_rel_gt_pre >::yes) { if(val > tmp) { return true; } } else if(is_same_type<op_type, op_rel_gt_post >::yes) { if(tmp > val) { return true; } } else if(is_same_type<op_type, op_rel_lteq_pre >::yes) { if(val <= tmp) { return true; } } else if(is_same_type<op_type, op_rel_lteq_post>::yes) { if(tmp <= val) { return true; } } else if(is_same_type<op_type, op_rel_gteq_pre >::yes) { if(val >= tmp) { return true; } } else if(is_same_type<op_type, op_rel_gteq_post>::yes) { if(tmp >= val) { return true; } } else if(is_same_type<op_type, op_rel_eq >::yes) { if(tmp == val) { return true; } } else if(is_same_type<op_type, op_rel_noteq >::yes) { if(tmp != val) { return true; } } } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT tmp = P.at(row,col); if(is_same_type<op_type, op_rel_lt_pre >::yes) { if(val < tmp) { return true; } } else if(is_same_type<op_type, op_rel_lt_post >::yes) { if(tmp < val) { return true; } } else if(is_same_type<op_type, op_rel_gt_pre >::yes) { if(val > tmp) { return true; } } else if(is_same_type<op_type, op_rel_gt_post >::yes) { if(tmp > val) { return true; } } else if(is_same_type<op_type, op_rel_lteq_pre >::yes) { if(val <= tmp) { return true; } } else if(is_same_type<op_type, op_rel_lteq_post>::yes) { if(tmp <= val) { return true; } } else if(is_same_type<op_type, op_rel_gteq_pre >::yes) { if(val >= tmp) { return true; } } else if(is_same_type<op_type, op_rel_gteq_post>::yes) { if(tmp >= val) { return true; } } else if(is_same_type<op_type, op_rel_eq >::yes) { if(tmp == val) { return true; } } else if(is_same_type<op_type, op_rel_noteq >::yes) { if(tmp != val) { return true; } } } } return false; }
inline void subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x) { arma_extra_debug_sigprint(); Mat<eT>& m_local = *m_ptr; eT* m_mem = m_local.memptr(); const u32 m_n_elem = m_local.n_elem; const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local); const umat& aa = tmp.M; arma_debug_check ( ( aa.is_vec() == false ), "Mat::elem(): given object is not a vector" ); const u32* aa_mem = aa.memptr(); const u32 aa_n_elem = aa.n_elem; const Proxy<T2> P(x.get_ref()); arma_debug_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" ); if(P.is_alias(m) == false) { typename Proxy<T2>::ea_type X = P.get_ea(); u32 i,j; for(i=0, j=1; j<aa_n_elem; i+=2, j+=2) { const u32 ii = aa_mem[i]; const u32 jj = aa_mem[j]; arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); if(is_same_type<op_type, op_subview_elem_equ >::value == true) { m_mem[ii] = X[i]; m_mem[jj] = X[j]; } else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; m_mem[jj] += X[j]; } else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; m_mem[jj] -= X[j]; } else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; m_mem[jj] *= X[j]; } else if(is_same_type<op_type, op_subview_elem_inplace_div >::value == true) { m_mem[ii] /= X[i]; m_mem[jj] /= X[j]; } } if(i < aa_n_elem) { const u32 ii = aa_mem[i]; arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); if(is_same_type<op_type, op_subview_elem_equ >::value == true) { m_mem[ii] = X[i]; } else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; } else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; } else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; } else if(is_same_type<op_type, op_subview_elem_inplace_div >::value == true) { m_mem[ii] /= X[i]; } } } else { arma_extra_debug_print("subview_elem1::inplace_op(): aliasing detected"); const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, m_local); const Mat<eT>& M = tmp.M; const eT* X = M.memptr(); u32 i,j; for(i=0, j=1; j<aa_n_elem; i+=2, j+=2) { const u32 ii = aa_mem[i]; const u32 jj = aa_mem[j]; arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); if(is_same_type<op_type, op_subview_elem_equ >::value == true) { m_mem[ii] = X[i]; m_mem[jj] = X[j]; } else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; m_mem[jj] += X[j]; } else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; m_mem[jj] -= X[j]; } else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; m_mem[jj] *= X[j]; } else if(is_same_type<op_type, op_subview_elem_inplace_div >::value == true) { m_mem[ii] /= X[i]; m_mem[jj] /= X[j]; } } if(i < aa_n_elem) { const u32 ii = aa_mem[i]; arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); if(is_same_type<op_type, op_subview_elem_equ >::value == true) { m_mem[ii] = X[i]; } else if(is_same_type<op_type, op_subview_elem_inplace_plus >::value == true) { m_mem[ii] += X[i]; } else if(is_same_type<op_type, op_subview_elem_inplace_minus>::value == true) { m_mem[ii] -= X[i]; } else if(is_same_type<op_type, op_subview_elem_inplace_schur>::value == true) { m_mem[ii] *= X[i]; } else if(is_same_type<op_type, op_subview_elem_inplace_div >::value == true) { m_mem[ii] /= X[i]; } } } }
inline bool op_any::any_vec_helper ( const mtGlue<uword, T1, T2, glue_type>& X, const typename arma_glue_rel_only<glue_type>::result junk1, const typename arma_not_cx<typename T1::elem_type>::result junk2, const typename arma_not_cx<typename T2::elem_type>::result junk3 ) { arma_extra_debug_sigprint(); arma_ignore(junk1); arma_ignore(junk2); arma_ignore(junk3); typedef typename T1::elem_type eT1; typedef typename T2::elem_type eT2; typedef typename Proxy<T1>::ea_type ea_type1; typedef typename Proxy<T2>::ea_type ea_type2; const Proxy<T1> A(X.A); const Proxy<T2> B(X.B); arma_debug_assert_same_size(A, B, "relational operator"); const bool prefer_at_accessor = Proxy<T1>::prefer_at_accessor || Proxy<T2>::prefer_at_accessor; if(prefer_at_accessor == false) { ea_type1 PA = A.get_ea(); ea_type2 PB = B.get_ea(); const uword n_elem = A.get_n_elem(); for(uword i=0; i<n_elem; ++i) { const eT1 tmp1 = PA[i]; const eT2 tmp2 = PB[i]; if(is_same_type<glue_type, glue_rel_lt >::yes) { if(tmp1 < tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_gt >::yes) { if(tmp1 > tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_lteq >::yes) { if(tmp1 <= tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_gteq >::yes) { if(tmp1 >= tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_eq >::yes) { if(tmp1 == tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_noteq >::yes) { if(tmp1 != tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_and >::yes) { if(tmp1 && tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_or >::yes) { if(tmp1 || tmp2) { return true; } } } } else { const uword n_rows = A.get_n_rows(); const uword n_cols = A.get_n_cols(); for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT1 tmp1 = A.at(row,col); const eT2 tmp2 = B.at(row,col); if(is_same_type<glue_type, glue_rel_lt >::yes) { if(tmp1 < tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_gt >::yes) { if(tmp1 > tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_lteq >::yes) { if(tmp1 <= tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_gteq >::yes) { if(tmp1 >= tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_eq >::yes) { if(tmp1 == tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_noteq >::yes) { if(tmp1 != tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_and >::yes) { if(tmp1 && tmp2) { return true; } } else if(is_same_type<glue_type, glue_rel_or >::yes) { if(tmp1 || tmp2) { return true; } } } } return false; }
inline void op_unique::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_unique>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const Proxy<T1> P(X.m); const uword in_n_rows = P.get_n_rows(); const uword in_n_cols = P.get_n_cols(); const uword in_n_elem = P.get_n_elem(); if(in_n_elem <= 1) { if(in_n_elem == 1) { const eT tmp = P[0]; out.set_size(in_n_rows, in_n_cols); out[0] = tmp; } else { out.set_size(in_n_rows, in_n_cols); } return; } std::vector<eT> lvec(in_n_elem); if(Proxy<T1>::prefer_at_accessor == false) { typename Proxy<T1>::ea_type Pea = P.get_ea(); uword i,j; for(i=0, j=1; j < in_n_elem; i+=2, j+=2) { const eT tmp_i = Pea[i]; const eT tmp_j = Pea[j]; lvec[i] = tmp_i; lvec[j] = tmp_j; } if(i < in_n_elem) { lvec[i] = Pea[i]; } } else { uword i = 0; for(uword col=0; col < in_n_cols; ++col) for(uword row=0; row < in_n_rows; ++row, ++i) { lvec[i] = P.at(row,col); } } std::sort( lvec.begin(), lvec.end() ); uword N_unique = 1; for(uword i=1; i < in_n_elem; ++i) { const eT a = lvec[i-1]; const eT b = lvec[i ]; const eT diff = a - b; if(diff != eT(0)) { ++N_unique; } } uword out_n_rows; uword out_n_cols; if( (in_n_rows == 1) || (in_n_cols == 1) ) { if(in_n_rows == 1) { out_n_rows = 1; out_n_cols = N_unique; } else { out_n_rows = N_unique; out_n_cols = 1; } } else { out_n_rows = N_unique; out_n_cols = 1; } // we don't need to worry about aliasing at this stage, as all the data is stored in lvec out.set_size(out_n_rows, out_n_cols); eT* out_mem = out.memptr(); if(in_n_elem > 0) { out_mem[0] = lvec[0]; } N_unique = 1; for(uword i=1; i < in_n_elem; ++i) { const eT a = lvec[i-1]; const eT b = lvec[i ]; const eT diff = a - b; if(diff != eT(0)) { out_mem[N_unique] = b; ++N_unique; } } }
arma_hot inline typename T1::pod_type arma_vec_norm_1(const Proxy<T1>& P) { arma_extra_debug_sigprint(); typedef typename T1::pod_type T; T acc = T(0); if(Proxy<T1>::prefer_at_accessor == false) { typename Proxy<T1>::ea_type A = P.get_ea(); const uword N = P.get_n_elem(); T acc1 = T(0); T acc2 = T(0); uword i,j; for(i=0, j=1; j<N; i+=2, j+=2) { acc1 += std::abs(A[i]); acc2 += std::abs(A[j]); } if(i < N) { acc1 += std::abs(A[i]); } acc = acc1 + acc2; } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { for(uword col=0; col<n_cols; ++col) { acc += std::abs(P.at(0,col)); } } else { for(uword col=0; col<n_cols; ++col) { uword i,j; for(i=0, j=1; j<n_rows; i+=2, j+=2) { acc += std::abs(P.at(i,col)); acc += std::abs(P.at(j,col)); } if(i < n_rows) { acc += std::abs(P.at(i,col)); } } } } return acc; }
inline bool op_find_unique::apply_helper(Mat<uword>& out, const Proxy<T1>& P, const bool ascending_indices) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const uword n_elem = P.get_n_elem(); if(n_elem == 0) { out.set_size(0,1); return true; } if(n_elem == 1) { out.set_size(1,1); out[0] = 0; return true; } uvec indices(n_elem); std::vector< arma_find_unique_packet<eT> > packet_vec(n_elem); if(Proxy<T1>::prefer_at_accessor == false) { typename Proxy<T1>::ea_type Pea = P.get_ea(); for(uword i=0; i<n_elem; ++i) { const eT val = Pea[i]; if(arma_isnan(val)) { return false; } packet_vec[i].val = val; packet_vec[i].index = i; } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); uword i = 0; for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT val = P.at(row,col); if(arma_isnan(val)) { return false; } packet_vec[i].val = val; packet_vec[i].index = i; ++i; } } arma_find_unique_comparator<eT> comparator; std::sort( packet_vec.begin(), packet_vec.end(), comparator ); uword* indices_mem = indices.memptr(); indices_mem[0] = packet_vec[0].index; uword count = 1; for(uword i=1; i < n_elem; ++i) { const eT diff = packet_vec[i-1].val - packet_vec[i].val; if(diff != eT(0)) { indices_mem[count] = packet_vec[i].index; ++count; } } out.steal_mem_col(indices,count); if(ascending_indices) { std::sort(out.begin(), out.end()); } return true; }
inline bool arma_sort_index_helper(Mat<uword>& out, const Proxy<T1>& P, const uword sort_type, typename arma_not_cx<typename T1::elem_type>::result* junk = 0) { arma_extra_debug_sigprint(); arma_ignore(junk); typedef typename T1::elem_type eT; const uword n_elem = P.get_n_elem(); out.set_size(n_elem, 1); std::vector< arma_sort_index_packet<eT, uword> > packet_vec(n_elem); if(Proxy<T1>::prefer_at_accessor == false) { for(uword i=0; i<n_elem; ++i) { const eT val = P[i]; if(arma_isnan(val)) { out.reset(); return false; } packet_vec[i].val = val; packet_vec[i].index = i; } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); uword i = 0; for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT val = P.at(row,col); if(arma_isnan(val)) { out.reset(); return false; } packet_vec[i].val = val; packet_vec[i].index = i; ++i; } } if(sort_type == 0) { // ascend arma_sort_index_helper_ascend comparator; if(sort_stable == false) { std::sort( packet_vec.begin(), packet_vec.end(), comparator ); } else { std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator ); } } else { // descend arma_sort_index_helper_descend comparator; if(sort_stable == false) { std::sort( packet_vec.begin(), packet_vec.end(), comparator ); } else { std::stable_sort( packet_vec.begin(), packet_vec.end(), comparator ); } } uword* out_mem = out.memptr(); for(uword i=0; i<n_elem; ++i) { out_mem[i] = packet_vec[i].index; } return true; }
inline void op_fft_cx::apply_noalias(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword a, const uword b) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); const uword n_elem = P.get_n_elem(); const bool is_vec = ( (n_rows == 1) || (n_cols == 1) ); const uword N_orig = (is_vec) ? n_elem : n_rows; const uword N_user = (b == 0) ? a : N_orig; fft_engine<eT,inverse> worker(N_user); if(is_vec) { (n_cols == 1) ? out.set_size(N_user, 1) : out.set_size(1, N_user); if( (out.n_elem == 0) || (N_orig == 0) ) { out.zeros(); return; } if( (N_user == 1) && (N_orig >= 1) ) { out[0] = P[0]; return; } if( (N_user > N_orig) || (is_Mat<typename Proxy<T1>::stored_type>::value == false) ) { podarray<eT> data(N_user); eT* data_mem = data.memptr(); if(N_user > N_orig) { arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); } op_fft_cx::copy_vec( data_mem, P, (std::min)(N_user, N_orig) ); worker.run( out.memptr(), data_mem ); } else { const unwrap< typename Proxy<T1>::stored_type > tmp(P.Q); worker.run( out.memptr(), tmp.M.memptr() ); } } else { // process each column seperately out.set_size(N_user, n_cols); if( (out.n_elem == 0) || (N_orig == 0) ) { out.zeros(); return; } if( (N_user == 1) && (N_orig >= 1) ) { for(uword col=0; col < n_cols; ++col) { out.at(0,col) = P.at(0,col); } return; } if( (N_user > N_orig) || (is_Mat<typename Proxy<T1>::stored_type>::value == false) ) { podarray<eT> data(N_user); eT* data_mem = data.memptr(); if(N_user > N_orig) { arrayops::fill_zeros( &data_mem[N_orig], (N_user - N_orig) ); } const uword N = (std::min)(N_user, N_orig); for(uword col=0; col < n_cols; ++col) { for(uword i=0; i < N; ++i) { data_mem[i] = P.at(i, col); } worker.run( out.colptr(col), data_mem ); } } else { const unwrap< typename Proxy<T1>::stored_type > tmp(P.Q); for(uword col=0; col < n_cols; ++col) { worker.run( out.colptr(col), tmp.M.colptr(col) ); } } } // correct the scaling for the inverse transform if(inverse == true) { typedef typename get_pod_type<eT>::result T; const T k = T(1) / T(N_user); eT* out_mem = out.memptr(); const uword out_n_elem = out.n_elem; for(uword i=0; i < out_n_elem; ++i) { out_mem[i] *= k; } } }
inline void diagview<eT>::operator/=(const Base<eT,T1>& o) { arma_extra_debug_sigprint(); diagview<eT>& d = *this; Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m); const uword d_n_elem = d.n_elem; const uword d_row_offset = d.row_offset; const uword d_col_offset = d.col_offset; const Proxy<T1> P( o.get_ref() ); arma_debug_check ( ( (d_n_elem != P.get_n_elem()) || ((P.get_n_rows() != 1) && (P.get_n_cols() != 1)) ), "diagview: given object has incompatible size" ); const bool is_alias = P.is_alias(d_m); arma_extra_debug_warn(is_alias, "aliasing detected"); if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::prefer_at_accessor) || (is_alias) ) { const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias); const Mat<eT>& x = tmp.M; const eT* x_mem = x.memptr(); uword ii,jj; for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2) { const eT tmp_i = x_mem[ii]; const eT tmp_j = x_mem[jj]; d_m.at( ii + d_row_offset, ii + d_col_offset) /= tmp_i; d_m.at( jj + d_row_offset, jj + d_col_offset) /= tmp_j; } if(ii < d_n_elem) { d_m.at( ii + d_row_offset, ii + d_col_offset) /= x_mem[ii]; } } else { typename Proxy<T1>::ea_type Pea = P.get_ea(); uword ii,jj; for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2) { const eT tmp_i = Pea[ii]; const eT tmp_j = Pea[jj]; d_m.at( ii + d_row_offset, ii + d_col_offset) /= tmp_i; d_m.at( jj + d_row_offset, jj + d_col_offset) /= tmp_j; } if(ii < d_n_elem) { d_m.at( ii + d_row_offset, ii + d_col_offset) /= Pea[ii]; } } }
inline typename arma_cx_only<typename T1::elem_type>::result op_min::min_with_index(const Proxy<T1>& P, uword& index_of_min_val) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; typedef typename get_pod_type<eT>::result T; const uword n_elem = P.get_n_elem(); if(n_elem == 0) { arma_debug_check(true, "min(): object has no elements"); return Datum<eT>::nan; } T best_val = priv::most_pos<T>(); if(Proxy<T1>::prefer_at_accessor == false) { typedef typename Proxy<T1>::ea_type ea_type; ea_type A = P.get_ea(); uword best_index = 0; for(uword i=0; i<n_elem; ++i) { const T tmp = std::abs(A[i]); if(tmp < best_val) { best_val = tmp; best_index = i; } } index_of_min_val = best_index; return( A[best_index] ); } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); uword best_row = 0; uword best_col = 0; uword best_index = 0; if(n_rows == 1) { for(uword col=0; col < n_cols; ++col) { const T tmp = std::abs(P.at(0,col)); if(tmp < best_val) { best_val = tmp; best_col = col; } } best_index = best_col; } else if(n_cols == 1) { for(uword row=0; row < n_rows; ++row) { const T tmp = std::abs(P.at(row,0)); if(tmp < best_val) { best_val = tmp; best_row = row; } } best_index = best_row; } else { uword count = 0; for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const T tmp = std::abs(P.at(row,col)); if(tmp < best_val) { best_val = tmp; best_row = row; best_col = col; best_index = count; } ++count; } } index_of_min_val = best_index; return P.at(best_row, best_col); } }
inline arma_warn_unused typename T1::pod_type norm ( const Base<typename T1::elem_type,T1>& X, const uword k, const typename arma_float_or_cx_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); typedef typename T1::elem_type eT; typedef typename T1::pod_type T; const Proxy<T1> A(X.get_ref()); if(A.get_n_elem() == 0) { return T(0); } const bool is_vec = (A.get_n_rows() == 1) || (A.get_n_cols() == 1); if(is_vec == true) { switch(k) { case 1: return arma_vec_norm_1(A); break; case 2: return arma_vec_norm_2(A); break; default: { arma_debug_check( (k == 0), "norm(): k must be greater than zero" ); return arma_vec_norm_k(A, int(k)); } } } else { switch(k) { case 1: return arma_mat_norm_1(A); break; case 2: return arma_mat_norm_2(A); break; default: arma_stop("norm(): unsupported matrix norm type"); return T(0); } } }
arma_hot inline typename T1::pod_type op_norm::vec_norm_2(const Proxy<T1>& P, const typename arma_not_cx<typename T1::elem_type>::result* junk) { arma_extra_debug_sigprint(); arma_ignore(junk); const bool have_direct_mem = (is_Mat<typename Proxy<T1>::stored_type>::value) || (is_subview_col<typename Proxy<T1>::stored_type>::value); if(have_direct_mem) { const quasi_unwrap<typename Proxy<T1>::stored_type> tmp(P.Q); return op_norm::vec_norm_2_direct_std(tmp.M); } typedef typename T1::pod_type T; T acc = T(0); if(Proxy<T1>::use_at == false) { typename Proxy<T1>::ea_type A = P.get_ea(); const uword N = P.get_n_elem(); T acc1 = T(0); T acc2 = T(0); uword i,j; for(i=0, j=1; j<N; i+=2, j+=2) { const T tmp_i = A[i]; const T tmp_j = A[j]; acc1 += tmp_i * tmp_i; acc2 += tmp_j * tmp_j; } if(i < N) { const T tmp_i = A[i]; acc1 += tmp_i * tmp_i; } acc = acc1 + acc2; } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { for(uword col=0; col<n_cols; ++col) { const T tmp = P.at(0,col); acc += tmp * tmp; } } else { for(uword col=0; col<n_cols; ++col) { uword i,j; for(i=0, j=1; j<n_rows; i+=2, j+=2) { const T tmp_i = P.at(i,col); const T tmp_j = P.at(j,col); acc += tmp_i * tmp_i; acc += tmp_j * tmp_j; } if(i < n_rows) { const T tmp_i = P.at(i,col); acc += tmp_i * tmp_i; } } } } const T sqrt_acc = std::sqrt(acc); if( (sqrt_acc != T(0)) && arma_isfinite(sqrt_acc) ) { return sqrt_acc; } else { arma_extra_debug_print("op_norm::vec_norm_2(): detected possible underflow or overflow"); const quasi_unwrap<typename Proxy<T1>::stored_type> tmp(P.Q); return op_norm::vec_norm_2_direct_robust(tmp.M); } }
inline arma_warn_unused typename T1::pod_type norm ( const Base<typename T1::elem_type,T1>& X, const char* method, const typename arma_float_or_cx_only<typename T1::elem_type>::result* junk = 0 ) { arma_extra_debug_sigprint(); arma_ignore(junk); typedef typename T1::elem_type eT; typedef typename T1::pod_type T; const Proxy<T1> A(X.get_ref()); if(A.get_n_elem() == 0) { return T(0); } const char sig = method[0]; const bool is_vec = (A.get_n_rows() == 1) || (A.get_n_cols() == 1); if(is_vec == true) { if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // max norm { return arma_vec_norm_max(A); } else if(sig == '-') // min norm { return arma_vec_norm_min(A); } else if( (sig == 'f') || (sig == 'F') ) { return arma_vec_norm_2(A); } else { arma_stop("norm(): unsupported vector norm type"); return T(0); } } else { if( (sig == 'i') || (sig == 'I') || (sig == '+') ) // inf norm { return arma_mat_norm_inf(A); } else if( (sig == 'f') || (sig == 'F') ) { return arma_vec_norm_2(A); } else { arma_stop("norm(): unsupported matrix norm type"); return T(0); } } }
arma_hot inline typename T1::pod_type op_norm::vec_norm_min(const Proxy<T1>& P) { arma_extra_debug_sigprint(); typedef typename T1::pod_type T; const uword N = P.get_n_elem(); T min_val = (N != 1) ? priv::most_pos<T>() : std::abs(P[0]); if(Proxy<T1>::use_at == false) { typename Proxy<T1>::ea_type A = P.get_ea(); uword i,j; for(i=0, j=1; j<N; i+=2, j+=2) { const T tmp_i = std::abs(A[i]); const T tmp_j = std::abs(A[j]); if(min_val > tmp_i) { min_val = tmp_i; } if(min_val > tmp_j) { min_val = tmp_j; } } if(i < N) { const T tmp_i = std::abs(A[i]); if(min_val > tmp_i) { min_val = tmp_i; } } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows != 1) { for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const T tmp = std::abs(P.at(row,col)); if(min_val > tmp) { min_val = tmp; } } } else { for(uword col=0; col < n_cols; ++col) { const T tmp = std::abs(P.at(0,col)); if(min_val > tmp) { min_val = tmp; } } } } return min_val; }
arma_hot inline typename T1::pod_type arma_vec_norm_2(const Proxy<T1>& A, const typename arma_not_cx<typename T1::elem_type>::result* junk = 0) { arma_extra_debug_sigprint(); arma_ignore(junk); typedef typename T1::pod_type T; T acc = T(0); if(Proxy<T1>::prefer_at_accessor == false) { typename Proxy<T1>::ea_type P = A.get_ea(); const uword N = A.get_n_elem(); uword i,j; for(i=0, j=1; j<N; i+=2, j+=2) { const T tmp_i = P[i]; const T tmp_j = P[j]; acc += tmp_i * tmp_i; acc += tmp_j * tmp_j; } if(i < N) { const T tmp_i = P[i]; acc += tmp_i * tmp_i; } } else { const uword n_rows = A.get_n_rows(); const uword n_cols = A.get_n_cols(); for(uword col=0; col<n_cols; ++col) { uword i,j; for(i=0, j=1; j<n_rows; i+=2, j+=2) { const T tmp_i = A.at(i,col); const T tmp_j = A.at(j,col); acc += tmp_i * tmp_i; acc += tmp_j * tmp_j; } if(i < n_rows) { const T tmp_i = A.at(i,col); acc += tmp_i * tmp_i; } } } return std::sqrt(acc); }
inline void subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x) { arma_extra_debug_sigprint(); Mat<eT>& m_local = const_cast< Mat<eT>& >(m); eT* m_mem = m_local.memptr(); const uword m_n_elem = m_local.n_elem; const unwrap_check_mixed<T1> aa_tmp(a.get_ref(), m_local); const umat& aa = aa_tmp.M; arma_debug_check ( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), "Mat::elem(): given object is not a vector" ); const uword* aa_mem = aa.memptr(); const uword aa_n_elem = aa.n_elem; const Proxy<T2> P(x.get_ref()); arma_debug_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" ); const bool is_alias = P.is_alias(m); if( (is_alias == false) && (Proxy<T2>::prefer_at_accessor == false) ) { typename Proxy<T2>::ea_type X = P.get_ea(); uword iq,jq; for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2) { const uword ii = aa_mem[iq]; const uword jj = aa_mem[jq]; arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); if(is_same_type<op_type, op_subview_elem_equ >::yes) { m_mem[ii] = X[iq]; m_mem[jj] = X[jq]; } else if(is_same_type<op_type, op_subview_elem_inplace_plus >::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; } else if(is_same_type<op_type, op_subview_elem_inplace_minus>::yes) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; } else if(is_same_type<op_type, op_subview_elem_inplace_schur>::yes) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; } else if(is_same_type<op_type, op_subview_elem_inplace_div >::yes) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; } } if(iq < aa_n_elem) { const uword ii = aa_mem[iq]; arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); if(is_same_type<op_type, op_subview_elem_equ >::yes) { m_mem[ii] = X[iq]; } else if(is_same_type<op_type, op_subview_elem_inplace_plus >::yes) { m_mem[ii] += X[iq]; } else if(is_same_type<op_type, op_subview_elem_inplace_minus>::yes) { m_mem[ii] -= X[iq]; } else if(is_same_type<op_type, op_subview_elem_inplace_schur>::yes) { m_mem[ii] *= X[iq]; } else if(is_same_type<op_type, op_subview_elem_inplace_div >::yes) { m_mem[ii] /= X[iq]; } } } else { arma_extra_debug_print("subview_elem1::inplace_op(): aliasing or prefer_at_accessor detected"); const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, is_alias); const Mat<eT>& M = tmp.M; const eT* X = M.memptr(); uword iq,jq; for(iq=0, jq=1; jq < aa_n_elem; iq+=2, jq+=2) { const uword ii = aa_mem[iq]; const uword jj = aa_mem[jq]; arma_debug_check( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" ); if(is_same_type<op_type, op_subview_elem_equ >::yes) { m_mem[ii] = X[iq]; m_mem[jj] = X[jq]; } else if(is_same_type<op_type, op_subview_elem_inplace_plus >::yes) { m_mem[ii] += X[iq]; m_mem[jj] += X[jq]; } else if(is_same_type<op_type, op_subview_elem_inplace_minus>::yes) { m_mem[ii] -= X[iq]; m_mem[jj] -= X[jq]; } else if(is_same_type<op_type, op_subview_elem_inplace_schur>::yes) { m_mem[ii] *= X[iq]; m_mem[jj] *= X[jq]; } else if(is_same_type<op_type, op_subview_elem_inplace_div >::yes) { m_mem[ii] /= X[iq]; m_mem[jj] /= X[jq]; } } if(iq < aa_n_elem) { const uword ii = aa_mem[iq]; arma_debug_check( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" ); if(is_same_type<op_type, op_subview_elem_equ >::yes) { m_mem[ii] = X[iq]; } else if(is_same_type<op_type, op_subview_elem_inplace_plus >::yes) { m_mem[ii] += X[iq]; } else if(is_same_type<op_type, op_subview_elem_inplace_minus>::yes) { m_mem[ii] -= X[iq]; } else if(is_same_type<op_type, op_subview_elem_inplace_schur>::yes) { m_mem[ii] *= X[iq]; } else if(is_same_type<op_type, op_subview_elem_inplace_div >::yes) { m_mem[ii] /= X[iq]; } } } }
inline void op_reshape::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword in_n_rows, const uword in_n_cols) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; out.set_size(in_n_rows, in_n_cols); eT* out_mem = out.memptr(); const uword in_n_elem = in_n_rows * in_n_cols; if(P.get_n_elem() == in_n_elem) { if(Proxy<T1>::use_at == false) { typename Proxy<T1>::ea_type Pea = P.get_ea(); for(uword i=0; i<in_n_elem; ++i) { out_mem[i] = Pea[i]; } } else { const uword P_n_rows = P.get_n_rows(); const uword P_n_cols = P.get_n_cols(); for(uword col=0; col < P_n_cols; ++col) { uword i,j; for(i=0, j=1; j < P_n_rows; i+=2, j+=2) { const eT tmp_i = P.at(i,col); const eT tmp_j = P.at(j,col); *out_mem = tmp_i; out_mem++; *out_mem = tmp_j; out_mem++; } if(i < P_n_rows) { *out_mem = P.at(i,col); out_mem++; } } } } else { const uword n_elem_to_copy = (std::min)(P.get_n_elem(), in_n_elem); if(Proxy<T1>::use_at == false) { typename Proxy<T1>::ea_type Pea = P.get_ea(); for(uword i=0; i<n_elem_to_copy; ++i) { out_mem[i] = Pea[i]; } } else { uword i = 0; const uword P_n_rows = P.get_n_rows(); const uword P_n_cols = P.get_n_cols(); for(uword col=0; col < P_n_cols; ++col) for(uword row=0; row < P_n_rows; ++row) { if(i >= n_elem_to_copy) { goto nested_loop_end; } out_mem[i] = P.at(row,col); ++i; } nested_loop_end: ; } for(uword i=n_elem_to_copy; i<in_n_elem; ++i) { out_mem[i] = eT(0); } } }
inline typename arma_not_cx<typename T1::elem_type>::result op_min::min(const Base<typename T1::elem_type,T1>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const Proxy<T1> P(X.get_ref()); const uword n_elem = P.get_n_elem(); arma_debug_check( (n_elem == 0), "min(): given object has no elements" ); eT min_val = priv::most_pos<eT>(); if(Proxy<T1>::prefer_at_accessor == false) { typedef typename Proxy<T1>::ea_type ea_type; ea_type A = P.get_ea(); uword i,j; for(i=0, j=1; j<n_elem; i+=2, j+=2) { const eT tmp_i = A[i]; const eT tmp_j = A[j]; if(tmp_i < min_val) { min_val = tmp_i; } if(tmp_j < min_val) { min_val = tmp_j; } } if(i < n_elem) { const eT tmp_i = A[i]; if(tmp_i < min_val) { min_val = tmp_i; } } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { uword i,j; for(i=0, j=1; j < n_cols; i+=2, j+=2) { const eT tmp_i = P.at(0,i); const eT tmp_j = P.at(0,j); if(tmp_i < min_val) { min_val = tmp_i; } if(tmp_j < min_val) { min_val = tmp_j; } } if(i < n_cols) { const eT tmp_i = P.at(0,i); if(tmp_i < min_val) { min_val = tmp_i; } } } else { for(uword col=0; col < n_cols; ++col) { uword i,j; for(i=0, j=1; j < n_rows; i+=2, j+=2) { const eT tmp_i = P.at(i,col); const eT tmp_j = P.at(j,col); if(tmp_i < min_val) { min_val = tmp_i; } if(tmp_j < min_val) { min_val = tmp_j; } } if(i < n_rows) { const eT tmp_i = P.at(i,col); if(tmp_i < min_val) { min_val = tmp_i; } } } } } return min_val; }
inline typename arma_not_cx<typename T1::elem_type>::result op_max::max_with_index(const Proxy<T1>& P, uword& index_of_max_val) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const uword n_elem = P.get_n_elem(); if(n_elem == 0) { arma_debug_check(true, "max(): object has no elements"); return Datum<eT>::nan; } eT best_val = priv::most_neg<eT>(); uword best_index = 0; if(Proxy<T1>::prefer_at_accessor == false) { typedef typename Proxy<T1>::ea_type ea_type; ea_type A = P.get_ea(); for(uword i=0; i<n_elem; ++i) { const eT tmp = A[i]; if(tmp > best_val) { best_val = tmp; best_index = i; } } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { for(uword i=0; i < n_cols; ++i) { const eT tmp = P.at(0,i); if(tmp > best_val) { best_val = tmp; best_index = i; } } } else if(n_cols == 1) { for(uword i=0; i < n_rows; ++i) { const eT tmp = P.at(i,0); if(tmp > best_val) { best_val = tmp; best_index = i; } } } else { uword count = 0; for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT tmp = P.at(row,col); if(tmp > best_val) { best_val = tmp; best_index = count; } ++count; } } } index_of_max_val = best_index; return best_val; }
inline typename T1::elem_type op_prod::prod(const Base<typename T1::elem_type,T1>& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const Proxy<T1> P(X.get_ref()); eT val = eT(1); if(Proxy<T1>::prefer_at_accessor == false) { typedef typename Proxy<T1>::ea_type ea_type; const ea_type A = P.get_ea(); const uword n_elem = P.get_n_elem(); uword i,j; for(i=0, j=1; j < n_elem; i+=2, j+=2) { val *= A[i]; val *= A[j]; } if(i < n_elem) { val *= A[i]; } } else { const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); if(n_rows == 1) { uword i,j; for(i=0, j=1; j < n_cols; i+=2, j+=2) { val *= P.at(0,i); val *= P.at(0,j); } if(i < n_cols) { val *= P.at(0,i); } } else { for(uword col=0; col < n_cols; ++col) { uword i,j; for(i=0, j=1; j < n_rows; i+=2, j+=2) { val *= P.at(i,col); val *= P.at(j,col); } if(i < n_rows) { val *= P.at(i,col); } } } } return val; }
inline bool op_unique::apply_helper(Mat<typename T1::elem_type>& out, const Proxy<T1>& P) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); const uword n_elem = P.get_n_elem(); if(n_elem == 0) { out.set_size(n_rows, n_cols); return true; } if(n_elem == 1) { const eT tmp = (Proxy<T1>::use_at) ? P.at(0,0) : P[0]; out.set_size(n_rows, n_cols); out[0] = tmp; return true; } Mat<eT> X(n_elem,1); eT* X_mem = X.memptr(); if(Proxy<T1>::use_at == false) { typename Proxy<T1>::ea_type Pea = P.get_ea(); for(uword i=0; i<n_elem; ++i) { const eT val = Pea[i]; if(arma_isnan(val)) { out.reset(); return false; } X_mem[i] = val; } } else { for(uword col=0; col < n_cols; ++col) for(uword row=0; row < n_rows; ++row) { const eT val = P.at(row,col); if(arma_isnan(val)) { out.reset(); return false; } (*X_mem) = val; X_mem++; } X_mem = X.memptr(); } arma_unique_comparator<eT> comparator; std::sort( X.begin(), X.end(), comparator ); uword N_unique = 1; for(uword i=1; i < n_elem; ++i) { const eT a = X_mem[i-1]; const eT b = X_mem[i ]; const eT diff = a - b; if(diff != eT(0)) { ++N_unique; } } uword out_n_rows; uword out_n_cols; if( (n_rows == 1) || (n_cols == 1) ) { if(n_rows == 1) { out_n_rows = 1; out_n_cols = N_unique; } else { out_n_rows = N_unique; out_n_cols = 1; } } else { out_n_rows = N_unique; out_n_cols = 1; } out.set_size(out_n_rows, out_n_cols); eT* out_mem = out.memptr(); if(n_elem > 0) { (*out_mem) = X_mem[0]; out_mem++; } for(uword i=1; i < n_elem; ++i) { const eT a = X_mem[i-1]; const eT b = X_mem[i ]; const eT diff = a - b; if(diff != eT(0)) { (*out_mem) = b; out_mem++; } } return true; }