// Copyright (C) 2008-2015 National ICT Australia (NICTA) // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. // ------------------------------------------------------------------- // // Written by Conrad Sanderson - http://conradsanderson.id.au // Written by Ryan Curtin //! \addtogroup fn_accu //! @{ template arma_hot inline typename T1::elem_type accu_proxy_linear(const Proxy& P) { typedef typename T1::elem_type eT; const uword n_elem = P.get_n_elem(); #if defined(__FINITE_MATH_ONLY__) && (__FINITE_MATH_ONLY__ > 0) { eT val = eT(0); if(P.is_aligned()) { typename Proxy::aligned_ea_type A = P.get_aligned_ea(); for(uword i=0; i::ea_type A = P.get_ea(); for(uword i=0; i::ea_type A = P.get_ea(); uword i,j; for(i=0, j=1; j < n_elem; i+=2, j+=2) { val1 += A[i]; val2 += A[j]; } if(i < n_elem) { val1 += A[i]; // equivalent to: val1 += A[n_elem-1]; } return (val1 + val2); } #endif } template arma_hot inline typename T1::elem_type accu_proxy_mat(const Proxy& P) { const quasi_unwrap::stored_type> tmp(P.Q); return arrayops::accumulate(tmp.M.memptr(), tmp.M.n_elem); } template arma_hot inline typename T1::elem_type accu_proxy_at(const Proxy& P) { typedef typename T1::elem_type eT; const uword n_rows = P.get_n_rows(); const uword n_cols = P.get_n_cols(); eT val = eT(0); if(n_rows != 1) { eT val1 = eT(0); eT val2 = eT(0); for(uword col=0; col < n_cols; ++col) { uword i,j; for(i=0, j=1; j < n_rows; i+=2, j+=2) { val1 += P.at(i,col); val2 += P.at(j,col); } if(i < n_rows) { val1 += P.at(i,col); } } val = val1 + val2; } else { for(uword col=0; col < n_cols; ++col) { val += P.at(0,col); } } return val; } //! accumulate the elements of a matrix template arma_hot inline typename enable_if2< is_arma_type::value, typename T1::elem_type >::result accu(const T1& X) { arma_extra_debug_sigprint(); const Proxy P(X); const bool have_direct_mem = (is_Mat::stored_type>::value) || (is_subview_col::stored_type>::value); return (Proxy::prefer_at_accessor) ? accu_proxy_at(P) : (have_direct_mem ? accu_proxy_mat(P) : accu_proxy_linear(P)); } //! explicit handling of Hamming norm (also known as zero norm) template inline arma_warn_unused uword accu(const mtOp& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const eT val = X.aux; const Proxy P(X.m); uword n_nonzero = 0; if(Proxy::prefer_at_accessor == false) { typedef typename Proxy::ea_type ea_type; ea_type A = P.get_ea(); const uword n_elem = P.get_n_elem(); for(uword i=0; i inline arma_warn_unused uword accu(const mtOp& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const eT val = X.aux; const Proxy P(X.m); uword n_nonzero = 0; if(Proxy::prefer_at_accessor == false) { typedef typename Proxy::ea_type ea_type; ea_type A = P.get_ea(); const uword n_elem = P.get_n_elem(); for(uword i=0; i arma_hot arma_pure arma_warn_unused inline eT accu(const subview& X) { arma_extra_debug_sigprint(); const uword X_n_rows = X.n_rows; const uword X_n_cols = X.n_cols; eT val = eT(0); if(X_n_rows == 1) { typedef subview_row sv_type; const sv_type& sv = reinterpret_cast(X); // subview_row is a child class of subview and has no extra data const Proxy P(sv); val = accu_proxy_linear(P); } else if(X_n_cols == 1) { val = arrayops::accumulate( X.colptr(0), X_n_rows ); } else { for(uword col=0; col < X_n_cols; ++col) { val += arrayops::accumulate( X.colptr(col), X_n_rows ); } } return val; } template arma_hot arma_pure arma_warn_unused inline eT accu(const subview_col& X) { arma_extra_debug_sigprint(); return arrayops::accumulate( X.colptr(0), X.n_rows ); } //! accumulate the elements of a cube template arma_hot arma_warn_unused inline typename T1::elem_type accu(const BaseCube& X) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; typedef typename ProxyCube::ea_type ea_type; const ProxyCube A(X.get_ref()); if(is_Cube::stored_type>::value) { unwrap_cube::stored_type> tmp(A.Q); return arrayops::accumulate(tmp.M.memptr(), tmp.M.n_elem); } if(ProxyCube::prefer_at_accessor == false) { ea_type P = A.get_ea(); const uword n_elem = A.get_n_elem(); eT val1 = eT(0); eT val2 = eT(0); uword i,j; for(i=0, j=1; j arma_inline arma_warn_unused const typename arma_scalar_only::result & accu(const T& x) { return x; } //! accumulate values in a sparse object template arma_hot inline arma_warn_unused typename enable_if2::value, typename T1::elem_type>::result accu(const T1& x) { arma_extra_debug_sigprint(); typedef typename T1::elem_type eT; const SpProxy p(x); if(SpProxy::must_use_iterator == false) { // direct counting return arrayops::accumulate(p.get_values(), p.get_n_nonzero()); } else { typename SpProxy::const_iterator_type it = p.begin(); typename SpProxy::const_iterator_type it_end = p.end(); eT result = eT(0); while(it != it_end) { result += (*it); ++it; } return result; } } //! @}