Chris@49: // Copyright (C) 2012 Conrad Sanderson Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: Chris@49: //! \addtogroup subview_each Chris@49: //! @{ Chris@49: Chris@49: Chris@49: // Chris@49: // Chris@49: // subview_each_common Chris@49: Chris@49: template Chris@49: inline Chris@49: subview_each_common::subview_each_common(parent& in_p) Chris@49: : p(in_p) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: subview_each_common::get_mat_ref_helper(const Mat& X) const Chris@49: { Chris@49: return X; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: subview_each_common::get_mat_ref_helper(const subview& X) const Chris@49: { Chris@49: return X.m; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const Mat& Chris@49: subview_each_common::get_mat_ref() const Chris@49: { Chris@49: return get_mat_ref_helper(p); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each_common::check_size(const Mat& A) const Chris@49: { Chris@49: if(arma_config::debug == true) Chris@49: { Chris@49: if(mode == 0) Chris@49: { Chris@49: if( (A.n_rows != p.n_rows) || (A.n_cols != 1) ) Chris@49: { Chris@49: arma_stop( incompat_size_string(A) ); Chris@49: } Chris@49: } Chris@49: else Chris@49: { Chris@49: if( (A.n_rows != 1) || (A.n_cols != p.n_cols) ) Chris@49: { Chris@49: arma_stop( incompat_size_string(A) ); Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_cold Chris@49: inline Chris@49: const std::string Chris@49: subview_each_common::incompat_size_string(const Mat& A) const Chris@49: { Chris@49: std::stringstream tmp; Chris@49: Chris@49: if(mode == 0) Chris@49: { Chris@49: tmp << "each_col(): incompatible size; expected " << p.n_rows << "x1" << ", got " << A.n_rows << 'x' << A.n_cols; Chris@49: } Chris@49: else Chris@49: { Chris@49: tmp << "each_row(): incompatible size; expected 1x" << p.n_cols << ", got " << A.n_rows << 'x' << A.n_cols; Chris@49: } Chris@49: Chris@49: return tmp.str(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: // Chris@49: // Chris@49: // subview_each1 Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: subview_each1::~subview_each1() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: subview_each1::subview_each1(parent& in_p) Chris@49: : subview_each_common::subview_each_common(in_p) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each1::operator= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::copy( p.colptr(i), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_set( p.colptr(i), A_mem[i], p_n_rows); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each1::operator+= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_plus( p.colptr(i), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_plus( p.colptr(i), A_mem[i], p_n_rows); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each1::operator-= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_minus( p.colptr(i), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_minus( p.colptr(i), A_mem[i], p_n_rows); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each1::operator%= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_mul( p.colptr(i), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_mul( p.colptr(i), A_mem[i], p_n_rows); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each1::operator/= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_div( p.colptr(i), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < p_n_cols; ++i) Chris@49: { Chris@49: arrayops::inplace_div( p.colptr(i), A_mem[i], p_n_rows); Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: // Chris@49: // Chris@49: // subview_each2 Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: subview_each2::~subview_each2() Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: subview_each2::subview_each2(parent& in_p, const Base& in_indices) Chris@49: : subview_each_common::subview_each_common(in_p) Chris@49: , base_indices(in_indices) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each2::check_indices(const Mat& indices) const Chris@49: { Chris@49: if(mode == 0) Chris@49: { Chris@49: arma_debug_check( ((indices.is_vec() == false) && (indices.is_empty() == false)), "each_col(): list of indices must be a vector" ); Chris@49: } Chris@49: else Chris@49: { Chris@49: arma_debug_check( ((indices.is_vec() == false) && (indices.is_empty() == false)), "each_row(): list of indices must be a vector" ); Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each2::operator= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const unwrap_check_mixed tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& indices = tmp_indices.M; Chris@49: Chris@49: check_indices(indices); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: const uword* indices_mem = indices.memptr(); Chris@49: const uword N = indices.n_elem; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword col = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" ); Chris@49: Chris@49: arrayops::copy( p.colptr(col), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword row = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" ); Chris@49: Chris@49: for(uword col=0; col < p_n_cols; ++col) Chris@49: { Chris@49: p.at(row,col) = A_mem[col]; Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each2::operator+= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const unwrap_check_mixed tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& indices = tmp_indices.M; Chris@49: Chris@49: check_indices(indices); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: const uword* indices_mem = indices.memptr(); Chris@49: const uword N = indices.n_elem; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword col = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" ); Chris@49: Chris@49: arrayops::inplace_plus( p.colptr(col), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword row = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" ); Chris@49: Chris@49: for(uword col=0; col < p_n_cols; ++col) Chris@49: { Chris@49: p.at(row,col) += A_mem[col]; Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each2::operator-= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const unwrap_check_mixed tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& indices = tmp_indices.M; Chris@49: Chris@49: check_indices(indices); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: const uword* indices_mem = indices.memptr(); Chris@49: const uword N = indices.n_elem; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword col = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" ); Chris@49: Chris@49: arrayops::inplace_minus( p.colptr(col), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword row = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" ); Chris@49: Chris@49: for(uword col=0; col < p_n_cols; ++col) Chris@49: { Chris@49: p.at(row,col) -= A_mem[col]; Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each2::operator%= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const unwrap_check_mixed tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& indices = tmp_indices.M; Chris@49: Chris@49: check_indices(indices); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: const uword* indices_mem = indices.memptr(); Chris@49: const uword N = indices.n_elem; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword col = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" ); Chris@49: Chris@49: arrayops::inplace_mul( p.colptr(col), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword row = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" ); Chris@49: Chris@49: for(uword col=0; col < p_n_cols; ++col) Chris@49: { Chris@49: p.at(row,col) *= A_mem[col]; Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: void Chris@49: subview_each2::operator/= (const Base& in) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: parent& p = subview_each_common::p; Chris@49: Chris@49: const unwrap_check tmp( in.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& A = tmp.M; Chris@49: Chris@49: subview_each_common::check_size(A); Chris@49: Chris@49: const unwrap_check_mixed tmp_indices( base_indices.get_ref(), (*this).get_mat_ref() ); Chris@49: const Mat& indices = tmp_indices.M; Chris@49: Chris@49: check_indices(indices); Chris@49: Chris@49: const eT* A_mem = A.memptr(); Chris@49: const uword p_n_rows = p.n_rows; Chris@49: const uword p_n_cols = p.n_cols; Chris@49: Chris@49: const uword* indices_mem = indices.memptr(); Chris@49: const uword N = indices.n_elem; Chris@49: Chris@49: if(mode == 0) // each column Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword col = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (col > p_n_cols), "each_col(): index out of bounds" ); Chris@49: Chris@49: arrayops::inplace_div( p.colptr(col), A_mem, p_n_rows ); Chris@49: } Chris@49: } Chris@49: else // each row Chris@49: { Chris@49: for(uword i=0; i < N; ++i) Chris@49: { Chris@49: const uword row = indices_mem[i]; Chris@49: Chris@49: arma_debug_check( (row > p_n_rows), "each_row(): index out of bounds" ); Chris@49: Chris@49: for(uword col=0; col < p_n_cols; ++col) Chris@49: { Chris@49: p.at(row,col) /= A_mem[col]; Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! @}