Chris@49: // Copyright (C) 2011-2012 Ryan Curtin Chris@49: // Copyright (C) 2011 Matthew Amidon 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 SpRow Chris@49: //! @{ Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpRow::SpRow() Chris@49: : SpMat(1, 0) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpRow::SpRow(const uword in_n_elem) Chris@49: : SpMat(1, in_n_elem) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpRow::SpRow(const uword in_n_rows, const uword in_n_cols) Chris@49: : SpMat(in_n_rows, in_n_cols) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check((in_n_rows != 1), "SpRow::SpRow(): must have only one row"); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpRow::SpRow(const char* text) Chris@49: : SpMat(text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: Chris@49: arma_debug_check((SpMat::n_rows != 1), "SpRow::SpRow(): must have only one row"); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const SpRow& Chris@49: SpRow::operator=(const char* text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: Chris@49: SpMat::operator=(text); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpRow::SpRow(const std::string& text) Chris@49: : SpMat(text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: Chris@49: arma_debug_check((SpMat::n_rows != 1), "SpRow::SpRow(): must have only one row"); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const SpRow& Chris@49: SpRow::operator=(const std::string& text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: SpMat::operator=(text); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const SpRow& Chris@49: SpRow::operator=(const eT val) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: SpMat::operator=(val); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: SpRow::SpRow(const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: Chris@49: SpMat::operator=(X.get_ref()); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const SpRow& Chris@49: SpRow::operator=(const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: SpMat::operator=(X.get_ref()); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: SpRow::SpRow(const SpBase& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: Chris@49: SpMat::operator=(X.get_ref()); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: const SpRow& Chris@49: SpRow::operator=(const SpBase& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: SpMat::operator=(X.get_ref()); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: template Chris@49: inline Chris@49: SpRow::SpRow Chris@49: ( Chris@49: const SpBase::pod_type, T1>& A, Chris@49: const SpBase::pod_type, T2>& B Chris@49: ) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 2; Chris@49: Chris@49: SpMat::init(A,B); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpValProxy< SpMat > Chris@49: SpRow::col(const uword col_num) Chris@49: { Chris@49: arma_debug_check( (col_num >= SpMat::n_cols), "SpRow::col(): out of bounds" ); Chris@49: Chris@49: return SpMat::at(0, col_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: eT Chris@49: SpRow::col(const uword col_num) const Chris@49: { Chris@49: arma_debug_check( (col_num >= SpMat::n_cols), "SpRow::col(): out of bounds" ); Chris@49: Chris@49: return SpMat::at(0, col_num); Chris@49: } Chris@49: Chris@49: Chris@49: /* Chris@49: template Chris@49: arma_inline Chris@49: subview_row Chris@49: SpRow::cols(const uword in_col1, const uword in_col2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "SpRow::cols(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: const uword subview_n_cols = in_col2 - in_col1 + 1; Chris@49: Chris@49: return subview_row(*this, 0, in_col1, subview_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const subview_row Chris@49: SpRow::cols(const uword in_col1, const uword in_col2) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "SpRow::cols(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: const uword subview_n_cols = in_col2 - in_col1 + 1; Chris@49: Chris@49: return subview_row(*this, 0, in_col1, subview_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: subview_row Chris@49: SpRow::subvec(const uword in_col1, const uword in_col2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "SpRow::subvec(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: const uword subview_n_cols = in_col2 - in_col1 + 1; Chris@49: Chris@49: return subview_row(*this, 0, in_col1, subview_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const subview_row Chris@49: SpRow::subvec(const uword in_col1, const uword in_col2) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( ( (in_col1 > in_col2) || (in_col2 >= Mat::n_cols) ), "SpRow::subvec(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: const uword subview_n_cols = in_col2 - in_col1 + 1; Chris@49: Chris@49: return subview_row(*this, 0, in_col1, subview_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: subview_row Chris@49: SpRow::subvec(const span& col_span) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool col_all = col_span.whole; Chris@49: Chris@49: const uword local_n_cols = Mat::n_cols; Chris@49: Chris@49: const uword in_col1 = col_all ? 0 : col_span.a; Chris@49: const uword in_col2 = col_span.b; Chris@49: const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; Chris@49: Chris@49: arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "SpRow::subvec(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: return subview_row(*this, 0, in_col1, subvec_n_cols); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const subview_row Chris@49: SpRow::subvec(const span& col_span) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool col_all = col_span.whole; Chris@49: Chris@49: const uword local_n_cols = Mat::n_cols; Chris@49: Chris@49: const uword in_col1 = col_all ? 0 : col_span.a; Chris@49: const uword in_col2 = col_span.b; Chris@49: const uword subvec_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1; Chris@49: Chris@49: arma_debug_check( ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) ), "SpRow::subvec(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: return subview_row(*this, 0, in_col1, subvec_n_cols); Chris@49: } Chris@49: */ Chris@49: Chris@49: Chris@49: // template Chris@49: // arma_inline Chris@49: // subview_row Chris@49: // SpRow::operator()(const span& col_span) Chris@49: // { Chris@49: // arma_extra_debug_sigprint(); Chris@49: // Chris@49: // return subvec(col_span); Chris@49: // } Chris@49: // Chris@49: // Chris@49: // Chris@49: // template Chris@49: // arma_inline Chris@49: // const subview_row Chris@49: // SpRow::operator()(const span& col_span) const Chris@49: // { Chris@49: // arma_extra_debug_sigprint(); Chris@49: // Chris@49: // return subvec(col_span); Chris@49: // } Chris@49: Chris@49: Chris@49: Chris@49: //! remove specified columns Chris@49: template Chris@49: inline Chris@49: void Chris@49: SpRow::shed_col(const uword col_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( col_num >= SpMat::n_cols, "SpRow::shed_col(): out of bounds"); Chris@49: Chris@49: shed_cols(col_num, col_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! remove specified columns Chris@49: template Chris@49: inline Chris@49: void Chris@49: SpRow::shed_cols(const uword in_col1, const uword in_col2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_col1 > in_col2) || (in_col2 >= SpMat::n_cols), Chris@49: "SpRow::shed_cols(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword diff = (in_col2 - in_col1 + 1); Chris@49: Chris@49: // This is doubleplus easy because we have all the column pointers stored. Chris@49: const uword start = SpMat::col_ptrs[in_col1]; Chris@49: const uword end = SpMat::col_ptrs[in_col2 + 1]; Chris@49: Chris@49: if (start != end) Chris@49: { Chris@49: const uword elem_diff = end - start; Chris@49: Chris@49: eT* new_values = memory::acquire_chunked (SpMat::n_nonzero - elem_diff); Chris@49: uword* new_row_indices = memory::acquire_chunked(SpMat::n_nonzero - elem_diff); Chris@49: Chris@49: // Copy first set of elements, if necessary. Chris@49: if (start > 0) Chris@49: { Chris@49: arrayops::copy(new_values, SpMat::values, start); Chris@49: arrayops::copy(new_row_indices, SpMat::row_indices, start); Chris@49: } Chris@49: Chris@49: // Copy last set of elements, if necessary. Chris@49: if (end != SpMat::n_nonzero) Chris@49: { Chris@49: arrayops::copy(new_values + start, SpMat::values + end, (SpMat::n_nonzero - end)); Chris@49: arrayops::copy(new_row_indices + start, SpMat::row_indices + end, (SpMat::n_nonzero - end)); Chris@49: } Chris@49: Chris@49: memory::release(SpMat::values); Chris@49: memory::release(SpMat::row_indices); Chris@49: Chris@49: access::rw(SpMat::values) = new_values; Chris@49: access::rw(SpMat::row_indices) = new_row_indices; Chris@49: Chris@49: access::rw(SpMat::n_nonzero) -= elem_diff; Chris@49: } Chris@49: Chris@49: // Update column pointers. Chris@49: uword* new_col_ptrs = memory::acquire(SpMat::n_cols - diff + 1); Chris@49: Chris@49: // Copy first part of column pointers. Chris@49: if (in_col1 > 0) Chris@49: { Chris@49: arrayops::copy(new_col_ptrs, SpMat::col_ptrs, in_col1); Chris@49: } Chris@49: Chris@49: // Copy last part of column pointers (and adjust their values as necessary). Chris@49: if (in_col2 < SpMat::n_cols - 1) Chris@49: { Chris@49: arrayops::copy(new_col_ptrs + in_col1, SpMat::col_ptrs + in_col2 + 1, SpMat::n_cols - in_col2); Chris@49: // Modify their values. Chris@49: arrayops::inplace_minus(new_col_ptrs + in_col1, (end - start), SpMat::n_cols - in_col2); Chris@49: } Chris@49: Chris@49: memory::release(SpMat::col_ptrs); Chris@49: Chris@49: access::rw(SpMat::col_ptrs) = new_col_ptrs; Chris@49: Chris@49: access::rw(SpMat::n_cols) -= diff; Chris@49: access::rw(SpMat::n_elem) -= diff; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: // //! insert N cols at the specified col position, Chris@49: // //! optionally setting the elements of the inserted cols to zero Chris@49: // template Chris@49: // inline Chris@49: // void Chris@49: // SpRow::insert_cols(const uword col_num, const uword N, const bool set_to_zero) Chris@49: // { Chris@49: // arma_extra_debug_sigprint(); Chris@49: // Chris@49: // // insertion at col_num == n_cols is in effect an append operation Chris@49: // arma_debug_check( (col_num > SpMat::n_cols), "SpRow::insert_cols(): out of bounds"); Chris@49: // Chris@49: // arma_debug_check( (set_to_zero == false), "SpRow::insert_cols(): cannot set elements to nonzero values"); Chris@49: // Chris@49: // uword newVal = (col_num == 0) ? 0 : SpMat::col_ptrs[col_num]; Chris@49: // SpMat::col_ptrs.insert(col_num, N, newVal); Chris@49: // uword* new_col_ptrs = memory::acquire(SpMat::n_cols + N); Chris@49: // Chris@49: // arrayops::copy(new_col_ptrs, SpMat::col_ptrs, col_num); Chris@49: // Chris@49: // uword fill_value = (col_num == 0) ? 0 : SpMat::col_ptrs[col_num - 1]; Chris@49: // arrayops::inplace_set(new_col_ptrs + col_num, fill_value, N); Chris@49: // Chris@49: // arrayops::copy(new_col_ptrs + col_num + N, SpMat::col_ptrs + col_num, SpMat::n_cols - col_num); Chris@49: // Chris@49: // access::rw(SpMat::n_cols) += N; Chris@49: // access::rw(SpMat::n_elem) += N; Chris@49: // } Chris@49: // Chris@49: // Chris@49: // Chris@49: // //! insert the given object at the specified col position; Chris@49: // //! the given object must have one row Chris@49: // template Chris@49: // template Chris@49: // inline Chris@49: // void Chris@49: // SpRow::insert_cols(const uword col_num, const Base& X) Chris@49: // { Chris@49: // arma_extra_debug_sigprint(); Chris@49: // Chris@49: // SpMat::insert_cols(col_num, X); Chris@49: // } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename SpRow::row_iterator Chris@49: SpRow::begin_row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: // Since this is a row, row_num can only be 0. But the option is provided for Chris@49: // compatibility. Chris@49: arma_debug_check((row_num >= 1), "SpRow::row(): invalid row index"); Chris@49: Chris@49: return SpMat::begin(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename SpRow::const_row_iterator Chris@49: SpRow::begin_row(const uword row_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: // Since this is a row, row_num can only be 0. But the option is provided for Chris@49: // compatibility. Chris@49: arma_debug_check((row_num >= 1), "SpRow::row(): invalid row index"); Chris@49: Chris@49: return SpMat::begin(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename SpRow::row_iterator Chris@49: SpRow::end_row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: // Since this is a row, row_num can only be 0. But the option is provided for Chris@49: // compatibility. Chris@49: arma_debug_check((row_num >= 1), "SpRow::row(): invalid row index"); Chris@49: Chris@49: return SpMat::end(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename SpRow::const_row_iterator Chris@49: SpRow::end_row(const uword row_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: // Since this is a row, row_num can only be 0. But the option is provided for Chris@49: // compatibility. Chris@49: arma_debug_check((row_num >= 1), "SpRow::row(): invalid row index"); Chris@49: Chris@49: return SpMat::end(); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: Chris@49: #ifdef ARMA_EXTRA_SPROW_MEAT Chris@49: #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPROW_MEAT) Chris@49: #endif Chris@49: Chris@49: Chris@49: Chris@49: //! @}